Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: Joomla-Framework

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /joomla/application/router.php

Documentation is available at router.php

  1. <?php
  2. /**
  3. @version        $Id: pathway.php 6472 2007-02-03 10:47:26Z pasamio $
  4. @package        Joomla.Framework
  5. @subpackage    Application
  6. @copyright    Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
  7. @license        GNU/GPL, see LICENSE.php
  8. *  Joomla! is free software. This version may have been modified pursuant
  9. *  to the GNU General Public License, and as distributed it includes or
  10. *  is derivative of works licensed under the GNU General Public License or
  11. *  other free or open source software licenses.
  12. *  See COPYRIGHT.php for copyright notices and details.
  13. */
  14.  
  15. // Check to ensure this file is within the rest of the framework
  16. defined('JPATH_BASE'or die();
  17.  
  18. /**
  19.  * Route handling class
  20.  *
  21.  * @static
  22.  * @package     Joomla.Framework
  23.  * @subpackage    Application
  24.  * @since        1.5
  25.  */
  26. class JRoute
  27. {
  28.     /**
  29.      * Translates an internal Joomla URL to a humanly readible URL.
  30.      *
  31.      * @access public
  32.      * @param     string     $url     Absolute or Relative URI to Joomla resource
  33.      * @param    int        $ssl    Secure state for the resolved URI
  34.      *           1: Make URI secure using global secure site URI
  35.      *           0: Leave URI in the same secure state as it was passed to the function
  36.      *          -1: Make URI unsecure using the global unsecure site URI
  37.      * @return The translated humanly readible URL
  38.      */
  39.     function _($url$ssl 0)
  40.     {
  41.         global $mainframe;
  42.  
  43.         // If we are in the administrator application return
  44.         if($mainframe->isAdmin()) {
  45.             return $url;
  46.         }
  47.  
  48.         // Get the router
  49.         $router =$mainframe->getRouter();
  50.  
  51.         // Build route
  52.         $url $router->build($url);
  53.  
  54.         /*
  55.          * Get the secure/unsecure URLs.
  56.  
  57.          * If the first 5 characters of the BASE are 'https', then we are on an ssl connection over
  58.          * https and need to set our secure URL to the current request URL, if not, and the scheme is
  59.          * 'http', then we need to do a quick string manipulation to switch schemes.
  60.          */
  61.  
  62.         $base JURI::base()//get base URL
  63.  
  64.         if substr$base0== 'https' )
  65.         {
  66.             $secure     $base;
  67.             $unsecure    'http'.substr$base);
  68.         }
  69.         elseif substr$base0== 'http' )
  70.         {
  71.             $secure        'https'.substr$base);
  72.             $unsecure    $base;
  73.         }
  74.  
  75.         // Ensure that proper secure URL is used if ssl flag set secure
  76.         if ($ssl == 1{
  77.             $url $secure.$url;
  78.         }
  79.  
  80.         // Ensure that unsecure URL is used if ssl flag is set to unsecure
  81.         if ($ssl == -1{
  82.             $url $unsecure.$url;
  83.         }
  84.  
  85.         return $url;
  86.     }
  87. }
  88.  
  89. /**
  90.  * Class to create and parse routes
  91.  *
  92.  * @author        Johan Janssens <[email protected]>
  93.  * @package     Joomla.Framework
  94.  * @subpackage    Application
  95.  * @since        1.5
  96.  */
  97. class JRouter extends JObject
  98. {
  99.     /**
  100.      * The rewrite mode
  101.      *
  102.      * @access protected
  103.      * @var integer 
  104.      */
  105.     var $_mode = null;
  106.  
  107.     /**
  108.      * Class constructor
  109.      *
  110.      * @access public
  111.      */
  112.     function __construct($options array())
  113.     {
  114.         if(isset($options['mode'])) {
  115.             $this->_mode = $options['mode'];
  116.         else {
  117.             $this->_mode = 0;
  118.         }
  119.     }
  120.  
  121.     /**
  122.      * Returns a reference to the global Router object, only creating it
  123.      * if it doesn't already exist.
  124.      *
  125.      * This method must be invoked as:
  126.      *         <pre>  $router = &JRouter::getInstance();</pre>
  127.      *
  128.      * @access    public
  129.      * @return    JRouter    The Router object.
  130.      * @since    1.5
  131.      */
  132.     function getInstance($options array())
  133.     {
  134.         static $instance;
  135.  
  136.         if (!is_object($instance)) {
  137.             $instance new JRouter($options);
  138.         }
  139.  
  140.         return $instance;
  141.     }
  142.  
  143.    /**
  144.     * Route a request
  145.     *
  146.     * @access public
  147.     */
  148.     function parse($url)
  149.     {
  150.         //Create the URI object based on the passed in URL
  151.         $uri JURI::getInstance($url);
  152.         
  153.         /*
  154.          * Handle raw URL
  155.          */ 
  156.         if($itemid $uri->getVar('Itemid')) 
  157.         {
  158.             //Set active menu item
  159.             $menu  =JMenu::getInstance();
  160.             $menu->setActive($itemid);
  161.         
  162.             $item $menu->getActive();
  163.                 
  164.             //Set request information
  165.             JRequest::set($item->query'get'false);
  166.             return;
  167.         }
  168.  
  169.         /*
  170.          * Handle routed URL
  171.          */ 
  172.         $menu =JMenu::getInstance();
  173.  
  174.         // Get the base and full URLs
  175.         $full $uri->toStringarray('scheme''host''port''path'));
  176.         $base $uri->base();
  177.  
  178.         $url urldecode(trim(str_replace($base''$full)'/'));
  179.         $url str_replace('index.php/'''$url);
  180.         
  181.         // Set document link
  182.         $doc JFactory::getDocument();
  183.         $doc->setLink($base);
  184.         
  185.         // Parse the route
  186.         if (!empty($url)) 
  187.         {
  188.             // Parse application route
  189.             $this->_parseApplicationRoute($url);
  190.                             
  191.             //Parse component route
  192.             $this->_parseComponentRoute($url);
  193.         }
  194.     }
  195.  
  196.     /**
  197.       * Function to convert an internal URI to a route
  198.       *
  199.       * @param    string    $string    The internal URL
  200.       * @return    string    The absolute search engine friendly URL
  201.       * @since    1.5
  202.       */
  203.     function build($value)
  204.     {
  205.         global $mainframe$Itemid$option;
  206.  
  207.         static $strings;
  208.  
  209.         if (!$strings{
  210.             $strings array();
  211.         }
  212.         
  213.         // Replace all &amp; with & - ensures cache integrity
  214.         $string str_replace('&amp;''&'$value);
  215.  
  216.         if (!isset$strings[$string))
  217.         {
  218.             // Decompose link into url component parts
  219.             $uri  =JURI::getInstance($string);
  220.             $menu =JMenu::getInstance();
  221.  
  222.             // If the itemid isn't set in the URL use default
  223.             if(!$itemid $uri->getVar('Itemid')) {
  224.                 $uri->setVar('Itemid'JRequest::getVar('Itemid'$menu->getDefault()));
  225.             }
  226.             
  227.             // Get the active menu item
  228.             $item $menu->getItem($uri->getVar(('Itemid')));
  229.             
  230.             // If the option isn't set in the URL use the itemid
  231.             if(!$option $uri->getVar('option')) {
  232.                 $uri->setVar('option'$item->component);
  233.             }
  234.  
  235.             // rewite URL
  236.             if ($this->_mode && !eregi("^(([^:/?#]+):)"$string&& !strcasecmp(substr($string09)'index.php'))
  237.             {
  238.                 $route ''//the route created
  239.  
  240.                 $query $uri->getQuery(true);
  241.  
  242.                 //Built application route
  243.                 $app_route $this->_buildApplicationRoute($query);
  244.                 
  245.                 //Build component route
  246.                 $com_route $this->_buildComponentRoute($query);
  247.  
  248.                 //Set query again in the URI
  249.                 $uri->setQuery($query);
  250.  
  251.                 //Check if link contained fragment identifiers (ex. #foo)
  252.                 $fragment null;
  253.                 if ($fragment $uri->getFragment())
  254.                 {
  255.                     // ensure fragment identifiers are compatible with HTML4
  256.                     if (preg_match('@^[A-Za-z][A-Za-z0-9:_.-]*$@'$fragment)) {
  257.                         $fragment '#'.$fragment;
  258.                     }
  259.                 }
  260.  
  261.                 //Check if the component has left any query information unhandled
  262.                 if($query $uri->getQuery()) {
  263.                     $query '?'.$query;
  264.                 }
  265.  
  266.                 //Create the route
  267.                 $url $app_route.$com_route.$fragment.$query;
  268.  
  269.                 //Prepend the base URI if we are not using mod_rewrite
  270.                 if ($this->_mode == 1{
  271.                     $url 'index.php/'.$url;
  272.                 }
  273.                 
  274.                 if ($this->_mode == 2{
  275.                     $url $url.'.html';
  276.                 }
  277.  
  278.                 $strings[$string$url;
  279.  
  280.                 return str_replace'&''&amp;'$url );
  281.             }
  282.  
  283.             $strings[$string$uri->toString();
  284.         }
  285.  
  286.         return str_replace'&''&amp;'$strings[$string);
  287.     }
  288.     
  289.     /**
  290.     * Parse a application specific route
  291.     *
  292.     * @access protected
  293.     */
  294.     function _parseApplicationRoute(&$url)
  295.     {
  296.         if(substr($url09== 'component'
  297.         {
  298.             $segments explode('/'$url);
  299.             $url str_replace('component/'.$segments[1]''$url);; 
  300.             
  301.             JRequest::setVar('option''com_'.$segments[1]);
  302.         }
  303.         else
  304.         {
  305.             $menu  =JMenu::getInstance();
  306.         
  307.             //Need to reverse the array (highest sublevels first)
  308.             $items array_reverse($menu->getMenu());
  309.  
  310.             $itemid null;
  311.             foreach ($items as $item)
  312.             {
  313.                 if(strpos($url$item->route=== 0)
  314.                 {
  315.                     $itemid $item->id;
  316.                     $url    str_replace($item->route''$url);
  317.                     break;
  318.                 }
  319.             }
  320.         
  321.             //Set active menu item
  322.             $menu->setActive($itemid);
  323.             
  324.             //Set request information
  325.             JRequest::set($item->query'get'false);        
  326.             JRequest::setVar('Itemid'$itemid);
  327.         }
  328.     }
  329.  
  330.     /**
  331.     * Parse a component specific route
  332.     *
  333.     * @access protected
  334.     */
  335.     function _parseComponentRoute($url)
  336.     {
  337.         $segments explode('/'$url);
  338.         array_shift($segments);
  339.         
  340.         // Handle pagination
  341.         $limitstart JRequest::getVar('start'null'get');
  342.         if(isset($limitstart)) {
  343.             JRequest::setVar('limitstart'$limitstart);
  344.         }
  345.         
  346.         // Handle component    route
  347.         $component JRequest::getVar('option');
  348.         
  349.         // Use the component routing handler if it exists
  350.         $path JPATH_BASE.DS.'components'.DS.$component.DS.'router.php';
  351.  
  352.         if (file_exists($path&& count($segments))
  353.         {    
  354.             //decode the route segments
  355.             $segments $this->_decodeSegments($segments);
  356.             
  357.             require_once $path;
  358.             $function =  substr($component4).'ParseRoute';
  359.             $function($segments);
  360.         }
  361.     }
  362.     
  363.     /**
  364.     * Build the application specific route
  365.     *
  366.     * @access protected
  367.     */
  368.     function _buildApplicationRoute(&$query)
  369.     {
  370.         $route '';
  371.         
  372.         $menu =JMenu::getInstance();
  373.         $item $menu->getItem($query['Itemid']);
  374.         
  375.         if($query['option'== $item->component
  376.         {
  377.             $route $item->route;
  378.         
  379.         else 
  380.         {
  381.             $route 'component/'.substr($query['option']4);
  382.         }
  383.     
  384.         return $route;
  385.     }
  386.  
  387.     /**
  388.     * Build the component specific route
  389.     *
  390.     * @access protected
  391.     */
  392.     function _buildComponentRoute(&$query)
  393.     {
  394.         $route '';
  395.         
  396.         // Get the component
  397.         $component $query['option'];
  398.         
  399.         // Unset unneeded query information
  400.         unset($query['option'])
  401.         unset($query['Itemid'])
  402.  
  403.         // Use the component routing handler if it exists
  404.         $path JPATH_BASE.DS.'components'.DS.$component.DS.'router.php';
  405.  
  406.         // Use the custom request handler if it exists
  407.         if (file_exists($path))
  408.         {
  409.             require_once $path;
  410.             $function    substr($component4).'BuildRoute';
  411.             $parts        $function($query);
  412.  
  413.             if (isset$query['limitstart'))
  414.             {
  415.                 $query['start'= (int) $query['limitstart'];
  416.                 unset($query['limitstart']);
  417.             }
  418.             
  419.             //encode the route segments
  420.             $parts$this->_encodeSegments($parts);
  421.             
  422.             $route implode('/'$parts);
  423.             $route ($route'/'.$route null;
  424.         }
  425.  
  426.         return $route;
  427.     }
  428.     
  429.     function _encodeSegments($segments)
  430.     {
  431.         $total count($segments);
  432.         for($i=0$i<$total$i++{
  433.             $segments[$istr_replace(':''_'$segments[$i]);
  434.         }
  435.         
  436.         return $segments;
  437.     }
  438.     
  439.     function _decodeSegments($segments)
  440.     {
  441.         $total count($segments);
  442.         for($i=0$i<$total$i++)  {
  443.             $segments[$istr_replace('_'':'$segments[$i]);
  444.         }
  445.         
  446.         return $segments;
  447.     }
  448. }
  449. ?>

Documentation generated on Mon, 05 Mar 2007 21:20:24 +0000 by phpDocumentor 1.3.1