diff --git a/tests/unit/framework/web/UrlManagerTest.php b/tests/unit/framework/web/UrlManagerTest.php index 95b3bf6..1c522c3 100644 --- a/tests/unit/framework/web/UrlManagerTest.php +++ b/tests/unit/framework/web/UrlManagerTest.php @@ -85,6 +85,23 @@ class UrlManagerTest extends \yiiunit\TestCase $this->assertEquals('/post/1/sample+post.html', $url); $url = $manager->createUrl('post/index', array('page' => 1)); $this->assertEquals('/post/index.html?page=1', $url); + + // pretty URL with rules that have host info + $manager = new UrlManager(array( + 'enablePrettyUrl' => true, + 'cache' => null, + 'rules' => array( + array( + 'pattern' => 'http://.example.com/post//', + 'route' => 'post/view', + ), + ), + 'baseUrl' => '/test', + )); + $url = $manager->createUrl('post/view', array('id' => 1, 'title' => 'sample post', 'lang' => 'en')); + $this->assertEquals('http://en.example.com/test/post/1/sample+post', $url); + $url = $manager->createUrl('post/index', array('page' => 1)); + $this->assertEquals('/test/post/index?page=1', $url); } public function testCreateAbsoluteUrl() diff --git a/tests/unit/framework/web/UrlRuleTest.php b/tests/unit/framework/web/UrlRuleTest.php index 825199e..85d410a 100644 --- a/tests/unit/framework/web/UrlRuleTest.php +++ b/tests/unit/framework/web/UrlRuleTest.php @@ -26,7 +26,7 @@ class UrlRuleTest extends \yiiunit\TestCase public function testParseRequest() { $manager = new UrlManager(array('cache' => null)); - $request = new Request; + $request = new Request(array('hostInfo' => 'http://en.example.com')); $suites = $this->getTestsForParseRequest(); foreach ($suites as $i => $suite) { list ($name, $config, $tests) = $suite; @@ -327,6 +327,18 @@ class UrlRuleTest extends \yiiunit\TestCase array('post/index', array('page' => 1), 'posts/?page=1'), ), ), + array( + 'with host info', + array( + 'pattern' => 'http://<lang:(en|fr)>.example.com/post/<page:\d+>/<tag>', + 'route' => 'post/index', + 'defaults' => array('page' => 1), + ), + array( + array('post/index', array('page' => 1, 'tag' => 'a'), false), + array('post/index', array('page' => 1, 'tag' => 'a', 'lang' => 'en'), 'http://en.example.com/post/a'), + ), + ), ); } @@ -610,6 +622,18 @@ class UrlRuleTest extends \yiiunit\TestCase array('a', false), ), ), + array( + 'with host info', + array( + 'pattern' => 'http://<lang:en|fr>.example.com/post/<page:\d+>', + 'route' => 'post/index', + ), + array( + array('post/1', 'post/index', array('page' => '1', 'lang' => 'en')), + array('post/a', false), + array('post/1/a', false), + ), + ), ); } } diff --git a/yii/web/UrlManager.php b/yii/web/UrlManager.php index aab7979..7a03a93 100644 --- a/yii/web/UrlManager.php +++ b/yii/web/UrlManager.php @@ -183,7 +183,15 @@ class UrlManager extends Component /** @var $rule UrlRule */ foreach ($this->rules as $rule) { if (($url = $rule->createUrl($this, $route, $params)) !== false) { - return rtrim($baseUrl, '/') . '/' . $url . $anchor; + if ($rule->hasHostInfo) { + if ($baseUrl !== '' && ($pos = strpos($url, '/', 8)) !== false) { + return substr($url, 0, $pos) . $baseUrl . substr($url, $pos); + } else { + return $url . $baseUrl . $anchor; + } + } else { + return "$baseUrl/{$url}{$anchor}"; + } } } @@ -193,9 +201,9 @@ class UrlManager extends Component if (!empty($params)) { $route .= '?' . http_build_query($params); } - return rtrim($baseUrl, '/') . '/' . $route . $anchor; + return "$baseUrl/{$route}{$anchor}"; } else { - $url = $baseUrl . '?' . $this->routeVar . '=' . $route; + $url = "$baseUrl/?{$this->routeVar}=$route"; if (!empty($params)) { $url .= '&' . http_build_query($params); } @@ -213,7 +221,12 @@ class UrlManager extends Component */ public function createAbsoluteUrl($route, $params = array()) { - return $this->getHostInfo() . $this->createUrl($route, $params); + $url = $this->createUrl($route, $params); + if (strpos($url, '://') !== false) { + return $url; + } else { + return $this->getHostInfo() . $url; + } } /** @@ -238,7 +251,7 @@ class UrlManager extends Component */ public function setBaseUrl($value) { - $this->_baseUrl = $value; + $this->_baseUrl = rtrim($value, '/'); } /** diff --git a/yii/web/UrlRule.php b/yii/web/UrlRule.php index ed2bc14..7243b1b 100644 --- a/yii/web/UrlRule.php +++ b/yii/web/UrlRule.php @@ -28,7 +28,7 @@ class UrlRule extends Object const CREATION_ONLY = 2; /** - * @var string regular expression used to parse a URL + * @var string the pattern used to parse and create URLs. */ public $pattern; /** @@ -62,6 +62,11 @@ class UrlRule extends Object * If it is [[CREATION_ONLY]], the rule is for URL creation only. */ public $mode; + /** + * @var boolean whether this URL rule contains the host info part. + * This property is set after the URL rule is parsed. + */ + public $hasHostInfo; /** * @var string the template for generating a new URL. This is derived from [[pattern]] and is used in generating URL. @@ -102,6 +107,9 @@ class UrlRule extends Object } $this->pattern = trim($this->pattern, '/'); + + $this->hasHostInfo = !strncasecmp($this->pattern, 'http://', 7) || !strncasecmp($this->pattern, 'https://', 8); + if ($this->pattern === '') { $this->_template = ''; $this->pattern = '#^$#u'; @@ -162,11 +170,11 @@ class UrlRule extends Object return false; } - if ($this->verb !== null && !in_array($request->verb, $this->verb, true)) { + if ($this->verb !== null && !in_array($request->getRequestMethod(), $this->verb, true)) { return false; } - $pathInfo = $request->pathInfo; + $pathInfo = $request->getPathInfo(); $suffix = (string)($this->suffix === null ? $manager->suffix : $this->suffix); if ($suffix !== '' && $pathInfo !== '') { $n = strlen($suffix); @@ -182,6 +190,10 @@ class UrlRule extends Object } } + if ($this->hasHostInfo) { + $pathInfo = strtolower($request->getHostInfo()) . '/' . $pathInfo; + } + if (!preg_match($this->pattern, $pathInfo, $matches)) { return false; } @@ -267,7 +279,12 @@ class UrlRule extends Object } $url = trim(strtr($this->_template, $tr), '/'); - if (strpos($url, '//') !== false) { + if ($this->hasHostInfo) { + $pos = strpos($url, '/', 8); + if ($pos !== false) { + $url = substr($url, 0, $pos) . preg_replace('#/+#', '/', substr($url, $pos)); + } + } elseif (strpos($url, '//') !== false) { $url = preg_replace('#/+#', '/', $url); }