Source for file Contenido_UrlBuilder_MR.class.php

Documentation is available at Contenido_UrlBuilder_MR.class.php

  1. <?php
  2. /**
  3.  * Project:
  4.  * Contenido Content Management System
  5.  *
  6.  * Description:
  7.  * Implementation of Contenido_UrlBuilder to build front_content.php URL
  8.  *
  9.  * Requirements:
  10.  * @con_php_req 5.0
  11.  *
  12.  * @package     Contenido
  13.  * @subpackage  ModRewrite
  14.  * @version     0.2
  15.  * @author      Murat Purc
  16.  * @copyright   © Murat Purc 2008
  17.  * @license     http://www.contenido.org/license/LIZENZ.txt
  18.  * @link        http://www.4fb.de
  19.  * @link        http://www.contenido.org
  20.  */
  21.  
  22.  
  23. if(!defined('CON_FRAMEWORK')) {
  24.     die('Illegal call');
  25. }
  26.  
  27.  
  28. cInclude('classes', 'UrlBuilder/Contenido_UrlBuilder.class.php');
  29. cInclude('classes', 'UrlBuilder/Contenido_UrlBuilderFactory.class.php');
  30.  
  31.  
  32. /**
  33.  * Class to build frontend urls for Advandced Mod Rewrite plugin.
  34.  * Extends abstract Contenido_UrlBuilder class and implements singleton pattern.
  35.  *
  36.  * Usage:
  37.  * <code>
  38.  * cInclude('classes', 'UrlBuilder/Contenido_UrlBuilder_MR.class.php');
  39.  * $url = 'front_content.php?idart=123';
  40.  * $mrUrlBuilder = Contenido_UrlBuilder_MR::getInstance();
  41.  * $mrUrlBuilder->buildUrl(array($url));
  42.  * $newUrl = $mrUrlBuilder->getUrl();
  43.  * </code>
  44.  *
  45.  * @author      Murat Purc <murat@purc.de>
  46.  * @copyright   © Murat Purc 2008
  47.  * @package     Contenido
  48.  * @subpackage  ModRewrite
  49.  */
  50. class Contenido_UrlBuilder_MR extends Contenido_UrlBuilder {
  51.  
  52.     /**
  53.      * @var  Contenido_UrlBuilder_MR  Self instance
  54.      */
  55.     static private $_instance;
  56.  
  57.     /**
  58.      * @var  string  Ampersant used for composing several parameter value pairs
  59.      */
  60.     private $_sAmp = '&amp;';
  61.  
  62.     /**
  63.      * @var  bool  Is XHTML output?
  64.      */
  65.     private $_bIsXHTML = false;
  66.  
  67.     /**
  68.      * @var  bool  Is mod rewrite enabled?
  69.      */
  70.     private $_bMREnabled = false;
  71.  
  72.  
  73.     /**
  74.      * @var  array  Mod Rewrite configuration
  75.      */
  76.     private $_aMrCfg = null;
  77.  
  78.  
  79.     /**
  80.      * Constructor, tries to set some member variables.
  81.      */
  82.     private function __construct() {
  83.         $this->sHttpBasePath = '';
  84.         if (ModRewrite::is_enabled()) {
  85.             $this->_aMrCfg     = ModRewrite::getConfig();
  86.             $this->_bMREnabled = true;
  87.             $this->_bIsXHTML   = (getEffectiveSetting('generator', 'xhtml', 'false') == 'false') ? false : true;
  88.             $this->_sAmp       = ($this->_bIsXHTML) ? '&' : '&amp;';
  89.         }
  90.     }
  91.  
  92.  
  93.     /**
  94.      * Returns a instance of Contenido_UrlBuilder_MR
  95.      *
  96.      * @return  Contenido_UrlBuilder_MR 
  97.      */
  98.     public static function getInstance() {
  99.         if (self::$_instance == null) {
  100.             self::$_instance = new Contenido_UrlBuilder_MR();
  101.         }
  102.         return self::$_instance;
  103.     }
  104.  
  105.  
  106.     /**
  107.      * Builds a URL in front_content.php style.
  108.      *
  109.      * @param   array    $params  Parameter array, provides only following parameters:
  110.      *  <code>
  111.      *  $params[0] = 'front_content.php?idart=123...'
  112.      *  </code>
  113.      * @param   boolean  $bUseAbsolutePath  Flag to use absolute path, not used at the moment
  114.      * @return  string  new build url
  115.      */
  116.     public function buildUrl(array $params, $bUseAbsolutePath=false) {
  117.  
  118.         $url = (isset($params[0])) ? $params[0] : '';
  119.  
  120.         // cleanup any existing & entities
  121.         $url = str_replace('&amp;', '&', $url);
  122.  
  123.         if ($this->_bMREnabled) {
  124.  
  125.             // some preparation of different occurence front_content.php
  126.             if (strpos($url, './front_content.php') === 0) {
  127.                 $url = str_replace('./front_content.php', 'front_content.php', $url);
  128.             } elseif (strpos($url, './front_content.php') === 0) {
  129.                 $url = str_replace('/front_content.php', 'front_content.php', $url);
  130.             }
  131.  
  132.             $aUrl = ModRewrite::get_client_full_url_parts($url);
  133.             if (preg_match("/^front_content\.php(.*|.+?)/i", $aUrl['url'], $arr_hits) == 1) {
  134.                 $url = $aUrl['htmlpath'] . self::_buildUrl($arr_hits[1]);
  135.             } else {
  136.                 $GLOBALS['mpDebug']->addDebug($url, 'Contenido_UrlBuilder_MR::buildUrl() nomatch');
  137.             }
  138.         }
  139.  
  140.         // replace & against entity, if xhtml is to use
  141.         if ($this->_bIsXHTML) {
  142.             $url = str_replace('&', '&amp;', $url);
  143.         }
  144.  
  145. #        $urlDebug['out'] = $url;
  146. #        $GLOBALS['mpDebug']->addDebug($urlDebug, 'Contenido_UrlBuilder_MR::buildUrl() in -> out');
  147.  
  148.         $this->sUrl = $url;
  149.  
  150.     }
  151.  
  152.  
  153.     /**
  154.      * Private function to build the URL by analyzing passed arguments (parameter value pairs)
  155.      *
  156.      * TODO: Too much code in one function -> is to redesign...
  157.      *
  158.      * @param   string  $args  Arguments
  159.      * @return  string  New build url
  160.      */
  161.     private function _buildUrl($args='') {
  162.  
  163.         $sNewUrl        = '';
  164.         $sCategories    = '';
  165.         $sArticle       = '';
  166.         $aArgs          = array();
  167.         $sJoinParameter = '/';
  168.         $sFileExtension = '';
  169.         $aParts         = array();
  170.  
  171.         // only html files part
  172.             $sJoinParameter = $this->_aMrCfg['category_seperator'];
  173.             $sFileExtension = $this->_aMrCfg['file_extension'];
  174.         }
  175.  
  176.         // check arguments ... and split
  177.         $sAnchor = '';
  178.         // check for anchor
  179.         $aArgs = explode('#', $args);
  180.         if (is_array($aArgs) && count($aArgs) > 1) {
  181.             $args = $aArgs[0];
  182.             $sAnchor = '#' . urlencode(urldecode($aArgs[1]));
  183.         }
  184.  
  185.         $args = str_replace('?', '', $args);
  186.         $args = str_replace('&amp;', '&', $args);
  187.  
  188.         // extract arguments into current scope
  189.         parse_str($args);
  190.  
  191.         // some preparations to avoid too much checks in further code blocks
  192.         $idcat        = (isset($idcat)) ? (int) $idcat : 0;
  193.         $idart        = (isset($idart)) ? (int) $idart : 0;
  194.         $idcatart     = (isset($idcatart)) ? (int) $idcatart : 0;
  195.         $idartlang    = (isset($idartlang)) ? (int) $idartlang : 0;
  196.         $changelang   = (isset($changelang)) ? (int) $changelang : 0;
  197.         $changeclient = (isset($changeclient)) ? (int) $changeclient : 0;
  198.  
  199.         // get additional non contenido parameters
  200.         $sAdditionalParams = '';
  201.         $aAdditionalParams = array();
  202.         $aParamPairs       = split('&', $args);
  203.  
  204.         $aIgnoredParams = array(
  205.             'idcat', 'idart', 'lang', 'client', 'idcatart', 'idartlang'
  206.         );
  207.  
  208.         if ($this->_aMrCfg['use_language'] == 1) {
  209.             $aIgnoredParams[] = 'changelang';
  210.         }
  211.         if ($this->_aMrCfg['use_client'] == 1) {
  212.             $aIgnoredParams[] = 'changeclient';
  213.         }
  214.  
  215.         foreach ($aParamPairs as $sPair) {
  216.             $bFoundBad = false;
  217.             $aParam = explode('=', $sPair);
  218.  
  219.             foreach ($aIgnoredParams as $sKey) {
  220.                 if ($sKey == strtolower(trim($aParam[0]))) {
  221.                     $bFoundBad = true;
  222.                     break;
  223.                 }
  224.             }
  225.  
  226.             if ($bFoundBad == false) {
  227.                 $aAdditionalParams[] = urlencode(urldecode($aParam[0])) . '=' . urlencode(urldecode($aParam[1]));
  228.             }
  229.         }
  230.  
  231.         if (count($aAdditionalParams) > 0) {
  232.             $sAdditionalParams = '?' . implode($this->_sAmp, $aAdditionalParams);
  233.         }
  234.  
  235.         $idlang   = ($changelang > 0) ? $changelang : $GLOBALS['lang'];
  236.         $idclient = ($changeclient > 0) ? $changeclient : $GLOBALS['client'];
  237.  
  238.         // set client?
  239.         if ($this->_aMrCfg['use_client'] == 1) {
  240.             if ($this->_aMrCfg['use_client_name'] == 1) {
  241.                 $aParts[] = urlencode(ModRewrite::get_client_name($idclient));
  242.             } else {
  243.                 $aParts[] = $idclient;
  244.             }
  245.         }
  246.  
  247.         // set language?
  248.         if ($this->_aMrCfg['use_language'] == 1) {
  249.             if ($this->_aMrCfg['use_language_name'] == 1) {
  250.                 $aParts[] = urlencode(ModRewrite::get_language_name($idlang));
  251.             } else {
  252.                 $aParts[] = $idlang;
  253.             }
  254.         }
  255.  
  256.         // define rootpath ...
  257.         $sNewUrl = $this->_aMrCfg['rootdir'];
  258.  
  259.  
  260.         // try to catch category id
  261.         // ------------------------
  262.  
  263.         if ($idcat == 0) {
  264.  
  265.             if ($idart > 0) {
  266.                 // get category id by given idcat
  267.                 $sql = "SELECT idcat FROM " . $GLOBALS['cfg']['tab']['cat_art'] . " WHERE idart='$idart'";
  268.                 if ($aData = mr_query_n_next_record($sql)) {
  269.                     $idcat = $aData['idcat'];
  270.                 }
  271.             } elseif ($idcatart > 0) {
  272.                 // get category id and article id by given idcatart
  273.                 $sql = "SELECT idcat, idart FROM " . $GLOBALS['cfg']['tab']['cat_art'] . " WHERE idcatart='$idcatart'";
  274.                 if ($aData = mr_query_n_next_record($sql)) {
  275.                     $idcat = $aData['idcat'];
  276.                     $idart = $aData['idart'];
  277.                 }
  278.             } elseif ($idartlang > 0) {
  279.                 // get category id  by given idartlang
  280.                 $sql = "SELECT ca.idcat
  281.                         FROM " . $GLOBALS['cfg']['tab']['art_lang'] . " al
  282.                         LEFT JOIN " . $GLOBALS['cfg']['tab']['cat_art'] . " ca ON al.idart = ca.idart
  283.                         WHERE al.idartlang='$idartlang'";
  284.                 if ($aData = mr_query_n_next_record($sql)) {
  285.                     $idcat = $aData['idcat'];
  286.                 }
  287.             }
  288.  
  289.         }
  290.  
  291.         // try to catch article id
  292.         // -----------------------
  293.  
  294.         // check if article id is given and set article url
  295.         if ($idart > 0 && $idartlang == 0) {
  296.             $sArticle = ModRewrite::get_art_websafename($idart, $idlang);
  297.         } elseif ($idartlang > 0 && $idart == 0) {
  298.             // handle idartlang
  299.             $sArticle = ModRewrite::get_art_lang_websafename($idartlang);
  300.         } elseif ($idartlang > 0 && $idart > 0) {
  301.             // fallback, if both are set
  302.             $sArticle = ModRewrite::get_art_lang_websafename($idartlang);
  303.         }
  304.  
  305.  
  306.         // we have category but no article name and start article name should be added to url
  307.         if ($idcat > 0 && $sArticle == '' && $this->_aMrCfg['add_startart_name_to_url']) {
  308.  
  309.             if ($this->_aMrCfg['default_startart_name'] == '') {
  310.  
  311.                 // no default article name is configured get startarticle
  312.                 cInclude('classes', 'class.article.php');
  313.                 $artColl = new ArticleCollection(array('idcat' => $idcat, 'start' => 1));
  314.                 if ($artItem = $artColl->startArticle()) {
  315.                     $sArticle = ModRewrite::get_art_websafename($artItem->get('idart'), $idlang);
  316.                 }
  317.  
  318.             } else {
  319.  
  320.                 // use default start article name
  321.                 $sArticle = $this->_aMrCfg['default_startart_name'];
  322.             }
  323.         }
  324.  
  325.         if ($sArticle) {
  326.             $sFileExtension = $this->_aMrCfg['file_extension'];
  327.         } else {
  328.             $sFileExtension = '';
  329.         }
  330.  
  331.         // ok build dir list, if idcat found ...
  332.         if ($idcat > 0) {
  333.  
  334.             $sCategories = ModRewrite::build_recursiv_path($idcat, $idlang);
  335.  
  336.             // check start directory settings
  337.             if ($this->_aMrCfg['startfromroot'] == 0) {
  338.                 // splitt string in array
  339.                 $aCategories = explode($sJoinParameter, $sCategories);
  340.  
  341.                 // remove first category
  342.                 $sFirstCat = array_shift($aCategories);
  343.  
  344.                 // implode array with categories to new string
  345.                 $sCategories = implode($sJoinParameter, $aCategories);
  346.             }
  347.  
  348.             if (strlen($sCategories) > 0) {
  349.                 $aParts[] = $sCategories;
  350.             }
  351.         }
  352.         $sParts = implode($sJoinParameter, $aParts);
  353.  
  354.         // only html files part
  355.         if (strlen($sParts) > 0 && strlen($sArticle) > 0
  356.             && ModRewrite::validate_setting_categories_as_html()) {
  357.             $sParts .= $this->_aMrCfg['article_seperator'];
  358. #        } elseif ((int)$this->_aMrCfg['use_categories_as_html_file'] != 1 && strlen($sParts) > 0) {
  359.         } elseif (strlen($sParts) > 0) {
  360.             $sParts .= $sJoinParameter;
  361.         }
  362.  
  363.         // using lowercase uri?
  364.         if ($this->_aMrCfg['use_lowercase_uri'] == 1) {
  365.             $sFullUrl = $sNewUrl . strtolower($sParts . $sArticle . $sFileExtension) . $sAdditionalParams . $sAnchor;
  366.         } else {
  367.             $sFullUrl = $sNewUrl . $sParts . $sArticle . $sFileExtension . $sAdditionalParams . $sAnchor;
  368.         }
  369.  
  370.         // remove double or more join parameter
  371.         $sFullUrl = preg_replace('#' . $sJoinParameter .'{2,}#', $sJoinParameter, $sFullUrl);
  372.  
  373.         if (substr($sFullUrl, -2) == '?=') {
  374.             $sFullUrl = substr_replace($sFullUrl, '', -2);
  375.         }
  376.  
  377.         return $sFullUrl;
  378.  
  379.     }
  380.  
  381. }

Documentation generated on Mon, 08 Sep 2008 03:08:51 +0200 by phpDocumentor 1.4.0