1 <?php
defined('SYSPATH') OR die('No direct access allowed.');
3 * Calendar event observer class.
5 * $Id: Calendar_Event.php 3917 2009-01-21 03:06:22Z zombor $
9 * @copyright (c) 2007-2008 Kohana Team
10 * @license http://kohanaphp.com/license.html
12 class Calendar_Event
extends Event_Observer
{
15 protected $booleans = array
25 // Rendering conditions
26 protected $conditions = array();
29 protected $classes = array();
32 protected $output = '';
35 * Adds a condition to the event. The condition can be one of the following:
37 * timestamp - UNIX timestamp
38 * day - day number (1-31)
39 * week - week number (1-5)
40 * month - month number (1-12)
41 * year - year number (4 digits)
42 * day_of_week - day of week (1-7)
43 * current - active month (boolean) (only show data for the month being rendered)
44 * weekend - weekend day (boolean)
45 * first_day - first day of month (boolean)
46 * last_day - last day of month (boolean)
47 * occurrence - occurrence of the week day (1-5) (use with "day_of_week")
48 * last_occurrence - last occurrence of week day (boolean) (use with "day_of_week")
49 * easter - Easter day (boolean)
50 * callback - callback test (boolean)
52 * To unset a condition, call condition with a value of NULL.
55 * @param string condition key
56 * @param mixed condition value
59 public function condition($key, $value)
63 unset($this->conditions
[$key]);
67 if ($key === 'callback')
71 elseif (in_array($key, $this->booleans
))
73 // Make the value boolean
74 $value = (bool) $value;
78 // Make the value an int
79 $value = (int) $value;
82 $this->conditions
[$key] = $value;
89 * Add a CSS class for this event. This can be called multiple times.
92 * @param string CSS class name
95 public function add_class($class)
97 $this->classes
[$class] = $class;
103 * Remove a CSS class for this event. This can be called multiple times.
106 * @param string CSS class name
109 public function remove_class($class)
111 unset($this->classes
[$class]);
117 * Set HTML output for this event.
120 * @param string HTML output
123 public function output($str)
125 $this->output
= $str;
131 * Add a CSS class for this event. This can be called multiple times.
134 * @param string CSS class name
137 public function notify($data)
139 // Split the date and current status
140 list ($month, $day, $year, $week, $current) = $data;
142 // Get a timestamp for the day
143 $timestamp = mktime(0, 0, 0, $month, $day, $year);
148 'timestamp' => (int) $timestamp,
149 'day' => (int) date('j', $timestamp),
150 'week' => (int) $week,
151 'month' => (int) date('n', $timestamp),
152 'year' => (int) date('Y', $timestamp),
153 'day_of_week' => (int) date('w', $timestamp),
154 'current' => (bool) $current,
160 foreach ($condition as $key => $value)
162 // Test basic conditions first
163 if (isset($this->conditions
[$key]) AND $this->conditions
[$key] !== $value)
166 // Condition has been tested
167 $tested[$key] = TRUE;
170 if (isset($this->conditions
['weekend']))
172 // Weekday vs Weekend
173 $condition['weekend'] = ($condition['day_of_week'] === 0 OR $condition['day_of_week'] === 6);
176 if (isset($this->conditions
['first_day']))
178 // First day of month
179 $condition['first_day'] = ($condition['day'] === 1);
182 if (isset($this->conditions
['last_day']))
185 $condition['last_day'] = ($condition['day'] === (int) date('t', $timestamp));
188 if (isset($this->conditions
['occurrence']))
190 // Get the occurance of the current day
191 $condition['occurrence'] = $this->day_occurrence($timestamp);
194 if (isset($this->conditions
['last_occurrence']))
196 // Test if the next occurance of this date is next month
197 $condition['last_occurrence'] = ((int) date('n', $timestamp +
604800) !== $condition['month']);
200 if (isset($this->conditions
['easter']))
202 if ($condition['month'] === 3 OR $condition['month'] === 4)
204 // This algorithm is from Practical Astronomy With Your Calculator, 2nd Edition by Peter
205 // Duffett-Smith. It was originally from Butcher's Ecclesiastical Calendar, published in
206 // 1876. This algorithm has also been published in the 1922 book General Astronomy by
207 // Spencer Jones; in The Journal of the British Astronomical Association (Vol.88, page
208 // 91, December 1977); and in Astronomical Algorithms (1991) by Jean Meeus.
210 $a = $condition['year'] %
19;
211 $b = (int) ($condition['year'] / 100);
212 $c = $condition['year'] %
100;
215 $f = (int) (($b +
8) / 25);
216 $g = (int) (($b - $f +
1) / 3);
217 $h = (19 * $a +
$b - $d - $g +
15) %
30;
220 $l = (32 +
2 * $e +
2 * $i - $h - $k) %
7;
221 $m = (int) (($a +
11 * $h +
22 * $l) / 451);
222 $p = ($h +
$l - 7 * $m +
114) %
31;
224 $month = (int) (($h +
$l - 7 * $m +
114) / 31);
227 $condition['easter'] = ($condition['month'] === $month AND $condition['day'] === $day);
231 // Easter can only happen in March or April
232 $condition['easter'] = FALSE;
236 if (isset($this->conditions
['callback']))
238 // Use a callback to determine validity
239 $condition['callback'] = call_user_func($this->conditions
['callback'], $condition, $this);
242 $conditions = array_diff_key($this->conditions
, $tested);
244 foreach ($conditions as $key => $value)
246 if ($key === 'callback')
248 // Callbacks are tested on a TRUE/FALSE basis
252 // Test advanced conditions
253 if ($condition[$key] !== $value)
257 $this->caller
->add_data(array
259 'classes' => $this->classes
,
260 'output' => $this->output
,
265 * Find the week day occurrence for a specific timestamp. The occurrence is
266 * relative to the current month. For example, the second Saturday of any
267 * given month will return "2" as the occurrence. This is used in combination
268 * with the "occurrence" condition.
270 * @param integer UNIX timestamp
273 protected function day_occurrence($timestamp)
275 // Get the current month for the timestamp
276 $month = date('m', $timestamp);
278 // Default occurrence is one
281 // Reduce the timestamp by one week for each loop. This has the added
282 // benefit of preventing an infinite loop.
283 while ($timestamp -= 604800)
285 if (date('m', $timestamp) !== $month)
287 // Once the timestamp has gone into the previous month, the
288 // proper occurrence has been found.
292 // Increment the occurrence
297 } // End Calendar Event