Completed
Push — master ( a3cf5c...c7a2f3 )
by Ivan
02:35
created

Uri::setBasePath()   C

Complexity

Conditions 7
Paths 48

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 18
cts 18
cp 1
rs 6.9811
c 0
b 0
f 0
cc 7
eloc 17
nc 48
nop 1
crap 7
1
<?php
2
3
namespace vakata\http;
4
5
use Zend\Diactoros\Uri as ZendUri;
6
7
class Uri extends ZendUri
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) + $index;
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
        $path = $data['path'] . (isset($data['query']) ? '?' . $data['query'] : '');
79 1
        $frag = isset($data['fragment']) ? '#' . $data['fragment'] : '';
80
81 1
        if ($absolute || (isset($data['scheme']) && $data['scheme'] !== $curr['scheme'])) {
82
            return $data['scheme'] . '://' . $host . $path . $frag;
83
        }
84 1
        if ((isset($data['host']) && $data['host'] !== $curr['host']) ||
85 1
            (isset($data['port']) && $data['port'] !== $curr['port'])
86
        ) {
87
            return '//' . $host . $path . $frag;
88
        }
89 1
        return $path . $frag;
90
    }
91 1
    public function self(bool $absolute = false)
92
    {
93 1
        return $this->linkTo($this->realPath . ($this->getQuery() ? '?' . $this->getQuery() : ''), [], $absolute);
94
    }
95
96
    public function get(string $path = '', array $params = [], int $relative = 0)
97
    {
98
        return $this->linkTo($path, $params, $relative > 0);
99
    }
100
    public function __invoke(string $path = '', array $params = [], int $relative = 0)
101
    {
102
        return $this->linkTo($path, $params, $relative > 0);
103
    }
104
}
105