Passed
Push — master ( 5534ff...bbc089 )
by tsms
01:47
created

Week::nextWeek()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 18
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 16
nc 9
nop 1
dl 0
loc 18
rs 8.4444
c 0
b 0
f 0
1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4
/**
5
 * Contains the Calendar_Week class
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. The name of the author may not be used to endorse or promote products
17
 *    derived from this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
 * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
23
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * @category  Date and Time
31
 * @package   Calendar
32
 * @author    Harry Fuecks <[email protected]>
33
 * @author    Lorenzo Alberton <[email protected]>
34
 * @copyright 2003-2007 Harry Fuecks, Lorenzo Alberton
35
 * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
36
 * @version   CVS: $Id$
37
 * @link      http://pear.php.net/package/Calendar
38
 */
39
namespace PEAR\Calendar;
40
41
use PEAR\Calendar\Table\Helper;
42
43
/**
44
 * Represents a Week and builds Days in tabular format<br>
45
 * <code>
46
 * $Week = new \PEAR\Calendar\Week(2003, 10, 1); Oct 2003, 1st tabular week
47
 * echo '<tr>';
48
 * while ($Day = & $Week->fetch()) {
49
 *     if ($Day->isEmpty()) {
50
 *         echo '<td>&nbsp;</td>';
51
 *     } else {
52
 *         echo '<td>'.$Day->thisDay().'</td>';
53
 *      }
54
 * }
55
 * echo '</tr>';
56
 * </code>
57
 *
58
 * @category  Date and Time
59
 * @package   Calendar
60
 * @author    Harry Fuecks <[email protected]>
61
 * @author    Lorenzo Alberton <[email protected]>
62
 * @copyright 2003-2007 Harry Fuecks, Lorenzo Alberton
63
 * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
64
 * @link      http://pear.php.net/package/Calendar
65
 */
66
class Week extends Calendar
67
{
68
    /**
69
     * Instance of Calendar_Table_Helper
70
     * @var \PEAR\Calendar\Table\Helper
71
     * @access private
72
     */
73
    var $tableHelper;
74
75
    /**
76
     * Stores the timestamp of the first day of this week
77
     * @access private
78
     * @var object
79
     */
80
    var $thisWeek;
81
82
    /**
83
     * Stores the timestamp of first day of previous week
84
     * @access private
85
     * @var object
86
     */
87
    var $prevWeek;
88
89
    /**
90
     * Stores the timestamp of first day of next week
91
     * @access private
92
     * @var object
93
     */
94
    var $nextWeek;
95
96
    /**
97
     * Used by build() to set empty days
98
     * @access private
99
     * @var boolean
100
     */
101
    var $firstWeek = false;
102
103
    /**
104
     * Used by build() to set empty days
105
     * @access private
106
     * @var boolean
107
     */
108
    var $lastWeek = false;
109
110
    /**
111
     * First day of the week (0=sunday, 1=monday...)
112
     * @access private
113
     * @var boolean
114
     */
115
    var $firstDay = 1;
116
117
    /**
118
     * Constructs Week
119
     *
120
     * @param int $y        year e.g. 2003
121
     * @param int $m        month e.g. 5
122
     * @param int $d        a day of the desired week
123
     * @param int $firstDay (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
124
     *
125
     * @access public
126
     */
127
    function __construct($y, $m, $d, $firstDay = null)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
128
    {
129
        parent::__construct($y, $m, $d);
130
        $this->firstDay    = $this->defineFirstDayOfWeek($firstDay);
0 ignored issues
show
Documentation Bug introduced by
The property $firstDay was declared of type boolean, but $this->defineFirstDayOfWeek($firstDay) 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...
131
        $this->tableHelper = new Helper($this, $this->firstDay);
132
        $this->thisWeek    = $this->tableHelper->getWeekStart($y, $m, $d, $this->firstDay);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->tableHelper->getW...m, $d, $this->firstDay) of type integer is incompatible with the declared type object of property $thisWeek.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
133
        $this->prevWeek    = $this->tableHelper->getWeekStart(
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->tableHelper->getW...ay()), $this->firstDay) of type integer is incompatible with the declared type object of property $prevWeek.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
134
            $y, 
135
            $m, 
136
            $d - $this->cE->getDaysInWeek(
137
                $this->thisYear(),
138
                $this->thisMonth(),
139
                $this->thisDay()
140
            ), 
141
            $this->firstDay
142
        );
143
        $this->nextWeek = $this->tableHelper->getWeekStart(
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->tableHelper->getW...ay()), $this->firstDay) of type integer is incompatible with the declared type object of property $nextWeek.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
144
            $y, 
145
            $m, 
146
            $d + $this->cE->getDaysInWeek(
147
                $this->thisYear(),
148
                $this->thisMonth(),
149
                $this->thisDay()
150
            ), 
151
            $this->firstDay
152
        );
153
    }
154
155
    /**
156
     * Defines the calendar by a timestamp (Unix or ISO-8601), replacing values
157
     * passed to the constructor
158
     *
159
     * @param int|string $ts Unix or ISO-8601 timestamp
160
     *
161
     * @return void
162
     * @access public
163
     */
164
    function setTimestamp($ts)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
165
    {
166
        parent::setTimestamp($ts);
167
        $this->thisWeek = $this->tableHelper->getWeekStart(
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->tableHelper->getW...->day, $this->firstDay) of type integer is incompatible with the declared type object of property $thisWeek.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
168
            $this->year, $this->month, $this->day, $this->firstDay
0 ignored issues
show
Bug introduced by
$this->firstDay of type boolean is incompatible with the type integer expected by parameter $firstDay of PEAR\Calendar\Table\Helper::getWeekStart(). ( Ignorable by Annotation )

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

168
            $this->year, $this->month, $this->day, /** @scrutinizer ignore-type */ $this->firstDay
Loading history...
169
        );
170
        $this->prevWeek = $this->tableHelper->getWeekStart(
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->tableHelper->getW...ay()), $this->firstDay) of type integer is incompatible with the declared type object of property $prevWeek.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
171
            $this->year, 
172
            $this->month, 
173
            $this->day - $this->cE->getDaysInWeek(
174
                $this->thisYear(),
175
                $this->thisMonth(),
176
                $this->thisDay()
177
            ), 
178
            $this->firstDay
179
        );
180
        $this->nextWeek = $this->tableHelper->getWeekStart(
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->tableHelper->getW...ay()), $this->firstDay) of type integer is incompatible with the declared type object of property $nextWeek.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
181
            $this->year, 
182
            $this->month, 
183
            $this->day + $this->cE->getDaysInWeek(
184
                $this->thisYear(),
185
                $this->thisMonth(),
186
                $this->thisDay()
187
            ), 
188
            $this->firstDay
189
        );
190
    }
191
192
    /**
193
     * Builds Calendar_Day objects for this Week
194
     *
195
     * @param array $sDates (optional) Calendar_Day objects representing selected dates
196
     *
197
     * @return boolean
198
     * @access public
199
     */
200
    function build($sDates = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
201
    {
202
        $year  = $this->cE->stampToYear($this->thisWeek);
203
        $month = $this->cE->stampToMonth($this->thisWeek);
204
        $day   = $this->cE->stampToDay($this->thisWeek);
205
        $end   = $this->cE->getDaysInWeek(
206
            $this->thisYear(),
207
            $this->thisMonth(),
208
            $this->thisDay()
209
        );
210
211
        for ($i=1; $i <= $end; $i++) {
212
            $stamp = $this->cE->dateToStamp($year, $month, $day++);
213
            $this->children[$i] = new Day(
214
                $this->cE->stampToYear($stamp),
215
                $this->cE->stampToMonth($stamp),
216
                $this->cE->stampToDay($stamp)
217
            );
218
        }
219
220
        //set empty days (@see Calendar_Month_Weeks::build())
221
        if ($this->firstWeek) {
222
            $eBefore = $this->tableHelper->getEmptyDaysBefore();
223
            for ($i=1; $i <= $eBefore; $i++) {
224
                $this->children[$i]->setEmpty();
225
            }
226
        }
227
        if ($this->lastWeek) {
228
            $eAfter = $this->tableHelper->getEmptyDaysAfterOffset();
229
            for ($i = $eAfter+1; $i <= $end; $i++) {
230
                $this->children[$i]->setEmpty();
231
            }
232
        }
233
234
        if (count($sDates) > 0) {
235
            $this->setSelection($sDates);
236
        }
237
        return true;
238
    }
239
240
    /**
241
     * Set as first week of the month
242
     *
243
     * @param boolean $state whether it's first or not
244
     *
245
     * @return void
246
     * @access private
247
     */
248
    function setFirst($state = true)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
249
    {
250
        $this->firstWeek = $state;
251
    }
252
253
    /**
254
     * Set as last week of the month
255
     *
256
     * @param boolean $state whether it's lasst or not
257
     *
258
     * @return void
259
     * @access private
260
     */
261
    function setLast($state = true)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
262
    {
263
        $this->lastWeek = $state;
264
    }
265
266
    /**
267
     * Called from build()
268
     *
269
     * @param array $sDates Calendar_Day objects representing selected dates
270
     *
271
     * @return void
272
     * @access private
273
     */
274
    function setSelection($sDates)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
275
    {
276
        foreach ($sDates as $sDate) {
277
            foreach ($this->children as $key => $child) {
278
                if ($child->thisDay() == $sDate->thisDay() &&
279
                    $child->thisMonth() == $sDate->thisMonth() &&
280
                    $child->thisYear() == $sDate->thisYear()
281
                ) {
282
                    $this->children[$key] = $sDate;
283
                    $this->children[$key]->setSelected();
284
                }
285
            }
286
        }
287
        reset($this->children);
288
    }
289
290
    /**
291
     * Returns the value for this year
292
     *
293
     * When a on the first/last week of the year, the year of the week is
294
     * calculated according to ISO-8601
295
     *
296
     * @param string $format return value format ['int' | 'timestamp' | 'object' | 'array']
297
     *
298
     * @return int e.g. 2003 or timestamp
299
     * @access public
300
     */
301
    function thisYear($format = 'int')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
302
    {
303
        if (null !== $this->thisWeek) {
304
            $tmp_cal = new Calendar();
305
            $tmp_cal->setTimestamp($this->thisWeek);
0 ignored issues
show
Bug introduced by
$this->thisWeek of type object is incompatible with the type integer|string expected by parameter $ts of PEAR\Calendar\Calendar::setTimestamp(). ( Ignorable by Annotation )

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

305
            $tmp_cal->setTimestamp(/** @scrutinizer ignore-type */ $this->thisWeek);
Loading history...
306
            $first_dow = $tmp_cal->thisDay('array');
307
            $days_in_week = $tmp_cal->cE->getDaysInWeek($tmp_cal->year, $tmp_cal->month, $tmp_cal->day);
308
            $tmp_cal->day += $days_in_week;
309
            $last_dow  = $tmp_cal->thisDay('array');
310
311
            if ($first_dow['year'] == $last_dow['year']) {
312
                return $first_dow['year'];
313
            }
314
315
            if ($last_dow['day'] > floor($days_in_week / 2)) {
316
                return $last_dow['year'];
317
            }
318
            return $first_dow['year'];
319
        }
320
        return parent::thisYear();
321
    }
322
323
    /**
324
     * Gets the value of the previous week, according to the requested format
325
     *
326
     * @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
327
     *
328
     * @return mixed
329
     * @access public
330
     */
331
    function prevWeek($format = 'n_in_month')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
332
    {
333
        switch (strtolower($format)) {
334
        case 'int':
335
        case 'n_in_month':
336
            return ($this->firstWeek) ? null : $this->thisWeek('n_in_month') -1;
337
        case 'n_in_year':
338
            return $this->cE->getWeekNInYear(
339
                $this->cE->stampToYear($this->prevWeek),
340
                $this->cE->stampToMonth($this->prevWeek),
341
                $this->cE->stampToDay($this->prevWeek));
342
        case 'array':
343
            return $this->toArray($this->prevWeek);
344
        case 'object':
345
            return Factory::createByTimestamp('Week', $this->prevWeek);
0 ignored issues
show
Bug Best Practice introduced by
The method PEAR\Calendar\Factory::createByTimestamp() is not static, but was called statically. ( Ignorable by Annotation )

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

345
            return Factory::/** @scrutinizer ignore-call */ createByTimestamp('Week', $this->prevWeek);
Loading history...
346
        case 'timestamp':
347
        default:
348
            return $this->prevWeek;
349
        }
350
    }
351
352
    /**
353
     * Gets the value of the current week, according to the requested format
354
     *
355
     * @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
356
     *
357
     * @return mixed
358
     * @access public
359
     */
360
    function thisWeek($format = 'n_in_month')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
361
    {
362
        switch (strtolower($format)) {
363
        case 'int':
364
        case 'n_in_month':
365
            if ($this->firstWeek) {
366
                return 1;
367
            }
368
            if ($this->lastWeek) {
369
                return $this->cE->getWeeksInMonth(
370
                    $this->thisYear(),
371
                    $this->thisMonth(),
372
                    $this->firstDay);
373
            }
374
            return $this->cE->getWeekNInMonth(
375
                $this->thisYear(),
376
                $this->thisMonth(),
377
                $this->thisDay(),
378
                $this->firstDay);
379
        case 'n_in_year':
380
            return $this->cE->getWeekNInYear(
381
                $this->cE->stampToYear($this->thisWeek),
382
                $this->cE->stampToMonth($this->thisWeek),
383
                $this->cE->stampToDay($this->thisWeek));
384
        case 'array':
385
            return $this->toArray($this->thisWeek);
386
        case 'object':
387
            return Factory::createByTimestamp('Week', $this->thisWeek);
0 ignored issues
show
Bug Best Practice introduced by
The method PEAR\Calendar\Factory::createByTimestamp() is not static, but was called statically. ( Ignorable by Annotation )

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

387
            return Factory::/** @scrutinizer ignore-call */ createByTimestamp('Week', $this->thisWeek);
Loading history...
388
        case 'timestamp':
389
        default:
390
            return $this->thisWeek;
391
        }
392
    }
393
394
    /**
395
     * Gets the value of the following week, according to the requested format
396
     *
397
     * @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
398
     *
399
     * @return mixed
400
     * @access public
401
     */
402
    function nextWeek($format = 'n_in_month')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
403
    {
404
        switch (strtolower($format)) {
405
        case 'int':
406
        case 'n_in_month':
407
            return ($this->lastWeek) ? null : $this->thisWeek('n_in_month') +1;
408
        case 'n_in_year':
409
            return $this->cE->getWeekNInYear(
410
                $this->cE->stampToYear($this->nextWeek),
411
                $this->cE->stampToMonth($this->nextWeek),
412
                $this->cE->stampToDay($this->nextWeek));
413
        case 'array':
414
            return $this->toArray($this->nextWeek);
415
        case 'object':
416
            return Factory::createByTimestamp('Week', $this->nextWeek);
0 ignored issues
show
Bug Best Practice introduced by
The method PEAR\Calendar\Factory::createByTimestamp() is not static, but was called statically. ( Ignorable by Annotation )

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

416
            return Factory::/** @scrutinizer ignore-call */ createByTimestamp('Week', $this->nextWeek);
Loading history...
417
        case 'timestamp':
418
        default:
419
            return $this->nextWeek;
420
        }
421
    }
422
423
    /**
424
     * Returns the instance of Calendar_Table_Helper.
425
     * Called from Calendar_Validator::isValidWeek
426
     *
427
     * @return \PEAR\Calendar\Table\Helper
428
     * @access protected
429
     */
430
    function & getHelper()
431
    {
432
        return $this->tableHelper;
433
    }
434
435
    /**
436
     * Makes sure theres a value for $this->day
437
     *
438
     * @return void
439
     * @access private
440
     */
441
    function findFirstDay()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
442
    {
443
        if (!count($this->children) > 0) {
444
            $this->build();
445
            foreach ($this->children as $Day) {
446
                if (!$Day->isEmpty()) {
447
                    $this->day = $Day->thisDay();
448
                    break;
449
                }
450
            }
451
        }
452
    }
453
}
454