Passed
Push — master ( 5ad809...a6dba4 )
by Alexander
23:13
created

framework/web/UrlManager.php (3 issues)

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\CacheInterface;
14
use yii\di\Instance;
15
use yii\helpers\Url;
16
17
/**
18
 * UrlManager handles HTTP request parsing and creation of URLs based on a set of rules.
19
 *
20
 * UrlManager is configured as an application component in [[\yii\base\Application]] by default.
21
 * You can access that instance via `Yii::$app->urlManager`.
22
 *
23
 * You can modify its configuration by adding an array to your application config under `components`
24
 * as it is shown in the following example:
25
 *
26
 * ```php
27
 * 'urlManager' => [
28
 *     'enablePrettyUrl' => true,
29
 *     'rules' => [
30
 *         // your rules go here
31
 *     ],
32
 *     // ...
33
 * ]
34
 * ```
35
 *
36
 * Rules are classes implementing the [[UrlRuleInterface]], by default that is [[UrlRule]].
37
 * For nesting rules, there is also a [[GroupUrlRule]] class.
38
 *
39
 * For more details and usage information on UrlManager, see the [guide article on routing](guide:runtime-routing).
40
 *
41
 * @property string $baseUrl The base URL that is used by [[createUrl()]] to prepend to created URLs.
42
 * @property string $hostInfo The host info (e.g. `http://www.example.com`) that is used by
43
 * [[createAbsoluteUrl()]] to prepend to created URLs.
44
 * @property string $scriptUrl The entry script URL that is used by [[createUrl()]] to prepend to created
45
 * URLs.
46
 *
47
 * @author Qiang Xue <[email protected]>
48
 * @since 2.0
49
 */
50
class UrlManager extends Component
51
{
52
    /**
53
     * @var bool whether to enable pretty URLs. Instead of putting all parameters in the query
54
     * string part of a URL, pretty URLs allow using path info to represent some of the parameters
55
     * and can thus produce more user-friendly URLs, such as "/news/Yii-is-released", instead of
56
     * "/index.php?r=news%2Fview&id=100".
57
     */
58
    public $enablePrettyUrl = false;
59
    /**
60
     * @var bool whether to enable strict parsing. If strict parsing is enabled, the incoming
61
     * requested URL must match at least one of the [[rules]] in order to be treated as a valid request.
62
     * Otherwise, the path info part of the request will be treated as the requested route.
63
     * This property is used only when [[enablePrettyUrl]] is `true`.
64
     */
65
    public $enableStrictParsing = false;
66
    /**
67
     * @var array the rules for creating and parsing URLs when [[enablePrettyUrl]] is `true`.
68
     * This property is used only if [[enablePrettyUrl]] is `true`. Each element in the array
69
     * is the configuration array for creating a single URL rule. The configuration will
70
     * be merged with [[ruleConfig]] first before it is used for creating the rule object.
71
     *
72
     * A special shortcut format can be used if a rule only specifies [[UrlRule::pattern|pattern]]
73
     * and [[UrlRule::route|route]]: `'pattern' => 'route'`. That is, instead of using a configuration
74
     * array, one can use the key to represent the pattern and the value the corresponding route.
75
     * For example, `'post/<id:\d+>' => 'post/view'`.
76
     *
77
     * For RESTful routing the mentioned shortcut format also allows you to specify the
78
     * [[UrlRule::verb|HTTP verb]] that the rule should apply for.
79
     * You can do that  by prepending it to the pattern, separated by space.
80
     * For example, `'PUT post/<id:\d+>' => 'post/update'`.
81
     * You may specify multiple verbs by separating them with comma
82
     * like this: `'POST,PUT post/index' => 'post/create'`.
83
     * The supported verbs in the shortcut format are: GET, HEAD, POST, PUT, PATCH and DELETE.
84
     * Note that [[UrlRule::mode|mode]] will be set to PARSING_ONLY when specifying verb in this way
85
     * so you normally would not specify a verb for normal GET request.
86
     *
87
     * Here is an example configuration for RESTful CRUD controller:
88
     *
89
     * ```php
90
     * [
91
     *     'dashboard' => 'site/index',
92
     *
93
     *     'POST <controller:[\w-]+>' => '<controller>/create',
94
     *     '<controller:[\w-]+>s' => '<controller>/index',
95
     *
96
     *     'PUT <controller:[\w-]+>/<id:\d+>'    => '<controller>/update',
97
     *     'DELETE <controller:[\w-]+>/<id:\d+>' => '<controller>/delete',
98
     *     '<controller:[\w-]+>/<id:\d+>'        => '<controller>/view',
99
     * ];
100
     * ```
101
     *
102
     * Note that if you modify this property after the UrlManager object is created, make sure
103
     * you populate the array with rule objects instead of rule configurations.
104
     */
105
    public $rules = [];
106
    /**
107
     * @var string the URL suffix used when [[enablePrettyUrl]] is `true`.
108
     * For example, ".html" can be used so that the URL looks like pointing to a static HTML page.
109
     * This property is used only if [[enablePrettyUrl]] is `true`.
110
     */
111
    public $suffix;
112
    /**
113
     * @var bool whether to show entry script name in the constructed URL. Defaults to `true`.
114
     * This property is used only if [[enablePrettyUrl]] is `true`.
115
     */
116
    public $showScriptName = true;
117
    /**
118
     * @var string the GET parameter name for route. This property is used only if [[enablePrettyUrl]] is `false`.
119
     */
120
    public $routeParam = 'r';
121
    /**
122
     * @var CacheInterface|array|string|bool the cache object or the application component ID of the cache object.
123
     * This can also be an array that is used to create a [[CacheInterface]] instance in case you do not want to use
124
     * an application component.
125
     * Compiled URL rules will be cached through this cache object, if it is available.
126
     *
127
     * After the UrlManager object is created, if you want to change this property,
128
     * you should only assign it with a cache object.
129
     * Set this property to `false` or `null` if you do not want to cache the URL rules.
130
     *
131
     * Cache entries are stored for the time set by [[\yii\caching\Cache::$defaultDuration|$defaultDuration]] in
132
     * the cache configuration, which is unlimited by default. You may want to tune this value if your [[rules]]
133
     * change frequently.
134
     */
135
    public $cache = 'cache';
136
    /**
137
     * @var array the default configuration of URL rules. Individual rule configurations
138
     * specified via [[rules]] will take precedence when the same property of the rule is configured.
139
     */
140
    public $ruleConfig = ['class' => 'yii\web\UrlRule'];
141
    /**
142
     * @var UrlNormalizer|array|string|false the configuration for [[UrlNormalizer]] used by this UrlManager.
143
     * The default value is `false`, which means normalization will be skipped.
144
     * If you wish to enable URL normalization, you should configure this property manually.
145
     * For example:
146
     *
147
     * ```php
148
     * [
149
     *     'class' => 'yii\web\UrlNormalizer',
150
     *     'collapseSlashes' => true,
151
     *     'normalizeTrailingSlash' => true,
152
     * ]
153
     * ```
154
     *
155
     * @since 2.0.10
156
     */
157
    public $normalizer = false;
158
159
    /**
160
     * @var string the cache key for cached rules
161
     * @since 2.0.8
162
     */
163
    protected $cacheKey = __CLASS__;
164
165
    private $_baseUrl;
166
    private $_scriptUrl;
167
    private $_hostInfo;
168
    private $_ruleCache;
169
170
171
    /**
172
     * Initializes UrlManager.
173
     */
174 192
    public function init()
175
    {
176 192
        parent::init();
177
178 192
        if ($this->normalizer !== false) {
179 3
            $this->normalizer = Yii::createObject($this->normalizer);
180 3
            if (!$this->normalizer instanceof UrlNormalizer) {
181
                throw new InvalidConfigException('`' . get_class($this) . '::normalizer` should be an instance of `' . UrlNormalizer::className() . '` or its DI compatible configuration.');
182
            }
183
        }
184
185 192
        if (!$this->enablePrettyUrl) {
186 94
            return;
187
        }
188 98
189
        if (!empty($this->rules)) {
190 3
            $this->rules = $this->buildRules($this->rules);
191
        }
192
    }
193
194
    /**
195 98
     * Adds additional URL rules.
196 21
     *
197
     * This method will call [[buildRules()]] to parse the given rule declarations and then append or insert
198 78
     * them to the existing [[rules]].
199 78
     *
200
     * Note that if [[enablePrettyUrl]] is `false`, this method will do nothing.
201
     *
202
     * @param array $rules the new rules to be added. Each array element represents a single rule declaration.
203
     * Please refer to [[rules]] for the acceptable rule format.
204
     * @param bool $append whether to add the new rules by appending them to the end of the existing rules.
205
     */
206
    public function addRules($rules, $append = true)
207
    {
208
        if (!$this->enablePrettyUrl) {
209
            return;
210
        }
211
        $rules = $this->buildRules($rules);
212
        if ($append) {
213 3
            $this->rules = array_merge($this->rules, $rules);
214
        } else {
215 3
            $this->rules = array_merge($rules, $this->rules);
216
        }
217
    }
218 3
219 3
    /**
220 2
     * Builds URL rule objects from the given rule declarations.
221
     *
222 1
     * @param array $ruleDeclarations the rule declarations. Each array element represents a single rule declaration.
223
     * Please refer to [[rules]] for the acceptable rule formats.
224 3
     * @return UrlRuleInterface[] the rule objects built from the given rule declarations
225
     * @throws InvalidConfigException if a rule declaration is invalid
226
     */
227
    protected function buildRules($ruleDeclarations)
228
    {
229
        $builtRules = $this->getBuiltRulesFromCache($ruleDeclarations);
230
        if ($builtRules !== false) {
231
            return $builtRules;
232
        }
233
234 78
        $builtRules = [];
235
        $verbs = 'GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS';
236 78
        foreach ($ruleDeclarations as $key => $rule) {
237 78
            if (is_string($rule)) {
238 1
                $rule = ['route' => $rule];
239
                if (preg_match("/^((?:($verbs),)*($verbs))\\s+(.*)$/", $key, $matches)) {
240
                    $rule['verb'] = explode(',', $matches[1]);
241 77
                    $key = $matches[4];
242 77
                }
243 77
                $rule['pattern'] = $key;
244 77
            }
245 70
            if (is_array($rule)) {
246 70
                $rule = Yii::createObject(array_merge($this->ruleConfig, $rule));
247 9
            }
248 9
            if (!$rule instanceof UrlRuleInterface) {
249
                throw new InvalidConfigException('URL rule class must implement UrlRuleInterface.');
250 70
            }
251
            $builtRules[] = $rule;
252 77
        }
253 75
254
        $this->setBuiltRulesCache($ruleDeclarations, $builtRules);
255 77
256
        return $builtRules;
257
    }
258 77
259
    /**
260
     * @return CacheInterface|null|bool
261 77
     */
262
    private function ensureCache()
263 77
    {
264
        if (!$this->cache instanceof CacheInterface && $this->cache !== false && $this->cache !== null) {
265
            try {
266
                $this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface');
267
            } catch (InvalidConfigException $e) {
268
                Yii::warning('Unable to use cache for URL manager: ' . $e->getMessage());
269
                $this->cache = null;
270
            }
271
        }
272
273
        return $this->cache;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->cache also could return the type array|string which is incompatible with the documented return type boolean|null|yii\caching\CacheInterface.
Loading history...
274
    }
275 77
276
    /**
277 77
     * Stores $builtRules to cache, using $rulesDeclaration as a part of cache key.
278 75
     *
279
     * @param array $ruleDeclarations the rule declarations. Each array element represents a single rule declaration.
280
     * Please refer to [[rules]] for the acceptable rule formats.
281 2
     * @param UrlRuleInterface[] $builtRules the rule objects built from the given rule declarations.
282
     * @return bool whether the value is successfully stored into cache
283
     * @since 2.0.14
284
     */
285
    protected function setBuiltRulesCache($ruleDeclarations, $builtRules)
286
    {
287
        $cache = $this->ensureCache();
288
        if (!$cache) {
0 ignored issues
show
$cache is of type yii\caching\CacheInterface, thus it always evaluated to true.
Loading history...
289
            return false;
290
        }
291
292
        return $cache->set([$this->cacheKey, $this->ruleConfig, $ruleDeclarations], $builtRules);
293 78
    }
294
295 78
    /**
296 75
     * Provides the built URL rules that are associated with the $ruleDeclarations from cache.
297
     *
298
     * @param array $ruleDeclarations the rule declarations. Each array element represents a single rule declaration.
299 3
     * Please refer to [[rules]] for the acceptable rule formats.
300
     * @return UrlRuleInterface[]|false the rule objects built from the given rule declarations or boolean `false` when
301
     * there are no cache items for this definition exists.
302
     * @since 2.0.14
303
     */
304
    protected function getBuiltRulesFromCache($ruleDeclarations)
305
    {
306
        $cache = $this->ensureCache();
307
        if (!$cache) {
0 ignored issues
show
$cache is of type yii\caching\CacheInterface, thus it always evaluated to true.
Loading history...
308 17
            return false;
309
        }
310 17
311
        return $cache->get([$this->cacheKey, $this->ruleConfig, $ruleDeclarations]);
312 14
    }
313 10
314 10
    /**
315 10
     * Parses the user request.
316 10
     * @param Request $request the request component
317
     * @return array|bool the route and the associated parameters. The latter is always empty
318
     * if [[enablePrettyUrl]] is `false`. `false` is returned if the current request cannot be successfully parsed.
319 10
     */
320
    public function parseRequest($request)
321 10
    {
322 10
        if ($this->enablePrettyUrl) {
323
            /* @var $rule UrlRule */
324
            foreach ($this->rules as $rule) {
325
                $result = $rule->parseRequest($this, $request);
326 11
                if (YII_DEBUG) {
327 4
                    Yii::debug([
328
                        'rule' => method_exists($rule, '__toString') ? $rule->__toString() : get_class($rule),
329
                        'match' => $result !== false,
330 7
                        'parent' => null,
331
                    ], __METHOD__);
332 7
                }
333 7
                if ($result !== false) {
334 7
                    return $result;
335 7
                }
336 1
            }
337
338 7
            if ($this->enableStrictParsing) {
339 4
                return false;
340 4
            }
341 4
342 4
            Yii::debug('No matching URL rules. Using default URL parsing logic.', __METHOD__);
343
344 4
            $suffix = (string) $this->suffix;
345
            $pathInfo = $request->getPathInfo();
346
            $normalized = false;
347
            if ($this->normalizer !== false) {
348 4
                $pathInfo = $this->normalizer->normalizePathInfo($pathInfo, $suffix, $normalized);
349
            }
350
            if ($suffix !== '' && $pathInfo !== '') {
351
                $n = strlen($this->suffix);
352 7
                if (substr_compare($pathInfo, $this->suffix, -$n, $n) === 0) {
353
                    $pathInfo = substr($pathInfo, 0, -$n);
354 1
                    if ($pathInfo === '') {
355
                        // suffix alone is not allowed
356
                        return false;
357 6
                    }
358
                } else {
359
                    // suffix doesn't match
360 3
                    return false;
361 3
                }
362 3
            }
363 3
364
            if ($normalized) {
365
                // pathInfo was changed by normalizer - we need also normalize route
366 3
                return $this->normalizer->normalizeRoute([$pathInfo, []]);
367
            }
368
369
            return [$pathInfo, []];
370
        }
371
372
        Yii::debug('Pretty URL not enabled. Using default URL parsing logic.', __METHOD__);
373
        $route = $request->getQueryParam($this->routeParam, '');
374
        if (is_array($route)) {
375
            $route = '';
376
        }
377
378
        return [(string) $route, []];
379
    }
380
381
    /**
382
     * Creates a URL using the given route and query parameters.
383
     *
384
     * You may specify the route as a string, e.g., `site/index`. You may also use an array
385
     * if you want to specify additional query parameters for the URL being created. The
386
     * array format must be:
387
     *
388
     * ```php
389
     * // generates: /index.php?r=site%2Findex&param1=value1&param2=value2
390
     * ['site/index', 'param1' => 'value1', 'param2' => 'value2']
391
     * ```
392
     *
393
     * If you want to create a URL with an anchor, you can use the array format with a `#` parameter.
394
     * For example,
395
     *
396
     * ```php
397
     * // generates: /index.php?r=site%2Findex&param1=value1#name
398 146
     * ['site/index', 'param1' => 'value1', '#' => 'name']
399
     * ```
400 146
     *
401 146
     * The URL created is a relative one. Use [[createAbsoluteUrl()]] to create an absolute URL.
402 146
     *
403
     * Note that unlike [[\yii\helpers\Url::toRoute()]], this method always treats the given route
404 146
     * as an absolute route.
405 146
     *
406
     * @param string|array $params use a string to represent a route (e.g. `site/index`),
407 146
     * or an array to represent a route with query parameters (e.g. `['site/index', 'param1' => 'value1']`).
408
     * @return string the created URL
409 146
     */
410 80
    public function createUrl($params)
411 80
    {
412 80
        $params = (array) $params;
413 80
        $anchor = isset($params['#']) ? '#' . $params['#'] : '';
414
        unset($params['#'], $params[$this->routeParam]);
415
416
        $route = trim($params[0], '/');
417 80
        unset($params[0]);
418 80
419
        $baseUrl = $this->showScriptName || !$this->enablePrettyUrl ? $this->getScriptUrl() : $this->getBaseUrl();
420 80
421 64
        if ($this->enablePrettyUrl) {
422
            $cacheKey = $route . '?';
423
            foreach ($params as $key => $value) {
424 21
                if ($value !== null) {
425
                    $cacheKey .= $key . '&';
426 64
                }
427 64
            }
428 64
429
            $url = $this->getUrlFromCache($cacheKey, $route, $params);
430 64
            if ($url === false) {
431 64
                /* @var $rule UrlRule */
432
                foreach ($this->rules as $rule) {
433
                    if (in_array($rule, $this->_ruleCache[$cacheKey], true)) {
434
                        // avoid redundant calls of `UrlRule::createUrl()` for rules checked in `getUrlFromCache()`
435
                        // @see https://github.com/yiisoft/yii2/issues/14094
436 80
                        continue;
437 64
                    }
438 8
                    $url = $rule->createUrl($this, $route, $params);
439 3
                    if ($this->canBeCached($rule)) {
440
                        $this->setRuleToCache($cacheKey, $rule);
441
                    }
442 5
                    if ($url !== false) {
443 56
                        break;
444 4
                    }
445 3
                }
446
            }
447
448 4
            if ($url !== false) {
449
                if (strpos($url, '://') !== false) {
450
                    if ($baseUrl !== '' && ($pos = strpos($url, '/', 8)) !== false) {
451 52
                        return substr($url, 0, $pos) . $baseUrl . substr($url, $pos) . $anchor;
452 52
                    }
453
454
                    return $url . $baseUrl . $anchor;
455 64
                } elseif (strncmp($url, '//', 2) === 0) {
456 24
                    if ($baseUrl !== '' && ($pos = strpos($url, '/', 2)) !== false) {
457
                        return substr($url, 0, $pos) . $baseUrl . substr($url, $pos) . $anchor;
458 64
                    }
459 48
460
                    return $url . $baseUrl . $anchor;
461
                }
462 64
463 64
                $url = ltrim($url, '/');
464
                return "$baseUrl/{$url}{$anchor}";
465
            }
466 66
467 66
            if ($this->suffix !== null) {
468 50
                $route .= $this->suffix;
469
            }
470
            if (!empty($params) && ($query = http_build_query($params)) !== '') {
471 66
                $route .= '?' . $query;
472
            }
473
474
            $route = ltrim($route, '/');
475
            return "$baseUrl/{$route}{$anchor}";
476
        }
477
478
        $url = "$baseUrl?{$this->routeParam}=" . urlencode($route);
479
        if (!empty($params) && ($query = http_build_query($params)) !== '') {
480
            $url .= '&' . $query;
481
        }
482
483
        return $url . $anchor;
484 64
    }
485
486
    /**
487
     * Returns the value indicating whether result of [[createUrl()]] of rule should be cached in internal cache.
488
     *
489 64
     * @param UrlRuleInterface $rule
490 64
     * @return bool `true` if result should be cached, `false` if not.
491 64
     * @since 2.0.12
492
     * @see getUrlFromCache()
493
     * @see setRuleToCache()
494
     * @see UrlRule::getCreateUrlStatus()
495
     */
496
    protected function canBeCached(UrlRuleInterface $rule)
497
    {
498
        return
499
            // if rule does not provide info about create status, we cache it every time to prevent bugs like #13350
500
            // @see https://github.com/yiisoft/yii2/pull/13350#discussion_r114873476
501
            !method_exists($rule, 'getCreateUrlStatus') || ($status = $rule->getCreateUrlStatus()) === null
502
            || $status === UrlRule::CREATE_STATUS_SUCCESS
503 80
            || $status & UrlRule::CREATE_STATUS_PARAMS_MISMATCH;
504
    }
505 80
506 63
    /**
507
     * Get URL from internal cache if exists.
508 63
     * @param string $cacheKey generated cache key to store data.
509 63
     * @param string $route the route (e.g. `site/index`).
510
     * @param array $params rule params.
511
     * @return bool|string the created URL
512
     * @see createUrl()
513 80
     * @since 2.0.8
514
     */
515
    protected function getUrlFromCache($cacheKey, $route, $params)
516 80
    {
517
        if (!empty($this->_ruleCache[$cacheKey])) {
518
            foreach ($this->_ruleCache[$cacheKey] as $rule) {
519
                /* @var $rule UrlRule */
520
                if (($url = $rule->createUrl($this, $route, $params)) !== false) {
521
                    return $url;
522
                }
523
            }
524
        } else {
525 64
            $this->_ruleCache[$cacheKey] = [];
526
        }
527 64
528 64
        return false;
529
    }
530
531
    /**
532
     * Store rule (e.g. [[UrlRule]]) to internal cache.
533
     * @param $cacheKey
534
     * @param UrlRuleInterface $rule
535
     * @since 2.0.8
536
     */
537
    protected function setRuleToCache($cacheKey, UrlRuleInterface $rule)
538
    {
539
        $this->_ruleCache[$cacheKey][] = $rule;
540
    }
541
542
    /**
543
     * Creates an absolute URL using the given route and query parameters.
544
     *
545
     * This method prepends the URL created by [[createUrl()]] with the [[hostInfo]].
546 59
     *
547
     * Note that unlike [[\yii\helpers\Url::toRoute()]], this method always treats the given route
548 59
     * as an absolute route.
549 59
     *
550 59
     * @param string|array $params use a string to represent a route (e.g. `site/index`),
551 55
     * or an array to represent a route with query parameters (e.g. `['site/index', 'param1' => 'value1']`).
552 55
     * @param string|null $scheme the scheme to use for the URL (either `http`, `https` or empty string
553 4
     * for protocol-relative URL).
554
     * If not specified the scheme of the current request will be used.
555 55
     * @return string the created URL
556
     * @see createUrl()
557
     */
558
    public function createAbsoluteUrl($params, $scheme = null)
559 59
    {
560
        $params = (array) $params;
561
        $url = $this->createUrl($params);
562
        if (strpos($url, '://') === false) {
563
            $hostInfo = $this->getHostInfo();
564
            if (strncmp($url, '//', 2) === 0) {
565
                $url = substr($hostInfo, 0, strpos($hostInfo, '://')) . ':' . $url;
566
            } else {
567
                $url = $hostInfo . $url;
568
            }
569 42
        }
570
571 42
        return Url::ensureScheme($url, $scheme);
572 1
    }
573 1
574 1
    /**
575
     * Returns the base URL that is used by [[createUrl()]] to prepend to created URLs.
576
     * It defaults to [[Request::baseUrl]].
577
     * This is mainly used when [[enablePrettyUrl]] is `true` and [[showScriptName]] is `false`.
578
     * @return string the base URL that is used by [[createUrl()]] to prepend to created URLs.
579
     * @throws InvalidConfigException if running in console application and [[baseUrl]] is not configured.
580 42
     */
581
    public function getBaseUrl()
582
    {
583
        if ($this->_baseUrl === null) {
584
            $request = Yii::$app->getRequest();
585
            if ($request instanceof Request) {
586
                $this->_baseUrl = $request->getBaseUrl();
587
            } else {
588 113
                throw new InvalidConfigException('Please configure UrlManager::baseUrl correctly as you are running a console application.');
589
            }
590 113
        }
591 113
592
        return $this->_baseUrl;
593
    }
594
595
    /**
596
     * Sets the base URL that is used by [[createUrl()]] to prepend to created URLs.
597
     * This is mainly used when [[enablePrettyUrl]] is `true` and [[showScriptName]] is `false`.
598
     * @param string $value the base URL that is used by [[createUrl()]] to prepend to created URLs.
599
     */
600 106
    public function setBaseUrl($value)
601
    {
602 106
        $this->_baseUrl = $value === null ? null : rtrim(Yii::getAlias($value), '/');
603 18
    }
604 18
605 18
    /**
606
     * Returns the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
607
     * It defaults to [[Request::scriptUrl]].
608
     * This is mainly used when [[enablePrettyUrl]] is `false` or [[showScriptName]] is `true`.
609
     * @return string the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
610
     * @throws InvalidConfigException if running in console application and [[scriptUrl]] is not configured.
611 106
     */
612
    public function getScriptUrl()
613
    {
614
        if ($this->_scriptUrl === null) {
615
            $request = Yii::$app->getRequest();
616
            if ($request instanceof Request) {
617
                $this->_scriptUrl = $request->getScriptUrl();
618
            } else {
619 135
                throw new InvalidConfigException('Please configure UrlManager::scriptUrl correctly as you are running a console application.');
620
            }
621 135
        }
622 135
623
        return $this->_scriptUrl;
624
    }
625
626
    /**
627
     * Sets the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
628
     * This is mainly used when [[enablePrettyUrl]] is `false` or [[showScriptName]] is `true`.
629 57
     * @param string $value the entry script URL that is used by [[createUrl()]] to prepend to created URLs.
630
     */
631 57
    public function setScriptUrl($value)
632 8
    {
633 8
        $this->_scriptUrl = $value;
634 8
    }
635
636
    /**
637
     * Returns the host info that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
638
     * @return string the host info (e.g. `http://www.example.com`) that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
639
     * @throws InvalidConfigException if running in console application and [[hostInfo]] is not configured.
640 57
     */
641
    public function getHostInfo()
642
    {
643
        if ($this->_hostInfo === null) {
644
            $request = Yii::$app->getRequest();
645
            if ($request instanceof \yii\web\Request) {
646
                $this->_hostInfo = $request->getHostInfo();
647 110
            } else {
648
                throw new InvalidConfigException('Please configure UrlManager::hostInfo correctly as you are running a console application.');
649 110
            }
650 110
        }
651
652
        return $this->_hostInfo;
653
    }
654
655
    /**
656
     * Sets the host info that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
657
     * @param string $value the host info (e.g. "http://www.example.com") that is used by [[createAbsoluteUrl()]] to prepend to created URLs.
658
     */
659
    public function setHostInfo($value)
660
    {
661
        $this->_hostInfo = $value === null ? null : rtrim($value, '/');
662
    }
663
}
664