Completed
Push — master ( e31061...1587a0 )
by Joschi
02:44
created

ObjectUrl::getLocalPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * apparat-object
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Object\Domain
8
 * @author      Joschi Kuphal <[email protected]> / @jkphl
9
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
10
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
11
 */
12
13
/***********************************************************************************
14
 *  The MIT License (MIT)
15
 *
16
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
17
 *
18
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
19
 *  this software and associated documentation files (the "Software"), to deal in
20
 *  the Software without restriction, including without limitation the rights to
21
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
22
 *  the Software, and to permit persons to whom the Software is furnished to do so,
23
 *  subject to the following conditions:
24
 *
25
 *  The above copyright notice and this permission notice shall be included in all
26
 *  copies or substantial portions of the Software.
27
 *
28
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
30
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
31
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
32
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34
 ***********************************************************************************/
35
36
namespace Apparat\Object\Domain\Model\Path;
37
38
use Apparat\Kernel\Ports\Kernel;
39
use Apparat\Object\Domain\Model\Object\Id;
40
use Apparat\Object\Domain\Model\Object\Revision;
41
use Apparat\Object\Domain\Model\Object\Type;
42
43
/**
44
 * Object URL
45
 *
46
 * @package Apparat\Object\Domain\Model
47
 */
48
class ObjectUrl extends Url implements PathInterface
49
{
50
    /**
51
     * Object path
52
     *
53
     * @var LocalPath
54
     */
55
    protected $localPath = null;
56
57
    /*******************************************************************************
58
     * PUBLIC METHODS
59
     *******************************************************************************/
60
61
    /**
62
     * Object URL constructor
63
     *
64
     * @param string $url Object URL
65
     * @param boolean $remote Accept remote URL (less strict date component checking)
66
     * @throws InvalidArgumentException If remote URLs are not allowed and a remote URL is given
67
     */
68 31
    public function __construct($url, $remote = false)
69
    {
70 31
        parent::__construct($url);
71
72
        // If it's an invalid remote object URL
73 30
        if ($this->isAbsolute() && !$remote) {
74 1
            throw new InvalidArgumentException(
75 1
                sprintf('Unallowed remote object URL "%s"', $url),
76 1
                InvalidArgumentException::UNALLOWED_REMOTE_OBJECT_URL
77
            );
78
        }
79
80
        // Instantiate the local path component
81 29
        $this->localPath = new LocalPath(
82 29
            empty($this->urlParts['path']) ? '' : $this->urlParts['path'],
83 29
            $remote ? true : null,
84 29
            $this->urlParts['path']
85
        );
86
87
        // Normalize the path prefix
88 26
        if (!strlen($this->urlParts['path'])) {
89 12
            $this->urlParts['path'] = null;
90
        }
91 26
    }
92
93
    /**
94
     * Set the object's creation date
95
     *
96
     * @param \DateTimeImmutable $creationDate
97
     * @return PathInterface|ObjectUrl New object path
98
     */
99 1
    public function setCreationDate(\DateTimeImmutable $creationDate)
100
    {
101 1
        $this->localPath = $this->localPath->setCreationDate($creationDate);
102 1
        return $this;
103
    }
104
105
    /**
106
     * Set the object type
107
     *
108
     * @param Type $type Object type
109
     * @return PathInterface|ObjectUrl New object URL
110
     */
111 1
    public function setType(Type $type)
112
    {
113 1
        $this->localPath = $this->localPath->setType($type);
114 1
        return $this;
115
    }
116
117
    /**
118
     * Set the object ID
119
     *
120
     * @param Id $uid Object ID
121
     * @return PathInterface|ObjectUrl New object URL
122
     */
123 1
    public function setId(Id $uid)
124
    {
125 1
        $this->localPath = $this->localPath->setId($uid);
126 1
        return $this;
127
    }
128
129
    /**
130
     * Set the object revision
131
     *
132
     * @param Revision $revision Object revision
133
     * @return PathInterface|ObjectUrl New object URL
134
     */
135 1
    public function setRevision(Revision $revision)
136
    {
137 1
        $this->localPath = $this->localPath->setRevision($revision);
138 1
        return $this;
139
    }
140
141
    /**
142
     * Test if this URL matches all available parts of a given URL
143
     *
144
     * @param Url $url Comparison URL
145
     * @return bool This URL matches all available parts of the given URL
146
     */
147 7
    public function matches(Url $url)
148
    {
149
        // If the standard URL components don't match
150 7
        if (!parent::matches($url)) {
151 5
            return false;
152
        }
153
154
        // Extended tests if it's an object URL
155 4
        if ($url instanceof self) {
156
            // Test the object creation date
157 1
            if ($this->getCreationDate() != $url->getCreationDate()) {
158 1
                return false;
159
            }
160
161
            // Test the object ID
162 1
            if ($this->getId()->serialize() !== $url->getId()->serialize()) {
163 1
                return false;
164
            }
165
166
            // Test the object type
167 1
            if ($this->getType()->serialize() !== $url->getType()->serialize()) {
168 1
                return false;
169
            }
170
171
            // Test the object revision
172 1
            if ($this->getRevision()->serialize() !== $url->getRevision()->serialize()) {
173 1
                return false;
174
            }
175
        }
176
177 4
        return true;
178
    }
179
180
    /**
181
     * Return the object's creation date
182
     *
183
     * @return \DateTimeImmutable Object creation date
184
     */
185 6
    public function getCreationDate()
186
    {
187 6
        return $this->localPath->getCreationDate();
188
    }
189
190
    /**
191
     * Return the object ID
192
     *
193
     * @return Id Object ID
194
     */
195 9
    public function getId()
196
    {
197 9
        return $this->localPath->getId();
198
    }
199
200
    /**
201
     * Return the object type
202
     *
203
     * @return Type Object type
204
     */
205 6
    public function getType()
206
    {
207 6
        return $this->localPath->getType();
208
    }
209
210
    /**
211
     * Return the object revision
212
     *
213
     * @return Revision Object revision
214
     */
215 6
    public function getRevision()
216
    {
217 6
        return $this->localPath->getRevision();
218
    }
219
220
    /**
221
     * Return the local object path
222
     *
223
     * @return PathInterface|LocalPath Local object path
224
     */
225 1
    public function getLocalPath()
226
    {
227 1
        return $this->localPath;
228
    }
229
230
    /**
231
     * Return the repository URL part of this object URL
232
     *
233
     * @return string Repository URL
234
     * @see https://github.com/apparat/apparat/blob/master/doc/URL-DESIGN.md#repository-url
235
     */
236 10
    public function getRepositoryUrl()
237
    {
238
        // If the object URL is absolute and local: Extract the repository URL
239 10
        if ($this->isAbsoluteLocal()) {
240 1
            $baseUrl = Kernel::create(Url::class, [getenv('APPARAT_BASE_URL')]);
241 1
            return substr($this->getPath(), strlen($baseUrl->getPath()));
242
243
            // Else: If it's a relative URL: Extract the repository URL
244 9
        } elseif (!$this->isAbsolute()) {
245 6
            return $this->getPath();
246
        }
247
248
        // Else: It must be a remote repository
249
        $override = [
250 3
            'object' => '',
251
            'query' => '',
252
            'fragment' => '',
253
        ];
254 3
        return $this->getUrlInternal($override);
255
    }
256
257
    /*******************************************************************************
258
     * PRIVATE METHODS
259
     *******************************************************************************/
260
261
    /**
262
     * Return the a complete serialized object URL
263
     *
264
     * @param array $override Override components
265
     * @return string Serialized URL
266
     */
267 8
    protected function getUrlInternal(array &$override = [])
268
    {
269 8
        parent::getUrlInternal($override);
270
271
        // Prepare the local object path
272 8
        $override['object'] = isset($override['object']) ? $override['object'] : strval($this->localPath);
273
274 8
        return "{$override['scheme']}{$override['user']}{$override['pass']}{$override['host']}{$override['port']}".
275 8
        "{$override['path']}{$override['object']}{$override['query']}{$override['fragment']}";
276
    }
277
}
278