1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: class Kronolith_Ajax_Application extends Horde_Core_Ajax_Application
16: {
17: 18: 19: 20: 21:
22: public $notify = true;
23:
24: 25: 26: 27: 28: 29:
30: public function __construct($app, $vars, $action = null)
31: {
32: parent::__construct($app, $vars, $action);
33: $this->_defaultDomain = empty($GLOBALS['conf']['storage']['default_domain']) ? null : $GLOBALS['conf']['storage']['default_domain'];
34: }
35:
36: 37: 38:
39: public function poll()
40: {
41: return false;
42: }
43:
44: 45: 46:
47: public function listEvents()
48: {
49: $start = new Horde_Date($this->_vars->start);
50: $end = new Horde_Date($this->_vars->end);
51: $result = $this->_signedResponse($this->_vars->cal);
52: if (!($kronolith_driver = $this->_getDriver($this->_vars->cal))) {
53: return $result;
54: }
55: try {
56: session_write_close();
57: $events = $kronolith_driver->listEvents($start, $end, true, false, true);
58: session_start();
59: if (count($events)) {
60: $result->events = $events;
61: }
62: } catch (Exception $e) {
63: $GLOBALS['notification']->push($e, 'horde.error');
64: }
65: return $result;
66: }
67:
68: 69: 70:
71: public function getEvent()
72: {
73: $result = new stdClass;
74:
75: if (!($kronolith_driver = $this->_getDriver($this->_vars->cal)) ||
76: !isset($this->_vars->id)) {
77: return $result;
78: }
79:
80: try {
81: $event = $kronolith_driver->getEvent($this->_vars->id, $this->_vars->date);
82: $result->event = $event->toJson(null, true, $GLOBALS['prefs']->getValue('twentyFour') ? 'H:i' : 'h:i A');
83: } catch (Horde_Exception_NotFound $e) {
84: $GLOBALS['notification']->push(_("The requested event was not found."), 'horde.error');
85: } catch (Exception $e) {
86: $GLOBALS['notification']->push($e, 'horde.error');
87: }
88:
89: return $result;
90: }
91:
92: 93: 94:
95: public function saveEvent()
96: {
97: $result = $this->_signedResponse($this->_vars->targetcalendar);
98:
99: if (!($kronolith_driver = $this->_getDriver($this->_vars->targetcalendar))) {
100: return $result;
101: }
102:
103: if ($this->_vars->as_new) {
104: unset($this->_vars->event);
105: }
106: if (!$this->_vars->event) {
107: $perms = $GLOBALS['injector']->getInstance('Horde_Core_Perms');
108: if ($perms->hasAppPermission('max_events') !== true &&
109: $perms->hasAppPermission('max_events') <= Kronolith::countEvents()) {
110: Horde::permissionDeniedError(
111: 'kronolith',
112: 'max_events',
113: sprintf(_("You are not allowed to create more than %d events."), $perms->hasAppPermission('max_events'))
114: );
115: return $result;
116: }
117: }
118:
119: if ($this->_vars->event &&
120: $this->_vars->cal &&
121: $this->_vars->cal != $this->_vars->targetcalendar) {
122: if (strpos($kronolith_driver->calendar, '\\')) {
123: list($target, $user) = explode('\\', $kronolith_driver->calendar, 2);
124: } else {
125: $target = $kronolith_driver->calendar;
126: $user = $GLOBALS['registry']->getAuth();
127: }
128: $kronolith_driver = $this->_getDriver($this->_vars->cal);
129:
130:
131: try {
132: $sourceShare = Kronolith::getInternalCalendar($kronolith_driver->calendar);
133: $share = Kronolith::getInternalCalendar($target);
134: if ($sourceShare->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE) &&
135: (($user == $GLOBALS['registry']->getAuth() &&
136: $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) ||
137: ($user != $GLOBALS['registry']->getAuth() &&
138: $share->hasPermission($GLOBALS['registry']->getAuth(), Kronolith::PERMS_DELEGATE)))) {
139: $kronolith_driver->move($this->_vars->event, $target);
140: $kronolith_driver = $this->_getDriver($this->_vars->targetcalendar);
141: }
142: } catch (Exception $e) {
143: $GLOBALS['notification']->push(sprintf(_("There was an error moving the event: %s"), $e->getMessage()), 'horde.error');
144: return $result;
145: }
146: }
147:
148: if ($this->_vars->as_new) {
149: $event = $kronolith_driver->getEvent();
150: } else {
151: try {
152: $event = $kronolith_driver->getEvent($this->_vars->event);
153: } catch (Horde_Exception_NotFound $e) {
154: $GLOBALS['notification']->push(_("The requested event was not found."), 'horde.error');
155: return $result;
156: } catch (Exception $e) {
157: $GLOBALS['notification']->push($e);
158: return $result;
159: }
160: }
161:
162: if (!$event->hasPermission(Horde_Perms::EDIT)) {
163: $GLOBALS['notification']->push(_("You do not have permission to edit this event."), 'horde.warning');
164: return $result;
165: }
166:
167: try {
168: $event->readForm();
169: $result = $this->_saveEvent($event);
170: } catch (Exception $e) {
171: $GLOBALS['notification']->push($e);
172: return $result;
173: }
174: if (($result !== true) && $this->_vars->sendupdates) {
175: Kronolith::sendITipNotifications($event, $GLOBALS['notification'], Kronolith::ITIP_REQUEST);
176: }
177: Kronolith::notifyOfResourceRejection($event);
178:
179: return $result;
180: }
181:
182: 183: 184:
185: public function quickSaveEvent()
186: {
187: $cal = explode('|', $this->_vars->cal, 2);
188: try {
189: $event = Kronolith::quickAdd($this->_vars->text, $cal[1]);
190: return $this->_saveEvent($event);
191: } catch (Horde_Exception $e) {
192: $GLOBALS['notification']->push($e);
193: return $this->_signedResponse($this->_vars->cal);
194: }
195: }
196:
197: 198: 199:
200: public function updateEvent()
201: {
202: $result = $this->_signedResponse($this->_vars->cal);
203:
204: if (!($kronolith_driver = $this->_getDriver($this->_vars->cal)) ||
205: !isset($this->_vars->id)) {
206: return $result;
207: }
208:
209: try {
210: $oevent = $kronolith_driver->getEvent($this->_vars->id);
211: } catch (Exception $e) {
212: $GLOBALS['notification']->push($e, 'horde.error');
213: return $result;
214: }
215: if (!$oevent) {
216: $GLOBALS['notification']->push(_("The requested event was not found."), 'horde.error');
217: return $result;
218: } elseif (!$oevent->hasPermission(Horde_Perms::EDIT)) {
219: $GLOBALS['notification']->push(_("You do not have permission to edit this event."), 'horde.warning');
220: return $result;
221: }
222:
223: $attributes = Horde_Serialize::unserialize($this->_vars->att, Horde_Serialize::JSON);
224:
225:
226: if ($oevent->recurs()) {
227: $event = $this->_createExceptionEvent($oevent, $attributes);
228: } else {
229: $event = clone($oevent);
230: }
231:
232: foreach ($attributes as $attribute => $value) {
233: switch ($attribute) {
234: case 'start':
235: $event->start = new Horde_Date($value);
236: break;
237:
238: case 'end':
239: $event->end = new Horde_Date($value);
240: if ($event->end->hour == 23 &&
241: $event->end->min == 59 &&
242: $event->end->sec == 59) {
243: $event->end->mday++;
244: $event->end->hour = $event->end->min = $event->end->sec = 0;
245: }
246: break;
247:
248: case 'offDays':
249: $event->start->mday = $event->start->mday + $value;
250: $event->end->mday = $event->end->mday + $value;
251: break;
252:
253: case 'offMins':
254: $event->start->min += $value;
255: $event->end->min += $value;
256: break;
257: }
258: }
259:
260:
261: return $this->_saveEvent($event, ($oevent->recurs() ? $oevent : null), $attributes);
262: }
263:
264: 265: 266:
267: public function deleteEvent()
268: {
269: $result = new stdClass;
270:
271: if (!($kronolith_driver = $this->_getDriver($this->_vars->cal)) ||
272: !isset($this->_vars->id)) {
273: return $result;
274: }
275:
276: try {
277: $event = $kronolith_driver->getEvent($this->_vars->id);
278: if (!$event->hasPermission(Horde_Perms::DELETE)) {
279: $GLOBALS['notification']->push(_("You do not have permission to delete this event."), 'horde.warning');
280: return $result;
281: }
282: if ($event->recurs()) {
283: $result->uid = $event->uid;
284: }
285: $deleted = $kronolith_driver->deleteEvent($event->id);
286: if ($this->_vars->sendupdates) {
287: Kronolith::sendITipNotifications($event, $GLOBALS['notification'], Kronolith::ITIP_CANCEL);
288: }
289: $result->deleted = true;
290: } catch (Horde_Exception_NotFound $e) {
291: $GLOBALS['notification']->push(_("The requested event was not found."), 'horde.error');
292: } catch (Exception $e) {
293: $GLOBALS['notification']->push($e, 'horde.error');
294: }
295:
296: return $result;
297: }
298:
299: 300: 301:
302: public function searchEvents()
303: {
304: $query = Horde_Serialize::unserialize($this->_vars->query, Horde_Serialize::JSON);
305: if (!isset($query->start)) {
306: $query->start = new Horde_Date($_SERVER['REQUEST_TIME']);
307: }
308: if (!isset($query->end)) {
309: $query->end = null;
310: }
311: switch ($this->_vars->time) {
312: case 'all':
313: $query->start = null;
314: $query->end = null;
315: break;
316: case 'future':
317: $query->start = new Horde_Date($_SERVER['REQUEST_TIME']);
318: $query->end = null;
319: break;
320: case 'past':
321: $query->start = null;
322: $query->end = new Horde_Date($_SERVER['REQUEST_TIME']);
323: break;
324: }
325:
326: $tagger = new Kronolith_Tagger();
327: $cals = Horde_Serialize::unserialize($this->_vars->cals, Horde_Serialize::JSON);
328: $events = array();
329: foreach ($cals as $cal) {
330: if (!($kronolith_driver = $this->_getDriver($cal))) {
331: continue;
332: }
333: try {
334: $result = $kronolith_driver->search($query, true);
335: if ($result) {
336: $events[$cal] = $result;
337: }
338: } catch (Exception $e) {
339: $GLOBALS['notification']->push($e, 'horde.error');
340: }
341: $split = explode('|', $cal);
342: if ($split[0] == 'internal') {
343: $result = $tagger->search($query->title, array('type' => 'event', 'calendar' => $split[1]));
344: foreach ($result['events'] as $uid) {
345: Kronolith::addSearchEvents($events[$cal], $kronolith_driver->getByUID($uid), $query, true);
346: }
347: }
348: }
349:
350: $result = new stdClass;
351: $result->view = 'search';
352: $result->query = $this->_vars->query;
353: if ($events) {
354: $result->events = $events;
355: }
356:
357: return $result;
358: }
359:
360: 361: 362:
363: public function listTasks()
364: {
365: if (!$GLOBALS['registry']->hasMethod('tasks/listTasks')) {
366: return false;
367: }
368:
369: $result = new stdClass;
370: $result->list = $this->_vars->list;
371: $result->type = $this->_vars->type;
372:
373: try {
374: $tasks = $GLOBALS['registry']->tasks->listTasks(null, null, null, $this->_vars->list, $this->_vars->type == 'incomplete' ? 'future_incomplete' : $this->_vars->type, true);
375: if (count($tasks)) {
376: $result->tasks = $tasks;
377: }
378: } catch (Exception $e) {
379: $GLOBALS['notification']->push($e, 'horde.error');
380: }
381:
382: return $result;
383: }
384:
385: 386: 387:
388: public function getTask()
389: {
390: if (!$GLOBALS['registry']->hasMethod('tasks/getTask') ||
391: !isset($this->_vars->id) ||
392: !isset($this->_vars->list)) {
393: return false;
394: }
395:
396: $result = new stdClass;
397: try {
398: $task = $GLOBALS['registry']->tasks->getTask($this->_vars->list, $this->_vars->id);
399: if ($task) {
400: $result->task = $task->toJson(true, $GLOBALS['prefs']->getValue('twentyFour') ? 'H:i' : 'h:i A');
401: } else {
402: $GLOBALS['notification']->push(_("The requested task was not found."), 'horde.error');
403: }
404: } catch (Exception $e) {
405: $GLOBALS['notification']->push($e, 'horde.error');
406: }
407:
408: return $result;
409: }
410:
411: 412: 413:
414: public function saveTask()
415: {
416: if (!$GLOBALS['registry']->hasMethod('tasks/updateTask') ||
417: !$GLOBALS['registry']->hasMethod('tasks/addTask')) {
418: return false;
419: }
420:
421: $id = $this->_vars->task_id;
422: $list = $this->_vars->old_tasklist;
423: $task = $this->_vars->task;
424: $result = $this->_signedResponse('tasklists|tasks/' . $task['tasklist']);
425:
426: $due = trim($task['due_date'] . ' ' . $task['due_time']);
427: if (!empty($due)) {
428: try {
429: $due = Kronolith::parseDate($due);
430: $task['due'] = $due->timestamp();
431: } catch (Exception $e) {
432: $GLOBALS['notification']->push($e, 'horde.error');
433: return $result;
434: }
435: }
436:
437: if ($task['alarm']['on']) {
438: $value = $task['alarm']['value'];
439: $unit = $task['alarm']['unit'];
440: if ($value == 0) {
441: $value = $unit = 1;
442: }
443: $task['alarm'] = $value * $unit;
444: if (isset($task['alarm_methods']) && isset($task['methods'])) {
445: foreach (array_keys($task['methods']) as $method) {
446: if (!in_array($method, $task['alarm_methods'])) {
447: unset($task['methods'][$method]);
448: }
449: }
450: foreach ($task['alarm_methods'] as $method) {
451: if (!isset($task['methods'][$method])) {
452: $task['methods'][$method] = array();
453: }
454: }
455: } else {
456: $task['methods'] = array();
457: }
458: } else {
459: $task['alarm'] = 0;
460: $task['methods'] = array();
461: }
462: unset($task['alarm_methods']);
463:
464: if (!isset($task['completed'])) {
465: $task['completed'] = false;
466: }
467:
468: try {
469: $ids = ($id && $list)
470: ? $GLOBALS['registry']->tasks->updateTask($list, $id, $task)
471: : $GLOBALS['registry']->tasks->addTask($task);
472: if (!$id) {
473: $id = $ids[0];
474: }
475: $task = $GLOBALS['registry']->tasks->getTask($task['tasklist'], $id);
476: $result->tasks = array($id => $task->toJson(false, $GLOBALS['prefs']->getValue('twentyFour') ? 'H:i' : 'h:i A'));
477: $result->type = $task->completed ? 'complete' : 'incomplete';
478: $result->list = $task->tasklist;
479: } catch (Exception $e) {
480: $GLOBALS['notification']->push($e, 'horde.error');
481: return $result;
482: }
483:
484: if ($due &&
485: $kronolith_driver = $this->_getDriver('tasklists|tasks/' . $task->tasklist)) {
486: try {
487: $event = $kronolith_driver->getEvent('_tasks' . $id);
488: $end = clone $due;
489: $end->hour = 23;
490: $end->min = $end->sec = 59;
491: $start = clone $due;
492: $start->hour = $start->min = $start->sec = 0;
493: $events = array();
494: Kronolith::addEvents($events, $event, $start, $end, true, true);
495: if (count($events)) {
496: $result->events = $events;
497: }
498: } catch (Horde_Exception_NotFound $e) {
499: } catch (Exception $e) {
500: $GLOBALS['notification']->push($e, 'horde.error');
501: }
502: }
503:
504: return $result;
505: }
506:
507: 508: 509:
510: public function deleteTask()
511: {
512: $result = new stdClass;
513:
514: if (!$GLOBALS['registry']->hasMethod('tasks/deleteTask') ||
515: !isset($this->_vars->id) ||
516: !isset($this->_vars->list)) {
517: return $result;
518: }
519:
520: try {
521: $GLOBALS['registry']->tasks->deleteTask($this->_vars->list, $this->_vars->id);
522: $result->deleted = true;
523: } catch (Exception $e) {
524: $GLOBALS['notification']->push($e, 'horde.error');
525: }
526:
527: return $result;
528: }
529:
530: 531: 532:
533: public function toggleCompletion()
534: {
535: $result = new stdClass;
536:
537: if (!$GLOBALS['registry']->hasMethod('tasks/toggleCompletion')) {
538: return $result;
539: }
540:
541: try {
542: $GLOBALS['registry']->tasks->toggleCompletion($this->_vars->id, $this->_vars->list);
543: $result->toggled = true;
544: } catch (Exception $e) {
545: $GLOBALS['notification']->push($e, 'horde.error');
546: }
547:
548: return $result;
549: }
550:
551: 552: 553:
554: public function listTopTags()
555: {
556: $this->notify = false;
557: $tagger = new Kronolith_Tagger();
558: $result = new stdClass;
559: $result->tags = array();
560: $tags = $tagger->getCloud($GLOBALS['registry']->getAuth(), 10);
561: foreach ($tags as $tag) {
562: $result->tags[] = $tag['tag_name'];
563: }
564: return $result;
565: }
566:
567: 568: 569:
570: public function getFreeBusy()
571: {
572: $result = new stdClass;
573: try {
574: $result->fb = Kronolith_FreeBusy::get($this->_vars->email, true);
575: } catch (Exception $e) {
576: $GLOBALS['notification']->push($e->getMessage(), 'horde.warning');
577: }
578: return $result;
579: }
580:
581: 582: 583:
584: public function searchCalendars()
585: {
586: $result = new stdClass;
587: $result->events = 'Searched for calendars: ' . $this->_vars->title;
588: return $result;
589: }
590:
591: 592: 593:
594: public function saveCalendar()
595: {
596: $calendar_id = $this->_vars->calendar;
597: $result = new stdClass;
598:
599: switch ($this->_vars->type) {
600: case 'internal':
601: $info = array();
602: foreach (array('name', 'color', 'description', 'tags') as $key) {
603: $info[$key] = $this->_vars->$key;
604: }
605:
606:
607: if (!$calendar_id) {
608: if (!$GLOBALS['registry']->getAuth() ||
609: $GLOBALS['prefs']->isLocked('default_share')) {
610: return $result;
611: }
612: try {
613: $calendar = Kronolith::addShare($info);
614: Kronolith::readPermsForm($calendar);
615: if ($calendar->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) {
616: $wrapper = new Kronolith_Calendar_Internal(array('share' => $calendar));
617: $result->saved = true;
618: $result->id = $calendar->getName();
619: $result->calendar = $wrapper->toHash();
620: }
621: } catch (Exception $e) {
622: $GLOBALS['notification']->push($e, 'horde.error');
623: return $result;
624: }
625: $GLOBALS['notification']->push(sprintf(_("The calendar \"%s\" has been created."), $info['name']), 'horde.success');
626: break;
627: }
628:
629:
630: try {
631: $calendar = $GLOBALS['kronolith_shares']->getShare($calendar_id);
632: $original_name = $calendar->get('name');
633: $original_owner = $calendar->get('owner');
634: Kronolith::updateShare($calendar, $info);
635: Kronolith::readPermsForm($calendar);
636: if ($calendar->get('owner') != $original_owner) {
637: $result->deleted = true;
638: }
639: if ($calendar->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) {
640: $wrapper = new Kronolith_Calendar_Internal(array('share' => $calendar));
641: $result->saved = true;
642: $result->calendar = $wrapper->toHash();
643: }
644: } catch (Exception $e) {
645: $GLOBALS['notification']->push($e, 'horde.error');
646: return $result;
647:
648: }
649: if ($calendar->get('name') != $original_name) {
650: $GLOBALS['notification']->push(sprintf(_("The calendar \"%s\" has been renamed to \"%s\"."), $original_name, $calendar->get('name')), 'horde.success');
651: } else {
652: $GLOBALS['notification']->push(sprintf(_("The calendar \"%s\" has been saved."), $original_name), 'horde.success');
653: }
654: break;
655:
656: case 'tasklists':
657: $calendar = array();
658: foreach (array('name', 'color', 'description') as $key) {
659: $calendar[$key] = $this->_vars->$key;
660: }
661:
662:
663: if (!$calendar_id) {
664: if (!$GLOBALS['registry']->getAuth() ||
665: $GLOBALS['prefs']->isLocked('default_share')) {
666: return $result;
667: }
668: try {
669: $tasklistId = $GLOBALS['registry']->tasks->addTasklist($calendar['name'], $calendar['description'], $calendar['color']);
670: $tasklists = $GLOBALS['registry']->tasks->listTasklists(true);
671: if (!isset($tasklists[$tasklistId])) {
672: $GLOBALS['notification']->push(_("Added task list not found."), 'horde.error');
673: return $result;
674: }
675: $tasklist = $tasklists[$tasklistId];
676: Kronolith::readPermsForm($tasklist);
677: if ($tasklist->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) {
678: $wrapper = new Kronolith_Calendar_External_Tasks(array('api' => 'tasks', 'name' => $tasklistId, 'share' => $tasklist));
679:
680:
681: $all_external = $GLOBALS['session']->get('kronolith', 'all_external_calendars');
682: $all_external[] = array('a' => 'tasks', 'n' => $tasklistId, 'd' => $tasklist->get('name'));
683: $GLOBALS['session']->set('kronolith', 'all_external_calendars', $all_external);
684: $GLOBALS['display_external_calendars'][] = 'tasks/' . $tasklistId;
685: $GLOBALS['prefs']->setValue('display_external_cals', serialize($GLOBALS['display_external_calendars']));
686: $GLOBALS['all_external_calendars']['tasks/' . $tasklistId] = $wrapper;
687:
688: $result->saved = true;
689: $result->id = 'tasks/' . $tasklistId;
690: $result->calendar = $wrapper->toHash();
691: }
692: } catch (Exception $e) {
693: $GLOBALS['notification']->push($e, 'horde.error');
694: return $result;
695: }
696: $GLOBALS['notification']->push(sprintf(_("The task list \"%s\" has been created."), $calendar['name']), 'horde.success');
697: break;
698: }
699:
700:
701: $calendar_id = substr($calendar_id, 6);
702: try {
703: $GLOBALS['registry']->tasks->updateTasklist($calendar_id, $calendar);
704: $tasklists = $GLOBALS['registry']->tasks->listTasklists(true, Horde_Perms::EDIT);
705: $tasklist = $tasklists[$calendar_id];
706: $original_owner = $tasklist->get('owner');
707: Kronolith::readPermsForm($tasklist);
708: if ($tasklist->get('owner') != $original_owner) {
709: $result->deleted = true;
710: }
711: if ($tasklist->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) {
712: $wrapper = new Kronolith_Calendar_External_Tasks(array('api' => 'tasks', 'name' => $calendar_id, 'share' => $tasklist));
713: $result->saved = true;
714: $result->calendar = $wrapper->toHash();
715: }
716: } catch (Exception $e) {
717: $GLOBALS['notification']->push($e, 'horde.error');
718: return $result;
719: }
720: if ($tasklist->get('name') != $calendar['name']) {
721: $GLOBALS['notification']->push(sprintf(_("The task list \"%s\" has been renamed to \"%s\"."), $tasklist->get('name'), $calendar['name']), 'horde.success');
722: } else {
723: $GLOBALS['notification']->push(sprintf(_("The task list \"%s\" has been saved."), $tasklist->get('name')), 'horde.success');
724: }
725: break;
726:
727: case 'remote':
728: $calendar = array();
729: foreach (array('name', 'desc', 'url', 'color', 'user', 'password') as $key) {
730: $calendar[$key] = $this->_vars->$key;
731: }
732: try {
733: Kronolith::subscribeRemoteCalendar($calendar, $calendar_id);
734: } catch (Exception $e) {
735: $GLOBALS['notification']->push($e, 'horde.error');
736: return $result;
737: }
738: if ($calendar_id) {
739: $GLOBALS['notification']->push(sprintf(_("The calendar \"%s\" has been saved."), $calendar['name']), 'horde.success');
740: } else {
741: $GLOBALS['notification']->push(sprintf(_("You have been subscribed to \"%s\" (%s)."), $calendar['name'], $calendar['url']), 'horde.success');
742: $result->id = $calendar['url'];
743: }
744: $wrapper = new Kronolith_Calendar_Remote($calendar);
745: $result->saved = true;
746: $result->calendar = $wrapper->toHash();
747: break;
748: }
749:
750: return $result;
751: }
752:
753: 754: 755:
756: public function deleteCalendar()
757: {
758: $calendar_id = $this->_vars->calendar;
759: $result = new stdClass;
760:
761: switch ($this->_vars->type) {
762: case 'internal':
763: try {
764: $calendar = $GLOBALS['kronolith_shares']->getShare($calendar_id);
765: } catch (Exception $e) {
766: $GLOBALS['notification']->push($e, 'horde.error');
767: return $result;
768: }
769: try {
770: Kronolith::deleteShare($calendar);
771: } catch (Exception $e) {
772: $GLOBALS['notification']->push(sprintf(_("Unable to delete \"%s\": %s"), $calendar->get('name'), $e->getMessage()), 'horde.error');
773: return $result;
774: }
775: $GLOBALS['notification']->push(sprintf(_("The calendar \"%s\" has been deleted."), $calendar->get('name')), 'horde.success');
776: break;
777:
778: case 'tasklists':
779: $calendar_id = substr($calendar_id, 6);
780: $tasklists = $GLOBALS['registry']->tasks->listTasklists(true);
781: if (!isset($tasklists[$calendar_id])) {
782: $GLOBALS['notification']->push(_("You are not allowed to delete this task list."), 'horde.error');
783: return $result;
784: }
785: try {
786: $GLOBALS['registry']->tasks->deleteTasklist($calendar_id);
787: } catch (Exception $e) {
788: $GLOBALS['notification']->push(sprintf(_("Unable to delete \"%s\": %s"), $tasklists[$calendar_id]->get('name'), $e->getMessage()), 'horde.error');
789: return $result;
790: }
791: $GLOBALS['notification']->push(sprintf(_("The task list \"%s\" has been deleted."), $tasklists[$calendar_id]->get('name')), 'horde.success');
792: break;
793:
794: case 'remote':
795: try {
796: $deleted = Kronolith::unsubscribeRemoteCalendar($calendar_id);
797: } catch (Exception $e) {
798: $GLOBALS['notification']->push($e, 'horde.error');
799: return $result;
800: }
801: $GLOBALS['notification']->push(sprintf(_("You have been unsubscribed from \"%s\" (%s)."), $deleted['name'], $deleted['url']), 'horde.success');
802: break;
803: }
804:
805: $result->deleted = true;
806:
807: return $result;
808: }
809:
810: 811: 812:
813: public function getCalendar()
814: {
815: $result = new stdClass;
816: if (!isset($GLOBALS['all_calendars'][$this->_vars->cal])) {
817: $GLOBALS['notification']->push(_("You are not allowed to view this calendar."), 'horde.error');
818: return $result;
819: }
820: $calendar = $GLOBALS['all_calendars'][$this->_vars->cal];
821: $tagger = Kronolith::getTagger();
822: $result->calendar = $calendar->toHash();
823: return $result;
824: }
825:
826: 827: 828:
829: public function getRemoteInfo()
830: {
831: $params = array('timeout' => 15);
832: if ($user = $this->_vars->user) {
833: $params['user'] = $user;
834: $params['password'] = $this->_vars->password;
835: }
836: if (!empty($GLOBALS['conf']['http']['proxy']['proxy_host'])) {
837: $params['proxy'] = $GLOBALS['conf']['http']['proxy'];
838: }
839:
840: $result = new stdClass;
841: try {
842: $driver = $GLOBALS['injector']->getInstance('Kronolith_Factory_Driver')->create('Ical', $params);
843: $driver->open($this->_vars->url);
844: if ($driver->isCalDAV()) {
845: $result->success = true;
846:
847: } else {
848: $ical = $driver->getRemoteCalendar(false);
849: $result->success = true;
850: try {
851: $name = $ical->getAttribute('X-WR-CALNAME');
852: $result->name = $name;
853: } catch (Horde_Icalendar_Exception $e) {}
854: try {
855: $desc = $ical->getAttribute('X-WR-CALDESC');
856: $result->desc = $desc;
857: } catch (Horde_Icalendar_Exception $e) {}
858: }
859: } catch (Exception $e) {
860: if ($e->getCode() == 401) {
861: $result->auth = true;
862: } else {
863: $GLOBALS['notification']->push($e, 'horde.error');
864: }
865: }
866:
867: return $result;
868: }
869:
870: 871: 872:
873: public function saveCalPref()
874: {
875: return false;
876: }
877:
878: 879: 880: 881: 882: 883: 884:
885: protected function _getDriver($cal)
886: {
887: list($driver, $calendar) = explode('|', $cal);
888: if ($driver == 'internal' &&
889: !Kronolith::hasPermission($calendar, Horde_Perms::SHOW)) {
890: $GLOBALS['notification']->push(_("Permission Denied"), 'horde.error');
891: return false;
892: }
893: try {
894: $kronolith_driver = Kronolith::getDriver($driver, $calendar);
895: } catch (Exception $e) {
896: $GLOBALS['notification']->push($e, 'horde.error');
897: return false;
898: }
899: if ($driver == 'remote') {
900: $kronolith_driver->setParam('timeout', 15);
901: }
902: return $kronolith_driver;
903: }
904:
905: 906: 907: 908: 909: 910: 911: 912: 913: 914: 915: 916:
917: protected function _saveEvent(Kronolith_Event $event,
918: Kronolith_Event $original = null,
919: $attributes = null)
920: {
921: if ($this->_vars->targetcalendar) {
922: $cal = $this->_vars->targetcalendar;
923: } elseif ($this->_vars->cal) {
924: $cal = $this->_vars->cal;
925: } else {
926: $cal = $event->calendarType . '|' . $event->calendar;
927: }
928: $result = $this->_signedResponse($cal);
929: if (!$this->_vars->view_start || !$this->_vars->view_end) {
930: $result->events = array();
931: return $result;
932: }
933:
934: try {
935: $event->save();
936: $end = new Horde_Date($this->_vars->view_end);
937: $end->hour = 23;
938: $end->min = $end->sec = 59;
939: $events = array();
940: Kronolith::addEvents($events, $event,
941: new Horde_Date($this->_vars->view_start),
942: $end, true, true);
943:
944:
945: 946: 947:
948: if (!empty($original)) {
949: Kronolith::addEvents($events, $original,
950: new Horde_Date($attributes->cstart),
951: new Horde_Date($attributes->cend),
952: true, true);
953: }
954: $result->events = count($events) ? $events : array();
955: } catch (Exception $e) {
956: $GLOBALS['notification']->push($e, 'horde.error');
957: }
958: return $result;
959: }
960:
961: 962: 963: 964: 965: 966: 967:
968: protected function _signedResponse($calendar)
969: {
970: $result = new stdClass;
971: $result->cal = $calendar;
972: $result->view = $this->_vars->view;
973: $result->sig = $this->_vars->sig;
974: return $result;
975: }
976:
977: 978: 979: 980: 981: 982: 983: 984: 985: 986: 987: 988:
989: protected function _createExceptionEvent(Kronolith_Event $event, $attributes)
990: {
991:
992: if ($attributes->rstart) {
993: $rstart = new Horde_Date($attributes->rstart);
994: $rstart->setTimezone($event->start->timezone);
995: $rend = new Horde_Date($attributes->rend);
996: $rend->setTimezone($event->end->timezone);
997: } else {
998: $rstart = new Horde_Date($attributes->rday);
999: $rstart->setTimezone($event->start->timezone);
1000: $rstart->hour = $event->start->hour;
1001: $rstart->min = $event->start->min;
1002: $rend = $rstart->add($event->getDuration);
1003: $rend->setTimezone($event->end->timezone);
1004: $rend->hour = $event->end->hour;
1005: $rend->min = $event->end->min;
1006: }
1007:
1008: $event->recurrence->addException($rstart->year, $rstart->month, $rstart->mday);
1009: $event->save();
1010: $uid = $event->uid;
1011: $otime = $event->start->strftime('%T');
1012:
1013:
1014: $nevent = $event->getDriver()->getEvent();
1015: $nevent->baseid = $uid;
1016: $nevent->exceptionoriginaldate = new Horde_Date($rstart->strftime('%Y-%m-%d') . 'T' . $otime);
1017: $nevent->creator = $event->creator;
1018: $nevent->title = $event->title;
1019: $nevent->description = $event->description;
1020: $nevent->location = $event->location;
1021: $nevent->private = $event->private;
1022: $nevent->url = $event->url;
1023: $nevent->status = $event->status;
1024: $nevent->attendees = $event->attendees;
1025:
1026: $nevent->start = $rstart;
1027: $nevent->end = $rend;
1028: $nevent->initialized = true;
1029:
1030: return $nevent;
1031: }
1032: }
1033: