Completed
Push — master ( ccd9cb...ab24cf )
by
unknown
16s
created

UrlManager::canBeCached()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 4
cts 4
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 5
nc 4
nop 1
crap 4
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\web;
9
10
use Yii;
11
use yii\base\Component;
12
use yii\base\InvalidConfigException;
13
use yii\caching\Cache;
14
use yii\helpers\Url;
15
16
/**
17
 * UrlManager handles HTTP request parsing and creation of URLs based on a set of rules.
18
 *
19
 * UrlManager is configured as an application component in [[\yii\base\Application]] by default.
20
 * You can access that instance via `Yii::$app->urlManager`.
21
 *
22
 * You can modify its configuration by adding an array to your application config under `components`
23
 * as it is shown in the following example:
24
 *
25
 * ```php
26
 * 'urlManager' => [
27
 *     'enablePrettyUrl' => true,
28
 *     'rules' => [
29
 *         // your rules go here
30
 *     ],
31
 *     // ...
32
 * ]
33
 * ```
34
 *
35
 * Rules are classes implementing the [[UrlRuleInterface]], by default that is [[UrlRule]].
36
 * For nesting rules, there is also a [[GroupUrlRule]] class.
37
 *
38
 * For more details and usage information on UrlManager, see the [guide article on routing](guide:runtime-routing).
39
 *
40
 * @property string $baseUrl The base URL that is used by [[createUrl()]] to prepend to created URLs.
41
 * @property string $hostInfo The host info (e.g. `http://www.example.com`) that is used by
42
 * [[createAbsoluteUrl()]] to prepend to created URLs.
43
 * @property string $scriptUrl The entry script URL that is used by [[createUrl()]] to prepend to created
44
 * URLs.
45
 *
46
 * @author Qiang Xue <[email protected]>
47
 * @since 2.0
48
 */
49
class UrlManager extends Component
50
{
51
    /**
52
     * @var bool whether to enable pretty URLs. Instead of putting all parameters in the query
53
     * string part of a URL, pretty URLs allow using path info to represent some of the parameters
54
     * and can thus produce more user-friendly URLs, such as "/news/Yii-is-released", instead of
55
     * "/index.php?r=news%2Fview&id=100".
56
     */
57
    public $enablePrettyUrl = false;
58
    /**
59
     * @var bool whether to enable strict parsing. If strict parsing is enabled, the incoming
60
     * requested URL must match at least one of the [[rules]] in order to be treated as a valid request.
61
     * Otherwise, the path info part of the request will be treated as the requested route.
62
     * This property is used only when [[enablePrettyUrl]] is `true`.
63
     */
64
    public $enableStrictParsing = false;
65
    /**
66
     * @var array the rules for creating and parsing URLs when [[enablePrettyUrl]] is `true`.
67
     * This property is used only if [[enablePrettyUrl]] is `true`. Each element in the array
68
     * is the configuration array for creating a single URL rule. The configuration will
69
     * be merged with [[ruleConfig]] first before it is used for creating the rule object.
70
     *
71
     * A special shortcut format can be used if a rule only specifies [[UrlRule::pattern|pattern]]
72
     * and [[UrlRule::route|route]]: `'pattern' => 'route'`. That is, instead of using a configuration
73
     * array, one can use the key to represent the pattern and the value the corresponding route.
74
     * For example, `'post/<id:\d+>' => 'post/view'`.
75
     *
76
     * For RESTful routing the mentioned shortcut format also allows you to specify the
77
     * [[UrlRule::verb|HTTP verb]] that the rule should apply for.
78
     * You can do that  by prepending it to the pattern, separated by space.
79
     * For example, `'PUT post/<id:\d+>' => 'post/update'`.
80
     * You may specify multiple verbs by separating them with comma
81
     * like this: `'POST,PUT post/index' => 'post/create'`.
82
     * The supported verbs in the shortcut format are: GET, HEAD, POST, PUT, PATCH and DELETE.
83
     * Note that [[UrlRule::mode|mode]] will be set to PARSING_ONLY when specifying verb in this way
84
     * so you normally would not specify a verb for normal GET request.
85
     *
86
     * Here is an example configuration for RESTful CRUD controller:
87
     *
88
     * ```php
89
     * [
90
     *     'dashboard' => 'site/index',
91
     *
92
     *     'POST <controller:[\w-]+>s' => '<controller>/create',
93
     *     '<controller:[\w-]+>s' => '<controller>/index',
94
     *
95
     *     'PUT <controller:[\w-]+>/<id:\d+>'    => '<controller>/update',
96
     *     'DELETE <controller:[\w-]+>/<id:\d+>' => '<controller>/delete',
97
     *     '<controller:[\w-]+>/<id:\d+>'        => '<controller>/view',
98
     * ];
99
     * ```
100
     *
101
     * Note that if you modify this property after the UrlManager object is created, make sure
102
     * you populate the array with rule objects instead of rule configurations.
103
     */
104
    public $rules = [];
105
    /**
106
     * @var string the URL suffix used when [[enablePrettyUrl]] is `true`.
107
     * For example, ".html" can be used so that the URL looks like pointing to a static HTML page.
108
     * This property is used only if [[enablePrettyUrl]] is `true`.
109
     */
110
    public $suffix;
111
    /**
112
     * @var bool whether to show entry script name in the constructed URL. Defaults to `true`.
113
     * This property is used only if [[enablePrettyUrl]] is `true`.
114
     */
115
    public $showScriptName = true;
116
    /**
117
     * @var string the GET parameter name for route. This property is used only if [[enablePrettyUrl]] is `false`.
118
     */
119
    public $routeParam = 'r';
120
    /**
121
     * @var Cache|string the cache object or the application component ID of the cache object.
122
     * Compiled URL rules will be cached through this cache object, if it is available.
123
     *
124
     * After the UrlManager object is created, if you want to change this property,
125
     * you should only assign it with a cache object.
126
     * Set this property to `false` if you do not want to cache the URL rules.
127
     */
128
    public $cache = 'cache';
129
    /**
130
     * @var array the default configuration of URL rules. Individual rule configurations
131
     * specified via [[rules]] will take precedence when the same property of the rule is configured.
132
     */
133
    public $ruleConfig = ['class' => 'yii\web\UrlRule'];
134
    /**
135
     * @var UrlNormalizer|array|string|false the configuration for [[UrlNormalizer]] used by this UrlManager.
136
     * The default value is `false`, which means normalization will be skipped.
137
     * If you wish to enable URL normalization, you should configure this property manually.
138
     * For example:
139
     *
140
     * ```php
141
     * [
142
     *     'class' => 'yii\web\UrlNormalizer',
143
     *     'collapseSlashes' => true,
144
     *     'normalizeTrailingSlash' => true,
145
     * ]
146
     * ```
147
     *
148
     * @since 2.0.10
149
     */
150
    public $normalizer = false;
151
152
    /**
153
     * @var string the cache key for cached rules
154
     * @since 2.0.8
155
     */
156
    protected $cacheKey = __CLASS__;
157
158
    private $_baseUrl;
159
    private $_scriptUrl;
160
    private $_hostInfo;
161
    private $_ruleCache;
162
163
164
    /**
165
     * Initializes UrlManager.
166
     */
167 166
    public function init()
168
    {
169 166
        parent::init();
170
171 166
        if ($this->normalizer !== false) {
172 3
            $this->normalizer = Yii::createObject($this->normalizer);
173 3
            if (!$this->normalizer instanceof UrlNormalizer) {
174
                throw new InvalidConfigException('`' . get_class($this) . '::normalizer` should be an instance of `' . UrlNormalizer::className() . '` or its DI compatible configuration.');
175
            }
176
        }
177
178 166
        if (!$this->enablePrettyUrl || empty($this->rules)) {
179 95
            return;
180
        }
181 72
        if (is_string($this->cache)) {
182
            $this->cache = Yii::$app->get($this->cache, false);
183
        }
184 72
        if ($this->cache instanceof Cache) {
185
            $cacheKey = $this->cacheKey;
186
            $hash = md5(json_encode($this->rules));
187
            if (($data = $this->cache->get($cacheKey)) !== false && isset($data[1]) && $data[1] === $hash) {
188
                $this->rules = $data[0];
189
            } else {
190
                $this->rules = $this->buildRules($this->rules);
191
                $this->cache->set($cacheKey, [$this->rules, $hash]);
192
            }
193
        } else {
194 72
            $this->rules = $this->buildRules($this->rules);
195
        }
196 72
    }
197
198
    /**
199
     * Adds additional URL rules.
200
     *
201
     * This method will call [[buildRules()]] to parse the given rule declarations and then append or insert
202
     * them to the existing [[rules]].
203
     *
204
     * Note that if [[enablePrettyUrl]] is `false`, this method will do nothing.
205
     *
206
     * @param array $rules the new rules to be added. Each array element represents a single rule declaration.
207
     * Please refer to [[rules]] for the acceptable rule format.
208
     * @param bool $append whether to add the new rules by appending them to the end of the existing rules.
209
     */
210
    public function addRules($rules, $append = true)
211
    {
212
        if (!$this->enablePrettyUrl) {
213
            return;
214
        }
215
        $rules = $this->buildRules($rules);
216
        if ($append) {
217
            $this->rules = array_merge($this->rules, $rules);
218
        } else {
219
            $this->rules = array_merge($rules, $this->rules);
220
        }
221
    }
222
223
    /**
224
     * Builds URL rule objects from the given rule declarations.
225
     * @param array $rules the rule declarations. Each array element represents a single rule declaration.
226
     * Please refer to [[rules]] for the acceptable rule formats.
227
     * @return UrlRuleInterface[] the rule objects built from the given rule declarations
228
     * @throws InvalidConfigException if a rule declaration is invalid
229
     */
230 72
    protected function buildRules($rules)
231
    {
232 72
        $compiledRules = [];
233 72
        $verbs = 'GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS';
234 72
        foreach ($rules as $key => $rule) {
235 72
            if (is_string($rule)) {
236 65
                $rule = ['route' => $rule];
237 65
                if (preg_match("/^((?:($verbs),)*($verbs))\\s+(.*)$/", $key, $matches)) {
238 1
                    $rule['verb'] = explode(',', $matches[1]);
239
                    // rules that do not apply for GET requests should not be use to create urls
240 1
                    if (!in_array('GET', $rule['verb'])) {
241 1
                        $rule['mode'] = UrlRule::PARSING_ONLY;
242
                    }
243 1
                    $key = $matches[4];
244
                }
245 65
                $rule['pattern'] = $key;
246
            }
247 72
            if (is_array($rule)) {
248 70
                $rule = Yii::createObject(array_merge($this->ruleConfig, $rule));
249
            }
250 72
            if (!$rule instanceof UrlRuleInterface) {
251
                throw new InvalidConfigException('URL rule class must implement UrlRuleInterface.');
252
            }
253 72
            $compiledRules[] = $rule;
254
        }
255 72
        return $compiledRules;
256
    }
257
258
    /**
259
     * Parses the user request.
260
     * @param Request $request the request component
261
     * @return array|bool the route and the associated parameters. The latter is always empty
262
     * if [[enablePrettyUrl]] is `false`. `false` is returned if the current request cannot be successfully parsed.
263
     */
264 16
    public function parseRequest($request)
265
    {
266 16
        if ($this->enablePrettyUrl) {
267
            /* @var $rule UrlRule */
268 13
            foreach ($this->rules as $rule) {
269 9
                $result = $rule->parseRequest($this, $request);
270 9
                if (YII_DEBUG) {
271 9
                    Yii::trace([
272 9
                        'rule' => method_exists($rule, '__toString') ? $rule->__toString() : get_class($rule),
273
                        'match' => $result !== false,
274
                        'parent' => null,
275 9
                    ], __METHOD__);
276
                }
277 9
                if ($result !== false) {
278 9
                    return $result;
279
                }
280
            }
281
282 11
            if ($this->enableStrictParsing) {
283 4
                return false;
284
            }
285
286 7
            Yii::trace('No matching URL rules. Using default URL parsing logic.', __METHOD__);
287
288 7
            $suffix = (string) $this->suffix;
289 7
            $pathInfo = $request->getPathInfo();
290 7
            $normalized = false;
291 7
            if ($this->normalizer !== false) {
292 1
                $pathInfo = $this->normalizer->normalizePathInfo($pathInfo, $suffix, $normalized);
293
            }
294 7
            if ($suffix !== '' && $pathInfo !== '') {
295 4
                $n = strlen($this->suffix);
296 4
                if (substr_compare($pathInfo, $this->suffix, -$n, $n) === 0) {
297 4
                    $pathInfo = substr($pathInfo, 0, -$n);
298 4
                    if ($pathInfo === '') {
299
                        // suffix alone is not allowed
300
                        return false;
301
                    }
302
                } else {
303
                    // suffix doesn't match
304 4
                    return false;
305
                }
306
            }
307
308 7
            if ($normalized) {
309
                // pathInfo was changed by normalizer - we need also normalize route
310 1
                return $this->normalizer->normalizeRoute([$pathInfo, []]);
311
            } else {
312 6
                return [$pathInfo, []];
313
            }
314
        } else {
315 3
            Yii::trace('Pretty URL not enabled. Using default URL parsing logic.', __METHOD__);
316 3
            $route = $request->getQueryParam($this->routeParam, '');
317 3
            if (is_array($route)) {
318 3
                $route = '';
319
            }
320
321 3
            return [(string) $route, []];
322
        }
323
    }
324
325
    /**
326
     * Creates a URL using the given route and query parameters.
327
     *
328
     * You may specify the route as a string, e.g., `site/index`. You may also use an array
329
     * if you want to specify additional query parameters for the URL being created. The
330
     * array format must be:
331
     *
332
     * ```php
333
     * // generates: /index.php?r=site%2Findex&param1=value1&param2=value2
334
     * ['site/index', 'param1' => 'value1', 'param2' => 'value2']
335
     * ```
336
     *
337
     * If you want to create a URL with an anchor, you can use the array format with a `#` parameter.
338
     * For example,
339
     *
340
     * ```php
341
     * // generates: /index.php?r=site%2Findex&param1=value1#name
342
     * ['site/index', 'param1' => 'value1', '#' => 'name']
343
     * ```
344
     *
345
     * The URL created is a relative one. Use [[createAbsoluteUrl()]] to create an absolute URL.
346
     *
347
     * Note that unlike [[\yii\helpers\Url::toRoute()]], this method always treats the given route
348
     * as an absolute route.
349
     *
350
     * @param string|array $params use a string to represent a route (e.g. `site/index`),
351
     * or an array to represent a route with query parameters (e.g. `['site/index', 'param1' => 'value1']`).
352
     * @return string the created URL
353
     */
354 127
    public function createUrl($params)
355
    {
356 127
        $params = (array) $params;
357 127
        $anchor = isset($params['#']) ? '#' . $params['#'] : '';
358 127
        unset($params['#'], $params[$this->routeParam]);
359
360 127
        $route = trim($params[0], '/');
361 127
        unset($params[0]);
362
363 127
        $baseUrl = $this->showScriptName || !$this->enablePrettyUrl ? $this->getScriptUrl() : $this->getBaseUrl();
364
365 127
        if ($this->enablePrettyUrl) {
366 80
            $cacheKey = $route . '?';
367 80
            foreach ($params as $key => $value) {
368 80
                if ($value !== null) {
369 80
                    $cacheKey .= $key . '&';
370
                }
371
            }
372
373 80
            $url = $this->getUrlFromCache($cacheKey, $route, $params);
374 80
            if ($url === false) {
375
                /* @var $rule UrlRule */
376 80
                foreach ($this->rules as $rule) {
377 64
                    if (in_array($rule, $this->_ruleCache[$cacheKey], true)) {
378
                        // avoid redundant calls of `UrlRule::createUrl()` for rules checked in `getUrlFromCache()`
379
                        // @see https://github.com/yiisoft/yii2/issues/14094
380 21
                        continue;
381
                    }
382 64
                    $url = $rule->createUrl($this, $route, $params);
383 64
                    if ($this->canBeCached($rule)) {
384 63
                        $this->setRuleToCache($cacheKey, $rule);
385
                    }
386 64
                    if ($url !== false) {
387 63
                        break;
388
                    }
389
                }
390
            }
391
392 80
            if ($url !== false) {
393 63
                if (strpos($url, '://') !== false) {
394 8
                    if ($baseUrl !== '' && ($pos = strpos($url, '/', 8)) !== false) {
395 3
                        return substr($url, 0, $pos) . $baseUrl . substr($url, $pos) . $anchor;
396
                    } else {
397 5
                        return $url . $baseUrl . $anchor;
398
                    }
399 55
                } elseif (strpos($url, '//') === 0) {
400 4
                    if ($baseUrl !== '' && ($pos = strpos($url, '/', 2)) !== false) {
401 3
                        return substr($url, 0, $pos) . $baseUrl . substr($url, $pos) . $anchor;
402
                    } else {
403 4
                        return $url . $baseUrl . $anchor;
404
                    }
405
                } else {
406 51
                    $url = ltrim($url, '/');
407 51
                    return "$baseUrl/{$url}{$anchor}";
408
                }
409
            }
410
411 65
            if ($this->suffix !== null) {
412 24
                $route .= $this->suffix;
413
            }
414 65
            if (!empty($params) && ($query = http_build_query($params)) !== '') {
415 49
                $route .= '?' . $query;
416
            }
417
418 65
            $route = ltrim($route, '/');
419 65
            return "$baseUrl/{$route}{$anchor}";
420
        } else {
421 47
            $url = "$baseUrl?{$this->routeParam}=" . urlencode($route);
422 47
            if (!empty($params) && ($query = http_build_query($params)) !== '') {
423 37
                $url .= '&' . $query;
424
            }
425
426 47
            return $url . $anchor;
427
        }
428
    }
429
430
    /**
431
     * Returns the value indicating whether result of [[createUrl()]] of rule should be cached in internal cache.
432
     *
433
     * @param UrlRuleInterface $rule
434
     * @return bool `true` if result should be cached, `false` if not.
435
     * @since 2.0.12
436
     * @see getUrlFromCache()
437
     * @see setRuleToCache()
438
     * @see UrlRule::getCreateUrlStatus()
439
     */
440 64
    protected function canBeCached(UrlRuleInterface $rule)
441
    {
442
        return
443
            // if rule does not provide info about create status, we cache it every time to prevent bugs like #13350
444
            // @see https://github.com/yiisoft/yii2/pull/13350#discussion_r114873476
445 64
            !method_exists($rule, 'getCreateUrlStatus') || ($status = $rule->getCreateUrlStatus()) === null
0 ignored issues
show
Bug introduced by
The method getCreateUrlStatus() does not exist on yii\web\UrlRuleInterface. Did you maybe mean createUrl()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
446 64
            || $status === UrlRule::CREATE_STATUS_SUCCESS
447 64
            || $status & UrlRule::CREATE_STATUS_PARAMS_MISMATCH;
448
    }
449
450
    /**
451
     * Get URL from internal cache if exists
452
     * @param string $cacheKey generated cache key to store data.
453
     * @param string $route the route (e.g. `site/index`).
454
     * @param array $params rule params.
455
     * @return bool|string the created URL
456
     * @see createUrl()
457
     * @since 2.0.8
458
     */
459 80
    protected function getUrlFromCache($cacheKey, $route, $params)
460
    {
461 80
        if (!empty($this->_ruleCache[$cacheKey])) {
462 63
            foreach ($this->_ruleCache[$cacheKey] as $rule) {
463
                /* @var $rule UrlRule */
464 63
                if (($url = $rule->createUrl($this, $route, $params)) !== false) {
465 63
                    return $url;
466
                }
467
            }
468
        } else {
469 80
            $this->_ruleCache[$cacheKey] = [];
470
        }
471 80
        return false;
472
    }
473
474
    /**
475
     * Store rule (e.g. [[UrlRule]]) to internal cache
476
     * @param $cacheKey
477
     * @param UrlRuleInterface $rule
478
     * @since 2.0.8
479
     */
480 63
    protected function setRuleToCache($cacheKey, UrlRuleInterface $rule)
481
    {
482 63
        $this->_ruleCache[$cacheKey][] = $rule;
483 63
    }
484
485
    /**
486
     * Creates an absolute URL using the given route and query parameters.
487
     *
488
     * This method prepends the URL created by [[createUrl()]] with the [[hostInfo]].
489
     *
490
     * Note that unlike [[\yii\helpers\Url::toRoute()]], this method always treats the given route
491
     * as an absolute route.
492
     *
493
     * @param string|array $params use a string to represent a route (e.g. `site/index`),
494
     * or an array to represent a route with query parameters (e.g. `['site/index', 'param1' => 'value1']`).
495
     * @param string|null $scheme the scheme to use for the URL (either `http`, `https` or empty string
496
     * for protocol-relative URL).
497
     * If not specified the scheme of the current request will be used.
498
     * @return string the created URL
499
     * @see createUrl()
500
     */
501 58
    public function createAbsoluteUrl($params, $scheme = null)
502
    {
503 58
        $params = (array) $params;
504 58
        $url = $this->createUrl($params);
505 58
        if (strpos($url, '://') === false) {
506 54
            $hostInfo = $this->getHostInfo();
507 54
            if (strpos($url, '//') === 0) {
508 4
                $url = substr($hostInfo, 0, strpos($hostInfo, '://')) . ':' . $url;
509
            } else {
510 54
                $url = $hostInfo . $url;
511
            }
512
        }
513
514 58
        return Url::ensureScheme($url, $scheme);
515
    }
516
517
    /**
518
     * Returns the base URL that is used by [[createUrl()]] to prepend to created URLs.
519
     * It defaults to [[Request::baseUrl]].
520
     * This is mainly used when [[enablePrettyUrl]] is `true` and [[showScriptName]] is `false`.
521
     * @return string the base URL that is used by [[createUrl()]] to prepend to created URLs.
522
     * @throws InvalidConfigException if running in console application and [[baseUrl]] is not configured.
523
     */
524 41
    public function getBaseUrl()
525
    {
526 41
        if ($this->_baseUrl === null) {
527 1
            $request = Yii::$app->getRequest();
528 1
            if ($request instanceof Request) {
529 1
                $this->_baseUrl = $request->getBaseUrl();
530
            } else {
531
                throw new InvalidConfigException('Please configure UrlManager::baseUrl correctly as you are running a console application.');
532
            }
533
        }
534
535 41
        return $this->_baseUrl;
536
    }
537
538
    /**
539
     * Sets the base URL that is used by [[createUrl()]] to prepend to created URLs.
540
     * This is mainly used when [[enablePrettyUrl]] is `true` and [[showScriptName]] is `false`.
541
     * @param string $value the base URL that is used by [[createUrl()]] to prepend to created URLs.
542
     */
543 111
    public function setBaseUrl($value)
544
    {
545 111
        $this->_baseUrl = $value === null ? null : rtrim($value, '/');
546 111
    }
547
548
    /**
549
     * Returns the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
550
     * It defaults to [[Request::scriptUrl]].
551
     * This is mainly used when [[enablePrettyUrl]] is `false` or [[showScriptName]] is `true`.
552
     * @return string the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
553
     * @throws InvalidConfigException if running in console application and [[scriptUrl]] is not configured.
554
     */
555 87
    public function getScriptUrl()
556
    {
557 87
        if ($this->_scriptUrl === null) {
558 12
            $request = Yii::$app->getRequest();
559 12
            if ($request instanceof Request) {
560 12
                $this->_scriptUrl = $request->getScriptUrl();
561
            } else {
562
                throw new InvalidConfigException('Please configure UrlManager::scriptUrl correctly as you are running a console application.');
563
            }
564
        }
565
566 87
        return $this->_scriptUrl;
567
    }
568
569
    /**
570
     * Sets the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
571
     * This is mainly used when [[enablePrettyUrl]] is `false` or [[showScriptName]] is `true`.
572
     * @param string $value the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
573
     */
574 120
    public function setScriptUrl($value)
575
    {
576 120
        $this->_scriptUrl = $value;
577 120
    }
578
579
    /**
580
     * Returns the host info that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
581
     * @return string the host info (e.g. `http://www.example.com`) that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
582
     * @throws InvalidConfigException if running in console application and [[hostInfo]] is not configured.
583
     */
584 56
    public function getHostInfo()
585
    {
586 56
        if ($this->_hostInfo === null) {
587 7
            $request = Yii::$app->getRequest();
588 7
            if ($request instanceof \yii\web\Request) {
589 7
                $this->_hostInfo = $request->getHostInfo();
590
            } else {
591
                throw new InvalidConfigException('Please configure UrlManager::hostInfo correctly as you are running a console application.');
592
            }
593
        }
594
595 56
        return $this->_hostInfo;
596
    }
597
598
    /**
599
     * Sets the host info that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
600
     * @param string $value the host info (e.g. "http://www.example.com") that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
601
     */
602 108
    public function setHostInfo($value)
603
    {
604 108
        $this->_hostInfo = $value === null ? null : rtrim($value, '/');
605 108
    }
606
}
607