Completed
Push — master ( 5aac82...6c1d93 )
by Joschi
02:38
created

SystemProperties::publish()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.5

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 12
ccs 3
cts 6
cp 0.5
rs 9.4285
cc 2
eloc 6
nc 2
nop 0
crap 2.5
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)
0 ignored issues
show
Coding Style introduced by
Spaces must be used for alignment; tabs are not allowed
Loading history...
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
100
     *
101
     * @var Id
102
     */
103
    protected $id = null;
104
    /**
105
     * Object type
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
118
     *
119
     * @var \DateTimeImmutable
120
     */
121
    protected $created = null;
122
    /**
123
     * Publication date
124
     *
125
     * @var \DateTimeImmutable
126
     */
127
    protected $published = null;
128
    /**
129
     * Object hash
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 5
    public function __construct(array $data, ObjectInterface $object)
146
    {
147 5
        parent::__construct($data, $object);
148
149
        // Initialize the object ID
150 5
        if (array_key_exists(self::PROPERTY_ID, $data)) {
151 3
            $this->id = Id::unserialize($data[self::PROPERTY_ID]);
152 3
        }
153
154
        // Initialize the object type
155 5
        if (array_key_exists(self::PROPERTY_TYPE, $data)) {
156 4
            $this->type = Type::unserialize($data[self::PROPERTY_TYPE]);
157 3
        }
158
159
        // Initialize the object revision
160 4
        if (array_key_exists(self::PROPERTY_REVISION, $data)) {
161 3
            $this->revision = Revision::unserialize($data[self::PROPERTY_REVISION]);
162 3
        }
163
164
        // Initialize the object creation date
165 4
        if (array_key_exists(self::PROPERTY_CREATED, $data)) {
166 3
            $this->created = new \DateTimeImmutable('@' . $data[self::PROPERTY_CREATED]);
167 3
        }
168
169
        // Initialize the object publication date
170 4
        if (array_key_exists(self::PROPERTY_PUBLISHED, $data)) {
171 2
            $this->published = new \DateTimeImmutable('@' . $data[self::PROPERTY_PUBLISHED]);
172 2
        }
173
174
        // Initialize the object hash
175 4
        if (array_key_exists(self::PROPERTY_HASH, $data)) {
176 3
            $this->hash = $data[self::PROPERTY_HASH];
177 3
        }
178
179
        // Test if all mandatory properties are set
180
        if (
181 4
            !($this->id instanceof Id) ||
182 3
            !($this->type instanceof Type) ||
183 3
            !($this->revision instanceof Revision) ||
184 3
            !($this->created instanceof \DateTimeImmutable) ||
0 ignored issues
show
Bug introduced by
The class DateTimeImmutable does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
185 3
            !$this->hasValidHash()
186 4
        ) {
187 1
            throw new InvalidArgumentException('Invalid system properties', InvalidArgumentException::INVALID_SYSTEM_PROPERTIES);
188
        }
189 3
    }
190
191
    /**
192
     * Return the object ID
193
     *
194
     * @return Id Object ID
195
     */
196 1
    public function getId()
197
    {
198 1
        return $this->id;
199
    }
200
201
    /**
202
     * Return the object type
203
     *
204
     * @return Type Object type
205
     */
206 1
    public function getType()
207
    {
208 1
        return $this->type;
209
    }
210
211
    /**
212
     * Return the object revision
213
     *
214
     * @return Revision Object revision
215
     */
216 1
    public function getRevision()
217
    {
218 1
        return $this->revision;
219
    }
220
221
    /**
222
     * Return the creation date & time
223
     *
224
     * @return \DateTimeImmutable Creation date & time
225
     */
226 1
    public function getCreated()
227
    {
228 1
        return $this->created;
229
    }
230
231
    /**
232
     * Return the publication date & time
233
     *
234
     * @return \DateTimeImmutable Publication date & time
235
     */
236 1
    public function getPublished()
237
    {
238 1
        return $this->published;
239
    }
240
241
    /**
242
     * Return the object hash
243
     *
244
     * @return string Object hash
245
     */
246
    public function getHash()
247
    {
248
        return $this->hash;
249
    }
250
251
    /**
252
     * Indicate that the object now got published
253
     *
254
     * @return SystemProperties System properties
255
     * @throws RuntimeException If the object is already published
256
     */
257 1
    public function publish()
258
    {
259
260
        // If the object is already published
261 1
        if ($this->published instanceof \DateTimeImmutable) {
0 ignored issues
show
Bug introduced by
The class DateTimeImmutable does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
262 1
            throw new RuntimeException('Cannot republish object previously published at ' . $this->published->format('c'), RuntimeException::CANNOT_REPUBLISH_OBJECT);
263
        }
264
265
        $systemProperties = clone $this;
266
        $systemProperties->published = new \DateTimeImmutable();
267
        return $systemProperties;
268
    }
269
270
    /**
271
     * Return the property values as array
272
     *
273
     * @return array Property values
274
     */
275 1
    public function toArray()
276
    {
277 1
        return array_filter([
278 1
            self::PROPERTY_ID => $this->id->getId(),
279 1
            self::PROPERTY_TYPE => $this->type->getType(),
280 1
            self::PROPERTY_REVISION => $this->revision->getRevision(),
281 1
            self::PROPERTY_CREATED => $this->created->format('c'),
282 1
            self::PROPERTY_PUBLISHED => $this->published->format('c'),
283 1
            self::PROPERTY_HASH => $this->hash,
284 1
        ]);
285
    }
286
287
    /*******************************************************************************
288
     * PRIVATE METHODS
289
     *******************************************************************************/
290
291
    /**
292
     * Test if the object hash is a valid sha1 value
293
     *
294
     * @return bool The object hash is a valid sha1 value
295
     */
296 3
    protected function hasValidHash()
297
    {
298 3
        return preg_match('%[a-fA-F0-9]{40}%', $this->hash);
299
    }
300
}
301