Completed
Push — master ( 44b684...9b2655 )
by Michael
02:44
created

TaskBag   B

Complexity

Total Complexity 53

Size/Duplication

Total Lines 476
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 95.74%

Importance

Changes 3
Bugs 2 Features 0
Metric Value
wmc 53
c 3
b 2
f 0
lcom 1
cbo 3
dl 0
loc 476
ccs 135
cts 141
cp 0.9574
rs 7.4757

42 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 4
A getTask() 0 4 1
A setTask() 0 5 1
A getInterval() 0 4 1
A setInterval() 0 5 1
A setTime() 0 8 1
A addTime() 0 8 1
A setDate() 0 8 1
A addDate() 0 4 1
A setMonth() 0 5 1
A getMonth() 0 4 1
A addMonth() 0 5 1
A setDay() 0 5 1
A getDay() 0 4 1
A addDay() 0 5 1
A setMinute() 0 5 1
A getMinute() 0 4 1
A addMinute() 0 5 1
A setHour() 0 5 1
A getHour() 0 4 1
A addHour() 0 5 1
A setWeekday() 0 5 1
A getWeekday() 0 4 1
A addWeekday() 0 5 1
A setEnvironments() 0 9 2
A addEnvironment() 0 5 1
A getEnvironments() 0 4 1
A addFollowedBy() 0 5 1
A getFollowedBy() 0 4 1
A setFollowedBy() 0 5 1
A setCronExpression() 0 8 2
A getCronExpression() 0 4 2
A buildExpression() 0 6 1
A setExpressionBuilder() 0 4 1
A getExpressionBuilder() 0 4 2
A isDue() 0 4 1
A getNextRunDate() 0 4 1
A getPreviousRunDate() 0 4 1
A parseTime() 0 5 1
A parseDate() 0 10 2
A appendValue() 0 12 3
A forceToArray() 0 8 2

How to fix   Complexity   

Complex Class

Complex classes like TaskBag often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use TaskBag, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Mistletoe;
3
use Cron\CronExpression;
4
use Mistletoe\Contracts\ExpressionBuilderInterface;
5
use Mistletoe\Contracts\TaskBagInterface;
6
7
/**
8
 * Class TaskBag
9
 * @package FBS\Planner
10
 */
11
class TaskBag implements TaskBagInterface
12
{
13
    /** @var string Task */
14
    protected $task;
15
16
    /** @var array */
17
    protected $environments = [TaskPlanner::PRODUCTION_ENVIRONMENT, TaskPlanner::DEVELOPMENT_ENVIRONMENT];
18
19
    /** @var array|string Tasks that must follow this one */
20
    protected $followedBy = [];
21
22
    /** @var  CronExpression */
23
    protected $cronExpression;
24
25
    /* Expressions */
26
    /** @var bool|string */
27
    protected $interval = false; // @daily, @yearly
28
29
    /** @var null|string|int|array */
30
    protected $minute = null;
31
32
    /** @var null|string|int|array */
33
    protected $hour = null;
34
35
    /** @var null|string|int|array */
36
    protected $month = null; // 12
37
38
    /** @var null|string|int|array */
39
    protected $day = null; // 25
40
41
    /** @var null|string|int|array */
42
    protected $weekday = null;
43
44
    /* Dependencies */
45
    /** @var ExpressionBuilderInterface */
46
    protected $expressionBuilder;
47
48
49
    /**
50
     * TaskBag constructor.
51
     * @param string $task
52
     */
53 40
    public function __construct($task = null)
54
    {
55 40
        if (is_string($task)) {
56 37
            $this->task = $task;
57
58 40
        } elseif (is_array($task)) {
59
60
            // You may also pass in an array of values at construction
61
            // They MUST match the property names exactly
62 3
            foreach ($task as $key => $value) {
63 3
                $this->{'set'.ucfirst($key)}($value);
64 3
            }
65 3
        }
66 40
    }
67
68
    /**
69
     * @return string
70
     */
71 4
    public function getTask()
72
    {
73 4
        return $this->task;
74
    }
75
76
    /**
77
     * @param string $task
78
     * @return $this
79
     */
80 29
    public function setTask($task)
81
    {
82 29
        $this->task = $task;
83 29
        return $this;
84
    }
85
86
    /**
87
     * @return bool|string
88
     */
89 14
    public function getInterval()
90
    {
91 14
        return $this->interval;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->interval; of type boolean|string adds the type boolean to the return on line 91 which is incompatible with the return type declared by the interface Mistletoe\Contracts\TaskBagInterface::getInterval of type null|string.
Loading history...
92
    }
93
94
    /**
95
     * @param string $interval
96
     * @return $this
97
     */
98 15
    public function setInterval($interval)
99
    {
100 15
        $this->interval = $interval;
101 15
        return $this;
102
    }
103
104
    /**
105
     * Parses a time from format 12:14
106
     * @param $time
107
     * @return $this
108
     */
109 5
    public function setTime($time)
110
    {
111 5
        $parts = $this->parseTime($time);
112 5
        $this->setHour($parts[0]);
113 5
        $this->setMinute($parts[1]);
114
115 5
        return $this;
116
    }
117
118
    /**
119
     * @param string $time
120
     * @return $this
121
     */
122 12
    public function addTime($time)
123
    {
124 12
        $parts = $this->parseTime($time);
125 12
        $this->addHour($parts[0]);
126 12
        $this->addMinute($parts[1]);
127
128 12
        return $this;
129
    }
130
131
    /**
132
     * Parses a time from formats 11/15 or 11-15
133
     * @param string $date
134
     * @return $this
135
     */
136 6
    public function setDate($date)
137
    {
138 6
        $parts = $this->parseDate($date);
139 6
        $this->setMonth(intval($parts[0]));
140 6
        $this->setDay(intval($parts[1]));
141
142 6
        return $this;
143
    }
144
145
    /**
146
     * @param string $date
147
     * @return $this
148
     */
149 4
    public function addDate($date)
150
    {
151 4
        return $this->setDate($date);
152
    }
153
154
    /**
155
     * @param integer $month
156
     * @return $this
157
     */
158 8
    public function setMonth($month)
159
    {
160 8
        $this->month = $month;
161 8
        return $this;
162
    }
163
164
    /**
165
     * @return int|null|string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string|integer|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
166
     */
167 14
    public function getMonth()
168
    {
169 14
        return $this->month;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->month; of type null|string|integer|array adds the type array to the return on line 169 which is incompatible with the return type declared by the interface Mistletoe\Contracts\TaskBagInterface::getMonth of type integer|null|string.
Loading history...
170
    }
171
172
    /**
173
     * @param string|int|array $month
174
     * @return $this
175
     */
176 5
    public function addMonth($month)
177
    {
178 5
        $this->appendValue('month', $month);
179 5
        return $this;
180
    }
181
182
    /**
183
     * @param integer $day
184
     * @return $this
185
     */
186 10
    public function setDay($day)
187
    {
188 10
        $this->day = $day;
189 10
        return $this;
190
    }
191
192
    /**
193
     * @return int|null|string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string|integer|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
194
     */
195 14
    public function getDay()
196
    {
197 14
        return $this->day;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->day; of type null|string|integer|array adds the type array to the return on line 197 which is incompatible with the return type declared by the interface Mistletoe\Contracts\TaskBagInterface::getDay of type integer|null|string.
Loading history...
198
    }
199
200
    /**
201
     * @param string|int|array $day
202
     * @return $this
203
     */
204 7
    public function addDay($day)
205
    {
206 7
        $this->appendValue('day', $day);
207 7
        return $this;
208
    }
209
210
    /**
211
     * @param string|int|array $minute
212
     * @return $this
213
     * @throws \Exception
214
     */
215 8
    public function setMinute($minute)
216
    {
217 8
        $this->minute = $minute;
218 8
        return $this;
219
    }
220
221
    /**
222
     * @return int|null|string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string|integer|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
223
     */
224 14
    public function getMinute()
225
    {
226 14
        return $this->minute;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->minute; of type null|string|integer|array adds the type array to the return on line 226 which is incompatible with the return type declared by the interface Mistletoe\Contracts\TaskBagInterface::getMinute of type integer|null|string.
Loading history...
227
    }
228
229
    /**
230
     * @param string|int|array $minute
231
     * @return $this
232
     */
233 13
    public function addMinute($minute)
234
    {
235 13
        $this->appendValue('minute', $minute);
236 13
        return $this;
237
    }
238
239
    /**
240
     * @param string|int|array $hour
241
     * @return $this
242
     */
243 8
    public function setHour($hour)
244
    {
245 8
        $this->hour = $hour;
246 8
        return $this;
247
    }
248
249
    /**
250
     * @return int|null|string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string|integer|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
251
     */
252 14
    public function getHour()
253
    {
254 14
        return $this->hour;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->hour; of type null|string|integer|array adds the type array to the return on line 254 which is incompatible with the return type declared by the interface Mistletoe\Contracts\TaskBagInterface::getHour of type integer|null|string.
Loading history...
255
    }
256
257
    /**
258
     * @param string|int|array $hour
259
     * @return $this
260
     */
261 13
    public function addHour($hour)
262
    {
263 13
        $this->appendValue('hour', $hour);
264 13
        return $this;
265
    }
266
267
    /**
268
     * @param string|int|array $weekday
269
     * @return $this
270
     */
271 2
    public function setWeekday($weekday)
272
    {
273 2
        $this->weekday = $weekday;
274 2
        return $this;
275
    }
276
277
    /**
278
     * @return int|null|string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string|integer|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
279
     */
280 12
    public function getWeekday()
281
    {
282 12
        return $this->weekday;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->weekday; of type null|string|integer|array adds the type array to the return on line 282 which is incompatible with the return type declared by the interface Mistletoe\Contracts\TaskBagInterface::getWeekday of type integer|null|string.
Loading history...
283
    }
284
285
    /**
286
     * @param string|int|array $weekday
287
     * @return $this
288
     */
289 3
    public function addWeekday($weekday)
290
    {
291 3
        $this->appendValue('weekday', $weekday);
292 3
        return $this;
293
    }
294
295 5
    public function setEnvironments($environments)
296
    {
297 5
        if (!is_array($environments)) {
298 2
            $environments = [$environments];
299 2
        }
300
301 5
        $this->environments = $environments;
302 5
        return $this;
303
    }
304
305
    /**
306
     * @param string $environment
307
     * @return $this
308
     */
309 2
    public function addEnvironment($environment)
310
    {
311 2
        $this->environments[] = $environment;
312 2
        return $this;
313
    }
314
315
    /**
316
     * @return array
317
     */
318 4
    public function getEnvironments()
319
    {
320 4
        return $this->environments;
321
    }
322
323
    /**
324
     * @param string $task
325
     * @return $this
326
     */
327 7
    public function addFollowedBy($task)
328
    {
329 7
        $this->followedBy[] = $task;
330 7
        return $this;
331
    }
332
333
    /**
334
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
335
     */
336 3
    public function getFollowedBy()
337
    {
338 3
        return $this->followedBy;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->followedBy; of type array|string adds the type string to the return on line 338 which is incompatible with the return type declared by the interface Mistletoe\Contracts\Task...nterface::getFollowedBy of type array.
Loading history...
339
    }
340
341
    /**
342
     * @param string $followedBy
343
     * @return $this
344
     */
345 3
    public function setFollowedBy($followedBy)
346
    {
347 3
        $this->followedBy = $followedBy;
348 3
        return $this;
349
    }
350
351
    /**
352
     * @param string|CronExpression $cronExpression
353
     * @return $this
354
     */
355 16
    public function setCronExpression($cronExpression)
356
    {
357 16
        $this->cronExpression = ($cronExpression instanceof CronExpression)
358 16
            ? $cronExpression
359 16
            : CronExpression::factory($cronExpression);
360
361 16
        return $this;
362
    }
363
364
    /**
365
     * @return CronExpression
366
     */
367 12
    public function getCronExpression()
368
    {
369 12
        return ($this->cronExpression instanceof CronExpression) ? $this->cronExpression : $this->buildExpression();
370
    }
371
372
    /**
373
     * @return CronExpression
374
     */
375 8
    protected function buildExpression()
376
    {
377 8
        $expression = $this->getExpressionBuilder()->setTaskBag($this)->build();
378 8
        $this->setCronExpression($expression);
379 8
        return $expression;
380
    }
381
382
    /**
383
     * @param ExpressionBuilderInterface $expressionBuilder
384
     */
385 1
    public function setExpressionBuilder(ExpressionBuilderInterface $expressionBuilder)
386
    {
387 1
        $this->expressionBuilder = $expressionBuilder;
388 1
    }
389
390
    /**
391
     * @return ExpressionBuilder|ExpressionBuilderInterface
392
     */
393 8
    protected function getExpressionBuilder()
394
    {
395 8
        return ($this->expressionBuilder instanceof ExpressionBuilderInterface) ? $this->expressionBuilder : new ExpressionBuilder();
396
    }
397
398
399
    /* Just passed through to CronExpression */
400
    /**
401
     * @param string $currentTime
402
     * @return bool
403
     */
404 2
    public function isDue($currentTime = 'now')
405
    {
406 2
        return $this->getCronExpression()->isDue($currentTime);
407
    }
408
409
    /**
410
     * @param string $currentTime
411
     * @param int $nth
412
     * @param bool $allowCurrentDate
413
     */
414
    public function getNextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false)
415
    {
416
        $this->getCronExpression()->getNextRunDate($currentTime, $nth, $allowCurrentDate);
417
    }
418
419
    /**
420
     * @param string $currentTime
421
     * @param int $nth
422
     * @param bool $allowCurrentDate
423
     */
424
    public function getPreviousRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false)
425
    {
426
        $this->getCronExpression()->getPreviousRunDate($currentTime, $nth, $allowCurrentDate);
427
    }
428
429
    /* Internals */
430
    /**
431
     * @param $time
432
     * @return array
433
     */
434 14
    protected function parseTime($time)
435
    {
436 14
        $parts = explode(':', $time);
437 14
        return $parts;
438
    }
439
440
    /**
441
     * @param string $date
442
     * @return array
443
     */
444 6
    protected function parseDate($date)
445
    {
446 6
        if (strpos($date, '-')) {
447 4
            $parts = explode('-', $date);
448 4
            return $parts;
449
        } else {
450 5
            $parts = explode('/', $date);
451 5
            return $parts;
452
        }
453
    }
454
455
    /**
456
     * @param string $key
457
     * @param $value
458
     * @param string $deliminator
459
     */
460 20
    protected function appendValue($key, $value, $deliminator = ',')
461
    {
462 20
        $value = $this->forceToArray($value);
463
464 20
        foreach ($value as $item) {
465 20
            if (!is_null($this->$key)) {
466 11
                $this->$key = (string)$this->$key . $deliminator . $item;
467 11
            } else {
468 20
                $this->$key = (string)$item;
469
            }
470 20
        }
471 20
    }
472
473
    /**
474
     * @param $value
475
     * @return array
476
     * @internal param $minute
477
     */
478 20
    protected function forceToArray($value)
479
    {
480 20
        if (!is_array($value)) {
481 20
            return [$value];
482
        }
483
484 3
        return $value;
485
    }
486
}
487