Overview

Packages

  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Datatype
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cUriBuilderMR
  • ModRewrite
  • ModRewrite_ContentController
  • ModRewrite_ContentExpertController
  • ModRewrite_ContentTestController
  • ModRewrite_ControllerAbstract
  • ModRewriteBase
  • ModRewriteController
  • ModRewriteDebugger
  • ModRewriteTest
  • ModRewriteUrlStack
  • ModRewriteUrlUtil

Functions

  • mr_arrayValue
  • mr_buildGeneratedCode
  • mr_buildNewUrl
  • mr_conCopyArtLang
  • mr_conMoveArticles
  • mr_conSaveArticle
  • mr_conSyncArticle
  • mr_debugOutput
  • mr_getConfiguration
  • mr_getRequest
  • mr_header
  • mr_i18n
  • mr_loadConfiguration
  • mr_queryAndNextRecord
  • mr_removeMultipleChars
  • mr_requestCleanup
  • mr_runFrontendController
  • mr_setClientLanguageId
  • mr_setConfiguration
  • mr_strCopyCategory
  • mr_strMovedownCategory
  • mr_strMoveSubtree
  • mr_strMoveUpCategory
  • mr_strNewCategory
  • mr_strNewTree
  • mr_strRenameCategory
  • mr_strSyncCategory
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
   1: <?php
   2: /**
   3:  * AMR Mod Rewrite helper class
   4:  *
   5:  * @package     Plugin
   6:  * @subpackage  ModRewrite
   7:  * @version     SVN Revision $Rev:$
   8:  * @id          $Id: class.modrewrite.php 5599 2013-09-30 16:14:38Z marcus.gnass $:
   9:  * @author      Stefan Seifarth / stese
  10:  * @author      Murat Purc <murat@purc.de>
  11:  * @copyright   www.polycoder.de
  12:  * @copyright   four for business AG <www.4fb.de>
  13:  * @license     http://www.contenido.org/license/LIZENZ.txt
  14:  * @link        http://www.4fb.de
  15:  * @link        http://www.contenido.org
  16:  */
  17: 
  18: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
  19: 
  20: /**
  21:  * Class to create websafe names, it also provides several helper functions
  22:  *
  23:  * @author      Stefan Seifarth / stese
  24:  * @author      Murat Purc <murat@purc.de>
  25:  * @package     Plugin
  26:  * @subpackage  ModRewrite
  27:  */
  28: class ModRewrite extends ModRewriteBase {
  29: 
  30:     /**
  31:      * Database instance
  32:      *
  33:      * @var  cDb
  34:      */
  35:     private static $_db;
  36: 
  37:     /**
  38:      * Lookup table to cache some internal data such as db query results
  39:      *
  40:      * @var  array
  41:      */
  42:     protected static $_lookupTable;
  43: 
  44:     /**
  45:      * Initialization, is to call at least once, also possible to call multible
  46:      * times, if different client configuration is to load.
  47:      *
  48:      * Loads configuration of passed client and sets some properties.
  49:      *
  50:      * @param  int  $clientId  Client id
  51:      */
  52:     public static function initialize($clientId) {
  53:         mr_loadConfiguration($clientId, true);
  54:         self::$_db = cRegistry::getDb();
  55:         self::$_lookupTable = array();
  56:     }
  57: 
  58:     /**
  59:      * Check categories on websafe name
  60:      *
  61:      * Check all categories in the main parent category on existing same websafe name
  62:      *
  63:      * @param   string  $sName    Websafe name to check
  64:      * @param   int     $iCatId   Current category id
  65:      * @param   int     $iLangId  Current language id
  66:      * @return  bool    True if websafename already exists, false if not
  67:      */
  68:     public static function isInCategories($sName = '', $iCatId = 0, $iLangId = 0) {
  69:         global $cfg;
  70: 
  71:         $sName = self::$_db->escape($sName);
  72:         $iCatId = (int) $iCatId;
  73:         $iLangId = (int) $iLangId;
  74: 
  75:         // get parentid
  76:         $iParentId = 0;
  77:         $sql = "SELECT parentid FROM " . $cfg['tab']['cat'] . " WHERE idcat = " . $iCatId;
  78:         if ($aData = mr_queryAndNextRecord($sql)) {
  79:             $iParentId = ($aData['parentid'] > 0) ? (int) $aData['parentid'] : 0;
  80:         }
  81: 
  82:         // check if websafe name is in this category
  83:         $sql = "SELECT count(cl.idcat) as numcats FROM " . $cfg['tab']['cat_lang'] . " cl "
  84:                 . "LEFT JOIN " . $cfg['tab']['cat'] . " c ON cl.idcat = c.idcat WHERE "
  85:                 . "c.parentid = '$iParentId' AND cl.idlang = " . $iLangId . " AND "
  86:                 . "LOWER(cl.urlname) = LOWER('" . $sName . "') AND cl.idcat <> " . $iCatId;
  87:         ModRewriteDebugger::log($sql, 'ModRewrite::isInCategories $sql');
  88: 
  89:         if ($aData = mr_queryAndNextRecord($sql)) {
  90:             return ($aData['numcats'] > 0) ? true : false;
  91:         }
  92: 
  93:         return false;
  94:     }
  95: 
  96:     /**
  97:      * Check articles on websafe name.
  98:      *
  99:      * Check all articles in the current category on existing same websafe name.
 100:      *
 101:      * @param    string  $sName    Websafe name to check
 102:      * @param    int     $iArtId   Current article id
 103:      * @param    int     $iLangId  Current language id
 104:      * @param   int     $iCatId   Category id
 105:      * @return     bool    True if websafename already exists, false if not
 106:      */
 107:     public static function isInCatArticles($sName = '', $iArtId = 0, $iLangId = 0, $iCatId = 0) {
 108:         global $cfg;
 109: 
 110:         $sName = self::$_db->escape($sName);
 111:         $iArtId = (int) $iArtId;
 112:         $iLangId = (int) $iLangId;
 113:         $iCatId = (int) $iCatId;
 114: 
 115:         // handle multipages
 116:         if ($iCatId == 0) {
 117:             // get category id if not set
 118:             $sql = "SELECT idcat FROM " . $cfg['tab']['cat_art'] . " WHERE idart = " . $iArtId;
 119:             if ($aData = mr_queryAndNextRecord($sql)) {
 120:                 $iCatId = ($aData['idcat'] > 0) ? (int) $aData['idcat'] : 0;
 121:             }
 122:         }
 123: 
 124:         // check if websafe name is in this category
 125:         $sql = "SELECT count(al.idart) as numcats FROM " . $cfg['tab']['art_lang'] . " al "
 126:                 . "LEFT JOIN " . $cfg['tab']['cat_art'] . " ca ON al.idart = ca.idart WHERE "
 127:                 . " ca.idcat='$iCatId' AND al.idlang=" . $iLangId . " AND "
 128:                 . "LOWER(al.urlname) = LOWER('" . $sName . "') AND al.idart <> " . $iArtId;
 129:         if ($aData = mr_queryAndNextRecord($sql)) {
 130:             return ($aData['numcats'] > 0) ? true : false;
 131:         }
 132: 
 133:         return false;
 134:     }
 135: 
 136:     /**
 137:      * Set websafe name in article list.
 138:      *
 139:      * Insert new websafe name in article list
 140:      *
 141:      * @param   string  $sName    Original name (will be converted)
 142:      * @param   int     $iArtId   Current article id
 143:      * @param   int     $iLangId  Current language id
 144:      * @param   int     $iCatId   Category id
 145:      * @return     bool    True if insert was successfully
 146:      */
 147:     public static function setArtWebsafeName($sName = '', $iArtId = 0, $iLangId = 0, $iCatId = 0) {
 148:         global $cfg;
 149: 
 150:         $iArtId = (int) $iArtId;
 151:         $iLangId = (int) $iLangId;
 152:         $iCatId = (int) $iCatId;
 153: 
 154:         // get websafe name
 155:         $sNewName = cApiStrCleanURLCharacters(conHtmlEntityDecode($sName));
 156: 
 157:         // remove double or more separators
 158:         $sNewName = mr_removeMultipleChars('-', $sNewName);
 159: 
 160:         $sNewName = self::$_db->escape($sNewName);
 161: 
 162:         // check if websafe name already exists
 163:         if (self::isInCatArticles($sNewName, $iArtId, $iLangId, $iCatId)) {
 164:             // create new websafe name if exists
 165:             $sNewName = $sNewName . $iArtId;
 166:         }
 167: 
 168:         // check again - and set name
 169:         if (!self::isInCatArticles($sNewName, $iArtId, $iLangId, $iCatId)) {
 170:             // insert websafe name in article list
 171:             $sql = "UPDATE " . $cfg['tab']['art_lang'] . " SET urlname = '$sNewName' "
 172:                     . "WHERE idart = " . $iArtId . " AND idlang = " . $iLangId;
 173:             return self::$_db->query($sql);
 174:         } else {
 175:             return false;
 176:         }
 177:     }
 178: 
 179:     /**
 180:      * Set websafe name in category list.
 181:      *
 182:      * Insert new websafe name in category list.
 183:      *
 184:      * @param   string  $sName    Original name (will be converted) or alias
 185:      * @param   int     $iCatId   Category id
 186:      * @param   int     $iLangId  Language id
 187:      * @return  bool    True if insert was successfully
 188:      */
 189:     public static function setCatWebsafeName($sName = '', $iCatId = 0, $iLangId = 0) {
 190:         global $cfg;
 191: 
 192:         $iCatId = (int) $iCatId;
 193:         $iLangId = (int) $iLangId;
 194: 
 195:         // create websafe name
 196:         $sNewName = cApiStrCleanURLCharacters(conHtmlEntityDecode($sName));
 197: 
 198:         // remove double or more separators
 199:         $sNewName = mr_removeMultipleChars('-', $sNewName);
 200: 
 201:         $sNewName = self::$_db->escape($sNewName);
 202: 
 203:         // check if websafe name already exists
 204:         if (self::isInCategories($sNewName, $iCatId, $iLangId)) {
 205:             // create new websafe name if exists
 206:             $sNewName = $sNewName . $iCatId;
 207:         }
 208: 
 209:         // check again - and set name
 210:         if (!self::isInCategories($sNewName, $iCatId, $iLangId)) {
 211:             // insert websafe name in article list
 212:             $sql = "UPDATE " . $cfg['tab']['cat_lang'] . " SET urlname = '$sNewName' "
 213:                     . "WHERE idcat = " . $iCatId . " AND idlang = " . $iLangId;
 214: 
 215:             ModRewriteDebugger::log(array(
 216:                 'sName' => $sName,
 217:                 'iCatId' => $iCatId,
 218:                 'iLangId' => $iLangId,
 219:                 'sNewName' => $sNewName
 220:             ), 'ModRewrite::setCatWebsafeName $data');
 221: 
 222:             return self::$_db->query($sql);
 223:         } else {
 224:             return false;
 225:         }
 226:     }
 227: 
 228:     /**
 229:      * Set urlpath of category
 230:      *
 231:      * @param   int     $iCatId   Category id
 232:      * @param   int     $iLangId  Language id
 233:      * @return  bool    True if insert was successfully
 234:      */
 235:     public static function setCatUrlPath($iCatId = 0, $iLangId = 0) {
 236:         global $cfg;
 237: 
 238:         $sPath = self::buildRecursivPath($iCatId, $iLangId);
 239: 
 240:         $iCatId = (int) $iCatId;
 241:         $iLangId = (int) $iLangId;
 242: 
 243:         // insert websafe name in article list
 244:         $sql = "UPDATE " . $cfg['tab']['cat_lang'] . " SET urlpath = '$sPath' "
 245:                 . "WHERE idcat = " . $iCatId . " AND idlang = " . $iLangId;
 246: 
 247:         ModRewriteDebugger::log(array(
 248:             'iCatId' => $iCatId,
 249:             'iLangId' => $iLangId,
 250:             'sPath' => $sPath
 251:         ), 'ModRewrite::setCatUrlPath $data');
 252: 
 253:         return self::$_db->query($sql);
 254:     }
 255: 
 256:     /**
 257:      * Get article id and language id from article language id
 258:      *
 259:      * @param   int    $iArtlangId  Current article id
 260:      * @return  array  Array with idart and idlang of current article
 261:      */
 262:     public static function getArtIdByArtlangId($iArtlangId = 0) {
 263:         global $cfg;
 264: 
 265:         $iArtlangId = (int) $iArtlangId;
 266:         $sql = "SELECT idart, idlang FROM " . $cfg['tab']['art_lang'] . " WHERE idartlang = " . $iArtlangId;
 267:         if ($aData = mr_queryAndNextRecord($sql)) {
 268:             return $aData;
 269:         }
 270:         return array();
 271:     }
 272: 
 273:     /**
 274:      * Get article id by article websafe name
 275:      *
 276:      * @param   string    $sArtName  Websafe name
 277:      * @param   int       $iCatId    Category id
 278:      * @param   int       $iLangId   Language id
 279:      * @return  int|NULL  Recent article id or NULL
 280:      */
 281:     public static function getArtIdByWebsafeName($sArtName = '', $iCatId = 0, $iLangId = 0) {
 282:         global $cfg, $lang;
 283: 
 284:         $sArtName = self::$_db->escape($sArtName);
 285:         $iCatId = (int) $iCatId;
 286:         $iLangId = (int) $iLangId;
 287:         if (0 === $iLangId && is_int($lang)) {
 288:             $iLangId = $lang;
 289:         }
 290: 
 291:         $sWhere = '';
 292:         if ($iLangId !== 0) {
 293:             $sWhere = ' AND al.idlang = ' . $iLangId;
 294:         }
 295:         // only article name were given
 296:         if ($iCatId == 0) {
 297:             // get all basic category ids with parentid=0
 298:             $aCatIds = array();
 299:             $sql = "SELECT idcat FROM " . $cfg['tab']['cat'] . " WHERE parentid = 0";
 300:             self::$_db->query($sql);
 301:             while (self::$_db->nextRecord()) {
 302:                 $aCatIds[] = "idcat = " . (int) self::$_db->f('idcat');
 303:             }
 304:             $sWhere .= " AND (" . join(" OR ", $aCatIds) . ")";
 305:         } else {
 306:             $sWhere .= " AND ca.idcat = " . $iCatId;
 307:         }
 308: 
 309:         $sql = "SELECT al.idart FROM " . $cfg['tab']['art_lang'] . " al "
 310:                 . "LEFT JOIN " . $cfg['tab']['cat_art'] . " ca ON al.idart = ca.idart "
 311:                 . "WHERE LOWER(al.urlname) = LOWER('$sArtName')" . $sWhere;
 312: 
 313:         if ($aData = mr_queryAndNextRecord($sql)) {
 314:             return $aData['idart'];
 315:         } else {
 316:             return NULL;
 317:         }
 318:     }
 319: 
 320:     /**
 321:      * Get category name from category id and language id.
 322:      *
 323:      * @param   int     $iCatId   Category id
 324:      * @param   int     $iLangId  Language id
 325:      * @return  string  Category name
 326:      */
 327:     public static function getCatName($iCatId = 0, $iLangId = 0) {
 328:         global $cfg;
 329: 
 330:         $iCatId = (int) $iCatId;
 331:         $iLangId = (int) $iLangId;
 332:         $key = 'catname_by_catid_idlang_' . $iCatId . '_' . $iLangId;
 333: 
 334:         if (isset(self::$_lookupTable[$key])) {
 335:             return self::$_lookupTable[$key];
 336:         }
 337: 
 338:         $sql = "SELECT name FROM " . $cfg['tab']['cat_lang'] . " WHERE idcat = " . $iCatId . " AND idlang = " . $iLangId;
 339:         if ($aData = mr_queryAndNextRecord($sql)) {
 340:             $catName = $aData['name'];
 341:         } else {
 342:             $catName = '';
 343:         }
 344: 
 345:         self::$_lookupTable[$key] = $catName;
 346:         return $catName;
 347:     }
 348: 
 349:     /**
 350:      * Funcion to return cat id by path.
 351:      *
 352:      * Caches the paths at first call to provode faster processing at further calls.
 353:      *
 354:      * @param   string  $path  Category path
 355:      * @return  int  Category id
 356:      */
 357:     public static function getCatIdByUrlPath($path) {
 358:         global $cfg, $client, $lang;
 359: 
 360:         if (strpos($path, '/') === 0) {
 361:             $path = substr($path, 1);
 362:         }
 363:         if (strrpos($path, '/') === strlen($path) - 1) {
 364:             $path = substr($path, 0, -1);
 365:         }
 366: 
 367:         $catSeperator = '/';
 368:         $startFromRoot = parent::getConfig('startfromroot');
 369:         $urls2lowercase = parent::getConfig('use_lowercase_uri');
 370: 
 371:         $path = str_replace('/', parent::getConfig('category_seperator'), $path);
 372: 
 373:         $key = 'cat_ids_and_urlpath_' . $client . '_' . $lang;
 374: 
 375:         if (isset(self::$_lookupTable[$key])) {
 376:             $aPathsCache = self::$_lookupTable[$key];
 377:         } else {
 378:             $aPathsCache = array();
 379:         }
 380: 
 381:         if (count($aPathsCache) == 0) {
 382:             $sql = "SELECT cl.idcat, cl.urlpath FROM " . $cfg['tab']['cat_lang']
 383:                     . " AS cl, " . $cfg['tab']['cat'] . " AS c WHERE c.idclient = " . $client
 384:                     . " AND c.idcat = cl.idcat AND cl.idlang = " . $lang;
 385: 
 386:             self::$_db->query($sql);
 387:             while (self::$_db->nextRecord()) {
 388:                 $urlPath = self::$_db->f('urlpath');
 389:                 if ($startFromRoot == 0 && strpos($urlPath, $catSeperator) > 0) {
 390:                     // paths are stored with prefixed main category, but created
 391:                     // urls doesn't contain the main cat, remove it...
 392:                     $urlPath = substr($urlPath, strpos($urlPath, $catSeperator) + 1);
 393:                 }
 394:                 if ($urls2lowercase) {
 395:                     $urlPath = strtolower($urlPath);
 396:                 }
 397: 
 398:                 // store path
 399:                 $aPathsCache[self::$_db->f('idcat')] = $urlPath;
 400:             }
 401:         }
 402:         self::$_lookupTable[$key] = $aPathsCache;
 403: 
 404:         // compare paths using the similar_text algorithm
 405:         $fPercent = 0;
 406:         $aResults = array();
 407:         foreach ($aPathsCache as $id => $pathItem) {
 408:             similar_text($path, $pathItem, $fPercent);
 409:             $aResults[$id] = $fPercent;
 410:         }
 411: 
 412:         arsort($aResults, SORT_NUMERIC);
 413:         reset($aResults);
 414: 
 415:         ModRewriteDebugger::add($path, 'ModRewrite::getCatIdByUrlPath() $path');
 416:         ModRewriteDebugger::add($aPathsCache, 'ModRewrite::getCatIdByUrlPath() $aPathsCache');
 417:         ModRewriteDebugger::add($aResults, 'ModRewrite::getCatIdByUrlPath() $aResults');
 418: 
 419:         $iMinPercentage = (int) parent::getConfig('category_resolve_min_percentage', 0);
 420:         $catId = key($aResults);
 421:         if ($iMinPercentage > 0 && $aResults[$catId] < $iMinPercentage) {
 422:             return 0;
 423:         } else {
 424:             return $catId;
 425:         }
 426:     }
 427: 
 428:     /**
 429:      * Get article name from article id and language id
 430:      *
 431:      * @NOTE: seems to be not used???
 432:      *
 433:      * @param   int     $iArtId   Article id
 434:      * @param   int     $iLangId  Language id
 435:      * @return  string  Article name
 436:      */
 437:     public static function getArtTitle($iArtId = 0, $iLangId = 0) {
 438:         global $cfg;
 439: 
 440:         $iArtId = (int) $iArtId;
 441:         $iLangId = (int) $iLangId;
 442: 
 443:         $sql = "SELECT title FROM " . $cfg['tab']['art_lang'] . " WHERE "
 444:                 . "idart = " . $iArtId . " AND idlang = " . $iLangId;
 445:         if ($aData = mr_queryAndNextRecord($sql)) {
 446:             return $aData['title'];
 447:         }
 448:         return '';
 449:     }
 450: 
 451:     /**
 452:      * Get language ids from category id
 453:      *
 454:      * @param   int    $iCatId  Category id
 455:      * @return  array  Used language ids
 456:      */
 457:     public static function getCatLanguages($iCatId = 0) {
 458:         global $cfg;
 459: 
 460:         $iCatId = (int) $iCatId;
 461:         $key = 'cat_idlang_by_catid_' . $iCatId;
 462: 
 463:         if (isset(self::$_lookupTable[$key])) {
 464:             return self::$_lookupTable[$key];
 465:         }
 466: 
 467:         $aLanguages = array();
 468: 
 469:         $sql = "SELECT idlang FROM " . $cfg['tab']['cat_lang'] . " WHERE idcat = " . $iCatId;
 470:         self::$_db->query($sql);
 471:         while (self::$_db->nextRecord()) {
 472:             $aLanguages[] = self::$_db->f('idlang');
 473:         }
 474: 
 475:         self::$_lookupTable[$key] = $aLanguages;
 476:         return $aLanguages;
 477:     }
 478: 
 479:     /**
 480:      * Get article urlname and language id
 481:      *
 482:      * @param   int    $iArtlangId  idartlang
 483:      * @return  array  Urlname, idlang of empty array
 484:      */
 485:     public static function getArtIds($iArtlangId = 0) {
 486:         global $cfg;
 487: 
 488:         $iArtlangId = (int) $iArtlangId;
 489:         $sql = "SELECT urlname, idlang FROM " . $cfg['tab']['art_lang'] . " WHERE idartlang = " . $iArtlangId;
 490:         if ($aData = mr_queryAndNextRecord($sql)) {
 491:             return $aData;
 492:         }
 493:         return array();
 494:     }
 495: 
 496:     /**
 497:      * Build a recursiv path for mod_rewrite rule like server directories
 498:      * (dir1/dir2/dir3)
 499:      *
 500:      * @param   int     $iCatId   Latest category id
 501:      * @param   int     $iLangId  Language id
 502:      * @param   int     $iLastId  Last category id
 503:      * @return     string    linkpath with correct uri
 504:      */
 505:     public static function buildRecursivPath($iCatId = 0, $iLangId = 0, $iLastId = 0) {
 506:         global $cfg;
 507: 
 508:         $aDirectories = array();
 509:         $bFinish = false;
 510:         $iTmpCatId = (int) $iCatId;
 511:         $iLangId = (int) $iLangId;
 512:         $iLastId = (int) $iLastId;
 513: 
 514:         while ($bFinish == false) {
 515:             $sql = "SELECT cl.urlname, c.parentid FROM " . $cfg['tab']['cat_lang'] . " cl "
 516:                     . "LEFT JOIN " . $cfg['tab']['cat'] . " c ON cl.idcat = c.idcat "
 517:                     . "WHERE cl.idcat = " . $iTmpCatId . " AND cl.idlang = " . $iLangId;
 518:             if ($aData = mr_queryAndNextRecord($sql)) {
 519:                 $aDirectories[] = $aData['urlname'];
 520:                 $iTmpCatId = (int) $aData['parentid'];
 521: 
 522:                 if ($aData['parentid'] == 0 || $aData['parentid'] == $iLastId) {
 523:                     $bFinish = true;
 524:                 }
 525:             } else {
 526:                 $bFinish = true;
 527:             }
 528:         }
 529: 
 530:         // reverse array entries and create directory string
 531:         $sPath = join('/', array_reverse($aDirectories));
 532: 
 533:         return $sPath;
 534:     }
 535: 
 536:     /**
 537:      * Return full CONTENIDO url from single anchor
 538:      *
 539:      * @param   array   $aMatches [0] = complete anchor, [1] = pre arguments, [2] = anchor name, [3] = post arguments
 540:      * @return  string  New anchor
 541:      */
 542:     public static function rewriteHtmlAnchor(array $aMatches = array()) {
 543:         global $artname, $sess, $idart, $idcat, $client, $lang;
 544: 
 545:         // set article name
 546:         $sArtParam = '';
 547:         if (isset($artname) && strlen($artname) > 0) {
 548:             $sArtParam = '&idart=' . (int) $idart;
 549:         }
 550: 
 551:         // check for additional parameter in url
 552:         $aParamsToIgnore = array('idcat', 'idart', 'lang', 'client', 'idcatart', 'changelang', 'changeclient', 'idartlang', 'parts', 'artname');
 553:         $sOtherParams = '';
 554: 
 555:         if (isset($_GET) && count($_GET) > 0) {
 556:             foreach ($_GET as $key => $value) {
 557:                 if (!in_array($key, $aParamsToIgnore) && strlen(trim($value)) > 0) {
 558:                     $aNoAnchor = explode('#', $value);
 559:                     $sOtherParams .= '&' . urlencode(urldecode($key)) . '=' . urlencode(urldecode($value));
 560:                 }
 561:             }
 562:         }
 563: 
 564:         $url = $sess->url(
 565:                 'front_content.php?' . 'idcat=' . (int) $idcat . '&client=' . (int) $client .
 566:                 '&changelang=' . (int) $lang . $sArtParam . $sOtherParams . '#' . $aMatches[2]
 567:         );
 568: 
 569:         $sNewUrl = '<a' . $aMatches[1] . 'href="' . $url . '"' . $aMatches[3] . '>';
 570: 
 571:         return $sNewUrl;
 572:     }
 573: 
 574:     /**
 575:      * Return full CONTENIDO url from single anchor
 576:      *
 577:      * @param   array   $aMatches [0] = complete anchor, [1] = pre arguments, [2] = anchor name, [3] = post arguments
 578:      * @param   bool    $bXHTML  Flag to return XHTML valid url
 579:      * @return  string  New anchor
 580:      */
 581:     public static function contenidoHtmlAnchor(array $aMatches = array(), $bXHTML = true) {
 582:         global $sess;
 583: 
 584:         $aParams = array();
 585:         $sAmpersand = $bXHTML ? '&amp;' : '&';
 586: 
 587:         foreach ($_GET as $key => $value) {
 588:             $aNoAnchor = explode('#', $value);
 589:             $aParams[] = urlencode(urldecode($key)) . '=' . urlencode(urldecode($aNoAnchor[0]));
 590:         }
 591: 
 592:         $url = $sess->url('front_content.php?' . implode($sAmpersand, $aParams) . '#' . $aMatches[2]);
 593:         $sNewUrl = '<a' . $aMatches[1] . 'href="' . $url . '"' . $aMatches[3] . '>';
 594: 
 595:         return $sNewUrl;
 596:     }
 597: 
 598:     /**
 599:      * Get article websafe name from article id and language id.
 600:      *
 601:      * @param    int     $iArtId   Article id
 602:      * @param    int     $iLangId  Language id
 603:      * @return     string    Article websafe name
 604:      */
 605:     public static function getArtWebsafeName($iArtId = 0, $iLangId = 0) {
 606:         global $cfg;
 607: 
 608:         $iArtId = (int) $iArtId;
 609:         $iLangId = (int) $iLangId;
 610:         $sql = "SELECT urlname FROM " . $cfg['tab']['art_lang'] . " WHERE "
 611:                 . "idart = " . $iArtId . " AND idlang = " . $iLangId;
 612:         if ($aData = mr_queryAndNextRecord($sql)) {
 613:             return $aData['urlname'];
 614:         }
 615:         return NULL;
 616:     }
 617: 
 618:     /**
 619:      * Get article websafe name from idartlang.
 620:      *
 621:      * @param    int     $iArtLangId  idartlang
 622:      * @return     string    Article websafe name
 623:      */
 624:     public static function getArtLangWebsafeName($iArtLangId = 0) {
 625:         global $cfg;
 626: 
 627:         $iArtLangId = (int) $iArtLangId;
 628:         $sql = "SELECT urlname FROM " . $cfg['tab']['art_lang'] . " WHERE idartlang = " . $iArtLangId;
 629:         if ($aData = mr_queryAndNextRecord($sql)) {
 630:             return $aData['urlname'];
 631:         }
 632:         return NULL;
 633:     }
 634: 
 635:     /**
 636:      * Get name of client by id.
 637:      *
 638:      * @param   int     $clientId  Client id
 639:      * @return  string  Client name
 640:      */
 641:     public static function getClientName($clientId = 0) {
 642:         global $cfg;
 643: 
 644:         $clientId = (int) $clientId;
 645:         $key = 'clientname_by_clientid_' . $clientId;
 646: 
 647:         if (isset(self::$_lookupTable[$key])) {
 648:             return self::$_lookupTable[$key];
 649:         }
 650: 
 651:         $sql = "SELECT name FROM " . $cfg['tab']['clients'] . " WHERE idclient = " . $clientId;
 652:         if ($aData = mr_queryAndNextRecord($sql)) {
 653:             $clientName = $aData['name'];
 654:         } else {
 655:             $clientName = '';
 656:         }
 657: 
 658:         self::$_lookupTable[$key] = $clientName;
 659:         return $clientName;
 660:     }
 661: 
 662:     /**
 663:      * Get client id from client name
 664:      *
 665:      * @param   string   $sClientName  Client name
 666:      * @return  int  Client id
 667:      */
 668:     public static function getClientId($sClientName = '') {
 669:         global $cfg;
 670: 
 671:         $sClientName = strtolower(self::$_db->escape($sClientName));
 672:         $key = 'clientid_by_name_' . $sClientName;
 673: 
 674:         if (isset(self::$_lookupTable[$key])) {
 675:             return self::$_lookupTable[$key];
 676:         }
 677: 
 678:         $sql = "SELECT idclient FROM " . $cfg['tab']['clients'] . " WHERE LOWER(name) = '" . $sClientName . "' OR LOWER(name) = '" . urldecode($sClientName) . "'";
 679: 
 680:         if ($aData = mr_queryAndNextRecord($sql)) {
 681:             $clientId = $aData['idclient'];
 682:         } else {
 683:             $clientId = false;
 684:         }
 685: 
 686:         self::$_lookupTable[$key] = $clientId;
 687:         return $clientId;
 688:     }
 689: 
 690:     /**
 691:      * Checks if client id exists
 692:      *
 693:      * @param   int  $clientId
 694:      * @return  bool
 695:      */
 696:     public static function clientIdExists($clientId) {
 697:         global $cfg;
 698: 
 699:         $clientId = (int) $clientId;
 700:         $key = 'clientid_exists_' . $clientId;
 701: 
 702:         if (isset(self::$_lookupTable[$key])) {
 703:             return self::$_lookupTable[$key];
 704:         }
 705: 
 706:         $sql = "SELECT idclient FROM " . $cfg['tab']['clients'] . " WHERE idclient = " . $clientId;
 707:         if ($aData = mr_queryAndNextRecord($sql)) {
 708:             $exists = true;
 709:         } else {
 710:             $exists = false;
 711:         }
 712: 
 713:         self::$_lookupTable[$key] = $exists;
 714:         return $exists;
 715:     }
 716: 
 717:     /**
 718:      * Returns name of language by id.
 719:      *
 720:      * @param   int     $languageId  Language id
 721:      * @return  string  Lanuage name
 722:      */
 723:     public static function getLanguageName($languageId = 0) {
 724:         global $cfg;
 725: 
 726:         $languageId = (int) $languageId;
 727:         $key = 'languagename_by_id_' . $languageId;
 728: 
 729:         if (isset(self::$_lookupTable[$key])) {
 730:             return self::$_lookupTable[$key];
 731:         }
 732: 
 733:         $sql = "SELECT name FROM " . $cfg['tab']['lang'] . " WHERE idlang = " . $languageId;
 734:         if ($aData = mr_queryAndNextRecord($sql)) {
 735:             $languageName = $aData['name'];
 736:         } else {
 737:             $languageName = '';
 738:         }
 739: 
 740:         self::$_lookupTable[$key] = $languageName;
 741:         return $languageName;
 742:     }
 743: 
 744:     /**
 745:      * Checks if language id exists
 746:      *
 747:      * @param   int     $languageId  Language id
 748:      * @return  bool
 749:      */
 750:     public static function languageIdExists($languageId) {
 751:         global $cfg;
 752: 
 753:         $languageId = (int) $languageId;
 754:         $key = 'languageid_exists_' . $languageId;
 755: 
 756:         if (isset(self::$_lookupTable[$key])) {
 757:             return self::$_lookupTable[$key];
 758:         }
 759: 
 760:         $sql = "SELECT idlang FROM " . $cfg['tab']['lang'] . " WHERE idlang = " . $languageId;
 761:         if ($aData = mr_queryAndNextRecord($sql)) {
 762:             $exists = true;
 763:         } else {
 764:             $exists = false;
 765:         }
 766: 
 767:         self::$_lookupTable[$key] = $exists;
 768:         return $exists;
 769:     }
 770: 
 771:     /**
 772:      * Get language id from language name thanks to Nicolas Dickinson for multi
 773:      * Client/Language BugFix
 774:      *
 775:      * @param  string   $sLanguageName  Language name
 776:      * @param  int      $iClientId      Client id
 777:      * @return int  Language id
 778:      */
 779:     public static function getLanguageId($sLanguageName = '', $iClientId = 1) {
 780:         global $cfg;
 781: 
 782:         $sLanguageName = strtolower(self::$_db->escape($sLanguageName));
 783:         $iClientId = (int) $iClientId;
 784:         $key = 'langid_by_langname_clientid_' . $sLanguageName . '_' . $iClientId;
 785: 
 786:         if (isset(self::$_lookupTable[$key])) {
 787:             return self::$_lookupTable[$key];
 788:         }
 789: 
 790:         $sql = "SELECT l.idlang FROM " . $cfg['tab']['lang'] . " as l "
 791:                 . "LEFT JOIN " . $cfg['tab']['clients_lang'] . " AS cl ON l.idlang = cl.idlang "
 792:                 . "WHERE cl.idclient = " . $iClientId . " AND (LOWER(l.name) = '" . $sLanguageName . "' "
 793:                 . "OR LOWER(l.name) = '" . urldecode($sLanguageName) . "')";
 794:         if ($aData = mr_queryAndNextRecord($sql)) {
 795:             $languageId = $aData['idlang'];
 796:         } else {
 797:             $languageId = 0;
 798:         }
 799: 
 800:         self::$_lookupTable[$key] = $languageId;
 801:         return $languageId;
 802:     }
 803: 
 804:     /**
 805:      * Splits passed argument into scheme://host and path/query.
 806:      *
 807:      * Example:
 808:      * input  = http://host/front_content.php?idcat=123
 809:      * return = array('htmlpath' => 'http://host', 'url' => 'front_content.php?idcat=123')
 810:      *
 811:      * @param  string  $url  URL to split
 812:      * @return array   Assoziative array including the two parts:
 813:      *                 - array('htmlpath' => $path, 'url' => $url)
 814:      */
 815:     public static function getClientFullUrlParts($url) {
 816:         $clientPath = cRegistry::getFrontendUrl();
 817: 
 818:         if (stristr($url, $clientPath) !== false) {
 819:             // url includes full html path (scheme host path, etc.)
 820:             $url = str_replace($clientPath, '', $url);
 821:             $htmlPath = $clientPath;
 822:             $aComp = parse_url($htmlPath);
 823: 
 824:             // check if path matches to defined rootdir from mod_rewrite conf
 825:             if (isset($aComp['path']) && $aComp['path'] !== parent::getConfig('rootdir')) {
 826:                 // replace not matching path agaings configured one
 827:                 // this will replace e. g. "http://host/cms/" against "http://host/"
 828:                 $htmlPath = str_replace($aComp['path'], parent::getConfig('rootdir'), $htmlPath);
 829:                 if (substr($htmlPath, strlen($htmlPath) - 1) == '/') {
 830:                     // remove last slash
 831:                     $htmlPath = substr($htmlPath, 0, strlen($htmlPath) - 1);
 832:                 }
 833:             }
 834:         } else {
 835:             $htmlPath = '';
 836:         }
 837:         return array('htmlpath' => $htmlPath, 'url' => $url);
 838:     }
 839: 
 840:     /**
 841:      * Function to preclean a url.
 842:      *
 843:      * Removes absolute path declaration '/front_content.php' or relative path
 844:      * definition to actual dir './front_content.php', ampersand entities '&amp;'
 845:      * and returns a url like 'front_content.php?idart=12&idlang=1'
 846:      *
 847:      * @param   string  $url  Url to clean
 848:      * @return  string  Cleaned Url
 849:      */
 850:     public static function urlPreClean($url) {
 851:         // some preparation of different front_content.php occurence
 852:         if (strpos($url, './front_content.php') === 0) {
 853:             $url = str_replace('./front_content.php', 'front_content.php', $url);
 854:         } elseif (strpos($url, '/front_content.php') === 0) {
 855:             $url = str_replace('/front_content.php', 'front_content.php', $url);
 856:         }
 857:         $url = str_replace('&amp;', '&', $url);
 858:         return $url;
 859:     }
 860: 
 861:     /**
 862:      * Recreates all or only empty aliases in categories table.
 863:      *
 864:      * @param  bool  $bOnlyEmpty  Flag to reset only empty items
 865:      */
 866:     public static function recreateCategoriesAliases($bOnlyEmpty = false) {
 867:         global $cfg;
 868: 
 869:         $db = cRegistry::getDb();
 870: 
 871:         $aCats = array();
 872: 
 873:         // get all or only empty categories
 874:         $sql = "SELECT name, idcat, idlang FROM " . $cfg['tab']['cat_lang'];
 875:         if ($bOnlyEmpty === true) {
 876:             $sql .= " WHERE urlname IS NULL OR urlname = '' OR urlpath IS NULL OR urlpath = ''";
 877:         }
 878: 
 879:         $db->query($sql);
 880:         while ($db->nextRecord()) {
 881:             //set new alias
 882:             self::setCatWebsafeName($db->f('name'), $db->f('idcat'), $db->f('idlang'));
 883:             $aCats[] = array('idcat' => $db->f('idcat'), 'idlang' => $db->f('idlang'));
 884:         }
 885: 
 886:         foreach ($aCats as $p => $item) {
 887:             self::setCatUrlPath($item['idcat'], $item['idlang']);
 888:         }
 889: 
 890:         unset($db, $aCats);
 891:     }
 892: 
 893:     /**
 894:      * Returns list of all empty category aliases
 895:      *
 896:      * @param bool $bOnlyNumber
 897:      * @return array|int
 898:      */
 899:     public static function getEmptyCategoriesAliases($bOnlyNumber = true) {
 900:         global $cfg;
 901: 
 902:         $db = cRegistry::getDb();
 903:         $return = ($bOnlyNumber) ? 0 : array();
 904: 
 905:         // get all empty categories
 906:         $sql = "SELECT name, idcat, idlang FROM " . $cfg['tab']['cat_lang'];
 907:         $sql .= " WHERE urlname IS NULL OR urlname = '' OR urlpath IS NULL OR urlpath = ''";
 908: 
 909:         $db->query($sql);
 910: 
 911:         if ($bOnlyNumber) {
 912:             $return = (int) $db->numRows();
 913:         } else {
 914:             while ($db->nextRecord()) {
 915:                 $return[] = array($db->f('name'), $db->f('idcat'), $db->f('idlang'));
 916:             }
 917:         }
 918: 
 919:         unset($db);
 920:         return $return;
 921:     }
 922: 
 923:     /**
 924:      * Recreates all or only empty urlname entries in art_lang table.
 925:      *
 926:      * @param  bool  $bOnlyEmpty  Flag to reset only empty items
 927:      */
 928:     public static function recreateArticlesAliases($bOnlyEmpty = false) {
 929:         global $cfg;
 930: 
 931:         $db = cRegistry::getDb();
 932: 
 933:         // get all or only empty articles
 934:         $sql = "SELECT title, idart, idlang FROM " . $cfg['tab']['art_lang'];
 935:         if ($bOnlyEmpty === true) {
 936:             $sql .= " WHERE urlname IS NULL OR urlname = ''";
 937:         }
 938:         $db->query($sql);
 939: 
 940:         while ($db->nextRecord()) {
 941:             //set new alias
 942:             self::setArtWebsafeName($db->f('title'), $db->f('idart'), $db->f('idlang'));
 943:         }
 944: 
 945:         unset($db);
 946:     }
 947: 
 948:     /**
 949:      * Returns list of all empty article aliases
 950:      *
 951:      * @param bool $bOnlyNumber
 952:      * @return array|int
 953:      */
 954:     public static function getEmptyArticlesAliases($bOnlyNumber = true) {
 955:         global $cfg;
 956: 
 957:         $db = cRegistry::getDb();
 958:         $return = ($bOnlyNumber) ? 0 : array();
 959: 
 960:         // get all empty articles
 961:         $sql  = "SELECT title, idart, idlang FROM " . $cfg['tab']['art_lang'];
 962:         $sql .= " WHERE urlname IS NULL OR urlname = ''";
 963: 
 964:         $db->query($sql);
 965:         if ($bOnlyNumber) {
 966:             $return = (int) $db->numRows();
 967:         } else {
 968:             while ($db->nextRecord()) {
 969:                 $return[] = array($db->f('title'), $db->f('idart'), $db->f('idlang'));
 970:             }
 971:         }
 972: 
 973:         unset($db);
 974:         return $return;
 975:     }
 976: 
 977:     /**
 978:      * Method to reset all aliases (categories and articles).
 979:      *
 980:      * Shortcut to recreateCategoriesAliases() and recreateArticlesAliases()
 981:      */
 982:     public static function resetAliases() {
 983:         self::recreateCategoriesAliases();
 984:         self::recreateArticlesAliases();
 985:     }
 986: 
 987:     /**
 988:      * Recreate all or only empty aliases (categories and articles).
 989:      *
 990:      * Shortcut to recreateCategoriesAliases() and recreateArticlesAliases()
 991:      *
 992:      * @param  bool  $bOnlyEmpty  Flag to reset only empty items
 993:      */
 994:     public static function recreateAliases($bOnlyEmpty = false) {
 995:         self::recreateCategoriesAliases($bOnlyEmpty);
 996:         self::recreateArticlesAliases($bOnlyEmpty);
 997:     }
 998: 
 999:     /**
1000:      * Returns .htaccess related assoziative info array
1001:      *
1002:      * @return  array
1003:      */
1004:     public static function getHtaccessInfo() {
1005: 
1006:         $arr = array(
1007:             'contenido_full_path' => str_replace('\\', '/', realpath(cRegistry::getBackendPath() . '../') . '/'),
1008:             'client_full_path' => cRegistry::getFrontendPath(),
1009:         );
1010:         $arr['in_contenido_path'] = is_file($arr['contenido_full_path'] . '.htaccess');
1011:         $arr['in_client_path'] = is_file($arr['client_full_path'] . '.htaccess');
1012:         $arr['has_htaccess'] = ($arr['in_contenido_path'] || $arr['in_client_path']);
1013: 
1014:         return $arr;
1015:     }
1016: 
1017: }
1018: 
CMS CONTENIDO 4.9.3 API documentation generated by ApiGen 2.8.0