1
<?php
2
/**
3
* Calendar Library
4
*
5
* @author Zhou Yuan <yuanzhou19@gmail.com>
6
* @link http://www.infopotato.com/
7
* @copyright Copyright © 2009-2011 Zhou Yuan
8
* @license http://www.opensource.org/licenses/mit-license.php MIT Licence
9
*/
10
class Calendar_Library {
11
/**
12
* Calendar message
13
*
14
* @var string
15
*/
16
protected $show = array();
17
18
/**
19
* A Unix timestamp corresponding to the current time.
20
*
21
* @var string
22
*/
23
protected $local_time;
24
25
/**
26
* A string containing your calendar template.
27
*
28
* @var string
29
*/
30
protected $template = '';
31
32
/**
33
* Sets the day of the week the calendar should start on.
34
*
35
* @var string
36
*/
37
protected $start_day = 'sunday';
38
39
/**
40
* Determines what version of the month name to use in the header.
41
* long = January, short = Jan.
42
*
43
* @var string
44
*/
45
protected $month_type = 'long';
46
47
/**
48
* Determines what version of the weekday names to use in the column headers.
49
* long = Sunday, short = Sun, abr = Su.
50
*
51
* @var string
52
*/
53
protected $day_type = 'abr';
54
55
/**
56
* SDetermines whether to display links allowing you to toggle to next/previous months.
57
*
58
* @var boolean
59
*/
60
protected $show_next_prev = FALSE;
61
62
/**
63
* Sets the basepath used in the next/previous calendar links.
64
*
65
* @var string
66
*/
67
protected $next_prev_url = '';
68
69
/**
70
* Set the calendar message and sets the default time reference
71
*/
72
public function __construct(array $config = NULL) {
73
$this->show = array(
74
'cal_su' => 'Su',
75
'cal_mo' => 'Mo',
76
'cal_tu' => 'Tu',
77
'cal_we' => 'We',
78
'cal_th' => 'Th',
79
'cal_fr' => 'Fr',
80
'cal_sa' => 'Sa',
81
'cal_sun' => 'Sun',
82
'cal_mon' => 'Mon',
83
'cal_tue' => 'Tue',
84
'cal_wed' => 'Wed',
85
'cal_thu' => 'Thu',
86
'cal_fri' => 'Fri',
87
'cal_sat' => 'Sat',
88
'cal_sunday' => 'Sunday',
89
'cal_monday' => 'Monday',
90
'cal_tuesday' => 'Tuesday',
91
'cal_wednesday' => 'Wednesday',
92
'cal_thursday' => 'Thursday',
93
'cal_friday' => 'Friday',
94
'cal_saturday'=> 'Saturday',
95
'cal_jan' => 'Jan',
96
'cal_feb' => 'Feb',
97
'cal_mar' => 'Mar',
98
'cal_apr' => 'Apr',
99
'cal_may' => 'May',
100
'cal_jun' => 'Jun',
101
'cal_jul' => 'Jul',
102
'cal_aug' => 'Aug',
103
'cal_sep' => 'Sep',
104
'cal_oct' => 'Oct',
105
'cal_nov' => 'Nov',
106
'cal_dec' => 'Dec',
107
'cal_january' => 'January',
108
'cal_february' => 'February',
109
'cal_march' => 'March',
110
'cal_april' => 'April',
111
'cal_mayl' => 'May',
112
'cal_june' => 'June',
113
'cal_july' => 'July',
114
'cal_august' => 'August',
115
'cal_september' => 'September',
116
'cal_october' => 'October',
117
'cal_november' => 'November',
118
'cal_december' => 'December',
119
);
120
121
$this->local_time = time();
122
123
if (count($config) > 0) {
124
foreach ($config as $key => $val) {
125
if (isset($key)) {
126
$this->$key = $val;
127
}
128
}
129
}
130
}
131
132
/**
133
* Generate the calendar
134
*
135
* @param integer the year
136
* @param integer the month
137
* @param array the data to be shown in the calendar cells
138
* @return string
139
*/
140
public function generate($year = '', $month = '', array $data = NULL) {
141
// Set and validate the supplied month/year
142
if ($year == '') {
143
$year = date('Y', $this->local_time);
144
}
145
146
if ($month == '') {
147
$month = date('m', $this->local_time);
148
}
149
150
if (strlen($year) == 1) {
151
$year = '200'.$year;
152
}
153
154
if (strlen($year) == 2) {
155
$year = '20'.$year;
156
}
157
158
if (strlen($month) == 1) {
159
$month = '0'.$month;
160
}
161
162
$adjusted_date = $this->adjust_date($month, $year);
163
164
$month = $adjusted_date['month'];
165
$year = $adjusted_date['year'];
166
167
// Determine the total days in the month
168
$total_days = $this->get_total_days($month, $year);
169
170
// Set the starting day of the week
171
$start_days = array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);
172
$start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];
173
174
// Set the starting day number
175
$local_date = mktime(12, 0, 0, $month, 1, $year);
176
$date = getdate($local_date);
177
$day = $start_day + 1 - $date["wday"];
178
179
while ($day > 1) {
180
$day -= 7;
181
}
182
183
// Set the current month/year/day
184
// We use this to determine the "today" date
185
$cur_year = date("Y", $this->local_time);
186
$cur_month = date("m", $this->local_time);
187
$cur_day = date("j", $this->local_time);
188
189
$is_current_month = ($cur_year == $year && $cur_month == $month) ? TRUE : FALSE;
190
191
// Generate the template data array
192
$this->parse_template();
193
194
// Begin building the calendar output
195
$out = $this->temp['table_open'];
196
$out .= "\n";
197
198
$out .= "\n";
199
$out .= $this->temp['heading_row_start'];
200
$out .= "\n";
201
202
// "previous" month link
203
if ($this->show_next_prev == TRUE) {
204
// Add a trailing slash to the URL if needed
205
$this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/", $this->next_prev_url);
206
207
$adjusted_date = $this->adjust_date($month - 1, $year);
208
$out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']);
209
$out .= "\n";
210
}
211
212
// Heading containing the month/year
213
$colspan = ($this->show_next_prev == TRUE) ? 5 : 7;
214
215
$this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);
216
$this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)." ".$year, $this->temp['heading_title_cell']);
217
218
$out .= $this->temp['heading_title_cell'];
219
$out .= "\n";
220
221
// "next" month link
222
if ($this->show_next_prev == TRUE) {
223
$adjusted_date = $this->adjust_date($month + 1, $year);
224
$out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);
225
}
226
227
$out .= "\n";
228
$out .= $this->temp['heading_row_end'];
229
$out .= "\n";
230
231
// Write the cells containing the days of the week
232
$out .= "\n";
233
$out .= $this->temp['week_row_start'];
234
$out .= "\n";
235
236
$day_names = $this->get_day_names();
237
238
for ($i = 0; $i < 7; $i ++) {
239
$out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']);
240
}
241
242
$out .= "\n";
243
$out .= $this->temp['week_row_end'];
244
$out .= "\n";
245
246
// Build the main body of the calendar
247
while ($day <= $total_days) {
248
$out .= "\n";
249
$out .= $this->temp['cal_row_start'];
250
$out .= "\n";
251
252
for ($i = 0; $i < 7; $i++) {
253
$out .= ($is_current_month == TRUE && $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
254
255
if ($day > 0 && $day <= $total_days) {
256
if (isset($data[$day])) {
257
// Cells with content
258
$temp = ($is_current_month == TRUE && $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
259
$out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
260
} else {
261
// Cells with no content
262
$temp = ($is_current_month == TRUE && $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
263
$out .= str_replace('{day}', $day, $temp);
264
}
265
} else {
266
// Blank cells
267
$out .= $this->temp['cal_cell_blank'];
268
}
269
270
$out .= ($is_current_month == TRUE && $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
271
$day++;
272
}
273
274
$out .= "\n";
275
$out .= $this->temp['cal_row_end'];
276
$out .= "\n";
277
}
278
279
$out .= "\n";
280
$out .= $this->temp['table_close'];
281
282
return $out;
283
}
284
285
/**
286
* Get Month Name
287
*
288
* Generates a textual month name based on the numeric
289
* month provided.
290
*
291
* @param integer the month
292
* @return string
293
*/
294
public function get_month_name($month) {
295
if ($this->month_type == 'short') {
296
$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');
297
} else {
298
$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');
299
}
300
301
$month = $month_names[$month];
302
303
if ($this->show[$month] === FALSE) {
304
return ucfirst(str_replace('cal_', '', $month));
305
}
306
307
return $this->show[$month];
308
}
309
310
/**
311
* Get Day Names
312
*
313
* Returns an array of day names (Sunday, Monday, etc.) based
314
* on the type. Options: long, short, abrev
315
*
316
* @param string
317
* @return array
318
*/
319
public function get_day_names($day_type = '') {
320
if ($day_type != '') {
321
$this->day_type = $day_type;
322
}
323
324
if ($this->day_type == 'long') {
325
$day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
326
} elseif ($this->day_type == 'short') {
327
$day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
328
} else {
329
$day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa');
330
}
331
332
$days = array();
333
foreach ($day_names as $val) {
334
$days[] = ($this->show['cal_'.$val] === FALSE) ? ucfirst($val) : $this->show['cal_'.$val];
335
}
336
337
return $days;
338
}
339
340
/**
341
* Adjust Date
342
*
343
* This function makes sure that we have a valid month/year.
344
* For example, if you submit 13 as the month, the year will
345
* increment and the month will become January.
346
*
347
* @param integer the month
348
* @param integer the year
349
* @return array
350
*/
351
public function adjust_date($month, $year) {
352
$date = array();
353
354
$date['month'] = $month;
355
$date['year'] = $year;
356
357
while ($date['month'] > 12) {
358
$date['month'] -= 12;
359
$date['year']++;
360
}
361
362
while ($date['month'] <= 0) {
363
$date['month'] += 12;
364
$date['year']--;
365
}
366
367
if (strlen($date['month']) == 1) {
368
$date['month'] = '0'.$date['month'];
369
}
370
371
return $date;
372
}
373
374
/**
375
* Total days in a given month
376
*
377
* @param integer the month
378
* @param integer the year
379
* @return integer
380
*/
381
public function get_total_days($month, $year) {
382
$days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
383
384
if ($month < 1 || $month > 12) {
385
return 0;
386
}
387
388
// Is the year a leap year?
389
if ($month == 2) {
390
if ($year % 400 == 0 || ($year % 4 == 0 && $year % 100 != 0)) {
391
return 29;
392
}
393
}
394
395
return $days_in_month[$month - 1];
396
}
397
398
/**
399
* Set Default Template Data
400
*
401
* This is used in the event that the user has not created their own template
402
*
403
* @return array
404
*/
405
public function default_template() {
406
return array (
407
'table_open' => '<table border="0" cellpadding="0" cellspacing="0">',
408
'heading_row_start' => '<tr>',
409
'heading_previous_cell' => '<th><a href="{previous_url}"><<</a></th>',
410
'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>',
411
'heading_next_cell' => '<th><a href="{next_url}">>></a></th>',
412
'heading_row_end' => '</tr>',
413
'week_row_start' => '<tr>',
414
'week_day_cell' => '<td>{week_day}</td>',
415
'week_row_end' => '</tr>',
416
'cal_row_start' => '<tr>',
417
'cal_cell_start' => '<td>',
418
'cal_cell_start_today' => '<td>',
419
'cal_cell_content' => '<a href="{content}">{day}</a>',
420
'cal_cell_content_today' => '<a href="{content}"><strong>{day}</strong></a>',
421
'cal_cell_no_content' => '{day}',
422
'cal_cell_no_content_today' => '<strong>{day}</strong>',
423
'cal_cell_blank' => ' ',
424
'cal_cell_end' => '</td>',
425
'cal_cell_end_today' => '</td>',
426
'cal_row_end' => '</tr>',
427
'table_close' => '</table>'
428
);
429
}
430
431
/**
432
* Parse Template
433
*
434
* Harvests the data within the template {pseudo-variables}
435
* used to display the calendar
436
*
437
* @return void
438
*/
439
public function parse_template() {
440
$this->temp = $this->default_template();
441
442
if ($this->template == '') {
443
return;
444
}
445
446
$today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');
447
448
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) {
449
if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match)) {
450
$this->temp[$val] = $match['1'];
451
} else {
452
if (in_array($val, $today, TRUE)) {
453
$this->temp[$val] = $this->temp[str_replace('_today', '', $val)];
454
}
455
}
456
}
457
}
458
459
}
460
461
/* End of file: ./system/libraries/calendar/calendar_library.php */
Page URI: http://www.infopotato.com/index.php/code/library/calendar/
