Completed
Push — master ( b86bda...68c2b9 )
by Alex
02:22
created

Psr7UriExtension::urlFromUri()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 9
cts 9
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 11
nc 3
nop 1
crap 3
1
<?php
2
3
namespace AlexMasterov\TwigExtension;
4
5
use AlexMasterov\TwigExtension\Traits\ServerRequestTrait;
6
use Psr\Http\Message\UriInterface;
7
use Twig_Extension;
8
9
class Psr7UriExtension extends Twig_Extension
10
{
11
    use ServerRequestTrait;
12
13
    /**
14
     * @return string The extension name
15 1
     */
16
    public function getName()
17 1
    {
18
        return 'psr7_uri';
19
    }
20 1
21
    public function getFunctions()
22
    {
23 1
        return [
24 1
            new \Twig_SimpleFunction('absolute_url', [$this, 'generateAbsoluteUrl']),
25 1
            new \Twig_SimpleFunction('relative_path', [$this, 'generateRelativePath'])
26
        ];
27
    }
28
29
    /**
30
     * @param string $path
31
     *
32
     * @return string
33 10
     */
34
    public function generateAbsoluteUrl($path = null)
35 10
    {
36 1
        $requestUri = $this->request->getUri();
37
38
        $url = $this->urlFromUri($requestUri);
39 9
        if (null === $path) {
40
            return $url;
41 9
        }
42 9
43 1
        if ($this->isNetworkPath($path)) {
44
            return $path;
45
        }
46 8
47 1
        if (!$this->hasLeadingSlash($url)) {
48 1
            $url = rtrim($url, '/') . "/{$path}";
49
        }
50 8
51 3
        return $url;
52 3
    }
53
54 8
    /**
55
     * @param UriInterface $uri
56
     *
57
     * @return string
58
     */
59
    protected function urlFromUri(UriInterface $uri)
60
    {
61
        $host = $uri->getHost();
62 16
        $path = $uri->getPath();
63
        if (empty($host)) {
64 16
            return $path;
65 1
        }
66
67
        $port = $uri->getPort();
68 15
        if (!empty($port)) {
69
            $host .= ":{$port}";
70 15
        }
71 15
72 3
        $scheme = $uri->getScheme();
73
        $url = "{$scheme}://{$host}{$path}";
74
75 12
        return $url;
76 12
    }
77
78 12
    /**
79 12
     * @param string $path
80 12
     *
81 12
     * @return string
82 7
     */
83
    public function generateRelativePath($path)
84 12
    {
85
        if ($this->isNetworkPath($path) || !$this->hasLeadingSlash($path)) {
86 12
            return $path;
87
        }
88 12
89 1
        $uri = $this->request->getUri();
90
91
        $basePath = $uri->getPath();
92 11
        if ($path === $basePath) {
93 1
            return '';
94 1
        }
95
96 11
        $baseParts = explode('/', $basePath, -1);
97
        $pathParts = explode('/', $path);
98
99
        foreach ($baseParts as $i => $segment) {
100
            if (isset($pathParts[$i]) && $segment === $pathParts[$i]) {
101
                unset($baseParts[$i], $pathParts[$i]);
102
            } else {
103
                break;
104 26
            }
105
        }
106 26
107 26
        $path = str_repeat('../', count($baseParts)) . implode('/', $pathParts);
108
109
        if (empty($path)) {
110
            return './';
111
        }
112
113
        if (empty($baseParts) && false !== strpos(current($pathParts), ':')) {
114
            $path = './' . $path;
115 23
        }
116
117 23
        return $path;
118
    }
119
120
    /**
121
     * @param string $path
122
     *
123
     * @return bool
124
     */
125
    protected function isNetworkPath($path)
126
    {
127
        return false !== strpos($path, '://')
128
            || '//' === substr($path, 0, 2);
129
    }
130
131
    /**
132
     * @param string $path
133
     *
134
     * @return bool
135
     */
136
    protected function hasLeadingSlash($path)
137
    {
138
        return isset($path[0]) && '/' === $path[0];
139
    }
140
}
141