Completed
Push — master ( 4d04c4...151e42 )
by Joschi
03:25
created

Selector::validateRevisionComponent()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 16
ccs 11
cts 11
cp 1
crap 3
rs 9.4285
1
<?php
2
3
/**
4
 * apparat-object
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Object
8
 * @subpackage  Apparat\Object\Domain
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\Repository;
38
39
use Apparat\Object\Domain\Contract\TypeServiceInterface;
40
use Apparat\Object\Domain\Model\Object\Revision;
41
42
/**
43
 * Repository selector
44
 *
45
 * @package Apparat\Object
46
 * @subpackage Apparat\Object\Domain
47
 */
48
class Selector implements SelectorInterface
49
{
50
    /**
51
     * Year component
52
     *
53
     * @var int
54
     */
55
    protected $year = null;
56
    /**
57
     * Month component
58
     *
59
     * @var int
60
     */
61
    protected $month = null;
62
    /**
63
     * Day component
64
     *
65
     * @var int
66
     */
67
    protected $day = null;
68
    /**
69
     * Hour component
70
     *
71
     * @var int
72
     */
73
    protected $hour = null;
74
    /**
75
     * Minute component
76
     *
77
     * @var int
78
     */
79
    protected $minute = null;
80
    /**
81
     * Second component
82
     *
83
     * @var int
84
     */
85
    protected $second = null;
86
    /**
87
     * Object ID
88
     *
89
     * @var int|string
90
     */
91
    protected $uid = null;
92
    /**
93
     * Object type
94
     *
95
     * @var string
96
     */
97
    protected $type = null;
98
    /**
99
     * Revision component
100
     *
101
     * @var int
102
     */
103
    protected $revision = null;
104
    /**
105
     * Object visibility
106
     *
107
     * @var int
108
     */
109
    protected $visibility = SelectorInterface::VISIBLE;
110
    /**
111
     * Object draft
112
     *
113
     * @var int
114
     */
115
    protected $draft = SelectorInterface::PUBLISHED;
116
117
    /**
118
     * Repository selector constructor
119
     *
120
     * @param TypeServiceInterface $typeService Type Service
121
     * @param string|int|NULL $year Year
122
     * @param string|int|NULL $month Month
123
     * @param string|int|NULL $day Day
124
     * @param string|int|NULL $hour Hour
125
     * @param string|int|NULL $minute Minute
126
     * @param string|int|NULL $second Second
127
     * @param string|int|NULL $uid Object ID
128
     * @param string|NULL $type Object type
129
     * @param int|NULL $revision Revision
130
     * @param int $visibility Visibility
131
     * @param int $draft Draft state
132
     */
133 47
    public function __construct(
134
        TypeServiceInterface $typeService,
135
        $year = self::WILDCARD,
136
        $month = self::WILDCARD,
137
        $day = self::WILDCARD,
138
        $hour = self::WILDCARD,
139
        $minute = self::WILDCARD,
140
        $second = self::WILDCARD,
141
        $uid = self::WILDCARD,
142
        $type = self::WILDCARD,
143
        $revision = Revision::CURRENT,
144
        $visibility = SelectorInterface::VISIBLE,
145
        $draft = SelectorInterface::PUBLISHED
146
    ) {
147
        // Validate the date component
148 47
        $this->validateDateComponent($year, $month, $day, $hour, $minute, $second);
149
150
        // Validate the ID component
151 46
        $this->validateIdComponent($uid);
152
153
        // Validate the type component
154 45
        $this->validateTypeComponent($typeService, $type);
155
156
        // Validate the revision component
157 44
        $this->validateRevisionComponent($revision);
158
159
        // Validate the visibility component
160 43
        $this->validateVisibilityComponent($visibility);
161
162
        // Validate the draft component
163 42
        $this->validateDraftComponent($draft);
164 41
    }
165
166
    /**
167
     * Validate the date component
168
     *
169
     * @param string|int|NULL $year Year
170
     * @param string|int|NULL $month Month
171
     * @param string|int|NULL $day Day
172
     * @param string|int|NULL $hour Hour
173
     * @param string|int|NULL $minute Minute
174
     * @param string|int|NULL $second Second
175
     * @throws InvalidArgumentException If any of the date components isn't valid
176
     */
177 47
    protected function validateDateComponent(
178
        $year = self::WILDCARD,
179
        $month = self::WILDCARD,
180
        $day = self::WILDCARD,
181
        $hour = self::WILDCARD,
182
        $minute = self::WILDCARD,
183
        $second = self::WILDCARD
184
    ) {
185 47
        $datePrecision = intval(getenv('OBJECT_DATE_PRECISION'));
186
187
        // Validate the creation date and ID components
188
        $dateComponents = [
189 47
            'year' => $year,
190 47
            'month' => $month,
191 47
            'day' => $day,
192 47
            'hour' => $hour,
193 47
            'minute' => $minute,
194
            'second' => $second
195 47
        ];
196 47
        foreach (array_slice($dateComponents, 0, $datePrecision) as $label => $component) {
197
            // If the component isn't valid
198 47
            if (!is_int($component) && ($component !== self::WILDCARD)) {
199 1
                throw new InvalidArgumentException(
200 1
                    sprintf(
201 1
                        'Invalid repository selector '.$label.' component "%s"',
202
                        $component
203 1
                    ),
204 1
                    InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
205 1
                    null,
206
                    $label
207 1
                );
208
            }
209
210
            // Set the component value
211 46
            $this->$label =
212 46
                ($component === self::WILDCARD) ? self::WILDCARD : str_pad($component, 2, '0', STR_PAD_LEFT);
213 46
        }
214 46
    }
215
216
    /**
217
     * Validate the ID component
218
     *
219
     * @param string|int|NULL $uid Object ID
220
     * @throws InvalidArgumentException If the ID component isn't valid
221
     */
222 46
    protected function validateIdComponent($uid)
223
    {
224
        // If the ID component isn't valid
225 46
        if (!is_int($uid) && ($uid !== self::WILDCARD)) {
226 1
            throw new InvalidArgumentException(
227 1
                sprintf(
228 1
                    'Invalid repository selector ID component "%s"',
229
                    $uid
230 1
                ),
231 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
232 1
                null,
233
                'id'
234 1
            );
235
        }
236 45
        $this->uid = $uid;
237 45
    }
238
239
    /**
240
     * Validate the type component
241
     *
242
     * @param TypeServiceInterface $typeService Type Service
243
     * @param string|NULL $type Object type
244
     * @throws InvalidArgumentException If the type component isn't valid
245
     */
246 45
    protected function validateTypeComponent(TypeServiceInterface $typeService, $type)
247
    {
248
        // If the type component isn't valid
249 45
        if (!$typeService->supportsType($type) && ($type !== self::WILDCARD)) {
250 1
            throw new InvalidArgumentException(
251 1
                sprintf(
252 1
                    'Invalid repository selector type component "%s"',
253
                    $type
254 1
                ),
255 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
256 1
                null,
257
                'type'
258 1
            );
259
        }
260 44
        $this->type = $type;
261 44
    }
262
263
    /**
264
     * Validate the revision component
265
     *
266
     * @param int|NULL $revision Revision
267
     * @throws InvalidArgumentException If the revision component isn't valid
268
     */
269 44
    protected function validateRevisionComponent($revision)
270
    {
271
        // If the revision component isn't valid
272 44
        if (!Revision::isValidRevision($revision) && ($revision !== self::WILDCARD)) {
273 1
            throw new InvalidArgumentException(
274 1
                sprintf(
275 1
                    'Invalid repository selector revision component "%s"',
276
                    $revision
277 1
                ),
278 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
279 1
                null,
280
                'revision'
281 1
            );
282
        }
283 43
        $this->revision = $revision;
284 43
    }
285
286
    /**
287
     * Validate the visibility component
288
     *
289
     * @param int $visibility Visibility
290
     * @throws InvalidArgumentException If the visibility component isn't valid
291
     */
292 43
    protected function validateVisibilityComponent($visibility)
293
    {
294
        // If the object visibility isn't valid
295 43
        if (!self::isValidVisibility($visibility)) {
296 1
            throw new InvalidArgumentException(
297 1
                sprintf(
298 1
                    'Invalid repository selector visibility "%s"',
299
                    $visibility
300 1
                ),
301 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
302 1
                null,
303
                'visibility'
304 1
            );
305
        }
306 42
        $this->visibility = $visibility;
307 42
    }
308
309
    /**
310
     * Test if the given argument is a valid object visibility
311
     *
312
     * @param int $visibility Object visibility
313
     * @return boolean Valid visibility
314
     */
315 79
    public static function isValidVisibility($visibility)
316
    {
317 79
        return ($visibility === SelectorInterface::VISIBLE)
318 46
        || ($visibility === SelectorInterface::HIDDEN)
319 79
        || ($visibility === SelectorInterface::ALL);
320
    }
321
322
    /**
323
     * Validate the draft component
324
     *
325
     * @param int $draft Draft state
326
     * @throws InvalidArgumentException If the draft component isn't valid
327
     */
328 42
    protected function validateDraftComponent($draft)
329
    {
330
        // If the object draft state isn't valid
331 42
        if (!self::isValidDraftState($draft)) {
332 1
            throw new InvalidArgumentException(
333 1
                sprintf(
334 1
                    'Invalid repository selector draft state "%s"',
335
                    $draft
336 1
                ),
337 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
338 1
                null,
339
                'draft'
340 1
            );
341
        }
342 41
        $this->draft = $draft;
343 41
    }
344
345
    /**
346
     * Test if the given argument is a valid object draft state
347
     *
348
     * @param int $draft Object draft state
349
     * @return boolean Valid draft state
350
     */
351 42
    public static function isValidDraftState($draft)
352
    {
353 42
        return ($draft === SelectorInterface::PUBLISHED)
354 9
        || ($draft === SelectorInterface::DRAFT)
355 42
        || ($draft === SelectorInterface::ALL);
356
    }
357
358
    /**
359
     * Return the year component
360
     *
361
     * @return int Year component
362
     */
363 41
    public function getYear()
364
    {
365 41
        return $this->year;
366
    }
367
368
    /**
369
     * Return the month component
370
     *
371
     * @return int Month component
372
     */
373 41
    public function getMonth()
374
    {
375 41
        return $this->month;
376
    }
377
378
    /**
379
     * Return the day component
380
     *
381
     * @return int Day component
382
     */
383 41
    public function getDay()
384
    {
385 41
        return $this->day;
386
    }
387
388
    /**
389
     * Return the hour component
390
     *
391
     * @return int Hour component
392
     */
393 8
    public function getHour()
394
    {
395 8
        return $this->hour;
396
    }
397
398
    /**
399
     * Return the minute component
400
     *
401
     * @return int
402
     */
403 8
    public function getMinute()
404
    {
405 8
        return $this->minute;
406
    }
407
408
    /**
409
     * Return the second component
410
     *
411
     * @return int
412
     */
413 8
    public function getSecond()
414
    {
415 8
        return $this->second;
416
    }
417
418
    /**
419
     * Return the ID component
420
     *
421
     * @return int ID component
422
     */
423 41
    public function getId()
424
    {
425 41
        return $this->uid;
426
    }
427
428
    /**
429
     * Return the Type component
430
     *
431
     * @return string
432
     */
433 41
    public function getType()
434
    {
435 41
        return $this->type;
436
    }
437
438
    /**
439
     * Return the revision component
440
     *
441
     * @return int Revision component
442
     */
443 41
    public function getRevision()
444
    {
445 41
        return $this->revision;
446
    }
447
448
    /**
449
     * Return the object visibility
450
     *
451
     * @return int Object visibility
452
     */
453 41
    public function getVisibility()
454
    {
455 41
        return $this->visibility;
456
    }
457
458
    /**
459
     * Return the object draft state
460
     *
461
     * @return int Object draft state
462
     */
463 33
    public function getDraft()
464
    {
465 33
        return $this->draft;
466
    }
467
}
468