Source for file functions.mod_rewrite.php

Documentation is available at functions.mod_rewrite.php

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

Documentation generated on Sun, 21 Dec 2008 21:42:57 +0100 by phpDocumentor 1.4.1