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