Timestamp   F
last analyzed

Complexity

Total Complexity 101

Size/Duplication

Total Lines 601
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 101
lcom 1
cbo 3
dl 0
loc 601
rs 1.999
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 31 4
A setValue() 0 4 1
F setTimestampValue() 0 39 21
A getValue() 0 4 1
A getUnixValue() 0 4 1
A getDate() 0 4 1
A getEuroValue() 0 4 1
B setDate() 0 27 9
A getTime() 0 4 1
A getYear() 0 4 1
A getMonth() 0 4 1
A getDay() 0 4 1
A getWeekday() 0 4 1
A getHour() 0 4 1
A getMinute() 0 4 1
A getSecond() 0 4 1
C setTime() 0 22 14
F populateFromString() 0 102 31
A getRule() 0 4 1
A setRule() 0 4 1
A getHelper() 0 4 1
A setHelper() 0 4 1
A getTimeAway() 0 28 5

How to fix   Complexity   

Complex Class

Complex classes like Timestamp 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 Timestamp, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Alpha\Model\Type;
4
5
use Alpha\Util\Helper\Validator;
6
use Alpha\Exception\IllegalArguementException;
7
use Alpha\Util\Config\ConfigProvider;
8
9
/**
10
 * The Timestamp complex data type.
11
 *
12
 * @since 1.0
13
 *
14
 * @author John Collins <[email protected]>
15
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
16
 * @copyright Copyright (c) 2019, John Collins (founder of Alpha Framework).
17
 * All rights reserved.
18
 *
19
 * <pre>
20
 * Redistribution and use in source and binary forms, with or
21
 * without modification, are permitted provided that the
22
 * following conditions are met:
23
 *
24
 * * Redistributions of source code must retain the above
25
 *   copyright notice, this list of conditions and the
26
 *   following disclaimer.
27
 * * Redistributions in binary form must reproduce the above
28
 *   copyright notice, this list of conditions and the
29
 *   following disclaimer in the documentation and/or other
30
 *   materials provided with the distribution.
31
 * * Neither the name of the Alpha Framework nor the names
32
 *   of its contributors may be used to endorse or promote
33
 *   products derived from this software without specific
34
 *   prior written permission.
35
 *
36
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
37
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
38
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
39
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
41
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
47
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49
 * </pre>
50
 */
51
class Timestamp extends Type implements TypeInterface
52
{
53
    /**
54
     * The year part.
55
     *
56
     * @var string
57
     *
58
     * @since 1.0
59
     */
60
    private $year;
61
62
    /**
63
     * The month part.
64
     *
65
     * @var string
66
     *
67
     * @since 1.0
68
     */
69
    private $month;
70
71
    /**
72
     * The day part.
73
     *
74
     * @var string
75
     *
76
     * @since 1.0
77
     */
78
    private $day;
79
80
    /**
81
     * The hour part.
82
     *
83
     * @var string
84
     *
85
     * @since 1.0
86
     */
87
    private $hour;
88
89
    /**
90
     * The minute part.
91
     *
92
     * @var string
93
     *
94
     * @since 1.0
95
     */
96
    private $minute;
97
98
    /**
99
     * The second part.
100
     *
101
     * @var string
102
     *
103
     * @since 1.0
104
     */
105
    private $second;
106
107
    /**
108
     * The textual version of the day, e.g. Monday.
109
     *
110
     * @var string
111
     *
112
     * @since 1.0
113
     */
114
    private $weekday;
115
116
    /**
117
     * The validation rule (reg-ex) applied to Date values.
118
     *
119
     * @var string
120
     *
121
     * @since 1.0
122
     */
123
    private $validationRule;
124
125
    /**
126
     * The error message returned for invalid values.
127
     *
128
     * @var string
129
     *
130
     * @since 1.0
131
     */
132
    protected $helper = 'Not a valid timestamp value!  A timestamp should be in the format YYYY-MM-DD HH:MM:SS.';
133
134
    /**
135
     * Constructor.
136
     *
137
     * @since 1.0
138
     *
139
     * @throws \Alpha\Exception\IllegalArguementException
140
     */
141
    public function __construct($timestamp = '')
142
    {
143
        $config = ConfigProvider::getInstance();
144
145
        $this->validationRule = Validator::ALLOW_ALL;
146
147
        if (empty($timestamp)) {
148
            if ($config->get('app.default.datetime') == 'now') {
149
                $this->year = date('Y');
150
                $this->month = date('m');
151
                $this->day = date('d');
152
                $this->weekday = date('l');
153
                $this->hour = date('H');
154
                $this->minute = date('i');
155
                $this->second = date('s');
156
            } else {
157
                $this->year = '0000';
158
                $this->month = '00';
159
                $this->day = '00';
160
                $this->hour = '00';
161
                $this->minute = '00';
162
                $this->second = '00';
163
            }
164
        } else {
165
            if (preg_match($this->validationRule, $timestamp)) {
166
                $this->populateFromString($timestamp);
167
            } else {
168
                throw new IllegalArguementException($this->helper);
169
            }
170
        }
171
    }
172
173
    /**
174
     * Accepts a full date/time string in YYYY-mm-dd hh:ii:ss format.
175
     *
176
     * @param string $dateTime
177
     *
178
     * @since 1.0
179
     */
180
    public function setValue($dateTime)
181
    {
182
        $this->populateFromString($dateTime);
183
    }
184
185
    /**
186
     * Setter for the timestamp value.
187
     *
188
     * @param int $year
189
     * @param int $month
190
     * @param int $day
191
     * @param int $hour
192
     * @param int $minute
193
     * @param int $second
194
     *
195
     * @since 1.0
196
     *
197
     * @throws \Alpha\Exception\IllegalArguementException
198
     */
199
    public function setTimestampValue($year, $month, $day, $hour, $minute, $second)
200
    {
201
        $valid = null;
202
203
        if (!preg_match('/^[0-9]{4}$/', $year)) {
204
            $valid = 'The year value '.$year.' provided is invalid!';
205
        }
206
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $month)) {
207
            $valid = 'The month value '.$month.' provided is invalid!';
208
        }
209
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $day)) {
210
            $valid = 'The day value '.$day.' provided is invalid!';
211
        }
212
        if (!isset($valid) && !checkdate($month, $day, $year)) {
213
            $valid = 'The day value '.$year.'-'.$month.'-'.$day.' provided is invalid!';
214
        }
215
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $hour) || !($hour >= 0 && $hour < 24)) {
216
            $valid = 'The hour value '.$hour.' provided is invalid!';
217
        }
218
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $minute) || !($minute >= 0 && $minute < 60)) {
219
            $valid = 'The minute value '.$minute.' provided is invalid!';
220
        }
221
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $second) || !($second >= 0 && $second < 60)) {
222
            $valid = 'The second value '.$second.' provided is invalid!';
223
        }
224
225
        if (isset($valid)) {
226
            throw new IllegalArguementException($valid);
227
        } else {
228
            $this->year = $year;
0 ignored issues
show
Documentation Bug introduced by
The property $year was declared of type string, but $year is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
229
            $this->month = str_pad($month, 2, '0', STR_PAD_LEFT);
230
            $this->day = str_pad($day, 2, '0', STR_PAD_LEFT);
231
            $this->hour = str_pad($hour, 2, '0', STR_PAD_LEFT);
232
            $this->minute = str_pad($minute, 2, '0', STR_PAD_LEFT);
233
            $this->second = str_pad($second, 2, '0', STR_PAD_LEFT);
234
            $unixTime = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
235
            $this->weekday = date('l', $unixTime);
236
        }
237
    }
238
239
    /**
240
     * Getter for the Timestamp value.
241
     *
242
     * @return string
243
     *
244
     * @since 1.0
245
     */
246
    public function getValue()
247
    {
248
        return $this->year.'-'.$this->month.'-'.$this->day.' '.$this->hour.':'.$this->minute.':'.$this->second;
249
    }
250
251
    /**
252
     * Return the value in UNIX timestamp format.
253
     *
254
     * @return int
255
     *
256
     * @since 1.0
257
     */
258
    public function getUnixValue()
259
    {
260
        return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
261
    }
262
263
    /**
264
     * Getter for the date part.
265
     *
266
     * @return string
267
     *
268
     * @since 1.0
269
     */
270
    public function getDate()
271
    {
272
        return $this->year.'-'.$this->month.'-'.$this->day;
273
    }
274
275
    /**
276
     * Get the date value as a string in the format "DD/MM/YYYY".
277
     *
278
     * @return string
279
     *
280
     * @since 1.0
281
     */
282
    public function getEuroValue()
283
    {
284
        return $this->day.'/'.$this->month.'/'.mb_substr($this->year, 2, 2);
285
    }
286
287
    /**
288
     * Setter for the date part.
289
     *
290
     * @param int $year
291
     * @param int $month
292
     * @param int $day
293
     *
294
     * @since 1.0
295
     *
296
     * @throws \Alpha\Exception\IllegalArguementException
297
     */
298
    public function setDate($year, $month, $day)
299
    {
300
        $valid = null;
301
302
        if (!preg_match('/^[0-9]{4}$/', $year)) {
303
            $valid = 'The year value '.$year.' provided is invalid!';
304
        }
305
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $month)) {
306
            $valid = 'The month value '.$month.' provided is invalid!';
307
        }
308
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $day)) {
309
            $valid = 'The day value '.$day.' provided is invalid!';
310
        }
311
        if (!isset($valid) && !checkdate($month, $day, $year)) {
312
            $valid = 'The day value '.$year.'/'.$month.'/'.$day.' provided is invalid!';
313
        }
314
315
        if (isset($valid)) {
316
            throw new IllegalArguementException($valid);
317
        } else {
318
            $this->year = $year;
0 ignored issues
show
Documentation Bug introduced by
The property $year was declared of type string, but $year is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
319
            $this->month = str_pad($month, 2, '0', STR_PAD_LEFT);
320
            $this->day = str_pad($day, 2, '0', STR_PAD_LEFT);
321
            $unixTime = mktime(0, 0, 0, $this->month, $this->day, $this->year);
322
            $this->weekday = date('l', $unixTime);
323
        }
324
    }
325
326
    /**
327
     * Getter for the time part.
328
     *
329
     * @return string
330
     *
331
     * @since 1.0
332
     */
333
    public function getTime()
334
    {
335
        return $this->hour.':'.$this->minute.':'.$this->second;
336
    }
337
338
    /**
339
     * Getter for the year part.
340
     *
341
     * @return string
342
     *
343
     * @since 1.0
344
     */
345
    public function getYear()
346
    {
347
        return $this->year;
348
    }
349
350
    /**
351
     * Getter for the month part.
352
     *
353
     * @return string
354
     *
355
     * @since 1.0
356
     */
357
    public function getMonth()
358
    {
359
        return $this->month;
360
    }
361
362
    /**
363
     * Getter for the day part.
364
     *
365
     * @return string
366
     *
367
     * @since 1.0
368
     */
369
    public function getDay()
370
    {
371
        return $this->day;
372
    }
373
374
    /**
375
     * Get the textual weekday part, e.g. Monday.
376
     *
377
     * @return string
378
     *
379
     * @since 1.0
380
     */
381
    public function getWeekday()
382
    {
383
        return $this->weekday;
384
    }
385
386
    /**
387
     * Getter for the hour part.
388
     *
389
     * @return string
390
     *
391
     * @since 1.0
392
     */
393
    public function getHour()
394
    {
395
        return $this->hour;
396
    }
397
398
    /**
399
     * Getter for the minute part.
400
     *
401
     * @return string
402
     *
403
     * @since 1.0
404
     */
405
    public function getMinute()
406
    {
407
        return $this->minute;
408
    }
409
410
    /**
411
     * Getter for the second part.
412
     *
413
     * @return string
414
     *
415
     * @since 1.0
416
     */
417
    public function getSecond()
418
    {
419
        return $this->second;
420
    }
421
422
    /**
423
     * Setter for the time part.
424
     *
425
     * @param int $hour
426
     * @param int $minute
427
     * @param int $second
428
     *
429
     * @since 1.0
430
     *
431
     * @throws \Alpha\Exception\IllegalArguementException
432
     */
433
    public function setTime($hour, $minute, $second)
434
    {
435
        $valid = null;
436
437
        if (!isset($valid) && !preg_match('/^[0-9]{2}$/', $hour) || !($hour >= 0 && $hour < 24)) {
438
            $valid = 'The hour value '.$hour.' provided is invalid!';
439
        }
440
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $minute) || !($minute >= 0 && $minute < 60)) {
441
            $valid = 'The minute value '.$minute.' provided is invalid!';
442
        }
443
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $second) || !($second >= 0 && $second < 60)) {
444
            $valid = 'The second value '.$second.' provided is invalid!';
445
        }
446
447
        if (isset($valid)) {
448
            throw new IllegalArguementException($valid);
449
        } else {
450
            $this->hour = str_pad($hour, 2, '0', STR_PAD_LEFT);
451
            $this->minute = str_pad($minute, 2, '0', STR_PAD_LEFT);
452
            $this->second = str_pad($second, 2, '0', STR_PAD_LEFT);
453
        }
454
    }
455
456
    /**
457
     * Accepts a full date/time string in YYYY-mm-dd hh:ii:ss format.
458
     *
459
     * @param string $dateTime
460
     *
461
     * @since 1.0
462
     *
463
     * @throws \Alpha\Exception\IllegalArguementException
464
     */
465
    public function populateFromString($dateTime)
466
    {
467
        $valid = null;
468
469
        if ($dateTime == 'Please select' || $dateTime == '0000-00-00 00:00:00') {
470
            $this->year = '0000';
471
            $this->month = '00';
472
            $this->day = '00';
473
            $this->hour = '00';
474
            $this->minute = '00';
475
            $this->second = '00';
476
        } else {
477
            $spilt_by_space = explode(' ', $dateTime);
478
479
            if (isset($spilt_by_space[0])) {
480
                $date = $spilt_by_space[0];
481
            } else {
482
                throw new IllegalArguementException($this->helper);
483
            }
484
485
            if (isset($spilt_by_space[1])) {
486
                $time = $spilt_by_space[1];
487
            } else {
488
                throw new IllegalArguementException($this->helper);
489
            }
490
491
            $split_by_dash = explode('-', $date);
492
493
            if (isset($split_by_dash[0])) {
494
                $year = $split_by_dash[0];
495
            } else {
496
                throw new IllegalArguementException($this->helper);
497
            }
498
499
            if (isset($split_by_dash[1])) {
500
                $month = $split_by_dash[1];
501
            } else {
502
                throw new IllegalArguementException($this->helper);
503
            }
504
505
            if (isset($split_by_dash[2])) {
506
                $day = $split_by_dash[2];
507
            } else {
508
                throw new IllegalArguementException($this->helper);
509
            }
510
511
            $split_by_colon = explode(':', $time);
512
513
            if (isset($split_by_colon[0])) {
514
                $hour = $split_by_colon[0];
515
            } else {
516
                throw new IllegalArguementException($this->helper);
517
            }
518
519
            if (isset($split_by_colon[1])) {
520
                $minute = $split_by_colon[1];
521
            } else {
522
                throw new IllegalArguementException($this->helper);
523
            }
524
525
            if (isset($split_by_colon[2])) {
526
                $second = $split_by_colon[2];
527
            } else {
528
                throw new IllegalArguementException($this->helper);
529
            }
530
531
            if (!preg_match('/^[0-9]{4}$/', $year)) {
532
                $valid = 'The year value '.$year.' provided is invalid!';
533
            }
534
            if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $month)) {
535
                $valid = 'The month value '.$month.' provided is invalid!';
536
            }
537
            if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $day)) {
538
                $valid = 'The day value '.$day.' provided is invalid!';
539
            }
540
            if (!isset($valid) && !checkdate($month, $day, $year)) {
541
                $valid = 'The day value '.$year.'/'.$month.'/'.$day.' provided is invalid!';
542
            }
543
            if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $hour) || !($hour >= 0 && $hour < 24)) {
544
                $valid = 'The hour value '.$hour.' provided is invalid!';
545
            }
546
            if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $minute) || !($minute >= 0 && $minute < 60)) {
547
                $valid = 'The minute value '.$minute.' provided is invalid!';
548
            }
549
            if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $second) || !($second >= 0 && $second < 60)) {
550
                $valid = 'The second value '.$second.' provided is invalid!';
551
            }
552
553
            if (isset($valid)) {
554
                throw new IllegalArguementException($valid);
555
            } else {
556
                $this->year = $year;
557
                $this->month = str_pad($month, 2, '0', STR_PAD_LEFT);
558
                $this->day = str_pad($day, 2, '0', STR_PAD_LEFT);
559
                $this->hour = str_pad($hour, 2, '0', STR_PAD_LEFT);
560
                $this->minute = str_pad($minute, 2, '0', STR_PAD_LEFT);
561
                $this->second = str_pad($second, 2, '0', STR_PAD_LEFT);
562
                $unixTime = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
563
                $this->weekday = date('l', $unixTime);
564
            }
565
        }
566
    }
567
568
    /**
569
     * Get the validation rule.
570
     *
571
     * @return string
572
     *
573
     * @since 1.0
574
     */
575
    public function getRule()
576
    {
577
        return $this->validationRule;
578
    }
579
580
    /**
581
     * Set the validation rule.
582
     *
583
     * @param string $rule
584
     *
585
     * @since 1.0
586
     */
587
    public function setRule($rule)
588
    {
589
        $this->validationRule = $rule;
590
    }
591
592
    /**
593
     * Get the validation helper text.
594
     *
595
     * @return string
596
     *
597
     * @since 1.0
598
     */
599
    public function getHelper()
600
    {
601
        return $this->helper;
602
    }
603
604
    /**
605
     * Set the validation helper text.
606
     *
607
     * @param string $helper
608
     *
609
     * @since 1.0
610
     */
611
    public function setHelper($helper)
612
    {
613
        $this->helper = $helper;
614
    }
615
616
    /**
617
     * Returns the difference between now and this timestamp value, in a human-readable format, e.g: 3 days ago, 3 days from now.
618
     *
619
     * @return string
620
     *
621
     * @since 1.2.4
622
     */
623
    public function getTimeAway()
624
    {
625
        $periods = array('second', 'minute', 'hour', 'day', 'week', 'month', 'year', 'decade');
626
        $lengths = array('60', '60', '24', '7', '4.35', '12', '10');
627
628
        $now = time();
629
        $unixTS = $this->getUnixValue();
630
631
        if ($now > $unixTS) {
632
            $difference = $now-$unixTS;
633
            $tense = 'ago';
634
        } else {
635
            $difference = $unixTS-$now;
636
            $tense = 'from now';
637
        }
638
639
        for ($i = 0; $difference >= $lengths[$i] && $i < count($lengths)-1; ++$i) {
640
            $difference = round($difference/$lengths[$i]);
641
        }
642
643
        $difference = round($difference);
644
645
        if ($difference != 1) {
646
            $periods[$i] .= 's';
647
        }
648
649
        return $difference.' '.$periods[$i].' '.$tense;
650
    }
651
}
652