Completed
Push — master ( a783ca...18c4d4 )
by Joschi
03:44
created

SystemProperties::getLatitude()   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 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
cc 1
eloc 2
nc 1
nop 0
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
/**
4
 * apparat-object
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Object
8
 * @subpackage  Apparat\Object\Application
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Apparat\Object\Domain\Model\Properties;
38
39
use Apparat\Kernel\Tests\Kernel;
40
use Apparat\Object\Domain\Model\Object\Id;
41
use Apparat\Object\Domain\Model\Object\ObjectInterface;
42
use Apparat\Object\Domain\Model\Object\Revision;
43
use Apparat\Object\Domain\Model\Object\RuntimeException;
44
use Apparat\Object\Domain\Model\Object\Type;
45
46
/**
47
 * Object system properties collection
48
 *
49
 * In general, the system properties are used as read-only collection, with one exception: Draft objects don't have the
50
 * `published` property set, so there's a {@link publish()} method for advancing an object's state.
51
 *
52
 * @package Apparat\Object
53
 * @subpackage Apparat\Object\Application
54
 */
55
class SystemProperties extends AbstractProperties
56
{
57
    /**
58
     * Collection name
59
     *
60
     * @var string
61
     */
62
    const COLLECTION = 'system';
63
    /**
64
     * ID property
65
     *
66
     * @var string
67
     */
68
    const PROPERTY_ID = 'id';
69
    /**
70
     * Type property
71
     *
72
     * @var string
73
     */
74
    const PROPERTY_TYPE = 'type';
75
    /**
76
     * Revision property
77
     *
78
     * @var string
79
     */
80
    const PROPERTY_REVISION = 'revision';
81
    /**
82
     * Created property
83
     *
84
     * @var string
85
     */
86
    const PROPERTY_CREATED = 'created';
87
    /**
88
     * Published property
89
     *
90
     * @var string
91
     */
92
    const PROPERTY_PUBLISHED = 'published';
93
    /**
94
     * LocationProperties property
95
     *
96
     * @var string
97
     */
98
    const PROPERTY_LOCATION = 'location';
99
    /**
100
     * Object ID (constant throughout revisions)
101
     *
102
     * @var Id
103
     */
104
    protected $uid = null;
105
    /**
106
     * Object type (constant throughout revisions)
107
     *
108
     * @var Type
109
     */
110
    protected $type = null;
111
    /**
112
     * Object revision
113
     *
114
     * @var Revision
115
     */
116
    protected $revision = null;
117
    /**
118
     * Creation date of this revision
119
     *
120
     * @var \DateTimeImmutable
121
     */
122
    protected $created = null;
123
    /**
124
     * Publication date of this revision
125
     *
126
     * @var \DateTimeImmutable
127
     */
128
    protected $published = null;
129
    /**
130
     * Location
131
     *
132
     * @var LocationProperties
133
     */
134
    protected $location = null;
135
136
    /**
137
     * System properties constructor
138
     *
139
     * @param array $data Property data
140
     * @param ObjectInterface $object Owner object
141
     */
142 27
    public function __construct(array $data, ObjectInterface $object)
143
    {
144 27
        parent::__construct($data, $object);
145
146
        // Initialize the object ID
147 27
        if (array_key_exists(self::PROPERTY_ID, $data)) {
148 25
            $this->uid = Id::unserialize($data[self::PROPERTY_ID]);
149 25
        }
150
151
        // Initialize the object type
152 27
        if (array_key_exists(self::PROPERTY_TYPE, $data)) {
153 26
            $this->type = Type::unserialize($data[self::PROPERTY_TYPE]);
154 25
        }
155
156
        // Initialize the object revision
157 26
        if (array_key_exists(self::PROPERTY_REVISION, $data)) {
158 25
            $this->revision = Revision::unserialize($data[self::PROPERTY_REVISION]);
159 25
        }
160
161
        // Initialize the object creation date
162 26
        if (array_key_exists(self::PROPERTY_CREATED, $data)) {
163 25
            $this->created = new \DateTimeImmutable('@'.$data[self::PROPERTY_CREATED]);
164 25
        }
165
166
        // Initialize the object publication date
167 26
        if (array_key_exists(self::PROPERTY_PUBLISHED, $data)) {
168 20
            $this->published = new \DateTimeImmutable('@'.$data[self::PROPERTY_PUBLISHED]);
169 20
        }
170
171
        // Initialize the location
172 26
        $this->location = Kernel::create(
173 26
            LocationProperties::class,
174 26
            [empty($data[self::PROPERTY_LOCATION]) ? [] : $data[self::PROPERTY_LOCATION], $this->object]
175 26
        );
176
177
        // Test if all mandatory properties are set
178 26
        if (!($this->uid instanceof Id)
179 26
            || !($this->type instanceof Type)
180 25
            || !($this->revision instanceof Revision)
181 25
            || !($this->created instanceof \DateTimeImmutable)
182 26
        ) {
183 1
            throw new InvalidArgumentException(
184 1
                'Invalid system properties',
185
                InvalidArgumentException::INVALID_SYSTEM_PROPERTIES
186 1
            );
187
        }
188 25
    }
189
190
    /**
191
     * Return the object ID
192
     *
193
     * @return Id Object ID
194
     */
195 5
    public function getId()
196
    {
197 5
        return $this->uid;
198
    }
199
200
    /**
201
     * Return the object type
202
     *
203
     * @return Type Object type
204
     */
205 1
    public function getType()
206
    {
207 1
        return $this->type;
208
    }
209
210
    /**
211
     * Return the object revision
212
     *
213
     * @return Revision Object revision
214
     */
215 24
    public function getRevision()
216
    {
217 24
        return $this->revision;
218
    }
219
220
    /**
221
     * Return the object draft mode
222
     *
223
     * @return boolean Object draft mode
224
     */
225 5
    public function isDraft()
226
    {
227 5
        return !($this->published instanceof \DateTimeImmutable);
228
    }
229
230
    /**
231
     * Return the creation date & time of this revision
232
     *
233
     * @return \DateTimeImmutable Creation date & time
234
     */
235 1
    public function getCreated()
236
    {
237 1
        return $this->created;
238
    }
239
240
    /**
241
     * Return the publication date & time of this revision
242
     *
243
     * @return \DateTimeImmutable|null Publication date & time
244
     */
245 1
    public function getPublished()
246
    {
247 1
        return $this->published;
248
    }
249
250
    /**
251
     * Return the latitude
252
     *
253
     * @return float Latitude
254
     */
255 1
    public function getLatitude()
256
    {
257 1
        return $this->location->getLatitude();
258
    }
259
260
    /**
261
     * Set the latitude
262
     *
263
     * @param float $latitude Latitude
264
     * @return SystemProperties Self reference
265
     */
266 1
    public function setLatitude($latitude)
267
    {
268 1
        return $this->mutatePropertiesProperty(
269 1
            self::PROPERTY_LOCATION,
270 1
            $this->location->setLatitude($latitude)
271 1
        );
272
    }
273
274
    /**
275
     * Return the longitude
276
     *
277
     * @return float Longitude
278
     */
279 1
    public function getLongitude()
280
    {
281 1
        return $this->location->getLongitude();
282
    }
283
284
    /**
285
     * Set the longitude
286
     *
287
     * @param float $longitude Longitude
288
     * @return SystemProperties Self reference
289
     */
290 1
    public function setLongitude($longitude)
291
    {
292 1
        return $this->mutatePropertiesProperty(
293 1
            self::PROPERTY_LOCATION,
294 1
            $this->location->setLongitude($longitude)
295 1
        );
296
    }
297
298
    /**
299
     * Return the elevation
300
     *
301
     * @return float Elevation
302
     */
303 1
    public function getElevation()
304
    {
305 1
        return $this->location->getElevation();
306
    }
307
308
    /**
309
     * Set the elevation
310
     *
311
     * @param float $elevation
312
     * @return SystemProperties Self reference
313
     */
314 1
    public function setElevation($elevation)
315
    {
316 1
        return $this->mutatePropertiesProperty(
317 1
            self::PROPERTY_LOCATION,
318 1
            $this->location->setElevation($elevation)
319 1
        );
320
    }
321
322
    /**
323
     * Derive draft system properties
324
     *
325
     * @param Revision $draftRevision Draft revision
326
     * @return SystemProperties Draft system properties
327
     */
328 4
    public function createDraft(Revision $draftRevision)
329
    {
330 4
        return new static(
331
            [
332 4
                self::PROPERTY_ID => $this->uid->getId(),
333 4
                self::PROPERTY_TYPE => $this->type->getType(),
334 4
                self::PROPERTY_REVISION => $draftRevision->getRevision(),
335 4
                self::PROPERTY_CREATED => time(),
336 4
            ],
337 4
            $this->object
338 4
        );
339
    }
340
341
    /**
342
     * Indicate that the object got published
343
     *
344
     * @return SystemProperties System properties
345
     * @throws RuntimeException If the object is already published
346
     */
347 2
    public function publish()
348
    {
349
        // If the object is already published
350 2
        if ($this->published instanceof \DateTimeImmutable) {
351 1
            throw new RuntimeException(
352 1
                'Cannot republish object previously published at '.$this->published->format('c'),
353
                RuntimeException::CANNOT_REPUBLISH_OBJECT
354 1
            );
355
        }
356
357 2
        $systemProperties = clone $this;
358 2
        $systemProperties->published = new \DateTimeImmutable();
359 2
        return $systemProperties;
360
    }
361
362
    /**
363
     * Return the property values as array
364
     *
365
     * @return array Property values
366
     */
367 5
    public function toArray()
368
    {
369 5
        return array_filter([
370 5
            self::PROPERTY_ID => $this->uid->getId(),
371 5
            self::PROPERTY_TYPE => $this->type->getType(),
372 5
            self::PROPERTY_REVISION => $this->revision->getRevision(),
373 5
            self::PROPERTY_CREATED => $this->created->format('c'),
374 5
            self::PROPERTY_PUBLISHED => ($this->published instanceof \DateTimeImmutable) ?
375 5
                $this->published->format('c') : null,
376 5
            self::PROPERTY_LOCATION => $this->location->toArray(),
377 5
        ]);
378
    }
379
}
380