Imported Upstream version 0.6.24+dfsg1
This commit is contained in:
307
lib/kohana/system/libraries/Calendar_Event.php
Normal file
307
lib/kohana/system/libraries/Calendar_Event.php
Normal file
@@ -0,0 +1,307 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Calendar event observer class.
|
||||
*
|
||||
* $Id: Calendar_Event.php 4129 2009-03-27 17:47:03Z zombor $
|
||||
*
|
||||
* @package Calendar
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2008 Kohana Team
|
||||
* @license http://kohanaphp.com/license.html
|
||||
*/
|
||||
class Calendar_Event_Core extends Event_Observer {
|
||||
|
||||
// Boolean conditions
|
||||
protected $booleans = array
|
||||
(
|
||||
'current',
|
||||
'weekend',
|
||||
'first_day',
|
||||
'last_day',
|
||||
'last_occurrence',
|
||||
'easter',
|
||||
);
|
||||
|
||||
// Rendering conditions
|
||||
protected $conditions = array();
|
||||
|
||||
// Cell classes
|
||||
protected $classes = array();
|
||||
|
||||
// Cell output
|
||||
protected $output = '';
|
||||
|
||||
/**
|
||||
* Adds a condition to the event. The condition can be one of the following:
|
||||
*
|
||||
* timestamp - UNIX timestamp
|
||||
* day - day number (1-31)
|
||||
* week - week number (1-5)
|
||||
* month - month number (1-12)
|
||||
* year - year number (4 digits)
|
||||
* day_of_week - day of week (1-7)
|
||||
* current - active month (boolean) (only show data for the month being rendered)
|
||||
* weekend - weekend day (boolean)
|
||||
* first_day - first day of month (boolean)
|
||||
* last_day - last day of month (boolean)
|
||||
* occurrence - occurrence of the week day (1-5) (use with "day_of_week")
|
||||
* last_occurrence - last occurrence of week day (boolean) (use with "day_of_week")
|
||||
* easter - Easter day (boolean)
|
||||
* callback - callback test (boolean)
|
||||
*
|
||||
* To unset a condition, call condition with a value of NULL.
|
||||
*
|
||||
* @chainable
|
||||
* @param string condition key
|
||||
* @param mixed condition value
|
||||
* @return object
|
||||
*/
|
||||
public function condition($key, $value)
|
||||
{
|
||||
if ($value === NULL)
|
||||
{
|
||||
unset($this->conditions[$key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($key === 'callback')
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
elseif (in_array($key, $this->booleans))
|
||||
{
|
||||
// Make the value boolean
|
||||
$value = (bool) $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make the value an int
|
||||
$value = (int) $value;
|
||||
}
|
||||
|
||||
$this->conditions[$key] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CSS class for this event. This can be called multiple times.
|
||||
*
|
||||
* @chainable
|
||||
* @param string CSS class name
|
||||
* @return object
|
||||
*/
|
||||
public function add_class($class)
|
||||
{
|
||||
$this->classes[$class] = $class;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a CSS class for this event. This can be called multiple times.
|
||||
*
|
||||
* @chainable
|
||||
* @param string CSS class name
|
||||
* @return object
|
||||
*/
|
||||
public function remove_class($class)
|
||||
{
|
||||
unset($this->classes[$class]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HTML output for this event.
|
||||
*
|
||||
* @chainable
|
||||
* @param string HTML output
|
||||
* @return object
|
||||
*/
|
||||
public function output($str)
|
||||
{
|
||||
$this->output = $str;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CSS class for this event. This can be called multiple times.
|
||||
*
|
||||
* @chainable
|
||||
* @param string CSS class name
|
||||
* @return object
|
||||
*/
|
||||
public function notify($data)
|
||||
{
|
||||
// Split the date and current status
|
||||
list ($month, $day, $year, $week, $current) = $data;
|
||||
|
||||
// Get a timestamp for the day
|
||||
$timestamp = mktime(0, 0, 0, $month, $day, $year);
|
||||
|
||||
// Date conditionals
|
||||
$condition = array
|
||||
(
|
||||
'timestamp' => (int) $timestamp,
|
||||
'day' => (int) date('j', $timestamp),
|
||||
'week' => (int) $week,
|
||||
'month' => (int) date('n', $timestamp),
|
||||
'year' => (int) date('Y', $timestamp),
|
||||
'day_of_week' => (int) date('w', $timestamp),
|
||||
'current' => (bool) $current,
|
||||
);
|
||||
|
||||
// Tested conditions
|
||||
$tested = array();
|
||||
|
||||
foreach ($condition as $key => $value)
|
||||
{
|
||||
// Timestamps need to be handled carefully
|
||||
if($key === 'timestamp' AND isset($this->conditions['timestamp']))
|
||||
{
|
||||
// This adds 23 hours, 59 minutes and 59 seconds to today's timestamp, as 24 hours
|
||||
// is classed as a new day
|
||||
$next_day = $timestamp + 86399;
|
||||
|
||||
if($this->conditions['timestamp'] < $timestamp OR $this->conditions['timestamp'] > $next_day)
|
||||
return FALSE;
|
||||
}
|
||||
// Test basic conditions first
|
||||
elseif (isset($this->conditions[$key]) AND $this->conditions[$key] !== $value)
|
||||
return FALSE;
|
||||
|
||||
// Condition has been tested
|
||||
$tested[$key] = TRUE;
|
||||
}
|
||||
|
||||
if (isset($this->conditions['weekend']))
|
||||
{
|
||||
// Weekday vs Weekend
|
||||
$condition['weekend'] = ($condition['day_of_week'] === 0 OR $condition['day_of_week'] === 6);
|
||||
}
|
||||
|
||||
if (isset($this->conditions['first_day']))
|
||||
{
|
||||
// First day of month
|
||||
$condition['first_day'] = ($condition['day'] === 1);
|
||||
}
|
||||
|
||||
if (isset($this->conditions['last_day']))
|
||||
{
|
||||
// Last day of month
|
||||
$condition['last_day'] = ($condition['day'] === (int) date('t', $timestamp));
|
||||
}
|
||||
|
||||
if (isset($this->conditions['occurrence']))
|
||||
{
|
||||
// Get the occurance of the current day
|
||||
$condition['occurrence'] = $this->day_occurrence($timestamp);
|
||||
}
|
||||
|
||||
if (isset($this->conditions['last_occurrence']))
|
||||
{
|
||||
// Test if the next occurance of this date is next month
|
||||
$condition['last_occurrence'] = ((int) date('n', $timestamp + 604800) !== $condition['month']);
|
||||
}
|
||||
|
||||
if (isset($this->conditions['easter']))
|
||||
{
|
||||
if ($condition['month'] === 3 OR $condition['month'] === 4)
|
||||
{
|
||||
// This algorithm is from Practical Astronomy With Your Calculator, 2nd Edition by Peter
|
||||
// Duffett-Smith. It was originally from Butcher's Ecclesiastical Calendar, published in
|
||||
// 1876. This algorithm has also been published in the 1922 book General Astronomy by
|
||||
// Spencer Jones; in The Journal of the British Astronomical Association (Vol.88, page
|
||||
// 91, December 1977); and in Astronomical Algorithms (1991) by Jean Meeus.
|
||||
|
||||
$a = $condition['year'] % 19;
|
||||
$b = (int) ($condition['year'] / 100);
|
||||
$c = $condition['year'] % 100;
|
||||
$d = (int) ($b / 4);
|
||||
$e = $b % 4;
|
||||
$f = (int) (($b + 8) / 25);
|
||||
$g = (int) (($b - $f + 1) / 3);
|
||||
$h = (19 * $a + $b - $d - $g + 15) % 30;
|
||||
$i = (int) ($c / 4);
|
||||
$k = $c % 4;
|
||||
$l = (32 + 2 * $e + 2 * $i - $h - $k) % 7;
|
||||
$m = (int) (($a + 11 * $h + 22 * $l) / 451);
|
||||
$p = ($h + $l - 7 * $m + 114) % 31;
|
||||
|
||||
$month = (int) (($h + $l - 7 * $m + 114) / 31);
|
||||
$day = $p + 1;
|
||||
|
||||
$condition['easter'] = ($condition['month'] === $month AND $condition['day'] === $day);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Easter can only happen in March or April
|
||||
$condition['easter'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->conditions['callback']))
|
||||
{
|
||||
// Use a callback to determine validity
|
||||
$condition['callback'] = call_user_func($this->conditions['callback'], $condition, $this);
|
||||
}
|
||||
|
||||
$conditions = array_diff_key($this->conditions, $tested);
|
||||
|
||||
foreach ($conditions as $key => $value)
|
||||
{
|
||||
if ($key === 'callback')
|
||||
{
|
||||
// Callbacks are tested on a TRUE/FALSE basis
|
||||
$value = TRUE;
|
||||
}
|
||||
|
||||
// Test advanced conditions
|
||||
if ($condition[$key] !== $value)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->caller->add_data(array
|
||||
(
|
||||
'classes' => $this->classes,
|
||||
'output' => $this->output,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the week day occurrence for a specific timestamp. The occurrence is
|
||||
* relative to the current month. For example, the second Saturday of any
|
||||
* given month will return "2" as the occurrence. This is used in combination
|
||||
* with the "occurrence" condition.
|
||||
*
|
||||
* @param integer UNIX timestamp
|
||||
* @return integer
|
||||
*/
|
||||
protected function day_occurrence($timestamp)
|
||||
{
|
||||
// Get the current month for the timestamp
|
||||
$month = date('m', $timestamp);
|
||||
|
||||
// Default occurrence is one
|
||||
$occurrence = 1;
|
||||
|
||||
// Reduce the timestamp by one week for each loop. This has the added
|
||||
// benefit of preventing an infinite loop.
|
||||
while ($timestamp -= 604800)
|
||||
{
|
||||
if (date('m', $timestamp) !== $month)
|
||||
{
|
||||
// Once the timestamp has gone into the previous month, the
|
||||
// proper occurrence has been found.
|
||||
return $occurrence;
|
||||
}
|
||||
|
||||
// Increment the occurrence
|
||||
$occurrence++;
|
||||
}
|
||||
}
|
||||
|
||||
} // End Calendar Event
|
||||
Reference in New Issue
Block a user