Browse Source

Fixes issue #268: added support for subdomain matching of URL rules.

tags/2.0.0-beta
Qiang Xue 12 years ago
parent
commit
e6b52b8523
  1. 17
      tests/unit/framework/web/UrlManagerTest.php
  2. 26
      tests/unit/framework/web/UrlRuleTest.php
  3. 23
      yii/web/UrlManager.php
  4. 25
      yii/web/UrlRule.php

17
tests/unit/framework/web/UrlManagerTest.php

@ -85,6 +85,23 @@ class UrlManagerTest extends \yiiunit\TestCase
$this->assertEquals('/post/1/sample+post.html', $url); $this->assertEquals('/post/1/sample+post.html', $url);
$url = $manager->createUrl('post/index', array('page' => 1)); $url = $manager->createUrl('post/index', array('page' => 1));
$this->assertEquals('/post/index.html?page=1', $url); $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://<lang:en|fr>.example.com/post/<id>/<title>',
'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() public function testCreateAbsoluteUrl()

26
tests/unit/framework/web/UrlRuleTest.php

@ -26,7 +26,7 @@ class UrlRuleTest extends \yiiunit\TestCase
public function testParseRequest() public function testParseRequest()
{ {
$manager = new UrlManager(array('cache' => null)); $manager = new UrlManager(array('cache' => null));
$request = new Request; $request = new Request(array('hostInfo' => 'http://en.example.com'));
$suites = $this->getTestsForParseRequest(); $suites = $this->getTestsForParseRequest();
foreach ($suites as $i => $suite) { foreach ($suites as $i => $suite) {
list ($name, $config, $tests) = $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('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('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),
),
),
); );
} }
} }

23
yii/web/UrlManager.php

@ -183,7 +183,15 @@ class UrlManager extends Component
/** @var $rule UrlRule */ /** @var $rule UrlRule */
foreach ($this->rules as $rule) { foreach ($this->rules as $rule) {
if (($url = $rule->createUrl($this, $route, $params)) !== false) { 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)) { if (!empty($params)) {
$route .= '?' . http_build_query($params); $route .= '?' . http_build_query($params);
} }
return rtrim($baseUrl, '/') . '/' . $route . $anchor; return "$baseUrl/{$route}{$anchor}";
} else { } else {
$url = $baseUrl . '?' . $this->routeVar . '=' . $route; $url = "$baseUrl/?{$this->routeVar}=$route";
if (!empty($params)) { if (!empty($params)) {
$url .= '&' . http_build_query($params); $url .= '&' . http_build_query($params);
} }
@ -213,7 +221,12 @@ class UrlManager extends Component
*/ */
public function createAbsoluteUrl($route, $params = array()) 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) public function setBaseUrl($value)
{ {
$this->_baseUrl = $value; $this->_baseUrl = rtrim($value, '/');
} }
/** /**

25
yii/web/UrlRule.php

@ -28,7 +28,7 @@ class UrlRule extends Object
const CREATION_ONLY = 2; 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; public $pattern;
/** /**
@ -62,6 +62,11 @@ class UrlRule extends Object
* If it is [[CREATION_ONLY]], the rule is for URL creation only. * If it is [[CREATION_ONLY]], the rule is for URL creation only.
*/ */
public $mode; 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. * @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->pattern = trim($this->pattern, '/');
$this->hasHostInfo = !strncasecmp($this->pattern, 'http://', 7) || !strncasecmp($this->pattern, 'https://', 8);
if ($this->pattern === '') { if ($this->pattern === '') {
$this->_template = ''; $this->_template = '';
$this->pattern = '#^$#u'; $this->pattern = '#^$#u';
@ -162,11 +170,11 @@ class UrlRule extends Object
return false; 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; return false;
} }
$pathInfo = $request->pathInfo; $pathInfo = $request->getPathInfo();
$suffix = (string)($this->suffix === null ? $manager->suffix : $this->suffix); $suffix = (string)($this->suffix === null ? $manager->suffix : $this->suffix);
if ($suffix !== '' && $pathInfo !== '') { if ($suffix !== '' && $pathInfo !== '') {
$n = strlen($suffix); $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)) { if (!preg_match($this->pattern, $pathInfo, $matches)) {
return false; return false;
} }
@ -267,7 +279,12 @@ class UrlRule extends Object
} }
$url = trim(strtr($this->_template, $tr), '/'); $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); $url = preg_replace('#/+#', '/', $url);
} }

Loading…
Cancel
Save