source: sourcecode/system/libraries/Calendar.php @ 1

Last change on this file since 1 was 1, checked in by dungnv, 11 years ago
File size: 12.4 KB
Line 
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 */
29class 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.php', $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 */
Note: See TracBrowser for help on using the repository browser.