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