Completed
Push — master ( 299541...2cf242 )
by Joschi
03:39
created

Selector::__construct()   D

Complexity

Conditions 13
Paths 19

Size

Total Lines 114
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 59
CRAP Score 13.2018

Importance

Changes 10
Bugs 0 Features 2
Metric Value
cc 13
eloc 77
c 10
b 0
f 2
nc 19
nop 12
dl 0
loc 114
ccs 59
cts 66
cp 0.8939
crap 13.2018
rs 4.9922

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
     * @throws InvalidArgumentException If any of the components isn't valid
133
     */
134 45
    public function __construct(
135
        TypeServiceInterface $typeService,
136
        $year = self::WILDCARD,
137
        $month = self::WILDCARD,
138
        $day = self::WILDCARD,
139
        $hour = self::WILDCARD,
140
        $minute = self::WILDCARD,
141
        $second = self::WILDCARD,
142
        $uid = self::WILDCARD,
143
        $type = self::WILDCARD,
144
        $revision = Revision::CURRENT,
145
        $visibility = SelectorInterface::VISIBLE,
146
        $draft = SelectorInterface::PUBLISHED
147
    ) {
148 45
        $datePrecision = intval(getenv('OBJECT_DATE_PRECISION'));
149
150
        // Validate the creation date and ID components
151
        $dateComponents = [
152 45
            'year' => $year,
153 45
            'month' => $month,
154 45
            'day' => $day,
155 45
            'hour' => $hour,
156 45
            'minute' => $minute,
157
            'second' => $second
158 45
        ];
159 45
        foreach (array_slice($dateComponents, 0, $datePrecision) as $label => $component) {
160
            // If the component isn't valid
161 45
            if (!is_int($component) && ($component !== self::WILDCARD)) {
162 1
                throw new InvalidArgumentException(
163 1
                    sprintf(
164 1
                        'Invalid repository selector '.$label.' component "%s"',
165
                        $component
166 1
                    ),
167 1
                    InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
168 1
                    null,
169
                    $label
170 1
                );
171
            }
172
173
            // Set the component value
174 44
            $this->$label =
175 44
                ($component === self::WILDCARD) ? self::WILDCARD : str_pad($component, 2, '0', STR_PAD_LEFT);
176 44
        }
177
178
        // If the ID component isn't valid
179 44
        if (!is_int($uid) && ($uid !== self::WILDCARD)) {
180 1
            throw new InvalidArgumentException(
181 1
                sprintf(
182 1
                    'Invalid repository selector ID component "%s"',
183
                    $uid
184 1
                ),
185 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
186 1
                null,
187
                'id'
188 1
            );
189
        }
190 43
        $this->uid = $uid;
191
192
        // If the type component isn't valid
193 43
        if (!$typeService->supportsType($type) && ($type !== self::WILDCARD)) {
194 1
            throw new InvalidArgumentException(
195 1
                sprintf(
196 1
                    'Invalid repository selector type component "%s"',
197
                    $type
198 1
                ),
199 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
200 1
                null,
201
                'type'
202 1
            );
203
        }
204 42
        $this->type = $type;
205
206
        // If the revision component isn't valid
207 42
        if (!Revision::isValidRevision($revision) && ($revision !== self::WILDCARD)) {
208 1
            throw new InvalidArgumentException(
209 1
                sprintf(
210 1
                    'Invalid repository selector revision component "%s"',
211
                    $revision
212 1
                ),
213 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
214 1
                null,
215
                'revision'
216 1
            );
217
        }
218 41
        $this->revision = $revision;
219
220
        // If the object visibility isn't valid
221 41
        if (!self::isValidVisibility($visibility)) {
222 1
            throw new InvalidArgumentException(
223 1
                sprintf(
224 1
                    'Invalid repository selector visibility "%s"',
225
                    $visibility
226 1
                ),
227 1
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
228 1
                null,
229
                'visibility'
230 1
            );
231
        }
232 40
        $this->visibility = $visibility;
233
234
        // If the object draft state isn't valid
235 40
        if (!self::isValidDraftState($draft)) {
236
            throw new InvalidArgumentException(
237
                sprintf(
238
                    'Invalid repository selector draft state "%s"',
239
                    $visibility
240
                ),
241
                InvalidArgumentException::INVALID_REPOSITORY_SELECTOR_COMPONENT,
242
                null,
243
                'draft'
244
            );
245
        }
246 40
        $this->draft = $draft;
247 40
    }
248
249
    /**
250
     * Test if the given argument is a valid object visibility
251
     *
252
     * @param int $visibility Object visibility
253
     * @return boolean Valid visibility
254
     */
255 71
    public static function isValidVisibility($visibility)
256
    {
257 71
        return ($visibility === SelectorInterface::VISIBLE)
258 39
        || ($visibility === SelectorInterface::HIDDEN)
259 71
        || ($visibility === SelectorInterface::ALL);
260
    }
261
262
    /**
263
     * Test if the given argument is a valid object draft state
264
     *
265
     * @param int $draft Object draft state
266
     * @return boolean Valid draft state
267
     */
268 40
    public static function isValidDraftState($draft)
269
    {
270 40
        return ($draft === SelectorInterface::PUBLISHED)
271 8
        || ($draft === SelectorInterface::DRAFT)
272 40
        || ($draft === SelectorInterface::ALL);
273
    }
274
275
    /**
276
     * Return the year component
277
     *
278
     * @return int Year component
279
     */
280 40
    public function getYear()
281
    {
282 40
        return $this->year;
283
    }
284
285
    /**
286
     * Return the month component
287
     *
288
     * @return int Month component
289
     */
290 40
    public function getMonth()
291
    {
292 40
        return $this->month;
293
    }
294
295
    /**
296
     * Return the day component
297
     *
298
     * @return int Day component
299
     */
300 40
    public function getDay()
301
    {
302 40
        return $this->day;
303
    }
304
305
    /**
306
     * Return the hour component
307
     *
308
     * @return int Hour component
309
     */
310 7
    public function getHour()
311
    {
312 7
        return $this->hour;
313
    }
314
315
    /**
316
     * Return the minute component
317
     *
318
     * @return int
319
     */
320 7
    public function getMinute()
321
    {
322 7
        return $this->minute;
323
    }
324
325
    /**
326
     * Return the second component
327
     *
328
     * @return int
329
     */
330 7
    public function getSecond()
331
    {
332 7
        return $this->second;
333
    }
334
335
    /**
336
     * Return the ID component
337
     *
338
     * @return int ID component
339
     */
340 40
    public function getId()
341
    {
342 40
        return $this->uid;
343
    }
344
345
    /**
346
     * Return the Type component
347
     *
348
     * @return string
349
     */
350 40
    public function getType()
351
    {
352 40
        return $this->type;
353
    }
354
355
    /**
356
     * Return the revision component
357
     *
358
     * @return int Revision component
359
     */
360 40
    public function getRevision()
361
    {
362 40
        return $this->revision;
363
    }
364
365
    /**
366
     * Return the object visibility
367
     *
368
     * @return int Object visibility
369
     */
370 40
    public function getVisibility()
371
    {
372 40
        return $this->visibility;
373
    }
374
375
    /**
376
     * Return the object draft state
377
     *
378
     * @return int Object draft state
379
     */
380 33
    public function getDraft()
381
    {
382 33
        return $this->draft;
383
    }
384
}
385