GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — 3.0 ( 1eb04a...9ca0ec )
by Vermeulen
02:07
created

Dates::getDay()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace BFW\Helpers;
4
5
use \DateTime;
6
use \Exception;
7
8
/**
9
 * Class to have shortcuts to DateTime(Zone) methods and to display a date
10
 * with words and not only numbers (today, yesterday, since... etc).
11
 */
12
class Dates extends DateTime
13
{
14
    /**
15
     * @const ERR_MODIFY_PATTERN_NOT_MATCH Exception code if the pattern used
16
     * into the method modify() not match with the regex.
17
     */
18
    const ERR_MODIFY_PATTERN_NOT_MATCH = 1605001;
19
    
20
    /**
21
     * @const ERR_MODIFY_UNKNOWN_MODIFIER Exception code if the modifier used
22
     * into the method modify() is unknown.
23
     */
24
    const ERR_MODIFY_UNKNOWN_MODIFIER = 1605002;
25
    
26
    /**
27
     * @var string[] $humanReadableI18n Words used in method to transform
28
     *  date difference to human readable.
29
     */
30
    protected static $humanReadableI18n = [
31
        'now'       => 'now',
32
        'since'     => 'since',
33
        'in'        => 'in',
34
        'yesterday' => 'yesterday',
35
        'tomorrow'  => 'tomorrow',
36
        'the'       => 'the',
37
        'at'        => 'at'
38
    ];
39
40
    /**
41
     * @var string[] $humanReadableFormats Date and time formats used in
42
     *  method to transform date difference to human readable.
43
     */
44
    protected static $humanReadableFormats = [
45
        'dateSameYear'      => 'm-d',
46
        'dateDifferentYear' => 'Y-m-d',
47
        'time'              => 'H:i'
48
    ];
49
    
50
    /**
51
     * @var string[] $modifyNewKeywords Add new keywords which can be used
52
     *  with the modify method. The key is the new keyword and the value the
53
     *  corresponding keyword into DateTime::modify method.
54
     */
55
    protected static $modifyNewKeywords = [];
56
57
    /**
58
     * Return the value of the humanReadableI18n property
59
     * 
60
     * @return string[]
61
     */
62
    public static function getHumanReadableI18n(): array
63
    {
64
        return self::$humanReadableI18n;
65
    }
66
67
    /**
68
     * Define a new value for a key of the humanReadableI18n property
69
     * 
70
     * @param string $key The key in humanReadableI18n
71
     * @param string $value The new value for the key
72
     * 
73
     * @return void
74
     */
75
    public static function setHumanReadableI18nKey(string $key, string $value)
76
    {
77
        self::$humanReadableI18n[$key] = $value;
78
    }
79
80
    /**
81
     * Define a new value to the property humanReadableI18n
82
     * 
83
     * @param string[] $value The new value for the property
84
     * 
85
     * @return void
86
     */
87
    public static function setHumanReadableI18n(array $value)
88
    {
89
        self::$humanReadableI18n = $value;
90
    }
91
92
    /**
93
     * Return the value of the humanReadableFormats property
94
     * 
95
     * @return string[]
96
     */
97
    public static function getHumanReadableFormats(): array
98
    {
99
        return self::$humanReadableFormats;
100
    }
101
102
    /**
103
     * Define a new value for a key of the humanReadableFormats property
104
     * 
105
     * @param string $key The key in humanReadableFormats
106
     * @param string $value The new value for the key
107
     * 
108
     * @return void
109
     */
110
    public static function setHumanReadableFormatsKey(
111
        string $key,
112
        string $value
113
    ) {
114
        self::$humanReadableFormats[$key] = $value;
115
    }
116
117
    /**
118
     * Define a new value to the property humanReadableFormats
119
     * 
120
     * @param string[] $value The new value for the property
121
     * 
122
     * @return void
123
     */
124
    public static function setHumanReadableFormats(array $value)
125
    {
126
        self::$humanReadableFormats = $value;
127
    }
128
    
129
    /**
130
     * Return the value of the modifyNewKeywords property
131
     * 
132
     * @return string[]
133
     */
134
    public static function getModifyNewKeywords(): array
135
    {
136
        return self::$modifyNewKeywords;
137
    }
138
    
139
    /**
140
     * Define a new value to the property modifyNewKeywords
141
     * 
142
     * @param string[] $value The new value for the property
143
     * 
144
     * @return void
145
     */
146
    public static function setModifyNewKeywords(array $value)
147
    {
148
        self::$modifyNewKeywords = $value;
149
    }
150
151
    /**
152
     * Return the date. Format is Y-m-d H:i:sO
153
     * 
154
     * @return string
155
     */
156
    public function getDate(): string
157
    {
158
        return parent::format('Y-m-d H:i:sO');
159
    }
160
161
    /**
162
     * Return a numeric representation of a year, 4 digits.
163
     * 
164
     * @return int
165
     */
166
    public function getYear(): int
167
    {
168
        return (int) parent::format('Y');
169
    }
170
171
    /**
172
     * Return the numeric representation of a month, without leading zeros.
173
     * The returned int format can not have leading zeros.
174
     * 
175
     * @return int
176
     */
177
    public function getMonth(): int
178
    {
179
        return (int) parent::format('m');
180
    }
181
182
    /**
183
     * Return the day of the month without leading zeros.
184
     * The returned int format can not have leading zeros.
185
     * 
186
     * @return int
187
     */
188
    public function getDay(): int
189
    {
190
        return (int) parent::format('d');
191
    }
192
193
    /**
194
     * Return 24-hour format without leading zeros.
195
     * The returned int format can not have leading zeros.
196
     * 
197
     * @return int
198
     */
199
    public function getHour(): int
200
    {
201
        return (int) parent::format('H');
202
    }
203
204
    /**
205
     * Return minutes, without leading zeros.
206
     * The returned int format can not have leading zeros.
207
     * 
208
     * @return int
209
     */
210
    public function getMinute(): int
211
    {
212
        return (int) parent::format('i');
213
    }
214
215
    /**
216
     * Return second, without leading zeros.
217
     * The returned int format can not have leading zeros.
218
     * 
219
     * @return int
220
     */
221
    public function getSecond(): int
222
    {
223
        return (int) parent::format('s');
224
    }
225
226
    /**
227
     * Return the difference to Greenwich time (GMT)
228
     * with colon between hours and minutes
229
     * 
230
     * @return string
231
     */
232
    public function getZone(): string
233
    {
234
        return parent::format('P');
235
    }
236
237
    /**
238
     * Override modify DateTime method to allow personal keywords
239
     * 
240
     * @param string $modify A date/time string
241
     * 
242
     * @return \BFW\Dates
0 ignored issues
show
Bug introduced by
The type BFW\Dates was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
243
     */
244
    public function modify($modify)
245
    {
246
        $originalDate = clone $this;
247
        @parent::modify($modify); //Try/catch on Throwable don't work T-T
248
249
        //If the keyword used is ok with DateTime::modify method
250
        if ($originalDate != $this) {
251
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type BFW\Helpers\Dates which is incompatible with the documented return type BFW\Dates.
Loading history...
252
        }
253
254
        $this->modifyWithOthersKeywords($modify);
255
256
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type BFW\Helpers\Dates which is incompatible with the documented return type BFW\Dates.
Loading history...
257
    }
258
259
    /**
260
     * Get DateTime equivalent keyword for a personal keyword declared into
261
     * the property modifyNewKeywords.
262
     * 
263
     * @return array
264
     */
265
    protected function obtainNewKeywordsForModify(): array
266
    {
267
        $search  = [];
268
        $replace = [];
269
        
270
        foreach (self::$modifyNewKeywords as $searchKey => $replaceKey) {
271
            $search[]  = $searchKey;
272
            $replace[] = $replaceKey;
273
        }
274
        
275
        return [
276
            'search'  => $search,
277
            'replace' => $replace
278
        ];
279
    }
280
    
281
    /**
282
     * Use personal keyword on modify method
283
     * 
284
     * @param string $modify A date/time string
285
     * 
286
     * @throws \Exception If bad pattern or unknown keyword
287
     * 
288
     * @return void
289
     */
290
    protected function modifyWithOthersKeywords(string $modify)
291
    {
292
        $keywords = $this->obtainNewKeywordsForModify();
293
        $match    = [];
294
        
295
        //Regex on the $modify parameter to get the used keyword
296
        if (preg_match('#(\+|\-)([0-9]+) ([a-z]+)#i', $modify, $match) !== 1) {
297
            throw new Exception(
298
                'Dates::modify pattern not match.',
299
                $this::ERR_MODIFY_PATTERN_NOT_MATCH
300
            );
301
        }
302
        
303
        $keyword = str_replace(
304
            $keywords['search'],
305
            $keywords['replace'],
306
            strtolower($match[3])
307
        );
308
        
309
        $originalDate = clone $this;
310
        //Try/catch on Throwable don't work T-T
311
        @parent::modify($match[1].$match[2].' '.$keyword);
312
        
313
        //If no change on object, The keyword is unknown
314
        if ($originalDate == $this) {
315
            throw new Exception(
316
                'Dates::modify Parameter '.$match[3].' is unknown.',
317
                $this::ERR_MODIFY_UNKNOWN_MODIFIER
318
            );
319
        }
320
    }
321
    
322
    /**
323
     * Return date's SQL format (postgresql format).
324
     * The return can be an array or a string.
325
     * 
326
     * @param boolean $returnArray (default false) True to return an array.
327
     * @param boolean $withZone (default false) True to include the timezone
328
     *  into the time returned data.
329
     * 
330
     * @return string[]|string
331
     */
332
    public function getSqlFormat(
333
        bool $returnArray = false,
334
        bool $withZone = false
335
    ) {
336
        $date = $this->format('Y-m-d');
337
        $time = $this->format('H:i:s');
338
        
339
        if ($withZone === true) {
340
            $time .= $this->format('O');
341
        }
342
343
        if ($returnArray) {
344
            return [$date, $time];
345
        }
346
347
        return $date.' '.$time;
348
    }
349
350
    /**
351
     * List all timezone existing in current php version
352
     * 
353
     * @return string[]
354
     */
355
    public function lstTimeZone(): array
356
    {
357
        return parent::getTimezone()->listIdentifiers();
358
    }
359
360
    /**
361
     * List all continent define in php DateTimeZone.
362
     * 
363
     * @return string[]
364
     */
365
    public function lstTimeZoneContinent(): array
366
    {
367
        return [
368
            'Africa',
369
            'America',
370
            'Antartica',
371
            'Arctic',
372
            'Asia',
373
            'Atlantic',
374
            'Australia',
375
            'Europe',
376
            'Indian',
377
            'Pacific'
378
        ];
379
    }
380
381
    /**
382
     * List all available country for a continent
383
     * 
384
     * @param string $continent The continent for which we want
385
     *  the countries list
386
     * 
387
     * @return string[]
388
     */
389
    public function lstTimeZoneCountries(string $continent): array
390
    {
391
        $allCountries = $this->lstTimeZone();
392
        $countries    = [];
393
394
        foreach ($allCountries as $country) {
395
            if (strpos($country, $continent) !== false) {
396
                $countries[] = $country;
397
            }
398
        }
399
400
        return $countries;
401
    }
402
403
    /**
404
     * Transform a date to a human readable format
405
     * 
406
     * @param boolean $returnDateAndTime (default true) True to return date and
407
     *  time concatenated with a space. False to have only date.
408
     * 
409
     * @return string
410
     */
411
    public function humanReadable(bool $returnDateAndTime = true): string
412
    {
413
        $current = new Dates;
414
        $diff    = parent::diff($current);
415
        
416
        $parsedTxt = new class {
417
            public $date = '';
418
            public $time = '';
419
        };
420
421
        if ($current == $this) {
422
            //Now
423
            $this->humanDateNow($parsedTxt);
424
        } elseif ($diff->d === 1 && $diff->m === 0 && $diff->y === 0) {
425
            if ($diff->invert === 0) {
426
                $this->humanDateYesterday($parsedTxt); //Yesterday
427
            } else {
428
                $this->humanDateTomorrow($parsedTxt); //Tomorrow
429
            }
430
        } elseif ($diff->days === 0) {
431
            //Today
432
            $this->humanDateToday($parsedTxt, $diff);
0 ignored issues
show
Bug introduced by
It seems like $diff can also be of type false; however, parameter $diff of BFW\Helpers\Dates::humanDateToday() does only seem to accept DateInterval, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

432
            $this->humanDateToday($parsedTxt, /** @scrutinizer ignore-type */ $diff);
Loading history...
433
        } else {
434
            $this->humanDateOther($parsedTxt, $current);
435
        }
436
437
        $txtReturned = $parsedTxt->date;
438
        if ($returnDateAndTime === true && $parsedTxt->time !== '') {
439
            $txtReturned .= ' '.$parsedTxt->time;
440
        }
441
442
        return $txtReturned;
443
    }
444
    
445
    /**
446
     * Format date to human readable when the date is now
447
     * 
448
     * @param object $parsedTxt Texts returned by humanReadable method
449
     * 
450
     * @return void
451
     */
452
    protected function humanDateNow($parsedTxt)
453
    {
454
        $currentClass    = get_called_class();
455
        $parsedTxt->date = $currentClass::$humanReadableI18n['now'];
0 ignored issues
show
Bug introduced by
The property humanReadableI18n does not exist on string.
Loading history...
456
    }
457
    
458
    /**
459
     * Format date to human readable when date is today
460
     * 
461
     * @param object $parsedTxt Texts returned by humanReadable method
462
     * @param \DateInterval $diff Interval between now and date to read
463
     * 
464
     * @return void
465
     */
466
    protected function humanDateToday($parsedTxt, \DateInterval $diff)
467
    {
468
        $textKey = 'since';
469
        if ($diff->invert === 1) {
470
            $textKey = 'in';
471
        }
472
        
473
        $currentClass    = get_called_class();
474
        $parsedTxt->date = $currentClass::$humanReadableI18n[$textKey].' ';
0 ignored issues
show
Bug introduced by
The property humanReadableI18n does not exist on string.
Loading history...
475
476
        if ($diff->h === 0 && $diff->i === 0) {
477
            $parsedTxt->date .= $diff->s.'s';
478
        } elseif ($diff->h === 0) {
479
            $parsedTxt->date .= $diff->i.'min';
480
        } else {
481
            $parsedTxt->date .= $diff->h.'h';
482
        }
483
    }
484
    
485
    /**
486
     * Format date to human readable when date is yesterday
487
     * 
488
     * @param object $parsedTxt Texts returned by humanReadable method
489
     * 
490
     * @return void
491
     */
492
    protected function humanDateYesterday($parsedTxt)
493
    {
494
        $currentClass    = get_called_class();
495
        $parsedTxt->date = $currentClass::$humanReadableI18n['yesterday'];
0 ignored issues
show
Bug introduced by
The property humanReadableI18n does not exist on string.
Loading history...
496
        $parsedTxt->time = $currentClass::$humanReadableI18n['at']
497
            .' '
498
            .$this->format(
499
                $currentClass::$humanReadableFormats['time']
0 ignored issues
show
Bug introduced by
The property humanReadableFormats does not exist on string.
Loading history...
500
            );
501
    }
502
    
503
    /**
504
     * Format date to human readable when date is tomorrow
505
     * 
506
     * @param object $parsedTxt Texts returned by humanReadable method
507
     * 
508
     * @return void
509
     */
510
    protected function humanDateTomorrow($parsedTxt)
511
    {
512
        $currentClass    = get_called_class();
513
        $parsedTxt->date = $currentClass::$humanReadableI18n['tomorrow'];
0 ignored issues
show
Bug introduced by
The property humanReadableI18n does not exist on string.
Loading history...
514
        $parsedTxt->time = $currentClass::$humanReadableI18n['at']
515
            .' '
516
            .$this->format(
517
                $currentClass::$humanReadableFormats['time']
0 ignored issues
show
Bug introduced by
The property humanReadableFormats does not exist on string.
Loading history...
518
            );
519
    }
520
    
521
    /**
522
     * Format date to human readable when date is not now, today or yesterday
523
     * 
524
     * @param object $parsedTxt Texts returned by humanReadable method
525
     * @param \DateTime $current DateTime object for now
526
     * 
527
     * @return void
528
     */
529
    protected function humanDateOther($parsedTxt, \DateTime $current)
530
    {
531
        $currentClass = get_called_class();
532
        
533
        $dateFormat = $currentClass::$humanReadableFormats['dateDifferentYear'];
0 ignored issues
show
Bug introduced by
The property humanReadableFormats does not exist on string.
Loading history...
534
        if ($current->format('Y') === $this->format('Y')) {
535
            $dateFormat = $currentClass::$humanReadableFormats['dateSameYear'];
536
        }
537
538
        $parsedTxt->date = $currentClass::$humanReadableI18n['the']
0 ignored issues
show
Bug introduced by
The property humanReadableI18n does not exist on string.
Loading history...
539
            .' '
540
            .$this->format($dateFormat);
541
542
        $parsedTxt->time = $currentClass::$humanReadableI18n['at']
543
            .' '
544
            .$this->format(
545
                $currentClass::$humanReadableFormats['time']
546
            );
547
    }
548
}
549