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);
$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://<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()

26
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),
),
),
);
}
}

23
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, '/');
}
/**

25
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);
}

Loading…
Cancel
Save