Completed
Push — fix-numbervalidator-comma-deci... ( 08054b...a7f0a3 )
by Alexander
40:41 queued 37:41
created

BaseUrl   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 420
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 85.9%

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 4
dl 0
loc 420
ccs 67
cts 78
cp 0.859
rs 9.2
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A toRoute() 0 11 3
B normalizeRoute() 0 21 5
A base() 0 10 2
A remember() 0 10 2
A previous() 0 8 2
A canonical() 0 7 1
A home() 0 11 2
A isRelative() 0 4 2
A current() 0 7 1
A getUrlManager() 0 4 2
B to() 0 22 5
B ensureScheme() 0 21 7
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\helpers;
9
10
use Yii;
11
use yii\base\InvalidParamException;
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&param1=value1&param2=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&param1=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
     * // http://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 InvalidParamException a relative route is given while there is no active controller
95
     */
96 6
    public static function toRoute($route, $scheme = false)
97
    {
98 6
        $route = (array) $route;
99 6
        $route[0] = static::normalizeRoute($route[0]);
100
101 6
        if ($scheme !== false) {
102 3
            return static::getUrlManager()->createAbsoluteUrl($route, is_string($scheme) ? $scheme : null);
103
        } else {
104 5
            return static::getUrlManager()->createUrl($route);
105
        }
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 InvalidParamException a relative route is given while there is no active controller
126
     */
127 6
    protected static function normalizeRoute($route)
128
    {
129 6
        $route = Yii::getAlias((string) $route);
130 6
        if (strncmp($route, '/', 1) === 0) {
131
            // absolute route
132 5
            return ltrim($route, '/');
133
        }
134
135
        // relative route
136 2
        if (Yii::$app->controller === null) {
137 2
            throw new InvalidParamException("Unable to resolve the relative route: $route. No active controller is available.");
138
        }
139
140 2
        if (strpos($route, '/') === false) {
141
            // empty or an action ID
142 2
            return $route === '' ? Yii::$app->controller->getRoute() : Yii::$app->controller->getUniqueId() . '/' . $route;
143
        } else {
144
            // relative to module
145 1
            return ltrim(Yii::$app->controller->module->getUniqueId() . '/' . $route, '/');
146
        }
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
     * // http://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 InvalidParamException a relative route is given while there is no active controller
210
     */
211 88
    public static function to($url = '', $scheme = false)
212
    {
213 88
        if (is_array($url)) {
214 4
            return static::toRoute($url, $scheme);
215
        }
216
217 86
        $url = Yii::getAlias($url);
218 86
        if ($url === '') {
219 6
            $url = Yii::$app->getRequest()->getUrl();
220 6
        }
221
222 86
        if ($scheme === false) {
223 86
            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 1
        }
230
231 1
        return static::ensureScheme($url, $scheme);
0 ignored issues
show
Bug introduced by
It seems like $scheme defined by parameter $scheme on line 211 can also be of type boolean; however, yii\helpers\BaseUrl::ensureScheme() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
232
    }
233
234
    /**
235
     * Normalize URL by ensuring that it use specified scheme.
236
     *
237
     * If URL is relative or scheme is not string, normalization is skipped.
238
     *
239
     * @param string $url the URL to process
240
     * @param string $scheme the URI scheme used in URL (e.g. `http` or `https`). Use 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 15
    public static function ensureScheme($url, $scheme)
246
    {
247 15
        if (static::isRelative($url) || !is_string($scheme)) {
248 14
            return $url;
249
        }
250
251 6
        if (substr($url, 0, 2) === '//') {
252
            // e.g. //example.com/path/to/resource
253 1
            return $scheme === '' ? $url : "$scheme:$url";
254
        }
255
256 6
        if (($pos = strpos($url, '://')) !== false) {
257 6
            if ($scheme === '') {
258 5
                $url = substr($url, $pos + 1);
259 5
            } else {
260 6
                $url = $scheme . substr($url, $pos);
261
            }
262 6
        }
263
264 6
        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);
0 ignored issues
show
Bug introduced by
It seems like $scheme defined by parameter $scheme on line 277 can also be of type boolean; however, yii\helpers\BaseUrl::ensureScheme() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
283 1
        }
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 $name the name associated with the URL to be remembered. This can be used
294
     * later by [[previous()]]. If not set, it will use [[\yii\web\User::returnUrlParam]].
295
     * @see previous()
296
     */
297
    public static function remember($url = '', $name = null)
298
    {
299
        $url = static::to($url);
300
301
        if ($name === null) {
302
            Yii::$app->getUser()->setReturnUrl($url);
0 ignored issues
show
Bug introduced by
The method getUser does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
303
        } else {
304
            Yii::$app->getSession()->set($name, $url);
0 ignored issues
show
Bug introduced by
The method getSession does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
305
        }
306
    }
307
308
    /**
309
     * Returns the URL previously [[remember()|remembered]].
310
     *
311
     * @param string $name the named associated with the URL that was remembered previously.
312
     * If not set, it will use [[\yii\web\User::returnUrlParam]].
313
     * @return string|null the URL previously remembered. Null is returned if no URL was remembered with the given name.
314
     * @see remember()
315
     */
316
    public static function previous($name = null)
317
    {
318
        if ($name === null) {
319
            return Yii::$app->getUser()->getReturnUrl();
0 ignored issues
show
Bug introduced by
The method getUser does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
320
        } else {
321
            return Yii::$app->getSession()->get($name);
0 ignored issues
show
Bug introduced by
The method getSession does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
322
        }
323
    }
324
325
    /**
326
     * Returns the canonical URL of the currently requested page.
327
     * The canonical URL is constructed using the current controller's [[\yii\web\Controller::route]] and
328
     * [[\yii\web\Controller::actionParams]]. You may use the following code in the layout view to add a link tag
329
     * about canonical URL:
330
     *
331
     * ```php
332
     * $this->registerLinkTag(['rel' => 'canonical', 'href' => Url::canonical()]);
333
     * ```
334
     *
335
     * @return string the canonical URL of the currently requested page
336
     */
337 1
    public static function canonical()
338
    {
339 1
        $params = Yii::$app->controller->actionParams;
340 1
        $params[0] = Yii::$app->controller->getRoute();
341
342 1
        return static::getUrlManager()->createAbsoluteUrl($params);
343
    }
344
345
    /**
346
     * Returns the home URL.
347
     *
348
     * @param bool|string $scheme the URI scheme to use for the returned URL:
349
     *
350
     * - `false` (default): returning a relative URL.
351
     * - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]].
352
     * - string: returning an absolute URL with the specified scheme (either `http`, `https` or empty string
353
     *   for protocol-relative URL).
354
     *
355
     * @return string home URL
356
     */
357 1
    public static function home($scheme = false)
358
    {
359 1
        $url = Yii::$app->getHomeUrl();
0 ignored issues
show
Bug introduced by
The method getHomeUrl does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
360
361 1
        if ($scheme !== false) {
362 1
            $url = static::getUrlManager()->getHostInfo() . $url;
363 1
            $url = static::ensureScheme($url, $scheme);
0 ignored issues
show
Bug introduced by
It seems like $scheme defined by parameter $scheme on line 357 can also be of type boolean; however, yii\helpers\BaseUrl::ensureScheme() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
364 1
        }
365
366 1
        return $url;
367
    }
368
369
    /**
370
     * Returns a value indicating whether a URL is relative.
371
     * A relative URL does not have host info part.
372
     * @param string $url the URL to be checked
373
     * @return bool whether the URL is relative
374
     */
375 42
    public static function isRelative($url)
376
    {
377 42
        return strncmp($url, '//', 2) && strpos($url, '://') === false;
378
    }
379
380
    /**
381
     * Creates a URL by using the current route and the GET parameters.
382
     *
383
     * You may modify or remove some of the GET parameters, or add additional query parameters through
384
     * the `$params` parameter. In particular, if you specify a parameter to be null, then this parameter
385
     * will be removed from the existing GET parameters; all other parameters specified in `$params` will
386
     * be merged with the existing GET parameters. For example,
387
     *
388
     * ```php
389
     * // assume $_GET = ['id' => 123, 'src' => 'google'], current route is "post/view"
390
     *
391
     * // /index.php?r=post%2Fview&id=123&src=google
392
     * echo Url::current();
393
     *
394
     * // /index.php?r=post%2Fview&id=123
395
     * echo Url::current(['src' => null]);
396
     *
397
     * // /index.php?r=post%2Fview&id=100&src=google
398
     * echo Url::current(['id' => 100]);
399
     * ```
400
     *
401
     * Note that if you're replacing array parameters with `[]` at the end you should specify `$params` as nested arrays.
402
     * For a `PostSearchForm` model where parameter names are `PostSearchForm[id]` and `PostSearchForm[src]` the syntax
403
     * would be the following:
404
     *
405
     * ```php
406
     * // index.php?r=post%2Findex&PostSearchForm%5Bid%5D=100&PostSearchForm%5Bsrc%5D=google
407
     * echo Url::current([
408
     *     $postSearch->formName() => ['id' => 100, 'src' => 'google'],
409
     * ]);
410
     * ```
411
     *
412
     * @param array $params an associative array of parameters that will be merged with the current GET parameters.
413
     * If a parameter value is null, the corresponding GET parameter will be removed.
414
     * @param bool|string $scheme the URI scheme to use in the generated URL:
415
     *
416
     * - `false` (default): generating a relative URL.
417
     * - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]].
418
     * - string: generating an absolute URL with the specified scheme (either `http`, `https` or empty string
419
     *   for protocol-relative URL).
420
     *
421
     * @return string the generated URL
422
     * @since 2.0.3
423
     */
424 1
    public static function current(array $params = [], $scheme = false)
425
    {
426 1
        $currentParams = Yii::$app->getRequest()->getQueryParams();
427 1
        $currentParams[0] = '/' . Yii::$app->controller->getRoute();
428 1
        $route = ArrayHelper::merge($currentParams, $params);
429 1
        return static::toRoute($route, $scheme);
430
    }
431
432
    /**
433
     * @return \yii\web\UrlManager URL manager used to create URLs
434
     * @since 2.0.8
435
     */
436 9
    protected static function getUrlManager()
437
    {
438 9
        return static::$urlManager ?: Yii::$app->getUrlManager();
439
    }
440
}
441