Completed
Push — master ( 81c425...a2bf82 )
by Joschi
02:41
created

SystemProperties::publish()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.4285
cc 2
eloc 8
nc 2
nop 0
crap 2
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\Object\Domain\Model\Object\Id;
40
use Apparat\Object\Domain\Model\Object\ObjectInterface;
41
use Apparat\Object\Domain\Model\Object\Revision;
42
use Apparat\Object\Domain\Model\Object\RuntimeException;
43
use Apparat\Object\Domain\Model\Object\Type;
44
45
/**
46
 * Object system properties collection
47
 *
48
 * In general, the system properties are used as read-only collection, with one exception: Draft objects don't have the
49
 * `published` property set, so there's a {@link publish()} method for advancing an object's state.
50
 *
51
 * @package Apparat\Object
52
 * @subpackage Apparat\Object\Application
53
 */
54
class SystemProperties extends AbstractProperties
55
{
56
    /**
57
     * Collection name
58
     *
59
     * @var string
60
     */
61
    const COLLECTION = 'system';
62
    /**
63
     * ID property
64
     *
65
     * @var string
66
     */
67
    const PROPERTY_ID = 'id';
68
    /**
69
     * Type property
70
     *
71
     * @var string
72
     */
73
    const PROPERTY_TYPE = 'type';
74
    /**
75
     * Revision property
76
     *
77
     * @var string
78
     */
79
    const PROPERTY_REVISION = 'revision';
80
    /**
81
     * Created property
82
     *
83
     * @var string
84
     */
85
    const PROPERTY_CREATED = 'created';
86
    /**
87
     * Published property
88
     *
89
     * @var string
90
     */
91
    const PROPERTY_PUBLISHED = 'published';
92
    /**
93
     * Hash property
94
     *
95
     * @var string
96
     */
97
    const PROPERTY_HASH = 'hash';
98
    /**
99
     * Object ID (constant throughout revisions)
100
     *
101
     * @var Id
102
     */
103
    protected $uid = null;
104
    /**
105
     * Object type (constant throughout revisions)
106
     *
107
     * @var Type
108
     */
109
    protected $type = null;
110
    /**
111
     * Object revision
112
     *
113
     * @var Revision
114
     */
115
    protected $revision = null;
116
    /**
117
     * Creation date of this revision
118
     *
119
     * @var \DateTimeImmutable
120
     */
121
    protected $created = null;
122
    /**
123
     * Publication date of this revision
124
     *
125
     * @var \DateTimeImmutable
126
     */
127
    protected $published = null;
128
    /**
129
     * Object hash of this revision
130
     *
131
     * @var string
132
     */
133
    protected $hash = '';
134
135
    /*******************************************************************************
136
     * PUBLIC METHODS
137
     *******************************************************************************/
138
139
    /**
140
     * System properties constructor
141
     *
142
     * @param array $data Property data
143
     * @param ObjectInterface $object Owner object
144
     */
145 19
    public function __construct(array $data, ObjectInterface $object)
146
    {
147 19
        parent::__construct($data, $object);
148
149
        // Initialize the object ID
150 19
        if (array_key_exists(self::PROPERTY_ID, $data)) {
151 17
            $this->uid = Id::unserialize($data[self::PROPERTY_ID]);
152 17
        }
153
154
        // Initialize the object type
155 19
        if (array_key_exists(self::PROPERTY_TYPE, $data)) {
156 18
            $this->type = Type::unserialize($data[self::PROPERTY_TYPE]);
157 17
        }
158
159
        // Initialize the object revision
160 18
        if (array_key_exists(self::PROPERTY_REVISION, $data)) {
161 17
            $this->revision = Revision::unserialize($data[self::PROPERTY_REVISION]);
162 17
        }
163
164
        // Initialize the object creation date
165 18
        if (array_key_exists(self::PROPERTY_CREATED, $data)) {
166 17
            $this->created = new \DateTimeImmutable('@'.$data[self::PROPERTY_CREATED]);
167 17
        }
168
169
        // Initialize the object publication date
170 18
        if (array_key_exists(self::PROPERTY_PUBLISHED, $data)) {
171 11
            $this->published = new \DateTimeImmutable('@'.$data[self::PROPERTY_PUBLISHED]);
172 11
        }
173
174
        // Initialize the object hash
175 18
        if (array_key_exists(self::PROPERTY_HASH, $data)) {
176 16
            $this->hash = $data[self::PROPERTY_HASH];
177 16
        }
178
179
        // Test if all mandatory properties are set
180 18
        if (!($this->uid instanceof Id)
181 18
            || !($this->type instanceof Type)
182 17
            || !($this->revision instanceof Revision)
183 17
            || !($this->created instanceof \DateTimeImmutable)
184
//            || !$this->hasValidHash()
185 18
        ) {
186 1
            throw new InvalidArgumentException(
187 1
                'Invalid system properties',
188
                InvalidArgumentException::INVALID_SYSTEM_PROPERTIES
189 1
            );
190
        }
191 17
    }
192
193
    /**
194
     * Return the object ID
195
     *
196
     * @return Id Object ID
197
     */
198 5
    public function getId()
199
    {
200 5
        return $this->uid;
201
    }
202
203
    /**
204
     * Return the object type
205
     *
206
     * @return Type Object type
207
     */
208 1
    public function getType()
209
    {
210 1
        return $this->type;
211
    }
212
213
    /**
214
     * Return the object revision
215
     *
216
     * @return Revision Object revision
217
     */
218 15
    public function getRevision()
219
    {
220 15
        return $this->revision;
221
    }
222
223
    /**
224
     * Return the creation date & time of this revision
225
     *
226
     * @return \DateTimeImmutable Creation date & time
227
     */
228 1
    public function getCreated()
229
    {
230 1
        return $this->created;
231
    }
232
233
    /**
234
     * Return the publication date & time of this revision
235
     *
236
     * @return \DateTimeImmutable Publication date & time
237
     */
238 1
    public function getPublished()
239
    {
240 1
        return $this->published;
241
    }
242
243
    /**
244
     * Return the object hash of this revision
245
     *
246
     * @return string Object hash
247
     */
248 1
    public function getHash()
249
    {
250 1
        return $this->hash;
251
    }
252
253
    /**
254
     * Indicate that the object got published
255
     *
256
     * @return SystemProperties System properties
257
     * @throws RuntimeException If the object is already published
258
     */
259 1
    public function publish()
260
    {
261
262
        // If the object is already published
263 1
        if ($this->published instanceof \DateTimeImmutable) {
264 1
            throw new RuntimeException(
265 1
                'Cannot republish object previously published at '.$this->published->format('c'),
266
                RuntimeException::CANNOT_REPUBLISH_OBJECT
267 1
            );
268
        }
269
270 1
        $systemProperties = clone $this;
271 1
        $systemProperties->published = new \DateTimeImmutable();
272 1
        return $systemProperties;
273
    }
274
275
    /**
276
     * Return the property values as array
277
     *
278
     * @return array Property values
279
     */
280 2
    public function toArray()
281
    {
282 2
        return array_filter([
283 2
            self::PROPERTY_ID => $this->uid->getId(),
284 2
            self::PROPERTY_TYPE => $this->type->getType(),
285 2
            self::PROPERTY_REVISION => $this->revision->getRevision(),
286 2
            self::PROPERTY_CREATED => $this->created->format('c'),
287 2
            self::PROPERTY_PUBLISHED => ($this->published instanceof \DateTimeImmutable) ?
288 2
                $this->published->format('c') : null,
289 2
            self::PROPERTY_HASH => $this->hash,
290 2
        ]);
291
    }
292
293
    /*******************************************************************************
294
     * PRIVATE METHODS
295
     *******************************************************************************/
296
297
    /**
298
     * Test if the object hash is a valid sha1 value
299
     *
300
     * @return bool The object hash is a valid sha1 value
301
     */
302
    protected function hasValidHash()
303
    {
304
        return preg_match('%[a-fA-F0-9]{40}%', $this->hash);
305
    }
306
}
307