BaseUrl.php 7.53 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\helpers;

use yii\base\InvalidParamException;
use Yii;

/**
 * BaseUrl provides concrete implementation for [[Url]].
 *
 * Do not use BaseUrl. Use [[Url]] instead.
 *
 * @author Alexander Makarov <sam@rmcreative.ru>
 * @since 2.0
 */
class BaseUrl
{
	/**
24
	 * Returns URL for a route.
25
	 *
26
	 * @param array|string $route route as a string or route and parameters in form of
27
	 * `['route', 'param1' => 'value1', 'param2' => 'value2']`.
28
	 *
29 30
	 * If there is a controller running relative routes are recognized:
	 *
31
	 * - If the route is an empty string, the current [[\yii\web\Controller::route]] will be used;
32
	 * - If the route contains no slashes at all, it is considered to be an action ID
33
	 *   of the current controller and will be prepended with [[\yii\web\Controller::uniqueId]];
34 35 36
	 * - If the route has no leading slash, it is considered to be a route relative
	 *   to the current module and will be prepended with the module's uniqueId.
	 *
37
	 * In case there is no controller, [[\yii\web\UrlManager::createUrl()]] will be used.
38
	 *
39 40 41 42 43 44
	 * @param boolean|string $schema URI schema to use:
	 *
	 * - `false`: relative URL. Default behavior.
	 * - `true`: absolute URL with the current scheme.
	 * - string: absolute URL with string value used as schema.
	 *
45 46 47
	 * @return string the normalized URL
	 * @throws InvalidParamException if the parameter is invalid.
	 */
48
	public static function toRoute($route, $schema = false)
49
	{
50 51 52
		$route = (array)$route;
		if (!isset($route[0])) {
			throw new InvalidParamException('$route should contain at least one element.');
53 54
		}
		if (Yii::$app->controller instanceof \yii\web\Controller) {
55
			$route[0] = static::getNormalizedRoute($route[0]);
56
		}
57
		return $schema ? Yii::$app->getUrlManager()->createAbsoluteUrl($route, $schema) : Yii::$app->getUrlManager()->createUrl($route);
58 59 60 61 62 63 64 65
	}

	/**
	 * Normalizes route making it suitable for UrlManager. Absolute routes are staying as is
	 * while relative routes are converted to absolute routes.
	 *
	 * A relative route is a route without a leading slash, such as "view", "post/view".
	 *
66
	 * - If the route is an empty string, the current [[\yii\web\Controller::route]] will be used;
67
	 * - If the route contains no slashes at all, it is considered to be an action ID
68
	 *   of the current controller and will be prepended with [[\yii\web\Controller::uniqueId]];
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
	 * - If the route has no leading slash, it is considered to be a route relative
	 *   to the current module and will be prepended with the module's uniqueId.
	 *
	 * @param string $route the route. This can be either an absolute route or a relative route.
	 * @return string normalized route suitable for UrlManager
	 */
	private static function getNormalizedRoute($route)
	{
		if (strpos($route, '/') === false) {
			// empty or an action ID
			$route = $route === '' ? Yii::$app->controller->getRoute() : Yii::$app->controller->getUniqueId() . '/' . $route;
		} elseif ($route[0] !== '/') {
			// relative to module
			$route = ltrim(Yii::$app->controller->module->getUniqueId() . '/' . $route, '/');
		}
		return $route;
85
	}
Alexander Makarov committed
86

87
	/**
88
	 * Creates a link specified by the input parameter.
89
	 *
90 91 92 93 94 95
	 * If the input parameter
	 *
	 * - is an array: the first array element is considered a route, while the rest of the name-value
	 *   pairs are treated as the parameters to be used for URL creation using [[\yii\web\Controller::createUrl()]].
	 *   For example: `['post/index', 'page' => 2]`, `['index']`.
	 *   In case there is no controller, [[\yii\web\UrlManager::createUrl()]] will be used.
96 97 98 99 100
	 * - is an empty string: the currently requested URL will be returned;
	 * - is a non-empty string: it will first be processed by [[Yii::getAlias()]]. If the result
	 *   is an absolute URL, it will be returned without any change further; Otherwise, the result
	 *   will be prefixed with [[\yii\web\Request::baseUrl]] and returned.

101 102
	 *
	 * @param array|string $url the parameter to be used to generate a valid URL
103 104 105 106 107 108
	 * @param boolean|string $schema URI schema to use:
	 *
	 * - `false`: relative URL. Default behavior.
	 * - `true`: absolute URL with the current scheme.
	 * - string: absolute URL with string value used as schema.
	 *
109 110
	 * @return string the normalized URL
	 * @throws InvalidParamException if the parameter is invalid.
111
	 */
112
	public static function to($url = '', $schema = false)
113
	{
114
		if (is_array($url)) {
115
			return static::toRoute($url, $schema);
116
		} elseif ($url === '') {
117
			if ($schema) {
118
				$url = Yii::$app->request->getAbsoluteUrl();
119 120 121 122
				if ($schema !== true) {
					$pos = strpos($url, '://');
					$url = $schema . substr($url, $pos);
				}
123 124
			} else {
				$url = Yii::$app->request->getUrl();
125
			}
126
		} else {
127
			$url = Yii::getAlias($url);
128 129
			$pos = strpos($url, '://');
			if ($pos !== null) {
130
				// URI is already absolute, adjust schema if specified
131
				if ($schema  && $schema !== true) {
132 133
					$url = $schema . substr($url, $pos);
				}
134
			} else {
135 136 137 138 139
				// URI is relative
				if ($url === '' || ($url[0] !== '/' && $url[0] !== '#' && strncmp($url, './', 2))) {
					// URL is relative need to adjust it to be absolute
					$url = Yii::$app->getRequest()->getBaseUrl() . '/' . $url;
				}
140
				if ($schema) {
141
					$url = Yii::$app->getRequest()->getHostInfo() . $url;
142
					if ($schema !== true) {
143 144 145 146 147
						$pos = strpos($url, '://');
						if ($pos !== null) {
							$url = $schema . substr($url, $pos);
						}
					}
148
				}
149 150
			}
		}
151
		return $url;
152 153
	}

Alexander Makarov committed
154
	/**
155
	 * Remembers URL passed
Alexander Makarov committed
156
	 *
157 158
	 * @param string $url URL to remember. Default is current URL.
	 * @param string $name Name to use to remember URL. Defaults to `yii\web\User::returnUrlParam`.
Alexander Makarov committed
159
	 */
160
	public static function remember($url = '', $name = null)
Alexander Makarov committed
161
	{
162
		if ($url === '') {
163 164 165 166
			$url = Yii::$app->getRequest()->getUrl();
		}

		if ($name === null) {
167
			Yii::$app->getUser()->setReturnUrl($url);
168
		} else {
169
			Yii::$app->getSession()->set($name, $url);
170
		}
Alexander Makarov committed
171
	}
172 173

	/**
174 175 176 177
	 * Returns URL previously saved with remember method
	 *
	 * @param string $name Name used to remember URL. Defaults to `yii\web\User::returnUrlParam`.
	 * @return string URL
178
	 */
179
	public static function previous($name = null)
180
	{
181
		if ($name === null) {
182
			return Yii::$app->getUser()->getReturnUrl();
183
		} else {
184
			return Yii::$app->getSession()->get($name);
185
		}
186
	}
Alexander Makarov committed
187 188

	/**
189 190 191 192 193 194 195 196
	 * Returns the canonical URL of the currently requested page.
	 * The canonical URL is constructed using current controller's [[yii\web\Controller::route]] and
	 * [[yii\web\Controller::actionParams]]. You may use the following code in the layout view to add a link tag
	 * about canonical URL:
	 *
	 * ```php
	 * $this->registerLinkTag(['rel' => 'canonical', 'href' => Url::canonical()]);
	 * ```
Alexander Makarov committed
197
	 *
198
	 * @return string the canonical URL of the currently requested page
Alexander Makarov committed
199
	 */
200
	public static function canonical()
Alexander Makarov committed
201
	{
202 203 204
		$params = Yii::$app->controller->actionParams;
		$params[0] = Yii::$app->controller->getRoute();
		return Yii::$app->getUrlManager()->createAbsoluteUrl($params);
Alexander Makarov committed
205
	}
206 207 208 209

	/**
	 * Returns home URL
	 *
210 211 212 213 214 215
	 * @param boolean|string $schema URI schema to use:
	 *
	 * - `false`: relative URL. Default behavior.
	 * - `true`: absolute URL with the current scheme.
	 * - string: absolute URL with string value used as schema.
	 *
216 217
	 * @return string home URL
	 */
218
	public static function home($schema = false)
219
	{
220
		if ($schema) {
221
			$url = Yii::$app->getRequest()->getHostInfo() . Yii::$app->getHomeUrl();
222
			if ($schema !== true) {
223 224 225 226 227
				$pos = strpos($url, '://');
				$url = $schema . substr($url, $pos);
			}
		} else {
			$url = Yii::$app->getHomeUrl();
228
		}
229
		return $url;
230
	}
231 232
}