Completed
Push — master ( 698bc6...5c7680 )
by Thibaud
8s
created

ResourceUri::getPath()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 7
c 1
b 0
f 1
nc 4
nop 0
dl 0
loc 14
ccs 8
cts 8
cp 1
crap 3
rs 9.4285
1
<?php
2
3
/*
4
 * This file is part of alchemy/resource-component.
5
 *
6
 * (c) Alchemy <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Alchemy\Resource;
13
14
final class ResourceUri
15
{
16
17
    const DEFAULT_PROTOCOL = 'file';
18
19
    /**
20
     * @param $uri
21
     * @return array
22
     */
23
    private static function getNonEmptyParts($uri)
24
    {
25 224
        $nonEmptyStringFilter = function ($value) {
26 224
            return $value != '';
27 224
        };
28
29 224
        return array_filter(explode(self::PROTOCOL_SEPARATOR, $uri, 2), $nonEmptyStringFilter);
30
    }
31
32
    const PROTOCOL_SEPARATOR = '://';
33
34
    /**
35
     * @param $parts
36
     * @return bool
37
     */
38 224
    private static function validateResourceParts($parts)
39
    {
40 224
        return count($parts) === 2;
41
    }
42
43
    /**
44
     * @param $protocol
45
     * @param $resource
46
     * @return self
47
     */
48 20
    public static function fromProtocolAndResource($protocol, $resource)
49
    {
50 20
        return new self($protocol . self::PROTOCOL_SEPARATOR . $resource);
51
    }
52
53
    /**
54
     * @param $uri
55
     * @return bool
56
     */
57 236
    public static function isValidUri($uri)
58
    {
59 236
        if (strpos($uri, self::PROTOCOL_SEPARATOR) === false) {
60 24
            return false;
61
        }
62
63 224
        $parts = self::getNonEmptyParts($uri);
64
65 224
        if (! self::validateResourceParts($parts)) {
66 44
            return false;
67
        }
68
69 200
        if (strpos($parts[1], self::PROTOCOL_SEPARATOR) !== false) {
70 48
            return self::isValidUri($parts[1]);
71
        }
72
73 184
        return true;
74
    }
75
76 148
    public static function fromString($uri)
77
    {
78 148
        if (strpos($uri, self::PROTOCOL_SEPARATOR) === false) {
79 28
            $uri = self::DEFAULT_PROTOCOL . self::PROTOCOL_SEPARATOR . $uri;
80 21
        }
81
82 148
        return new self($uri);
83
    }
84
85 8
    public static function fromStringArray(array $uris)
86
    {
87 8
        $resourceUris = [];
88
89 8
        foreach ($uris as $uri) {
90 8
            $resourceUris[] = self::fromString($uri);
91 6
        }
92
93
94 4
        return $resourceUris;
95
    }
96
97
    /**
98
     * @var string
99
     */
100
    private $uri;
101
102
    /**
103
     * @var string
104
     */
105
    private $protocol;
106
107
    /**
108
     * @var string
109
     */
110
    private $resource;
111
112
    /**
113
     * @param string $uri
114
     */
115 180
    public function __construct($uri)
116
    {
117 180
        if (! self::isValidUri($uri)) {
118 24
            throw new \InvalidArgumentException(sprintf(
119 24
                'Malformed URI: required format is "protocol://resource", got "%s"',
120
                $uri
121 18
            ));
122
        }
123
124 160
        $this->uri = $uri;
125
126 160
        list ($this->protocol, $this->resource) = explode('://', $uri, 2);
127 160
    }
128
129
    /**
130
     * @return string
131
     */
132 56
    public function getUri()
133
    {
134 56
        return $this->uri;
135
    }
136
137
    /**
138
     * @return string
139
     */
140 28
    public function getProtocol()
141
    {
142 28
        return $this->protocol;
143
    }
144
145
    /**
146
     * @return string
147
     */
148 24
    public function getResource()
149
    {
150 24
        return $this->resource;
151
    }
152
153
    /**
154
     * @return bool
155
     */
156 24
    public function hasChainedResource()
157
    {
158 24
        return self::isValidUri($this->resource);
159
    }
160
161
    /**
162
     * @return self
163
     */
164 16
    public function getChainedResource()
165
    {
166 16
        return new self($this->resource);
167
    }
168
169
    /**
170
     * @param ResourceUri $other
171
     * @return bool
172
     */
173 8
    public function equals(ResourceUri $other)
174
    {
175 8
        return $this->getUri() == $other->getUri();
176
    }
177
178 8
    public function chain($containerProtocol)
179
    {
180 8
        return self::fromProtocolAndResource($containerProtocol, (string) $this);
181
    }
182
183 12
    public function child($childRelativePath)
184
    {
185 12
        return self::fromProtocolAndResource($this->protocol, $this->resource . '/' . ltrim($childRelativePath, '/'));
186
    }
187
188 12
    public function getPath()
189
    {
190 12
        $resource = $this;
191
192 12
        while ($resource->hasChainedResource()) {
193 4
            $resource = $resource->getChainedResource();
194 3
        }
195
196 12
        if (false === $position = strrpos($resource->getResource(), '/')) {
197 4
            return '';
198
        }
199
200 8
        return substr($resource->getResource(), $position + 1);
201
    }
202
203
    /**
204
     * @return string
205
     */
206 44
    public function __toString()
207
    {
208 44
        return $this->uri;
209
    }
210
}
211