Source for file functions.mod_rewrite.php

Documentation is available at functions.mod_rewrite.php

  1. <?php
  2. /**
  3.  * Defines the 'modrewrite' related 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.  * mr_get_language_id()
  36.  *
  37.  * get language id from language name
  38.  * thanks to Nicolas Dickinson for multi
  39.  * Client/Language BugFix
  40.  *
  41.  * @param    string    language name
  42.  * @return integer    language id
  43.  */
  44. function mr_get_language_id $str_languagename ""$int_client {
  45.     global $cfg;
  46.  
  47.     $int_lang_id false;
  48.  
  49.     $sql "SELECT l.idlang
  50.            FROM " $cfg["tab"]["lang"" as l
  51.            LEFT JOIN " $cfg["tab"]["clients_lang"" AS cl ON l.idlang = cl.idlang
  52.            WHERE
  53.               cl.idclient = '". (int)$int_client "' AND
  54.               l.name = '" urldecode($str_languagename"'";
  55.     if ($aData mr_query_n_next_record($sql)) {
  56.         $int_lang_id $aData['idlang'];
  57.     }
  58.  
  59.     return $int_lang_id;
  60. }
  61.  
  62.  
  63. /**
  64.  * mr_get_client_id()
  65.  *
  66.  * get client id from client name
  67.  *
  68.  * @param      string    client name
  69.  * @return  integer   client id
  70.  */
  71. function mr_get_client_id $str_clientname "" {
  72.     global $cfg;
  73.  
  74.     $int_client_id false;
  75.  
  76.     $sql "SELECT idclient
  77.             FROM " $cfg["tab"]["clients""
  78.             WHERE name = '" urldecode($str_clientname"'";
  79.     if ($aData mr_query_n_next_record($sql)) {
  80.         $int_client_id $aData['idclient'];
  81.     }
  82.  
  83.     return $int_client_id;
  84. }
  85.  
  86.  
  87. /**
  88.  * mr_get_idart()
  89.  *
  90.  * get article id
  91.  *
  92.  * get recent article from websafe name tree
  93.  *
  94.  * @modified: 2005-09-11
  95.  * @param    string    Websafe name
  96.  * @param    integer    category id
  97.  * @return     integer    recent article id
  98.  */
  99. function mr_get_idart $str_artname ""$int_id 0$int_lang_id {
  100.     global $cfg;
  101.     static $db;
  102.  
  103.     $int_idart false;
  104.  
  105.     if (!isset($db)) {
  106.         $db new DB_Contenido;
  107.     }
  108.  
  109.     $str_where "";
  110.     // only article name were given
  111.     if ($int_id == 0{
  112.         // get all basic category ids with parentid=0
  113.         $sql "SELECT idcat FROM " $cfg["tab"]["cat"" WHERE parentid = '0'";
  114.         $db->query $sql );
  115.  
  116.         $arr_idcats array();
  117.         $arr_where array();
  118.  
  119.         while ($db->next_record()) {
  120.             $arr_idcats["idcat = '" $db->f("idcat""'";
  121.         }
  122.         $str_where " AND ( " join(" OR "$arr_idcats")";
  123.     else {
  124.         $str_where " AND ca.idcat = '$int_id'";
  125.     }
  126.  
  127.     $sql "SELECT al.idart
  128.             FROM " $cfg["tab"]["art_lang"" al
  129.             LEFT JOIN " $cfg["tab"]["cat_art"" ca
  130.     ON al.idart = ca.idart
  131.     WHERE al.urlname = '$str_artname'$str_where;
  132.  
  133.     if ($aData mr_query_n_next_record($sql)) {
  134.         $int_idart $aData['idart'];
  135.     }
  136.  
  137.     return $int_idart;
  138. }
  139.  
  140.  
  141.  
  142. // plugin Advanced Mod Rewrite - Murat Purc (aka xmurrix)
  143.  
  144. /**
  145.  * Processes mod_rewrite related job after moving a category up.
  146.  *
  147.  * Will be called as a action code from table con_actions.
  148.  *
  149.  * @param  int  $idcat  Id of category beeing moved up
  150.  */
  151. function mr_strMoveUpCategory($idcat{
  152.  
  153.     // category check
  154.     $cat new cApiCategory($idcat);
  155.     if (!$cat->get('preid')) {
  156.         return;
  157.     }
  158.  
  159.     // get all cat languages
  160.     $arr_idlang ModRewrite::get_cat_languages($idcat);
  161.  
  162.     // update ...
  163.     foreach ($arr_idlang as $int_idlang{
  164.         // get urlname
  165.         $str_catname ModRewrite::get_catname($idcat$int_idlang);
  166.         // set new urlname - because original set urlname isn't validated for double entries in same parent category
  167.         ModRewrite::set_category($str_catname$idcat$int_idlang);
  168.     }
  169.  
  170. }
  171.  
  172.  
  173. /**
  174.  * Processes mod_rewrite related job after moving a category down.
  175.  *
  176.  * Will be called as a action code from table con_actions.
  177.  *
  178.  * @param  int  $idcat  Id of category beeing moved down
  179.  */
  180. function mr_strMoveDownCategory($idcat{
  181.  
  182.     // category check
  183.     $cat new cApiCategory($idcat);
  184.     if (!$cat->get('id')) {
  185.         return;
  186.     }
  187.  
  188.     // get all cat languages
  189.     $arr_idlang ModRewrite::get_cat_languages($idcat);
  190.     // update ...
  191.     foreach ($arr_idlang as $int_idlang{
  192.         // get urlname
  193.         $str_catname ModRewrite::get_catname($idcat$int_idlang);
  194.         // set new urlname - because original set urlname isn't validated for double entries in same parent category
  195.         ModRewrite::set_category($str_catname$idcat$int_idlang);
  196.     }
  197.  
  198. }
  199.  
  200.  
  201.  
  202. /**
  203.  * Processes mod_rewrite related job after moving a category subtree.
  204.  *
  205.  * Will be called as a action code from table con_actions.
  206.  *
  207.  * @param  int  $idcat  Id of category where the subtree has beeen moved
  208.  */
  209. function mr_strMoveSubtree($idcat{
  210.     // category check
  211.     $cat new cApiCategory($idcat);
  212.     if (!$cat->get('id')) {
  213.         return;
  214.     }
  215.  
  216.     // get all cat languages
  217.     $arr_idlang ModRewrite::get_cat_languages($idcat);
  218.     // update ...
  219.     foreach ($arr_idlang as $int_idlang{
  220.         // get urlname
  221.         $str_catname ModRewrite::get_catname($idcat$int_idlang);
  222.         // set new urlname - because original set urlname isn't validated for double entries in same parent category
  223.         ModRewrite::set_category($str_catname$idcat$int_idlang);
  224.     }
  225. }
  226.  
  227.  
  228. /**
  229.  * Processes mod_rewrite related job after editing a article first time.
  230.  *
  231.  * Will be called as a action code from table con_actions.
  232.  *
  233.  * @param  int  $newIdart  Id of new edited article
  234.  */
  235. function mr_conEditFirstTime($newIdart{
  236.     global $client$title$urlname$idcat;
  237.  
  238.     if (strlen(trim($urlname)) == 0{
  239.         $urlname $title;
  240.     }
  241.  
  242.     $a_languages getLanguagesByClient($client);
  243.  
  244.     foreach ($a_languages as $tmp_lang{
  245.         ModRewrite::set_article($urlname$newIdart$tmp_lang$idcat);
  246.     }
  247. }
  248.  
  249.  
  250. /**
  251.  * Processes mod_rewrite related job after editing a article.
  252.  *
  253.  * Will be called as a action code from table con_actions.
  254.  *
  255.  * @param  int  $idart  Id of edited article
  256.  */
  257. function mr_conEditArt($idart){
  258.     global $urlname$title$idartlang$idcat;
  259.  
  260.     if (strlen(trim($urlname)) == 0{
  261.         $urlname $title;
  262.     }
  263.  
  264.     $arr_art ModRewrite::get_id_from_idartlang($idartlang);
  265.     if (isset($arr_art['idart']&& isset($arr_art['idlang'])) {
  266.         ModRewrite::set_article($urlname$arr_art['idart']$arr_art['idlang']$idcat);
  267.     }
  268. }
  269.  
  270.  
  271. /**
  272.  * Processes mod_rewrite related job for articles beeing moved.
  273.  *
  274.  * Will be called by chain 'Contenido.Article.conMoveArticles_Loop'.
  275.  *
  276.  * @param   array  $param  Assoziative array with record entries
  277.  * @return  array  Loop through of arguments
  278.  */
  279. function mr_conMoveArticles($param){
  280.     // too defensive but secure way
  281.     if (!is_array($param)) {
  282.         return $param;
  283.     elseif (!isset($param['idartlang'])) {
  284.         return $param;
  285.     elseif (!isset($param['idart'])) {
  286.         return $param;
  287.     }
  288.  
  289.     $arr_art ModRewrite::get_artids($param['idartlang']);
  290.     if (count($arr_art== 2{
  291.         ModRewrite::set_article($arr_art["urlname"]$param['idart']$arr_art["idlang"]);
  292.     }
  293.  
  294.     return $param;
  295. }
  296.  
  297.  
  298. /**
  299.  * Processes mod_rewrite related job for duplicated articles.
  300.  *
  301.  * Will be called by chain 'Contenido.Article.conCopyArtLang_AfterInsert'.
  302.  *
  303.  * @param   array  $param  Assoziative array with record entries
  304.  * @return  array  Loop through of arguments
  305.  */
  306. function mr_conCopyArtLang($param{
  307.     // too defensive but secure way
  308.     if (!is_array($param)) {
  309.         return $param;
  310.     elseif (!isset($param['title'])) {
  311.         return $param;
  312.     elseif (!isset($param['idart'])) {
  313.         return $param;
  314.     elseif (!isset($param['idlang'])) {
  315.         return $param;
  316.     }
  317.  
  318.     ModRewrite::set_article($param['title']$param['idart']$param['idlang']);
  319.  
  320.     return $param;
  321. }
  322.  
  323.  
  324. /**
  325.  * Processes mod_rewrite related job for synchronized articles.
  326.  *
  327.  * Will be called by chain 'Contenido.Article.conSyncArticle_AfterInsert'.
  328.  *
  329.  * @param   array  $param  Assoziative array with record entries as follows:
  330.  *  <code>
  331.  *  array(
  332.  *      'src_art_lang'  => Recordset (assoziative array) of source item from con_art_lang table
  333.  *      'dest_art_lang' => Recordset (assoziative array) of inserted destination item from con_art_lang table
  334.  *  );
  335.  *  </code>
  336.  *
  337.  * @return  array  Loop through of argument
  338.  */
  339. function mr_conSyncArticle($param){
  340.     // too defensive but secure way
  341.     if (!is_array($param)) {
  342.         return $param;
  343.     elseif (!isset($param['src_art_lang']|| !is_array($param['src_art_lang'])) {
  344.         return $param;
  345.     elseif (!isset($param['dest_art_lang']|| !is_array($param['dest_art_lang'])) {
  346.         return $param;
  347.     elseif (!isset($param['dest_art_lang']['idart'])) {
  348.         return $param;
  349.     elseif (!isset($param['dest_art_lang']['idlang'])) {
  350.         return $param;
  351.     }
  352.  
  353.     if (!isset($param['src_art_lang']['urlname'])) {
  354.         $artLang new cApiArticleLanguage($param['src_art_lang']['idartlang']);
  355.         $urlname $artLang->get('urlname');
  356.     else {
  357.         $urlname $param['src_art_lang']['urlname'];
  358.     }
  359.  
  360.     if ($urlname{
  361.         ModRewrite::set_article($urlname$param['dest_art_lang']['idart']$param['dest_art_lang']['idlang']);
  362.     }
  363.  
  364.     return $param;
  365. }
  366.  
  367.  
  368.  
  369. /**
  370.  * mr_build_new_url()
  371.  *
  372.  * Works as a wrapper for creation of urls using Contenido_UrlBuilder_MR.
  373.  *
  374.  * Will be called by chain 'Contenido.Frontend.CreateURL'.
  375.  *
  376.  * @deprecated  Some parts of the function are replaced against new Url building
  377.  *               logic.
  378.  *
  379.  * @param   string  $url  URL to rebuild
  380.  * @return  string        New URL
  381.  */
  382. function mr_build_new_url($url{
  383.  
  384. // NOTE: try to use new way of url building
  385. /*
  386.     // TODO: Usage of ContenidoUrl class is not fully discussed!
  387.     static $notFirstCall;
  388.     if (!isset($notFirstCall)) {
  389.         $GLOBALS['cfg']['url_builder'] = array(
  390.             'classname' => 'Contenido_UrlBuilder_MR',
  391.             'where'     => 'plugins',
  392.             'what'      => 'mod_rewrite/classes/Contenido_UrlBuilder_MR.class.php'
  393.         );
  394.         cInclude('classes', 'mp/ContenidoUrl.class.php');
  395.  
  396.     }
  397.     $newUrl = ContenidoUrl::build($url);
  398.     return $newUrl;
  399. */
  400.  
  401.  
  402.     // TODO: Use this untill the code above is not cleared up
  403.     static $mrUrlBuilder;
  404.     if (!isset($mrUrlBuilder)) {
  405.         cInclude('plugins''mod_rewrite/classes/Contenido_UrlBuilder_MR.class.php');
  406.         $mrUrlBuilder Contenido_UrlBuilder_MR::getInstance();
  407.     }
  408.  
  409.     $mrUrlBuilder->buildUrl(array($url));
  410.     $newUrl $mrUrlBuilder->getUrl();
  411.  
  412.     $urlDebug['in']  $url;
  413.     $urlDebug['out'$newUrl;
  414.     $GLOBALS['mpDebug']->addDebug($urlDebug'mr_build_new_url() in -> out');
  415.  
  416.     return $newUrl;
  417.  
  418.  
  419. /*
  420.     // the old code 4 url building
  421.  
  422.     global $cfg;
  423.     static $isXHTML;
  424.     if (!isset($isXHTML)) {
  425.         $isXHTML = (getEffectiveSetting('generator', 'xhtml', 'false') == 'false') ? false : true;
  426.     }
  427.  
  428.     $urlDebug['in'] = $url;
  429.  
  430.     // cleanup any existing & entities
  431.     $url = str_replace('&amp;', '&', $url);
  432.  
  433.     if ($cfg['mod_rewrite']['use'] == 1) {
  434.  
  435.         // now a little hack to replace occuring index_controller.php against
  436.         // front_content.php. This happens using $auth->url()/$auth->purl()
  437.         // which composes the URL using $PHP_SELF
  438.         if (strpos($url, 'index_controller.php') !== false) {
  439.             $url = str_replace('index_controller.php', 'front_content.php', $url);
  440.  
  441.             // self_url returns url including absoute path from root (/cms/foobar.php)
  442.             // modify this...
  443.             $path = $GLOBALS['cfgClient'][$GLOBALS['client']]['path']['htmlpath'];
  444.             $comp = @parse_url($path);
  445.             if (isset($comp['path']) && (strpos($url, $comp['path']) === 0)) {
  446.                 $url = substr($url, strlen($comp['path']));
  447.             }
  448.         }
  449.  
  450.         $aUrl = ModRewrite::get_client_full_url_parts($url);
  451.         if (preg_match("/^front_content\.php(.*|.+?)/i", $aUrl['url'], $arr_hits) == 1) {
  452.             $url = $aUrl['htmlpath'] . ModRewrite::build_new_url($arr_hits[1]);
  453.         } else {
  454.             $GLOBALS['mpDebug']->addDebug($url, 'mr_build_new_url() nomatch');
  455.         }
  456.     }
  457.  
  458.     // replace & against entity, if xhtml is to use
  459.     if ($isXHTML) {
  460.         $url = str_replace('&', '&amp;', $url);
  461.     }
  462.  
  463.     $urlDebug['out'] = $url;
  464.     $GLOBALS['mpDebug']->addDebug($urlDebug, 'mr_build_new_url() in -> out');
  465.     return $url;
  466. */
  467.  
  468. }
  469.  
  470.  
  471.  
  472. /**
  473.  * mr_build_generated_code()
  474.  *
  475.  * Replaces existing ancors inside passed code, while rebuilding the urls.
  476.  *
  477.  * Will be called by chain 'Contenido.Content.conGenerateCode' or
  478.  * 'Contenido.Frontend.HTMLCodeOutput' depening on mod_rewrite settings.
  479.  *
  480.  * @param   string  $code   Code to prepare
  481.  * @return  string          New code
  482.  */
  483. function mr_build_generated_code($code{
  484.     global $cfg;
  485.  
  486.     $GLOBALS['mpDebug']->addDebug($code'mr_build_generated_code() in');
  487.  
  488.     // mod rewrite is activated
  489.     if ($cfg['mod_rewrite']['use'== 1{
  490.         $sseStarttime getmicrotime();
  491.  
  492.         // edit 060603 - anchor hack
  493.         $code preg_replace_callback(
  494.             "/<a([^>]*)href\s*=\s*[\"|\'][\/]#(.?|.+?)[\"|\']([^>]*)>/i",
  495.             create_function('$arr_matches' 'return ModRewrite::rewrite_html_anchor($arr_matches);'),
  496.             $code
  497.         );
  498.  
  499.         // remove fucking tinymce single quote entities:
  500.         $code str_replace("&#39;""'"$code);
  501.  
  502.         // IE hack with wrong base href interpretation
  503.         $code preg_replace("/([\"|\'|=])upload\/(.?|.+?)([\"|\'|>])/ie""stripslashes('\\1${str_base_uri}upload/\\2\\3')"$code);
  504.  
  505.         // ok let it beginn, start mod rewrite class
  506.         $code preg_replace_callback(
  507.             "/([\"|\'|=])front_content\.php(.?|.+?)([\"|\'|>])/i",
  508.             create_function('$arr_matches' 'return $arr_matches[1] . mr_build_new_url("front_content.php" . $arr_matches[2]) . $arr_matches[3];'),
  509.             $code
  510.         );
  511.         $code preg_replace_callback(
  512.             "/([\"|\'|=])index_controller\.php(.?|.+?)([\"|\'|>])/i",
  513.             create_function('$arr_matches' 'return $arr_matches[1] . mr_build_new_url("front_content.php" . $arr_matches[2]) . $arr_matches[3];'),
  514.             $code
  515.         );
  516.  
  517.         $sseEndtime getmicrotime();
  518.     else {
  519.         // anchor hack for non modrewrite websites
  520.         $code preg_replace_callback(
  521.                     "/<a([^>]*)href\s*=\s*[\"|\'][\/]#(.?|.+?)[\"|\']([^>]*)>/i",
  522.         create_function('$arr_matches' 'return ModRewrite::contenido_html_anchor($arr_matches, $GLOBALS["is_XHTML"]);'),
  523.         $code
  524.         );
  525.     }
  526.  
  527.     $GLOBALS['mpDebug']->addDebug($code'mr_build_generated_code() out');
  528.  
  529.     return $code;
  530.     // print "\n\n<!-- modrewrite generation time: " . ($sseEndtime - $sseStarttime) . " seconds -->";
  531. }
  532.  
  533.  
  534. /**
  535.  * Sets language of client, like done in front_content.php
  536.  *
  537.  * @param  int  $client  Client id
  538.  */
  539. function mr_set_client_language($client{
  540.     if ($GLOBALS['lang'|| (int) $GLOBALS['lang'0{
  541.         // there is nothing to do
  542.         return;
  543.     }
  544.  
  545.     // use the first language of this client
  546.     if (isset($GLOBALS['load_lang'])) {
  547.         // load_client is set in frontend/config.php
  548.         $GLOBALS['lang'$GLOBALS['load_lang'];
  549.         return;
  550.     }
  551.  
  552.     // try to get clients language from table
  553.     $sql "SELECT B.idlang FROM
  554.                 ".$GLOBALS['cfg']['tab']['clients_lang']." AS A,
  555.                 ".$GLOBALS['cfg']['tab']['lang']." AS B
  556.             WHERE
  557.                 A.idclient='" ((int) $client"' AND
  558.                 A.idlang=B.idlang
  559.             LIMIT 0,1";
  560.  
  561.     if ($aData mr_query_n_next_record($sql)) {
  562.         $GLOBALS['lang'$aData['idlang'];
  563.     }
  564. }
  565.  
  566.  
  567. /**
  568.  * Loads Advanced Mod Rewrite configuration for passed client using serialized
  569.  * file containing the settings.
  570.  *
  571.  * File is placed in /contenido/mod_rewrite/includes/and is named like
  572.  * config.mod_rewrite_{client_id}.php.
  573.  *
  574.  *
  575.  * @param  int  $clientId  Id of client
  576.  */
  577. function mr_load_configuration($clientId{
  578.     global $cfg;
  579.     static $aLoaded;
  580.  
  581.     $clientId = (int) $clientId;
  582.     if (!isset($aLoaded)) {
  583.         $aLoaded array();
  584.     elseif (isset($aLoaded[$clientId])) {
  585.         return;
  586.     }
  587.  
  588.     $options['key'$cfg['path']['contenido'$cfg['path']['plugins''mod_rewrite/includes/config.mod_rewrite_' $clientId '.php';
  589.  
  590.     $config ConfigFactory::get('serializer'$options);
  591.     $mrConfig $config->get();
  592.     if (is_array($mrConfig)) {
  593.  
  594.         // merge mod rewrite configuration with global cfg array
  595.         $cfg array_merge($cfg$mrConfig);
  596.  
  597.     else {
  598.  
  599.         // couldn't load configuration, set defaults
  600.         include_once($cfg['path']['contenido'$cfg['path']['plugins''mod_rewrite/includes/config.mod_rewrite_default.php');
  601.  
  602.     }
  603.  
  604.     $aLoaded[$clientIdtrue;
  605.  
  606. }
  607.  
  608.  
  609. /**
  610.  * Database query helper. Used to execute a select statement and to return the result of first
  611.  * recordset.
  612.  *
  613.  * Minimizes following code:
  614.  * <code>
  615.  * // default way
  616.  * $db  = new DB_Contenido();
  617.  * $sql = "SELECT * FROM foo WHERE bar='foobar'";
  618.  * $db->query($sql);
  619.  * $db->next_record();
  620.  * $data = $db->Record;
  621.  *
  622.  * // new way
  623.  * $sql  = "SELECT * FROM foo WHERE bar='foobar'";
  624.  * $data = mr_query_n_next_record($sql);
  625.  * </code>
  626.  *
  627.  * @param   string  $query  Query to execute
  628.  * @return  mixed   Assoziative array including recordset or null
  629.  */
  630. function mr_query_n_next_record($query){
  631.     static $db;
  632.     if (!isset($db)) {
  633.         $db new DB_Contenido();
  634.     }
  635.     $db->query($query);
  636.     return ($db->next_record()) $db->Record null;
  637. }
  638.  
  639.  
  640. /**
  641.  * Returns value of an array key (assoziative or indexed).
  642.  *
  643.  * Shortcut function for some ways to access to arrays:
  644.  * <code>
  645.  * // old way
  646.  * if (is_array($foo) && isset($foo['bar']) && $foo['bar'] == 'yieeha') {
  647.  *     // do something
  648.  * }
  649.  *
  650.  * // new, more readable way:
  651.  * if (mr_arrayValue($foo, 'bar') == 'yieeha') {
  652.  *     // do something
  653.  * }
  654.  *
  655.  * // old way
  656.  * if (is_array($foo) && isset($foo['bar'])) {
  657.  *     $jep = $foo['bar'];
  658.  * } else {
  659.  *     $jep = 'yummy';
  660.  * }
  661.  *
  662.  * // new way
  663.  * $jep = mr_arrayValue($foo, 'bar', 'yummy');
  664.  * </code>
  665.  *
  666.  * @param   array  $array    The array
  667.  * @param   mixed  $key      Position of an indexed array or key of an assoziative array
  668.  * @param   mixed  $default  Default value to return
  669.  * @return  mixed  Either the found value or the default value
  670.  */
  671. function mr_arrayValue($array$key$default=null{
  672.     if (!is_array($array)) {
  673.         return $default;
  674.     elseif (!isset($array[$key])) {
  675.         return $default;
  676.     else {
  677.         return $array[$key];
  678.     }
  679. }
  680.  
  681.  
  682. /**
  683.  * Request cleanup function. Request data is allways tainted and must be filtered.
  684.  * Pass the array to cleanup using several options.
  685.  * Emulates array_walk_recursive().
  686.  *
  687.  * @param   mixed  $data     Data to cleanup
  688.  * @param   array  $options  Default options array, provides only 'filter' key with several
  689.  *                            filter functions which are to execute as follows:
  690.  *  <code>
  691.  *  $options['filter'] = array('trim', 'myFilterFunc');
  692.  *  </code>
  693.  *                            If no filter functions are set, 'trim', 'strip_tags' and 'stripslashes'
  694.  *                            will be used by default.
  695.  *                            A userdefined function must accept the value as a parameter and must return
  696.  *                            the filtered parameter, e. g.
  697.  *  <code>
  698.  *  function myFilter($data) {
  699.  *     // do what you want with the data, e. g. cleanup of xss content
  700.  *     return $data;
  701.  *  }
  702.  *  </code>
  703.  *
  704.  * @return  mixed  Cleaned data
  705.  */
  706. function mr_requestCleanup(&$data$options=null{
  707.     if (!mr_arrayValue($options'filter')) {
  708.         $options['filter'array('trim''strip_tags''stripslashes');
  709.     }
  710.  
  711.     if (is_array($data)) {
  712.         foreach ($data as $p => $v{
  713.             $data[$pmr_requestCleanup($v$options);
  714.         }
  715.     else {
  716.         foreach ($options['filter'as $filter{
  717.             if ($filter == 'trim'{
  718.                 $data trim($data);
  719.             elseif ($filter == 'strip_tags'{
  720.                 $data strip_tags($data);
  721.             elseif ($filter == 'stripslashes'{
  722.                 $data stripslashes($data);
  723.             elseif (function_exists($filer)) {
  724.                 $data call_user_func($filter$data);
  725.             }
  726.         }
  727.     }
  728.     return $data;
  729. }

Documentation generated on Sun, 03 Aug 2008 22:22:01 +0200 by phpDocumentor 1.4.0