Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • 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: /**
  4:  * This file contains the uri builder mod rewrite class.
  5:  *
  6:  * @package Plugin
  7:  * @subpackage ModRewrite
  8:  * @author Murat Purc <murat@purc.de>
  9:  * @copyright four for business AG <www.4fb.de>
 10:  * @license http://www.contenido.org/license/LIZENZ.txt
 11:  * @link http://www.4fb.de
 12:  * @link http://www.contenido.org
 13:  */
 14: 
 15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 16: 
 17: /**
 18:  * Class to build frontend urls for advandced mod rewrite plugin.
 19:  *
 20:  * Extends abstract Contenido_UriBuilder class and implements the
 21:  * singleton pattern.
 22:  *
 23:  * Usage:
 24:  * <pre>
 25:  * cInclude('classes', 'uri/class.uriBuilder.MR.php');
 26:  * $url = 'front_content.php?idart=123';
 27:  * $mrUriBuilder = cUriBuilderMR::getInstance();
 28:  * $mrUriBuilder->buildUrl(array($url));
 29:  * $newUrl = $mrUriBuilder->getUrl();
 30:  * </pre>
 31:  *
 32:  * @todo add handling of absolute paths
 33:  * @todo standardize handling of fragments
 34:  * @package Plugin
 35:  * @subpackage ModRewrite
 36:  */
 37: class cUriBuilderMR extends cUriBuilder {
 38: 
 39:     /**
 40:      * Self instance
 41:      *
 42:      * @var cUriBuilderMR
 43:      */
 44:     private static $_instance;
 45: 
 46:     /**
 47:      * Cached rootdir.
 48:      *
 49:      * The rootdir can differ from the configured one if an alternate
 50:      * frontendpath is configured as client setting. In order to determine the
 51:      * current rootdir only once this is cached as static class member.
 52:      *
 53:      * @var string
 54:      */
 55:     private static $_cachedRootDir;
 56: 
 57:     /**
 58:      * Ampersand used for composing several parameter value pairs
 59:      *
 60:      * @var string
 61:      */
 62:     private $_sAmp = '&amp;';
 63: 
 64:     /**
 65:      * Is XHTML output?
 66:      *
 67:      * @var bool
 68:      */
 69:     private $_bIsXHTML = false;
 70: 
 71:     /**
 72:      * Is mod rewrite enabled?
 73:      *
 74:      * @var bool
 75:      */
 76:     private $_bMREnabled = false;
 77: 
 78:     /**
 79:      * Mod Rewrite configuration
 80:      *
 81:      * @var array
 82:      */
 83:     private $_aMrCfg = NULL;
 84: 
 85:     /**
 86:      * Constructor to create an instance of this class.
 87:      *
 88:      * Tries to set some member variables.
 89:      */
 90:     private function __construct() {
 91:         $this->sHttpBasePath = '';
 92:         if (ModRewrite::isEnabled()) {
 93:             $this->_aMrCfg = ModRewrite::getConfig();
 94:             $this->_bMREnabled = true;
 95:             $this->_bIsXHTML = (getEffectiveSetting('generator', 'xhtml', 'false') == 'false') ? false : true;
 96:             $this->_sAmp = ($this->_bIsXHTML) ? '&amp;' : '&';
 97:         }
 98:     }
 99: 
100:     /**
101:      * Returns a instance of cUriBuilderMR.
102:      *
103:      * @return cUriBuilderMR
104:      */
105:     public static function getInstance() {
106:         if (self::$_instance == NULL) {
107:             self::$_instance = new self();
108:         }
109:         return self::$_instance;
110:     }
111: 
112:     /**
113:      * Builds a URL based on defined mod rewrite settings.
114:      *
115:      * @param array $params
116:      *         Parameter array, provides only following parameters:
117:      *         <code>
118:      *         $params[0] = 'front_content.php?idart=123...'
119:      *         </code>
120:      * @param bool $bUseAbsolutePath [optional]
121:      *         Flag to use absolute path (not used at the moment)
122:      * @return string
123:      *         New build url
124:      */
125:     public function buildUrl(array $params, $bUseAbsolutePath = false) {
126:         ModRewriteDebugger::add($params, 'cUriBuilderMR::buildUrl() $params');
127:         $urlDebug = array();
128:         $urlDebug['in'] = $params;
129: 
130:         $url = self::_buildUrl($params);
131: 
132:         $urlPrefix = '';
133:         if ($bUseAbsolutePath) {
134:             $hmlPath = cRegistry::getFrontendUrl();
135:             $aComp = parse_url($hmlPath);
136:             $urlPrefix = $aComp['scheme'] . '://' . $aComp['host'];
137:             if (mr_arrayValue($aComp, 'port', '') !== '') {
138:                 $urlPrefix .= ':' . $aComp['port'];
139:             }
140:         }
141: 
142:         $this->sUrl = $urlPrefix . $url;
143: 
144:         $urlDebug['out'] = $this->sUrl;
145:         ModRewriteDebugger::add($urlDebug, 'cUriBuilderMR::buildUrl() in -> out');
146:     }
147: 
148:     /**
149:      * Builds the SEO-URL by analyzing passed arguments
150:      * (parameter value pairs).
151:      *
152:      * @param array $aParams
153:      *         Parameter array
154:      * @return string
155:      *         New build pretty url
156:      */
157:     private function _buildUrl(array $aParams) {
158:         // language should changed, set lang parameter
159:         if (isset($aParams['changelang'])) {
160:             $aParams['lang'] = $aParams['changelang'];
161:         }
162: 
163:         // build the query
164:         $sQuery = http_build_query($aParams);
165: 
166:         // get pretty url parts
167:         $oMRUrlStack = ModRewriteUrlStack::getInstance();
168:         $aPretty = $oMRUrlStack->getPrettyUrlParts('front_content.php?' . $sQuery);
169: 
170:         // get all non CONTENIDO related query parameter
171:         $sQuery = $this->_createUrlQueryPart($aParams);
172: 
173:         // some presettings of variables
174:         $aParts = array();
175: 
176:         // add client id/name if desired
177:         $param = $this->_getClientParameter($aParams);
178:         if ($param) {
179:             $aParts[] = $param;
180:         }
181: 
182:         // add language id/name if desired
183:         $param = $this->_getLanguageParameter($aParams);
184:         if ($param) {
185:             $aParts[] = $param;
186:         }
187: 
188:         // get path part of the url
189:         $sPath = $this->_getPath($aPretty);
190:         if ($sPath !== '') {
191:             $aParts[] = $sPath;
192:         }
193:         $sPath = implode('/', $aParts) . '/';
194: 
195:         // get pagename part of the url
196:         $sArticle = $this->_getArticleName($aPretty, $aParams);
197: 
198:         if ($sArticle !== '') {
199:             $sFileExt = $this->_aMrCfg['file_extension'];
200:         } else {
201:             $sFileExt = '';
202:         }
203: 
204:         $sPathAndArticle = $sPath . $sArticle . $sFileExt;
205: 
206:         // use lowercase url
207:         if ($this->_aMrCfg['use_lowercase_uri'] == 1) {
208:             $sPathAndArticle = strtolower($sPathAndArticle);
209:         }
210: 
211:         // $sUrl = $this->_aMrCfg['rootdir'] . $sPathAndArticle . $sQuery;
212:         $sUrl = $sPathAndArticle . $sQuery;
213: 
214:         // remove double or more join parameter
215:         $sUrl = mr_removeMultipleChars('/', $sUrl);
216:         if (substr($sUrl, -2) == '?=') {
217:             $sUrl = substr_replace($sUrl, '', -2);
218:         }
219: 
220:         // now convert CONTENIDO url to an AMR url
221:         $sUrl = ModRewriteUrlUtil::getInstance()->toModRewriteUrl($sUrl);
222: 
223:         // prepend rootdir as defined in config
224:         // $sUrl = $this->_aMrCfg['rootdir'] . $sUrl;
225:         // this version allows for multiple domains of a client
226:         $sUrl = self::getMultiClientRootDir($this->_aMrCfg['rootdir']) . $sUrl;
227: 
228:         // remove double slashes
229:         $sUrl = mr_removeMultipleChars('/', $sUrl);
230: 
231:         return $sUrl;
232:     }
233: 
234:     /**
235:      * Returns the defined rootdir.
236:      *
237:      * Allows for root dir being alternativly defined as path of setting
238:      * client/%frontend_path%.
239:      *
240:      * @param string $configuredRootDir
241:      *         defined rootdir
242:      * @return string
243:      */
244:     public static function getMultiClientRootDir($configuredRootDir) {
245: 
246:         // return cached rootdir if set
247:         if (isset(self::$_cachedRootDir)) {
248:             return self::$_cachedRootDir;
249:         }
250: 
251:         // get props of current client
252:         $props = cRegistry::getClient()->getProperties();
253:         // $props = cRegistry::getClient()->getPropertiesByType('client');
254: 
255:         // return rootdir as defined in AMR if client has no props
256:         if (!is_array($props)) {
257:             self::$_cachedRootDir = $configuredRootDir;
258:             return $configuredRootDir;
259:         }
260: 
261:         foreach ($props as $prop) {
262:             // skip props that are not of type 'client'
263:             if ($prop['type'] != 'client') {
264:                 continue;
265:             }
266: 
267:             // skip props whose name does not contain 'frontend_path'
268:             if (false === strstr($prop['name'], 'frontend_path')) {
269:                 continue;
270:             }
271: 
272:             // current host & path (HTTP_HOST & REQUEST_URI)
273:             $httpHost = $_SERVER['HTTP_HOST'];
274:             $httpPath = $_SERVER['REQUEST_URI'];
275: 
276:             // host & path of configured alternative URL
277:             $propHost = parse_url($prop['value'], PHP_URL_HOST);
278:             $propPath = parse_url($prop['value'], PHP_URL_PATH);
279: 
280:             // skip if http host does not equal configured host (allowing for
281:             // optional www)
282:             if ($propHost != $httpHost && ('www.' . $propHost) != $httpHost && $propHost != 'www.' . $httpHost) {
283:                 continue;
284:             }
285: 
286:             // skip if http path does not start with configured path
287:             if (0 !== strpos($httpPath, $propPath)) {
288:                 continue;
289:             }
290: 
291:             // return path as specified in client settings
292:             self::$_cachedRootDir = $propPath;
293:             return $propPath;
294:         }
295: 
296:         // return rootdir as defined in AMR
297:         self::$_cachedRootDir = $configuredRootDir;
298:         return $configuredRootDir;
299:     }
300: 
301:     /**
302:      * Loops through given parameter array and creates the query part of
303:      * the URL.
304:      *
305:      * All non CONTENIDO related parameters will be excluded from
306:      * composition.
307:      *
308:      * @param array $aArgs
309:      *         associative parameter array
310:      * @return string
311:      *         composed query part for the URL
312:      *         like '?foo=bar&amp;param=value'
313:      */
314:     private function _createUrlQueryPart(array $aArgs) {
315:         // set list of parameter which are to ignore while setting additional
316:         // parameter
317:         $aIgnoredParams = array(
318:             'idcat',
319:             'idart',
320:             'lang',
321:             'client',
322:             'idcatart',
323:             'idartlang'
324:         );
325:         if ($this->_aMrCfg['use_language'] == 1) {
326:             $aIgnoredParams[] = 'changelang';
327:         }
328:         if ($this->_aMrCfg['use_client'] == 1) {
329:             $aIgnoredParams[] = 'changeclient';
330:         }
331: 
332:         // collect additional non CONTENIDO related parameters
333:         $sQuery = '';
334:         foreach ($aArgs as $p => $v) {
335:             if (!in_array($p, $aIgnoredParams)) {
336:                 // $sQuery .= urlencode(urldecode($p)) . '=' .
337:                 // urlencode(urldecode($v)) . $this->_sAmp;
338:                 $p = urlencode(urldecode($p));
339:                 if (is_array($v)) {
340:                     // handle query parameter like foobar[0}=a&foobar[1]=b...
341:                     foreach ($v as $p2 => $v2) {
342:                         $p2 = urlencode(urldecode($p2));
343:                         $v2 = urlencode(urldecode($v2));
344:                         $sQuery .= $p . '[' . $p2 . ']=' . $v2 . $this->_sAmp;
345:                     }
346:                 } else {
347:                     $v = urlencode(urldecode($v));
348:                     $sQuery .= $p . '=' . $v . $this->_sAmp;
349:                 }
350:             }
351:         }
352:         if (strlen($sQuery) > 0) {
353:             $sQuery = '?' . substr($sQuery, 0, -strlen($this->_sAmp));
354:         }
355:         return $sQuery;
356:     }
357: 
358:     /**
359:      * Returns client id or name depending on settings.
360:      *
361:      * @param array $aArgs
362:      *         Additional arguments
363:      * @return mixed
364:      *         Client id, client name or NULL
365:      */
366:     private function _getClientParameter(array $aArgs) {
367:         global $client;
368: 
369:         // set client if desired
370:         if ($this->_aMrCfg['use_client'] == 1) {
371:             $iChangeClient = (isset($aArgs['changeclient'])) ? (int) $aArgs['changeclient'] : 0;
372:             $idclient = ($iChangeClient > 0) ? $iChangeClient : $client;
373:             if ($this->_aMrCfg['use_client_name'] == 1) {
374:                 return urlencode(ModRewrite::getClientName($idclient));
375:             } else {
376:                 return $idclient;
377:             }
378:         }
379:         return NULL;
380:     }
381: 
382:     /**
383:      * Returns language id or name depending on settings.
384:      *
385:      * @param array $aArgs
386:      *         Additional arguments
387:      * @return mixed
388:      *         Language id, language name or NULL
389:      */
390:     private function _getLanguageParameter(array $aArgs) {
391:         global $lang;
392: 
393:         // set language if desired
394:         if ($this->_aMrCfg['use_language'] == 1) {
395:             $iChangeLang = (isset($aArgs['changelang'])) ? (int) $aArgs['changelang'] : 0;
396:             $idlang = ($iChangeLang > 0) ? $iChangeLang : $lang;
397:             if ($this->_aMrCfg['use_language_name'] == 1) {
398:                 return urlencode(ModRewrite::getLanguageName($idlang));
399:             } else {
400:                 return $idlang;
401:             }
402:         }
403:         return NULL;
404:     }
405: 
406:     /**
407:      * Returns composed path of url (normally the category structure).
408:      *
409:      * @param array $aPretty
410:      *         Pretty url array
411:      * @return string
412:      *         Path
413:      */
414:     private function _getPath(array $aPretty) {
415:         $sPath = (isset($aPretty['urlpath'])) ? $aPretty['urlpath'] : '';
416: 
417:         // check start directory settings
418:         if ($this->_aMrCfg['startfromroot'] == 0 && (strlen($sPath) > 0)) {
419:             // splitt string in array
420:             $aCategories = explode('/', $sPath);
421: 
422:             // remove first category
423:             array_shift($aCategories);
424: 
425:             // implode array with categories to new string
426:             $sPath = implode('/', $aCategories);
427:         }
428: 
429:         return $sPath;
430:     }
431: 
432:     /**
433:      * Returns articlename depending on current setting.
434:      *
435:      * @param array $aPretty
436:      *         Pretty url array
437:      * @param array $aArgs
438:      *         Additional arguments
439:      * @return string
440:      *         Articlename
441:      */
442:     private function _getArticleName(array $aPretty, array $aArgs) {
443:         $sArticle = (isset($aPretty['urlname'])) ? $aPretty['urlname'] : '';
444: 
445:         $iIdCat = (isset($aArgs['idcat'])) ? (int) $aArgs['idcat'] : 0;
446:         $iIdCatLang = (isset($aArgs['idcatlang'])) ? (int) $aArgs['idcatlang'] : 0;
447:         $iIdCatArt = (isset($aArgs['idcatart'])) ? (int) $aArgs['idcatart'] : 0;
448:         $iIdArt = (isset($aArgs['idart'])) ? (int) $aArgs['idart'] : 0;
449:         $iIdArtLang = (isset($aArgs['idartlang'])) ? (int) $aArgs['idartlang'] : 0;
450: 
451:         // category id was passed but not article id
452:         if (($iIdCat > 0 || $iIdCatLang > 0) && $iIdCatArt == 0 && $iIdArt == 0 && $iIdArtLang == 0) {
453:             $sArticle = '';
454:             if ($this->_aMrCfg['add_startart_name_to_url']) {
455:                 if ($this->_aMrCfg['default_startart_name'] !== '') {
456:                     // use default start article name
457:                     $sArticle = $this->_aMrCfg['default_startart_name'];
458:                 } else {
459:                     $sArticle = (isset($aPretty['urlname'])) ? $aPretty['urlname'] : '';
460:                 }
461:             } else {
462:                 // url is to create without article name
463:                 $sArticle = '';
464:             }
465:         }
466: 
467:         return $sArticle;
468:     }
469: }
470: 
CMS CONTENIDO 4.9.11 API documentation generated by ApiGen 2.8.0