Advertisement
Guest User

unzend.com_234

a guest
Nov 28th, 2015
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 27.51 KB | None | 0 0
  1. <?php
  2. // ionCube version 9 Decoder unzend.com - Email: unzend@gmail.com
  3. // http://www.unzend.com
  4. /**
  5.  * CUrlManager class file
  6.  *
  7.  * @author Qiang Xue <qiang.xue@gmail.com>
  8.  * @link http://www.yiiframework.com/
  9.  * @copyright 2008-2013 Yii Software LLC
  10.  * @license http://www.yiiframework.com/license/
  11.  */
  12.  
  13. /**
  14.  * CUrlManager manages the URLs of Yii Web applications.
  15.  *
  16.  * It provides URL construction ({@link createUrl()}) as well as parsing ({@link parseUrl()}) functionality.
  17.  *
  18.  * URLs managed via CUrlManager can be in one of the following two formats,
  19.  * by setting {@link setUrlFormat urlFormat} property:
  20.  * <ul>
  21.  * <li>'path' format: /path/to/EntryScript.php/name1/value1/name2/value2...</li>
  22.  * <li>'get' format:  /path/to/EntryScript.php?name1=value1&name2=value2...</li>
  23.  * </ul>
  24.  *
  25.  * When using 'path' format, CUrlManager uses a set of {@link setRules rules} to:
  26.  * <ul>
  27.  * <li>parse the requested URL into a route ('ControllerID/ActionID') and GET parameters;</li>
  28.  * <li>create URLs based on the given route and GET parameters.</li>
  29.  * </ul>
  30.  *
  31.  * A rule consists of a route and a pattern. The latter is used by CUrlManager to determine
  32.  * which rule is used for parsing/creating URLs. A pattern is meant to match the path info
  33.  * part of a URL. It may contain named parameters using the syntax '&lt;ParamName:RegExp&gt;'.
  34.  *
  35.  * When parsing a URL, a matching rule will extract the named parameters from the path info
  36.  * and put them into the $_GET variable; when creating a URL, a matching rule will extract
  37.  * the named parameters from $_GET and put them into the path info part of the created URL.
  38.  *
  39.  * If a pattern ends with '/*', it means additional GET parameters may be appended to the path
  40.  * info part of the URL; otherwise, the GET parameters can only appear in the query string part.
  41.  *
  42.  * To specify URL rules, set the {@link setRules rules} property as an array of rules (pattern=>route).
  43.  * For example,
  44.  * <pre>
  45.  * array(
  46.  *     'articles'=>'article/list',
  47.  *     'article/<id:\d+>/*'=>'article/read',
  48.  * )
  49.  * </pre>
  50.  * Two rules are specified in the above:
  51.  * <ul>
  52.  * <li>The first rule says that if the user requests the URL '/path/to/index.php/articles',
  53.  *   it should be treated as '/path/to/index.php/article/list'; and vice versa applies
  54.  *   when constructing such a URL.</li>
  55.  * <li>The second rule contains a named parameter 'id' which is specified using
  56.  *   the &lt;ParamName:RegExp&gt; syntax. It says that if the user requests the URL
  57.  *   '/path/to/index.php/article/13', it should be treated as '/path/to/index.php/article/read?id=13';
  58.  *   and vice versa applies when constructing such a URL.</li>
  59.  * </ul>
  60.  *
  61.  * The route part may contain references to named parameters defined in the pattern part.
  62.  * This allows a rule to be applied to different routes based on matching criteria.
  63.  * For example,
  64.  * <pre>
  65.  * array(
  66.  *      '<_c:(post|comment)>/<id:\d+>/<_a:(create|update|delete)>'=>'<_c>/<_a>',
  67.  *      '<_c:(post|comment)>/<id:\d+>'=>'<_c>/view',
  68.  *      '<_c:(post|comment)>s/*'=>'<_c>/list',
  69.  * )
  70.  * </pre>
  71.  * In the above, we use two named parameters '<_c>' and '<_a>' in the route part. The '<_c>'
  72.  * parameter matches either 'post' or 'comment', while the '<_a>' parameter matches an action ID.
  73.  *
  74.  * Like normal rules, these rules can be used for both parsing and creating URLs.
  75.  * For example, using the rules above, the URL '/index.php/post/123/create'
  76.  * would be parsed as the route 'post/create' with GET parameter 'id' being 123.
  77.  * And given the route 'post/list' and GET parameter 'page' being 2, we should get a URL
  78.  * '/index.php/posts/page/2'.
  79.  *
  80.  * It is also possible to include hostname into the rules for parsing and creating URLs.
  81.  * One may extract part of the hostname to be a GET parameter.
  82.  * For example, the URL <code>http://admin.example.com/en/profile</code> may be parsed into GET parameters
  83.  * <code>user=admin</code> and <code>lang=en</code>. On the other hand, rules with hostname may also be used to
  84.  * create URLs with parameterized hostnames.
  85.  *
  86.  * In order to use parameterized hostnames, simply declare URL rules with host info, e.g.:
  87.  * <pre>
  88.  * array(
  89.  *     'http://<user:\w+>.example.com/<lang:\w+>/profile' => 'user/profile',
  90.  * )
  91.  * </pre>
  92.  *
  93.  * Starting from version 1.1.8, one can write custom URL rule classes and use them for one or several URL rules.
  94.  * For example,
  95.  * <pre>
  96.  * array(
  97.  *   // a standard rule
  98.  *   '<action:(login|logout)>' => 'site/<action>',
  99.  *   // a custom rule using data in DB
  100.  *   array(
  101.  *     'class' => 'application.components.MyUrlRule',
  102.  *     'connectionID' => 'db',
  103.  *   ),
  104.  * )
  105.  * </pre>
  106.  * Please note that the custom URL rule class should extend from {@link CBaseUrlRule} and
  107.  * implement the following two methods,
  108.  * <ul>
  109.  *    <li>{@link CBaseUrlRule::createUrl()}</li>
  110.  *    <li>{@link CBaseUrlRule::parseUrl()}</li>
  111.  * </ul>
  112.  *
  113.  * CUrlManager is a default application component that may be accessed via
  114.  * {@link CWebApplication::getUrlManager()}.
  115.  *
  116.  * @property string $baseUrl The base URL of the application (the part after host name and before query string).
  117.  * If {@link showScriptName} is true, it will include the script name part.
  118.  * Otherwise, it will not, and the ending slashes are stripped off.
  119.  * @property string $urlFormat The URL format. Defaults to 'path'. Valid values include 'path' and 'get'.
  120.  * Please refer to the guide for more details about the difference between these two formats.
  121.  *
  122.  * @author Qiang Xue <qiang.xue@gmail.com>
  123.  * @package system.web
  124.  * @since 1.0
  125.  */
  126. class CUrlManager extends CApplicationComponent
  127. {
  128.     const CACHE_KEY='Yii.CUrlManager.rules';
  129.     const GET_FORMAT='get';
  130.     const PATH_FORMAT='path';
  131.  
  132.     /**
  133.      * @var array the URL rules (pattern=>route).
  134.      */
  135.     public $rules=array();
  136.     /**
  137.      * @var string the URL suffix used when in 'path' format.
  138.      * For example, ".html" can be used so that the URL looks like pointing to a static HTML page. Defaults to empty.
  139.      */
  140.     public $urlSuffix='';
  141.     /**
  142.      * @var boolean whether to show entry script name in the constructed URL. Defaults to true.
  143.      */
  144.     public $showScriptName=true;
  145.     /**
  146.      * @var boolean whether to append GET parameters to the path info part. Defaults to true.
  147.      * This property is only effective when {@link urlFormat} is 'path' and is mainly used when
  148.      * creating URLs. When it is true, GET parameters will be appended to the path info and
  149.      * separate from each other using slashes. If this is false, GET parameters will be in query part.
  150.      */
  151.     public $appendParams=true;
  152.     /**
  153.      * @var string the GET variable name for route. Defaults to 'r'.
  154.      */
  155.     public $routeVar='r';
  156.     /**
  157.      * @var boolean whether routes are case-sensitive. Defaults to true. By setting this to false,
  158.      * the route in the incoming request will be turned to lower case first before further processing.
  159.      * As a result, you should follow the convention that you use lower case when specifying
  160.      * controller mapping ({@link CWebApplication::controllerMap}) and action mapping
  161.      * ({@link CController::actions}). Also, the directory names for organizing controllers should
  162.      * be in lower case.
  163.      */
  164.     public $caseSensitive=true;
  165.     /**
  166.      * @var boolean whether the GET parameter values should match the corresponding
  167.      * sub-patterns in a rule before using it to create a URL. Defaults to false, meaning
  168.      * a rule will be used for creating a URL only if its route and parameter names match the given ones.
  169.      * If this property is set true, then the given parameter values must also match the corresponding
  170.      * parameter sub-patterns. Note that setting this property to true will degrade performance.
  171.      * @since 1.1.0
  172.      */
  173.     public $matchValue=false;
  174.     /**
  175.      * @var string the ID of the cache application component that is used to cache the parsed URL rules.
  176.      * Defaults to 'cache' which refers to the primary cache application component.
  177.      * Set this property to false if you want to disable caching URL rules.
  178.      */
  179.     public $cacheID='cache';
  180.     /**
  181.      * @var boolean whether to enable strict URL parsing.
  182.      * This property is only effective when {@link urlFormat} is 'path'.
  183.      * If it is set true, then an incoming URL must match one of the {@link rules URL rules}.
  184.      * Otherwise, it will be treated as an invalid request and trigger a 404 HTTP exception.
  185.      * Defaults to false.
  186.      */
  187.     public $useStrictParsing=false;
  188.     /**
  189.      * @var string the class name or path alias for the URL rule instances. Defaults to 'CUrlRule'.
  190.      * If you change this to something else, please make sure that the new class must extend from
  191.      * {@link CBaseUrlRule} and have the same constructor signature as {@link CUrlRule}.
  192.      * It must also be serializable and autoloadable.
  193.      * @since 1.1.8
  194.      */
  195.     public $urlRuleClass='CUrlRule';
  196.  
  197.     private $_urlFormat=self::GET_FORMAT;
  198.     private $_rules=array();
  199.     private $_baseUrl;
  200.  
  201.  
  202.     /**
  203.      * Initializes the application component.
  204.      */
  205.     public function init()
  206.     {
  207.         parent::init();
  208.         $this->processRules();
  209.     }
  210.  
  211.     /**
  212.      * Processes the URL rules.
  213.      */
  214.     protected function processRules()
  215.     {
  216.         if(empty($this->rules) || $this->getUrlFormat()===self::GET_FORMAT)
  217.             return;
  218.         if($this->cacheID!==false && ($cache=Yii::app()->getComponent($this->cacheID))!==null)
  219.         {
  220.             $hash=md5(serialize($this->rules));
  221.             if(($data=$cache->get(self::CACHE_KEY))!==false && isset($data[1]) && $data[1]===$hash)
  222.             {
  223.                 $this->_rules=$data[0];
  224.                 return;
  225.             }
  226.         }
  227.         foreach($this->rules as $pattern=>$route)
  228.             $this->_rules[]=$this->createUrlRule($route,$pattern);
  229.         if(isset($cache))
  230.             $cache->set(self::CACHE_KEY,array($this->_rules,$hash));
  231.     }
  232.  
  233.     /**
  234.      * Adds new URL rules.
  235.      * In order to make the new rules effective, this method must be called BEFORE
  236.      * {@link CWebApplication::processRequest}.
  237.      * @param array $rules new URL rules (pattern=>route).
  238.      * @param boolean $append whether the new URL rules should be appended to the existing ones. If false,
  239.      * they will be inserted at the beginning.
  240.      * @since 1.1.4
  241.      */
  242.     public function addRules($rules,$append=true)
  243.     {
  244.         if ($append)
  245.         {
  246.             foreach($rules as $pattern=>$route)
  247.                 $this->_rules[]=$this->createUrlRule($route,$pattern);
  248.         }
  249.         else
  250.         {
  251.             $rules=array_reverse($rules);
  252.             foreach($rules as $pattern=>$route)
  253.                 array_unshift($this->_rules, $this->createUrlRule($route,$pattern));
  254.         }
  255.     }
  256.  
  257.     /**
  258.      * Creates a URL rule instance.
  259.      * The default implementation returns a CUrlRule object.
  260.      * @param mixed $route the route part of the rule. This could be a string or an array
  261.      * @param string $pattern the pattern part of the rule
  262.      * @return CUrlRule the URL rule instance
  263.      * @since 1.1.0
  264.      */
  265.     protected function createUrlRule($route,$pattern)
  266.     {
  267.         if(is_array($route) && isset($route['class']))
  268.             return $route;
  269.         else
  270.         {
  271.             $urlRuleClass=Yii::import($this->urlRuleClass,true);
  272.             return new $urlRuleClass($route,$pattern);
  273.         }
  274.     }
  275.  
  276.     /**
  277.      * Constructs a URL.
  278.      * @param string $route the controller and the action (e.g. article/read)
  279.      * @param array $params list of GET parameters (name=>value). Both the name and value will be URL-encoded.
  280.      * If the name is '#', the corresponding value will be treated as an anchor
  281.      * and will be appended at the end of the URL.
  282.      * @param string $ampersand the token separating name-value pairs in the URL. Defaults to '&'.
  283.      * @return string the constructed URL
  284.      */
  285.     public function createUrl($route,$params=array(),$ampersand='&')
  286.     {
  287.         unset($params[$this->routeVar]);
  288.         foreach($params as $i=>$param)
  289.             if($param===null)
  290.                 $params[$i]='';
  291.  
  292.         if(isset($params['#']))
  293.         {
  294.             $anchor='#'.$params['#'];
  295.             unset($params['#']);
  296.         }
  297.         else
  298.             $anchor='';
  299.         $route=trim($route,'/');
  300.         foreach($this->_rules as $i=>$rule)
  301.         {
  302.             if(is_array($rule))
  303.                 $this->_rules[$i]=$rule=Yii::createComponent($rule);
  304.             if(($url=$rule->createUrl($this,$route,$params,$ampersand))!==false)
  305.             {
  306.                 if($rule->hasHostInfo)
  307.                     return $url==='' ? '/'.$anchor : $url.$anchor;
  308.                 else
  309.                     return $this->getBaseUrl().'/'.$url.$anchor;
  310.             }
  311.         }
  312.         return $this->createUrlDefault($route,$params,$ampersand).$anchor;
  313.     }
  314.  
  315.     /**
  316.      * Creates a URL based on default settings.
  317.      * @param string $route the controller and the action (e.g. article/read)
  318.      * @param array $params list of GET parameters
  319.      * @param string $ampersand the token separating name-value pairs in the URL.
  320.      * @return string the constructed URL
  321.      */
  322.     protected function createUrlDefault($route,$params,$ampersand)
  323.     {
  324.         if($this->getUrlFormat()===self::PATH_FORMAT)
  325.         {
  326.             $url=rtrim($this->getBaseUrl().'/'.$route,'/');
  327.             if($this->appendParams)
  328.             {
  329.                 $url=rtrim($url.'/'.$this->createPathInfo($params,'/','/'),'/');
  330.                 return $route==='' ? $url : $url.$this->urlSuffix;
  331.             }
  332.             else
  333.             {
  334.                 if($route!=='')
  335.                     $url.=$this->urlSuffix;
  336.                 $query=$this->createPathInfo($params,'=',$ampersand);
  337.                 return $query==='' ? $url : $url.'?'.$query;
  338.             }
  339.         }
  340.         else
  341.         {
  342.             $url=$this->getBaseUrl();
  343.             if(!$this->showScriptName)
  344.                 $url.='/';
  345.             if($route!=='')
  346.             {
  347.                 $url.='?'.$this->routeVar.'='.$route;
  348.                 if(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
  349.                     $url.=$ampersand.$query;
  350.             }
  351.             elseif(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
  352.                 $url.='?'.$query;
  353.             return $url;
  354.         }
  355.     }
  356.  
  357.     /**
  358.      * Parses the user request.
  359.      * @param CHttpRequest $request the request application component
  360.      * @return string the route (controllerID/actionID) and perhaps GET parameters in path format.
  361.      */
  362.     public function parseUrl($request)
  363.     {
  364.         if($this->getUrlFormat()===self::PATH_FORMAT)
  365.         {
  366.             $rawPathInfo=$request->getPathInfo();
  367.             $pathInfo=$this->removeUrlSuffix($rawPathInfo,$this->urlSuffix);
  368.             foreach($this->_rules as $i=>$rule)
  369.             {
  370.                 if(is_array($rule))
  371.                     $this->_rules[$i]=$rule=Yii::createComponent($rule);
  372.                 if(($r=$rule->parseUrl($this,$request,$pathInfo,$rawPathInfo))!==false)
  373.                     return isset($_GET[$this->routeVar]) ? $_GET[$this->routeVar] : $r;
  374.             }
  375.             if($this->useStrictParsing)
  376.                 throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
  377.                     array('{route}'=>$pathInfo)));
  378.             else
  379.                 return $pathInfo;
  380.         }
  381.         elseif(isset($_GET[$this->routeVar]))
  382.             return $_GET[$this->routeVar];
  383.         elseif(isset($_POST[$this->routeVar]))
  384.             return $_POST[$this->routeVar];
  385.         else
  386.             return '';
  387.     }
  388.  
  389.     /**
  390.      * Parses a path info into URL segments and saves them to $_GET and $_REQUEST.
  391.      * @param string $pathInfo path info
  392.      */
  393.     public function parsePathInfo($pathInfo)
  394.     {
  395.         if($pathInfo==='')
  396.             return;
  397.         $segs=explode('/',$pathInfo.'/');
  398.         $n=count($segs);
  399.         for($i=0;$i<$n-1;$i+=2)
  400.         {
  401.             $key=$segs[$i];
  402.             if($key==='') continue;
  403.             $value=$segs[$i+1];
  404.             if(($pos=strpos($key,'['))!==false && ($m=preg_match_all('/\[(.*?)\]/',$key,$matches))>0)
  405.             {
  406.                 $name=substr($key,0,$pos);
  407.                 for($j=$m-1;$j>=0;--$j)
  408.                 {
  409.                     if($matches[1][$j]==='')
  410.                         $value=array($value);
  411.                     else
  412.                         $value=array($matches[1][$j]=>$value);
  413.                 }
  414.                 if(isset($_GET[$name]) && is_array($_GET[$name]))
  415.                     $value=CMap::mergeArray($_GET[$name],$value);
  416.                 $_REQUEST[$name]=$_GET[$name]=$value;
  417.             }
  418.             else
  419.                 $_REQUEST[$key]=$_GET[$key]=$value;
  420.         }
  421.     }
  422.  
  423.     /**
  424.      * Creates a path info based on the given parameters.
  425.      * @param array $params list of GET parameters
  426.      * @param string $equal the separator between name and value
  427.      * @param string $ampersand the separator between name-value pairs
  428.      * @param string $key this is used internally.
  429.      * @return string the created path info
  430.      */
  431.     public function createPathInfo($params,$equal,$ampersand, $key=null)
  432.     {
  433.         $pairs = array();
  434.         foreach($params as $k => $v)
  435.         {
  436.             if ($key!==null)
  437.                 $k = $key.'['.$k.']';
  438.  
  439.             if (is_array($v))
  440.                 $pairs[]=$this->createPathInfo($v,$equal,$ampersand, $k);
  441.             else
  442.                 $pairs[]=urlencode($k).$equal.urlencode($v);
  443.         }
  444.         return implode($ampersand,$pairs);
  445.     }
  446.  
  447.     /**
  448.      * Removes the URL suffix from path info.
  449.      * @param string $pathInfo path info part in the URL
  450.      * @param string $urlSuffix the URL suffix to be removed
  451.      * @return string path info with URL suffix removed.
  452.      */
  453.     public function removeUrlSuffix($pathInfo,$urlSuffix)
  454.     {
  455.         if($urlSuffix!=='' && substr($pathInfo,-strlen($urlSuffix))===$urlSuffix)
  456.             return substr($pathInfo,0,-strlen($urlSuffix));
  457.         else
  458.             return $pathInfo;
  459.     }
  460.  
  461.     /**
  462.      * Returns the base URL of the application.
  463.      * @return string the base URL of the application (the part after host name and before query string).
  464.      * If {@link showScriptName} is true, it will include the script name part.
  465.      * Otherwise, it will not, and the ending slashes are stripped off.
  466.      */
  467.     public function getBaseUrl()
  468.     {
  469.         if($this->_baseUrl!==null)
  470.             return $this->_baseUrl;
  471.         else
  472.         {
  473.             if($this->showScriptName)
  474.                 $this->_baseUrl=Yii::app()->getRequest()->getScriptUrl();
  475.             else
  476.                 $this->_baseUrl=Yii::app()->getRequest()->getBaseUrl();
  477.             return $this->_baseUrl;
  478.         }
  479.     }
  480.  
  481.     /**
  482.      * Sets the base URL of the application (the part after host name and before query string).
  483.      * This method is provided in case the {@link baseUrl} cannot be determined automatically.
  484.      * The ending slashes should be stripped off. And you are also responsible to remove the script name
  485.      * if you set {@link showScriptName} to be false.
  486.      * @param string $value the base URL of the application
  487.      * @since 1.1.1
  488.      */
  489.     public function setBaseUrl($value)
  490.     {
  491.         $this->_baseUrl=$value;
  492.     }
  493.  
  494.     /**
  495.      * Returns the URL format.
  496.      * @return string the URL format. Defaults to 'path'. Valid values include 'path' and 'get'.
  497.      * Please refer to the guide for more details about the difference between these two formats.
  498.      */
  499.     public function getUrlFormat()
  500.     {
  501.         return $this->_urlFormat;
  502.     }
  503.  
  504.     /**
  505.      * Sets the URL format.
  506.      * @param string $value the URL format. It must be either 'path' or 'get'.
  507.      */
  508.     public function setUrlFormat($value)
  509.     {
  510.         if($value===self::PATH_FORMAT || $value===self::GET_FORMAT)
  511.             $this->_urlFormat=$value;
  512.         else
  513.             throw new CException(Yii::t('yii','CUrlManager.UrlFormat must be either "path" or "get".'));
  514.     }
  515. }
  516.  
  517.  
  518. /**
  519.  * CBaseUrlRule is the base class for a URL rule class.
  520.  *
  521.  * Custom URL rule classes should extend from this class and implement two methods:
  522.  * {@link createUrl} and {@link parseUrl}.
  523.  *
  524.  * @author Qiang Xue <qiang.xue@gmail.com>
  525.  * @package system.web
  526.  * @since 1.1.8
  527.  */
  528. abstract class CBaseUrlRule extends CComponent
  529. {
  530.     /**
  531.      * @var boolean whether this rule will also parse the host info part. Defaults to false.
  532.      */
  533.     public $hasHostInfo=false;
  534.     /**
  535.      * Creates a URL based on this rule.
  536.      * @param CUrlManager $manager the manager
  537.      * @param string $route the route
  538.      * @param array $params list of parameters (name=>value) associated with the route
  539.      * @param string $ampersand the token separating name-value pairs in the URL.
  540.      * @return mixed the constructed URL. False if this rule does not apply.
  541.      */
  542.     abstract public function createUrl($manager,$route,$params,$ampersand);
  543.     /**
  544.      * Parses a URL based on this rule.
  545.      * @param CUrlManager $manager the URL manager
  546.      * @param CHttpRequest $request the request object
  547.      * @param string $pathInfo path info part of the URL (URL suffix is already removed based on {@link CUrlManager::urlSuffix})
  548.      * @param string $rawPathInfo path info that contains the potential URL suffix
  549.      * @return mixed the route that consists of the controller ID and action ID. False if this rule does not apply.
  550.      */
  551.     abstract public function parseUrl($manager,$request,$pathInfo,$rawPathInfo);
  552. }
  553.  
  554. /**
  555.  * CUrlRule represents a URL formatting/parsing rule.
  556.  *
  557.  * It mainly consists of two parts: route and pattern. The former classifies
  558.  * the rule so that it only applies to specific controller-action route.
  559.  * The latter performs the actual formatting and parsing role. The pattern
  560.  * may have a set of named parameters.
  561.  *
  562.  * @author Qiang Xue <qiang.xue@gmail.com>
  563.  * @package system.web
  564.  * @since 1.0
  565.  */
  566. class CUrlRule extends CBaseUrlRule
  567. {
  568.     /**
  569.      * @var string the URL suffix used for this rule.
  570.      * For example, ".html" can be used so that the URL looks like pointing to a static HTML page.
  571.      * Defaults to null, meaning using the value of {@link CUrlManager::urlSuffix}.
  572.      */
  573.     public $urlSuffix;
  574.     /**
  575.      * @var boolean whether the rule is case sensitive. Defaults to null, meaning
  576.      * using the value of {@link CUrlManager::caseSensitive}.
  577.      */
  578.     public $caseSensitive;
  579.     /**
  580.      * @var array the default GET parameters (name=>value) that this rule provides.
  581.      * When this rule is used to parse the incoming request, the values declared in this property
  582.      * will be injected into $_GET.
  583.      */
  584.     public $defaultParams=array();
  585.     /**
  586.      * @var boolean whether the GET parameter values should match the corresponding
  587.      * sub-patterns in the rule when creating a URL. Defaults to null, meaning using the value
  588.      * of {@link CUrlManager::matchValue}. When this property is false, it means
  589.      * a rule will be used for creating a URL if its route and parameter names match the given ones.
  590.      * If this property is set true, then the given parameter values must also match the corresponding
  591.      * parameter sub-patterns. Note that setting this property to true will degrade performance.
  592.      * @since 1.1.0
  593.      */
  594.     public $matchValue;
  595.     /**
  596.      * @var string the HTTP verb (e.g. GET, POST, DELETE) that this rule should match.
  597.      * If this rule can match multiple verbs, please separate them with commas.
  598.      * If this property is not set, the rule can match any verb.
  599.      * Note that this property is only used when parsing a request. It is ignored for URL creation.
  600.      * @since 1.1.7
  601.      */
  602.     public $verb;
  603.     /**
  604.      * @var boolean whether this rule is only used for request parsing.
  605.      * Defaults to false, meaning the rule is used for both URL parsing and creation.
  606.      * @since 1.1.7
  607.      */
  608.     public $parsingOnly=false;
  609.     /**
  610.      * @var string the controller/action pair
  611.      */
  612.     public $route;
  613.     /**
  614.      * @var array the mapping from route param name to token name (e.g. _r1=><1>)
  615.      */
  616.     public $references=array();
  617.     /**
  618.      * @var string the pattern used to match route
  619.      */
  620.     public $routePattern;
  621.     /**
  622.      * @var string regular expression used to parse a URL
  623.      */
  624.     public $pattern;
  625.     /**
  626.      * @var string template used to construct a URL
  627.      */
  628.     public $template;
  629.     /**
  630.      * @var array list of parameters (name=>regular expression)
  631.      */
  632.     public $params=array();
  633.     /**
  634.      * @var boolean whether the URL allows additional parameters at the end of the path info.
  635.      */
  636.     public $append;
  637.     /**
  638.      * @var boolean whether host info should be considered for this rule
  639.      */
  640.     public $hasHostInfo;
  641.  
  642.     /**
  643.      * Constructor.
  644.      * @param string $route the route of the URL (controller/action)
  645.      * @param string $pattern the pattern for matching the URL
  646.      */
  647.     public function __construct($route,$pattern)
  648.     {
  649.         if(is_array($route))
  650.         {
  651.             foreach(array('urlSuffix', 'caseSensitive', 'defaultParams', 'matchValue', 'verb', 'parsingOnly') as $name)
  652.             {
  653.                 if(isset($route[$name]))
  654.                     $this->$name=$route[$name];
  655.             }
  656.             if(isset($route['pattern']))
  657.                 $pattern=$route['pattern'];
  658.             $route=$route[0];
  659.         }
  660.         $this->route=trim($route,'/');
  661.  
  662.         $tr2['/']=$tr['/']='\\/';
  663.  
  664.         if(strpos($route,'<')!==false && preg_match_all('/<(\w+)>/',$route,$matches2))
  665.         {
  666.             foreach($matches2[1] as $name)
  667.                 $this->references[$name]="<$name>";
  668.         }
  669.  
  670.         $this->hasHostInfo=!strncasecmp($pattern,'http://',7) || !strncasecmp($pattern,'https://',8);
  671.  
  672.         if($this->verb!==null)
  673.             $this->verb=preg_split('/[\s,]+/',strtoupper($this->verb),-1,PREG_SPLIT_NO_EMPTY);
  674.  
  675.         if(preg_match_all('/<(\w+):?(.*?)?>/',$pattern,$matches))
  676.         {
  677.             $tokens=array_combine($matches[1],$matches[2]);
  678.             foreach($tokens as $name=>$value)
  679.             {
  680.                 if($value==='')
  681.                     $value='[^\/]+';
  682.                 $tr["<$name>"]="(?P<$name>$value)";
  683.                 if(isset($this->references[$name]))
  684.                     $tr2["<$name>"]=$tr["<$name>"];
  685.                 else
  686.                     $this->params[$name]=$value;
  687.             }
  688.         }
  689.         $p=rtrim($pattern,'*');
  690.         $this->append=$p!==$pattern;
  691.         $p=trim($p,'/');
  692.         $this->template=preg_replace('/<(\w+):?.*?>/','<$1>',$p);
  693.         $this->pattern='/^'.strtr($this->template,$tr).'\/';
  694.         if($this->append)
  695.             $this->pattern.='/u';
  696.         else
  697.             $this->pattern.='$/u';
  698.  
  699.         if($this->references!==array())
  700.             $this->routePattern='/^'.strtr($this->route,$tr2).'$/u';
  701.  
  702.         if(YII_DEBUG && @preg_match($this->pattern,'test')===false)
  703.             throw new CException(Yii::t('yii','The URL pattern "{pattern}" for route "{route}" is not a valid regular expression.',
  704.                 array('{route}'=>$route,'{pattern}'=>$pattern)));
  705.     }
  706.  
  707.     /**
  708.      * Creates a URL based on this rule.
  709.      * @param CUrlManager $manager the manager
  710.      * @param string $route the route
  711.      * @param array $params list of parameters
  712.      * @param string $ampersand the token separating name-value pairs in the URL.
  713.      * @return mixed the constructed URL or false on error
  714.      */
  715.     public function createUrl($manager,$route,$params,$ampersand)
  716.     {
  717.         if($this->parsingOnly)
  718.             return false;
  719.  
  720.         if($manager->caseSensitive && $this->caseSensitive===null || $this->caseSensitive)
  721.             $case='';
  722.         else
  723.             $case='i';
  724.  
  725.         $tr=array();
  726.         if($route!==$this->route)
  727.         {
  728.             if($this->routePattern!==null && preg_match($this->routePattern.$case,$route,$matches))
  729.             {
  730.                 foreach($this->references as $key=>$name)
  731.                     $tr[$name]=$matches[$key];
  732.             }
  733.             else
  734.                 return false;
  735.         }
  736.  
  737.         foreach($this->defaultParams as $key=>$value)
  738.         {
  739.             if(isset($params[$key]))
  740.             {
  741.                 if($params[$key]==$value)
  742.                     unset($params[$key]);
  743.                 else
  744.                     return false;
  745.             }
  746.         }
  747.  
  748.         foreach($this->params as $key=>$value)
  749.             if(!isset($params[$key]))
  750.                 return false;
  751.  
  752.         if($manager->matchValue && $this->matchValue===null || $this->matchValue)
  753.         {
  754.             foreach($this->params as $key=>$value)
  755.             {
  756.                 if(!preg_match('/\A'.$value.'\z/u'.$case,$params[$key]))
  757.                     return false;
  758.             }
  759.         }
  760.  
  761.         foreach($this->params as $key=>$value)
  762.         {
  763.             $tr["<$key>"]=urlencode($params[$key]);
  764.             unset($params[$key]);
  765.         }
  766.  
  767.         $suffix=$this->urlSuffix===null ? $manager->urlSuffix : $this->urlSuffix;
  768.  
  769.         $url=strtr($this->template,$tr);
  770.  
  771.         if($this->hasHostInfo)
  772.         {
  773.             $hostInfo=Yii::app()->getRequest()->getHostInfo();
  774.             if(stripos($url,$hostInfo)===0)
  775.                 $url=substr($url,strlen($hostInfo));
  776.         }
  777.  
  778.         if(empty($params))
  779.             return $url!=='' ? $url.$suffix : $url;
  780.  
  781.         if($this->append)
  782.             $url.='/'.$manager->createPathInfo($params,'/','/').$suffix;
  783.         else
  784.         {
  785.             if($url!=='')
  786.                 $url.=$suffix;
  787.             $url.='?'.$manager->createPathInfo($params,'=',$ampersand);
  788.         }
  789.  
  790.         return $url;
  791.     }
  792.  
  793.     /**
  794.      * Parses a URL based on this rule.
  795.      * @param CUrlManager $manager the URL manager
  796.      * @param CHttpRequest $request the request object
  797.      * @param string $pathInfo path info part of the URL
  798.      * @param string $rawPathInfo path info that contains the potential URL suffix
  799.      * @return mixed the route that consists of the controller ID and action ID or false on error
  800.      */
  801.     public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
  802.     {
  803.         if($this->verb!==null && !in_array($request->getRequestType(), $this->verb, true))
  804.             return false;
  805.  
  806.         if($manager->caseSensitive && $this->caseSensitive===null || $this->caseSensitive)
  807.             $case='';
  808.         else
  809.             $case='i';
  810.  
  811.         if($this->urlSuffix!==null)
  812.             $pathInfo=$manager->removeUrlSuffix($rawPathInfo,$this->urlSuffix);
  813.  
  814.         // URL suffix required, but not found in the requested URL
  815.         if($manager->useStrictParsing && $pathInfo===$rawPathInfo)
  816.         {
  817.             $urlSuffix=$this->urlSuffix===null ? $manager->urlSuffix : $this->urlSuffix;
  818.             if($urlSuffix!='' && $urlSuffix!=='/')
  819.                 return false;
  820.         }
  821.  
  822.         if($this->hasHostInfo)
  823.             $pathInfo=strtolower($request->getHostInfo()).rtrim('/'.$pathInfo,'/');
  824.  
  825.         $pathInfo.='/';
  826.  
  827.         if(preg_match($this->pattern.$case,$pathInfo,$matches))
  828.         {
  829.             foreach($this->defaultParams as $name=>$value)
  830.             {
  831.                 if(!isset($_GET[$name]))
  832.                     $_REQUEST[$name]=$_GET[$name]=$value;
  833.             }
  834.             $tr=array();
  835.             foreach($matches as $key=>$value)
  836.             {
  837.                 if(isset($this->references[$key]))
  838.                     $tr[$this->references[$key]]=$value;
  839.                 elseif(isset($this->params[$key]))
  840.                     $_REQUEST[$key]=$_GET[$key]=$value;
  841.             }
  842.             if($pathInfo!==$matches[0]) // there're additional GET params
  843.                 $manager->parsePathInfo(ltrim(substr($pathInfo,strlen($matches[0])),'/'));
  844.             if($this->routePattern!==null)
  845.                 return strtr($this->route,$tr);
  846.             else
  847.                 return $this->route;
  848.         }
  849.         else
  850.             return false;
  851.     }
  852. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement