Completed
Push — develop ( 1e8e59...ae338f )
by John
02:38
created

Date   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 366
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 41
lcom 1
cbo 3
dl 0
loc 366
rs 9.1199
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 25 4
A setValue() 0 4 1
B setDateValue() 0 27 9
A getValue() 0 4 1
A getUnixValue() 0 4 1
A getEuroValue() 0 4 1
A getUSValue() 0 4 1
A getYear() 0 4 1
A getMonth() 0 4 1
A getDay() 0 4 1
A getWeekday() 0 4 1
C populateFromString() 0 53 15
A getRule() 0 4 1
A setRule() 0 4 1
A increment() 0 5 1
A getStartAndEndDate() 0 13 1

How to fix   Complexity   

Complex Class

Complex classes like Date 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 Date, 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
use \DateTime;
9
10
/**
11
 * The Date complex data type.
12
 *
13
 * @since 1.0
14
 *
15
 * @author John Collins <[email protected]>
16
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
17
 * @copyright Copyright (c) 2018, John Collins (founder of Alpha Framework).
18
 * All rights reserved.
19
 *
20
 * <pre>
21
 * Redistribution and use in source and binary forms, with or
22
 * without modification, are permitted provided that the
23
 * following conditions are met:
24
 *
25
 * * Redistributions of source code must retain the above
26
 *   copyright notice, this list of conditions and the
27
 *   following disclaimer.
28
 * * Redistributions in binary form must reproduce the above
29
 *   copyright notice, this list of conditions and the
30
 *   following disclaimer in the documentation and/or other
31
 *   materials provided with the distribution.
32
 * * Neither the name of the Alpha Framework nor the names
33
 *   of its contributors may be used to endorse or promote
34
 *   products derived from this software without specific
35
 *   prior written permission.
36
 *
37
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
42
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
48
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50
 * </pre>
51
 */
52
class Date extends Type implements TypeInterface
53
{
54
    /**
55
     * The year part.
56
     *
57
     * @var string
58
     *
59
     * @since 1.0
60
     */
61
    private $year;
62
63
    /**
64
     * The month part.
65
     *
66
     * @var string
67
     *
68
     * @since 1.0
69
     */
70
    private $month;
71
72
    /**
73
     * The day part.
74
     *
75
     * @var string
76
     *
77
     * @since 1.0
78
     */
79
    private $day;
80
81
    /**
82
     * The textual version of the day, e.g. Monday.
83
     *
84
     * @var string
85
     *
86
     * @since 1.0
87
     */
88
    private $weekday;
89
90
    /**
91
     * The validation rule (reg-ex) applied to Date values.
92
     *
93
     * @var string
94
     *
95
     * @since 1.0
96
     */
97
    private $validationRule;
98
99
    /**
100
     * The error message returned for invalid values.
101
     *
102
     * @var string
103
     *
104
     * @since 1.0
105
     */
106
    protected $helper = 'Not a valid date value!  A date should be in the ISO format YYYY-MM-DD.';
107
108
    /**
109
     * Constructor.  Leave $date param empty to default to now.
110
     *
111
     * @param string $date Date string in the ISO format YYYY-MM-DD.
112
     *
113
     * @since 1.0
114
     *
115
     * @throws \Alpha\Exception\IllegalArguementException
116
     */
117
    public function __construct($date = '')
118
    {
119
        $config = ConfigProvider::getInstance();
120
121
        $this->validationRule = Validator::ALLOW_ALL;
122
123
        if (empty($date)) {
124
            if ($config->get('app.default.datetime') == 'now') {
125
                $this->year = date('Y');
126
                $this->month = date('m');
127
                $this->day = date('d');
128
                $this->weekday = date('l');
129
            } else {
130
                $this->year = '0000';
131
                $this->month = '00';
132
                $this->day = '00';
133
            }
134
        } else {
135
            if (preg_match($this->validationRule, $date)) {
136
                $this->populateFromString($date);
137
            } else {
138
                throw new IllegalArguementException($this->helper);
139
            }
140
        }
141
    }
142
143
    /**
144
     * Accepts a full date string in ISO YYYY-mm-dd format and populates relevent Date attributes.
145
     *
146
     * @param string $date
147
     *
148
     * @since 1.0
149
     *
150
     * @throws \Alpha\Exception\IllegalArguementException
151
     */
152
    public function setValue($date)
153
    {
154
        $this->populateFromString($date);
155
    }
156
157
    /**
158
     * Set the Date attributes to match the three values provided.
159
     *
160
     * @param int $year
161
     * @param int $month
162
     * @param int $day
163
     *
164
     * @throws \Alpha\Exception\IllegalArguementException
165
     *
166
     * @since 1.0
167
     */
168
    public function setDateValue($year, $month, $day)
169
    {
170
        $valid = null;
171
172
        if (!preg_match('/^[0-9]{4}$/', $year)) {
173
            $valid = 'Error: the year value '.$year.' provided is invalid!';
174
        }
175
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $month)) {
176
            $valid = 'Error: the month value '.$month.' provided is invalid!';
177
        }
178
        if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $day)) {
179
            $valid = 'Error: the day value '.$day.' provided is invalid!';
180
        }
181
        if (!isset($valid) && !checkdate($month, $day, $year)) {
182
            $valid = 'Error: the day value '.$year.'-'.$month.'-'.$day.' provided is invalid!';
183
        }
184
185
        if (isset($valid)) {
186
            throw new IllegalArguementException($valid);
187
        } else {
188
            $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...
189
            $this->month = str_pad($month, 2, '0', STR_PAD_LEFT);
190
            $this->day = str_pad($day, 2, '0', STR_PAD_LEFT);
191
            $unixTime = mktime(0, 0, 0, $this->month, $this->day, $this->year);
192
            $this->weekday = date('l', $unixTime);
193
        }
194
    }
195
196
    /**
197
     * Get the date value as a string in the format "YYYY-MM-DD".
198
     *
199
     * @return string
200
     *
201
     * @since 1.0
202
     */
203
    public function getValue()
204
    {
205
        return $this->year.'-'.$this->month.'-'.$this->day;
206
    }
207
208
    /**
209
     * Return the value in UNIX timestamp format.
210
     *
211
     * @return int
212
     *
213
     * @since 1.0
214
     */
215
    public function getUnixValue()
216
    {
217
        return mktime(0, 0, 0, $this->month, $this->day, $this->year);
218
    }
219
220
    /**
221
     * Get the date value as a string in the format "DD/MM/YYYY".
222
     *
223
     * @return string
224
     *
225
     * @since 1.0
226
     */
227
    public function getEuroValue()
228
    {
229
        return $this->day.'/'.$this->month.'/'.mb_substr($this->year, 2, 2);
230
    }
231
232
    /**
233
     * Get the date value as a string in the format "MM/DD/YYYY".
234
     *
235
     * @return string
236
     *
237
     * @since 1.0
238
     */
239
    public function getUSValue()
240
    {
241
        return $this->month.'/'.$this->day.'/'.mb_substr($this->year, 2, 2);
242
    }
243
244
    /**
245
     * Get the year part.
246
     *
247
     * @return string
248
     *
249
     * @since 1.0
250
     */
251
    public function getYear()
252
    {
253
        return $this->year;
254
    }
255
256
    /**
257
     * Get the month part.
258
     *
259
     * @return string
260
     *
261
     * @since 1.0
262
     */
263
    public function getMonth()
264
    {
265
        return $this->month;
266
    }
267
268
    /**
269
     * Get the day part.
270
     *
271
     * @return string
272
     *
273
     * @since 1.0
274
     */
275
    public function getDay()
276
    {
277
        return $this->day;
278
    }
279
280
    /**
281
     * Get the textual weekday part, e.g. Monday.
282
     *
283
     * @return string
284
     *
285
     * @since 1.0
286
     */
287
    public function getWeekday()
288
    {
289
        return $this->weekday;
290
    }
291
292
    /**
293
     * Accepts a full date string in YYYY-MM-DD format and populates relevent Date attributes.
294
     *
295
     * @param string $date
296
     *
297
     * @throws \Alpha\Exception\IllegalArguementException
298
     *
299
     * @since 1.0
300
     */
301
    public function populateFromString($date)
302
    {
303
        $valid = null;
304
305
        if ($date == '' || $date == '0000-00-00') {
306
            $this->year = '0000';
307
            $this->month = '00';
308
            $this->day = '00';
309
        } else {
310
            // This is just here for legacy to ensure that any old time value from a Date object is ignored
311
            $spilt_by_space = explode(' ', $date);
312
313
            if (isset($spilt_by_space[0])) {
314
                $date = $spilt_by_space[0];
315
            } else {
316
                throw new IllegalArguementException('Invalid Date value ['.$date.'] provided!');
317
            }
318
319
            $split_by_dash = explode('-', $date);
320
321
            // Parse for the date parts, seperated by "-"
322
            if (isset($split_by_dash[0]) && isset($split_by_dash[1]) && isset($split_by_dash[2])) {
323
                $year = $split_by_dash[0];
324
                $month = $split_by_dash[1];
325
                $day = $split_by_dash[2];
326
            } else {
327
                throw new IllegalArguementException('Invalid Date value ['.$date.'] provided!');
328
            }
329
330
            if (!preg_match('/^[0-9]{4}$/', $year)) {
331
                $valid = 'Error: the year value '.$year.' provided is invalid!';
332
            }
333
            if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $month)) {
334
                $valid = 'Error: the month value '.$month.' provided is invalid!';
335
            }
336
            if (!isset($valid) && !preg_match('/^[0-9]{1,2}$/', $day)) {
337
                $valid = 'Error: the day value '.$day.' provided is invalid!';
338
            }
339
            if (!isset($valid) && !checkdate($month, $day, $year)) {
340
                $valid = 'Error: the date value '.$year.'-'.$month.'-'.$day.' provided is invalid!';
341
            }
342
343
            if (isset($valid)) {
344
                throw new IllegalArguementException($valid);
345
            } else {
346
                $this->year = $year;
347
                $this->month = str_pad($month, 2, '0', STR_PAD_LEFT);
348
                $this->day = str_pad($day, 2, '0', STR_PAD_LEFT);
349
                $unixTime = mktime(0, 0, 0, $this->month, $this->day, $this->year);
350
                $this->weekday = date('l', $unixTime);
351
            }
352
        }
353
    }
354
355
    /**
356
     * Get the validation rule.
357
     *
358
     * @return string
359
     *
360
     * @since 1.0
361
     */
362
    public function getRule()
363
    {
364
        return $this->validationRule;
365
    }
366
367
    /**
368
     * Set the validation rule.
369
     *
370
     * @param string $rule
371
     *
372
     * @since 1.0
373
     */
374
    public function setRule($rule)
375
    {
376
        $this->validationRule = $rule;
377
    }
378
379
    /**
380
     *
381
     * Increment the cunrrent date by the amount provided
382
     *
383
     * @param string $amount The amount to increment the date by, e.g. "1 day"
384
     *
385
     * @since 3.1.0
386
     */
387
    public function increment($amount)
388
    {
389
        $date = strtotime($amount, strtotime($this->getValue()));
390
        $this->setValue(date("Y-m-d", $date));
391
    }
392
393
    /**
394
     *
395
     * Get the start date and the end date of the week of the year provided
396
     *
397
     * @param int The number of the week (1-52)
398
     * @param int The year (YYYY)
399
     *
400
     * @return array An array containing the "start" date and "end" date.
401
     *
402
     * @since 3.1.0
403
     */
404
    public static function getStartAndEndDate($week, $year)
405
    {
406
        $dateTime = new DateTime();
407
        $dateTime->setISODate($year, $week);
408
409
        $value = array();
410
411
        $value['start'] = $dateTime->format('Y-m-d');
412
        $dateTime->modify('+6 days');
413
        $value['end'] = $dateTime->format('Y-m-d');
414
        
415
        return $value;
416
    }
417
}
418