Support Joomla!

Packages

Package: Joomla-Framework

License

Content on this site is copyright © 2005 - 2008 Open Source Matters Inc and can be used in accordance with the Joomla! Electronic Documentation License. Some parts of this website may be subject to other licenses.
Source code for file /joomla/environment/uri.php

Documentation is available at uri.php

  1. <?php
  2. /**
  3.  * @version        $Id: uri.php 12389 2009-07-01 00:34:45Z ian $
  4.  * @package        Joomla.Framework
  5.  * @subpackage    Environment
  6.  * @copyright    Copyright (C) 2005 - 2008 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.  * JURI Class
  20.  *
  21.  * This class serves two purposes.  First to parse a URI and provide a common interface
  22.  * for the Joomla Framework to access and manipulate a URI.  Second to attain the URI of
  23.  * the current executing script from the server regardless of server.
  24.  *
  25.  * @package        Joomla.Framework
  26.  * @subpackage    Environment
  27.  * @since        1.5
  28.  */
  29. class JURI extends JObject
  30. {
  31.     /**
  32.      * Original URI
  33.      *
  34.      * @var        string 
  35.      */
  36.     var $_uri = null;
  37.  
  38.     /**
  39.      * Protocol
  40.      *
  41.      * @var        string 
  42.      */
  43.     var $_scheme = null;
  44.  
  45.     /**
  46.      * Host
  47.      *
  48.      * @var        string 
  49.      */
  50.     var $_host = null;
  51.  
  52.     /**
  53.      * Port
  54.      *
  55.      * @var        integer 
  56.      */
  57.     var $_port = null;
  58.  
  59.     /**
  60.      * Username
  61.      *
  62.      * @var        string 
  63.      */
  64.     var $_user = null;
  65.  
  66.     /**
  67.      * Password
  68.      *
  69.      * @var        string 
  70.      */
  71.     var $_pass = null;
  72.  
  73.     /**
  74.      * Path
  75.      *
  76.      * @var        string 
  77.      */
  78.     var $_path = null;
  79.  
  80.     /**
  81.      * Query
  82.      *
  83.      * @var        string 
  84.      */
  85.     var $_query = null;
  86.  
  87.     /**
  88.      * Anchor
  89.      *
  90.      * @var        string 
  91.      */
  92.     var $_fragment = null;
  93.  
  94.     /**
  95.      * Query variable hash
  96.      *
  97.      * @var        array 
  98.      */
  99.     var $_vars = array ();
  100.  
  101.     /**
  102.      * Constructor.
  103.      * You can pass a URI string to the constructor to initialize a specific URI.
  104.      *
  105.      * @param    string $uri The optional URI string
  106.      */
  107.     function __construct($uri null)
  108.     {
  109.         if ($uri !== null{
  110.             $this->parse($uri);
  111.         }
  112.     }
  113.  
  114.     /**
  115.      * Returns a reference to a global JURI object, only creating it
  116.      * if it doesn't already exist.
  117.      *
  118.      * This method must be invoked as:
  119.      *         <pre>  $uri =& JURI::getInstance([$uri]);</pre>
  120.      *
  121.      * @static
  122.      * @param    string $uri The URI to parse.  [optional: if null uses script URI]
  123.      * @return    JURI  The URI object.
  124.      * @since    1.5
  125.      */
  126.     function &getInstance($uri 'SERVER')
  127.     {
  128.         static $instances array();
  129.  
  130.         if (!isset ($instances[$uri]))
  131.         {
  132.             // Are we obtaining the URI from the server?
  133.                         if ($uri == 'SERVER')
  134.             {
  135.                 // Determine if the request was over SSL (HTTPS)
  136.                                 if (isset($_SERVER['HTTPS']&& !empty($_SERVER['HTTPS']&& (strtolower($_SERVER['HTTPS']!= 'off')) {
  137.                     $https 's://';
  138.                 else {
  139.                     $https '://';
  140.                 }
  141.  
  142.                 /*
  143.                  * Since we are assigning the URI from the server variables, we first need
  144.                  * to determine if we are running on apache or IIS.  If PHP_SELF and REQUEST_URI
  145.                  * are present, we will assume we are running on apache.
  146.                  */
  147.                 if (!empty ($_SERVER['PHP_SELF']&& !empty ($_SERVER['REQUEST_URI'])) {
  148.  
  149.                     /*
  150.                      * To build the entire URI we need to prepend the protocol, and the http host
  151.                      * to the URI string.
  152.                      */
  153.                     $theURI 'http' $https $_SERVER['HTTP_HOST'$_SERVER['REQUEST_URI'];
  154.  
  155.                 /*
  156.                  * Since we do not have REQUEST_URI to work with, we will assume we are
  157.                  * running on IIS and will therefore need to work some magic with the SCRIPT_NAME and
  158.                  * QUERY_STRING environment variables.
  159.                  */
  160.                 }
  161.                  else
  162.                  {
  163.                     // IIS uses the SCRIPT_NAME variable instead of a REQUEST_URI variable... thanks, MS
  164.                                         $theURI 'http' $https $_SERVER['HTTP_HOST'$_SERVER['SCRIPT_NAME'];
  165.  
  166.                     // If the query string exists append it to the URI string
  167.                                         if (isset($_SERVER['QUERY_STRING']&& !empty($_SERVER['QUERY_STRING'])) {
  168.                         $theURI .= '?' $_SERVER['QUERY_STRING'];
  169.                     }
  170.                 }
  171.  
  172.                 // Now we need to clean what we got since we can't trust the server var
  173.                                 $theURI urldecode($theURI);
  174.                 $theURI str_replace('"''&quot;',$theURI);
  175.                 $theURI str_replace('<''&lt;',$theURI);
  176.                 $theURI str_replace('>''&gt;',$theURI);
  177.                 $theURI preg_replace('/eval\((.*)\)/'''$theURI);
  178.                 $theURI preg_replace('/[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']/''""'$theURI);
  179.             }
  180.             else
  181.             {
  182.                 // We were given a URI
  183.                                 $theURI $uri;
  184.             }
  185.  
  186.             // Create the new JURI instance
  187.                         $instances[$urinew JURI($theURI);
  188.         }
  189.         return $instances[$uri];
  190.     }
  191.  
  192.     /**
  193.      * Returns the base URI for the request.
  194.      *
  195.      * @access    public
  196.      * @static
  197.      * @param    boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
  198.      * @return    string    The base URI string
  199.      * @since    1.5
  200.      */
  201.     function base($pathonly false)
  202.     {
  203.         static $base;
  204.  
  205.         // Get the base request path
  206.         if (!isset($base))
  207.         {
  208.             $config =JFactory::getConfig();
  209.             $live_site $config->getValue('config.live_site');
  210.             if(trim($live_site!= ''{
  211.                 $uri =JURI::getInstance($live_site);
  212.                 $base['prefix'$uri->toStringarray('scheme''host''port'));
  213.                 $base['path'rtrim($uri->toStringarray('path'))'/\\');
  214.                 if(JPATH_BASE == JPATH_ADMINISTRATOR{
  215.                     $base['path'.= '/administrator';
  216.                 }
  217.             else {
  218.                 $uri             =JURI::getInstance();
  219.                 $base['prefix'$uri->toStringarray('scheme''host''port'));
  220.  
  221.                 if (strpos(php_sapi_name()'cgi'!== false && !empty($_SERVER['REQUEST_URI'])) {
  222.                     //Apache CGI
  223.                     $base['path'=  rtrim(dirname(str_replace(array('"''<''>'"'")''$_SERVER["PHP_SELF"]))'/\\');
  224.                 else {
  225.                     //Others
  226.                     $base['path'=  rtrim(dirname($_SERVER['SCRIPT_NAME'])'/\\');
  227.                 }
  228.             }
  229.         }
  230.  
  231.         return $pathonly === false $base['prefix'].$base['path'].'/' $base['path'];
  232.     }
  233.  
  234.     /**
  235.      * Returns the root URI for the request.
  236.      *
  237.      * @access    public
  238.      * @static
  239.      * @param    boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
  240.      * @return    string    The root URI string
  241.      * @since    1.5
  242.      */
  243.     function root($pathonly false$path null)
  244.     {
  245.         static $root;
  246.  
  247.         // Get the scheme
  248.         if(!isset($root))
  249.         {
  250.             $uri            =JURI::getInstance(JURI::base());
  251.             $root['prefix'$uri->toStringarray('scheme''host''port') );
  252.             $root['path']   rtrim($uri->toStringarray('path') )'/\\');
  253.         }
  254.  
  255.         // Get the scheme
  256.         if(isset($path)) {
  257.             $root['path']    $path;
  258.         }
  259.  
  260.         return $pathonly === false $root['prefix'].$root['path'].'/' $root['path'];
  261.     }
  262.  
  263.     /**
  264.      * Returns the URL for the request, minus the query
  265.      *
  266.      * @access    public
  267.      * @return    string 
  268.      * @since    1.5
  269.      */
  270.     function current()
  271.     {
  272.         static $current;
  273.  
  274.         // Get the current URL
  275.         if (!isset($current))
  276.         {
  277.             $uri     JURI::getInstance();
  278.             $current $uri->toStringarray('scheme''host''port''path'));
  279.         }
  280.  
  281.         return $current;
  282.     }
  283.  
  284.     /**
  285.      * Parse a given URI and populate the class fields
  286.      *
  287.      * @access    public
  288.      * @param    string $uri The URI string to parse
  289.      * @return    boolean True on success
  290.      * @since    1.5
  291.      */
  292.     function parse($uri)
  293.     {
  294.         //Initialize variables
  295.         $retval false;
  296.  
  297.         // Set the original URI to fall back on
  298.         $this->_uri $uri;
  299.  
  300.         /*
  301.          * Parse the URI and populate the object fields.  If URI is parsed properly,
  302.          * set method return value to true.
  303.          */
  304.         if ($_parts $this->_parseURL($uri)) {
  305.             $retval true;
  306.         }
  307.  
  308.         //We need to replace &amp; with & for parse_str to work right...
  309.         if(isset ($_parts['query']&& strpos($_parts['query']'&amp;')) {
  310.             $_parts['query'str_replace('&amp;''&'$_parts['query']);
  311.         }
  312.  
  313.         $this->_scheme = isset ($_parts['scheme']$_parts['scheme'null;
  314.         $this->_user = isset ($_parts['user']$_parts['user'null;
  315.         $this->_pass = isset ($_parts['pass']$_parts['pass'null;
  316.         $this->_host = isset ($_parts['host']$_parts['host'null;
  317.         $this->_port = isset ($_parts['port']$_parts['port'null;
  318.         $this->_path = isset ($_parts['path']$_parts['path'null;
  319.         $this->_query = isset ($_parts['query'])$_parts['query'null;
  320.         $this->_fragment = isset ($_parts['fragment']$_parts['fragment'null;
  321.  
  322.         //parse the query
  323.  
  324.         if(isset ($_parts['query'])) parse_str($_parts['query']$this->_vars);
  325.         return $retval;
  326.     }
  327.  
  328.     /**
  329.      * Returns full uri string
  330.      *
  331.      * @access    public
  332.      * @param    array $parts An array specifying the parts to render
  333.      * @return    string The rendered URI string
  334.      * @since    1.5
  335.      */
  336.     function toString($parts array('scheme''user''pass''host''port''path''query''fragment'))
  337.     {
  338.         $query $this->getQuery()//make sure the query is created
  339.  
  340.         $uri '';
  341.         $uri .= in_array('scheme'$parts)  (!empty($this->_scheme$this->_scheme.'://' '''';
  342.         $uri .= in_array('user'$parts)    $this->_user '';
  343.         $uri .= in_array('pass'$parts)    (!empty ($this->_pass':' ''.$this->_pass(!empty ($this->_user'@' '''';
  344.         $uri .= in_array('host'$parts)    $this->_host '';
  345.         $uri .= in_array('port'$parts)    (!empty ($this->_port':' '').$this->_port '';
  346.         $uri .= in_array('path'$parts)    $this->_path '';
  347.         $uri .= in_array('query'$parts)    (!empty ($query'?'.$query '''';
  348.         $uri .= in_array('fragment'$parts)(!empty ($this->_fragment'#'.$this->_fragment '''';
  349.  
  350.         return $uri;
  351.     }
  352.  
  353.     /**
  354.      * Adds a query variable and value, replacing the value if it
  355.      * already exists and returning the old value.
  356.      *
  357.      * @access    public
  358.      * @param    string $name Name of the query variable to set
  359.      * @param    string $value Value of the query variable
  360.      * @return    string Previous value for the query variable
  361.      * @since    1.5
  362.      */
  363.     function setVar($name$value)
  364.     {
  365.         $tmp @$this->_vars[$name];
  366.         $this->_vars[$name$value;
  367.  
  368.         //empty the query
  369.         $this->_query null;
  370.  
  371.         return $tmp;
  372.     }
  373.  
  374.     /**
  375.      * Returns a query variable by name
  376.      *
  377.      * @access    public
  378.      * @param    string $name Name of the query variable to get
  379.      * @return    array Query variables
  380.      * @since    1.5
  381.      */
  382.     function getVar($name null$default=null)
  383.     {
  384.         if(isset($this->_vars[$name])) {
  385.             return $this->_vars[$name];
  386.         }
  387.         return $default;
  388.     }
  389.  
  390.     /**
  391.      * Removes an item from the query string variables if it exists
  392.      *
  393.      * @access    public
  394.      * @param    string $name Name of variable to remove
  395.      * @since    1.5
  396.      */
  397.     function delVar($name)
  398.     {
  399.         if (in_array($namearray_keys($this->_vars)))
  400.         {
  401.             unset ($this->_vars[$name]);
  402.  
  403.             //empty the query
  404.             $this->_query null;
  405.         }
  406.     }
  407.  
  408.     /**
  409.      * Sets the query to a supplied string in format:
  410.      *         foo=bar&x=y
  411.      *
  412.      * @access    public
  413.      * @param    mixed (array|string) $query The query string
  414.      * @since    1.5
  415.      */
  416.     function setQuery($query)
  417.     {
  418.         if(!is_array($query)) {
  419.             if(strpos($query'&amp;'!== false)
  420.             {
  421.                $query str_replace('&amp;','&',$query);
  422.             }
  423.             parse_str($query$this->_vars);
  424.         }
  425.  
  426.         if(is_array($query)) {
  427.             $this->_vars $query;
  428.         }
  429.  
  430.         //empty the query
  431.         $this->_query null;
  432.     }
  433.  
  434.     /**
  435.      * Returns flat query string
  436.      *
  437.      * @access    public
  438.      * @return    string Query string
  439.      * @since    1.5
  440.      */
  441.     function getQuery($toArray false)
  442.     {
  443.         if($toArray{
  444.             return $this->_vars;
  445.         }
  446.  
  447.         //If the query is empty build it first
  448.         if(is_null($this->_query)) {
  449.             $this->_query $this->buildQuery($this->_vars);
  450.         }
  451.  
  452.         return $this->_query;
  453.     }
  454.  
  455.     /**
  456.      * Build a query from a array (reverse of the PHP parse_str())
  457.      *
  458.      * @access    public
  459.      * @return    string The resulting query string
  460.      * @since    1.5
  461.      * @see    parse_str()
  462.      */
  463.     function buildQuery ($params$akey null)
  464.     {
  465.         if !is_array($params|| count($params== {
  466.             return false;
  467.         }
  468.  
  469.         $out array();
  470.  
  471.         //reset in case we are looping
  472.         if!isset($akey&& !count($out) )  {
  473.             unset($out);
  474.             $out array();
  475.         }
  476.  
  477.         foreach $params as $key => $val )
  478.         {
  479.             if is_array($val) ) {
  480.                 $out[JURI::buildQuery($val,$key);
  481.                 continue;
  482.             }
  483.  
  484.             $thekey !$akey $key $akey.'['.$key.']';
  485.             $out[$thekey."=".urlencode($val);
  486.         }
  487.  
  488.         return implode("&",$out);
  489.     }
  490.  
  491.     /**
  492.      * Get URI scheme (protocol)
  493.      *         ie. http, https, ftp, etc...
  494.      *
  495.      * @access    public
  496.      * @return    string The URI scheme
  497.      * @since    1.5
  498.      */
  499.     function getScheme({
  500.         return $this->_scheme;
  501.     }
  502.  
  503.     /**
  504.      * Set URI scheme (protocol)
  505.      *         ie. http, https, ftp, etc...
  506.      *
  507.      * @access    public
  508.      * @param    string $scheme The URI scheme
  509.      * @since    1.5
  510.      */
  511.     function setScheme($scheme{
  512.         $this->_scheme $scheme;
  513.     }
  514.  
  515.     /**
  516.      * Get URI username
  517.      *         returns the username, or null if no username was specified
  518.      *
  519.      * @access    public
  520.      * @return    string The URI username
  521.      * @since    1.5
  522.      */
  523.     function getUser({
  524.         return $this->_user;
  525.     }
  526.  
  527.     /**
  528.      * Set URI username
  529.      *
  530.      * @access    public
  531.      * @param    string $user The URI username
  532.      * @since    1.5
  533.      */
  534.     function setUser($user{
  535.         $this->_user $user;
  536.     }
  537.  
  538.     /**
  539.      * Get URI password
  540.      *         returns the password, or null if no password was specified
  541.      *
  542.      * @access    public
  543.      * @return    string The URI password
  544.      * @since    1.5
  545.      */
  546.     function getPass({
  547.         return $this->_pass;
  548.     }
  549.  
  550.     /**
  551.      * Set URI password
  552.      *
  553.      * @access    public
  554.      * @param    string $pass The URI password
  555.      * @since    1.5
  556.      */
  557.     function setPass($pass{
  558.         $this->_pass $pass;
  559.     }
  560.  
  561.     /**
  562.      * Get URI host
  563.      *         returns the hostname/ip, or null if no hostname/ip was specified
  564.      *
  565.      * @access    public
  566.      * @return    string The URI host
  567.      * @since    1.5
  568.      */
  569.     function getHost({
  570.         return $this->_host;
  571.     }
  572.  
  573.     /**
  574.      * Set URI host
  575.      *
  576.      * @access    public
  577.      * @param    string $host The URI host
  578.      * @since    1.5
  579.      */
  580.     function setHost($host{
  581.         $this->_host $host;
  582.     }
  583.  
  584.     /**
  585.      * Get URI port
  586.      *         returns the port number, or null if no port was specified
  587.      *
  588.      * @access    public
  589.      * @return    int The URI port number
  590.      */
  591.     function getPort({
  592.         return (isset ($this->_port)) $this->_port null;
  593.     }
  594.  
  595.     /**
  596.      * Set URI port
  597.      *
  598.      * @access    public
  599.      * @param    int $port The URI port number
  600.      * @since    1.5
  601.      */
  602.     function setPort($port{
  603.         $this->_port $port;
  604.     }
  605.  
  606.     /**
  607.      * Gets the URI path string
  608.      *
  609.      * @access    public
  610.      * @return    string The URI path string
  611.      * @since    1.5
  612.      */
  613.     function getPath({
  614.         return $this->_path;
  615.     }
  616.  
  617.     /**
  618.      * Set the URI path string
  619.      *
  620.      * @access    public
  621.      * @param    string $path The URI path string
  622.      * @since    1.5
  623.      */
  624.     function setPath($path{
  625.         $this->_path $this->_cleanPath($path);
  626.     }
  627.  
  628.     /**
  629.      * Get the URI archor string
  630.      *         everything after the "#"
  631.      *
  632.      * @access    public
  633.      * @return    string The URI anchor string
  634.      * @since    1.5
  635.      */
  636.     function getFragment({
  637.         return $this->_fragment;
  638.     }
  639.  
  640.     /**
  641.      * Set the URI anchor string
  642.      *         everything after the "#"
  643.      *
  644.      * @access    public
  645.      * @param    string $anchor The URI anchor string
  646.      * @since    1.5
  647.      */
  648.     function setFragment($anchor{
  649.         $this->_fragment $anchor;
  650.     }
  651.  
  652.     /**
  653.      * Checks whether the current URI is using HTTPS
  654.      *
  655.      * @access    public
  656.      * @return    boolean True if using SSL via HTTPS
  657.      * @since    1.5
  658.      */
  659.     function isSSL({
  660.         return $this->getScheme(== 'https' true false;
  661.     }
  662.  
  663.     /** 
  664.      * Checks if the supplied URL is internal
  665.      *
  666.      * @access    public
  667.      * @param     string $url The URL to check
  668.      * @return    boolean True if Internal
  669.      * @since    1.5
  670.      */
  671.     function isInternal($url{
  672.         $uri =JURI::getInstance($url);
  673.         $base $uri->toString(array('scheme''host''port''path'));
  674.         $host $uri->toString(array('scheme''host''port'));
  675.         if(stripos($baseJURI::base()) !== && !empty($host)) {
  676.             return false;
  677.         }
  678.         return true;
  679.     }
  680.  
  681.     /**
  682.      * Resolves //, ../ and ./ from a path and returns
  683.      * the result. Eg:
  684.      *
  685.      * /foo/bar/../boo.php    => /foo/boo.php
  686.      * /foo/bar/../../boo.php => /boo.php
  687.      * /foo/bar/.././/boo.php => /foo/boo.php
  688.      *
  689.      * @access    private
  690.      * @param    string $uri The URI path to clean
  691.      * @return    string Cleaned and resolved URI path
  692.      * @since    1.5
  693.      */
  694.     function _cleanPath($path)
  695.     {
  696.         $path explode('/'preg_replace('#(/+)#''/'$path));
  697.  
  698.         for ($i 0$i count($path)$i ++{
  699.             if ($path[$i== '.'{
  700.                 unset ($path[$i]);
  701.                 $path array_values($path);
  702.                 $i --;
  703.  
  704.             }
  705.             elseif ($path[$i== '..' AND ($i OR ($i == AND $path[0!= ''))) {
  706.                 unset ($path[$i]);
  707.                 unset ($path[$i -1]);
  708.                 $path array_values($path);
  709.                 $i -= 2;
  710.  
  711.             }
  712.             elseif ($path[$i== '..' AND $i == AND $path[0== ''{
  713.                 unset ($path[$i]);
  714.                 $path array_values($path);
  715.                 $i --;
  716.  
  717.             else {
  718.                 continue;
  719.             }
  720.         }
  721.  
  722.         return implode('/'$path);
  723.     }
  724.  
  725.     /**
  726.      * Backwards compatibility function for parse_url function
  727.      *
  728.      * This function solves different bugs in PHP versions lower then
  729.      * 4.4, will be deprecated in future versions.
  730.      *
  731.      * @access    private
  732.      * @return    array Associative array containing the URL parts
  733.      * @since    1.5
  734.      * @see parse_url()
  735.      */
  736.     function _parseURL($uri)
  737.     {
  738.         $parts array();
  739.         if (version_comparephpversion()'4.4' 0)
  740.         {
  741.             $regex "<^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?>";
  742.             $matches array();
  743.             preg_match($regex$uri$matchesPREG_OFFSET_CAPTURE);
  744.  
  745.             $authority @$matches[4][0];
  746.             if (strpos($authority'@'!== false{
  747.                 $authority explode('@'$authority);
  748.                 @list($parts['user']$parts['pass']explode(':'$authority[0]);
  749.                 $authority $authority[1];
  750.             }
  751.  
  752.             if (strpos($authority':'!== false{
  753.                 $authority explode(':'$authority);
  754.                 $parts['host'$authority[0];
  755.                 $parts['port'$authority[1];
  756.             else {
  757.                 $parts['host'$authority;
  758.             }
  759.  
  760.             $parts['scheme'@$matches[2][0];
  761.             $parts['path'@$matches[5][0];
  762.             $parts['query'@$matches[7][0];
  763.             $parts['fragment'@$matches[9][0];
  764.         }
  765.         else
  766.         {
  767.             $parts @parse_url($uri);
  768.         }
  769.         return $parts;
  770.     }
  771.  
  772.  
  773. }

Documentation generated on Sat, 14 Nov 2009 11:22:51 +0000 by phpDocumentor 1.3.1