|  |  | @ -33,40 +33,66 @@ class UrlRule extends Object | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 * will be injected into $_GET. |  |  |  | 	 * will be injected into $_GET. | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 */ |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	public $defaults = array(); |  |  |  | 	public $defaults = array(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * @var boolean whether this rule is only used for request parsing. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * Defaults to false, meaning the rule is used for both URL parsing and creation. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	public $parsingOnly = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * @var string the URL suffix used for this rule. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * For example, ".html" can be used so that the URL looks like pointing to a static HTML page. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * If not, the value of [[UrlManager::suffix]] will be used. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	public $suffix; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * @var string|array the HTTP verb (e.g. GET, POST, DELETE) that this rule should match. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * Use array to represent multiple verbs that this rule may match. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * If this property is not set, the rule can match any verb. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * Note that this property is only used when parsing a request. It is ignored for URL creation. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * @see parsingOnly | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	public $verb; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * @var string the host info (e.g. `http://www.example.com`) that this rule should match. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 * If not set, it means the host info is ignored. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	public $hostInfo; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	/** |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 * @var string the template for generating a new URL. This is derived from [[pattern]] and is used in generating URL. |  |  |  | 	 * @var string the template for generating a new URL. This is derived from [[pattern]] and is used in generating URL. | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 */ |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	protected $template; |  |  |  | 	private $_template; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	/** |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 * @var string the regex for matching the route part. This is used in generating URL. |  |  |  | 	 * @var string the regex for matching the route part. This is used in generating URL. | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 */ |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	protected $routeRule; |  |  |  | 	private $_routeRule; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	/** |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 * @var array list of regex for matching parameters. This is used in generating URL. |  |  |  | 	 * @var array list of regex for matching parameters. This is used in generating URL. | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 */ |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	protected $paramRules = array(); |  |  |  | 	private $_paramRules = array(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	/** |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 * @var array list of parameters used in the route. |  |  |  | 	 * @var array list of parameters used in the route. | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 */ |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	protected $routeParams = array(); |  |  |  | 	private $_routeParams = array(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	/** |  |  |  | 	/** | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 * Initializes this rule. |  |  |  | 	 * Initializes this rule. | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 */ |  |  |  | 	 */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	public function init() |  |  |  | 	public function init() | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ |  |  |  | 	{ | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$this->compileRule(); |  |  |  | 		if ($this->verb !== null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (is_array($this->verb)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				foreach ($this->verb as $i => $verb) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					$this->verb[$i] = strtoupper($verb); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				$this->verb = array(strtoupper($this->verb)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	/** |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 * Compiles the rule using the current configuration. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	 */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	protected function compileRule() |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$this->pattern = trim($this->pattern, '/'); |  |  |  | 		$this->pattern = trim($this->pattern, '/'); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if ($this->pattern === '') { |  |  |  | 		if ($this->pattern === '') { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			$this->template = ''; |  |  |  | 			$this->_template = ''; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			$this->pattern = '#^$#u'; |  |  |  | 			$this->pattern = '#^$#u'; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			return; |  |  |  | 			return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} else { |  |  |  | 		} else { | 
			
		
	
	
		
		
			
				
					|  |  | @ -76,7 +102,7 @@ class UrlRule extends Object | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$this->route = trim($this->route, '/'); |  |  |  | 		$this->route = trim($this->route, '/'); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (strpos($this->route, '<') !== false && preg_match_all('/<(\w+)>/', $this->route, $matches)) { |  |  |  | 		if (strpos($this->route, '<') !== false && preg_match_all('/<(\w+)>/', $this->route, $matches)) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			foreach ($matches[1] as $name) { |  |  |  | 			foreach ($matches[1] as $name) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				$this->routeParams[$name] = "<$name>"; |  |  |  | 				$this->_routeParams[$name] = "<$name>"; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -96,24 +122,28 @@ class UrlRule extends Object | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} else { |  |  |  | 				} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 					$tr["<$name>"] = "(?P<$name>$pattern)"; |  |  |  | 					$tr["<$name>"] = "(?P<$name>$pattern)"; | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  | 				if (isset($this->routeParams[$name])) { |  |  |  | 				if (isset($this->_routeParams[$name])) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 					$tr2["<$name>"] = "(?P<$name>$pattern)"; |  |  |  | 					$tr2["<$name>"] = "(?P<$name>$pattern)"; | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} else { |  |  |  | 				} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 					$this->paramRules[$name] = $pattern === '[^\/]+' ? '' : "#^$pattern$#"; |  |  |  | 					$this->_paramRules[$name] = $pattern === '[^\/]+' ? '' : "#^$pattern$#"; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$this->template = preg_replace('/<(\w+):?([^>]+)?>/', '<$1>', $this->pattern); |  |  |  | 		$this->_template = preg_replace('/<(\w+):?([^>]+)?>/', '<$1>', $this->pattern); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		$this->pattern = '#^' . trim(strtr($this->template, $tr), '/') . '$#u'; |  |  |  | 		$this->pattern = '#^' . trim(strtr($this->_template, $tr), '/') . '$#u'; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if ($this->routeParams !== array()) { |  |  |  | 		if ($this->_routeParams !== array()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			$this->routeRule = '#^' . strtr($this->route, $tr2) . '$#u'; |  |  |  | 			$this->_routeRule = '#^' . strtr($this->route, $tr2) . '$#u'; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	public function parseUrl($pathInfo) |  |  |  | 	public function parseUrl($pathInfo) | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ |  |  |  | 	{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if ($this->verb !== null && !in_array(\Yii::$app->getRequest()->verb, $this->verb, true)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (!preg_match($this->pattern, $pathInfo, $matches)) { |  |  |  | 		if (!preg_match($this->pattern, $pathInfo, $matches)) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			return false; |  |  |  | 			return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
	
		
		
			
				
					|  |  | @ -125,14 +155,14 @@ class UrlRule extends Object | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$params = $this->defaults; |  |  |  | 		$params = $this->defaults; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$tr = array(); |  |  |  | 		$tr = array(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		foreach ($matches as $name => $value) { |  |  |  | 		foreach ($matches as $name => $value) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (isset($this->routeParams[$name])) { |  |  |  | 			if (isset($this->_routeParams[$name])) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				$tr[$this->routeParams[$name]] = $value; |  |  |  | 				$tr[$this->_routeParams[$name]] = $value; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 				unset($params[$name]); |  |  |  | 				unset($params[$name]); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} elseif (isset($this->paramRules[$name])) { |  |  |  | 			} elseif (isset($this->_paramRules[$name])) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 				$params[$name] = $value; |  |  |  | 				$params[$name] = $value; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if ($this->routeRule !== null) { |  |  |  | 		if ($this->_routeRule !== null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			$route = strtr($this->route, $tr); |  |  |  | 			$route = strtr($this->route, $tr); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} else { |  |  |  | 		} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			$route = $this->route; |  |  |  | 			$route = $this->route; | 
			
		
	
	
		
		
			
				
					|  |  | @ -142,12 +172,16 @@ class UrlRule extends Object | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	public function createUrl($route, $params) |  |  |  | 	public function createUrl($route, $params) | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ |  |  |  | 	{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if ($this->parsingOnly) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$tr = array(); |  |  |  | 		$tr = array(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// match the route part first |  |  |  | 		// match the route part first | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if ($route !== $this->route) { |  |  |  | 		if ($route !== $this->route) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if ($this->routeRule !== null && preg_match($this->routeRule, $route, $matches)) { |  |  |  | 			if ($this->_routeRule !== null && preg_match($this->_routeRule, $route, $matches)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				foreach ($this->routeParams as $name => $token) { |  |  |  | 				foreach ($this->_routeParams as $name => $token) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 					if (isset($this->defaults[$name]) && strcmp($this->defaults[$name], $matches[$name]) === 0) { |  |  |  | 					if (isset($this->defaults[$name]) && strcmp($this->defaults[$name], $matches[$name]) === 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 						$tr[$token] = ''; |  |  |  | 						$tr[$token] = ''; | 
			
		
	
		
		
			
				
					
					|  |  |  | 					} else { |  |  |  | 					} else { | 
			
		
	
	
		
		
			
				
					|  |  | @ -162,23 +196,23 @@ class UrlRule extends Object | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// match default params |  |  |  | 		// match default params | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// if a default param is not in the route pattern, its value must also be matched |  |  |  | 		// if a default param is not in the route pattern, its value must also be matched | 
			
		
	
		
		
			
				
					
					|  |  |  | 		foreach ($this->defaults as $name => $value) { |  |  |  | 		foreach ($this->defaults as $name => $value) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (isset($this->routeParams[$name])) { |  |  |  | 			if (isset($this->_routeParams[$name])) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 				continue; |  |  |  | 				continue; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (!isset($params[$name])) { |  |  |  | 			if (!isset($params[$name])) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				return false; |  |  |  | 				return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} elseif (strcmp($params[$name], $value) === 0) { // strcmp will do string conversion automatically |  |  |  | 			} elseif (strcmp($params[$name], $value) === 0) { // strcmp will do string conversion automatically | 
			
		
	
		
		
			
				
					
					|  |  |  | 				unset($params[$name]); |  |  |  | 				unset($params[$name]); | 
			
		
	
		
		
			
				
					
					|  |  |  | 				if (isset($this->paramRules[$name])) { |  |  |  | 				if (isset($this->_paramRules[$name])) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 					$tr["<$name>"] = ''; |  |  |  | 					$tr["<$name>"] = ''; | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} elseif (!isset($this->paramRules[$name])) { |  |  |  | 			} elseif (!isset($this->_paramRules[$name])) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 				return false; |  |  |  | 				return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// match params in the pattern |  |  |  | 		// match params in the pattern | 
			
		
	
		
		
			
				
					
					|  |  |  | 		foreach ($this->paramRules as $name => $rule) { |  |  |  | 		foreach ($this->_paramRules as $name => $rule) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			if (isset($params[$name]) && ($rule === '' || preg_match($rule, $params[$name]))) { |  |  |  | 			if (isset($params[$name]) && ($rule === '' || preg_match($rule, $params[$name]))) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				$tr["<$name>"] = urlencode($params[$name]); |  |  |  | 				$tr["<$name>"] = urlencode($params[$name]); | 
			
		
	
		
		
			
				
					
					|  |  |  | 				unset($params[$name]); |  |  |  | 				unset($params[$name]); | 
			
		
	
	
		
		
			
				
					|  |  | @ -187,7 +221,7 @@ class UrlRule extends Object | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		$url = trim(strtr($this->template, $tr), '/'); |  |  |  | 		$url = trim(strtr($this->_template, $tr), '/'); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		if (strpos($url, '//') !== false) { |  |  |  | 		if (strpos($url, '//') !== false) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			$url = preg_replace('#/+#', '/', $url); |  |  |  | 			$url = preg_replace('#/+#', '/', $url); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
	
		
		
			
				
					|  |  | 
 |