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