]> git.datanom.net - webcal.git/blob - caldav/caldavresource.class.php
Initial upload
[webcal.git] / caldav / caldavresource.class.php
1 <?php
2
3 /* $Id$ */
4 final class VTYPE {
5 const VEVENT = 1;
6 const VTODO = 2;
7 const VJOURNAL = 3;
8 const VFREEBUSY = 4;
9 const VTIMEZONE = 5;
10 const VALARM = 6;
11 private $value;
12
13 public function __construct($value) {
14 switch ($value) {
15 case 'VEVENT': $this->value = self::VEVENT; break;
16 case 'VTODO': $this->value = self::VTODO; break;
17 case 'VJOURNAL': $this->value = self::VJOURNAL; break;
18 case 'VFREEBUSY': $this->value = self::VFREEBUSY; break;
19 case 'VTIMEZONE': $this->value = self::VTIMEZONE; break;
20 case 'VALARM': $this->value = self::VALARM; break;
21 case self::VEVENT:
22 case self::VTODO:
23 case self::VJOURNAL:
24 case self::VFREEBUSY:
25 case self::VTIMEZONE:
26 case self::VALARM: $this->value = $value; break;
27 default: throw new Exception ("$value: Invalid VTYPE");
28 }
29 }
30
31 private function __clone() {}
32
33 public function ordinal() {
34 return $this->value;
35 }
36
37 public function __toString() {
38 switch ($this->value) {
39 case self::VEVENT: return 'VEVENT'; break;
40 case self::VTODO: return 'VTODO'; break;
41 case self::VJOURNAL: return 'VJOURNAL'; break;
42 case self::VFREEBUSY: return 'VFREEBUSY'; break;
43 case self::VTIMEZONE: return 'VTIMEZONE'; break;
44 case self::VALARM: return 'VALARM'; break;
45 }
46 }
47
48 }
49
50 abstract class CaldavRessource
51 implements ArrayAccess, IteratorAggregate {
52
53 private $client;
54
55 function __construct($url, $uid = '', $pwd = '', $cal = '') {
56 if (empty($url))
57 throw new Exception("Missing URL");
58 $this->client = new CalDAVClient($url, $uid, $pwd, $cal);
59 }
60
61 /**
62 * abstract functions to be implemented by sub classes
63 */
64 abstract function update($url, $etag = NULL);
65 abstract function newComponent($c_type);
66 abstract function getComponents($start, $end);
67 abstract function delete($url, $etag = NULL);
68
69 protected function callServer($method, $param = array()) {
70 $error = TRUE;
71 $msg = "Unknown error";
72
73 if (! is_array($param))
74 throw new Exception("Parameters must be inclosed in an array");
75 switch (strtolower($method)) {
76 case 'getevents':
77 if (count($param) != 2) {
78 $error = TRUE;
79 $msg = "Expected 2 parameters";
80 break;
81 }
82 if ($this->isDateTime($param[0]) &&
83 $this->isDateTime($param[1])) {
84 $res = $this->client->GetEvents($param[0], $param[1]);
85 $error = FALSE;
86 }
87 else {
88 $msg = "[${param[0]},${param[1]}]: Invalid DateTime";
89 $error = TRUE;
90 }
91 break;
92 case 'getbyuid':
93 if (count($param) != 1) {
94 $error = TRUE;
95 $msg = "Expected 1 parameter";
96 break;
97 }
98 $res = $this->client->GetEntryByUid($param[0]);
99 $error = FALSE;
100 break;
101 case 'put':
102 if (count($param) < 2 || count($param) > 3) {
103 $error = TRUE;
104 $msg = "Syntax: URL, CalDAV_resource[, ETag]";
105 break;
106 }
107 if (count($param) == 2)
108 $res = $this->client->DoPUTRequest($param[0], $param[1]);
109 else
110 $res = $this->client->DoPUTRequest($param[0], $param[1], $param[2]);
111 $error = FALSE;
112 break;
113 case 'delete':
114 if (count($param) < 1 || count($param) > 2) {
115 $error = TRUE;
116 $msg = "Syntax: URL[, ETag]";
117 break;
118 }
119 if (count($param) == 1)
120 $res = $this->client->DoDELETERequest($param[0]);
121 else
122 $res = $this->client->DoDELETERequest($param[0], $param[1]);
123 $error = FALSE;
124 break;
125 default:
126 throw new Exception("$method: Unknown method");
127 }
128 if ($error)
129 throw new Exception($msg);
130 else
131 return $res;
132 }
133
134 static function isDateTime($var) {
135 return (preg_match("/^([0-9]{8})T([0-9]{6})Z?$/", $var) > 0);
136 }
137
138 /**
139 * Returned date-time will always be in UTC
140 */
141 static function timestamp2ICal($ts, $localtime = TRUE) {
142 $ts = (int) $ts;
143 if ($ts < 0)
144 throw new Exception("$ts: invalid timestamp");
145 if ($localtime) {
146 $date = date('Ymd', $ts);
147 $time = date('His', $ts);
148 $res = sprintf("%sT%s", $date, $time);
149 }
150 else {
151 $date = gmdate('Ymd', $ts);
152 $time = gmdate('His', $ts);
153 $res = sprintf("%sT%sZ", $date, $time);
154 }
155 return $res;
156 }
157
158 static function iCal2Timestamp($ical) {
159 if (! self::isDateTime($ical)) {
160 // test for badly formed all-day event
161 //print "$ical";
162 $res = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/",
163 $ical, $parts);
164 if ($res == 0)
165 throw new Exception("$ical: invalid CalDAV Date-Time");
166 else {
167 $timepart = array('00', '00', '00');
168 $parts = array_merge($parts, $timepart);
169 }
170 }
171 else {
172 $date = "([0-9]{4})([0-9]{2})([0-9]{2})";
173 $time = "([0-9]{2})([0-9]{2})([0-9]{2})";
174 preg_match("/^${date}T${time}(Z?)$/", $ical, $parts);
175 }
176 if (count($parts) == 8 && ! empty($parts[7]))
177 return gmmktime($parts[4], $parts[5], $parts[6],
178 $parts[2], $parts[3], $parts[1]);
179 else
180 return mktime($parts[4], $parts[5], $parts[6],
181 $parts[2], $parts[3], $parts[1]);
182 }
183
184 private static function down_hour($date) {
185 //print "$date<br/>";
186 if (! self::isDateTime($date)) {
187 // test for badly formed all-day event
188 $res = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/",
189 $date, $parts);
190 if ($res == 0)
191 throw new Exception("$date: invalid CalDAV Date-Time");
192 else {
193 array_shift($parts);
194 $timepart = array('T', '00', '00', '00');
195 $parts = array_merge($parts, $timepart);
196 return implode('', $parts);
197 }
198 }
199 else {
200 $a = explode('T', $date);
201 $a[1] = substr_replace($a[1], '0000', 2);
202 return $a[0].'T'.$a[1];
203 }
204 }
205
206 static function fix_allday_event(&$date_a, &$date_b) {
207 //print "$date_a : $date_b<br/>";
208 if ($date_a == $date_b) {
209 if (! self::isDateTime($date_a) && ! self::isDateTime($date_b)) {
210 $res1 = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/",
211 $date_a);
212 $res2 = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/",
213 $date_b);
214 if ($res1 == 0 || $res2 == 0)
215 throw new Exception("$date_a, $date_b: invalid CalDAV Date-Time");
216 else {
217 $date_a .= "T000000";
218 $date_b .= "T235959";
219 }
220 }
221 else {
222 preg_match("/^([0-9]{4}[0-9]{2}[0-9]{2})T([0-9]{6})$/",
223 $date_a, $part_a);
224 preg_match("/^([0-9]{4}[0-9]{2}[0-9]{2})T([0-9]{6})$/",
225 $date_b, $part_b);
226 $date_a = $part_a[1]."T000000";
227 $date_b = $part_b[1]."T235959";
228 //print "$date_a : $date_b<br/>";
229 }
230 //print "$date_a : $date_b<br/>";
231 }
232 }
233
234 static function datecmp($date_a, $date_b) {
235 $date_a = self::iCal2Timestamp($date_a);
236 $date_b = self::iCal2Timestamp(self::down_hour($date_b));
237 if ($date_a < $date_b)
238 $res = -1;
239 else if ($date_a > $date_b)
240 $res = 1;
241 else
242 $res = 0;
243 return $res;
244 }
245
246 private static function intcmpstr($a_str, $b_str) {
247 $a = (int) $a_str;
248 $b = (int) $b_str;
249 //print "$a:$b<br/>";
250 if ($a > $b)
251 return 1;
252 else if ($a < $b)
253 return -1;
254 else
255 return 0;
256 }
257
258 static function cmpdate($date_a, $date_b) {
259 $datepart = explode('T', $date_a);
260 $d_a = $datepart[0];
261 $datepart = explode('T', $date_b);
262 $d_b = $datepart[0];
263 $y_cmp = self::intcmpstr(substr($d_a, 0, 4), substr($d_b, 0, 4));
264 if ($y_cmp == 0) {
265 $m_cmp = self::intcmpstr(substr($d_a, 4, 2), substr($d_b, 4, 2));
266 if ($m_cmp == 0) {
267 return self::intcmpstr(substr($d_a, 6, 2), substr($d_b, 6, 2));
268 }
269 return $m_cmp;
270 }
271 return $y_cmp;
272 }
273
274 static function cmptime($time_a, $time_b) {
275 $timepart = explode('T', $time_a);
276 $t_a = $timepart[1];
277 $timepart = explode('T', $time_b);
278 $t_b = $timepart[1];
279 //print "$t_a:$t_b<br/>";
280 $h_cmp = self::intcmpstr(substr($t_a, 0, 2), substr($t_b, 0, 2));
281 if ($h_cmp == 0) {
282 $m_cmp = self::intcmpstr(substr($t_a, 2, 2), substr($t_b, 2, 2));
283 if ($m_cmp == 0) {
284 return self::intcmpstr(substr($t_a, 4, 2), substr($t_b, 4, 2));
285 }
286 return $m_cmp;
287 }
288 return $h_cmp;
289 }
290
291 static function allDayEvent($time_a, $time_b) {
292 //echo $time_a.':'.$time_b.'<br/>';
293 $a = explode('T', $time_a);
294 if (count($a) < 2)
295 array_push($a, '0000');
296 $b = explode('T', $time_b);
297 if (count($b) < 2)
298 array_push($b, '0000');
299 $t = strtotime($time_b) - 3600;
300 $t = date("Ymd\THm", $t);
301 return (self::cmpdate($time_a, $t) == 0 &&
302 $a[1] == '0000' && $b[1] == '0000');
303 }
304 }
This page took 0.115303 seconds and 6 git commands to generate.