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