* @copyright www.polycoder.de
* @copyright four for business AG
* array(
* 'src_art_lang' => Recordset (assoziative array) of source item from con_art_lang table
* 'dest_art_lang' => Recordset (assoziative array) of inserted destination item from con_art_lang table
* );
*
*
* @return array Loop through of argument
*/
function mr_conSyncArticle($data) {
ModRewriteDebugger::log($data, 'mr_conSyncArticle $data');
// too defensive but secure way
if (!is_array($data)) {
return $data;
} elseif (!isset($data['src_art_lang']) || !is_array($data['src_art_lang'])) {
return $data;
} elseif (!isset($data['dest_art_lang']) || !is_array($data['dest_art_lang'])) {
return $data;
} elseif (!isset($data['dest_art_lang']['idart'])) {
return $data;
} elseif (!isset($data['dest_art_lang']['idlang'])) {
return $data;
}
if (!isset($data['src_art_lang']['urlname'])) {
$artLang = new cApiArticleLanguage($data['src_art_lang']['idartlang']);
$urlname = $artLang->get('urlname');
} else {
$urlname = $data['src_art_lang']['urlname'];
}
if ($urlname) {
ModRewrite::setArtWebsafeName($urlname, $data['dest_art_lang']['idart'], $data['dest_art_lang']['idlang']);
}
return $data;
}
/**
* Works as a wrapper for Contenido_Url.
*
* Will also be called by chain 'Contenido.Frontend.CreateURL'.
*
* @todo: Still exists bcause of downwards compatibility (some other modules/plugins are using it)
*
* @param string $url URL to rebuild
* @return string New URL
*/
function mr_buildNewUrl($url) {
global $lang;
ModRewriteDebugger::add($url, 'mr_buildNewUrl() in -> $url');
$oUrl = Contenido_Url::getInstance();
$aUrl = $oUrl->parse($url);
// add language, if not exists
if (!isset($aUrl['params']['lang'])) {
$aUrl['params']['lang'] = $lang;
}
// build url
$newUrl = $oUrl->build($aUrl['params']);
// add existing fragment
if (isset($aUrl['fragment'])) {
$newUrl .= '#' . $aUrl['fragment'];
}
$arr = array(
'in' => $url,
'out' => $newUrl,
);
ModRewriteDebugger::add($arr, 'mr_buildNewUrl() in -> out');
return $newUrl;
}
/**
* Replaces existing ancors inside passed code, while rebuilding the urls.
*
* Will be called by chain 'Contenido.Content.conGenerateCode' or
* 'Contenido.Frontend.HTMLCodeOutput' depening on mod_rewrite settings.
*
* @param string $code Code to prepare
* @return string New code
*/
function mr_buildGeneratedCode($code) {
global $client, $cfgClient;
ModRewriteDebugger::add($code, 'mr_buildGeneratedCode() in');
// mod rewrite is activated
if (ModRewrite::isEnabled()) {
$sseStarttime = getmicrotime();
// anchor hack
$code = preg_replace_callback(
"/]*)href\s*=\s*[\"|\'][\/]#(.?|.+?)[\"|\']([^>]*)>/i",
create_function('$matches', 'return ModRewrite::rewriteHtmlAnchor($matches);'),
$code
);
// remove tinymce single quote entities:
$code = str_replace("'", "'", $code);
// get base uri
$sBaseUri = $cfgClient[$client]['path']['htmlpath'];
$sBaseUri = CEC_Hook::execute("Contenido.Frontend.BaseHrefGeneration", $sBaseUri);
// IE hack with wrong base href interpretation
$code = preg_replace_callback(
"/([\"|\'|=])upload\/(.?|.+?)([\"|\'|>])/i",
create_function('$matches', 'return stripslashes($matches[1]' . $sBaseUri . ' . "upload/" . $matches[2] . $matches[3]);'),
$code
);
// define some preparations to replace /front_content.php & ./front_content.php
// against front_content.php, because urls should start with front_content.php
$aPattern = array(
'/([\"|\'|=])\/front_content\.php(.?|.+?)([\"|\'|>])/i',
'/([\"|\'|=])\.\/front_content\.php(.?|.+?)([\"|\'|>])/i'
);
$aReplace = array(
'\1front_content.php\2\3',
'\1front_content.php\2\3'
);
// perform the pre replacements
$code = preg_replace($aPattern, $aReplace, $code);
// create url stack object and fill it with found urls...
$oMRUrlStack = ModRewriteUrlStack::getInstance();
$oMRUrlStack->add('front_content.php');
$matches = null;
preg_match_all("/([\"|\'|=])front_content\.php(.?|.+?)([\"|\'|>])/i", $code, $matches, PREG_SET_ORDER);
foreach ($matches as $val) {
$oMRUrlStack->add('front_content.php' . $val[2]);
}
// ok let it beginn, build the clean urls
$code = str_replace('"front_content.php"', '"' . mr_buildNewUrl('front_content.php') . '"', $code);
$code = str_replace("'front_content.php'", "'" . mr_buildNewUrl('front_content.php') . "'", $code);
$code = preg_replace_callback(
"/([\"|\'|=])front_content\.php(.?|.+?)([\"|\'|>])/i",
create_function('$aMatches', 'return $aMatches[1] . mr_buildNewUrl("front_content.php" . $aMatches[2]) . $aMatches[3];'),
$code
);
ModRewriteDebugger::add($code, 'mr_buildGeneratedCode() out');
$sseEndtime = getmicrotime();
} else {
// anchor hack for non modrewrite websites
$code = preg_replace_callback(
"/]*)href\s*=\s*[\"|\'][\/]#(.?|.+?)[\"|\']([^>]*)>/i",
create_function('$matches', 'return ModRewrite::contenidoHtmlAnchor($matches, $GLOBALS["is_XHTML"]);'),
$code
);
}
ModRewriteDebugger::add(($sseEndtime - $sseStarttime), 'mr_buildGeneratedCode() total spend time');
if ($debug = mr_debugOutput(false)) {
$code = cString::iReplaceOnce("
", $debug . "\n", $code);
}
return $code;
// print "\n\n";
}
/**
* Sets language of client, like done in front_content.php
*
* @param int $client Client id
*/
function mr_setClientLanguageId($client) {
global $lang, $load_lang, $cfg;
if ((int) $lang > 0) {
// there is nothing to do
return;
} elseif ($load_lang) {
// load_client is set in frontend/config.php
$lang = $load_lang;
return;
}
// try to get clients language from table
$sql = "SELECT B.idlang FROM "
. $cfg['tab']['clients_lang'] . " AS A, "
. $cfg['tab']['lang'] . " AS B "
. "WHERE "
. "A.idclient='" . ((int) $client) . "' AND A.idlang=B.idlang"
. "LIMIT 0,1";
if ($aData = mr_queryAndNextRecord($sql)) {
$lang = $aData['idlang'];
}
}
/**
* Loads Advanced Mod Rewrite configuration for passed client using serialized
* file containing the settings.
*
* File is placed in /contenido/mod_rewrite/includes/and is named like
* config.mod_rewrite_{client_id}.php.
*
* @param int $clientId Id of client
* @param bool $forceReload Flag to force to reload configuration, e. g. after
* done changes on it
*/
function mr_loadConfiguration($clientId, $forceReload = false) {
global $cfg;
static $aLoaded;
$clientId = (int) $clientId;
if (!isset($aLoaded)) {
$aLoaded = array();
} elseif (isset($aLoaded[$clientId]) && $forceReload == false) {
return;
}
$mrConfig = mr_getConfiguration($clientId);
if (is_array($mrConfig)) {
// merge mod rewrite configuration with global cfg array
$cfg = array_merge($cfg, $mrConfig);
} else {
// couldn't load configuration, set defaults
include_once($cfg['path']['contenido'] . $cfg['path']['plugins'] . 'mod_rewrite/includes/config.mod_rewrite_default.php');
}
$aLoaded[$clientId] = true;
}
/**
* Returns the mod rewrite configuration array of an client.
*
* File is placed in /contenido/mod_rewrite/includes/and is named like
* config.mod_rewrite_{client_id}.php.
*
* @param int $clientId Id of client
* @return array|null
*/
function mr_getConfiguration($clientId) {
global $cfg;
$file = $cfg['path']['contenido'] . $cfg['path']['plugins'] . 'mod_rewrite/includes/config.mod_rewrite_' . $clientId . '.php';
if (!is_file($file) || !is_readable($file)) {
return null;
}
if ($content = file_get_contents($file)) {
return unserialize($content);
} else {
return null;
}
}
/**
* Saves the mod rewrite configuration array of an client.
*
* File is placed in /contenido/mod_rewrite/includes/and is named like
* config.mod_rewrite_{client_id}.php.
*
* @param int $clientId Id of client
* @param array $config Configuration to save
* @return bool
*/
function mr_setConfiguration($clientId, array $config) {
global $cfg;
$file = $cfg['path']['contenido'] . $cfg['path']['plugins'] . 'mod_rewrite/includes/config.mod_rewrite_' . $clientId . '.php';
$result = file_put_contents($file, serialize($config));
return ($result) ? true : false;
}
/**
* Includes the frontend controller script which parses the url and extacts
* needed data like idcat, idart, lang and client from it.
*
* Will be called by chain 'Contenido.Frontend.AfterLoadPlugins' at front_content.php.
*
* @return bool Just a return value
*/
function mr_runFrontendController() {
$iStartTime = getmicrotime();
plugin_include('mod_rewrite', 'includes/config.plugin.php');
if (ModRewrite::isEnabled() == true) {
plugin_include('mod_rewrite', 'includes/front_content_controller.php');
$totalTime = sprintf('%.4f', (getmicrotime() - $iStartTime));
ModRewriteDebugger::add($totalTime, 'mr_runFrontendController() total time');
}
return true;
}
/**
* Cleanups passed string from characters beeing repeated two or more times
*
* @param string $char Character to remove
* @param string $string String to clean from character
* @return string Cleaned string
*/
function mr_removeMultipleChars($char, $string) {
while (strpos($string, $char . $char) !== false) {
$string = str_replace($char . $char, $char, $string);
}
return $string;
}
/**
* Returns amr related translation text
*
* @param string $key The message id as string
* @return string Related message
*/
function mr_i18n($key) {
global $lngAMR;
return (is_array($lngAMR) && isset($lngAMR[$key])) ? $lngAMR[$key] : 'n. a.';
}
################################################################################
### Some helper functions, which are not plugin specific
/**
* Database query helper. Used to execute a select statement and to return the
* result of first recordset.
*
* Minimizes following code:
*
* // default way
* $db = new DB_Contenido();
* $sql = "SELECT * FROM foo WHERE bar='foobar'";
* $db->query($sql);
* $db->next_record();
* $data = $db->Record;
*
* // new way
* $sql = "SELECT * FROM foo WHERE bar='foobar'";
* $data = mr_queryAndNextRecord($sql);
*
*
* @param string $query Query to execute
* @return mixed Assoziative array including recordset or null
*/
function mr_queryAndNextRecord($query) {
static $db;
if (!isset($db)) {
$db = new DB_Contenido();
}
if (!$db->query($query)) {
return null;
}
return ($db->next_record()) ? $db->Record : null;
}
/**
* Returns value of an array key (assoziative or indexed).
*
* Shortcut function for some ways to access to arrays:
*
* // old way
* if (is_array($foo) && isset($foo['bar']) && $foo['bar'] == 'yieeha') {
* // do something
* }
*
* // new, more readable way:
* if (mr_arrayValue($foo, 'bar') == 'yieeha') {
* // do something
* }
*
* // old way
* if (is_array($foo) && isset($foo['bar'])) {
* $jep = $foo['bar'];
* } else {
* $jep = 'yummy';
* }
*
* // new way
* $jep = mr_arrayValue($foo, 'bar', 'yummy');
*
*
* @param array $array The array
* @param mixed $key Position of an indexed array or key of an assoziative array
* @param mixed $default Default value to return
* @return mixed Either the found value or the default value
*/
function mr_arrayValue($array, $key, $default = null) {
if (!is_array($array)) {
return $default;
} elseif (!isset($array[$key])) {
return $default;
} else {
return $array[$key];
}
}
/**
* Request cleanup function. Request data is allways tainted and must be filtered.
* Pass the array to cleanup using several options.
* Emulates array_walk_recursive().
*
* @param mixed $data Data to cleanup
* @param array $options Default options array, provides only 'filter' key with several
* filter functions which are to execute as follows:
*
* $options['filter'] = array('trim', 'myFilterFunc');
*
* If no filter functions are set, 'trim', 'strip_tags' and 'stripslashes'
* will be used by default.
* A userdefined function must accept the value as a parameter and must return
* the filtered parameter, e. g.
*
* function myFilter($data) {
* // do what you want with the data, e. g. cleanup of xss content
* return $data;
* }
*
*
* @return mixed Cleaned data
*/
function mr_requestCleanup(&$data, $options = null) {
if (!mr_arrayValue($options, 'filter')) {
$options['filter'] = array('trim', 'strip_tags', 'stripslashes');
}
if (is_array($data)) {
foreach ($data as $p => $v) {
$data[$p] = mr_requestCleanup($v, $options);
}
} else {
foreach ($options['filter'] as $filter) {
if ($filter == 'trim') {
$data = trim($data);
} elseif ($filter == 'strip_tags') {
$data = strip_tags($data);
} elseif ($filter == 'stripslashes') {
$data = stripslashes($data);
} elseif (function_exists($filter)) {
$data = call_user_func($filter, $data);
}
}
}
return $data;
}
/**
* Minimalistic'n simple way to get request variables.
*
* Checks occurance in $_GET, then in $_POST. Uses trim() and strip_tags() to preclean data.
*
* @param string $key Name of var to get
* @param mixed $default Default value to return
* @return mixed The value
*/
function mr_getRequest($key, $default = null) {
static $cache;
if (!isset($cache)) {
$cache = array();
}
if (isset($cache[$key])) {
return $cache[$key];
}
if (isset($_GET[$key])) {
$val = $_GET[$key];
} elseif (isset($_POST[$key])) {
$val = $_POST[$key];
} else {
$val = $default;
}
$cache[$key] = strip_tags(trim($val));
return $cache[$key];
}
/**
* Replaces calling of header method for redirects in front_content.php,
* used during development.
*
* @param $header Header value for redirect
*/
function mr_header($header) {
header($header);
return;
$header = str_replace('Location: ', '', $header);
echo '