blob: 23a6bf791eaa7dd18a7a77ff7acd0053d0030f9e [file] [log] [blame]
adminb0dd10f2006-08-25 17:25:49 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * Code Igniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, pMachine, Inc.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Code Igniter Calendar Class
20 *
21 * This class enables the creation of calendars
22 *
23 * @package CodeIgniter
24 * @subpackage Libraries
25 * @category Libraries
26 * @author Rick Ellis
27 * @link http://www.codeigniter.com/user_guide/libraries/calendar.html
admine79dc712006-09-26 03:52:45 +000028 */
adminb0dd10f2006-08-25 17:25:49 +000029class CI_Calendar {
30
adminb3ab70b2006-10-07 03:07:29 +000031 var $CI;
adminb0dd10f2006-08-25 17:25:49 +000032 var $lang;
adminb0dd10f2006-08-25 17:25:49 +000033 var $local_time;
34 var $template = '';
35 var $start_day = 'sunday';
36 var $month_type = 'long';
37 var $day_type = 'abr';
38 var $show_next_prev = FALSE;
39 var $next_prev_url = '';
40
41 /**
42 * Constructor
43 *
44 * Loads the calendar language file and sets the default time reference
45 *
46 * @access public
47 */
48 function CI_Calendar()
49 {
adminb3ab70b2006-10-07 03:07:29 +000050 $this->CI =& get_instance();
admin10c3f412006-10-08 07:21:12 +000051
adminb3ab70b2006-10-07 03:07:29 +000052 if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE))
adminb0dd10f2006-08-25 17:25:49 +000053 {
adminb3ab70b2006-10-07 03:07:29 +000054 $this->CI->lang->load('calendar');
adminb0dd10f2006-08-25 17:25:49 +000055 }
56
57 $this->local_time = time();
58 log_message('debug', "Calendar Class Initialized");
59 }
adminb0dd10f2006-08-25 17:25:49 +000060
61 // --------------------------------------------------------------------
62
63 /**
64 * Initialize the user preferences
65 *
66 * Accepts an associative array as input, containing display preferences
67 *
68 * @access public
69 * @param array config preferences
70 * @return void
71 */
72 function initialize($config = array())
73 {
74 foreach ($config as $key => $val)
75 {
76 if (isset($this->$key))
77 {
78 $this->$key = $val;
79 }
80 }
81 }
adminb0dd10f2006-08-25 17:25:49 +000082
83 // --------------------------------------------------------------------
84
85 /**
86 * Generate the calendar
87 *
88 * @access public
89 * @param integer the year
90 * @param integer the month
91 * @param array the data to be shown in the calendar cells
92 * @return string
93 */
94 function generate($year = '', $month = '', $data = array())
95 {
96 // Set and validate the supplied month/year
97 if ($year == '')
98 $year = date("Y", $this->local_time);
99
100 if ($month == '')
101 $month = date("m", $this->local_time);
102
103 if (strlen($year) == 1)
104 $year = '200'.$year;
105
106 if (strlen($year) == 2)
107 $year = '20'.$year;
108
109 if (strlen($month) == 1)
110 $month = '0'.$month;
111
112 $adjusted_date = $this->adjust_date($month, $year);
113
114 $month = $adjusted_date['month'];
115 $year = $adjusted_date['year'];
116
117 // Determine the total days in the month
118 $total_days = $this->get_total_days($month, $year);
119
120 // Set the starting day of the week
121 $start_days = array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);
122 $start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];
123
124 // Set the starting day number
125 $local_date = mktime(12, 0, 0, $month, 1, $year);
126 $date = getdate($local_date);
127 $day = $start_day + 1 - $date["wday"];
128
129 while ($day > 1)
130 {
131 $day -= 7;
132 }
133
134 // Set the current month/year/day
135 // We use this to determine the "today" date
136 $cur_year = date("Y", $this->local_time);
137 $cur_month = date("m", $this->local_time);
138 $cur_day = date("j", $this->local_time);
139
140 $is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;
141
142 // Generate the template data array
143 $this->parse_template();
144
145 // Begin building the calendar output
146 $out = $this->temp['table_open'];
147 $out .= "\n";
148
149 $out .= "\n";
150 $out .= $this->temp['heading_row_start'];
151 $out .= "\n";
152
153 // "previous" month link
154 if ($this->show_next_prev == TRUE)
155 {
156 $adjusted_date = $this->adjust_date($month - 1, $year);
157 $out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']);
158 $out .= "\n";
159 }
160
161 // Heading containing the month/year
162 $colspan = ($this->show_next_prev == TRUE) ? 5 : 7;
163
164 $this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);
165 $this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)."&nbsp;".$year, $this->temp['heading_title_cell']);
166
167 $out .= $this->temp['heading_title_cell'];
168 $out .= "\n";
169
170 // "next" month link
171 if ($this->show_next_prev == TRUE)
172 {
173 $adjusted_date = $this->adjust_date($month + 1, $year);
174 $out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);
175 }
176
177 $out .= "\n";
178 $out .= $this->temp['heading_row_end'];
179 $out .= "\n";
180
181 // Write the cells containing the days of the week
182 $out .= "\n";
183 $out .= $this->temp['week_row_start'];
184 $out .= "\n";
185
186 $day_names = $this->get_day_names();
187
188 for ($i = 0; $i < 7; $i ++)
189 {
190 $out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']);
191 }
192
193 $out .= "\n";
194 $out .= $this->temp['week_row_end'];
195 $out .= "\n";
196
197 // Build the main body of the calendar
198 while ($day <= $total_days)
199 {
200 $out .= "\n";
201 $out .= $this->temp['cal_row_start'];
202 $out .= "\n";
203
204 for ($i = 0; $i < 7; $i++)
205 {
206 $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
207
208 if ($day > 0 AND $day <= $total_days)
209 {
210 if (isset($data[$day]))
211 {
212 // Cells with content
213 $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
214 $out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
215 }
216 else
217 {
218 // Cells with no content
219 $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
220 $out .= str_replace('{day}', $day, $temp);
221 }
222 }
223 else
224 {
225 // Blank cells
226 $out .= $this->temp['cal_cell_blank'];
227 }
228
229 $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
230 $day++;
231 }
232
233 $out .= "\n";
234 $out .= $this->temp['cal_row_end'];
235 $out .= "\n";
236 }
237
238 $out .= "\n";
239 $out .= $this->temp['table_close'];
240
241 return $out;
242 }
adminb0dd10f2006-08-25 17:25:49 +0000243
244 // --------------------------------------------------------------------
245
246 /**
247 * Get Month Name
248 *
249 * Generates a texual month name based on the numeric
250 * month provided.
251 *
252 * @access public
253 * @parm integer the month
254 * @return string
255 */
256 function get_month_name($month)
257 {
258 if ($this->month_type == 'short')
259 {
260 $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');
261 }
262 else
263 {
adminb071bb52006-08-26 19:28:37 +0000264 $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');
adminb0dd10f2006-08-25 17:25:49 +0000265 }
266
267 $month = $month_names[$month];
268
adminb3ab70b2006-10-07 03:07:29 +0000269 if ($this->CI->lang->line($month) === FALSE)
adminb0dd10f2006-08-25 17:25:49 +0000270 {
271 return ucfirst(str_replace('cal_', '', $month));
272 }
273
adminb3ab70b2006-10-07 03:07:29 +0000274 return $this->CI->lang->line($month);
adminb0dd10f2006-08-25 17:25:49 +0000275 }
adminb0dd10f2006-08-25 17:25:49 +0000276
277 // --------------------------------------------------------------------
278
279 /**
280 * Get Day Names
281 *
282 * Returns an array of day names (Sunday, Monday, etc.) based
283 * on the type. Options: long, short, abrev
284 *
285 * @access public
286 * @param string
287 * @return array
288 */
289 function get_day_names($day_type = '')
290 {
291 if ($day_type != '')
292 $this->day_type = $day_type;
293
294 if ($this->day_type == 'long')
295 {
296 $day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
297 }
298 elseif ($this->day_type == 'short')
299 {
300 $day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
301 }
302 else
303 {
304 $day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa');
305 }
306
307 $days = array();
308 foreach ($day_names as $val)
309 {
adminb3ab70b2006-10-07 03:07:29 +0000310 $days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val);
adminb0dd10f2006-08-25 17:25:49 +0000311 }
312
313 return $days;
314 }
adminb0dd10f2006-08-25 17:25:49 +0000315
316 // --------------------------------------------------------------------
317
318 /**
319 * Adjust Date
320 *
321 * This function makes sure that we have a valid month/year.
322 * For example, if you submit 13 as the month, the year will
323 * increment and the month will become January.
324 *
325 * @access public
326 * @param integer the month
327 * @param integer the year
328 * @return array
329 */
330 function adjust_date($month, $year)
331 {
332 $date = array();
333
334 $date['month'] = $month;
335 $date['year'] = $year;
336
337 while ($date['month'] > 12)
338 {
339 $date['month'] -= 12;
340 $date['year']++;
341 }
342
343 while ($date['month'] <= 0)
344 {
345 $date['month'] += 12;
346 $date['year']--;
347 }
348
349 if (strlen($date['month']) == 1)
350 {
351 $date['month'] = '0'.$date['month'];
352 }
353
354 return $date;
355 }
adminb0dd10f2006-08-25 17:25:49 +0000356
357 // --------------------------------------------------------------------
358
359 /**
360 * Total days in a given month
361 *
362 * @access public
363 * @param integer the month
364 * @param integer the year
365 * @return integer
366 */
367 function get_total_days($month, $year)
368 {
369 $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
370
371 if ($month < 1 OR $month > 12)
372 {
373 return 0;
374 }
375
admin10c3f412006-10-08 07:21:12 +0000376 // Is the year a leap year?
adminb0dd10f2006-08-25 17:25:49 +0000377 if ($month == 2)
378 {
379 if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))
380 {
381 return 29;
382 }
383 }
384
385 return $days_in_month[$month - 1];
386 }
adminb0dd10f2006-08-25 17:25:49 +0000387
388 // --------------------------------------------------------------------
389
390 /**
391 * Set Default Template Data
392 *
393 * This is used in the event that the user has not created their own template
394 *
395 * @access public
396 * @return array
397 */
398 function default_template()
399 {
400 return array (
401 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
402 'heading_row_start' => '<tr>',
403 'heading_previous_cell' => '<th><a href="{previous_url}">&lt;&lt;</a></th>',
404 'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>',
405 'heading_next_cell' => '<th><a href="{next_url}">&gt;&gt;</a></th>',
406 'heading_row_end' => '</tr>',
407 'week_row_start' => '<tr>',
408 'week_day_cell' => '<td>{week_day}</td>',
409 'week_row_end' => '</tr>',
410 'cal_row_start' => '<tr>',
411 'cal_cell_start' => '<td>',
412 'cal_cell_start_today' => '<td>',
413 'cal_cell_content' => '<a href="{content}">{day}</a>',
414 'cal_cell_content_today' => '<a href="{content}"><strong>{day}</strong></a>',
415 'cal_cell_no_content' => '{day}',
416 'cal_cell_no_content_today' => '<strong>{day}</strong>',
417 'cal_cell_blank' => '&nbsp;',
418 'cal_cell_end' => '</td>',
419 'cal_cell_end_today' => '</td>',
420 'cal_row_end' => '</tr>',
421 'table_close' => '</table>'
422 );
423 }
adminb0dd10f2006-08-25 17:25:49 +0000424
425 // --------------------------------------------------------------------
426
427 /**
428 * Parse Template
429 *
430 * Harvests the data within the template {pseudo-variables}
431 * used to display the calendar
432 *
433 * @access public
434 * @return void
435 */
436 function parse_template()
437 {
438 $this->temp = $this->default_template();
439
440 if ($this->template == '')
441 {
442 return;
443 }
444
445 $today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');
446
447 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)
448 {
449 if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match))
450 {
451 $this->temp[$val] = $match['1'];
452 }
453 else
454 {
adminee54c112006-09-28 17:13:38 +0000455 if (in_array($val, $today, TRUE))
adminb0dd10f2006-08-25 17:25:49 +0000456 {
457 $this->temp[$val] = $this->temp[str_replace('_today', '', $val)];
458 }
459 }
460 }
461 }
adminb0dd10f2006-08-25 17:25:49 +0000462
463}
464
465// END CI_Calendar class
466?>