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