Avail feature updated
[ninja.git] / system / libraries / Calendar.php
blobc0eba2d6783db0a2a918a02685b23b7a2bd75b2f
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3 * Calendar creation library.
5 * $Id: Calendar.php 3917 2009-01-21 03:06:22Z zombor $
7 * @package Calendar
8 * @author Kohana Team
9 * @copyright (c) 2007-2008 Kohana Team
10 * @license http://kohanaphp.com/license.html
12 class Calendar extends Event_Subject {
14 // Start the calendar on Sunday by default
15 public static $start_monday = FALSE;
17 // Month and year to use for calendaring
18 protected $month;
19 protected $year;
21 // Week starts on Sunday
22 protected $week_start = 0;
24 // Observed data
25 protected $observed_data;
27 /**
28 * Returns an array of the names of the days, using the current locale.
30 * @param integer left of day names
31 * @return array
33 public static function days($length = TRUE)
35 // strftime day format
36 $format = ($length > 3) ? '%A' : '%a';
38 // Days of the week
39 $days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
41 if (Calendar::$start_monday === TRUE)
43 // Push Sunday to the end of the days
44 array_push($days, array_shift($days));
47 if (strpos(Kohana::config('locale.language.0'), 'en') !== 0)
49 // This is a bit awkward, but it works properly and is reliable
50 foreach ($days as $i => $day)
52 // Convert the English names to i18n names
53 $days[$i] = strftime($format, strtotime($day));
57 if (is_int($length) OR ctype_digit($length))
59 foreach ($days as $i => $day)
61 // Shorten the days to the expected length
62 $days[$i] = utf8::substr($day, 0, $length);
66 return $days;
69 /**
70 * Create a new Calendar instance. A month and year can be specified.
71 * By default, the current month and year are used.
73 * @param integer month number
74 * @param integer year number
75 * @return object
77 public static function factory($month = NULL, $year = NULL)
79 return new Calendar($month, $year);
82 /**
83 * Create a new Calendar instance. A month and year can be specified.
84 * By default, the current month and year are used.
86 * @param integer month number
87 * @param integer year number
88 * @return void
90 public function __construct($month = NULL, $year = NULL)
92 empty($month) and $month = date('n'); // Current month
93 empty($year) and $year = date('Y'); // Current year
95 // Set the month and year
96 $this->month = (int) $month;
97 $this->year = (int) $year;
99 if (Calendar::$start_monday === TRUE)
101 // Week starts on Monday
102 $this->week_start = 1;
107 * Allows fetching the current month and year.
109 * @param string key to get
110 * @return mixed
112 public function __get($key)
114 if ($key === 'month' OR $key === 'year')
116 return $this->$key;
121 * Calendar_Event factory method.
123 * @param string unique name for the event
124 * @return object Calendar_Event
126 public function event($name = NULL)
128 return new Calendar_Event($this);
132 * Calendar_Event factory method.
134 * @chainable
135 * @param string standard event type
136 * @return object
138 public function standard($name)
140 switch ($name)
142 case 'today':
143 // Add an event for the current day
144 $this->attach($this->event()->condition('timestamp', strtotime('today'))->add_class('today'));
145 break;
146 case 'prev-next':
147 // Add an event for padding days
148 $this->attach($this->event()->condition('current', FALSE)->add_class('prev-next'));
149 break;
150 case 'holidays':
151 // Base event
152 $event = $this->event()->condition('current', TRUE)->add_class('holiday');
154 // Attach New Years
155 $holiday = clone $event;
156 $this->attach($holiday->condition('month', 1)->condition('day', 1));
158 // Attach Valentine's Day
159 $holiday = clone $event;
160 $this->attach($holiday->condition('month', 2)->condition('day', 14));
162 // Attach St. Patrick's Day
163 $holiday = clone $event;
164 $this->attach($holiday->condition('month', 3)->condition('day', 17));
166 // Attach Easter
167 $holiday = clone $event;
168 $this->attach($holiday->condition('easter', TRUE));
170 // Attach Memorial Day
171 $holiday = clone $event;
172 $this->attach($holiday->condition('month', 5)->condition('day_of_week', 1)->condition('last_occurrence', TRUE));
174 // Attach Independance Day
175 $holiday = clone $event;
176 $this->attach($holiday->condition('month', 7)->condition('day', 4));
178 // Attach Labor Day
179 $holiday = clone $event;
180 $this->attach($holiday->condition('month', 9)->condition('day_of_week', 1)->condition('occurrence', 1));
182 // Attach Halloween
183 $holiday = clone $event;
184 $this->attach($holiday->condition('month', 10)->condition('day', 31));
186 // Attach Thanksgiving
187 $holiday = clone $event;
188 $this->attach($holiday->condition('month', 11)->condition('day_of_week', 4)->condition('occurrence', 4));
190 // Attach Christmas
191 $holiday = clone $event;
192 $this->attach($holiday->condition('month', 12)->condition('day', 25));
193 break;
194 case 'weekends':
195 // Weekend events
196 $this->attach($this->event()->condition('weekend', TRUE)->add_class('weekend'));
197 break;
200 return $this;
204 * Returns an array for use with a view. The array contains an array for
205 * each week. Each week contains 7 arrays, with a day number and status:
206 * TRUE if the day is in the month, FALSE if it is padding.
208 * @return array
210 public function weeks()
212 // First day of the month as a timestamp
213 $first = mktime(1, 0, 0, $this->month, 1, $this->year);
215 // Total number of days in this month
216 $total = (int) date('t', $first);
218 // Last day of the month as a timestamp
219 $last = mktime(1, 0, 0, $this->month, $total, $this->year);
221 // Make the month and week empty arrays
222 $month = $week = array();
224 // Number of days added. When this reaches 7, start a new week
225 $days = 0;
226 $week_number = 1;
228 if (($w = (int) date('w', $first) - $this->week_start) < 0)
230 $w = 6;
233 if ($w > 0)
235 // Number of days in the previous month
236 $n = (int) date('t', mktime(1, 0, 0, $this->month - 1, 1, $this->year));
238 // i = number of day, t = number of days to pad
239 for ($i = $n - $w + 1, $t = $w; $t > 0; $t--, $i++)
241 // Notify the listeners
242 $this->notify(array($this->month - 1, $i, $this->year, $week_number, FALSE));
244 // Add previous month padding days
245 $week[] = array($i, FALSE, $this->observed_data);
246 $days++;
250 // i = number of day
251 for ($i = 1; $i <= $total; $i++)
253 if ($days % 7 === 0)
255 // Start a new week
256 $month[] = $week;
257 $week = array();
259 $week_number++;
262 // Notify the listeners
263 $this->notify(array($this->month, $i, $this->year, $week_number, TRUE));
265 // Add days to this month
266 $week[] = array($i, TRUE, $this->observed_data);
267 $days++;
270 if (($w = (int) date('w', $last) - $this->week_start) < 0)
272 $w = 6;
275 if ($w >= 0)
277 // i = number of day, t = number of days to pad
278 for ($i = 1, $t = 6 - $w; $t > 0; $t--, $i++)
280 // Notify the listeners
281 $this->notify(array($this->month + 1, $i, $this->year, $week_number, FALSE));
283 // Add next month padding days
284 $week[] = array($i, FALSE, $this->observed_data);
288 if ( ! empty($week))
290 // Append the remaining days
291 $month[] = $week;
294 return $month;
298 * Adds new data from an observer. All event data contains and array of CSS
299 * classes and an array of output messages.
301 * @param array observer data.
302 * @return void
304 public function add_data(array $data)
306 // Add new classes
307 $this->observed_data['classes'] += $data['classes'];
309 if ( ! empty($data['output']))
311 // Only add output if it's not empty
312 $this->observed_data['output'][] = $data['output'];
317 * Resets the observed data and sends a notify to all attached events.
319 * @param array UNIX timestamp
320 * @return void
322 public function notify($data)
324 // Reset observed data
325 $this->observed_data = array
327 'classes' => array(),
328 'output' => array(),
331 // Send a notify
332 parent::notify($data);
336 * Convert the calendar to HTML using the kohana_calendar view.
338 * @return string
340 public function render()
342 $view = new View('kohana_calendar', array
344 'month' => $this->month,
345 'year' => $this->year,
346 'weeks' => $this->weeks(),
349 return $view->render();
353 * Magically convert this object to a string, the rendered calendar.
355 * @return string
357 public function __toString()
359 return $this->render();
362 } // End Calendar