Subversion-Projekte lars-tiefland.ci

Revision

Revision 2257 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
68 lars 1
<?php
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP
6
 *
7
 * This content is released under the MIT License (MIT)
8
 *
2414 lars 9
 * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
68 lars 10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a copy
12
 * of this software and associated documentation files (the "Software"), to deal
13
 * in the Software without restriction, including without limitation the rights
14
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
 * copies of the Software, and to permit persons to whom the Software is
16
 * furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies or substantial portions of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
 * THE SOFTWARE.
28
 *
29
 * @package	CodeIgniter
30
 * @author	EllisLab Dev Team
31
 * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
2414 lars 32
 * @copyright	Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
33
 * @license	https://opensource.org/licenses/MIT	MIT License
68 lars 34
 * @link	https://codeigniter.com
35
 * @since	Version 1.0.0
36
 * @filesource
37
 */
38
defined('BASEPATH') OR exit('No direct script access allowed');
39
 
40
/**
41
 * CodeIgniter Calendar Class
42
 *
43
 * This class enables the creation of calendars
44
 *
45
 * @package		CodeIgniter
46
 * @subpackage	Libraries
47
 * @category	Libraries
48
 * @author		EllisLab Dev Team
49
 * @link		https://codeigniter.com/user_guide/libraries/calendar.html
50
 */
51
class CI_Calendar {
52
 
53
	/**
54
	 * Calendar layout template
55
	 *
56
	 * @var mixed
57
	 */
58
	public $template = '';
59
 
60
	/**
61
	 * Replacements array for template
62
	 *
63
	 * @var array
64
	 */
65
	public $replacements = array();
66
 
67
	/**
68
	 * Day of the week to start the calendar on
69
	 *
70
	 * @var string
71
	 */
72
	public $start_day = 'sunday';
73
 
74
	/**
75
	 * How to display months
76
	 *
77
	 * @var string
78
	 */
79
	public $month_type = 'long';
80
 
81
	/**
82
	 * How to display names of days
83
	 *
84
	 * @var string
85
	 */
86
	public $day_type = 'abr';
87
 
88
	/**
89
	 * Whether to show next/prev month links
90
	 *
91
	 * @var bool
92
	 */
93
	public $show_next_prev = FALSE;
94
 
95
	/**
96
	 * Url base to use for next/prev month links
97
	 *
98
	 * @var bool
99
	 */
100
	public $next_prev_url = '';
101
 
102
	/**
103
	 * Show days of other months
104
	 *
105
	 * @var bool
106
	 */
107
	public $show_other_days = FALSE;
108
 
109
	// --------------------------------------------------------------------
110
 
111
	/**
112
	 * CI Singleton
113
	 *
114
	 * @var object
115
	 */
116
	protected $CI;
117
 
118
	// --------------------------------------------------------------------
119
 
120
	/**
121
	 * Class constructor
122
	 *
123
	 * Loads the calendar language file and sets the default time reference.
124
	 *
125
	 * @uses	CI_Lang::$is_loaded
126
	 *
127
	 * @param	array	$config	Calendar options
128
	 * @return	void
129
	 */
130
	public function __construct($config = array())
131
	{
132
		$this->CI =& get_instance();
133
		$this->CI->lang->load('calendar');
134
 
135
		empty($config) OR $this->initialize($config);
136
 
137
		log_message('info', 'Calendar Class Initialized');
138
	}
139
 
140
	// --------------------------------------------------------------------
141
 
142
	/**
143
	 * Initialize the user preferences
144
	 *
145
	 * Accepts an associative array as input, containing display preferences
146
	 *
147
	 * @param	array	config preferences
148
	 * @return	CI_Calendar
149
	 */
150
	public function initialize($config = array())
151
	{
152
		foreach ($config as $key => $val)
153
		{
154
			if (isset($this->$key))
155
			{
156
				$this->$key = $val;
157
			}
158
		}
159
 
160
		// Set the next_prev_url to the controller if required but not defined
161
		if ($this->show_next_prev === TRUE && empty($this->next_prev_url))
162
		{
163
			$this->next_prev_url = $this->CI->config->site_url($this->CI->router->class.'/'.$this->CI->router->method);
164
		}
165
 
166
		return $this;
167
	}
168
 
169
	// --------------------------------------------------------------------
170
 
171
	/**
172
	 * Generate the calendar
173
	 *
174
	 * @param	int	the year
175
	 * @param	int	the month
176
	 * @param	array	the data to be shown in the calendar cells
177
	 * @return	string
178
	 */
179
	public function generate($year = '', $month = '', $data = array())
180
	{
181
		$local_time = time();
182
 
183
		// Set and validate the supplied month/year
184
		if (empty($year))
185
		{
186
			$year = date('Y', $local_time);
187
		}
188
		elseif (strlen($year) === 1)
189
		{
190
			$year = '200'.$year;
191
		}
192
		elseif (strlen($year) === 2)
193
		{
194
			$year = '20'.$year;
195
		}
196
 
197
		if (empty($month))
198
		{
199
			$month = date('m', $local_time);
200
		}
201
		elseif (strlen($month) === 1)
202
		{
203
			$month = '0'.$month;
204
		}
205
 
206
		$adjusted_date = $this->adjust_date($month, $year);
207
 
208
		$month	= $adjusted_date['month'];
209
		$year	= $adjusted_date['year'];
210
 
211
		// Determine the total days in the month
212
		$total_days = $this->get_total_days($month, $year);
213
 
214
		// Set the starting day of the week
215
		$start_days	= array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);
216
		$start_day	= isset($start_days[$this->start_day]) ? $start_days[$this->start_day] : 0;
217
 
218
		// Set the starting day number
219
		$local_date = mktime(12, 0, 0, $month, 1, $year);
220
		$date = getdate($local_date);
221
		$day  = $start_day + 1 - $date['wday'];
222
 
223
		while ($day > 1)
224
		{
225
			$day -= 7;
226
		}
227
 
228
		// Set the current month/year/day
229
		// We use this to determine the "today" date
230
		$cur_year	= date('Y', $local_time);
231
		$cur_month	= date('m', $local_time);
232
		$cur_day	= date('j', $local_time);
233
 
234
		$is_current_month = ($cur_year == $year && $cur_month == $month);
235
 
236
		// Generate the template data array
237
		$this->parse_template();
238
 
239
		// Begin building the calendar output
240
		$out = $this->replacements['table_open']."\n\n".$this->replacements['heading_row_start']."\n";
241
 
242
		// "previous" month link
243
		if ($this->show_next_prev === TRUE)
244
		{
245
			// Add a trailing slash to the URL if needed
246
			$this->next_prev_url = preg_replace('/(.+?)\/*$/', '\\1/', $this->next_prev_url);
247
 
248
			$adjusted_date = $this->adjust_date($month - 1, $year);
249
			$out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->replacements['heading_previous_cell'])."\n";
250
		}
251
 
252
		// Heading containing the month/year
253
		$colspan = ($this->show_next_prev === TRUE) ? 5 : 7;
254
 
255
		$this->replacements['heading_title_cell'] = str_replace('{colspan}', $colspan,
256
								str_replace('{heading}', $this->get_month_name($month).'&nbsp;'.$year, $this->replacements['heading_title_cell']));
257
 
258
		$out .= $this->replacements['heading_title_cell']."\n";
259
 
260
		// "next" month link
261
		if ($this->show_next_prev === TRUE)
262
		{
263
			$adjusted_date = $this->adjust_date($month + 1, $year);
264
			$out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->replacements['heading_next_cell']);
265
		}
266
 
267
		$out .= "\n".$this->replacements['heading_row_end']."\n\n"
268
			// Write the cells containing the days of the week
269
			.$this->replacements['week_row_start']."\n";
270
 
271
		$day_names = $this->get_day_names();
272
 
273
		for ($i = 0; $i < 7; $i ++)
274
		{
275
			$out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->replacements['week_day_cell']);
276
		}
277
 
278
		$out .= "\n".$this->replacements['week_row_end']."\n";
279
 
280
		// Build the main body of the calendar
281
		while ($day <= $total_days)
282
		{
283
			$out .= "\n".$this->replacements['cal_row_start']."\n";
284
 
285
			for ($i = 0; $i < 7; $i++)
286
			{
287
				if ($day > 0 && $day <= $total_days)
288
				{
289
					$out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->replacements['cal_cell_start_today'] : $this->replacements['cal_cell_start'];
290
 
291
					if (isset($data[$day]))
292
					{
293
						// Cells with content
294
						$temp = ($is_current_month === TRUE && $day == $cur_day) ?
295
								$this->replacements['cal_cell_content_today'] : $this->replacements['cal_cell_content'];
296
						$out .= str_replace(array('{content}', '{day}'), array($data[$day], $day), $temp);
297
					}
298
					else
299
					{
300
						// Cells with no content
301
						$temp = ($is_current_month === TRUE && $day == $cur_day) ?
302
								$this->replacements['cal_cell_no_content_today'] : $this->replacements['cal_cell_no_content'];
303
						$out .= str_replace('{day}', $day, $temp);
304
					}
305
 
306
					$out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->replacements['cal_cell_end_today'] : $this->replacements['cal_cell_end'];
307
				}
308
				elseif ($this->show_other_days === TRUE)
309
				{
310
					$out .= $this->replacements['cal_cell_start_other'];
311
 
312
					if ($day <= 0)
313
					{
314
						// Day of previous month
315
						$prev_month = $this->adjust_date($month - 1, $year);
316
						$prev_month_days = $this->get_total_days($prev_month['month'], $prev_month['year']);
317
						$out .= str_replace('{day}', $prev_month_days + $day, $this->replacements['cal_cell_other']);
318
					}
319
					else
320
					{
321
						// Day of next month
322
						$out .= str_replace('{day}', $day - $total_days, $this->replacements['cal_cell_other']);
323
					}
324
 
325
					$out .= $this->replacements['cal_cell_end_other'];
326
				}
327
				else
328
				{
329
					// Blank cells
330
					$out .= $this->replacements['cal_cell_start'].$this->replacements['cal_cell_blank'].$this->replacements['cal_cell_end'];
331
				}
332
 
333
				$day++;
334
			}
335
 
336
			$out .= "\n".$this->replacements['cal_row_end']."\n";
337
		}
338
 
339
		return $out .= "\n".$this->replacements['table_close'];
340
	}
341
 
342
	// --------------------------------------------------------------------
343
 
344
	/**
345
	 * Get Month Name
346
	 *
347
	 * Generates a textual month name based on the numeric
348
	 * month provided.
349
	 *
350
	 * @param	int	the month
351
	 * @return	string
352
	 */
353
	public function get_month_name($month)
354
	{
355
		if ($this->month_type === 'short')
356
		{
357
			$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');
358
		}
359
		else
360
		{
361
			$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');
362
		}
363
 
364
		return ($this->CI->lang->line($month_names[$month]) === FALSE)
365
			? ucfirst(substr($month_names[$month], 4))
366
			: $this->CI->lang->line($month_names[$month]);
367
	}
368
 
369
	// --------------------------------------------------------------------
370
 
371
	/**
372
	 * Get Day Names
373
	 *
374
	 * Returns an array of day names (Sunday, Monday, etc.) based
375
	 * on the type. Options: long, short, abr
376
	 *
377
	 * @param	string
378
	 * @return	array
379
	 */
380
	public function get_day_names($day_type = '')
381
	{
382
		if ($day_type !== '')
383
		{
384
			$this->day_type = $day_type;
385
		}
386
 
387
		if ($this->day_type === 'long')
388
		{
389
			$day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
390
		}
391
		elseif ($this->day_type === 'short')
392
		{
393
			$day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
394
		}
395
		else
396
		{
397
			$day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa');
398
		}
399
 
400
		$days = array();
401
		for ($i = 0, $c = count($day_names); $i < $c; $i++)
402
		{
403
			$days[] = ($this->CI->lang->line('cal_'.$day_names[$i]) === FALSE) ? ucfirst($day_names[$i]) : $this->CI->lang->line('cal_'.$day_names[$i]);
404
		}
405
 
406
		return $days;
407
	}
408
 
409
	// --------------------------------------------------------------------
410
 
411
	/**
412
	 * Adjust Date
413
	 *
414
	 * This function makes sure that we have a valid month/year.
415
	 * For example, if you submit 13 as the month, the year will
416
	 * increment and the month will become January.
417
	 *
418
	 * @param	int	the month
419
	 * @param	int	the year
420
	 * @return	array
421
	 */
422
	public function adjust_date($month, $year)
423
	{
424
		$date = array();
425
 
426
		$date['month']	= $month;
427
		$date['year']	= $year;
428
 
429
		while ($date['month'] > 12)
430
		{
431
			$date['month'] -= 12;
432
			$date['year']++;
433
		}
434
 
435
		while ($date['month'] <= 0)
436
		{
437
			$date['month'] += 12;
438
			$date['year']--;
439
		}
440
 
441
		if (strlen($date['month']) === 1)
442
		{
443
			$date['month'] = '0'.$date['month'];
444
		}
445
 
446
		return $date;
447
	}
448
 
449
	// --------------------------------------------------------------------
450
 
451
	/**
452
	 * Total days in a given month
453
	 *
454
	 * @param	int	the month
455
	 * @param	int	the year
456
	 * @return	int
457
	 */
458
	public function get_total_days($month, $year)
459
	{
460
		$this->CI->load->helper('date');
461
		return days_in_month($month, $year);
462
	}
463
 
464
	// --------------------------------------------------------------------
465
 
466
	/**
467
	 * Set Default Template Data
468
	 *
469
	 * This is used in the event that the user has not created their own template
470
	 *
471
	 * @return	array
472
	 */
473
	public function default_template()
474
	{
475
		return array(
476
			'table_open'				=> '<table border="0" cellpadding="4" cellspacing="0">',
477
			'heading_row_start'			=> '<tr>',
478
			'heading_previous_cell'		=> '<th><a href="{previous_url}">&lt;&lt;</a></th>',
479
			'heading_title_cell'		=> '<th colspan="{colspan}">{heading}</th>',
480
			'heading_next_cell'			=> '<th><a href="{next_url}">&gt;&gt;</a></th>',
481
			'heading_row_end'			=> '</tr>',
482
			'week_row_start'			=> '<tr>',
483
			'week_day_cell'				=> '<td>{week_day}</td>',
484
			'week_row_end'				=> '</tr>',
485
			'cal_row_start'				=> '<tr>',
486
			'cal_cell_start'			=> '<td>',
487
			'cal_cell_start_today'		=> '<td>',
488
			'cal_cell_start_other'		=> '<td style="color: #666;">',
489
			'cal_cell_content'			=> '<a href="{content}">{day}</a>',
490
			'cal_cell_content_today'	=> '<a href="{content}"><strong>{day}</strong></a>',
491
			'cal_cell_no_content'		=> '{day}',
492
			'cal_cell_no_content_today'	=> '<strong>{day}</strong>',
493
			'cal_cell_blank'			=> '&nbsp;',
494
			'cal_cell_other'			=> '{day}',
495
			'cal_cell_end'				=> '</td>',
496
			'cal_cell_end_today'		=> '</td>',
497
			'cal_cell_end_other'		=> '</td>',
498
			'cal_row_end'				=> '</tr>',
499
			'table_close'				=> '</table>'
500
		);
501
	}
502
 
503
	// --------------------------------------------------------------------
504
 
505
	/**
506
	 * Parse Template
507
	 *
508
	 * Harvests the data within the template {pseudo-variables}
509
	 * used to display the calendar
510
	 *
511
	 * @return	CI_Calendar
512
	 */
513
	public function parse_template()
514
	{
515
		$this->replacements = $this->default_template();
516
 
517
		if (empty($this->template))
518
		{
519
			return $this;
520
		}
521
 
522
		if (is_string($this->template))
523
		{
524
			$today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');
525
 
526
			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', 'cal_cell_start_other', 'cal_cell_other', 'cal_cell_end_other') as $val)
527
			{
528
				if (preg_match('/\{'.$val.'\}(.*?)\{\/'.$val.'\}/si', $this->template, $match))
529
				{
530
					$this->replacements[$val] = $match[1];
531
				}
532
				elseif (in_array($val, $today, TRUE))
533
				{
534
					$this->replacements[$val] = $this->replacements[substr($val, 0, -6)];
535
				}
536
			}
537
		}
538
		elseif (is_array($this->template))
539
		{
540
			$this->replacements = array_merge($this->replacements, $this->template);
541
		}
542
 
543
		return $this;
544
	}
545
 
546
}