Source for file class.modrewriteurlstack.php

Documentation is available at class.modrewriteurlstack.php

  1. <?php
  2. /**
  3.  * Includes mod rewrite url stack class.
  4.  *
  5.  * @author      Murat Purc <murat@purc.de>
  6.  * @copyright   © Murat Purc 2008
  7.  * @date        09.10.2008
  8.  * @package     Contenido
  9.  * @subpackage  ModRewrite
  10.  */
  11.  
  12.  
  13. defined('CON_FRAMEWORK'or die('Illegal call');
  14.  
  15.  
  16. /**
  17.  * Mod rewrite url stack class. Provides features to collect urls and to get the
  18.  * pretty path and names of categories/articles at one go.
  19.  *
  20.  * Main goal of this class is to collect urls and to get the urlpath and urlname
  21.  * of the related categories/articles at one go. This will reduce the queries
  22.  * against the database.
  23.  * Therefore the full advantage will be taken by rewriting the urls at codeoutput
  24.  * in front_content.php, where you will be able to collect all urls at once...
  25.  *
  26.  * Usage:
  27.  * <code>
  28.  * // get the instance
  29.  * $oMRUrlStack = ModRewriteUrlStack::getInstance();
  30.  *
  31.  * // add several urls to fill the stack
  32.  * $oMRUrlStack->add('front_content.php?idcat=123');
  33.  * $oMRUrlStack->add('front_content.php?idart=321');
  34.  * $oMRUrlStack->add('front_content.php?idcatart=213');
  35.  * $oMRUrlStack->add('front_content.php?idcatlang=213');
  36.  * $oMRUrlStack->add('front_content.php?idartlang=312');
  37.  *
  38.  * // now the first call will get the pretty path and names from database at one go
  39.  * $aPrettyParts = $oMRUrlStack->getPrettyUrlParts('front_content.php?idcat=123');
  40.  * echo $aPrettyParts['urlpath']; // something like 'Main-category-name/Category-name/Another-category-name/'
  41.  * echo $aPrettyParts['urlname']; // something like 'Name-of-an-article'
  42.  * </code>
  43.  *
  44.  * @author      Murat Purc <murat@purc.de>
  45.  * @copyright   © Murat Purc 2008
  46.  * @date        09.10.2008
  47.  * @package     Contenido
  48.  * @subpackage  ModRewrite
  49.  */
  50.  
  51.     /**
  52.      * Self instance
  53.      *
  54.      * @var  ModRewriteUrlStack 
  55.      */
  56.     private static $_instance;
  57.  
  58.     /**
  59.      * Database object
  60.      *
  61.      * @var  DB_Contenido 
  62.      */
  63.     private $_oDb;
  64.  
  65.     /**
  66.      * Array for urls
  67.      *
  68.      * @var  array 
  69.      */
  70.     private $_aUrls = array();
  71.  
  72.     /**
  73.      * Url stack array
  74.      *
  75.      * @var  array 
  76.      */
  77.     private $_aStack = array();
  78.  
  79.     /**
  80.      * Contenido related parameter array
  81.      *
  82.      * @var  array 
  83.      */
  84.     private $_aConParams = array(
  85.         'idcat' => 1'idart' => 1'lang' => 1'idcatlang' => 1'idcatart' => 1'idartlang' => 1
  86.     );
  87.  
  88.     /**
  89.      * Database tables array
  90.      *
  91.      * @var  array 
  92.      */
  93.     private $_aTab;
  94.  
  95.     /**
  96.      * Language id
  97.      *
  98.      * @var  int 
  99.      */
  100.     private $_idLang;
  101.  
  102.  
  103.     /**
  104.      * Constructor, sets some properties.
  105.      */
  106.     private function __construct({
  107.         $this->_oDb    = new DB_Contenido();
  108.         $this->_aTab   = mpGlobals::getInstance()->get('cfg/tab');
  109.         $this->_idLang = mpGlobals::getInstance()->get('lang');
  110.     }
  111.  
  112.  
  113.     /**
  114.      * Returns a instance of ModRewriteUrlStack (singleton implementation)
  115.      *
  116.      * @return  ModRewriteUrlStack 
  117.      */
  118.     public static function getInstance({
  119.         if (self::$_instance == null{
  120.             self::$_instance new ModRewriteUrlStack();
  121.         }
  122.         return self::$_instance;
  123.     }
  124.  
  125.  
  126.     /**
  127.      * Adds an url to the stack
  128.      *
  129.      * @param  string  Url, like front_content.php?idcat=123...
  130.      */
  131.     public function add($url{
  132.         $url  ModRewrite::urlPreClean($url);
  133.         if (isset($this->_aUrls[$url])) {
  134.             return;
  135.         }
  136.  
  137.         $aUrl $this->_extractUrl($url);
  138.  
  139.         // cleanup parameter
  140.         foreach ($aUrl['params'as $p => $v{
  141.             if (!isset($this->_aConParams[$p])) {
  142.                 unset($aUrl['params'][$p]);
  143.             }
  144.         }
  145.  
  146.         // add language id, if not available
  147.         if ((int) mr_arrayValue($aUrl['params']'lang'== 0{
  148.             $aUrl['params']['lang'$this->_idLang;
  149.         }
  150.  
  151.         $sStackId $this->_makeStackId($aUrl['params']);
  152.         $this->_aUrls[$url]       $sStackId;
  153.         $this->_aStack[$sStackIdarray('params' => $aUrl['params']);
  154.     }
  155.  
  156.  
  157.     /**
  158.      * Returns the pretty urlparts (only category path an article name) of the
  159.      * desired url.
  160.      *
  161.      * @param   string  Url, like front_content.php?idcat=123...
  162.      * @return  array   Assoziative array like
  163.      *  <code>
  164.      *  $arr['urlpath']
  165.      *  $arr['urlname']
  166.      *  </code>
  167.      */
  168.     public function getPrettyUrlParts($url{
  169.         if (!isset($this->_aUrls[$url])) {
  170.             $this->add($url);
  171.         }
  172.  
  173.         $sStackId $this->_aUrls[$url];
  174.         if (!isset($this->_aStack[$sStackId]['urlpath'])) {
  175.             $this->_chunkSetPrettyUrlParts();
  176.         }
  177.         $aPretty array(
  178.             'urlpath' => $this->_aStack[$sStackId]['urlpath'],
  179.             'urlname' => $this->_aStack[$sStackId]['urlname']
  180.         );
  181.         return $aPretty;
  182.     }
  183.  
  184.  
  185.     /**
  186.      * Extracts passed url using parse_urla and adds also the 'params' array to it
  187.      *
  188.      * @param   string  Url, like front_content.php?idcat=123...
  189.      * @return  array  Components containing result of parse_url with additional
  190.      *                  'params' array
  191.      */
  192.     private function _extractUrl($url{
  193.         $aUrl @parse_url($url);
  194.         if (isset($aUrl['query'])) {
  195.             $aUrl['query'str_replace('&amp;''&'$aUrl['query']);
  196.             parse_str($aUrl['query']$aUrl['params']);
  197.         }
  198.         if (!isset($aUrl['params']&& !is_array($aUrl['params'])) {
  199.             $aUrl['params'array();
  200.         }
  201.         return $aUrl;
  202.     }
  203.  
  204.  
  205.     /**
  206.      * Extracts article or category related parameter from passed params array
  207.      * and generates an identifier.
  208.      *
  209.      * @param   array   $aParams  Parameter array
  210.      * @return  string  Composed stack id
  211.      */
  212.     private function _makeStackId(array $aParams{
  213.         # idcatart
  214.         if ((int) mr_arrayValue($aParams'idart'0{
  215.             $sStackId 'idart_' $aParams['idart''_lang_' $aParams['lang'];
  216.         elseif ((int) mr_arrayValue($aParams'idartlang'0{
  217.             $sStackId 'idartlang_' $aParams['idartlang'];
  218.         elseif ((int) mr_arrayValue($aParams'idcatart'0{
  219.             $sStackId 'idcatart_' $aParams['idcatart''_lang_' $aParams['lang'];
  220.         elseif ((int) mr_arrayValue($aParams'idcat'0{
  221.             $sStackId 'idcat_' $aParams['idcat''_lang_' $aParams['lang'];
  222.         elseif ((int) mr_arrayValue($aParams'idcatlang'0{
  223.             $sStackId 'idcatlang_' $aParams['idcatlang'];
  224.         else {
  225.             $sStackId 'lang_' $aParams['lang'];
  226.         }
  227.         return $sStackId;
  228.     }
  229.  
  230.  
  231.     /**
  232.      * Main function to get the urlparts of urls.
  233.      *
  234.      * Composes the query by looping thru stored but non processed urls, executes
  235.      * the query and adds the (urlpath and urlname) result to the stack.
  236.      */
  237.     private function _chunkSetPrettyUrlParts({
  238.         // collect stack parameter to get urlpath and urlname
  239.         $aStack array();
  240.         foreach ($this->_aStack as $stackId => $item{
  241.             if (!isset($item['urlpath'])) {
  242.                 // pretty url is to create
  243.                 $aStack[$stackId$item;
  244.             }
  245.         }
  246.  
  247.         // now, it's time to compose the where clause of the query
  248.         $sWhere '';
  249.         foreach ($aStack as $stackId => $item{
  250.             $aP $item['params'];
  251.             if ((int) mr_arrayValue($aP'idart'0{
  252.                 $sWhere .= '(al.idart = ' $aP['idart'' AND al.idlang = ' $aP['lang'') OR ';
  253.             elseif ((int) mr_arrayValue($aP'idartlang'0{
  254.                 $sWhere .= '(al.idartlang = ' $aP['idartlang'') OR ';
  255.             elseif ((int) mr_arrayValue($aP'idcat'0{
  256.                 $sWhere .= '(cl.idcat = ' $aP['idcat'' AND cl.idlang = ' $aP['lang'' AND cl.startidartlang = al.idartlang) OR ';
  257.             elseif ((int) mr_arrayValue($aP'idcatart'0{
  258.                 $sWhere .= '(ca.idcatart = ' $aP['idcatart'' AND ca.idart = al.idart AND al.idlang = ' $aP['lang'') OR ';
  259.             elseif ((int) mr_arrayValue($aP'idcatlang'0{
  260.                 $sWhere .= '(cl.idcatlang = ' $aP['idcatlang'' AND cl.startidartlang = al.idartlang) OR ';
  261.             }
  262.         }
  263.         if ($sWhere == ''{
  264.             return;
  265.         }
  266.         $sWhere substr($sWhere0-4);
  267.         $sWhere str_replace(' OR '" OR \n"$sWhere);
  268.  
  269.         // compose query and execute it
  270.         $sql = <<<SQL
  271. SELECT
  272.         al.idartlang, al.idart, al.idlang, al.urlname, cl.idcatlang, cl.idcat,
  273.         cl.urlpath, ca.idcatart
  274. FROM
  275.         {$this->_aTab['art_lang']} AS al, {$this->_aTab['cat_lang']} AS cl, {$this->_aTab['cat_art']} AS ca
  276. WHERE
  277.         al.idart = ca.idart AND
  278.         ca.idcat = cl.idcat AND
  279.         al.idlang = cl.idlang AND
  280.         ( $sWhere )
  281. SQL;
  282.         Contenido_mpDebug::getInstance()->addDebug($sql'ModRewriteUrlStack->_chunkSetPrettyUrlParts() $sql');
  283.  
  284.         $aNewStack array();
  285.  
  286.         $this->_oDb->query($sql);
  287.         while ($this->_oDb->next_record()) {
  288.             $aRS $this->_oDb->Record;
  289.  
  290.             // check current recordset against existing entries in stack
  291.             foreach ($aStack as $stackId => $item{
  292.                 $bFound false;
  293.                 $aP $item['params'];
  294.                 if (mr_arrayValue($aP'idart'== $aRS['idart'&& mr_arrayValue($aP'lang'== $aRS['idlang']{
  295.                     $bFound true;
  296.                 elseif (mr_arrayValue($aP'idartlang'== $aRS['idartlang']{
  297.                     $bFound true;
  298.                 elseif (mr_arrayValue($aP'idcatart'== $aRS['idcatart'&& mr_arrayValue($aP'lang'== $aRS['idlang']{
  299.                     $bFound true;
  300.                 elseif (mr_arrayValue($aP'idcat'== $aRS['idcat'&& mr_arrayValue($aP'lang'== $aRS['idlang']{
  301.                     $bFound true;
  302.                 elseif (mr_arrayValue($aP'idcatlang'== $aRS['idcatlang']{
  303.                     $bFound true;
  304.                 }
  305.  
  306.                 if ($bFound{
  307.                     // matching entry found, add urlpath and urlname
  308.                     $aNewStack[$stackId]['urlpath'$aRS['urlpath'];
  309.                     $aNewStack[$stackId]['urlname'$aRS['urlname'];
  310.                     // remove from base stack
  311.                     unset($aStack[$stackId]);
  312.                     break;
  313.                 }
  314.  
  315.             }
  316.  
  317.         }
  318.         Contenido_mpDebug::getInstance()->addDebug($aNewStack'ModRewriteUrlStack->_chunkSetPrettyUrlParts() $aNewStack');
  319.  
  320.         // merge stack data
  321.         $this->_aStack array_merge($this->_aStack$aNewStack);
  322.     }
  323.  
  324. }

Documentation generated on Wed, 24 Dec 2008 21:44:04 +0100 by phpDocumentor 1.4.1