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

Documentation generated on Tue, 25 Nov 2008 22:07:38 +0100 by phpDocumentor 1.4.1