Issues (491)

src/Week.php (7 issues)

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)
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)
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
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())
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)
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)
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)
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')
302
    {
303
        if (null !== $this->thisWeek) {
304
            $tmp_cal = new Calendar();
305
            $tmp_cal->setTimestamp($this->thisWeek);
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')
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);
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')
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);
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')
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);
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()
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