Source for file class.modrewrite.php
Documentation is available at class.modrewrite.php
* Includes class to create websafe names
* @author Stefan Seifarth / stese
* @copyright © www.polycoder.de
* @author Murat Purc <murat@purc.de>
/******************************************
* File : class.modrewrite.php
* Descr : class to create websafe names
* Author : Stefan Seifarth / stese
* Class to create websafe names
* @author Stefan Seifarth / stese
* @author Murat Purc <murat@purc.de>
* Initialization, is to call at least once, also possible to call multible
* times, if different client configuration is to load.
* Loads configuration of passed client and sets some properties.
* @param int $clientId Client id
* Check categories on websafe name
* Check all categories in the main parent category on existing same websafe name
* @param string $sName Websafe name to check
* @param int $iCatId Current category id
* @param int $iLangId Current language id
* @return bool True if websafename already exists, false if not
public static function isInCategories($sName=
'', $iCatId=
0, $iLangId=
0) {
$iLangId = (int)
$iLangId;
$aTab =
parent::$_oGlobals->get('cfg/tab');
$sql =
"SELECT parentid FROM " .
$aTab['cat'] .
" WHERE idcat = '$iCatId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
$iParentId =
($aData['parentid'] >
0 ) ? (int)
$aData['parentid'] :
0;
// check if websafe name is in this category
$sql =
"SELECT count(cl.idcat) as numcats FROM " .
$aTab['cat_lang'] .
" cl "
.
"LEFT JOIN " .
$aTab['cat'] .
" c ON cl.idcat = c.idcat WHERE "
.
"c.parentid = '$iParentId' AND cl.idlang = '" .
$iLangId .
"' AND "
.
"cl.urlname = '" .
$sName .
"' AND cl.idcat <> '$iCatId'";
self::$_oDebug->log($sql, 'ModRewrite::isInCategories $sql');
if ($aData =
mr_queryAndNextRecord($sql)) {
return ($aData['numcats'] >
0) ?
true :
false;
* Check articles on websafe name.
* Check all articles in the current category on existing same websafe name.
* @param string $sName Websafe name to check
* @param int $iArtId Current article id
* @param int $iLangId Current language id
* @param int $iCatId Category id
* @return bool True if websafename already exists, false if not
public static function isInCatArticles($sName=
'', $iArtId=
0, $iLangId=
0, $iCatId=
0) {
$iLangId = (int)
$iLangId;
$aTab =
parent::$_oGlobals->get('cfg/tab');
// get category id if not set
$sql =
"SELECT idcat FROM " .
$aTab['cat_art'] .
" WHERE idart = '$iArtId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
$iCatId =
($aData['idcat'] >
0) ? (int)
$aData['idcat'] :
0;
// check if websafe name is in this category
$sql =
"SELECT count(al.idart) as numcats FROM " .
$aTab['art_lang'] .
" al "
.
"LEFT JOIN " .
$aTab['cat_art'] .
" ca ON al.idart = ca.idart WHERE "
.
" ca.idcat='$iCatId' AND al.idlang='" .
$iLangId .
"' AND "
.
"al.urlname='" .
$sName .
"' AND al.idart <> '$iArtId'";
return ($aData['numcats'] >
0) ?
true :
false;
* Set websafe name in article list.
* Insert new websafe name in article list
* @param string $sName Original name (will be converted)
* @param int $iArtId Current article id
* @param int $iLangId Current language id
* @param int $iCatId Category id
* @return bool True if insert was successfully
public static function setArtWebsafeName($sName=
'', $iArtId=
0, $iLangId=
0, $iCatId=
0) {
$iLangId = (int)
$iLangId;
##++## $sArtWordSep = parent::getConfig('article_word_seperator');
##++## $sNewName = str_replace(parent::getConfig('article_seperator'), $sArtWordSep, $sNewName);
// article word separator
if ($sArtWordSep !==
'') {
if ($sArtWordSep !==
'-') {
// replace set '-' by capiStrCleanURLCharacters against configured one
// remove double or more separators
// check if websafe name already exists
if (self::isInCatArticles($sNewName, $iArtId, $iLangId, $iCatId)) {
// create new websafe name if exists
$sNewName =
$sNewName .
$iArtId;
// check again - and set name
if (!self::isInCatArticles($sNewName, $iArtId, $iLangId, $iCatId)) {
// insert websafe name in article list
$tab =
parent::$_oGlobals->get('cfg/tab/art_lang');
$sql =
"UPDATE " .
$tab .
" SET urlname = '$sNewName' WHERE idart = '$iArtId' AND idlang = '$iLangId'";
* Set websafe name in category list.
* Insert new websafe name in category list.
* @param string $sName Original name (will be converted) or alias
* @param int $iCatId Category id
* @param int $iLangId Language id
* @return bool True if insert was successfully
$iLangId = (int)
$iLangId;
##++## $sCatWordSep = parent::getConfig('category_word_seperator');
##++## $sNewName = str_replace(parent::getConfig('category_seperator'), $sCatWordSep, $sNewName);
##++## $sNewName = str_replace(parent::getConfig('article_seperator'), $sCatWordSep, $sNewName);
// category word separator
if ($sCatWordSep !==
'-') {
// replace set '-' by capiStrCleanURLCharacters against configured one
// remove double or more separators
// check if websafe name already exists
if (self::isInCategories($sNewName, $iCatId, $iLangId)) {
// create new websafe name if exists
$sNewName =
$sNewName .
$iCatId;
// check again - and set name
if (!self::isInCategories($sNewName, $iCatId, $iLangId)) {
// insert websafe name in article list
$tag =
parent::$_oGlobals->get('cfg/tab/cat_lang');
$sql =
"UPDATE " .
$tag .
" SET urlname = '$sNewName' WHERE idcat = '$iCatId' AND idlang = '$iLangId'";
self::$_oDebug->log(array(
), 'ModRewrite::setCatWebsafeName $data'
* Set urlpath of category
* @param int $iCatId Category id
* @param int $iLangId Language id
* @return bool True if insert was successfully
// insert websafe name in article list
$tab =
parent::$_oGlobals->get('cfg/tab/cat_lang');
$sql =
"UPDATE " .
$tab .
" SET urlpath = '$sPath' WHERE idcat = '$iCatId' AND idlang = '$iLangId'";
self::$_oDebug->log(array(
), 'ModRewrite::setCatUrlPath $data'
* Get article id and language id from article language id
* @param int $iArtlangId Current article id
* @return array Array with idart and idlang of current article
$iArtlangId = (int)
$iArtlangId;
$tab =
parent::$_oGlobals->get('cfg/tab/art_lang');
$sql =
"SELECT idart, idlang FROM " .
$tab .
" WHERE idartlang = '$iArtlangId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
* Get article id by article websafe name
* @param string Websafe name
* @return int Recent article id
$aTab =
parent::$_oGlobals->get('cfg/tab');
if ((int)
$iLangId !==
0) {
$sWhere =
' AND al.idlang=' .
$iLangId;
// only article name were given
// get all basic category ids with parentid=0
$sql =
"SELECT idcat FROM " .
$aTab['cat'] .
" WHERE parentid = '0'";
while ($db->next_record()) {
$aCatIds[] =
"idcat = '" .
$db->f('idcat') .
"'";
$sWhere .=
" AND ( " .
join(" OR ", $aCatIds) .
")";
$sWhere .=
" AND ca.idcat = '$iCatId'";
$sql =
"SELECT al.idart FROM " .
$aTab['art_lang'] .
" al "
.
"LEFT JOIN " .
$aTab['cat_art'] .
" ca ON al.idart = ca.idart "
.
"WHERE al.urlname = '$sArtName'" .
$sWhere;
$iArtId =
$aData['idart'];
* Get category name from category id and language id.
* @param int $iCatId Category id
* @param int $iLangId Language id
* @return string Category name
public static function getCatName($iCatId=
0, $iLangId=
0) {
$iLangId = (int)
$iLangId;
$key =
$iCatId .
'-' .
$iLangId;
$key =
'mr_statics/catname_by_catid_idlang/' .
$iCatId .
'_' .
$iLangId;
$catName =
parent::$_oGlobals->get($key);
$tab =
parent::$_oGlobals->get('cfg/tab/cat_lang');
$sql =
"SELECT name FROM " .
$tab .
" WHERE idcat = '$iCatId' AND idlang = '$iLangId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
$catName =
$aData['name'];
parent::$_oGlobals->set($key, $catName);
* Funcion to return cat id by path.
* Caches the paths at first call to provode faster processing at further calls.
* @param string $path Category path
* @return int Category id
if (strpos($path, '/') ===
0) {
##++## $catSeperator = parent::getConfig('category_seperator');
$startFromRoot =
parent::getConfig('startfromroot');
$key =
'mr_statics/cat_ids_and_urlpath';
$aPathsCache =
parent::$_oGlobals->get($key, array());
if (count($aPathsCache) ==
0) {
$aTab =
parent::$_oGlobals->get('cfg/tab');
$client =
parent::$_oGlobals->get('client');
$lang =
parent::$_oGlobals->get('lang');
$db =
new DB_Contenido();
$sql =
"SELECT cl.idcat, cl.urlpath FROM " .
$aTab['cat_lang'] .
" AS cl, " .
$aTab['cat'] .
" AS c WHERE "
.
"c.idclient = " .
$client .
" AND c.idcat = cl.idcat AND cl.idlang = " .
$lang;
while ($db->next_record()) {
$urlPath =
$db->f('urlpath');
if ($startFromRoot ==
0 &&
strpos($urlPath, $catSeperator) >
0) {
// paths are stored with prefixed main category, but created
// urls doesn't contain the main cat, remove it...
$urlPath =
substr($urlPath, strpos($urlPath, $catSeperator)+
1);
$aPathsCache[$db->f('idcat')] =
$urlPath;
parent::$_oGlobals->set($key, $aPathsCache);
// compare paths using the similar_text algorithm
foreach ($aPathsCache as $id =>
$pathItem) {
similar_text($path, $pathItem, $fPercent);
$aResults[$id] =
$fPercent;
arsort($aResults, SORT_NUMERIC);
parent::$_oDebug->addDebug($path, 'ModRewrite::getCatIdByUrlPath() $path');
parent::$_oDebug->addDebug($aPathsCache, 'ModRewrite::getCatIdByUrlPath() $aPathsCache');
parent::$_oDebug->addDebug($aResults, 'ModRewrite::getCatIdByUrlPath() $aResults');
$iMinPercentage = (int)
parent::getConfig('category_resolve_min_percentage', 0);
if ($iMinPercentage >
0 &&
$aResults[$catId] <
$iMinPercentage) {
* Get article name from article id and language id
* @NOTE: seems to be not used???
* @param int $iArtId Article id
* @param int $iLangId Language id
* @return string Article name
public static function getArtTitle($iArtId=
0, $iLangId=
0) {
$iLangId = (int)
$iLangId;
$tab =
parent::$_oGlobals->get('cfg/tab/art_lang');
$sql =
"SELECT title FROM " .
$tab .
" WHERE idart = '$iArtId' AND idlang = '$iLangId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
* Get language ids from category id
* @param int $iCatId Category id
* @return array Used language ids
$key =
'mr_statics/cat_idlang_by_catid/' .
$iCatId;
$aLanguages =
parent::$_oGlobals->get($key);
if ($aLanguages !==
null) {
$db =
new DB_Contenido();
$tab =
parent::$_oGlobals->get('cfg/tab/cat_lang');
$sql =
"SELECT idlang FROM " .
$tab .
" WHERE idcat = '$iCatId'";
while ($db->next_record()) {
$aLanguages[] =
$db->f('idlang');
parent::$_oGlobals->set($key, $aLanguages);
* Get article urlname and language id
* @param int $iArtlangId idartlang
* @return array Urlname, idlang of empty array
public static function getArtIds($iArtlangId=
0) {
$iArtlangId = (int)
$iArtlangId;
$tab =
parent::$_oGlobals->get('cfg/tab/art_lang');
$sql =
"SELECT urlname, idlang FROM " .
$tab .
" WHERE idartlang = '$iArtlangId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
* Build a recursiv path for mod_rewrite rule like server directories
* @param int $iCatId Latest category id
* @param int $iLangId Language id
* @param int $iLastId Last category id
* @return string linkpath with correct uri
$aTabs =
parent::$_oGlobals->get('cfg/tab');
while ($bFinish ==
false) {
$sql =
"SELECT cl.urlname, c.parentid FROM " .
$aTabs['cat_lang'] .
" cl "
.
"LEFT JOIN " .
$aTabs['cat'] .
" c ON cl.idcat = c.idcat "
.
"WHERE cl.idcat = '$iTmpCatId' AND cl.idlang = '$iLangId'";
$aDirectories[] =
$aData['urlname'];
$iTmpCatId =
$aData['parentid'];
if ($aData['parentid'] ==
0 ||
$aData['parentid'] ==
$iLastId) {
##++## $sPathSeparator = parent::getConfig('category_seperator');
// reverse array entries and create directory string
* Return full contenido url from single anchor
* @param array $aMatches [0] = complete anchor, [1] = pre arguments, [2] = anchor name, [3] = post arguments
* @return string New anchor
$artname =
parent::$_oGlobals->get('artname');
$sess =
parent::$_oGlobals->get('sess');
if (isset
($artname) &&
strlen($artname) >
0) {
$sArtParam =
'&idart=' .
parent::$_oGlobals->get('idart');
// check for additional parameter in url
$aParamsToIgnore =
array ('idcat', 'idart', 'lang', 'client', 'idcatart', 'changelang', 'changeclient', 'idartlang', 'parts', 'artname');
if (isset
($_GET) &&
count($_GET) >
0) {
foreach ($_GET as $key =>
$value) {
$idcat =
parent::$_oGlobals->get('idcat');
$client =
parent::$_oGlobals->get('client');
$lang =
parent::$_oGlobals->get('lang');
'front_content.php?' .
'idcat=' .
$idcat .
'&client=' .
$client .
'&changelang=' .
$lang .
$sArtParam .
$sOtherParams .
'#' .
$aMatches[2]
$sNewUrl =
'<a' .
$aMatches[1] .
'href="' .
$url .
'"' .
$aMatches[3] .
'>';
* Return full contenido url from single anchor
* @param array $aMatches [0] = complete anchor, [1] = pre arguments, [2] = anchor name, [3] = post arguments
* @return string New anchor
$artname =
parent::$_oGlobals->get('artname');
$sess =
parent::$_oGlobals->get('sess');
$sAmpersand =
$bXHTML ?
'&' :
'&';
foreach ($_GET as $key =>
$value) {
$aNoAnchor =
explode('#', $value);
$url =
$sess->url( 'front_content.php?' .
implode($sAmpersand, $aParams) .
'#' .
$aMatches[2]);
$sNewUrl =
'<a' .
$aMatches[1] .
'href="' .
$url .
'"' .
$aMatches[3] .
'>';
* Get article websafe name from article id and language id.
* @param int $iArtId Article id
* @param int $iLangId Language id
* @return string Article websafe name
$iLangId = (int)
$iLangId;
$tab =
parent::$_oGlobals->get('cfg/tab/art_lang');
$sql =
"SELECT urlname FROM " .
$tab .
" WHERE "
.
"idart = '" .
$iArtId .
"' AND idlang = '" .
$iLangId .
"'";
if ($aData =
mr_queryAndNextRecord($sql)) {
* Get article websafe name from idartlang.
* @param int $iArtLangId idartlang
* @return string Article websafe name
$iArtLangId = (int)
$iArtLangId;
$tab =
parent::$_oGlobals->get('cfg/tab/art_lang');
$sql =
"SELECT urlname FROM " .
$tab .
" WHERE idartlang = '".
$iArtLangId .
"'";
if ($aData =
mr_queryAndNextRecord($sql)) {
* Get name of client by id.
* @param int $clientId Client id
* @return string Client name
$clientId = (int)
$clientId;
$key =
'mr_statics/clientname_by_clientid/' .
$clientId;
$clientName =
parent::$_oGlobals->get($key);
if ($clientName !==
null) {
$tab =
parent::$_oGlobals->get('cfg/tab/clients');
$sql =
"SELECT name FROM " .
$tab .
" WHERE idclient = '$clientId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
$clientName =
$aData['name'];
parent::$_oGlobals->set($key, $clientName);
* Get client id from client name
* @param string Client name
* @return integer Client id
$key =
'mr_statics/clientid_by_name/' .
$sClientName;
$clientId =
parent::$_oGlobals->get($key);
if ($clientId !==
null) {
$tab =
parent::$_oGlobals->get('cfg/tab/clients');
$sql =
"SELECT idclient FROM " .
$tab .
" WHERE name = '" .
urldecode($sClientName) .
"'";
$clientId =
$aData['idclient'];
parent::$_oGlobals->set($key, $clientId);
* Returns name of language by id.
* @param int $languageId Language id
* @return string Lanuage name
$languageId = (int)
$languageId;
$key =
'mr_statics/languagename_by_id/' .
$languageId;
$languageName =
parent::$_oGlobals->get($key);
if ($languageName !==
null) {
$tab =
parent::$_oGlobals->get('cfg/tab/lang');
$sql =
"SELECT name FROM " .
$tab .
" WHERE idlang = '$languageId'";
if ($aData =
mr_queryAndNextRecord($sql)) {
$languageName =
$aData['name'];
parent::$_oGlobals->set($key, $languageName);
* Get language id from language name thanks to Nicolas Dickinson for multi
* @param string $sLanguageName Language name
* @param int $iClientId Client id
* @return integer Language id
public static function getLanguageId($sLanguageName=
'', $iClientId=
1) {
$iClientId = (int)
$iClientId;
$key =
'mr_statics/langid_by_langname_clientid/' .
$sLanguageName .
'_' .
$iClientId;
$languageId =
parent::$_oGlobals->get($key);
if ($languageId !==
null) {
$aTab =
parent::$_oGlobals->get('cfg/tab');
$sql =
"SELECT l.idlang FROM " .
$aTab['lang'] .
" as l "
.
"LEFT JOIN " .
$aTab['clients_lang'] .
" AS cl ON l.idlang = cl.idlang "
.
"WHERE cl.idclient = '".
$iClientId .
"' AND l.name = '" .
urldecode($sLanguageName) .
"'";
$languageId =
$aData['idlang'];
parent::$_oGlobals->set($key, $languageId);
* Splits passed argument into scheme://host and path/query.
* input = http://host/front_content.php?idcat=123
* return = array('htmlpath' => 'http://host', 'url' => 'front_content.php?idcat=123')
* @param string $url URL to split
* @return array Assoziative array including the two parts:
* - array('htmlpath' => $path, 'url' => $url)
$path =
'cfgClient/' .
parent::$_oGlobals->get('client') .
'/path/htmlpath';
$clientPath =
parent::$_oGlobals->get($path);
if (stristr($url, $clientPath) !==
false) {
// url includes full html path (scheme host path, etc.)
// check if path matches to defined rootdir from mod_rewrite conf
if (isset
($aComp['path']) &&
$aComp['path'] !==
parent::getConfig('rootdir')) {
// replace not matching path agaings configured one
// this will replace e. g. "http://host/cms/" against "http://host/"
return array('htmlpath' =>
$htmlPath, 'url' =>
$url);
* Function to preclean a url.
* Removes absolute path declaration '/front_content.php' or relative path
* definition to actual dir './front_content.php', ampersand entities '&'
* and returns a url like 'front_content.php?idart=12&idlang=1'
* @param string $url Url to clean
* @return string Cleaned Url
// some preparation of different front_content.php occurence
if (strpos($url, './front_content.php') ===
0) {
$url =
str_replace('./front_content.php', 'front_content.php', $url);
} elseif (strpos($url, '/front_content.php') ===
0) {
$url =
str_replace('/front_content.php', 'front_content.php', $url);
* Method to reset all aliases in categories.
$db =
new DB_Contenido();
$tab =
parent::$_oGlobals->get('cfg/tab/cat_lang');
$db->query("UPDATE " .
$tab .
" SET urlname = ''");
$db->query("SELECT name, idcat, idlang FROM " .
$tab);
while ($db->next_record()) {
self::setCatWebsafeName($db->f('name'), $db->f('idcat'), $db->f('idlang'));
$aCats[] =
array('idcat' =>
$db->f('idcat'), 'idlang' =>
$db->f('idlang'));
foreach ($aCats as $p =>
$item) {
self::setCatUrlPath($item['idcat'], $item['idlang']);
* Method to reset all aliases in articles.
$db =
new DB_Contenido();
$tab =
parent::$_oGlobals->get('cfg/tab/art_lang');
$db->query("UPDATE " .
$tab .
" SET urlname = ''");
$db->query("SELECT title, idart, idlang FROM " .
$tab);
while ($db->next_record()) {
self::setArtWebsafeName($db->f('title'), $db->f('idart'), $db->f('idlang'));
* Method to reset all aliases (categories and articles).
self::resetCategoriesAliases();
self::resetArticlesAliases();
* Used to postprocess resolved path
* Error site handling if category not found
* if percentage == 100 and there is no 100 percentage result value,
* error site will be shown - can be adjust by user settings for
* smooth similar effects - 80 to 95 will be best but have to check by user
* @deprecated Is no more used
* @todo remove usage at /contenido/includes/functions.pathresolver.php
* @param array $results Pathresolver results array
* @return mixed Categoryid or false
$iMinPercentage = (int)
parent::getConfig('category_resolve_min_percentage', 0);
if ($iMinPercentage >
0 &&
$results[$catId] <
$iMinPercentage) {
Documentation generated on Tue, 25 Nov 2008 22:07:21 +0100 by phpDocumentor 1.4.1