4113 |
efrain |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
//--------------------------------------------------------------------------------------------------
|
|
|
4 |
// Utilities for our event-fetching scripts.
|
|
|
5 |
//
|
|
|
6 |
// Requires PHP 5.2.0 or higher.
|
|
|
7 |
//--------------------------------------------------------------------------------------------------
|
|
|
8 |
|
|
|
9 |
// PHP will fatal error if we attempt to use the DateTime class without this being set.
|
|
|
10 |
date_default_timezone_set('UTC');
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
class Event {
|
|
|
14 |
|
|
|
15 |
// Tests whether the given ISO8601 string has a time-of-day or not
|
|
|
16 |
const ALL_DAY_REGEX = '/^\d{4}-\d\d-\d\d$/'; // matches strings like "2013-12-29"
|
|
|
17 |
|
|
|
18 |
public $title;
|
|
|
19 |
public $allDay; // a boolean
|
|
|
20 |
public $start; // a DateTime
|
|
|
21 |
public $end; // a DateTime, or null
|
|
|
22 |
public $properties = array(); // an array of other misc properties
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
// Constructs an Event object from the given array of key=>values.
|
|
|
26 |
// You can optionally force the timezone of the parsed dates.
|
|
|
27 |
public function __construct($array, $timezone=null) {
|
|
|
28 |
|
|
|
29 |
$this->title = $array['title'];
|
|
|
30 |
|
|
|
31 |
if (isset($array['allDay'])) {
|
|
|
32 |
// allDay has been explicitly specified
|
|
|
33 |
$this->allDay = (bool)$array['allDay'];
|
|
|
34 |
}
|
|
|
35 |
else {
|
|
|
36 |
// Guess allDay based off of ISO8601 date strings
|
|
|
37 |
$this->allDay = preg_match(self::ALL_DAY_REGEX, $array['start']) &&
|
|
|
38 |
(!isset($array['end']) || preg_match(self::ALL_DAY_REGEX, $array['end']));
|
|
|
39 |
}
|
|
|
40 |
|
|
|
41 |
if ($this->allDay) {
|
|
|
42 |
// If dates are allDay, we want to parse them in UTC to avoid DST issues.
|
|
|
43 |
$timezone = null;
|
|
|
44 |
}
|
|
|
45 |
|
|
|
46 |
// Parse dates
|
|
|
47 |
$this->start = parseDateTime($array['start'], $timezone);
|
|
|
48 |
$this->end = isset($array['end']) ? parseDateTime($array['end'], $timezone) : null;
|
|
|
49 |
|
|
|
50 |
// Record misc properties
|
|
|
51 |
foreach ($array as $name => $value) {
|
|
|
52 |
if (!in_array($name, array('title', 'allDay', 'start', 'end'))) {
|
|
|
53 |
$this->properties[$name] = $value;
|
|
|
54 |
}
|
|
|
55 |
}
|
|
|
56 |
}
|
|
|
57 |
|
|
|
58 |
|
|
|
59 |
// Returns whether the date range of our event intersects with the given all-day range.
|
|
|
60 |
// $rangeStart and $rangeEnd are assumed to be dates in UTC with 00:00:00 time.
|
|
|
61 |
public function isWithinDayRange($rangeStart, $rangeEnd) {
|
|
|
62 |
|
|
|
63 |
// Normalize our event's dates for comparison with the all-day range.
|
|
|
64 |
$eventStart = stripTime($this->start);
|
|
|
65 |
|
|
|
66 |
if (isset($this->end)) {
|
|
|
67 |
$eventEnd = stripTime($this->end); // normalize
|
|
|
68 |
}
|
|
|
69 |
else {
|
|
|
70 |
$eventEnd = $eventStart; // consider this a zero-duration event
|
|
|
71 |
}
|
|
|
72 |
|
|
|
73 |
// Check if the two whole-day ranges intersect.
|
|
|
74 |
return $eventStart < $rangeEnd && $eventEnd >= $rangeStart;
|
|
|
75 |
}
|
|
|
76 |
|
|
|
77 |
|
|
|
78 |
// Converts this Event object back to a plain data array, to be used for generating JSON
|
|
|
79 |
public function toArray() {
|
|
|
80 |
|
|
|
81 |
// Start with the misc properties (don't worry, PHP won't affect the original array)
|
|
|
82 |
$array = $this->properties;
|
|
|
83 |
|
|
|
84 |
$array['title'] = $this->title;
|
|
|
85 |
|
|
|
86 |
// Figure out the date format. This essentially encodes allDay into the date string.
|
|
|
87 |
if ($this->allDay) {
|
|
|
88 |
$format = 'Y-m-d'; // output like "2013-12-29"
|
|
|
89 |
}
|
|
|
90 |
else {
|
|
|
91 |
$format = 'c'; // full ISO8601 output, like "2013-12-29T09:00:00+08:00"
|
|
|
92 |
}
|
|
|
93 |
|
|
|
94 |
// Serialize dates into strings
|
|
|
95 |
$array['start'] = $this->start->format($format);
|
|
|
96 |
if (isset($this->end)) {
|
|
|
97 |
$array['end'] = $this->end->format($format);
|
|
|
98 |
}
|
|
|
99 |
|
|
|
100 |
return $array;
|
|
|
101 |
}
|
|
|
102 |
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
|
|
|
106 |
// Date Utilities
|
|
|
107 |
//----------------------------------------------------------------------------------------------
|
|
|
108 |
|
|
|
109 |
|
|
|
110 |
// Parses a string into a DateTime object, optionally forced into the given timezone.
|
|
|
111 |
function parseDateTime($string, $timezone=null) {
|
|
|
112 |
$date = new DateTime(
|
|
|
113 |
$string,
|
|
|
114 |
$timezone ? $timezone : new DateTimeZone('UTC')
|
|
|
115 |
// Used only when the string is ambiguous.
|
|
|
116 |
// Ignored if string has a timezone offset in it.
|
|
|
117 |
);
|
|
|
118 |
if ($timezone) {
|
|
|
119 |
// If our timezone was ignored above, force it.
|
|
|
120 |
$date->setTimezone($timezone);
|
|
|
121 |
}
|
|
|
122 |
return $date;
|
|
|
123 |
}
|
|
|
124 |
|
|
|
125 |
|
|
|
126 |
// Takes the year/month/date values of the given DateTime and converts them to a new DateTime,
|
|
|
127 |
// but in UTC.
|
|
|
128 |
function stripTime($datetime) {
|
|
|
129 |
return new DateTime($datetime->format('Y-m-d'));
|
|
|
130 |
}
|