Subversion Repositories Applications.gtt

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 jpm 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
//
4
// +----------------------------------------------------------------------+
5
// | PHP Version 4                                                        |
6
// +----------------------------------------------------------------------+
7
// | Copyright (c) 1997-2002 The PHP Group                                |
8
// +----------------------------------------------------------------------+
9
// | This source file is subject to version 2.02 of the PHP license,      |
10
// | that is bundled with this package in the file LICENSE, and is        |
11
// | available at through the world-wide-web at                           |
12
// | http://www.php.net/license/3_0.txt.                                  |
13
// | If you did not receive a copy of the PHP license and are unable to   |
14
// | obtain it through the world-wide-web, please send a note to          |
15
// | license@php.net so we can mail you a copy immediately.               |
16
// +----------------------------------------------------------------------+
17
// | Authors: Harry Fuecks <hfuecks@phppatterns.com>                      |
18
// |          Lorenzo Alberton <l dot alberton at quipo dot it>           |
19
// +----------------------------------------------------------------------+
20
//
21
// $Id: Calendar.php,v 1.3 2005/10/22 10:07:11 quipo Exp $
22
//
23
/**
24
 * @package Calendar
25
 * @version $Id: Calendar.php,v 1.3 2005/10/22 10:07:11 quipo Exp $
26
 */
27
 
28
/**
29
 * Allows Calendar include path to be redefined
30
 */
31
if (!defined('CALENDAR_ROOT')) {
32
    define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
33
}
34
 
35
/**
36
 * Constant which defines the calculation engine to use
37
 */
38
if (!defined('CALENDAR_ENGINE')) {
39
    define('CALENDAR_ENGINE', 'UnixTS');
40
}
41
 
42
/**
43
 * Define Calendar Month states
44
 */
45
define('CALENDAR_USE_MONTH',          1);
46
define('CALENDAR_USE_MONTH_WEEKDAYS', 2);
47
define('CALENDAR_USE_MONTH_WEEKS',    3);
48
 
49
/**
50
 * Contains a factory method to return a Singleton instance of a class
51
 * implementing the Calendar_Engine_Interface.<br>
52
 * <b>Note:</b> this class must be modified to "register" alternative
53
 * Calendar_Engines. The engine used can be controlled with the constant
54
 * CALENDAR_ENGINE
55
 * @see Calendar_Engine_Interface
56
 * @package Calendar
57
 * @access protected
58
 */
59
class Calendar_Engine_Factory
60
{
61
    /**
62
     * Returns an instance of the engine
63
     * @return object instance of a calendar calculation engine
64
     * @access protected
65
     */
66
    function & getEngine()
67
    {
68
        static $engine = false;
69
        switch (CALENDAR_ENGINE) {
70
            case 'PearDate':
71
                $class = 'Calendar_Engine_PearDate';
72
                break;
73
            case 'UnixTS':
74
            default:
75
                $class = 'Calendar_Engine_UnixTS';
76
            break;
77
        }
78
        if (!$engine) {
79
            if (!class_exists($class)) {
80
                require_once CALENDAR_ROOT.'Engine'.DIRECTORY_SEPARATOR.CALENDAR_ENGINE.'.php';
81
            }
82
            $engine = new $class;
83
        }
84
        return $engine;
85
    }
86
}
87
 
88
/**
89
 * Base class for Calendar API. This class should not be instantiated
90
 * directly.
91
 * @abstract
92
 * @package Calendar
93
 */
94
class Calendar
95
{
96
    /**
97
     * Instance of class implementing calendar engine interface
98
     * @var object
99
     * @access private
100
     */
101
    var $cE;
102
 
103
    /**
104
     * Instance of Calendar_Validator (lazy initialized when isValid() or
105
     * getValidor() is called
106
     * @var Calendar_Validator
107
     * @access private
108
     */
109
    var $validator;
110
 
111
    /**
112
     * Year for this calendar object e.g. 2003
113
     * @access private
114
     * @var int
115
     */
116
   var $year;
117
 
118
    /**
119
     * Month for this calendar object e.g. 9
120
     * @access private
121
     * @var int
122
     */
123
    var $month;
124
 
125
    /**
126
     * Day of month for this calendar object e.g. 23
127
     * @access private
128
     * @var int
129
     */
130
    var $day;
131
 
132
    /**
133
     * Hour of day for this calendar object e.g. 13
134
     * @access private
135
     * @var int
136
     */
137
    var $hour;
138
 
139
    /**
140
     * Minute of hour this calendar object e.g. 46
141
     * @access private
142
     * @var int
143
     */
144
    var $minute;
145
 
146
    /**
147
     * Second of minute this calendar object e.g. 34
148
     * @access private
149
     * @var int
150
     */
151
    var $second;
152
 
153
    /**
154
     * Marks this calendar object as selected (e.g. 'today')
155
     * @access private
156
     * @var boolean
157
     */
158
    var $selected = false;
159
 
160
    /**
161
     * Collection of child calendar objects created from subclasses
162
     * of Calendar. Type depends on the object which created them.
163
     * @access private
164
     * @var array
165
     */
166
    var $children = array();
167
 
168
    /**
169
     * Constructs the Calendar
170
     * @param int year
171
     * @param int month
172
     * @param int day
173
     * @param int hour
174
     * @param int minute
175
     * @param int second
176
     * @access protected
177
     */
178
    function Calendar($y = 2000, $m = 1, $d = 1, $h = 0, $i = 0, $s = 0)
179
    {
180
        static $cE = null;
181
        if (!isset($cE)) {
182
            $cE = & Calendar_Engine_Factory::getEngine();
183
        }
184
        $this->cE = & $cE;
185
        $this->year   = (int)$y;
186
        $this->month  = (int)$m;
187
        $this->day    = (int)$d;
188
        $this->hour   = (int)$h;
189
        $this->minute = (int)$i;
190
        $this->second = (int)$s;
191
    }
192
 
193
    /**
194
     * Defines the calendar by a timestamp (Unix or ISO-8601), replacing values
195
     * passed to the constructor
196
     * @param int|string Unix or ISO-8601 timestamp
197
     * @return void
198
     * @access public
199
     */
200
    function setTimestamp($ts)
201
    {
202
        $this->year   = $this->cE->stampToYear($ts);
203
        $this->month  = $this->cE->stampToMonth($ts);
204
        $this->day    = $this->cE->stampToDay($ts);
205
        $this->hour   = $this->cE->stampToHour($ts);
206
        $this->minute = $this->cE->stampToMinute($ts);
207
        $this->second = $this->cE->stampToSecond($ts);
208
    }
209
 
210
    /**
211
     * Returns a timestamp from the current date / time values. Format of
212
     * timestamp depends on Calendar_Engine implementation being used
213
     * @return int|string timestamp
214
     * @access public
215
     */
216
    function getTimestamp()
217
    {
218
        return $this->cE->dateToStamp(
219
            $this->year, $this->month, $this->day,
220
            $this->hour, $this->minute, $this->second);
221
    }
222
 
223
    /**
224
     * Defines calendar object as selected (e.g. for today)
225
     * @param boolean state whether Calendar subclass
226
     * @return void
227
     * @access public
228
     */
229
    function setSelected($state = true)
230
    {
231
        $this->selected = $state;
232
    }
233
 
234
    /**
235
     * True if the calendar subclass object is selected (e.g. today)
236
     * @return boolean
237
     * @access public
238
     */
239
    function isSelected()
240
    {
241
        return $this->selected;
242
    }
243
 
244
    /**
245
     * Adjusts the date (helper method)
246
     * @return void
247
     * @access public
248
     */
249
    function adjust()
250
    {
251
        $stamp = $this->getTimeStamp();
252
        $this->year   = $this->cE->stampToYear($stamp);
253
        $this->month  = $this->cE->stampToMonth($stamp);
254
        $this->day    = $this->cE->stampToDay($stamp);
255
        $this->hour   = $this->cE->stampToHour($stamp);
256
        $this->minute = $this->cE->stampToMinute($stamp);
257
        $this->second = $this->cE->stampToSecond($stamp);
258
    }
259
 
260
    /**
261
     * Returns the date as an associative array (helper method)
262
     * @param mixed timestamp (leave empty for current timestamp)
263
     * @return array
264
     * @access public
265
     */
266
    function toArray($stamp=null)
267
    {
268
        if (is_null($stamp)) {
269
            $stamp = $this->getTimeStamp();
270
        }
271
        return array(
272
            'year'   => $this->cE->stampToYear($stamp),
273
            'month'  => $this->cE->stampToMonth($stamp),
274
            'day'    => $this->cE->stampToDay($stamp),
275
            'hour'   => $this->cE->stampToHour($stamp),
276
            'minute' => $this->cE->stampToMinute($stamp),
277
            'second' => $this->cE->stampToSecond($stamp)
278
        );
279
    }
280
 
281
    /**
282
     * Returns the value as an associative array (helper method)
283
     * @param string type of date object that return value represents
284
     * @param string $format ['int' | 'array' | 'timestamp' | 'object']
285
     * @param mixed timestamp (depending on Calendar engine being used)
286
     * @param int integer default value (i.e. give me the answer quick)
287
     * @return mixed
288
     * @access private
289
     */
290
    function returnValue($returnType, $format, $stamp, $default)
291
    {
292
        switch (strtolower($format)) {
293
            case 'int':
294
                return $default;
295
            case 'array':
296
                return $this->toArray($stamp);
297
                break;
298
            case 'object':
299
                require_once CALENDAR_ROOT.'Factory.php';
300
                return Calendar_Factory::createByTimestamp($returnType,$stamp);
301
                break;
302
            case 'timestamp':
303
            default:
304
                return $stamp;
305
                break;
306
        }
307
    }
308
 
309
    /**
310
     * Abstract method for building the children of a calendar object.
311
     * Implemented by Calendar subclasses
312
     * @param array containing Calendar objects to select (optional)
313
     * @return boolean
314
     * @access public
315
     * @abstract
316
     */
317
    function build($sDates = array())
318
    {
319
        require_once 'PEAR.php';
320
        PEAR::raiseError(
321
            'Calendar::build is abstract', null, PEAR_ERROR_TRIGGER,
322
            E_USER_NOTICE, 'Calendar::build()');
323
        return false;
324
    }
325
 
326
    /**
327
     * Abstract method for selected data objects called from build
328
     * @param array
329
     * @return boolean
330
     * @access public
331
     * @abstract
332
     */
333
    function setSelection($sDates)
334
    {
335
        require_once 'PEAR.php';
336
        PEAR::raiseError(
337
            'Calendar::setSelection is abstract', null, PEAR_ERROR_TRIGGER,
338
            E_USER_NOTICE, 'Calendar::setSelection()');
339
        return false;
340
    }
341
 
342
    /**
343
     * Iterator method for fetching child Calendar subclass objects
344
     * (e.g. a minute from an hour object). On reaching the end of
345
     * the collection, returns false and resets the collection for
346
     * further iteratations.
347
     * @return mixed either an object subclass of Calendar or false
348
     * @access public
349
     */
350
    function fetch()
351
    {
352
        $child = each($this->children);
353
        if ($child) {
354
            return $child['value'];
355
        } else {
356
            reset($this->children);
357
            return false;
358
        }
359
    }
360
 
361
    /**
362
     * Fetches all child from the current collection of children
363
     * @return array
364
     * @access public
365
     */
366
    function fetchAll()
367
    {
368
        return $this->children;
369
    }
370
 
371
    /**
372
     * Get the number Calendar subclass objects stored in the internal
373
     * collection.
374
     * @return int
375
     * @access public
376
     */
377
    function size()
378
    {
379
        return count($this->children);
380
    }
381
 
382
    /**
383
     * Determine whether this date is valid, with the bounds determined by
384
     * the Calendar_Engine. The call is passed on to
385
     * Calendar_Validator::isValid
386
     * @return boolean
387
     * @access public
388
     */
389
    function isValid()
390
    {
391
        $validator = & $this->getValidator();
392
        return $validator->isValid();
393
    }
394
 
395
    /**
396
     * Returns an instance of Calendar_Validator
397
     * @return Calendar_Validator
398
     * @access public
399
     */
400
    function & getValidator()
401
    {
402
        if (!isset($this->validator)) {
403
            require_once CALENDAR_ROOT.'Validator.php';
404
            $this->validator = & new Calendar_Validator($this);
405
        }
406
        return $this->validator;
407
    }
408
 
409
    /**
410
     * Returns a reference to the current Calendar_Engine being used. Useful
411
     * for Calendar_Table_Helper and Calendar_Validator
412
     * @return object implementing Calendar_Engine_Inteface
413
     * @access protected
414
     */
415
    function & getEngine()
416
    {
417
        return $this->cE;
418
    }
419
 
420
    /**
421
     * Set the CALENDAR_FIRST_DAY_OF_WEEK constant to the $firstDay value
422
     * if the constant is not set yet.
423
     * @throws E_USER_WARNING this method throws a WARNING if the
424
     *    CALENDAR_FIRST_DAY_OF_WEEK constant is already defined and
425
     *    the $firstDay parameter is set to a different value
426
     * @param integer $firstDay first day of the week (0=sunday, 1=monday, ...)
427
     * @return integer
428
     * @access protected
429
     */
430
    function defineFirstDayOfWeek($firstDay = null)
431
    {
432
        if (defined('CALENDAR_FIRST_DAY_OF_WEEK')) {
433
            if (!is_null($firstDay) && ($firstDay != CALENDAR_FIRST_DAY_OF_WEEK)) {
434
                $msg = 'CALENDAR_FIRST_DAY_OF_WEEK constant already defined.'
435
                  .' The $firstDay parameter will be ignored.';
436
                trigger_error($msg, E_USER_WARNING);
437
            }
438
            return CALENDAR_FIRST_DAY_OF_WEEK;
439
        }
440
        if (is_null($firstDay)) {
441
            $firstDay = $this->cE->getFirstDayOfWeek(
442
                $this->thisYear(),
443
                $this->thisMonth(),
444
                $this->thisDay()
445
            );
446
        }
447
        define ('CALENDAR_FIRST_DAY_OF_WEEK', $firstDay);
448
        return CALENDAR_FIRST_DAY_OF_WEEK;
449
    }
450
 
451
    /**
452
     * Returns the value for the previous year
453
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
454
     * @return int e.g. 2002 or timestamp
455
     * @access public
456
     */
457
    function prevYear($format = 'int')
458
    {
459
        $ts = $this->cE->dateToStamp($this->year-1, 1, 1, 0, 0, 0);
460
        return $this->returnValue('Year', $format, $ts, $this->year-1);
461
    }
462
 
463
    /**
464
     * Returns the value for this year
465
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
466
     * @return int e.g. 2003 or timestamp
467
     * @access public
468
     */
469
    function thisYear($format = 'int')
470
    {
471
        $ts = $this->cE->dateToStamp($this->year, 1, 1, 0, 0, 0);
472
        return $this->returnValue('Year', $format, $ts, $this->year);
473
    }
474
 
475
    /**
476
     * Returns the value for next year
477
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
478
     * @return int e.g. 2004 or timestamp
479
     * @access public
480
     */
481
    function nextYear($format = 'int')
482
    {
483
        $ts = $this->cE->dateToStamp($this->year+1, 1, 1, 0, 0, 0);
484
        return $this->returnValue('Year', $format, $ts, $this->year+1);
485
    }
486
 
487
    /**
488
     * Returns the value for the previous month
489
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
490
     * @return int e.g. 4 or Unix timestamp
491
     * @access public
492
     */
493
    function prevMonth($format = 'int')
494
    {
495
        $ts = $this->cE->dateToStamp($this->year, $this->month-1, 1, 0, 0, 0);
496
        return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts));
497
    }
498
 
499
    /**
500
     * Returns the value for this month
501
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
502
     * @return int e.g. 5 or timestamp
503
     * @access public
504
     */
505
    function thisMonth($format = 'int')
506
    {
507
        $ts = $this->cE->dateToStamp($this->year, $this->month, 1, 0, 0, 0);
508
        return $this->returnValue('Month', $format, $ts, $this->month);
509
    }
510
 
511
    /**
512
     * Returns the value for next month
513
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
514
     * @return int e.g. 6 or timestamp
515
     * @access public
516
     */
517
    function nextMonth($format = 'int')
518
    {
519
        $ts = $this->cE->dateToStamp($this->year, $this->month+1, 1, 0, 0, 0);
520
        return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts));
521
    }
522
 
523
    /**
524
     * Returns the value for the previous day
525
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
526
     * @return int e.g. 10 or timestamp
527
     * @access public
528
     */
529
    function prevDay($format = 'int')
530
    {
531
        $ts = $this->cE->dateToStamp(
532
            $this->year, $this->month, $this->day-1, 0, 0, 0);
533
        return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts));
534
    }
535
 
536
    /**
537
     * Returns the value for this day
538
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
539
     * @return int e.g. 11 or timestamp
540
     * @access public
541
     */
542
    function thisDay($format = 'int')
543
    {
544
        $ts = $this->cE->dateToStamp(
545
            $this->year, $this->month, $this->day, 0, 0, 0);
546
        return $this->returnValue('Day', $format, $ts, $this->day);
547
    }
548
 
549
    /**
550
     * Returns the value for the next day
551
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
552
     * @return int e.g. 12 or timestamp
553
     * @access public
554
     */
555
    function nextDay($format = 'int')
556
    {
557
        $ts = $this->cE->dateToStamp(
558
            $this->year, $this->month, $this->day+1, 0, 0, 0);
559
        return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts));
560
    }
561
 
562
    /**
563
     * Returns the value for the previous hour
564
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
565
     * @return int e.g. 13 or timestamp
566
     * @access public
567
     */
568
    function prevHour($format = 'int')
569
    {
570
        $ts = $this->cE->dateToStamp(
571
            $this->year, $this->month, $this->day, $this->hour-1, 0, 0);
572
        return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts));
573
    }
574
 
575
    /**
576
     * Returns the value for this hour
577
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
578
     * @return int e.g. 14 or timestamp
579
     * @access public
580
     */
581
    function thisHour($format = 'int')
582
    {
583
        $ts = $this->cE->dateToStamp(
584
            $this->year, $this->month, $this->day, $this->hour, 0, 0);
585
        return $this->returnValue('Hour', $format, $ts, $this->hour);
586
    }
587
 
588
    /**
589
     * Returns the value for the next hour
590
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
591
     * @return int e.g. 14 or timestamp
592
     * @access public
593
     */
594
    function nextHour($format = 'int')
595
    {
596
        $ts = $this->cE->dateToStamp(
597
            $this->year, $this->month, $this->day, $this->hour+1, 0, 0);
598
        return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts));
599
    }
600
 
601
    /**
602
     * Returns the value for the previous minute
603
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
604
     * @return int e.g. 23 or timestamp
605
     * @access public
606
     */
607
    function prevMinute($format = 'int')
608
    {
609
        $ts = $this->cE->dateToStamp(
610
            $this->year, $this->month, $this->day,
611
            $this->hour, $this->minute-1, 0);
612
        return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts));
613
    }
614
 
615
    /**
616
     * Returns the value for this minute
617
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
618
     * @return int e.g. 24 or timestamp
619
     * @access public
620
     */
621
    function thisMinute($format = 'int')
622
    {
623
        $ts = $this->cE->dateToStamp(
624
            $this->year, $this->month, $this->day,
625
            $this->hour, $this->minute, 0);
626
        return $this->returnValue('Minute', $format, $ts, $this->minute);
627
    }
628
 
629
    /**
630
    * Returns the value for the next minute
631
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
632
     * @return int e.g. 25 or timestamp
633
     * @access public
634
     */
635
    function nextMinute($format = 'int')
636
    {
637
        $ts = $this->cE->dateToStamp(
638
            $this->year, $this->month, $this->day,
639
            $this->hour, $this->minute+1, 0);
640
        return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts));
641
    }
642
 
643
    /**
644
     * Returns the value for the previous second
645
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
646
     * @return int e.g. 43 or timestamp
647
     * @access public
648
     */
649
    function prevSecond($format = 'int')
650
    {
651
        $ts = $this->cE->dateToStamp(
652
            $this->year, $this->month, $this->day,
653
            $this->hour, $this->minute, $this->second-1);
654
        return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts));
655
    }
656
 
657
    /**
658
     * Returns the value for this second
659
    * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
660
     * @return int e.g. 44 or timestamp
661
     * @access public
662
     */
663
    function thisSecond($format = 'int')
664
    {
665
        $ts = $this->cE->dateToStamp(
666
            $this->year, $this->month, $this->day,
667
            $this->hour, $this->minute, $this->second);
668
        return $this->returnValue('Second', $format, $ts, $this->second);
669
    }
670
 
671
    /**
672
     * Returns the value for the next second
673
     * @param string return value format ['int' | 'timestamp' | 'object' | 'array']
674
     * @return int e.g. 45 or timestamp
675
     * @access public
676
     */
677
    function nextSecond($format = 'int')
678
    {
679
        $ts = $this->cE->dateToStamp(
680
            $this->year, $this->month, $this->day,
681
            $this->hour, $this->minute, $this->second+1);
682
        return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts));
683
    }
684
}
685
?>