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