1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: class Kronolith_Driver_Kolab extends Kronolith_Driver
16: {
17: 18: 19: 20: 21:
22: private $_session;
23:
24: 25: 26: 27: 28:
29: private $_kolab = null;
30:
31: 32: 33: 34: 35:
36: private $_events_cache;
37:
38: 39: 40: 41: 42:
43: private $_synchronized;
44:
45: 46: 47: 48: 49:
50: private $_data;
51:
52: 53: 54:
55: public function initialize()
56: {
57: if (empty($this->_params['storage'])) {
58: throw new InvalidArgumentException('Missing required Horde_Kolab_Storage instance');
59: }
60: $this->_kolab = $this->_params['storage'];
61: $this->reset();
62: }
63:
64: 65: 66: 67: 68:
69: public function open($calendar)
70: {
71: if ($this->calendar == $calendar) {
72: return;
73: }
74: $this->calendar = $calendar;
75: $this->reset();
76: }
77:
78: 79: 80: 81: 82:
83: public function backgroundColor()
84: {
85: if (isset($GLOBALS['all_calendars'][$this->calendar])) {
86: return $GLOBALS['all_calendars'][$this->calendar]->background();
87: }
88: return '#dddddd';
89: }
90:
91: 92: 93:
94: public function reset()
95: {
96: $this->_events_cache = array();
97: $this->_synchronized = false;
98: }
99:
100:
101:
102:
103: public function synchronize($force = false)
104: {
105: if ($this->_synchronized && !$force) {
106: return;
107: }
108:
109:
110: $this->_data = $this->_kolab->getData(
111: $GLOBALS['all_calendars'][$this->calendar]->share()->get('folder'),
112: 'event'
113: );
114:
115:
116:
117: $this->_events_cache = array();
118: $events = $this->_data->getObjects();
119: foreach ($events as $event) {
120: $this->_events_cache[$event['uid']] = new Kronolith_Event_Kolab($this, $event);
121: }
122:
123: $this->_synchronized = true;
124: }
125:
126: 127: 128:
129: public function listAlarms($date, $fullevent = false)
130: {
131: $allevents = $this->listEvents($date, null, false, true);
132: $events = array();
133:
134: foreach ($allevents as $eventId => $data) {
135: $event = $this->getEvent($eventId);
136: if (!$event->recurs()) {
137: $start = new Horde_Date($event->start);
138: $start->min -= $event->alarm;
139: if ($start->compareDateTime($date) <= 0 &&
140: $date->compareDateTime($event->end) <= -1) {
141: $events[] = $fullevent ? $event : $eventId;
142: }
143: } else {
144: if ($next = $event->recurrence->nextRecurrence($date)) {
145: if ($event->recurrence->hasException($next->year, $next->month, $next->mday)) {
146: continue;
147: }
148: $start = new Horde_Date($next);
149: $start->min -= $event->alarm;
150: $end = new Horde_Date(array('year' => $next->year,
151: 'month' => $next->month,
152: 'mday' => $next->mday,
153: 'hour' => $event->end->hour,
154: 'min' => $event->end->min,
155: 'sec' => $event->end->sec));
156: if ($start->compareDateTime($date) <= 0 &&
157: $date->compareDateTime($end) <= -1) {
158: if ($fullevent) {
159: $event->start = $start;
160: $event->end = $end;
161: $events[] = $event;
162: } else {
163: $events[] = $eventId;
164: }
165: }
166: }
167: }
168: }
169:
170: return is_array($events) ? $events : array();
171: }
172:
173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183:
184: public function exists($uid, $calendar_id = null)
185: {
186:
187: if ($calendar_id != $this->calendar) {
188: Horde::logMessage(sprintf("Kolab::exists called for calendar %s. Currently active is %s.", $calendar_id, $this->calendar), 'ERR');
189: throw new Kronolith_Exception(sprintf("Kolab::exists called for calendar %s. Currently active is %s.", $calendar_id, $this->calendar));
190: }
191:
192: $result = $this->synchronize();
193:
194: if ($this->_data->objectIdExists($uid)) {
195: return $uid;
196: }
197:
198: return false;
199: }
200:
201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218:
219: public function listEvents($startDate = null, $endDate = null,
220: $showRecurrence = false, $hasAlarm = false,
221: $json = false, $coverDates = true,
222: $fetchTags = false)
223: {
224: $result = $this->synchronize();
225:
226: if (empty($startDate)) {
227: $startDate = new Horde_Date(array('mday' => 1,
228: 'month' => 1,
229: 'year' => 0000));
230: }
231: if (empty($endDate)) {
232: $endDate = new Horde_Date(array('mday' => 31,
233: 'month' => 12,
234: 'year' => 9999));
235: }
236: if (!($startDate instanceOf Horde_Date)) {
237: $startDate = new Horde_Date($startDate);
238: }
239: if (!($endDate instanceOf Horde_Date)) {
240: $endDate = new Horde_Date($endDate);
241: }
242:
243: $startDate = clone $startDate;
244: $startDate->hour = $startDate->min = $startDate->sec = 0;
245: $endDate = clone $endDate;
246: $endDate->hour = 23;
247: $endDate->min = $endDate->sec = 59;
248:
249: $events = array();
250: foreach($this->_events_cache as $event) {
251: if ($hasAlarm && !$event->alarm) {
252: continue;
253: }
254:
255:
256: if (
257:
258: $event->start->compareDateTime($endDate) > 0 ||
259:
260: (!$event->recurs() &&
261: $event->end->compareDateTime($startDate) < 0) ||
262:
263: ($event->recurs() &&
264:
265: ($event->recurrence->hasRecurEnd() &&
266: $event->recurrence->recurEnd->compareDateTime($startDate) < 0))) {
267: continue;
268: }
269:
270: Kronolith::addEvents($events, $event, $startDate, $endDate,
271: $showRecurrence, $json, $coverDates);
272: }
273:
274: return $events;
275: }
276:
277: 278: 279: 280:
281: public function getEvent($eventId = null)
282: {
283: if (!strlen($eventId)) {
284: return new Kronolith_Event_Kolab($this);
285: }
286:
287: $result = $this->synchronize();
288:
289: if (array_key_exists($eventId, $this->_events_cache)) {
290: return $this->_events_cache[$eventId];
291: }
292:
293: throw new Horde_Exception_NotFound(sprintf(_("Event not found: %s"), $eventId));
294: }
295:
296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307:
308: public function getByUID($uid, $calendars = null, $getAll = false)
309: {
310: if (!is_array($calendars)) {
311: $calendars = array_keys(Kronolith::listInternalCalendars(true, Horde_Perms::READ));
312: }
313:
314: foreach ($calendars as $calendar) {
315: $this->open($calendar);
316: $this->synchronize();
317:
318: if (!array_key_exists($uid, $this->_events_cache)) {
319: continue;
320: }
321:
322:
323: $event = $this->_events_cache[$uid];
324:
325: if ($getAll) {
326: $events = array();
327: $events[] = $event;
328: return $events;
329: } else {
330: return $event;
331: }
332: }
333:
334: throw new Horde_Exception_NotFound(sprintf(_("Event not found: %s"), $uid));
335: }
336:
337: 338: 339: 340: 341: 342: 343: 344:
345: protected function _updateEvent(Kronolith_Event $event)
346: {
347: return $this->_saveEvent($event, true);
348: }
349:
350: 351: 352: 353: 354: 355: 356: 357:
358: protected function _addEvent(Kronolith_Event $event)
359: {
360: return $this->_saveEvent($event, false);
361: }
362:
363: 364: 365: 366: 367: 368: 369: 370:
371: protected function _saveEvent($event, $edit)
372: {
373: $this->synchronize();
374:
375: $action = $edit
376: ? array('action' => 'modify')
377: : array('action' => 'add');
378:
379: if (!$event->uid) {
380: $event->uid = $this->_data->generateUID();
381: }
382: if (!$edit) {
383: $object = $event->toKolab();
384: $this->_data->create($object);
385: } else {
386: $object = $event->toKolab();
387: $this->_data->modify($object);
388: }
389:
390:
391: if ($edit) {
392: Kronolith::getTagger()->replaceTags($event->uid, $event->tags, $event->creator, 'event');
393: } else {
394: Kronolith::getTagger()->tag($event->uid, $event->tags, $event->creator, 'event');
395: }
396:
397: $cal = $GLOBALS['kronolith_shares']->getShare($event->calendar);
398:
399:
400: Kronolith::sendNotification($event, $edit ? 'edit' : 'add');
401:
402:
403: try {
404: $GLOBALS['injector']->getInstance('Horde_History')->log('kronolith:' . $event->calendar . ':' . $event->uid, $action, true);
405: } catch (Exception $e) {
406: Horde::logMessage($e, 'ERR');
407: }
408:
409:
410: $this->synchronize(true);
411:
412: if (is_callable('Kolab', 'triggerFreeBusyUpdate')) {
413:
414: }
415:
416: return $event->uid;
417: }
418:
419: 420: 421: 422: 423: 424: 425: 426: 427: 428:
429: protected function _move($eventId, $newCalendar)
430: {
431: $event = $this->getEvent($eventId);
432: $result = $this->synchronize();
433:
434: global $kronolith_shares;
435: $target = $kronolith_shares->getShare($newCalendar);
436: $folder = $target->getId();
437:
438: $result = $this->_data->move($eventId, $folder);
439: if ($result) {
440: unset($this->_events_cache[$eventId]);
441: }
442:
443: if (is_callable('Kolab', 'triggerFreeBusyUpdate')) {
444:
445:
446: }
447:
448: return $event;
449: }
450:
451: 452: 453: 454: 455: 456: 457:
458: public function delete($calendar)
459: {
460: $this->open($calendar);
461: $result = $this->synchronize();
462:
463: $result = $this->_data->deleteAll($calendar);
464: if (is_callable('Kolab', 'triggerFreeBusyUpdate')) {
465:
466: }
467: }
468:
469: 470: 471: 472: 473: 474: 475: 476: 477:
478: public function deleteEvent($eventId, $silent = false)
479: {
480: $result = $this->synchronize();
481:
482: if (!$this->_data->objectIdExists($eventId)) {
483: throw new Kronolith_Exception(sprintf(_("Event not found: %s"), $eventId));
484: }
485:
486: $event = $this->getEvent($eventId);
487: $this->_data->delete($eventId);
488:
489:
490: if (!$silent) {
491: Kronolith::sendNotification($event, 'delete');
492: }
493:
494:
495: try {
496: $GLOBALS['injector']->getInstance('Horde_History')->log('kronolith:' . $event->calendar . ':' . $event->uid, array('action' => 'delete'), true);
497: } catch (Exception $e) {
498: Horde::logMessage($e, 'ERR');
499: }
500:
501: unset($this->_events_cache[$eventId]);
502: }
503:
504: }
505: