Uri::linkTo()   F
last analyzed

Complexity

Conditions 20
Paths 386

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 21.6384

Importance

Changes 0
Metric Value
dl 0
loc 35
ccs 21
cts 25
cp 0.84
rs 1.0083
c 0
b 0
f 0
cc 20
nc 386
nop 3
crap 21.6384

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace vakata\http;
4
5
use Laminas\Diactoros\Uri as LaminasUri;
6
7
class Uri extends LaminasUri
8
{
9
    protected $basePath;
10
    protected $realPath;
11
    protected $segments;
12
13 2
    public function __construct($uri = '', string $base = null)
14
    {
15 2
        parent::__construct($uri);
16 2
        $this->setBasePath($base);
17 2
    }
18
19 2
    public function setBasePath(string $base = null)
20
    {
21 2
        $base = $base ?: (isset($_SERVER['PHP_SELF']) ? dirname($_SERVER['PHP_SELF']) : '/');
22 2
        $this->basePath = str_replace('//', '/', '/' . trim(str_replace('\\', '/', $base), '/') . '/');
23 2
        $this->realPath = $this->getPath();
24 2
        $hasTrailingSlash = strlen($this->realPath) && substr($this->realPath, -1) === '/';
25 2
        $this->realPath = explode('?', $this->realPath, 2)[0];
26 2
        $this->realPath = str_replace('//', '/', '/' . trim($this->realPath, '/') . '/');
27 2
        if (strpos($this->realPath, $this->basePath) === 0) {
28 1
            $this->realPath = substr($this->realPath, strlen($this->basePath)) ?: '';
29
        }
30 2
        $this->realPath = rtrim($this->realPath, '/') . ($hasTrailingSlash ? '/' : '');
31 2
        $this->segments = array_map('urldecode', array_filter(
32 2
            explode('/', trim($this->realPath, '/')),
33 2
            function ($v) {
34 2
                return $v !== '';
35 2
            }
36
        ));
37 2
        $this->segments['base'] = $this->basePath;
38 2
        $this->segments['path'] = trim($this->realPath, '/');
39 2
        return $this;
40
    }
41
42 1
    public function getBasePath()
43
    {
44 1
        return $this->basePath;
45
    }
46 1
    public function getRealPath()
47
    {
48 1
        return $this->realPath;
49
    }
50 1
    public function getSegment($index, $default = null)
51
    {
52 1
        if (is_numeric($index) && (int)$index < 0) {
53
            $index = count($this->segments) - 2 + $index; // -2 to avoid "base" and "path"
54
        }
55 1
        return $this->segments[$index] ?? $default;
56
    }
57 1
    public function linkTo(string $path = '', array $params = [], bool $absolute = false)
58
    {
59 1
        if (strpos($path, '?') !== false) {
60 1
            list($path, $query) = explode('?', $path, 2);
61 1
            $params = array_merge(Request::fixedQueryParams($query), $params);
62
        }
63 1
        $data = parse_url($path . (count($params) ? '?' . http_build_query($params) : ''));
64 1
        if (!isset($data['host']) && !isset($data['path'])) {
65
            throw new \Exception('Invalid destination');
66
        }
67 1
        if (!isset($data['path']) || !strlen($data['path'])) {
68
            $data['path'] = isset($data['host']) ? '/' : $this->getBasePath();
69
        }
70 1
        if (substr($data['path'], 0, 1) !== '/') {
71 1
            $data['path'] = $this->basePath . $data['path'];
72
        }
73 1
        $curr = parse_url((string)$this);
74 1
        unset($curr['query']);
75 1
        unset($curr['fragment']);
76 1
        $data = array_merge($curr, $data);
77 1
        $host = $data['host'] . (isset($data['port']) ? ':' . $data['port'] : '');
78 1
        $data['path'] = implode('/', array_map('urlencode', explode('/', $data['path'])));
79 1
        $path = $data['path'] . (isset($data['query']) ? '?' . $data['query'] : '');
80 1
        $frag = isset($data['fragment']) ? '#' . $data['fragment'] : '';
81
82 1
        if ($absolute || (isset($data['scheme']) && $data['scheme'] !== ($curr['scheme'] ?? null))) {
83
            return (isset($data['scheme']) ? $data['scheme'] . ':' : '') . '//' . $host . $path . $frag;
84
        }
85 1
        if ((isset($data['host']) && $data['host'] !== $curr['host']) ||
86 1
            (isset($data['port']) && $data['port'] !== $curr['port'])
87
        ) {
88
            return '//' . $host . $path . $frag;
89
        }
90 1
        return $path . $frag;
91
    }
92 1
    public function self(bool $absolute = false)
93
    {
94 1
        return $this->linkTo($this->realPath . ($this->getQuery() ? '?' . $this->getQuery() : ''), [], $absolute);
95
    }
96
97
    public function get(string $path = '', array $params = [], int $relative = 0)
98
    {
99
        return $this->linkTo($path, $params, $relative > 0);
100
    }
101
    public function __invoke(string $path = '', array $params = [], int $relative = 0)
102
    {
103
        return $this->linkTo($path, $params, $relative > 0);
104
    }
105
}
106