blob: f5ef4d576b539a0852b014e6b5cad7c266660e2d [file] [log] [blame]
Derek Jones37f4b9c2011-07-01 17:56:50 -05001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
28// ------------------------------------------------------------------------
29
30/**
31 * CodeIgniter Calendar Class
32 *
33 * This class enables the creation of calendars
34 *
35 * @package CodeIgniter
36 * @subpackage Libraries
37 * @category Libraries
Derek Jonesf4a4bd82011-10-20 12:18:42 -050038 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000039 * @link http://codeigniter.com/user_guide/libraries/calendar.html
40 */
41class CI_Calendar {
42
43 var $CI;
44 var $lang;
45 var $local_time;
46 var $template = '';
47 var $start_day = 'sunday';
Barry Mienydd671972010-10-04 16:33:58 +020048 var $month_type = 'long';
Derek Allard2067d1a2008-11-13 22:59:24 +000049 var $day_type = 'abr';
50 var $show_next_prev = FALSE;
51 var $next_prev_url = '';
52
53 /**
54 * Constructor
55 *
56 * Loads the calendar language file and sets the default time reference
Derek Allard2067d1a2008-11-13 22:59:24 +000057 */
Greg Akera9263282010-11-10 15:26:43 -060058 public function __construct($config = array())
Barry Mienydd671972010-10-04 16:33:58 +020059 {
Derek Allard2067d1a2008-11-13 22:59:24 +000060 $this->CI =& get_instance();
Barry Mienydd671972010-10-04 16:33:58 +020061
Greg Aker3a746652011-04-19 10:59:47 -050062 if ( ! in_array('calendar_lang.php', $this->CI->lang->is_loaded, TRUE))
Derek Allard2067d1a2008-11-13 22:59:24 +000063 {
64 $this->CI->lang->load('calendar');
65 }
66
67 $this->local_time = time();
Barry Mienydd671972010-10-04 16:33:58 +020068
Derek Allard2067d1a2008-11-13 22:59:24 +000069 if (count($config) > 0)
70 {
71 $this->initialize($config);
72 }
Barry Mienydd671972010-10-04 16:33:58 +020073
Derek Allard2067d1a2008-11-13 22:59:24 +000074 log_message('debug', "Calendar Class Initialized");
75 }
Barry Mienydd671972010-10-04 16:33:58 +020076
Derek Allard2067d1a2008-11-13 22:59:24 +000077 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +020078
Derek Allard2067d1a2008-11-13 22:59:24 +000079 /**
80 * Initialize the user preferences
81 *
82 * Accepts an associative array as input, containing display preferences
83 *
84 * @access public
85 * @param array config preferences
86 * @return void
Barry Mienydd671972010-10-04 16:33:58 +020087 */
Derek Allard2067d1a2008-11-13 22:59:24 +000088 function initialize($config = array())
89 {
90 foreach ($config as $key => $val)
91 {
92 if (isset($this->$key))
93 {
94 $this->$key = $val;
95 }
96 }
97 }
Barry Mienydd671972010-10-04 16:33:58 +020098
Derek Allard2067d1a2008-11-13 22:59:24 +000099 // --------------------------------------------------------------------
100
101 /**
102 * Generate the calendar
103 *
104 * @access public
105 * @param integer the year
106 * @param integer the month
107 * @param array the data to be shown in the calendar cells
108 * @return string
109 */
110 function generate($year = '', $month = '', $data = array())
111 {
112 // Set and validate the supplied month/year
113 if ($year == '')
Derek Jones37f4b9c2011-07-01 17:56:50 -0500114 $year = date("Y", $this->local_time);
Barry Mienydd671972010-10-04 16:33:58 +0200115
Derek Allard2067d1a2008-11-13 22:59:24 +0000116 if ($month == '')
117 $month = date("m", $this->local_time);
Barry Mienydd671972010-10-04 16:33:58 +0200118
119 if (strlen($year) == 1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000120 $year = '200'.$year;
Barry Mienydd671972010-10-04 16:33:58 +0200121
122 if (strlen($year) == 2)
Derek Allard2067d1a2008-11-13 22:59:24 +0000123 $year = '20'.$year;
124
Barry Mienydd671972010-10-04 16:33:58 +0200125 if (strlen($month) == 1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000126 $month = '0'.$month;
Barry Mienydd671972010-10-04 16:33:58 +0200127
Derek Allard2067d1a2008-11-13 22:59:24 +0000128 $adjusted_date = $this->adjust_date($month, $year);
Barry Mienydd671972010-10-04 16:33:58 +0200129
Derek Allard2067d1a2008-11-13 22:59:24 +0000130 $month = $adjusted_date['month'];
131 $year = $adjusted_date['year'];
Barry Mienydd671972010-10-04 16:33:58 +0200132
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 // Determine the total days in the month
134 $total_days = $this->get_total_days($month, $year);
Barry Mienydd671972010-10-04 16:33:58 +0200135
Derek Allard2067d1a2008-11-13 22:59:24 +0000136 // Set the starting day of the week
137 $start_days = array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);
138 $start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];
Barry Mienydd671972010-10-04 16:33:58 +0200139
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 // Set the starting day number
141 $local_date = mktime(12, 0, 0, $month, 1, $year);
142 $date = getdate($local_date);
Derek Jones37f4b9c2011-07-01 17:56:50 -0500143 $day = $start_day + 1 - $date["wday"];
Barry Mienydd671972010-10-04 16:33:58 +0200144
Derek Allard2067d1a2008-11-13 22:59:24 +0000145 while ($day > 1)
146 {
147 $day -= 7;
148 }
Barry Mienydd671972010-10-04 16:33:58 +0200149
Derek Allard2067d1a2008-11-13 22:59:24 +0000150 // Set the current month/year/day
151 // We use this to determine the "today" date
152 $cur_year = date("Y", $this->local_time);
153 $cur_month = date("m", $this->local_time);
154 $cur_day = date("j", $this->local_time);
Barry Mienydd671972010-10-04 16:33:58 +0200155
Derek Allard2067d1a2008-11-13 22:59:24 +0000156 $is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200157
Derek Allard2067d1a2008-11-13 22:59:24 +0000158 // Generate the template data array
159 $this->parse_template();
Derek Allard2067d1a2008-11-13 22:59:24 +0000160
Barry Mienydd671972010-10-04 16:33:58 +0200161 // Begin building the calendar output
162 $out = $this->temp['table_open'];
163 $out .= "\n";
164
165 $out .= "\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000166 $out .= $this->temp['heading_row_start'];
167 $out .= "\n";
Barry Mienydd671972010-10-04 16:33:58 +0200168
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 // "previous" month link
170 if ($this->show_next_prev == TRUE)
171 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500172 // Add a trailing slash to the URL if needed
173 $this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/", $this->next_prev_url);
Barry Mienydd671972010-10-04 16:33:58 +0200174
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 $adjusted_date = $this->adjust_date($month - 1, $year);
176 $out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']);
177 $out .= "\n";
178 }
179
180 // Heading containing the month/year
181 $colspan = ($this->show_next_prev == TRUE) ? 5 : 7;
Barry Mienydd671972010-10-04 16:33:58 +0200182
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 $this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);
184 $this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)."&nbsp;".$year, $this->temp['heading_title_cell']);
Barry Mienydd671972010-10-04 16:33:58 +0200185
Derek Allard2067d1a2008-11-13 22:59:24 +0000186 $out .= $this->temp['heading_title_cell'];
187 $out .= "\n";
188
189 // "next" month link
190 if ($this->show_next_prev == TRUE)
Barry Mienydd671972010-10-04 16:33:58 +0200191 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 $adjusted_date = $this->adjust_date($month + 1, $year);
193 $out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);
194 }
195
Barry Mienydd671972010-10-04 16:33:58 +0200196 $out .= "\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 $out .= $this->temp['heading_row_end'];
198 $out .= "\n";
199
200 // Write the cells containing the days of the week
Barry Mienydd671972010-10-04 16:33:58 +0200201 $out .= "\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000202 $out .= $this->temp['week_row_start'];
203 $out .= "\n";
204
205 $day_names = $this->get_day_names();
206
207 for ($i = 0; $i < 7; $i ++)
208 {
209 $out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']);
210 }
211
212 $out .= "\n";
213 $out .= $this->temp['week_row_end'];
214 $out .= "\n";
215
216 // Build the main body of the calendar
217 while ($day <= $total_days)
218 {
219 $out .= "\n";
220 $out .= $this->temp['cal_row_start'];
221 $out .= "\n";
222
223 for ($i = 0; $i < 7; $i++)
224 {
225 $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
Barry Mienydd671972010-10-04 16:33:58 +0200226
Derek Allard2067d1a2008-11-13 22:59:24 +0000227 if ($day > 0 AND $day <= $total_days)
Barry Mienydd671972010-10-04 16:33:58 +0200228 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000229 if (isset($data[$day]))
Barry Mienydd671972010-10-04 16:33:58 +0200230 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 // Cells with content
232 $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
233 $out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
234 }
235 else
236 {
237 // Cells with no content
238 $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
239 $out .= str_replace('{day}', $day, $temp);
240 }
241 }
242 else
243 {
244 // Blank cells
245 $out .= $this->temp['cal_cell_blank'];
246 }
Barry Mienydd671972010-10-04 16:33:58 +0200247
Derek Jones37f4b9c2011-07-01 17:56:50 -0500248 $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000249 $day++;
250 }
Barry Mienydd671972010-10-04 16:33:58 +0200251
252 $out .= "\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000253 $out .= $this->temp['cal_row_end'];
Barry Mienydd671972010-10-04 16:33:58 +0200254 $out .= "\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 }
256
Barry Mienydd671972010-10-04 16:33:58 +0200257 $out .= "\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000258 $out .= $this->temp['table_close'];
259
260 return $out;
261 }
Barry Mienydd671972010-10-04 16:33:58 +0200262
Derek Allard2067d1a2008-11-13 22:59:24 +0000263 // --------------------------------------------------------------------
264
265 /**
266 * Get Month Name
267 *
268 * Generates a textual month name based on the numeric
269 * month provided.
270 *
271 * @access public
272 * @param integer the month
273 * @return string
274 */
275 function get_month_name($month)
276 {
277 if ($this->month_type == 'short')
278 {
279 $month_names = array('01' => 'cal_jan', '02' => 'cal_feb', '03' => 'cal_mar', '04' => 'cal_apr', '05' => 'cal_may', '06' => 'cal_jun', '07' => 'cal_jul', '08' => 'cal_aug', '09' => 'cal_sep', '10' => 'cal_oct', '11' => 'cal_nov', '12' => 'cal_dec');
280 }
281 else
282 {
Derek Allarddefaa172009-08-17 17:24:31 +0000283 $month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_mayl', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december');
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 }
Barry Mienydd671972010-10-04 16:33:58 +0200285
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 $month = $month_names[$month];
Barry Mienydd671972010-10-04 16:33:58 +0200287
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 if ($this->CI->lang->line($month) === FALSE)
289 {
290 return ucfirst(str_replace('cal_', '', $month));
291 }
292
293 return $this->CI->lang->line($month);
294 }
Barry Mienydd671972010-10-04 16:33:58 +0200295
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 // --------------------------------------------------------------------
297
298 /**
299 * Get Day Names
300 *
301 * Returns an array of day names (Sunday, Monday, etc.) based
Derek Jones37f4b9c2011-07-01 17:56:50 -0500302 * on the type. Options: long, short, abrev
Derek Allard2067d1a2008-11-13 22:59:24 +0000303 *
304 * @access public
305 * @param string
306 * @return array
307 */
308 function get_day_names($day_type = '')
309 {
310 if ($day_type != '')
311 $this->day_type = $day_type;
Barry Mienydd671972010-10-04 16:33:58 +0200312
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 if ($this->day_type == 'long')
314 {
315 $day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
316 }
317 elseif ($this->day_type == 'short')
318 {
319 $day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
320 }
321 else
322 {
323 $day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa');
324 }
Barry Mienydd671972010-10-04 16:33:58 +0200325
Derek Allard2067d1a2008-11-13 22:59:24 +0000326 $days = array();
327 foreach ($day_names as $val)
Barry Mienydd671972010-10-04 16:33:58 +0200328 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 $days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val);
330 }
Barry Mienydd671972010-10-04 16:33:58 +0200331
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 return $days;
333 }
Barry Mienydd671972010-10-04 16:33:58 +0200334
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 // --------------------------------------------------------------------
336
337 /**
338 * Adjust Date
339 *
340 * This function makes sure that we have a valid month/year.
341 * For example, if you submit 13 as the month, the year will
342 * increment and the month will become January.
343 *
344 * @access public
345 * @param integer the month
346 * @param integer the year
347 * @return array
348 */
349 function adjust_date($month, $year)
350 {
351 $date = array();
352
353 $date['month'] = $month;
354 $date['year'] = $year;
355
356 while ($date['month'] > 12)
357 {
358 $date['month'] -= 12;
359 $date['year']++;
360 }
361
362 while ($date['month'] <= 0)
363 {
364 $date['month'] += 12;
365 $date['year']--;
366 }
367
368 if (strlen($date['month']) == 1)
369 {
370 $date['month'] = '0'.$date['month'];
371 }
372
373 return $date;
374 }
Barry Mienydd671972010-10-04 16:33:58 +0200375
Derek Allard2067d1a2008-11-13 22:59:24 +0000376 // --------------------------------------------------------------------
377
378 /**
379 * Total days in a given month
380 *
381 * @access public
382 * @param integer the month
383 * @param integer the year
384 * @return integer
385 */
386 function get_total_days($month, $year)
387 {
388 $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
389
390 if ($month < 1 OR $month > 12)
391 {
392 return 0;
393 }
394
395 // Is the year a leap year?
396 if ($month == 2)
397 {
398 if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))
399 {
400 return 29;
401 }
402 }
403
404 return $days_in_month[$month - 1];
405 }
Barry Mienydd671972010-10-04 16:33:58 +0200406
Derek Allard2067d1a2008-11-13 22:59:24 +0000407 // --------------------------------------------------------------------
408
409 /**
410 * Set Default Template Data
411 *
412 * This is used in the event that the user has not created their own template
413 *
414 * @access public
415 * @return array
416 */
417 function default_template()
418 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500419 return array (
Barry Mienydd671972010-10-04 16:33:58 +0200420 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
421 'heading_row_start' => '<tr>',
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 'heading_previous_cell' => '<th><a href="{previous_url}">&lt;&lt;</a></th>',
Barry Mienydd671972010-10-04 16:33:58 +0200423 'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>',
424 'heading_next_cell' => '<th><a href="{next_url}">&gt;&gt;</a></th>',
425 'heading_row_end' => '</tr>',
426 'week_row_start' => '<tr>',
427 'week_day_cell' => '<td>{week_day}</td>',
428 'week_row_end' => '</tr>',
429 'cal_row_start' => '<tr>',
430 'cal_cell_start' => '<td>',
Derek Allard2067d1a2008-11-13 22:59:24 +0000431 'cal_cell_start_today' => '<td>',
432 'cal_cell_content' => '<a href="{content}">{day}</a>',
433 'cal_cell_content_today' => '<a href="{content}"><strong>{day}</strong></a>',
434 'cal_cell_no_content' => '{day}',
435 'cal_cell_no_content_today' => '<strong>{day}</strong>',
436 'cal_cell_blank' => '&nbsp;',
437 'cal_cell_end' => '</td>',
438 'cal_cell_end_today' => '</td>',
439 'cal_row_end' => '</tr>',
440 'table_close' => '</table>'
Barry Mienydd671972010-10-04 16:33:58 +0200441 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000442 }
Barry Mienydd671972010-10-04 16:33:58 +0200443
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 // --------------------------------------------------------------------
445
446 /**
447 * Parse Template
448 *
449 * Harvests the data within the template {pseudo-variables}
450 * used to display the calendar
451 *
452 * @access public
453 * @return void
454 */
Barry Mienydd671972010-10-04 16:33:58 +0200455 function parse_template()
456 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000457 $this->temp = $this->default_template();
Barry Mienydd671972010-10-04 16:33:58 +0200458
459 if ($this->template == '')
460 {
461 return;
462 }
463
Derek Allard2067d1a2008-11-13 22:59:24 +0000464 $today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');
Barry Mienydd671972010-10-04 16:33:58 +0200465
Derek Jones37f4b9c2011-07-01 17:56:50 -0500466 foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 {
468 if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match))
469 {
470 $this->temp[$val] = $match['1'];
471 }
472 else
473 {
474 if (in_array($val, $today, TRUE))
475 {
476 $this->temp[$val] = $this->temp[str_replace('_today', '', $val)];
477 }
478 }
Barry Mienydd671972010-10-04 16:33:58 +0200479 }
480 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000481
482}
483
484// END CI_Calendar class
485
486/* End of file Calendar.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +0000487/* Location: ./system/libraries/Calendar.php */