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

Selector::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 11
Bugs 0 Features 2
Metric Value
cc 1
eloc 19
c 11
b 0
f 2
nc 1
nop 12
dl 0
loc 32
ccs 8
cts 8
cp 1
crap 1
rs 8.8571

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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