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
  • Function
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * Mod Rewrite front_content.php controller. Does some preprocessing jobs, tries
  4:  * to set following variables, depending on mod rewrite configuration and if
  5:  * request part exists:
  6:  * - $client
  7:  * - $changeclient
  8:  * - $lang
  9:  * - $changelang
 10:  * - $idart
 11:  * - $idcat
 12:  *
 13:  * @package     Plugin
 14:  * @subpackage  ModRewrite
 15:  * @version     SVN Revision $Rev:$
 16:  * @id          $Id$:
 17:  * @author      Stefan Seifarth / stese
 18:  * @author      Murat Purc <murat@purc.de>
 19:  * @copyright   www.polycoder.de
 20:  * @copyright   four for business AG <www.4fb.de>
 21:  * @license     http://www.contenido.org/license/LIZENZ.txt
 22:  * @link        http://www.4fb.de
 23:  * @link        http://www.contenido.org
 24:  */
 25: 
 26: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 27: 
 28: /**
 29:  * Processes mod_rewrite related job for created new tree.
 30:  *
 31:  * Will be called by chain 'Contenido.Action.str_newtree.AfterCall'.
 32:  *
 33:  * @param   array  $data  Assoziative array with some values
 34:  * @return  array  Passed parameter
 35:  */
 36: function mr_strNewTree(array $data) {
 37:     global $lang;
 38: 
 39:     ModRewriteDebugger::log($data, 'mr_strNewTree $data');
 40: 
 41:     if ((int) $data['newcategoryid'] > 0) {
 42:         $mrCatAlias = (trim($data['categoryalias']) !== '') ? trim($data['categoryalias']) : trim($data['categoryname']);
 43:         // set new urlname - because original set urlname isn''t validated for double entries in same parent category
 44:         ModRewrite::setCatWebsafeName($mrCatAlias, $data['newcategoryid'], $lang);
 45:         ModRewrite::setCatUrlPath($data['newcategoryid'], $lang);
 46:     }
 47: 
 48:     return $data;
 49: }
 50: 
 51: /**
 52:  * Processes mod_rewrite related job for created new category.
 53:  *
 54:  * Will be called by chain 'Contenido.Action.str_newcat.AfterCall'.
 55:  *
 56:  * @param   array  $data  Assoziative array with some values
 57:  * @return  array  Passed parameter
 58:  */
 59: function mr_strNewCategory(array $data) {
 60:     global $lang;
 61: 
 62:     ModRewriteDebugger::log($data, 'mr_strNewCategory $data');
 63: 
 64:     if ((int) $data['newcategoryid'] > 0) {
 65:         $mrCatAlias = (trim($data['categoryalias']) !== '') ? trim($data['categoryalias']) : trim($data['categoryname']);
 66:         // set new urlname - because original set urlname isn''t validated for double entries in same parent category
 67:         ModRewrite::setCatWebsafeName($mrCatAlias, $data['newcategoryid'], $lang);
 68:         ModRewrite::setCatUrlPath($data['newcategoryid'], $lang);
 69:     }
 70: 
 71:     return $data;
 72: }
 73: 
 74: /**
 75:  * Processes mod_rewrite related job for renamed category
 76:  * 2010-02-01: and now all existing subcategories and modify their paths too...
 77:  * 2010-02-01: max 50 recursion level
 78:  *
 79:  * Will be called by chain 'Contenido.Action.str_renamecat.AfterCall'.
 80:  *
 81:  * @param   array  $data  Assoziative array with some values
 82:  * @return  array  Passed parameter
 83:  */
 84: function mr_strRenameCategory(array $data) {
 85:     ModRewriteDebugger::log($data, 'mr_strRenameCategory $data');
 86: 
 87:     // hes 20100102
 88:     // maximal 50 recursion level
 89:     $recursion = (is_int($data['recursion'])) ? $data['recursion'] : 1;
 90:     if ($recursion > 50) {
 91:         exit("#20100201-1503: sorry - maximum function nesting level of " . $recursion . " reached");
 92:     }
 93: 
 94:     $mrCatAlias = (trim($data['newcategoryalias']) !== '') ? trim($data['newcategoryalias']) : trim($data['newcategoryname']);
 95:     if ($mrCatAlias != '') {
 96:         // set new urlname - because original set urlname isn''t validated for double entries in same parent category
 97:         ModRewrite::setCatWebsafeName($mrCatAlias, $data['idcat'], $data['lang']);
 98:         ModRewrite::setCatUrlPath($data['idcat'], $data['lang']);
 99:     }
100: 
101:     // hes 20100102
102:     // now dive into all existing subcategories and modify their paths too...
103:     $str = 'parentid=' . $data['idcat'];
104:     $oCatColl = new cApiCategoryCollection($str);
105: 
106:     while ($oCat = $oCatColl->next()) {
107:         // hes 20100102
108:         $str = 'idcat=' . $oCat->get('idcat') . ' AND idlang=' . (int) $data['lang'];
109:         $oCatLanColl = new cApiCategoryLanguageCollection($str);
110:         if ($oCatLan = $oCatLanColl->next()) {
111:             // hes 20100102
112:             $childData = array(
113:                 'idcat' => $oCat->get('idcat'),
114:                 'lang' => (int) $data['lang'],
115:                 'newcategoryname' => $oCatLan->get('name'),
116:                 'newcategoryalias' => $oCatLan->get('urlname'),
117:                 'recursion' => $recursion + 1
118:             );
119: 
120:             $resData = mr_strRenameCategory($childData);
121:         }
122:     }
123: 
124:     return $data;
125: }
126: 
127: /**
128:  * Processes mod_rewrite related job after moving a category up.
129:  *
130:  * Will be called by chain 'Contenido.Action.str_moveupcat.AfterCall'.
131:  *
132:  * @todo  do we really need processing of the category? there is no mr relevant data
133:  *        changes while moving the category on same level, level and name won't change
134:  *
135:  * @param   int  $idcat  Category id
136:  * @return  int  Category id
137:  */
138: function mr_strMoveUpCategory($idcat) {
139:     ModRewriteDebugger::log($idcat, 'mr_strMoveUpCategory $idcat');
140: 
141:     // category check
142:     $cat = new cApiCategory((int) $idcat);
143:     if (!$cat->get('preid')) {
144:         return;
145:     }
146: 
147:     // get all cat languages
148:     $aIdLang = ModRewrite::getCatLanguages($idcat);
149: 
150:     // update ...
151:     foreach ($aIdLang as $iIdLang) {
152:         // get urlname
153:         $sCatname = ModRewrite::getCatName($idcat, $iIdLang);
154:         // set new urlname - because original set urlname isn't validated for double entries in same parent category
155:         ModRewrite::setCatWebsafeName($sCatname, $idcat, $iIdLang);
156:     }
157: 
158:     return $idcat;
159: }
160: 
161: /**
162:  * Processes mod_rewrite related job after moving a category down.
163:  *
164:  * Will be called by chain 'Contenido.Action.str_movedowncat.AfterCall'.
165:  *
166:  * @todo  do we really need processing of the category? there is no mr relevant data
167:  *        changes while moving the category on same level, level and name won't change
168:  *
169:  * @param   int  $idcat  Id of category beeing moved down
170:  * @return  int  Category id
171:  */
172: function mr_strMovedownCategory($idcat) {
173:     ModRewriteDebugger::log($idcat, 'mr_strMovedownCategory $idcat');
174: 
175:     // category check
176:     $cat = new cApiCategory((int) $idcat);
177:     if (!$cat->get('id')) {
178:         return;
179:     }
180: 
181:     // get all cat languages
182:     $aIdLang = ModRewrite::getCatLanguages($idcat);
183:     // update ...
184:     foreach ($aIdLang as $iIdLang) {
185:         // get urlname
186:         $sCatname = ModRewrite::getCatName($idcat, $iIdLang);
187:         // set new urlname - because original set urlname isn't validated for double entries in same parent category
188:         ModRewrite::setCatWebsafeName($sCatname, $idcat, $iIdLang);
189:     }
190: 
191:     return $idcat;
192: }
193: 
194: /**
195:  * Processes mod_rewrite related job after moving a category subtree.
196:  *
197:  * Will be called by chain 'Contenido.Action.str_movesubtree.AfterCall'.
198:  *
199:  * @param   array  $data  Assoziative array with some values
200:  * @return  array  Passed parameter
201:  */
202: function mr_strMoveSubtree(array $data) {
203:     ModRewriteDebugger::log($data, 'mr_strMoveSubtree $data');
204: 
205:     // category check
206:     if ((int) $data['idcat'] <= 0) {
207:         return;
208:     }
209: 
210:     // next category check
211:     $cat = new cApiCategory($data['idcat']);
212:     if (!$cat->get('idcat')) {
213:         return;
214:     }
215: 
216:     // get all cat languages
217:     $aIdLang = ModRewrite::getCatLanguages($data['idcat']);
218:     // update all languages
219:     foreach ($aIdLang as $iIdLang) {
220:         // get urlname
221:         $sCatname = ModRewrite::getCatName($data['idcat'], $iIdLang);
222:         // set new urlname - because original set urlname isn't validated for double entries in same parent category
223:         ModRewrite::setCatWebsafeName($sCatname, $data['idcat'], $iIdLang);
224:         ModRewrite::setCatUrlPath($data['idcat'], $iIdLang);
225:     }
226: 
227:     // now dive into all existing subcategories and modify their paths too...
228:     $oCatColl = new cApiCategoryCollection('parentid=' . $data['idcat']);
229:     while ($oCat = $oCatColl->next()) {
230:         mr_strMoveSubtree(array('idcat' => $oCat->get('idcat')));
231:     }
232: 
233:     return $data;
234: }
235: 
236: /**
237:  * Processes mod_rewrite related job after copying a category subtree.
238:  *
239:  * Will be called by chain 'Contenido.Category.strCopyCategory'.
240:  *
241:  * @param   array  $data  Assoziative array with some values
242:  * @return  array  Passed parameter
243:  */
244: function mr_strCopyCategory(array $data) {
245:     ModRewriteDebugger::log($data, 'mr_strCopyCategory $data');
246: 
247:     $idcat = (int) $data['newcat']->get('idcat');
248:     if ($idcat <= 0) {
249:         return $data;
250:     }
251: 
252:     // get all cat languages
253:     $aIdLang = ModRewrite::getCatLanguages($idcat);
254:     // update ...
255:     foreach ($aIdLang as $iIdLang) {
256:         // get urlname
257:         $sCatname = ModRewrite::getCatName($idcat, $iIdLang);
258:         // set new urlname - because original set urlname isn't validated for double entries in same parent category
259:         ModRewrite::setCatWebsafeName($sCatname, $idcat, $iIdLang);
260:         ModRewrite::setCatUrlPath($idcat, $iIdLang);
261:     }
262: }
263: 
264: /**
265:  * Processes mod_rewrite related job during structure synchronisation process,
266:  * sets the urlpath of current category.
267:  *
268:  * Will be called by chain 'Contenido.Category.strSyncCategory_Loop'.
269:  *
270:  * @param   array  $data  Assoziative array with some values
271:  * @return  array  Passed parameter
272:  */
273: function mr_strSyncCategory(array $data) {
274:     ModRewriteDebugger::log($data, 'mr_strSyncCategory $data');
275:     ModRewrite::setCatUrlPath($data['idcat'], $data['idlang']);
276:     return $data;
277: }
278: 
279: /**
280:  * Processes mod_rewrite related job for saved articles (new or modified article).
281:  *
282:  * Will be called by chain 'Contenido.Action.con_saveart.AfterCall'.
283:  *
284:  * @param   array  $data  Assoziative array with some article properties
285:  * @return  array  Passed parameter
286:  */
287: function mr_conSaveArticle(array $data) {
288:     global $tmp_firstedit, $client;
289: 
290:     ModRewriteDebugger::log($data, 'mr_conSaveArticle $data');
291: 
292:     if ((int) $data['idart'] == 0) {
293:         return $data;
294:     }
295: 
296:     if (strlen(trim($data['urlname'])) == 0) {
297:         $data['urlname'] = $data['title'];
298:     }
299: 
300:     if (1 == $tmp_firstedit) {
301:         // new article
302:         $aLanguages = getLanguagesByClient($client);
303: 
304:         foreach ($aLanguages as $iLang) {
305:             ModRewrite::setArtWebsafeName($data['urlname'], $data['idart'], $iLang, $data['idcat']);
306:         }
307:     } else {
308:         // modified article
309:         $aArticle = ModRewrite::getArtIdByArtlangId($data['idartlang']);
310: 
311:         if (isset($aArticle['idart']) && isset($aArticle['idlang'])) {
312:             ModRewrite::setArtWebsafeName($data['urlname'], $aArticle['idart'], $aArticle['idlang'], $data['idcat']);
313:         }
314:     }
315: 
316:     return $data;
317: }
318: 
319: /**
320:  * Processes mod_rewrite related job for articles beeing moved.
321:  *
322:  * Will be called by chain 'Contenido.Article.conMoveArticles_Loop'.
323:  *
324:  * @param   array  $data  Assoziative array with record entries
325:  * @return  array  Loop through of arguments
326:  */
327: function mr_conMoveArticles($data) {
328:     ModRewriteDebugger::log($data, 'mr_conMoveArticles $data');
329: 
330:     // too defensive but secure way
331:     if (!is_array($data)) {
332:         return $data;
333:     } elseif (!isset($data['idartlang'])) {
334:         return $data;
335:     } elseif (!isset($data['idart'])) {
336:         return $data;
337:     }
338: 
339:     $arr_art = ModRewrite::getArtIds($data['idartlang']);
340:     if (count($arr_art) == 2) {
341:         ModRewrite::setArtWebsafeName($arr_art["urlname"], $data['idart'], $arr_art["idlang"]);
342:     }
343: 
344:     return $data;
345: }
346: 
347: /**
348:  * Processes mod_rewrite related job for duplicated articles.
349:  *
350:  * Will be called by chain 'Contenido.Article.conCopyArtLang_AfterInsert'.
351:  *
352:  * @param   array  $data  Assoziative array with record entries
353:  * @return  array  Loop through of arguments
354:  */
355: function mr_conCopyArtLang($data) {
356:     ModRewriteDebugger::log($data, 'mr_conCopyArtLang $data');
357: 
358:     // too defensive but secure way
359:     if (!is_array($data)) {
360:         return $data;
361:     } elseif (!isset($data['title'])) {
362:         return $data;
363:     } elseif (!isset($data['idart'])) {
364:         return $data;
365:     } elseif (!isset($data['idlang'])) {
366:         return $data;
367:     }
368: 
369:     ModRewrite::setArtWebsafeName($data['title'], $data['idart'], $data['idlang']);
370: 
371:     return $data;
372: }
373: 
374: /**
375:  * Processes mod_rewrite related job for synchronized articles.
376:  *
377:  * Will be called by chain 'Contenido.Article.conSyncArticle_AfterInsert'.
378:  *
379:  * @param   array  $data  Assoziative array with record entries as follows:
380:  * <code>
381:  * array(
382:  *     'src_art_lang'  => Recordset (assoziative array) of source item from con_art_lang table
383:  *     'dest_art_lang' => Recordset (assoziative array) of inserted destination item from con_art_lang table
384:  * );
385:  * </code>
386:  *
387:  * @return  array  Loop through of argument
388:  */
389: function mr_conSyncArticle($data) {
390:     ModRewriteDebugger::log($data, 'mr_conSyncArticle $data');
391: 
392:     // too defensive but secure way
393:     if (!is_array($data)) {
394:         return $data;
395:     } elseif (!isset($data['src_art_lang']) || !is_array($data['src_art_lang'])) {
396:         return $data;
397:     } elseif (!isset($data['dest_art_lang']) || !is_array($data['dest_art_lang'])) {
398:         return $data;
399:     } elseif (!isset($data['dest_art_lang']['idart'])) {
400:         return $data;
401:     } elseif (!isset($data['dest_art_lang']['idlang'])) {
402:         return $data;
403:     }
404: 
405:     if (!isset($data['src_art_lang']['urlname'])) {
406:         $artLang = new cApiArticleLanguage($data['src_art_lang']['idartlang']);
407:         $urlname = $artLang->get('urlname');
408:     } else {
409:         $urlname = $data['src_art_lang']['urlname'];
410:     }
411: 
412:     if ($urlname) {
413:         ModRewrite::setArtWebsafeName($urlname, $data['dest_art_lang']['idart'], $data['dest_art_lang']['idlang']);
414:     }
415: 
416:     return $data;
417: }
418: 
419: /**
420:  * Works as a wrapper for Contenido_Url.
421:  *
422:  * Will also be called by chain 'Contenido.Frontend.CreateURL'.
423:  *
424:  * @todo: Still exists bcause of downwards compatibility (some other modules/plugins are using it)
425:  *
426:  * @param   string  $url  URL to rebuild
427:  * @return  string        New URL
428:  */
429: function mr_buildNewUrl($url) {
430:     global $lang;
431: 
432:     ModRewriteDebugger::add($url, 'mr_buildNewUrl() in -> $url');
433: 
434:     $oUrl = cUri::getInstance();
435:     $aUrl = $oUrl->parse($url);
436: 
437:     // add language, if not exists
438:     if (!isset($aUrl['params']['lang'])) {
439:         $aUrl['params']['lang'] = $lang;
440:     }
441: 
442:     // build url
443:     $newUrl = $oUrl->build($aUrl['params']);
444: 
445:     // add existing fragment
446:     if (isset($aUrl['fragment'])) {
447:         $newUrl .= '#' . $aUrl['fragment'];
448:     }
449: 
450:     $arr = array(
451:         'in' => $url,
452:         'out' => $newUrl,
453:     );
454:     ModRewriteDebugger::add($arr, 'mr_buildNewUrl() in -> out');
455: 
456:     return $newUrl;
457: }
458: 
459: /**
460:  * Replaces existing ancors inside passed code, while rebuilding the urls.
461:  *
462:  * Will be called by chain 'Contenido.Content.conGenerateCode' or
463:  * 'Contenido.Frontend.HTMLCodeOutput' depening on mod_rewrite settings.
464:  *
465:  * @param   string  $code   Code to prepare
466:  * @return  string          New code
467:  */
468: function mr_buildGeneratedCode($code) {
469:     global $client, $cfgClient;
470: 
471:     ModRewriteDebugger::add($code, 'mr_buildGeneratedCode() in');
472: 
473:     // mod rewrite is activated
474:     if (ModRewrite::isEnabled()) {
475:         $sseStarttime = getmicrotime();
476: 
477:         // anchor hack
478:         $code = preg_replace_callback(
479:                 "/<a([^>]*)href\s*=\s*[\"|\'][\/]#(.?|.+?)[\"|\']([^>]*)>/i", create_function('$arr_matches', 'return ModRewrite::rewriteHtmlAnchor($arr_matches);'), $code
480:         );
481: 
482:         // remove fucking tinymce single quote entities:
483:         $code = str_replace("&#39;", "'", $code);
484: 
485:         // == IE hack with wrong base href interpretation
486:         // get base uri
487: //         $sBaseUri = cRegistry::getFrontendUrl();
488: //         $sBaseUri = cApiCecHook::execute("Contenido.Frontend.BaseHrefGeneration", $sBaseUri);
489: //         $code = preg_replace("/([\"|\'|=])upload\/(.?|.+?)([\"|\'|>])/ie", "stripslashes('\\1{$sBaseUri}upload/\\2\\3')", $code);
490: 
491:         $baseUri = cRegistry::getFrontendUrl();
492:         $baseUri = cApiCecHook::execute("Contenido.Frontend.BaseHrefGeneration", $baseUri);
493: 
494:         // CON-1389 modifier /e is deprecated as of PHP 5.5
495:         $code = preg_replace_callback("/([\"|\'|=])upload\/(.?|.+?)([\"|\'|>])/i", create_function('$m', '
496:                 return stripslashes($m[1] . "' . $baseUri . 'upload/" . $m[2] . $m[3]);'), $code);
497: 
498:         // define some preparations to replace /front_content.php & ./front_content.php
499:         // against front_content.php, because urls should start with front_content.php
500:         $aPattern = array(
501:             '/([\"|\'|=])\/front_content\.php(.?|.+?)([\"|\'|>])/i',
502:             '/([\"|\'|=])\.\/front_content\.php(.?|.+?)([\"|\'|>])/i'
503:         );
504: 
505:         $aReplace = array(
506:             '\1front_content.php\2\3',
507:             '\1front_content.php\2\3'
508:         );
509: 
510:         // perform the pre replacements
511:         $code = preg_replace($aPattern, $aReplace, $code);
512: 
513:         // create url stack object and fill it with found urls...
514:         $oMRUrlStack = ModRewriteUrlStack::getInstance();
515:         $oMRUrlStack->add('front_content.php');
516: 
517:         $matches = NULL;
518:         preg_match_all("/([\"|\'|=])front_content\.php(.?|.+?)([\"|\'|>])/i", $code, $matches, PREG_SET_ORDER);
519:         foreach ($matches as $val) {
520:             $oMRUrlStack->add('front_content.php' . $val[2]);
521:         }
522: 
523:         // ok let it beginn, start mod rewrite class
524:         $code = str_replace('"front_content.php"', '"' . mr_buildNewUrl('front_content.php') . '"', $code);
525:         $code = str_replace("'front_content.php'", "'" . mr_buildNewUrl('front_content.php') . "'", $code);
526:         $code = preg_replace_callback(
527:                 "/([\"|\'|=])front_content\.php(.?|.+?)([\"|\'|>])/i", create_function('$aMatches', 'return $aMatches[1] . mr_buildNewUrl("front_content.php" . $aMatches[2]) . $aMatches[3];'), $code
528:         );
529: 
530:         ModRewriteDebugger::add($code, 'mr_buildGeneratedCode() out');
531: 
532:         $sseEndtime = getmicrotime();
533:     } else {
534:         // anchor hack for non modrewrite websites
535:         $code = preg_replace_callback(
536:                 "/<a([^>]*)href\s*=\s*[\"|\'][\/]#(.?|.+?)[\"|\']([^>]*)>/i", create_function('$arr_matches', 'return ModRewrite::contenidoHtmlAnchor($arr_matches, $GLOBALS["is_XHTML"]);'), $code
537:         );
538:     }
539: 
540:     ModRewriteDebugger::add(($sseEndtime - $sseStarttime), 'mr_buildGeneratedCode() total spend time');
541: 
542:     if ($debug = mr_debugOutput(false)) {
543:         $code = cString::iReplaceOnce("</body>", $debug . "\n</body>", $code);
544:     }
545: 
546:     return $code;
547:     // print "\n\n<!-- modrewrite generation time: " . ($sseEndtime - $sseStarttime) . " seconds -->";
548: }
549: 
550: /**
551:  * Sets language of client, like done in front_content.php
552:  *
553:  * @param  int  $client  Client id
554:  */
555: function mr_setClientLanguageId($client) {
556:     global $lang, $load_lang, $cfg;
557: 
558:     if ((int) $lang > 0) {
559:         // there is nothing to do
560:         return;
561:     } elseif ($load_lang) {
562:         // use the first language of this client, load_client is set in __FRONTEND_PATH__/data/config/config.php
563:         $lang = $load_lang;
564:         return;
565:     }
566: 
567:     // try to get clients language from table
568:     $sql = "SELECT B.idlang FROM "
569:             . $cfg['tab']['clients_lang'] . " AS A, "
570:             . $cfg['tab']['lang'] . " AS B "
571:             . "WHERE "
572:             . "A.idclient='" . ((int) $client) . "' AND A.idlang=B.idlang"
573:             . "LIMIT 0,1";
574: 
575:     if ($aData = mr_queryAndNextRecord($sql)) {
576:         $lang = $aData['idlang'];
577:     }
578: }
579: 
580: /**
581:  * Loads Advanced Mod Rewrite configuration for passed client using serialized
582:  * file containing the settings.
583:  *
584:  * File is placed in /contenido/mod_rewrite/includes/and is named like
585:  * config.mod_rewrite_{client_id}.php.
586:  *
587:  * @param  int   $clientId     Id of client
588:  * @param  bool  $forceReload  Flag to force to reload configuration, e. g. after
589:  *                             done changes on it
590:  */
591: function mr_loadConfiguration($clientId, $forceReload = false) {
592:     global $cfg;
593:     static $aLoaded;
594: 
595:     $clientId = (int) $clientId;
596:     if (!isset($aLoaded)) {
597:         $aLoaded = array();
598:     } elseif (isset($aLoaded[$clientId]) && $forceReload == false) {
599:         return;
600:     }
601: 
602:     $mrConfig = mr_getConfiguration($clientId);
603: 
604:     if (is_array($mrConfig)) {
605:         // merge mod rewrite configuration with global cfg array
606:         $cfg = array_merge($cfg, $mrConfig);
607:     } else {
608:         // couldn't load configuration, set defaults
609:         $backendPath = cRegistry::getBackendPath();
610:         include_once($backendPath . $cfg['path']['plugins'] . 'mod_rewrite/includes/config.mod_rewrite_default.php');
611:     }
612: 
613:     $aLoaded[$clientId] = true;
614: }
615: 
616: /**
617:  * Returns the mod rewrite configuration array of an client.
618:  *
619:  * File is placed in /contenido/mod_rewrite/includes/and is named like
620:  * config.mod_rewrite_{client_id}.php.
621:  *
622:  * @param   int   $clientId     Id of client
623:  * @return  array|NULL
624:  */
625: function mr_getConfiguration($clientId) {
626:     global $cfg;
627: 
628:     $clientId = (int) $clientId;
629: 
630:     $backendPath = cRegistry::getBackendPath();
631: 
632:     $clientConfig = cRegistry::getClientConfig($clientId);
633:     $fePath = $clientConfig['path']['frontend'];
634: 
635:     $file = $fePath . 'data/config/' . CON_ENVIRONMENT . '/config.mod_rewrite.php';
636: 
637:     if (!is_file($file) || !is_readable($file)) {
638:         $file = $backendPath . $cfg['path']['plugins'] . 'mod_rewrite/includes/config.mod_rewrite_' . $clientId . '.php';
639:     }
640: 
641:     if (!is_file($file) || !is_readable($file)) {
642:         return NULL;
643:     }
644:     if ($content = cFileHandler::read($file)) {
645:         return unserialize($content);
646:     } else {
647:         return NULL;
648:     }
649: }
650: 
651: /**
652:  * Saves the mod rewrite configuration array of an client.
653:  *
654:  * File is placed in /contenido/mod_rewrite/includes/and is named like
655:  * config.mod_rewrite_{client_id}.php.
656:  *
657:  * @param   int    $clientId     Id of client
658:  * @param   array  $config       Configuration to save
659:  * @return  bool
660:  */
661: function mr_setConfiguration($clientId, array $config) {
662:     global $cfg;
663: 
664:     $clientId = (int) $clientId;
665: 
666:     $clientConfig = cRegistry::getClientConfig($clientId);
667:     $fePath = $clientConfig['path']['frontend'];
668: 
669:     $file = $fePath . 'data/config/' . CON_ENVIRONMENT . '/config.mod_rewrite.php';
670:     $result = cFileHandler::write($file, serialize($config));
671: 
672:     $file = $backendPath . $cfg['path']['plugins'] . 'mod_rewrite/includes/config.mod_rewrite_' . $clientId . '.php';
673:     if (is_file($file) && is_writeable($file)) {
674:         cFileHandler::remove($file, serialize($config));
675:     }
676: 
677:     return ($result) ? true : false;
678: }
679: 
680: /**
681:  * Includes the frontend controller script which parses the url and extacts
682:  * needed data like idcat, idart, lang and client from it.
683:  *
684:  * Will be called by chain 'Contenido.Frontend.AfterLoadPlugins' at front_content.php.
685:  *
686:  * @return  bool  Just a return value
687:  */
688: function mr_runFrontendController() {
689:     $iStartTime = getmicrotime();
690: 
691:     plugin_include('mod_rewrite', 'includes/config.plugin.php');
692: 
693:     if (ModRewrite::isEnabled() == true) {
694:         plugin_include('mod_rewrite', 'includes/front_content_controller.php');
695: 
696:         $totalTime = sprintf('%.4f', (getmicrotime() - $iStartTime));
697:         ModRewriteDebugger::add($totalTime, 'mr_runFrontendController() total time');
698:     }
699: 
700:     return true;
701: }
702: 
703: /**
704:  * Cleanups passed string from characters beeing repeated two or more times
705:  *
706:  * @param   string  $char    Character to remove
707:  * @param   string  $string  String to clean from character
708:  * @return  string  Cleaned string
709:  */
710: function mr_removeMultipleChars($char, $string) {
711:     while (strpos($string, $char . $char) !== false) {
712:         $string = str_replace($char . $char, $char, $string);
713:     }
714:     return $string;
715: }
716: 
717: /**
718:  * Returns amr related translation text
719:  *
720:  * @param   string  $key    The message id as string
721:  * @return  string  Related message
722:  */
723: function mr_i18n($key) {
724:     global $lngAMR;
725:     return (is_array($lngAMR) && isset($lngAMR[$key])) ? $lngAMR[$key] : 'n. a.';
726: }
727: 
728: ################################################################################
729: ### Some helper functions, which are not plugin specific
730: 
731: /**
732:  * Database query helper. Used to execute a select statement and to return the
733:  * result of first recordset.
734:  *
735:  * Minimizes following code:
736:  * <code>
737:  * // default way
738:  * $db  = cRegistry::getDb();
739:  * $sql = "SELECT * FROM foo WHERE bar='foobar'";
740:  * $db->query($sql);
741:  * $db->nextRecord();
742:  * $data = $db->getRecord();
743:  *
744:  * // new way
745:  * $sql  = "SELECT * FROM foo WHERE bar='foobar'";
746:  * $data = mr_queryAndNextRecord($sql);
747:  * </code>
748:  *
749:  * @param   string  $query  Query to execute
750:  * @return  mixed   Assoziative array including recordset or NULL
751:  */
752: function mr_queryAndNextRecord($query) {
753:     static $db;
754:     if (!isset($db)) {
755:         $db = cRegistry::getDb();
756:     }
757:     if (!$db->query($query)) {
758:         return NULL;
759:     }
760:     return ($db->nextRecord()) ? $db->getRecord() : NULL;
761: }
762: 
763: /**
764:  * Returns value of an array key (assoziative or indexed).
765:  *
766:  * Shortcut function for some ways to access to arrays:
767:  * <code>
768:  * // old way
769:  * if (is_array($foo) && isset($foo['bar']) && $foo['bar'] == 'yieeha') {
770:  *     // do something
771:  * }
772:  *
773:  * // new, more readable way:
774:  * if (mr_arrayValue($foo, 'bar') == 'yieeha') {
775:  *     // do something
776:  * }
777:  *
778:  * // old way
779:  * if (is_array($foo) && isset($foo['bar'])) {
780:  *     $jep = $foo['bar'];
781:  * } else {
782:  *     $jep = 'yummy';
783:  * }
784:  *
785:  * // new way
786:  * $jep = mr_arrayValue($foo, 'bar', 'yummy');
787:  * </code>
788:  *
789:  * @param   array  $array    The array
790:  * @param   mixed  $key      Position of an indexed array or key of an assoziative array
791:  * @param   mixed  $default  Default value to return
792:  * @return  mixed  Either the found value or the default value
793:  */
794: function mr_arrayValue($array, $key, $default = NULL) {
795:     if (!is_array($array)) {
796:         return $default;
797:     } elseif (!isset($array[$key])) {
798:         return $default;
799:     } else {
800:         return $array[$key];
801:     }
802: }
803: 
804: /**
805:  * Request cleanup function. Request data is allways tainted and must be filtered.
806:  * Pass the array to cleanup using several options.
807:  * Emulates array_walk_recursive().
808:  *
809:  * @param   mixed  $data     Data to cleanup
810:  * @param   array  $options  Default options array, provides only 'filter' key with several
811:  *                           filter functions which are to execute as follows:
812:  * <code>
813:  * $options['filter'] = array('trim', 'myFilterFunc');
814:  * </code>
815:  *                           If no filter functions are set, 'trim', 'strip_tags' and 'stripslashes'
816:  *                           will be used by default.
817:  *                           A userdefined function must accept the value as a parameter and must return
818:  *                           the filtered parameter, e. g.
819:  * <code>
820:  * function myFilter($data) {
821:  *    // do what you want with the data, e. g. cleanup of xss content
822:  *    return $data;
823:  * }
824:  * </code>
825:  *
826:  * @return  mixed  Cleaned data
827:  */
828: function mr_requestCleanup(&$data, $options = NULL) {
829:     if (!mr_arrayValue($options, 'filter')) {
830:         $options['filter'] = array('trim', 'strip_tags', 'stripslashes');
831:     }
832: 
833:     if (is_array($data)) {
834:         foreach ($data as $p => $v) {
835:             $data[$p] = mr_requestCleanup($v, $options);
836:         }
837:     } else {
838:         foreach ($options['filter'] as $filter) {
839:             if ($filter == 'trim') {
840:                 $data = trim($data);
841:             } elseif ($filter == 'strip_tags') {
842:                 $data = strip_tags($data);
843:             } elseif ($filter == 'stripslashes') {
844:                 $data = stripslashes($data);
845:             } elseif (function_exists($filter)) {
846:                 $data = call_user_func($filter, $data);
847:             }
848:         }
849:     }
850:     return $data;
851: }
852: 
853: /**
854:  * Minimalistic'n simple way to get request variables.
855:  *
856:  * Checks occurance in $_GET, then in $_POST. Uses trim() and strip_tags() to preclean data.
857:  *
858:  * @param   string  $key      Name of var to get
859:  * @param   mixed   $default  Default value to return
860:  * @return  mixed   The value
861:  */
862: function mr_getRequest($key, $default = NULL) {
863:     static $cache;
864:     if (!isset($cache)) {
865:         $cache = array();
866:     }
867:     if (isset($cache[$key])) {
868:         return $cache[$key];
869:     }
870:     if (isset($_GET[$key])) {
871:         $val = $_GET[$key];
872:     } elseif (isset($_POST[$key])) {
873:         $val = $_POST[$key];
874:     } else {
875:         $val = $default;
876:     }
877:     $cache[$key] = strip_tags(trim($val));
878:     return $cache[$key];
879: }
880: 
881: /**
882:  * Replaces calling of header method for redirects in front_content.php,
883:  * used during development.
884:  *
885:  * @param  $header  string Header value for redirect
886:  */
887: function mr_header($header) {
888:     header($header);
889:     return;
890: 
891:     $header = str_replace('Location: ', '', $header);
892:     echo '<html>
893:         <head></head>
894:         <body>
895:         <p><a href="' . $header . '">' . $header . '</a></p>';
896:     mr_debugOutput();
897:     echo '</body></html>';
898:     exit();
899: }
900: 
901: /**
902:  * Debug output only during development
903:  *
904:  * @param   bool  $print  Flag to echo the debug data
905:  * @return  mixed  Either the debug data, if parameter $print is set to true, or nothing
906:  */
907: function mr_debugOutput($print = true) {
908:     global $DB_Contenido_QueryCache;
909:     if (isset($DB_Contenido_QueryCache) && is_array($DB_Contenido_QueryCache) &&
910:             count($DB_Contenido_QueryCache) > 0) {
911:         ModRewriteDebugger::add($DB_Contenido_QueryCache, 'sql statements');
912: 
913:         // calculate total time consumption of queries
914:         $timeTotal = 0;
915:         foreach ($DB_Contenido_QueryCache as $pos => $item) {
916:             $timeTotal += $item['time'];
917:         }
918:         ModRewriteDebugger::add($timeTotal, 'sql total time');
919:     }
920: 
921:     $sOutput = ModRewriteDebugger::getAll();
922:     if ($print == true) {
923:         echo $sOutput;
924:     } else {
925:         return $sOutput;
926:     }
927: }
928: 
CMS CONTENIDO 4.9.8 API documentation generated by ApiGen 2.8.0