Completed
Push — master ( c1c6ff...d793b2 )
by ignace nyamagana
05:44
created

Resolve::__invoke()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 3
eloc 19
c 5
b 0
f 0
nc 3
nop 1
dl 0
loc 26
ccs 16
cts 16
cp 1
crap 3
rs 8.8571
1
<?php
2
/**
3
 * League.Uri (http://uri.thephpleague.com)
4
 *
5
 * @package   League.uri
6
 * @author    Ignace Nyamagana Butera <[email protected]>
7
 * @copyright 2013-2015 Ignace Nyamagana Butera
8
 * @license   https://github.com/thephpleague/uri/blob/master/LICENSE (MIT License)
9
 * @version   4.2.0
10
 * @link      https://github.com/thephpleague/uri/
11
 */
12
namespace League\Uri\Modifiers;
13
14
use League\Uri\Components\Path;
15
use League\Uri\Interfaces\Uri;
16
use League\Uri\Modifiers\Filters\Uri as UriFilter;
17
use Psr\Http\Message\UriInterface;
18
19
/**
20
 * Resolve an URI according to a base URI using
21
 * RFC3986 rules
22
 *
23
 * @package League.uri
24
 * @author  Ignace Nyamagana Butera <[email protected]>
25
 * @since   4.0.0
26
 */
27
class Resolve extends AbstractUriModifier
28
{
29
    use UriFilter;
30
31
    /**
32
     * New instance
33
     *
34
     * @param Uri|UriInterface $uri
35
     */
36 150
    public function __construct($uri)
37
    {
38 150
        $this->assertUriObject($uri);
39 150
        $this->uri = $uri;
40 150
    }
41
42
    /**
43
     * Return a Uri object modified according to the modifier
44
     *
45
     * @param Uri|UriInterface $payload
46
     *
47
     * @return Uri|UriInterface
48
     */
49 150
    public function __invoke($payload)
50
    {
51 150
        $meta = \League\Uri\uri_get_meta_data($payload);
52 150
        $path = $payload->getPath();
53 150
        if ($meta['absolute_uri']) {
54
            return $payload
55 6
                ->withPath((new Path($path))->withoutDotSegments()->__toString());
56
        }
57
58 144
        if ($meta['network_path']) {
59
            return $payload
60 3
                ->withScheme($this->uri->getScheme())
61 3
                ->withPath((new Path($path))->withoutDotSegments()->__toString());
62
        }
63
64 141
        $userInfo = explode(':', $this->uri->getUserInfo(), 2);
65 141
        $components = $this->resolvePathAndQuery($path, $payload->getQuery());
66
67
        return $payload
68 141
            ->withPath($this->formatPath($components['path']))
69 141
            ->withQuery($components['query'])
70 141
            ->withHost($this->uri->getHost())
71 141
            ->withPort($this->uri->getPort())
72 141
            ->withUserInfo((string) array_shift($userInfo), array_shift($userInfo))
73 141
            ->withScheme($this->uri->getScheme());
74
    }
75
76
    /**
77
     * Resolve the URI for a Authority-less payload URI
78
     *
79
     * @param string $path  the payload path component
80
     * @param string $query the payload query component
81
     *
82
     * @return string[]
83
     */
84 141
    protected function resolvePathAndQuery($path, $query)
85
    {
86 141
        $components = ['path' => $path, 'query' => $query];
87
88 141
        if ('' === $components['path']) {
89 9
            $components['path'] = $this->uri->getPath();
90 9
            if ('' === $components['query']) {
91 6
                $components['query'] = $this->uri->getQuery();
92 4
            }
93
94 9
            return $components;
95
        }
96
97 132
        if (0 !== strpos($components['path'], '/')) {
98 123
            $components['path'] = $this->mergePath($components['path']);
99 82
        }
100
101 132
        return $components;
102
    }
103
104
    /**
105
     * Merging Relative URI path with Base URI path
106
     *
107
     * @param string $path
108
     *
109
     * @return string
110
     */
111 123
    protected function mergePath($path)
112
    {
113 123
        $basePath = $this->uri->getPath();
114 123
        if ('' !== $this->uri->getAuthority() && '' === $basePath) {
115 3
            return (string) (new Path($path))->withLeadingSlash();
116
        }
117
118 120
        if ('' !== $basePath) {
119 120
            $segments = explode('/', $basePath);
120 120
            array_pop($segments);
121 120
            $path = implode('/', $segments).'/'.$path;
122 80
        }
123
124 120
        return $path;
125
    }
126
127
    /**
128
     * Format the resolved path
129
     *
130
     * @param string $path
131
     *
132
     * @return string
133
     */
134 141
    protected function formatPath($path)
135
    {
136 141
        $path = (new Path($path))->withoutDotSegments();
137 141
        if ('' !== $this->uri->getAuthority() && '' !== $path->__toString()) {
138 126
            $path = $path->withLeadingSlash();
139 84
        }
140
141 141
        return (string) $path;
142
    }
143
}
144