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: