Commit 43c17d99 by Alexander Makarov

Fixes #2426: Changed URL creation method signatures to be consistent

parent 1c9cfc01
......@@ -6,7 +6,7 @@ use yii\helpers\Html;
* @var common\models\User $user
*/
$resetLink = Yii::$app->urlManager->createAbsoluteUrl('site/reset-password', ['token' => $user->password_reset_token]);
$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
?>
Hello <?= Html::encode($user->username) ?>,
......
......@@ -21,8 +21,8 @@ Creating URLs
The most important rule for creating URLs in your site is to always do so using the URL manager. The URL manager is a built-in application component named `urlManager`. This component is accessible from both web and console applications via
`\Yii::$app->urlManager`. The component makes availabe the two following URL creation methods:
- `createUrl($route, $params = [])`
- `createAbsoluteUrl($route, $params = [])`
- `createUrl($params)`
- `createAbsoluteUrl($params, $schema = null)`
The `createUrl` method creates an URL relative to the application root, such as `/index.php/site/index/`.
The `createAbsoluteUrl` method creates an URL prefixed with the proper protocol and hostname:
......@@ -33,11 +33,11 @@ generating RSS feeds etc.
Some examples:
```php
echo \Yii::$app->urlManager->createUrl('site/page', ['id' => 'about']);
echo \Yii::$app->urlManager->createUrl(['site/page', 'id' => 'about']);
// /index.php/site/page/id/about/
echo \Yii::$app->urlManager->createUrl('date-time/fast-forward', ['id' => 105])
echo \Yii::$app->urlManager->createUrl(['date-time/fast-forward', 'id' => 105])
// /index.php?r=date-time/fast-forward&id=105
echo \Yii::$app->urlManager->createAbsoluteUrl('blog/post/index');
echo \Yii::$app->urlManager->createAbsoluteUrl(['blog/post/index']);
// http://www.example.com/index.php/blog/post/index/
```
......@@ -56,15 +56,15 @@ Inside a web application controller, you can use the controller's `createUrl` sh
```php
echo $this->createUrl(''); // currently active route
echo $this->createUrl('view', ['id' => 'contact']); // same controller, different action
echo $this->createUrl('post/index'); // same module, different controller and action
echo $this->createUrl('/site/index'); // absolute route no matter what controller is making this call
echo $this->createurl('hi-tech'); // url for the case sensitive action `actionHiTech` of the current controller
echo $this->createurl('/date-time/fast-forward', ['id' => 105]); // url for action the case sensitive controller, `DateTimeController::actionFastForward`
echo $this->createUrl(['view', 'id' => 'contact']); // same controller, different action
echo $this->createUrl(['post/index']); // same module, different controller and action
echo $this->createUrl(['/site/index']); // absolute route no matter what controller is making this call
echo $this->createurl(['hi-tech']); // url for the case sensitive action `actionHiTech` of the current controller
echo $this->createurl(['/date-time/fast-forward', 'id' => 105]); // url for action the case sensitive controller, `DateTimeController::actionFastForward`
```
> **Tip**: In order to generate URL with a hashtag, for example `/index.php?r=site/page&id=100#title`, you need to
specify the parameter named `#` using `$this->createUrl('post/read', ['id' => 100, '#' => 'title'])`.
specify the parameter named `#` using `$this->createUrl(['post/read', 'id' => 100, '#' => 'title'])`.
Customizing URLs
----------------
......@@ -114,11 +114,11 @@ Let's use some examples to explain how URL rules work. We assume that our rule s
]
```
- Calling `$this->createUrl('post/list')` generates `/index.php/posts`. The first rule is applied.
- Calling `$this->createUrl('post/read', ['id' => 100])` generates `/index.php/post/100`. The second rule is applied.
- Calling `$this->createUrl('post/read', ['year' => 2008, 'title' => 'a sample post'])` generates
- Calling `$this->createUrl(['post/list'])` generates `/index.php/posts`. The first rule is applied.
- Calling `$this->createUrl(['post/read', 'id' => 100])` generates `/index.php/post/100`. The second rule is applied.
- Calling `$this->createUrl(['post/read', 'year' => 2008, 'title' => 'a sample post'])` generates
`/index.php/post/2008/a%20sample%20post`. The third rule is applied.
- Calling `$this->createUrl('post/read')` generates `/index.php/post/read`. None of the rules is applied, convention is used
- Calling `$this->createUrl(['post/read'])` generates `/index.php/post/read`. None of the rules is applied, convention is used
instead.
In summary, when using `createUrl` to generate a URL, the route and the `GET` parameters passed to the method are used to
......
......@@ -236,7 +236,8 @@ class OAuth1 extends BaseOAuth
{
$params = $_GET;
unset($params['oauth_token']);
return Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->controller->getRoute(), $params);
$params[0] = Yii::$app->controller->getRoute();
return Yii::$app->getUrlManager()->createAbsoluteUrl($params);
}
/**
......
......@@ -168,7 +168,8 @@ class OAuth2 extends BaseOAuth
{
$params = $_GET;
unset($params['code']);
return Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->controller->getRoute(), $params);
$params[0] = Yii::$app->controller->getRoute();
return Yii::$app->getUrlManager()->createAbsoluteUrl($params);
}
/**
......
......@@ -199,7 +199,8 @@ class OpenId extends BaseClient implements ClientInterface
unset($params[$name]);
}
}
$url = Yii::$app->getUrlManager()->createUrl(Yii::$app->requestedRoute, $params);
$params[0] = Yii::$app->requestedRoute;
$url = Yii::$app->getUrlManager()->createUrl($params);
return $this->getTrustRoot() . $url;
}
......
......@@ -139,7 +139,8 @@ class LinkedIn extends OAuth2
$params = $_GET;
unset($params['code']);
unset($params['state']);
return Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->controller->getRoute(), $params);
$params[0] = Yii::$app->controller->getRoute();
return Yii::$app->getUrlManager()->createAbsoluteUrl($params);
}
/**
......
......@@ -47,12 +47,10 @@ abstract class BasePage extends Component
public function getUrl($params = [])
{
if (is_string($this->route)) {
return Yii::$app->getUrlManager()->createUrl($this->route, $params);
$params[0] = $this->route;
return Yii::$app->getUrlManager()->createUrl($params);
} elseif (is_array($this->route) && isset($this->route[0])) {
$route = $this->route[0];
$ps = $this->route;
unset($this->route[0]);
return Yii::$app->getUrlManager()->createUrl($route, array_merge($ps, $params));
return Yii::$app->getUrlManager()->createUrl(array_merge($this->route, $params));
} else {
throw new InvalidConfigException('The "route" property must be set.');
}
......
......@@ -124,7 +124,7 @@ class Module extends \yii\base\Module
if (!$this->checkAccess() || Yii::$app->getRequest()->getIsAjax()) {
return;
}
$url = Yii::$app->getUrlManager()->createUrl($this->id . '/default/toolbar', [
$url = Yii::$app->getUrlManager()->createUrl([$this->id . '/default/toolbar',
'tag' => $this->logTarget->tag,
]);
echo '<div id="yii-debug-toolbar" data-url="' . $url . '" style="display:none"></div>';
......
......@@ -88,7 +88,7 @@ class Panel extends Component
*/
public function getUrl()
{
return Yii::$app->getUrlManager()->createUrl($this->module->id . '/default/view', [
return Yii::$app->getUrlManager()->createUrl([$this->module->id . '/default/view',
'panel' => $this->id,
'tag' => $this->tag,
]);
......
......@@ -110,7 +110,7 @@ class DefaultController extends Controller
/**
* @inheritdoc
*/
public function createUrl($route, $params = [])
public function createUrl(array $params)
{
if (!isset($params['id']) && $this->generator !== null) {
foreach ($this->module->generators as $id => $generator) {
......@@ -120,7 +120,7 @@ class DefaultController extends Controller
}
}
}
return parent::createUrl($route, $params);
return parent::createUrl($params);
}
/**
......@@ -139,7 +139,8 @@ class DefaultController extends Controller
}
}
$params['name'] = $name;
return parent::createUrl('action', $params);
$params[0] = 'action';
return parent::createUrl($params);
}
/**
......
......@@ -149,9 +149,9 @@ class Generator extends \yii\gii\Generator
{
$actions = $this->getActionIDs();
if (in_array('index', $actions)) {
$route = $this->controller . '/index';
$route = [$this->controller . '/index'];
} else {
$route = $this->controller . '/' . reset($actions);
$route = [$this->controller . '/' . reset($actions)];
}
$link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($route), ['target' => '_blank']);
return "The controller has been generated successfully. You may $link.";
......
......@@ -84,7 +84,7 @@ class Generator extends \yii\gii\Generator
public function successMessage()
{
if (Yii::$app->hasModule($this->moduleID)) {
$link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($this->moduleID), ['target' => '_blank']);
$link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl([$this->moduleID]), ['target' => '_blank']);
return "The module has been generated successfully. You may $link.";
}
......
......@@ -90,7 +90,7 @@ In these cases, ensure you have converted [[\MongoId]] into the string:
```php
/** @var yii\web\View $this */
echo $this->createUrl('item/update', ['id' => (string)$row['_id']]);
echo $this->createUrl(['item/update', 'id' => (string)$row['_id']]);
```
While building condition, values for the key '_id' will be automatically cast to [[\MongoId]] instance,
......
......@@ -163,6 +163,7 @@ Yii Framework 2 Change Log
- Chg #2248: Renamed `yii\base\Model::DEFAULT_SCENARIO` to `yii\base\Model::SCENARIO_DEFAULT` (samdark)
- Chg #2281: Renamed `ActiveRecord::create()` to `populateRecord()` and changed signature. This method will not call instantiate() anymore (cebe)
- Chg #2405: The CSS class of `MaskedInput` now defaults to `form-control` (qiangxue)
- Chg #2426: Changed URL creation method signatures to be consistent (samdark)
- Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue)
- Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue)
- Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue)
......
......@@ -78,7 +78,7 @@ class Captcha extends InputWidget
} else {
$input = Html::textInput($this->name, $this->value, $this->options);
}
$url = Yii::$app->getUrlManager()->createUrl($this->captchaAction, ['v' => uniqid()]);
$url = Yii::$app->getUrlManager()->createUrl([$this->captchaAction, 'v' => uniqid()]);
$image = Html::img($url, $this->imageOptions);
echo strtr($this->template, [
'{input}' => $input,
......
......@@ -124,7 +124,7 @@ class CaptchaAction extends Action
'hash2' => $this->generateValidationHash(strtolower($code)),
// we add a random 'v' parameter so that FireFox can refresh the image
// when src attribute of image tag is changed
'url' => $controller->createUrl($this->id, ['v' => uniqid()]),
'url' => $controller->createUrl([$this->id, 'v' => uniqid()]),
]);
} else {
$this->setHttpHeaders();
......
......@@ -190,12 +190,12 @@ class Pagination extends Object
} else {
unset($params[$this->pageParam]);
}
$route = $this->route === null ? Yii::$app->controller->getRoute() : $this->route;
$params[0] = $this->route === null ? Yii::$app->controller->getRoute() : $this->route;
$urlManager = $this->urlManager === null ? Yii::$app->getUrlManager() : $this->urlManager;
if ($absolute) {
return $urlManager->createAbsoluteUrl($route, $params);
return $urlManager->createAbsoluteUrl($params);
} else {
return $urlManager->createUrl($route, $params);
return $urlManager->createUrl($params);
}
}
......
......@@ -335,12 +335,12 @@ class Sort extends Object
$params = $request instanceof Request ? $request->getQueryParams() : [];
}
$params[$this->sortParam] = $this->createSortParam($attribute);
$route = $this->route === null ? Yii::$app->controller->getRoute() : $this->route;
$params[0] = $this->route === null ? Yii::$app->controller->getRoute() : $this->route;
$urlManager = $this->urlManager === null ? Yii::$app->getUrlManager() : $this->urlManager;
if ($absolute) {
return $urlManager->createAbsoluteUrl($route, $params);
return $urlManager->createAbsoluteUrl($params);
} else {
return $urlManager->createUrl($route, $params);
return $urlManager->createUrl($params);
}
}
......
......@@ -124,8 +124,8 @@ class ActionColumn extends Column
return call_user_func($this->urlCreator, $action, $model, $key, $index);
} else {
$params = is_array($key) ? $key : ['id' => (string)$key];
$route = $this->controller ? $this->controller . '/' . $action : $action;
return Yii::$app->controller->createUrl($route, $params);
$params[0] = $this->controller ? $this->controller . '/' . $action : $action;
return Yii::$app->controller->createUrl($params);
}
}
......
......@@ -1489,12 +1489,10 @@ class BaseHtml
{
if (is_array($url)) {
if (isset($url[0])) {
$route = $url[0];
$params = array_splice($url, 1);
if (Yii::$app->controller instanceof \yii\web\Controller) {
return Yii::$app->controller->createUrl($route, $params);
return Yii::$app->controller->createUrl($url);
} else {
return Yii::$app->getUrlManager()->createUrl($route, $params);
return Yii::$app->getUrlManager()->createUrl($url);
}
} else {
throw new InvalidParamException('The array specifying a URL must contain at least one element.');
......
......@@ -159,14 +159,13 @@ class Controller extends \yii\base\Controller
*
* After this route conversion, the method calls [[UrlManager::createUrl()]] to create a URL.
*
* @param string $route the route. This can be either an absolute route or a relative route.
* @param array $params the parameters (name-value pairs) to be included in the generated URL
* @param array $params route and parameters in form of ['route', 'param1' => 'value1', 'param2' => 'value2']
* @return string the created relative URL
*/
public function createUrl($route, $params = [])
public function createUrl(array $params)
{
$route = $this->getNormalizedRoute($route);
return Yii::$app->getUrlManager()->createUrl($route, $params);
$params[0] = $this->getNormalizedRoute($params[0]);
return Yii::$app->getUrlManager()->createUrl($params);
}
/**
......@@ -183,16 +182,15 @@ class Controller extends \yii\base\Controller
*
* After this route conversion, the method calls [[UrlManager::createUrl()]] to create a URL.
*
* @param string $route the route. This can be either an absolute route or a relative route.
* @param array $params the parameters (name-value pairs) to be included in the generated URL
* @param array $params route and parameters in form of ['route', 'param1' => 'value1', 'param2' => 'value2']
* @param string $schema the schema to use for the url. e.g. 'http' or 'https'. If not specified
* the schema of the current request will be used.
* @return string the created absolute URL
*/
public function createAbsoluteUrl($route, $params = [], $schema = null)
public function createAbsoluteUrl(array $params, $schema = null)
{
$route = $this->getNormalizedRoute($route);
return Yii::$app->getUrlManager()->createAbsoluteUrl($route, $params, $schema);
$params[0] = $this->getNormalizedRoute($params[0]);
return Yii::$app->getUrlManager()->createAbsoluteUrl($params, $schema);
}
/**
......@@ -208,7 +206,9 @@ class Controller extends \yii\base\Controller
*/
public function getCanonicalUrl()
{
return Yii::$app->getUrlManager()->createAbsoluteUrl($this->getRoute(), $this->actionParams);
$params = $this->actionParams;
$params[0] = $this->getRoute();
return Yii::$app->getUrlManager()->createAbsoluteUrl($params);
}
/**
......
......@@ -228,16 +228,16 @@ class UrlManager extends Component
/**
* Creates a URL using the given route and parameters.
* The URL created is a relative one. Use [[createAbsoluteUrl()]] to create an absolute URL.
* @param string $route the route
* @param array $params the parameters (name-value pairs)
* @param array $params route and parameters in form of ['route', 'param1' => 'value1', 'param2' => 'value2']
* @return string the created URL
*/
public function createUrl($route, $params = [])
public function createUrl(array $params)
{
$anchor = isset($params['#']) ? '#' . $params['#'] : '';
unset($params['#'], $params[$this->routeParam]);
$route = trim($route, '/');
$route = trim($params[0], '/');
unset($params[0]);
$baseUrl = $this->getBaseUrl();
if ($this->enablePrettyUrl) {
......@@ -275,16 +275,15 @@ class UrlManager extends Component
/**
* Creates an absolute URL using the given route and parameters.
* This method prepends the URL created by [[createUrl()]] with the [[hostInfo]].
* @param string $route the route
* @param array $params the parameters (name-value pairs)
* @param array $params route and parameters in form of ['route', 'param1' => 'value1', 'param2' => 'value2']
* @param string $schema the schema to use for the url. e.g. 'http' or 'https'. If not specified
* the schema of the current request will be used.
* @return string the created URL
* @see createUrl()
*/
public function createAbsoluteUrl($route, $params = [], $schema = null)
public function createAbsoluteUrl(array $params, $schema = null)
{
$url = $this->createUrl($route, $params);
$url = $this->createUrl($params);
if (strpos($url, '://') === false) {
$url = $this->getHostInfo($schema) . $url;
}
......
......@@ -23,9 +23,9 @@ class UrlManagerTest extends TestCase
'baseUrl' => '/',
'cache' => null,
]);
$url = $manager->createUrl('post/view');
$url = $manager->createUrl(['post/view']);
$this->assertEquals('?r=post/view', $url);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('?r=post/view&id=1&title=sample+post', $url);
// default setting with '/test/' as base url
......@@ -33,7 +33,7 @@ class UrlManagerTest extends TestCase
'baseUrl' => '/test/',
'cache' => null,
]);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('/test?r=post/view&id=1&title=sample+post', $url);
// pretty URL without rules
......@@ -42,21 +42,21 @@ class UrlManagerTest extends TestCase
'baseUrl' => '/',
'cache' => null,
]);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('/post/view?id=1&title=sample+post', $url);
$manager = new UrlManager([
'enablePrettyUrl' => true,
'baseUrl' => '/test/',
'cache' => null,
]);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('/test/post/view?id=1&title=sample+post', $url);
$manager = new UrlManager([
'enablePrettyUrl' => true,
'baseUrl' => '/test/index.php',
'cache' => null,
]);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('/test/index.php/post/view?id=1&title=sample+post', $url);
// todo: test showScriptName
......@@ -73,9 +73,9 @@ class UrlManagerTest extends TestCase
],
'baseUrl' => '/',
]);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('/post/1/sample+post', $url);
$url = $manager->createUrl('post/index', ['page' => 1]);
$url = $manager->createUrl(['post/index', 'page' => 1]);
$this->assertEquals('/post/index?page=1', $url);
// pretty URL with rules and suffix
......@@ -91,9 +91,9 @@ class UrlManagerTest extends TestCase
'baseUrl' => '/',
'suffix' => '.html',
]);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('/post/1/sample+post.html', $url);
$url = $manager->createUrl('post/index', ['page' => 1]);
$url = $manager->createUrl(['post/index', 'page' => 1]);
$this->assertEquals('/post/index.html?page=1', $url);
// pretty URL with rules that have host info
......@@ -109,9 +109,9 @@ class UrlManagerTest extends TestCase
],
'baseUrl' => '/test',
]);
$url = $manager->createUrl('post/view', ['id' => 1, 'title' => 'sample post', 'lang' => 'en']);
$url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post', 'lang' => 'en']);
$this->assertEquals('http://en.example.com/test/post/1/sample+post', $url);
$url = $manager->createUrl('post/index', ['page' => 1]);
$url = $manager->createUrl(['post/index', 'page' => 1]);
$this->assertEquals('/test/post/index?page=1', $url);
}
......@@ -122,14 +122,14 @@ class UrlManagerTest extends TestCase
'hostInfo' => 'http://www.example.com',
'cache' => null,
]);
$url = $manager->createAbsoluteUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$url = $manager->createAbsoluteUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
$this->assertEquals('http://www.example.com?r=post/view&id=1&title=sample+post', $url);
$url = $manager->createAbsoluteUrl('post/view', ['id' => 1, 'title' => 'sample post'], 'https');
$url = $manager->createAbsoluteUrl(['post/view', 'id' => 1, 'title' => 'sample post'], 'https');
$this->assertEquals('https://www.example.com?r=post/view&id=1&title=sample+post', $url);
$manager->hostInfo = 'https://www.example.com';
$url = $manager->createAbsoluteUrl('post/view', ['id' => 1, 'title' => 'sample post'], 'http');
$url = $manager->createAbsoluteUrl(['post/view', 'id' => 1, 'title' => 'sample post'], 'http');
$this->assertEquals('http://www.example.com?r=post/view&id=1&title=sample+post', $url);
}
......@@ -309,7 +309,7 @@ class UrlManagerTest extends TestCase
]
]
], \yii\web\Application::className());
$this->assertEquals('/app/post/delete?id=123', $manager->createUrl('post/delete', ['id' => 123]));
$this->assertEquals('/app/post/delete?id=123', $manager->createUrl(['post/delete', 'id' => 123]));
$this->destroyApplication();
unset($_SERVER['REQUEST_METHOD']);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment