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.
Completed
Push — 3.0 ( 043bf5...92a966 )
by Vermeulen
02:10
created

Dates::getModifyNewKeywords()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
244
245
        //If the keyword used is ok with DateTime::modify method
246
        if ($originalDate != $this) {
247
            return $this;
248
        }
249
250
        $this->modifyWithOthersKeywords($modify);
251
252
        return $this;
253
    }
254
255
    /**
256
     * Get DateTime equivalent keyword for a personal keyword declared into
257
     * the property modifyNewKeywords.
258
     * 
259
     * @return \stdClass
260
     */
261
    protected function getNewKeywordsForModify()
262
    {
263
        $search  = [];
264
        $replace = [];
265
        
266
        foreach (self::$modifyNewKeywords as $searchKey => $replaceKey) {
267
            $search[]  = $searchKey;
268
            $replace[] = $replaceKey;
269
        }
270
        
271
        return (object) [
272
            'search'  => $search,
273
            'replace' => $replace
274
        ];
275
    }
276
    
277
    /**
278
     * Use personal keyword on modify method
279
     * 
280
     * @param string $modify A date/time string
281
     * 
282
     * @throws Exception If bad pattern or unknown keyword
283
     */
284
    protected function modifyWithOthersKeywords($modify)
285
    {
286
        $keywords = $this->getNewKeywordsForModify();
287
        $match    = [];
288
        
289
        //Regex on the $modify parameter to get the used keyword
290
        if (preg_match('#(\+|\-)([0-9]+) ([a-z]+)#i', $modify, $match) !== 1) {
291
            throw new Exception('Dates::modify pattern not match.');
292
        }
293
        
294
        $keyword = str_replace(
295
            $keywords->search,
296
            $keywords->replace,
297
            strtolower($match[3])
298
        );
299
        
300
        $originalDate = clone $this;
301
        //Yeurk, but I preferer sends an Exception, not an error
302
        @parent::modify($match[1].$match[2].' '.$keyword);
2 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (modify() instead of modifyWithOthersKeywords()). Are you sure this is correct? If so, you might want to change this to $this->modify().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
303
        
304
        //If no change on object, The keyword is unknown
305
        if ($originalDate == $this) {
306
            throw new Exception(
307
                'Dates::modify Parameter '.$match[3].' is unknown.'
308
            );
309
        }
310
    }
311
    
312
    /**
313
     * Return date's SQL format (postgresql format).
314
     * The return can be an array or a string.
315
     * 
316
     * @param boolean $returnArray (default false) True to return an array.
317
     * 
318
     * @return string[]|string
319
     */
320
    public function getSqlFormat($returnArray = false)
321
    {
322
        $date = $this->format('Y-m-d');
323
        $time = $this->format('H:i:s');
324
325
        if ($returnArray) {
326
            return [$date, $time];
327
        }
328
329
        return $date.' '.$time;
330
    }
331
332
    /**
333
     * List all timezone existing in current php version
334
     * 
335
     * @return string[]
336
     */
337
    public function lstTimeZone()
338
    {
339
        return parent::getTimezone()->listIdentifiers();
340
    }
341
342
    /**
343
     * List all continent define in php DateTimeZone.
344
     * 
345
     * @return string[]
346
     */
347
    public function lstTimeZoneContinent()
348
    {
349
        return [
350
            'africa',
351
            'america',
352
            'antartica',
353
            'arctic',
354
            'asia',
355
            'atlantic',
356
            'australia',
357
            'europe',
358
            'indian',
359
            'pacific'
360
        ];
361
    }
362
363
    /**
364
     * List all available country for a continent
365
     * 
366
     * @param string $continent The continent for which we want
367
     *  the countries list
368
     * 
369
     * @return string[]
370
     */
371
    public function lstTimeZonePays($continent)
372
    {
373
        $allCountries = $this->lstTimeZone();
374
        $countries    = [];
375
376
        foreach ($allCountries as $country) {
377
            if (strpos($country, $continent) !== false) {
378
                $countries[] = $country;
379
            }
380
        }
381
382
        return $countries;
383
    }
384
385
    /**
386
     * Transform a date to a human readable format
387
     * 
388
     * @param boolean $returnDateAndTime (default true) True to return date and
389
     *  time concatenated with a space. False to have only date.
390
     * 
391
     * @return string
392
     */
393
    public function humanReadable($returnDateAndTime = true)
394
    {
395
        $current = new Dates;
396
        $diff    = parent::diff($current);
1 ignored issue
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (diff() instead of humanReadable()). Are you sure this is correct? If so, you might want to change this to $this->diff().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
397
398
        $parsedTxt = (object) [
399
            'date' => '',
400
            'time' => ''
401
        ];
402
403
        if ($current == $this) {
404
            //Now
405
            $this->humanDateNow($parsedTxt);
406
        } elseif ($diff->d === 1 && $diff->m === 0 && $diff->y === 0) {
407
            //Yesterday
408
            $this->humanDateYesterday($parsedTxt);
409
        } elseif ($diff->days === 0) {
410
            //Today
411
            $this->humanDateToday($parsedTxt, $diff);
412
        } else {
413
            $this->humanDateOther($parsedTxt, $current);
414
        }
415
416
        $txtReturned = $parsedTxt->date;
417
        if ($returnDateAndTime === true && $parsedTxt->time !== '') {
418
            $txtReturned .= ' '.$parsedTxt->time;
419
        }
420
421
        return $txtReturned;
422
    }
423
    
424
    /**
425
     * Format date to human readable when the date is now
426
     * 
427
     * @param \stdClass $parsedTxt Texts returned by humanReadable method
428
     * 
429
     * @return void
430
     */
431
    protected function humanDateNow($parsedTxt)
432
    {
433
        $currentClass    = get_called_class();
434
        $parsedTxt->date = $currentClass::$humanReadableI18n['now'];
435
    }
436
    
437
    /**
438
     * Format date to human readable when date is today
439
     * 
440
     * @param \stdClass $parsedTxt Texts returned by humanReadable method
441
     * @param \DateInterval $diff Interval between now and date to read
442
     * 
443
     * @return void
444
     */
445
    protected function humanDateToday($parsedTxt, $diff)
446
    {
447
        $textKey = 'since';
448
        if ($diff->invert === 1) {
449
            $textKey = 'in';
450
        }
451
        
452
        $currentClass    = get_called_class();
453
        $parsedTxt->date = $currentClass::$humanReadableI18n[$textKey].' ';
454
455
        if ($diff->h === 0 && $diff->i === 0) {
456
            $parsedTxt->date .= $diff->s.'s';
457
        } elseif ($diff->h === 0) {
458
            $parsedTxt->date .= $diff->i.'min';
459
        } else {
460
            $parsedTxt->date .= $diff->h.'h';
461
        }
462
    }
463
    
464
    /**
465
     * Format date to human readable when date is yesterday
466
     * 
467
     * @param \stdClass $parsedTxt Texts returned by humanReadable method
468
     * 
469
     * @return void
470
     */
471
    protected function humanDateYesterday($parsedTxt)
472
    {
473
        $currentClass    = get_called_class();
474
        $parsedTxt->date = $currentClass::$humanReadableI18n['yesterday'];
475
        $parsedTxt->time = $currentClass::$humanReadableI18n['at']
476
            .' '
477
            .$this->format(
478
                $currentClass::$humanReadableFormats['time']
479
            );
480
    }
481
    
482
    /**
483
     * Format date to human readable when date is not now, today or yesterday
484
     * 
485
     * @param \stdClass $parsedTxt Texts returned by humanReadable method
486
     * @param \DateTime $current DateTime object for now
487
     * 
488
     * @return void
489
     */
490
    protected function humanDateOther($parsedTxt, $current)
491
    {
492
        $currentClass = get_called_class();
493
        
494
        $dateFormat = $currentClass::$humanReadableFormats['dateDifferentYear'];
495
        if ($current->format('Y') === $this->format('Y')) {
496
            $dateFormat = $currentClass::$humanReadableFormats['dateSameYear'];
497
        }
498
499
        $parsedTxt->date = $currentClass::$humanReadableI18n['the']
500
            .' '
501
            .$this->format($dateFormat);
502
503
        $parsedTxt->time = $currentClass::$humanReadableI18n['at']
504
            .' '
505
            .$this->format(
506
                $currentClass::$humanReadableFormats['time']
507
            );
508
    }
509
}
510