1 | <?php |
||||||
2 | /** |
||||||
3 | * @link https://www.yiiframework.com/ |
||||||
4 | * @copyright Copyright (c) 2008 Yii Software LLC |
||||||
5 | * @license https://www.yiiframework.com/license/ |
||||||
6 | */ |
||||||
7 | |||||||
8 | namespace yii\helpers; |
||||||
9 | |||||||
10 | use Yii; |
||||||
11 | use yii\base\InvalidArgumentException; |
||||||
12 | |||||||
13 | /** |
||||||
14 | * BaseUrl provides concrete implementation for [[Url]]. |
||||||
15 | * |
||||||
16 | * Do not use BaseUrl. Use [[Url]] instead. |
||||||
17 | * |
||||||
18 | * @author Alexander Makarov <[email protected]> |
||||||
19 | * @since 2.0 |
||||||
20 | */ |
||||||
21 | class BaseUrl |
||||||
22 | { |
||||||
23 | /** |
||||||
24 | * @var \yii\web\UrlManager URL manager to use for creating URLs |
||||||
25 | * @since 2.0.8 |
||||||
26 | */ |
||||||
27 | public static $urlManager; |
||||||
28 | |||||||
29 | |||||||
30 | /** |
||||||
31 | * Creates a URL for the given route. |
||||||
32 | * |
||||||
33 | * This method will use [[\yii\web\UrlManager]] to create a URL. |
||||||
34 | * |
||||||
35 | * You may specify the route as a string, e.g., `site/index`. You may also use an array |
||||||
36 | * if you want to specify additional query parameters for the URL being created. The |
||||||
37 | * array format must be: |
||||||
38 | * |
||||||
39 | * ```php |
||||||
40 | * // generates: /index.php?r=site/index¶m1=value1¶m2=value2 |
||||||
41 | * ['site/index', 'param1' => 'value1', 'param2' => 'value2'] |
||||||
42 | * ``` |
||||||
43 | * |
||||||
44 | * If you want to create a URL with an anchor, you can use the array format with a `#` parameter. |
||||||
45 | * For example, |
||||||
46 | * |
||||||
47 | * ```php |
||||||
48 | * // generates: /index.php?r=site/index¶m1=value1#name |
||||||
49 | * ['site/index', 'param1' => 'value1', '#' => 'name'] |
||||||
50 | * ``` |
||||||
51 | * |
||||||
52 | * A route may be either absolute or relative. An absolute route has a leading slash (e.g. `/site/index`), |
||||||
53 | * while a relative route has none (e.g. `site/index` or `index`). A relative route will be converted |
||||||
54 | * into an absolute one by the following rules: |
||||||
55 | * |
||||||
56 | * - If the route is an empty string, the current [[\yii\web\Controller::route|route]] will be used; |
||||||
57 | * - If the route contains no slashes at all (e.g. `index`), it is considered to be an action ID |
||||||
58 | * of the current controller and will be prepended with [[\yii\web\Controller::uniqueId]]; |
||||||
59 | * - If the route has no leading slash (e.g. `site/index`), it is considered to be a route relative |
||||||
60 | * to the current module and will be prepended with the module's [[\yii\base\Module::uniqueId|uniqueId]]. |
||||||
61 | * |
||||||
62 | * Starting from version 2.0.2, a route can also be specified as an alias. In this case, the alias |
||||||
63 | * will be converted into the actual route first before conducting the above transformation steps. |
||||||
64 | * |
||||||
65 | * Below are some examples of using this method: |
||||||
66 | * |
||||||
67 | * ```php |
||||||
68 | * // /index.php?r=site%2Findex |
||||||
69 | * echo Url::toRoute('site/index'); |
||||||
70 | * |
||||||
71 | * // /index.php?r=site%2Findex&src=ref1#name |
||||||
72 | * echo Url::toRoute(['site/index', 'src' => 'ref1', '#' => 'name']); |
||||||
73 | * |
||||||
74 | * // https://www.example.com/index.php?r=site%2Findex |
||||||
75 | * echo Url::toRoute('site/index', true); |
||||||
76 | * |
||||||
77 | * // https://www.example.com/index.php?r=site%2Findex |
||||||
78 | * echo Url::toRoute('site/index', 'https'); |
||||||
79 | * |
||||||
80 | * // /index.php?r=post%2Findex assume the alias "@posts" is defined as "post/index" |
||||||
81 | * echo Url::toRoute('@posts'); |
||||||
82 | * ``` |
||||||
83 | * |
||||||
84 | * @param string|array $route use a string to represent a route (e.g. `index`, `site/index`), |
||||||
85 | * or an array to represent a route with query parameters (e.g. `['site/index', 'param1' => 'value1']`). |
||||||
86 | * @param bool|string $scheme the URI scheme to use in the generated URL: |
||||||
87 | * |
||||||
88 | * - `false` (default): generating a relative URL. |
||||||
89 | * - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]]. |
||||||
90 | * - string: generating an absolute URL with the specified scheme (either `http`, `https` or empty string |
||||||
91 | * for protocol-relative URL). |
||||||
92 | * |
||||||
93 | * @return string the generated URL |
||||||
94 | * @throws InvalidArgumentException a relative route is given while there is no active controller |
||||||
95 | */ |
||||||
96 | 14 | public static function toRoute($route, $scheme = false) |
|||||
97 | { |
||||||
98 | 14 | $route = (array) $route; |
|||||
99 | 14 | $route[0] = static::normalizeRoute($route[0]); |
|||||
100 | |||||||
101 | 14 | if ($scheme !== false) { |
|||||
102 | 3 | return static::getUrlManager()->createAbsoluteUrl($route, is_string($scheme) ? $scheme : null); |
|||||
103 | } |
||||||
104 | |||||||
105 | 13 | return static::getUrlManager()->createUrl($route); |
|||||
106 | } |
||||||
107 | |||||||
108 | /** |
||||||
109 | * Normalizes route and makes it suitable for UrlManager. Absolute routes are staying as is |
||||||
110 | * while relative routes are converted to absolute ones. |
||||||
111 | * |
||||||
112 | * A relative route is a route without a leading slash, such as "view", "post/view". |
||||||
113 | * |
||||||
114 | * - If the route is an empty string, the current [[\yii\web\Controller::route|route]] will be used; |
||||||
115 | * - If the route contains no slashes at all, it is considered to be an action ID |
||||||
116 | * of the current controller and will be prepended with [[\yii\web\Controller::uniqueId]]; |
||||||
117 | * - If the route has no leading slash, it is considered to be a route relative |
||||||
118 | * to the current module and will be prepended with the module's uniqueId. |
||||||
119 | * |
||||||
120 | * Starting from version 2.0.2, a route can also be specified as an alias. In this case, the alias |
||||||
121 | * will be converted into the actual route first before conducting the above transformation steps. |
||||||
122 | * |
||||||
123 | * @param string $route the route. This can be either an absolute route or a relative route. |
||||||
124 | * @return string normalized route suitable for UrlManager |
||||||
125 | * @throws InvalidArgumentException a relative route is given while there is no active controller |
||||||
126 | */ |
||||||
127 | 14 | protected static function normalizeRoute($route) |
|||||
128 | { |
||||||
129 | 14 | $route = Yii::getAlias((string) $route); |
|||||
130 | 14 | if (strncmp($route, '/', 1) === 0) { |
|||||
131 | // absolute route |
||||||
132 | 13 | return ltrim($route, '/'); |
|||||
133 | } |
||||||
134 | |||||||
135 | // relative route |
||||||
136 | 3 | if (Yii::$app->controller === null) { |
|||||
137 | 2 | throw new InvalidArgumentException("Unable to resolve the relative route: $route. No active controller is available."); |
|||||
138 | } |
||||||
139 | |||||||
140 | 3 | if (strpos($route, '/') === false) { |
|||||
141 | // empty or an action ID |
||||||
142 | 3 | return $route === '' ? Yii::$app->controller->getRoute() : Yii::$app->controller->getUniqueId() . '/' . $route; |
|||||
143 | } |
||||||
144 | |||||||
145 | // relative to module |
||||||
146 | 1 | return ltrim(Yii::$app->controller->module->getUniqueId() . '/' . $route, '/'); |
|||||
147 | } |
||||||
148 | |||||||
149 | /** |
||||||
150 | * Creates a URL based on the given parameters. |
||||||
151 | * |
||||||
152 | * This method is very similar to [[toRoute()]]. The only difference is that this method |
||||||
153 | * requires a route to be specified as an array only. If a string is given, it will be treated as a URL. |
||||||
154 | * In particular, if `$url` is |
||||||
155 | * |
||||||
156 | * - an array: [[toRoute()]] will be called to generate the URL. For example: |
||||||
157 | * `['site/index']`, `['post/index', 'page' => 2]`. Please refer to [[toRoute()]] for more details |
||||||
158 | * on how to specify a route. |
||||||
159 | * - a string with a leading `@`: it is treated as an alias, and the corresponding aliased string |
||||||
160 | * will be returned. |
||||||
161 | * - an empty string: the currently requested URL will be returned; |
||||||
162 | * - a normal string: it will be returned as is. |
||||||
163 | * |
||||||
164 | * When `$scheme` is specified (either a string or `true`), an absolute URL with host info (obtained from |
||||||
165 | * [[\yii\web\UrlManager::$hostInfo]]) will be returned. If `$url` is already an absolute URL, its scheme |
||||||
166 | * will be replaced with the specified one. |
||||||
167 | * |
||||||
168 | * Below are some examples of using this method: |
||||||
169 | * |
||||||
170 | * ```php |
||||||
171 | * // /index.php?r=site%2Findex |
||||||
172 | * echo Url::to(['site/index']); |
||||||
173 | * |
||||||
174 | * // /index.php?r=site%2Findex&src=ref1#name |
||||||
175 | * echo Url::to(['site/index', 'src' => 'ref1', '#' => 'name']); |
||||||
176 | * |
||||||
177 | * // /index.php?r=post%2Findex assume the alias "@posts" is defined as "/post/index" |
||||||
178 | * echo Url::to(['@posts']); |
||||||
179 | * |
||||||
180 | * // the currently requested URL |
||||||
181 | * echo Url::to(); |
||||||
182 | * |
||||||
183 | * // /images/logo.gif |
||||||
184 | * echo Url::to('@web/images/logo.gif'); |
||||||
185 | * |
||||||
186 | * // images/logo.gif |
||||||
187 | * echo Url::to('images/logo.gif'); |
||||||
188 | * |
||||||
189 | * // https://www.example.com/images/logo.gif |
||||||
190 | * echo Url::to('@web/images/logo.gif', true); |
||||||
191 | * |
||||||
192 | * // https://www.example.com/images/logo.gif |
||||||
193 | * echo Url::to('@web/images/logo.gif', 'https'); |
||||||
194 | * |
||||||
195 | * // //www.example.com/images/logo.gif |
||||||
196 | * echo Url::to('@web/images/logo.gif', ''); |
||||||
197 | * ``` |
||||||
198 | * |
||||||
199 | * |
||||||
200 | * @param array|string $url the parameter to be used to generate a valid URL |
||||||
201 | * @param bool|string $scheme the URI scheme to use in the generated URL: |
||||||
202 | * |
||||||
203 | * - `false` (default): generating a relative URL. |
||||||
204 | * - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]]. |
||||||
205 | * - string: generating an absolute URL with the specified scheme (either `http`, `https` or empty string |
||||||
206 | * for protocol-relative URL). |
||||||
207 | * |
||||||
208 | * @return string the generated URL |
||||||
209 | * @throws InvalidArgumentException a relative route is given while there is no active controller |
||||||
210 | */ |
||||||
211 | 153 | public static function to($url = '', $scheme = false) |
|||||
212 | { |
||||||
213 | 153 | if (is_array($url)) { |
|||||
214 | 12 | return static::toRoute($url, $scheme); |
|||||
215 | } |
||||||
216 | |||||||
217 | 145 | $url = Yii::getAlias($url); |
|||||
218 | 145 | if ($url === '') { |
|||||
219 | 9 | $url = Yii::$app->getRequest()->getUrl(); |
|||||
220 | } |
||||||
221 | |||||||
222 | 145 | if ($scheme === false) { |
|||||
223 | 145 | return $url; |
|||||
224 | } |
||||||
225 | |||||||
226 | 1 | if (static::isRelative($url)) { |
|||||
227 | // turn relative URL into absolute |
||||||
228 | 1 | $url = static::getUrlManager()->getHostInfo() . '/' . ltrim($url, '/'); |
|||||
229 | } |
||||||
230 | |||||||
231 | 1 | return static::ensureScheme($url, $scheme); |
|||||
232 | } |
||||||
233 | |||||||
234 | /** |
||||||
235 | * Normalize the URL by ensuring it uses specified scheme. |
||||||
236 | * |
||||||
237 | * If the URL is relative or the scheme is not a string, normalization is skipped. |
||||||
238 | * |
||||||
239 | * @param string $url the URL to process |
||||||
240 | * @param string $scheme the URI scheme used in the URL (e.g. `http` or `https`). Use an empty string to |
||||||
241 | * create protocol-relative URL (e.g. `//example.com/path`) |
||||||
242 | * @return string the processed URL |
||||||
243 | * @since 2.0.11 |
||||||
244 | */ |
||||||
245 | 63 | public static function ensureScheme($url, $scheme) |
|||||
246 | { |
||||||
247 | 63 | if (static::isRelative($url) || !is_string($scheme)) { |
|||||
248 | 58 | return $url; |
|||||
249 | } |
||||||
250 | |||||||
251 | 22 | if (strncmp($url, '//', 2) === 0) { |
|||||
252 | // e.g. //example.com/path/to/resource |
||||||
253 | 2 | return $scheme === '' ? $url : "$scheme:$url"; |
|||||
254 | } |
||||||
255 | |||||||
256 | 22 | if (($pos = strpos($url, '://')) !== false) { |
|||||
257 | 22 | if ($scheme === '') { |
|||||
258 | 17 | $url = substr($url, $pos + 1); |
|||||
259 | } else { |
||||||
260 | 22 | $url = $scheme . substr($url, $pos); |
|||||
261 | } |
||||||
262 | } |
||||||
263 | |||||||
264 | 22 | return $url; |
|||||
265 | } |
||||||
266 | |||||||
267 | /** |
||||||
268 | * Returns the base URL of the current request. |
||||||
269 | * @param bool|string $scheme the URI scheme to use in the returned base URL: |
||||||
270 | * |
||||||
271 | * - `false` (default): returning the base URL without host info. |
||||||
272 | * - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]]. |
||||||
273 | * - string: returning an absolute base URL with the specified scheme (either `http`, `https` or empty string |
||||||
274 | * for protocol-relative URL). |
||||||
275 | * @return string |
||||||
276 | */ |
||||||
277 | 1 | public static function base($scheme = false) |
|||||
278 | { |
||||||
279 | 1 | $url = static::getUrlManager()->getBaseUrl(); |
|||||
280 | 1 | if ($scheme !== false) { |
|||||
281 | 1 | $url = static::getUrlManager()->getHostInfo() . $url; |
|||||
282 | 1 | $url = static::ensureScheme($url, $scheme); |
|||||
283 | } |
||||||
284 | |||||||
285 | 1 | return $url; |
|||||
286 | } |
||||||
287 | |||||||
288 | /** |
||||||
289 | * Remembers the specified URL so that it can be later fetched back by [[previous()]]. |
||||||
290 | * |
||||||
291 | * @param string|array $url the URL to remember. Please refer to [[to()]] for acceptable formats. |
||||||
292 | * If this parameter is not specified, the currently requested URL will be used. |
||||||
293 | * @param string|null $name the name associated with the URL to be remembered. This can be used |
||||||
294 | * later by [[previous()]]. If not set, [[\yii\web\User::setReturnUrl()]] will be used with passed URL. |
||||||
295 | * @see previous() |
||||||
296 | * @see \yii\web\User::setReturnUrl() |
||||||
297 | */ |
||||||
298 | 1 | public static function remember($url = '', $name = null) |
|||||
299 | { |
||||||
300 | 1 | $url = static::to($url); |
|||||
301 | |||||||
302 | 1 | if ($name === null) { |
|||||
303 | 1 | Yii::$app->getUser()->setReturnUrl($url); |
|||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||||
304 | } else { |
||||||
305 | 1 | Yii::$app->getSession()->set($name, $url); |
|||||
0 ignored issues
–
show
The method
getSession() does not exist on yii\base\Application . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
306 | } |
||||||
307 | 1 | } |
|||||
308 | |||||||
309 | /** |
||||||
310 | * Returns the URL previously [[remember()|remembered]]. |
||||||
311 | * |
||||||
312 | * @param string|null $name the named associated with the URL that was remembered previously. |
||||||
313 | * If not set, [[\yii\web\User::getReturnUrl()]] will be used to obtain remembered URL. |
||||||
314 | * @return string|null the URL previously remembered. Null is returned if no URL was remembered with the given name |
||||||
315 | * and `$name` is not specified. |
||||||
316 | * @see remember() |
||||||
317 | * @see \yii\web\User::getReturnUrl() |
||||||
318 | */ |
||||||
319 | 1 | public static function previous($name = null) |
|||||
320 | { |
||||||
321 | 1 | if ($name === null) { |
|||||
322 | 1 | return Yii::$app->getUser()->getReturnUrl(); |
|||||
323 | } |
||||||
324 | |||||||
325 | 1 | return Yii::$app->getSession()->get($name); |
|||||
326 | } |
||||||
327 | |||||||
328 | /** |
||||||
329 | * Returns the canonical URL of the currently requested page. |
||||||
330 | * |
||||||
331 | * The canonical URL is constructed using the current controller's [[\yii\web\Controller::route]] and |
||||||
332 | * [[\yii\web\Controller::actionParams]]. You may use the following code in the layout view to add a link tag |
||||||
333 | * about canonical URL: |
||||||
334 | * |
||||||
335 | * ```php |
||||||
336 | * $this->registerLinkTag(['rel' => 'canonical', 'href' => Url::canonical()]); |
||||||
337 | * ``` |
||||||
338 | * |
||||||
339 | * @return string the canonical URL of the currently requested page |
||||||
340 | */ |
||||||
341 | 1 | public static function canonical() |
|||||
342 | { |
||||||
343 | 1 | $params = Yii::$app->controller->actionParams; |
|||||
0 ignored issues
–
show
The property
actionParams does not exist on yii\base\Controller . Since you implemented __get , consider adding a @property annotation.
Loading history...
|
|||||||
344 | 1 | $params[0] = Yii::$app->controller->getRoute(); |
|||||
345 | |||||||
346 | 1 | return static::getUrlManager()->createAbsoluteUrl($params); |
|||||
347 | } |
||||||
348 | |||||||
349 | /** |
||||||
350 | * Returns the home URL. |
||||||
351 | * |
||||||
352 | * @param bool|string $scheme the URI scheme to use for the returned URL: |
||||||
353 | * |
||||||
354 | * - `false` (default): returning a relative URL. |
||||||
355 | * - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]]. |
||||||
356 | * - string: returning an absolute URL with the specified scheme (either `http`, `https` or empty string |
||||||
357 | * for protocol-relative URL). |
||||||
358 | * |
||||||
359 | * @return string home URL |
||||||
360 | */ |
||||||
361 | 1 | public static function home($scheme = false) |
|||||
362 | { |
||||||
363 | 1 | $url = Yii::$app->getHomeUrl(); |
|||||
0 ignored issues
–
show
The method
getHomeUrl() does not exist on yii\base\Application . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
364 | |||||||
365 | 1 | if ($scheme !== false) { |
|||||
366 | 1 | $url = static::getUrlManager()->getHostInfo() . $url; |
|||||
367 | 1 | $url = static::ensureScheme($url, $scheme); |
|||||
368 | } |
||||||
369 | |||||||
370 | 1 | return $url; |
|||||
371 | } |
||||||
372 | |||||||
373 | /** |
||||||
374 | * Returns a value indicating whether a URL is relative. |
||||||
375 | * A relative URL does not have host info part. |
||||||
376 | * @param string $url the URL to be checked |
||||||
377 | * @return bool whether the URL is relative |
||||||
378 | */ |
||||||
379 | 105 | public static function isRelative($url) |
|||||
380 | { |
||||||
381 | 105 | return strncmp($url, '//', 2) && strpos($url, '://') === false; |
|||||
382 | } |
||||||
383 | |||||||
384 | /** |
||||||
385 | * Creates a URL by using the current route and the GET parameters. |
||||||
386 | * |
||||||
387 | * You may modify or remove some of the GET parameters, or add additional query parameters through |
||||||
388 | * the `$params` parameter. In particular, if you specify a parameter to be null, then this parameter |
||||||
389 | * will be removed from the existing GET parameters; all other parameters specified in `$params` will |
||||||
390 | * be merged with the existing GET parameters. For example, |
||||||
391 | * |
||||||
392 | * ```php |
||||||
393 | * // assume $_GET = ['id' => 123, 'src' => 'google'], current route is "post/view" |
||||||
394 | * |
||||||
395 | * // /index.php?r=post%2Fview&id=123&src=google |
||||||
396 | * echo Url::current(); |
||||||
397 | * |
||||||
398 | * // /index.php?r=post%2Fview&id=123 |
||||||
399 | * echo Url::current(['src' => null]); |
||||||
400 | * |
||||||
401 | * // /index.php?r=post%2Fview&id=100&src=google |
||||||
402 | * echo Url::current(['id' => 100]); |
||||||
403 | * ``` |
||||||
404 | * |
||||||
405 | * Note that if you're replacing array parameters with `[]` at the end you should specify `$params` as nested arrays. |
||||||
406 | * For a `PostSearchForm` model where parameter names are `PostSearchForm[id]` and `PostSearchForm[src]` the syntax |
||||||
407 | * would be the following: |
||||||
408 | * |
||||||
409 | * ```php |
||||||
410 | * // index.php?r=post%2Findex&PostSearchForm%5Bid%5D=100&PostSearchForm%5Bsrc%5D=google |
||||||
411 | * echo Url::current([ |
||||||
412 | * $postSearch->formName() => ['id' => 100, 'src' => 'google'], |
||||||
413 | * ]); |
||||||
414 | * ``` |
||||||
415 | * |
||||||
416 | * @param array $params an associative array of parameters that will be merged with the current GET parameters. |
||||||
417 | * If a parameter value is null, the corresponding GET parameter will be removed. |
||||||
418 | * @param bool|string $scheme the URI scheme to use in the generated URL: |
||||||
419 | * |
||||||
420 | * - `false` (default): generating a relative URL. |
||||||
421 | * - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]]. |
||||||
422 | * - string: generating an absolute URL with the specified scheme (either `http`, `https` or empty string |
||||||
423 | * for protocol-relative URL). |
||||||
424 | * |
||||||
425 | * @return string the generated URL |
||||||
426 | * @since 2.0.3 |
||||||
427 | */ |
||||||
428 | 1 | public static function current(array $params = [], $scheme = false) |
|||||
429 | { |
||||||
430 | 1 | $currentParams = Yii::$app->getRequest()->getQueryParams(); |
|||||
431 | 1 | $currentParams[0] = '/' . Yii::$app->controller->getRoute(); |
|||||
432 | 1 | $route = array_replace_recursive($currentParams, $params); |
|||||
433 | 1 | return static::toRoute($route, $scheme); |
|||||
434 | } |
||||||
435 | |||||||
436 | /** |
||||||
437 | * @return \yii\web\UrlManager URL manager used to create URLs |
||||||
438 | * @since 2.0.8 |
||||||
439 | */ |
||||||
440 | 17 | protected static function getUrlManager() |
|||||
441 | { |
||||||
442 | 17 | return static::$urlManager ?: Yii::$app->getUrlManager(); |
|||||
443 | } |
||||||
444 | } |
||||||
445 |