From 0c16a057ab7863b20bd315895e498bf2ffa74031 Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Wed, 11 Aug 2010 00:53:29 +0200 Subject: [PATCH] Add light wrappers classes for individual calendars, so that we have a common calendar API independent of the underlying driver. Prepare to edit/add events in drivers other than the internal drivers. --- kronolith/calendars/index.php | 2 +- kronolith/calendars/info.php | 4 +- kronolith/data.php | 57 +++--- kronolith/edit.php | 171 +++++++++++------- kronolith/js/kronolith.js | 4 +- kronolith/lib/Ajax/Application.php | 18 +- kronolith/lib/Api.php | 53 +++--- kronolith/lib/Application.php | 5 +- kronolith/lib/Block/month.php | 61 ++----- kronolith/lib/Block/monthlist.php | 42 ++--- kronolith/lib/Block/prevmonthlist.php | 24 ++- kronolith/lib/Block/summary.php | 49 ++---- kronolith/lib/Calendar.php | 121 +++++++++++++ kronolith/lib/Calendar/External.php | 78 +++++++++ kronolith/lib/Calendar/Holiday.php | 57 ++++++ kronolith/lib/Calendar/Internal.php | 123 +++++++++++++ kronolith/lib/Calendar/Remote.php | 165 ++++++++++++++++++ kronolith/lib/Driver/Ical.php | 29 +-- kronolith/lib/Driver/Kolab.php | 8 +- kronolith/lib/Driver/Sql.php | 10 +- kronolith/lib/Event.php | 2 +- kronolith/lib/Event/Ical.php | 15 +- kronolith/lib/Event/Sql.php | 8 +- kronolith/lib/Kronolith.php | 242 ++++++++++++++++---------- kronolith/lib/LoginTasks/Task/PurgeEvents.php | 2 +- kronolith/lib/View/Day.php | 15 +- kronolith/lib/View/EditEvent.php | 15 +- kronolith/lib/View/Month.php | 6 +- kronolith/lib/View/Week.php | 12 +- kronolith/new.php | 15 +- kronolith/search.php | 24 ++- kronolith/templates/calendar_titles.inc | 2 +- kronolith/templates/data/export.inc | 8 +- kronolith/templates/data/import.inc | 8 +- kronolith/templates/edit/edit.inc | 8 +- kronolith/templates/panel.inc | 25 ++- 36 files changed, 1002 insertions(+), 486 deletions(-) create mode 100644 kronolith/lib/Calendar.php create mode 100644 kronolith/lib/Calendar/External.php create mode 100644 kronolith/lib/Calendar/Holiday.php create mode 100644 kronolith/lib/Calendar/Internal.php create mode 100644 kronolith/lib/Calendar/Remote.php diff --git a/kronolith/calendars/index.php b/kronolith/calendars/index.php index e2485c761..b4f4587fe 100644 --- a/kronolith/calendars/index.php +++ b/kronolith/calendars/index.php @@ -49,7 +49,7 @@ $subscribe_url_base = Horde::url($subscribe_url_base, true, -1); $calendars = array(); $sorted_calendars = array(); -$my_calendars = Kronolith::listCalendars(true); +$my_calendars = Kronolith::listInternalCalendars(true); foreach ($my_calendars as $calendar) { $calendars[$calendar->getName()] = $calendar; $sorted_calendars[$calendar->getName()] = $calendar->get('name'); diff --git a/kronolith/calendars/info.php b/kronolith/calendars/info.php index 52cb36809..6a9fa7ece 100644 --- a/kronolith/calendars/info.php +++ b/kronolith/calendars/info.php @@ -30,8 +30,8 @@ if (strncmp($calendarId, 'remote_', 7) === 0) { $rewrite = isset($conf['urls']['pretty']) && $conf['urls']['pretty'] == 'rewrite'; $subscribe_url = Horde::url($registry->get('webroot', 'horde') . ($rewrite ? '/rpc/kronolith/' : '/rpc.php/kronolith/'), true, -1) - . ($calendar->get('owner') ? $calendar->get('owner') : '-system-') - . '/' . $calendar->getName() . '.ics'; + . ($calendar->owner() ? $calendar->owner() : '-system-') + . '/' . $calendarId . '.ics'; } if (is_null($calendar)) { diff --git a/kronolith/data.php b/kronolith/data.php index 56e2273ea..246471446 100644 --- a/kronolith/data.php +++ b/kronolith/data.php @@ -81,7 +81,6 @@ $param = array('time_fields' => $time_fields, 'file_types' => $file_types); $import_format = Horde_Util::getFormData('import_format', ''); $error = false; -$kronolith_driver = Kronolith::getDriver(); /* Loop through the action handlers. */ switch ($actionID) { @@ -105,17 +104,17 @@ case 'export': } $exportID = Horde_Util::getFormData('exportID'); - foreach ($calendars as $cal) { - if ($kronolith_driver->calendar != $cal) { - $kronolith_driver->open($cal); - } - $events[$cal] = $kronolith_driver->listEvents($start, // Start date - $end, // End date - false, // Only return recurrences once - false, // Don't limit to alarms - false, // Don't cache json - false, // Don't add events to all days - ($exportID == Horde_Data::EXPORT_ICALENDAR) ? true : false); // Don't return exception events + foreach ($calendars as $calendar) { + list($type, $cal) = explode('_', $calendar, 2); + $kronolith_driver = Kronolith::getDriver($type, $cal); + $events[$calendar] = $kronolith_driver->listEvents( + $start, // Start date + $end, // End date + false, // Only return recurrences once + false, // Don't limit to alarms + false, // Don't cache json + false, // Don't add events to all days + ($exportID == Horde_Data::EXPORT_ICALENDAR) ? true : false); // Don't return exception events } if (!$events) { @@ -127,7 +126,7 @@ case 'export': switch ($exportID) { case Horde_Data::EXPORT_CSV: $data = array(); - foreach ($events as $cal => $calevents) { + foreach ($events as $calevents) { foreach ($calevents as $dayevents) { foreach ($dayevents as $event) { $row = array(); @@ -168,7 +167,7 @@ case 'export': $iCal = new Horde_Icalendar(); $calIds = array(); - foreach ($events as $cal => $calevents) { + foreach ($events as $calevents) { foreach ($calevents as $dayevents) { foreach ($dayevents as $event) { $calIds[$event->calendar] = true; @@ -205,8 +204,7 @@ if (!$error && $import_format) { if ($actionID == Horde_Data::IMPORT_FILE) { $cleanup = true; try { - $share = $kronolith_shares->getShare($_SESSION['import_data']['import_cal']); - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) { + if (!in_array($_SESSION['import_data']['import_cal'], Kronolith::listCalendars(Horde_Perms::EDIT))) { $notification->push(_("You do not have permission to add events to the selected calendar."), 'horde.error'); } else { $next_step = $data->nextStep($actionID, $param); @@ -241,7 +239,8 @@ if (is_array($next_step)) { if ($max_events !== true) { $num_events = Kronolith::countEvents(); } - $kronolith_driver->open($_SESSION['import_data']['import_cal']); + list($type, $calendar) = explode('_', $_SESSION['import_data']['import_cal'], 2); + $kronolith_driver = Kronolith::getDriver($type, $calendar); if (!count($next_step)) { $notification->push(sprintf(_("The %s file didn't contain any events."), @@ -251,7 +250,7 @@ if (is_array($next_step)) { /* Purge old calendar if requested. */ if ($_SESSION['import_data']['purge']) { try { - $kronolith_driver->delete($_SESSION['import_data']['import_cal']); + $kronolith_driver->delete($calendar); $notification->push(_("Calendar successfully purged."), 'horde.success'); } catch (Exception $e) { $notification->push(sprintf(_("The calendar could not be purged: %s"), $e->getMessage()), 'horde.error'); @@ -332,7 +331,7 @@ if (is_array($next_step)) { $notification->push(sprintf(_("%s file successfully imported"), $file_types[$_SESSION['import_data']['format']]), 'horde.success'); if (Horde_Util::getFormData('import_ajax')) { - Horde::addInlineScript('window.parent.KronolithCore.loadCalendar(\'internal\', \'' . $_SESSION['import_data']['import_cal'] . '\');'); + Horde::addInlineScript('window.parent.KronolithCore.loadCalendar(\'' . $type . '\', \'' . $calendar . '\');'); } } $next_step = $data->cleanup(); @@ -350,25 +349,9 @@ if (Horde_Util::getFormData('import_ajax')) { $import_calendars = $export_calendars = array(); if ($GLOBALS['registry']->getAuth()) { - $calendars = Kronolith::listCalendars(false, Horde_Perms::EDIT); - foreach ($calendars as $id => $calendar) { - if ($calendar->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($calendar->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $import_calendars[$id] = $calendar; - } -} -$calendars = Kronolith::listCalendars(false, Horde_Perms::READ); -foreach ($calendars as $id => $calendar) { - if ($calendar->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($calendar->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $export_calendars[$id] = $calendar; + $import_calendars = Kronolith::listCalendars(Horde_Perms::EDIT, true); } +$export_calendars = Kronolith::listCalendars(Horde_Perms::READ, true); $title = _("Import/Export Calendar"); require KRONOLITH_TEMPLATES . '/common-header.inc'; diff --git a/kronolith/edit.php b/kronolith/edit.php index 4fb89220c..cf555a6f5 100644 --- a/kronolith/edit.php +++ b/kronolith/edit.php @@ -46,43 +46,74 @@ if (Kronolith::showAjaxView()) { Horde::applicationUrl('', true)->redirect(); } -$kronolith_driver = Kronolith::getDriver(); +do { + if ($exception = Horde_Util::getFormData('del_exception')) { + /* Deleting recurrence exceptions. */ + list($type, $calendar) = explode('_', Horde_Util::getFormData('calendar'), 2); + try { + $kronolith_driver = Kronolith::getDriver($type, $calendar); + switch ($type) { + case 'internal': + $kronolith_calendar = $all_calendars[$calendar]; + break; + case 'remote': + $kronolith_calendar = $all_remote_calendars[$calendar]; + break; + } -if ($exception = Horde_Util::getFormData('del_exception')) { - $calendar = Horde_Util::getFormData('calendar'); - try { - $share = Kronolith::getInternalCalendar($calendar); - $kronolith_driver->open($calendar); - $event = $kronolith_driver->getEvent(Horde_Util::getFormData('eventID')); - $result = sscanf($exception, '%04d%02d%02d', $year, $month, $day); - if ($result == 3 && $event->recurs()) { - $event->recurrence->deleteException($year, $month, $day); - _save($event); + $event = $kronolith_driver->getEvent(Horde_Util::getFormData('eventID')); + if (!$kronolith_calendar->hasPermission($registry->getAuth(), Horde_Perms::EDIT, $event->creator)) { + $notification->push(_("You do not have permission to edit this event."), 'horde.warning'); + break; + } + $result = sscanf($exception, '%04d%02d%02d', $year, $month, $day); + if ($result == 3 && $event->recurs()) { + $event->recurrence->deleteException($year, $month, $day); + _save($event); + } + } catch (Exception $e) { + $notification->push(sprintf(_("There was an error accessing the calendar: %s"), $e->getMessage()), 'horde.error'); } - } catch (Exception $e) { - $notification->push(sprintf(_("There was an error accessing the calendar: %s"), $e->getMessage()), 'horde.error'); + break; + } + + if (Horde_Util::getFormData('cancel')) { + break; } -} elseif (!Horde_Util::getFormData('cancel')) { - $source = Horde_Util::getFormData('existingcalendar'); - $targetcalendar = Horde_Util::getFormData('targetcalendar'); + + list($sourceType, $source) = explode('_', Horde_Util::getFormData('existingcalendar'), 2); + list($targetType, $targetcalendar) = explode('_', Horde_Util::getFormData('targetcalendar'), 2); if (strpos($targetcalendar, ':')) { list($target, $user) = explode(':', $targetcalendar, 2); } else { $target = $targetcalendar; $user = $GLOBALS['registry']->getAuth(); } + try { - $share = Kronolith::getInternalCalendar($target); $event = false; if (($edit_recur = Horde_Util::getFormData('edit_recur')) && $edit_recur != 'all' && $edit_recur != 'copy' && - _check_max()) { + ($targetType != 'internal' || _check_max())) { + /* Edit a recurring exception. */ /* Get event details. */ - $kronolith_driver->open($source); + $kronolith_driver = Kronolith::getDriver($sourceType, $source); + switch ($sourceType) { + case 'internal': + $kronolith_calendar = $all_calendars[$source]; + break; + case 'remote': + $kronolith_calendar = $all_remote_calendars[$source]; + break; + } $event = $kronolith_driver->getEvent(Horde_Util::getFormData('eventID')); - $recur_ex = Horde_Util::getFormData('recur_ex'); - $exception = new Horde_Date($recur_ex); + if (!$event->hasPermission(Horde_Perms::EDIT)) { + $notification->push(_("You do not have permission to edit this event."), 'horde.warning'); + break; + } + + $exception = new Horde_Date(Horde_Util::getFormData('recur_ex')); switch ($edit_recur) { case 'current': @@ -95,7 +126,6 @@ if ($exception = Horde_Util::getFormData('del_exception')) { $originaltime = $event->start->strftime('%T'); /* Create one-time event. */ - $kronolith_driver->open($target); $event = $kronolith_driver->getEvent(); $event->readForm(); $event->baseid = $uid; @@ -106,7 +136,8 @@ if ($exception = Horde_Util::getFormData('del_exception')) { case 'future': /* Set recurrence end. */ $exception->mday--; - if ($event->end->compareDate($exception) > 0) { + if ($event->end->compareDate($exception) > 0 && + $event->hasPermission(Horde_Perms::DELETE)) { try { $kronolith_driver->deleteEvent($event->id); } catch (Exception $e) { @@ -118,7 +149,6 @@ if ($exception = Horde_Util::getFormData('del_exception')) { } /* Create new event. */ - $kronolith_driver->open($target); $event = $kronolith_driver->getEvent(); $event->readForm(); @@ -127,61 +157,78 @@ if ($exception = Horde_Util::getFormData('del_exception')) { $event->uid = null; _save($event); - $event = null; - } elseif (Horde_Util::getFormData('saveAsNew') || - $edit_recur == 'copy') { - if (_check_max()) { - $kronolith_driver->open($target); - $event = $kronolith_driver->getEvent(); + break; + } + + /* Permission checks on the target calendar . */ + switch ($targetType) { + case 'internal': + $kronolith_calendar = $all_calendars[$target]; + break; + case 'remote': + $kronolith_calendar = $all_remote_calendars[$target]; + break; + default: + break 2; + } + if ($user == $GLOBALS['registry']->getAuth() && + !$kronolith_calendar->hasPermission(Horde_Perms::EDIT)) { + $notification->push(_("You do not have permission to edit this event."), 'horde.warning'); + break; + } + if ($user != $GLOBALS['registry']->getAuth() && + !$kronolith_calendar->hasPermission(Kronolith::PERMS_DELEGATE)) { + $notification->push(sprintf(_("You do not have permission to delegate events to %s."), Kronolith::getUserName($user)), 'horde.warning'); + break; + } + + if (Horde_Util::getFormData('saveAsNew') || $edit_recur == 'copy') { + /* Creating a copy of the event. */ + if ($targetType == 'internal' && !_check_max()) { + break; } + $kronolith_driver = Kronolith::getDriver($targetType, $target); + $event = $kronolith_driver->getEvent(); } else { - $event_load_from = $source; + /* Regular saving of event. */ + $eventId = Horde_Util::getFormData('eventID'); + $kronolith_driver = Kronolith::getDriver($sourceType, $source); + $event = $kronolith_driver->getEvent($eventId); if ($target != $source) { - // Only delete the event from the source calendar if this user - // has permissions to do so. - try { - $sourceShare = Kronolith::getInternalCalendar($source); - if ($sourceShare->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE) && - (($user == $GLOBALS['registry']->getAuth() && - $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) || - ($user != $GLOBALS['registry']->getAuth() && - $share->hasPermission($GLOBALS['registry']->getAuth(), Kronolith::PERMS_DELEGATE)))) { - $kronolith_driver->open($source); + /* Moving the event to a different calendar. Only delete the + * event from the source calendar if this user has permissions + * to do so. */ + if (!$event->hasPermission(Horde_Perms::DELETE)) { + $notification->push(_("You do not have permission to move this event."), 'horde.warning'); + } else { + if ($sourceType == 'internal' && + $targetType == 'internal') { try { - $kronolith_driver->move(Horde_Util::getFormData('eventID'), $target); - $event_load_from = $target; + // TODO: abstract this out. + $kronolith_driver->move($eventId, $target); + $kronolith_driver->open($target); + $event = $kronolith_driver->getEvent($eventId); } catch (Exception $e) { $notification->push(sprintf(_("There was an error moving the event: %s"), $e->getMessage()), 'horde.error'); } + } else { + $kronolith_driver->deleteEvent($eventId); + $kronolith_driver = Kronolith::getDriver($targetType, $target); + $event = $kronolith_driver->getEvent(); } - } catch (Exception $e) { } } - - $kronolith_driver->open($event_load_from); - $event = $kronolith_driver->getEvent(Horde_Util::getFormData('eventID')); } if ($event) { - if (isset($sourceShare) - && !$sourceShare->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)) { - $notification->push(_("You do not have permission to move this event."), 'horde.warning'); - } elseif ($user != $GLOBALS['registry']->getAuth() && - !$share->hasPermission($GLOBALS['registry']->getAuth(), Kronolith::PERMS_DELEGATE, $event->creator)) { - $notification->push(sprintf(_("You do not have permission to delegate events to %s."), Kronolith::getUserName($user)), 'horde.warning'); - } elseif ($user == $GLOBALS['registry']->getAuth() && - !$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT, $event->creator)) { - $notification->push(_("You do not have permission to edit this event."), 'horde.warning'); - } else { - $event->readForm(); - _save($event); - } + $event->readForm(); + _save($event); } } catch (Exception $e) { $notification->push(sprintf(_("There was an error accessing the calendar: %s"), $e->getMessage()), 'horde.error'); } -} +} while (false); $url = Horde_Util::getFormData('url'); if (!empty($url)) { @@ -192,5 +239,5 @@ if (!empty($url)) { 'year' => Horde_Util::getFormData('year'))); } -// Make sure URL is unique. +/* Make sure URL is unique. */ $url->unique()->redirect(); diff --git a/kronolith/js/kronolith.js b/kronolith/js/kronolith.js index b38ca8248..348258894 100644 --- a/kronolith/js/kronolith.js +++ b/kronolith/js/kronolith.js @@ -2888,7 +2888,7 @@ KronolithCore = { switch (type) { case 'internal': this.calendarTagAc.reset(Kronolith.conf.calendars.internal[calendar].tg); - $('kronolithCalendar' + type + 'ImportCal').setValue(calendar); + $('kronolithCalendar' + type + 'ImportCal').setValue('internal_' + calendar); if (info.edit) { $('kronolithCalendar' + type + 'LinkImport').up('li').show(); } else { @@ -2901,7 +2901,7 @@ KronolithCore = { $('kronolithCalendar' + type + 'Description').setValue(info.desc); $('kronolithCalendar' + type + 'LinkExport').up('span').show(); $('kronolithCalendar' + type + 'Export').href = type == 'internal' - ? Kronolith.conf.URI_CALENDAR_EXPORT + '=' + calendar + ? Kronolith.conf.URI_CALENDAR_EXPORT + calendar : Kronolith.conf.tasks.URI_TASKLIST_EXPORT + '=' + calendar.substring(6); $('kronolithCalendar' + type + 'LinkUrls').up().show(); $('kronolithCalendar' + type + 'UrlSub').setValue(info.sub); diff --git a/kronolith/lib/Ajax/Application.php b/kronolith/lib/Ajax/Application.php index 6956c6964..fc3e2dcd7 100644 --- a/kronolith/lib/Ajax/Application.php +++ b/kronolith/lib/Ajax/Application.php @@ -666,7 +666,7 @@ class Kronolith_Ajax_Application extends Horde_Core_Ajax_Application return $result; } $tasklist = $tasklists[$tasklistId]; - $_SESSION['all_external_calendars']['tasks'][$tasklistId] = $tasklist->get('name'); + $_SESSION['all_external_calendars']['tasks/' . $tasklistId] = new Kronolith_Calendar_External(array('api' => 'tasks', 'name' => $tasklist->get('name'))); $GLOBALS['display_external_calendars'][] = 'tasks/' . $tasklistId; $GLOBALS['prefs']->setValue('display_external_cals', serialize($GLOBALS['display_external_calendars'])); Kronolith::readPermsForm($tasklist); @@ -794,15 +794,15 @@ class Kronolith_Ajax_Application extends Horde_Core_Ajax_Application $calendar = $GLOBALS['all_calendars'][$this->_vars->cal]; $tagger = Kronolith::getTagger(); $result->calendar = array( - 'name' => (!$calendar->get('owner') ? '' : '[' . $GLOBALS['registry']->convertUsername($calendar->get('owner'), false) . '] ') . $calendar->get('name'), - 'desc' => $calendar->get('desc'), + 'name' => (!$calendar->owner() ? '' : '[' . $GLOBALS['registry']->convertUsername($calendar->owner(), false) . '] ') . $calendar->name(), + 'desc' => $calendar->description(), 'owner' => false, - 'fg' => Kronolith::foregroundColor($calendar), - 'bg' => Kronolith::backgroundColor($calendar), + 'fg' => $calendar->foreground(), + 'bg' => $calendar->background(), 'show' => false, - 'perms' => Kronolith::permissionToJson($calendar->getPermission()), - 'edit' => $calendar->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT), - 'tg' => array_values($tagger->getTags($calendar->getName(), 'calendar'))); + 'perms' => Kronolith::permissionToJson($calendar->permission()), + 'edit' => $calendar->hasPermission(Horde_Perms::EDIT), + 'tg' => array_values($tagger->getTags($this->_vars->cal, 'calendar'))); return $result; } @@ -865,7 +865,7 @@ class Kronolith_Ajax_Application extends Horde_Core_Ajax_Application list($driver, $calendar) = explode('|', $cal); if ($driver == 'internal' && !array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::SHOW))) { + Kronolith::listInternalCalendars(false, Horde_Perms::SHOW))) { $GLOBALS['notification']->push(_("Permission Denied"), 'horde.error'); return false; } diff --git a/kronolith/lib/Api.php b/kronolith/lib/Api.php index edbb5c614..ea767cb79 100644 --- a/kronolith/lib/Api.php +++ b/kronolith/lib/Api.php @@ -72,7 +72,7 @@ class Kronolith_Api extends Horde_Registry_Api if (empty($path)) { // This request is for a list of all users who have calendars // visible to the requesting user. - $calendars = Kronolith::listCalendars(false, Horde_Perms::READ); + $calendars = Kronolith::listInternalCalendars(false, Horde_Perms::READ); $owners = array(); foreach ($calendars as $calendar) { if ($calendar->get('owner') != $GLOBALS['registry']->getAuth() && @@ -175,7 +175,7 @@ class Kronolith_Api extends Horde_Registry_Api return $results; } elseif (count($parts) == 2 && - array_key_exists($parts[1], Kronolith::listCalendars(false, Horde_Perms::READ))) { + array_key_exists($parts[1], Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { // This request is browsing into a specific calendar. Generate // the list of items and represent them as files within the // directory. @@ -221,7 +221,7 @@ class Kronolith_Api extends Horde_Registry_Api // The only valid request left is for either a specific event or // for the entire calendar. if (count($parts) == 3 && - array_key_exists($parts[1], Kronolith::listCalendars(false, Horde_Perms::READ))) { + array_key_exists($parts[1], Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { // This request is for a specific item within a given calendar. $event = Kronolith::getDriver(null, $parts[1])->getEvent($parts[2]); @@ -235,7 +235,7 @@ class Kronolith_Api extends Horde_Registry_Api return $result; } elseif (count($parts) == 2 && substr($parts[1], -4, 4) == '.ics' && - array_key_exists(substr($parts[1], 0, -4), Kronolith::listCalendars(false, Horde_Perms::READ))) { + array_key_exists(substr($parts[1], 0, -4), Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { // This request is for an entire calendar (calendar.ics). $ical_data = $this->exportCalendar(substr($parts[1], 0, -4), 'text/calendar'); $result = array('data' => $ical_data, @@ -287,7 +287,7 @@ class Kronolith_Api extends Horde_Registry_Api throw new Kronolith_Exception("Invalid calendar data supplied."); } - if (!array_key_exists($calendar, Kronolith::listCalendars(false, Horde_Perms::EDIT))) { + if (!array_key_exists($calendar, Kronolith::listInternalCalendars(false, Horde_Perms::EDIT))) { // FIXME: Should we attempt to create a calendar based on the // filename in the case that the requested calendar does not // exist? @@ -366,7 +366,7 @@ class Kronolith_Api extends Horde_Registry_Api throw new Kronolith_Exception(sprintf(_("Unsupported Content-Type: %s"), $content_type)); } - if (array_key_exists($calendar, Kronolith::listCalendars(false, Horde_Perms::DELETE))) { + if (array_key_exists($calendar, Kronolith::listInternalCalendars(false, Horde_Perms::DELETE))) { foreach (array_keys($uids_remove) as $uid) { $this->delete($uid); } @@ -397,7 +397,7 @@ class Kronolith_Api extends Horde_Registry_Api } if (!(count($parts) == 2 || count($parts) == 3) || - !array_key_exists($calendarId, Kronolith::listCalendars(false, Horde_Perms::DELETE))) { + !array_key_exists($calendarId, Kronolith::listInternalCalendars(false, Horde_Perms::DELETE))) { throw new Kronolith_Exception("Calendar does not exist or no permission to delete"); } @@ -432,7 +432,7 @@ class Kronolith_Api extends Horde_Registry_Api if (is_null($permission)) { $permission = Horde_Perms::SHOW; } - return array_keys(Kronolith::listCalendars($owneronly, $permission)); + return array_keys(Kronolith::listInternalCalendars($owneronly, $permission)); } /** @@ -451,7 +451,7 @@ class Kronolith_Api extends Horde_Registry_Api $calendar = Kronolith::getDefaultCalendar(); } if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::READ))) { + Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { throw new Horde_Exception_PermissionDenied(); } @@ -489,7 +489,7 @@ class Kronolith_Api extends Horde_Registry_Api } if ($calendar === false || - !array_key_exists($calendar, Kronolith::listCalendars(false, Horde_Perms::READ))) { + !array_key_exists($calendar, Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { throw new Horde_Exception_PermissionDenied(); } @@ -522,7 +522,7 @@ class Kronolith_Api extends Horde_Registry_Api /* Only get the calendar once */ $c = Kronolith::getDefaultCalendar(); if ($c === false || - !array_key_exists($c, Kronolith::listCalendars(false, Horde_Perms::READ))) { + !array_key_exists($c, Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { throw new Horde_Exception_PermissionDenied(); } @@ -591,7 +591,7 @@ class Kronolith_Api extends Horde_Registry_Api } if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::READ))) { + Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { throw new Horde_Exception_PermissionDenied(); } @@ -618,7 +618,7 @@ class Kronolith_Api extends Horde_Registry_Api $calendar = Kronolith::getDefaultCalendar(Horde_Perms::EDIT); } if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::EDIT))) { + Kronolith::listInternalCalendars(false, Horde_Perms::EDIT))) { throw new Horde_Exception_PermissionDenied(); } @@ -734,7 +734,7 @@ class Kronolith_Api extends Horde_Registry_Api $calendar = Kronolith::getDefaultCalendar(Horde_Perms::EDIT); } if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::EDIT))) { + Kronolith::listInternalCalendars(false, Horde_Perms::EDIT))) { throw new Horde_Exception_PermissionDenied(); } $event = Kronolith::quickAdd($text, $calendar); @@ -810,7 +810,7 @@ class Kronolith_Api extends Horde_Registry_Api global $kronolith_shares; if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::READ))) { + Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { throw new Horde_Exception_PermissionDenied(); } @@ -875,7 +875,7 @@ class Kronolith_Api extends Horde_Registry_Api // First try the user's own calendars. if (empty($event)) { - $ownerCalendars = Kronolith::listCalendars(true, Horde_Perms::DELETE); + $ownerCalendars = Kronolith::listInternalCalendars(true, Horde_Perms::DELETE); foreach ($events as $ev) { if ($GLOBALS['registry']->isAdmin() || isset($ownerCalendars[$ev->calendar])) { $event = $ev; @@ -886,7 +886,7 @@ class Kronolith_Api extends Horde_Registry_Api // If not successful, try all calendars the user has access to. if (empty($event)) { - $deletableCalendars = Kronolith::listCalendars(false, Horde_Perms::DELETE); + $deletableCalendars = Kronolith::listInternalCalendars(false, Horde_Perms::DELETE); foreach ($events as $ev) { if (isset($deletableCalendars[$ev->calendar])) { $kronolith_driver->open($ev->calendar); @@ -1052,7 +1052,7 @@ class Kronolith_Api extends Horde_Registry_Api $events = Kronolith::getDriver()->getByUID($uid, null, true); /* First try the user's own calendars. */ - $ownerCalendars = Kronolith::listCalendars(true, Horde_Perms::EDIT); + $ownerCalendars = Kronolith::listInternalCalendars(true, Horde_Perms::EDIT); $event = null; foreach ($events as $ev) { if (isset($ownerCalendars[$ev->calendar])) { @@ -1063,7 +1063,7 @@ class Kronolith_Api extends Horde_Registry_Api /* If not successful, try all calendars the user has access to. */ if (empty($event)) { - $editableCalendars = Kronolith::listCalendars(false, Horde_Perms::EDIT); + $editableCalendars = Kronolith::listInternalCalendars(false, Horde_Perms::EDIT); foreach ($events as $ev) { if (isset($editableCalendars[$ev->calendar])) { $event = $ev; @@ -1131,16 +1131,17 @@ class Kronolith_Api extends Horde_Registry_Api * @throws Kronolith_Exception */ public function listEvents($startstamp = null, $endstamp = null, - $calendars = null, $showRecurrence = true, - $alarmsOnly = false, $showRemote = true, $hideExceptions = false, - $coverDates = true, $fetchTags = false) + $calendars = null, $showRecurrence = true, + $alarmsOnly = false, $showRemote = true, + $hideExceptions = false, $coverDates = true, + $fetchTags = false) { if (!isset($calendars)) { $calendars = array($GLOBALS['prefs']->getValue('default_share')); } elseif (!is_array($calendars)) { $calendars = array($calendars); } - $allowed_calendars = Kronolith::listCalendars(false, Horde_Perms::READ); + $allowed_calendars = Kronolith::listInternalCalendars(false, Horde_Perms::READ); foreach ($calendars as $calendar) { if (!array_key_exists($calendar, $allowed_calendars)) { throw new Horde_Exception_PermissionDenied(); @@ -1313,7 +1314,7 @@ class Kronolith_Api extends Horde_Registry_Api public function lock($calendar, $event = null) { if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::EDIT))) { + Kronolith::listInternalCalendars(false, Horde_Perms::EDIT))) { throw new Horde_Exception_PermissionDenied(); } if (!empty($event)) { @@ -1333,7 +1334,7 @@ class Kronolith_Api extends Horde_Registry_Api public function unlock($calendar, $lockid) { if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::EDIT))) { + Kronolith::listInternalCalendars(false, Horde_Perms::EDIT))) { throw new Horde_Exception_PermissionDenied(); } @@ -1351,7 +1352,7 @@ class Kronolith_Api extends Horde_Registry_Api public function checkLocks($calendar, $event = null) { if (!array_key_exists($calendar, - Kronolith::listCalendars(false, Horde_Perms::READ))) { + Kronolith::listInternalCalendars(false, Horde_Perms::READ))) { throw new Horde_Exception_PermissionDenied(); } if (!empty($event)) { diff --git a/kronolith/lib/Application.php b/kronolith/lib/Application.php index 9963db8cb..34944ff43 100644 --- a/kronolith/lib/Application.php +++ b/kronolith/lib/Application.php @@ -124,16 +124,13 @@ class Kronolith_Application extends Horde_Registry_Application foreach (Kronolith::listCalendars() as $fb_cal => $cal) { $fb_list[htmlspecialchars($fb_cal)] = htmlspecialchars($cal->get('name')); } - foreach ($GLOBALS['all_remote_calendars'] as $cal) { - $fb_list['remote_' . htmlspecialchars($cal['url'])] = $cal['name']; - } $ui->override['fb_cals'] = $fb_list; } break; case 'share': if (!$prefs->isLocked('default_share')) { - $all_shares = Kronolith::listCalendars(); + $all_shares = Kronolith::listInternalCalendars(); $sharelist = array(); foreach ($all_shares as $id => $share) { diff --git a/kronolith/lib/Block/month.php b/kronolith/lib/Block/month.php index 62aa9b1a7..b74b2d5e7 100644 --- a/kronolith/lib/Block/month.php +++ b/kronolith/lib/Block/month.php @@ -19,23 +19,8 @@ class Horde_Block_Kronolith_month extends Horde_Block 'type' => 'enum', 'default' => '__all')); $params['calendar']['values']['__all'] = _("All Visible"); - foreach (Kronolith::listCalendars() as $id => $cal) { - if ($cal->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($cal->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $params['calendar']['values'][$id] = $cal->get('name'); - } - - foreach ($GLOBALS['all_external_calendars'] as $api => $categories) { - if (count($categories)) { - $app = $GLOBALS['registry']->get('name', $GLOBALS['registry']->hasInterface($api)); - $externals[$app] = array(); - foreach ($categories as $id => $name) { - $params['calendar']['values'][$api . '/' . $id] = $name; - } - } + foreach (Kronolith::listCalendars(Horde_Perms::SHOW, true) as $id => $cal) { + $params['calendar']['values'][$id] = $cal->name(); } return $params; @@ -52,17 +37,13 @@ class Horde_Block_Kronolith_month extends Horde_Block $url = Horde::url($GLOBALS['registry']->getInitialPage(), true); if (isset($this->_params['calendar']) && $this->_params['calendar'] != '__all') { - if (strpos($this->_params['calendar'], '/') !== false) { - list($api, $c) = split('/', $this->_params['calendar']); - $app = $GLOBALS['registry']->get('name', $GLOBALS['registry']->hasInterface($api)); - $title = htmlspecialchars($app . ' ' . $c); + $calendars = Kronolith::listCalendars(); + if (isset($calendars[$this->_params['calendar']])) { + $title = htmlspecialchars($calendars[$this->_params['calendar']]->name()); } else { - try { - $this->_share = $GLOBALS['kronolith_shares']->getShare($this->_params['calendar']); - $url->add('display_cal', $this->_params['calendar']); - $title = htmlspecialchars($this->_share->get('name')); - } catch (Exception $e) {} + $title = _("Calendar not found"); } + $url->add('display_cal', $this->_params['calendar']); } $date = new Horde_Date(time()); @@ -78,16 +59,13 @@ class Horde_Block_Kronolith_month extends Horde_Block { global $prefs; - if (isset($this->_params['calendar']) && $this->_params['calendar'] != '__all' && - strpos($this->_params['calendar'], '/') === false) { - if (empty($this->_share)) { - try { - $this->_share = $GLOBALS['kronolith_shares']->getShare($this->_params['calendar']); - } catch (Exception $e) { - throw new Horde_Block_Exception(_(sprintf("There was an error accessing the calendar: %s", $e->getMessage()))); - } + if (isset($this->_params['calendar']) && + $this->_params['calendar'] != '__all') { + $calendars = Kronolith::listCalendars(); + if (!isset($calendars[$this->_params['calendar']])) { + return _("Calendar not found"); } - if (!$this->_share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) { + if (!$calendars[$this->_params['calendar']]->hasPermission(Horde_Perms::READ)) { return _("Permission Denied"); } } @@ -145,16 +123,9 @@ class Horde_Block_Kronolith_month extends Horde_Block try { if (isset($this->_params['calendar']) && $this->_params['calendar'] != '__all') { - - if (strpos($this->_params['calendar'], '/') !== false) { - /* listTimeObjects */ - $driver = Kronolith::getDriver('Horde'); - $driver->open($this->_params['calendar']); - $all_events = $driver->listEvents($startDate, $endDate, true, false, false, true); - } else { - $all_events = Kronolith::listEvents($startDate,$endDate, array($this->_params['calendar']), true, false, false); - } - + list($type, $calendar) = explode('_', $this->_params['calendar'], 2); + $driver = Kronolith::getDriver($type, $calendar); + $all_events = $driver->listEvents($startDate, $endDate, true); } else { $all_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']); } diff --git a/kronolith/lib/Block/monthlist.php b/kronolith/lib/Block/monthlist.php index acbb93cec..642d65c1b 100644 --- a/kronolith/lib/Block/monthlist.php +++ b/kronolith/lib/Block/monthlist.php @@ -27,23 +27,8 @@ class Horde_Block_Kronolith_monthlist extends Horde_Block 'type' => 'checkbox', 'default' => 0)); $params['calendar']['values']['__all'] = _("All Visible"); - foreach (Kronolith::listCalendars() as $id => $cal) { - if ($cal->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($cal->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $params['calendar']['values'][$id] = $cal->get('name'); - } - - foreach ($GLOBALS['all_external_calendars'] as $api => $categories) { - if (count($categories)) { - $app = $GLOBALS['registry']->get('name', $GLOBALS['registry']->hasInterface($api)); - $externals[$app] = array(); - foreach ($categories as $id => $name) { - $params['calendar']['values'][$api . '/' . $id] = $name; - } - } + foreach (Kronolith::listCalendars(Horde_Perms::SHOW, true) as $id => $cal) { + $params['calendar']['values'][$id] = $cal->name(); } return $params; } @@ -84,21 +69,16 @@ class Horde_Block_Kronolith_monthlist extends Horde_Block try { if (isset($this->_params['calendar']) && $this->_params['calendar'] != '__all') { - - if (strpos($this->_params['calendar'], '/') !== false) { - /* listTimeObjects */ - $driver = Kronolith::getDriver('Horde'); - $driver->open($this->_params['calendar']); - $all_events = $driver->listEvents($startDate, $endDate, true, false, false, true); - } else { - try { - $calendar = $GLOBALS['kronolith_shares']->getShare($this->_params['calendar']); - if (!$calendar->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) { - return _("Permission Denied"); - } - } catch (Exception $e) {} - $all_events = Kronolith::listEvents($startDate, $endDate, array($this->_params['calendar']), true, false, false); + $calendars = Kronolith::listCalendars(); + if (!isset($calendars[$this->_params['calendar']])) { + return _("Calendar not found"); + } + if (!$calendars[$this->_params['calendar']]->hasPermission(Horde_Perms::READ)) { + return _("Permission Denied"); } + list($type, $calendar) = explode('_', $this->_params['calendar'], 2); + $driver = Kronolith::getDriver($type, $calendar); + $all_events = $driver->listEvents($startDate, $endDate, true); } else { $all_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']); } diff --git a/kronolith/lib/Block/prevmonthlist.php b/kronolith/lib/Block/prevmonthlist.php index 2261e4c7e..dcb0219da 100644 --- a/kronolith/lib/Block/prevmonthlist.php +++ b/kronolith/lib/Block/prevmonthlist.php @@ -24,13 +24,8 @@ class Horde_Block_Kronolith_prevmonthlist extends Horde_Block 'type' => 'checkbox', 'default' => 0)); $params['calendar']['values']['__all'] = _("All Visible"); - foreach (Kronolith::listCalendars() as $id => $cal) { - if ($cal->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($cal->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $params['calendar']['values'][$id] = $cal->get('name'); + foreach (Kronolith::listCalendars(Horde_Perms::SHOW, true) as $id => $cal) { + $params['calendar']['values'][$id] = $cal->name(); } return $params; @@ -73,14 +68,15 @@ class Horde_Block_Kronolith_prevmonthlist extends Horde_Block try { if (isset($this->_params['calendar']) && $this->_params['calendar'] != '__all') { - try { - $calendar = $GLOBALS['kronolith_shares']->getShare($this->_params['calendar']); - if (!$calendar->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) { - return _("Permission Denied"); - } - } catch (Exception $e) { + $calendars = Kronolith::listCalendars(); + if (!isset($calendars[$this->_params['calendar']])) { + return _("Calendar not found"); + } + if (!$calendars[$this->_params['calendar']]->hasPermission(Horde_Perms::READ)) { + return _("Permission Denied"); } - $all_events = Kronolith::listEvents($startDate, $endDate, array($this->_params['calendar']), true, false, false); + list($type, $calendar) = explode('_', $this->_params['calendar'] $driver = Kronolith::getDriver($type, $calendar); + $all_events = $driver->listEvents($startDate, $endDate, true); } else { $all_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']); } diff --git a/kronolith/lib/Block/summary.php b/kronolith/lib/Block/summary.php index 2da599c8c..6893d2b87 100644 --- a/kronolith/lib/Block/summary.php +++ b/kronolith/lib/Block/summary.php @@ -45,23 +45,8 @@ class Horde_Block_Kronolith_summary extends Horde_Block 'type' => 'checkbox', 'default' => 0)); $params['calendar']['values']['__all'] = _("All Visible"); - foreach (Kronolith::listCalendars() as $id => $cal) { - if ($cal->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($cal->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $params['calendar']['values'][$id] = $cal->get('name'); - } - - foreach ($GLOBALS['all_external_calendars'] as $api => $categories) { - if (count($categories)) { - $app = $GLOBALS['registry']->get('name', $GLOBALS['registry']->hasInterface($api)); - $externals[$app] = array(); - foreach ($categories as $id => $name) { - $params['calendar']['values'][$api . '/' . $id] = $name; - } - } + foreach (Kronolith::listCalendars(Horde_Perms::SHOW, true) as $id => $cal) { + $params['calendar']['values'][$id] = $cal->name(); } return $params; @@ -101,28 +86,18 @@ class Horde_Block_Kronolith_summary extends Horde_Block try { if (isset($this->_params['calendar']) && $this->_params['calendar'] != '__all') { - - if (strpos($this->_params['calendar'], '/') !== false) { - /* listTimeObjects */ - $driver = Kronolith::getDriver('Horde'); - $driver->open($this->_params['calendar']); - $all_events = $driver->listEvents($startDate, $endDate, true, false, false, true); - } else { - try { - $calendar = $GLOBALS['kronolith_shares']->getShare($this->_params['calendar']); - if (!$calendar->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::SHOW)) { - return _("Permission Denied"); - } - } catch (Exception $e) { - } - $all_events = Kronolith::listEvents($startDate, - $endDate, - array($this->_params['calendar']), - true, false, false); + $calendars = Kronolith::listCalendars(); + if (!isset($calendars[$this->_params['calendar']])) { + return _("Calendar not found"); + } + if (!$calendars[$this->_params['calendar']]->hasPermission(Horde_Perms::READ)) { + return _("Permission Denied"); } + list($type, $calendar) = explode('_', $this->_params['calendar'], 2); + $driver = Kronolith::getDriver($type, $calendar); + $all_events = $driver->listEvents($startDate, $endDate, true); } else { - $all_events = Kronolith::listEvents($startDate, - $endDate, + $all_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']); } } catch (Exception $e) { diff --git a/kronolith/lib/Calendar.php b/kronolith/lib/Calendar.php new file mode 100644 index 000000000..a815cef54 --- /dev/null +++ b/kronolith/lib/Calendar.php @@ -0,0 +1,121 @@ + + * @package Kronolith + */ +abstract class Kronolith_Calendar +{ + /** + * Constructor. + * + * @param array $params A hash with any parameters that this calendar + * might need. + */ + public function __construct($params = array()) + { + foreach ($params as $param => $value) { + $this->{'_' . $param} = $value; + } + } + + /** + * Returns the owner of this calendar. + * + * @return string This calendar's owner. + */ + public function owner() + { + return $GLOBALS['registry']->getAuth(); + } + + /** + * Returns the name of this calendar. + * + * @return string This calendar's name. + */ + abstract public function name(); + + /** + * Returns the description of this calendar. + * + * @return string This calendar's description. + */ + public function description() + { + return ''; + } + + /** + * Returns the background color for this calendar. + * + * @return string A HTML color code. + */ + public function background() + { + return '#dddddd'; + } + + /** + * Returns the foreground color for this calendar. + * + * @return string A HTML color code. + */ + public function foreground() + { + return Horde_Image::brightness($this->background()) < 128 ? '#fff' : '#000'; + } + + /** + * Returns the CSS color definition for this calendar. + * + * @param boolean $with_attribute Whether to wrap the colors inside a + * "style" attribute. + * + * @return string A CSS string with color definitions. + */ + public function css($with_attribute = true) + { + $css = 'background-color:' . $this->background() . ';color:' . $this->foreground(); + if ($with_attribute) { + $css = ' style="' . $css . '"'; + } + return $css; + } + + /** + * Encapsulates permissions checking. + * + * @param integer $permission The permission to check for. + * @param string $user The user to check permissions for. Defaults + * to the current user. + * @param string $creator An event creator, to check for creator + * permissions. + * + * @return boolean Whether the user has the permission on this calendar. + */ + public function hasPermission($permission, $user = null, $creator = null) + { + switch ($permission) { + case Horde_Perms::SHOW: + case Horde_Perms::READ: + return true; + + default: + return false; + } + } + + /** + * Whether this calendar is supposed to be displayed in lists. + * + * @return boolean True if this calendar should be displayed. + */ + abstract public function display(); +} diff --git a/kronolith/lib/Calendar/External.php b/kronolith/lib/Calendar/External.php new file mode 100644 index 000000000..ebd38b061 --- /dev/null +++ b/kronolith/lib/Calendar/External.php @@ -0,0 +1,78 @@ + + * @package Kronolith + */ +class Kronolith_Calendar_External extends Kronolith_Calendar +{ + /** + * The application of this timeobject source. + * + * @var string + */ + protected $_api; + + /** + * The name of this timeobject source. + * + * @var string + */ + protected $_name; + + /** + * Constructor. + * + * @param array $params A hash with any parameters that this calendar + * might need. + * Required parameters: + * - share: The share of this calendar. + */ + public function __construct($params = array()) + { + if (!isset($params['name'])) { + throw new BadMethodCallException('name parameter is missing'); + } + if (!isset($params['api'])) { + throw new BadMethodCallException('api parameter is missing'); + } + parent::__construct($params); + } + + /** + * Returns the name of this calendar. + * + * @return string This calendar's name. + */ + public function name() + { + return $this->_name; + } + + /** + * Whether this calendar is supposed to be displayed in lists. + * + * @return boolean True if this calendar should be displayed. + */ + public function display() + { + return empty($GLOBALS['conf']['share']['hidden']) || + in_array($this->_api . '/' . $this->_name, $GLOBALS['display_external_calendars']); + } + + /** + * Returns the application of this calendar. + * + * @return string This calendar's timeobject application. + */ + public function api() + { + return $this->_api; + } +} diff --git a/kronolith/lib/Calendar/Holiday.php b/kronolith/lib/Calendar/Holiday.php new file mode 100644 index 000000000..ab4f96010 --- /dev/null +++ b/kronolith/lib/Calendar/Holiday.php @@ -0,0 +1,57 @@ + + * @package Kronolith + */ +class Kronolith_Calendar_Holiday extends Kronolith_Calendar +{ + /** + * The Date_Holidays driver information. + * + * @var array + */ + protected $_driver; + + /** + * Constructor. + * + * @param array $params A hash with any parameters that this calendar + * might need. + * Required parameters: + * - share: The share of this calendar. + */ + public function __construct($params = array()) + { + if (!isset($params['driver'])) { + throw new BadMethodCallException('driver parameter is missing'); + } + parent::__construct($params); + } + + /** + * Returns the name of this calendar. + * + * @return string This calendar's name. + */ + public function name() + { + return $this->_driver['title']; + } + + /** + * Whether this calendar is supposed to be displayed in lists. + * + * @return boolean True if this calendar should be displayed. + */ + public function display() + { + return true; + } +} diff --git a/kronolith/lib/Calendar/Internal.php b/kronolith/lib/Calendar/Internal.php new file mode 100644 index 000000000..8ecbad545 --- /dev/null +++ b/kronolith/lib/Calendar/Internal.php @@ -0,0 +1,123 @@ + + * @package Kronolith + */ +class Kronolith_Calendar_Internal extends Kronolith_Calendar +{ + /** + * The share of this calendar. + * + * @var Horde_Share_Object + */ + protected $_share; + + /** + * Constructor. + * + * @param array $params A hash with any parameters that this calendar + * might need. + * Required parameters: + * - share: The share of this calendar. + */ + public function __construct($params = array()) + { + if (!isset($params['share'])) { + throw new BadMethodCallException('share parameter is missing'); + } + if (!($params['share'] instanceof Horde_Share_Object)) { + throw new InvalidArgumentException('share parameter is not a Horde_Share_Object'); + } + parent::__construct($params); + } + + /** + * Returns the owner of this calendar. + * + * @return string This calendar's owner. + */ + public function owner() + { + return $this->_share->get('owner'); + } + + /** + * Returns the name of this calendar. + * + * @return string This calendar's name. + */ + public function name() + { + return $this->_share->get('name'); + } + + /** + * Returns the description of this calendar. + * + * @return string This calendar's description. + */ + public function description() + { + return $this->_share->get('description'); + } + + /** + * Returns the background color for this calendar. + * + * @return string A HTML color code. + */ + public function background() + { + $color = $this->_share->get('color'); + return empty($color) ? parent::background() : $color; + } + + /** + * Encapsulates permissions checking. + * + * @param integer $permission The permission to check for. + * @param string $user The user to check permissions for. Defaults + * to the current user. + * @param string $creator An event creator, to check for creator + * permissions. + * + * @return boolean Whether the user has the permission on this calendar. + */ + public function hasPermission($permission, $user = null, $creator = null) + { + if ($user === null) { + $user = $GLOBALS['registry']->getAuth(); + } + return $this->_share->hasPermission($user, $permission, $creator); + } + + /** + * Whether this calendar is supposed to be displayed in lists. + * + * @return boolean True if this calendar should be displayed. + */ + public function display() + { + return $this->owner() == $GLOBALS['registry']->getAuth() || + empty($GLOBALS['conf']['share']['hidden']) || + in_array($this->_share->getName(), $GLOBALS['display_calendars']); + } + + /** + * Returns the share of this calendar. + * + * @return Horde_Share_Object This calendar's share. + */ + public function share() + { + return $this->_share; + } +} diff --git a/kronolith/lib/Calendar/Remote.php b/kronolith/lib/Calendar/Remote.php new file mode 100644 index 000000000..85cb88d37 --- /dev/null +++ b/kronolith/lib/Calendar/Remote.php @@ -0,0 +1,165 @@ + + * @package Kronolith + */ +class Kronolith_Calendar_Remote extends Kronolith_Calendar +{ + /** + * The URL of this calendar. + * + * @var string + */ + protected $_url; + + /** + * The name of this calendar. + * + * @var string + */ + protected $_name; + + /** + * The description of this calendar. + * + * @var string + */ + protected $_desc = ''; + + /** + * The HTTP user name for this calendar. + * + * @var string + */ + protected $_user; + + /** + * The HTTP password for this calendar. + * + * @var string + */ + protected $_password; + + /** + * The color of this calendar. + * + * @var string + */ + protected $_color; + + /** + * Constructor. + * + * @param array $params A hash with any parameters that this calendar + * might need. + * Required parameters: + * - share: The share of this calendar. + */ + public function __construct($params = array()) + { + if (!isset($params['url'])) { + throw new BadMethodCallException('url parameter is missing'); + } + if (!isset($params['name'])) { + throw new BadMethodCallException('name parameter is missing'); + } + $key = $GLOBALS['registry']->getAuthCredential('password'); + if ($key) { + $secret = $GLOBALS['injector']->getInstance('Horde_Secret'); + if (!empty($params['user'])) { + $params['user'] = $secret->read($key, base64_decode($params['user'])); + } + if (!empty($params['password'])) { + $params['password'] = $secret->read($key, base64_decode($params['password'])); + } + } + parent::__construct($params); + } + + /** + * Returns the name of this calendar. + * + * @return string This calendar's name. + */ + public function name() + { + return $this->_name; + } + + /** + * Returns the description of this calendar. + * + * @return string This calendar's description. + */ + public function description() + { + return $this->_desc; + } + + /** + * Returns the background color for this calendar. + * + * @return string A HTML color code. + */ + public function background() + { + return empty($this->_color) ? parent::background() : $this->_color; + } + + /** + * Encapsulates permissions checking. + * + * @param integer $permission The permission to check for. + * @param string $user The user to check permissions for. Defaults + * to the current user. + * @param string $creator An event creator, to check for creator + * permissions. + * + * @return boolean Whether the user has the permission on this calendar. + */ + public function hasPermission($permission, $user = null, $creator = null) + { + return Kronolith::getDriver('Ical', $this->_url)->getPermission() & $permission; + } + + /** + * Whether this calendar is supposed to be displayed in lists. + * + * @return boolean True if this calendar should be displayed. + */ + public function display() + { + return true; + } + + /** + * Returns the URL of this calendar. + * + * @return string This calendar's URL. + */ + public function url() + { + return $this->_url; + } + + /** + * Returns the authentication credentials for this calendar. + * + * @return array This calendar's credentials. + */ + public function credentials() + { + if (!empty($this->_user)) { + return array('user' => $this->_user, 'password' => $this->_password); + } + return array(); + } +} diff --git a/kronolith/lib/Driver/Ical.php b/kronolith/lib/Driver/Ical.php index a73cfef1b..dfe02633a 100644 --- a/kronolith/lib/Driver/Ical.php +++ b/kronolith/lib/Driver/Ical.php @@ -60,7 +60,7 @@ class Kronolith_Driver_Ical extends Kronolith_Driver { parent::open($calendar); $this->_client = null; - unset($this->_davSupport); + unset($this->_davSupport, $this->_permission); } /** @@ -70,14 +70,9 @@ class Kronolith_Driver_Ical extends Kronolith_Driver */ public function backgroundColor() { - foreach ($GLOBALS['all_remote_calendars'] as $calendar) { - if ($calendar['url'] == $this->calendar) { - return empty($calendar['color']) - ? '#dddddd' - : $calendar['color']; - } - } - return '#dddddd'; + return empty($GLOBALS['all_remote_calendars'][$this->calendar]) + ? '#dddddd' + : $GLOBALS['all_remote_calendars'][$this->calendar]->background(); } public function listAlarms($date, $fullevent = false) @@ -281,7 +276,7 @@ class Kronolith_Driver_Ical extends Kronolith_Driver if ($component->getType() == 'vEvent') { $event = new Kronolith_Event_Ical($this); $event->status = Kronolith::STATUS_FREE; - $event->permission = $this->_permission; + $event->permission = $this->getPermission(); $event->fromiCalendar($component); // Force string so JSON encoding is consistent across drivers. $event->id = $id ? $id : 'ical' . $i; @@ -372,6 +367,7 @@ class Kronolith_Driver_Ical extends Kronolith_Driver $components[$eventId]->getType() == 'vEvent') { $event = new Kronolith_Event_Ical($this); $event->status = Kronolith::STATUS_FREE; + $event->permission = $this->getPermission(); $event->fromiCalendar($components[$eventId]); $event->id = 'ical' . $eventId; return $event; @@ -569,6 +565,19 @@ class Kronolith_Driver_Ical extends Kronolith_Driver } /** + * Returns the permissions for the current calendar. + * + * @return integer A Horde_Perms permission bit mask. + */ + public function getPermission() + { + if ($this->isCalDAV()) { + return $this->_permission; + } + return Horde_Perms::SHOW | Horde_Perms::READ; + } + + /** * Sends a CalDAV request. * * @param string $method A request method. diff --git a/kronolith/lib/Driver/Kolab.php b/kronolith/lib/Driver/Kolab.php index a24c7c5ac..3df74aef6 100644 --- a/kronolith/lib/Driver/Kolab.php +++ b/kronolith/lib/Driver/Kolab.php @@ -80,11 +80,7 @@ class Kronolith_Driver_Kolab extends Kronolith_Driver public function backgroundColor() { if (isset($GLOBALS['all_calendars'][$this->calendar])) { - $share = $GLOBALS['all_calendars'][$this->calendar]; - $color = $share->get('color'); - if (!empty($color)) { - return $color; - } + return $GLOBALS['all_calendars'][$this->calendar]->background(); } return '#dddddd'; } @@ -305,7 +301,7 @@ class Kronolith_Driver_Kolab extends Kronolith_Driver public function getByUID($uid, $calendars = null, $getAll = false) { if (!is_array($calendars)) { - $calendars = array_keys(Kronolith::listCalendars(true, Horde_Perms::READ)); + $calendars = array_keys(Kronolith::listInternalCalendars(true, Horde_Perms::READ)); } foreach ($calendars as $calendar) { diff --git a/kronolith/lib/Driver/Sql.php b/kronolith/lib/Driver/Sql.php index c1c9ce612..b6264166b 100644 --- a/kronolith/lib/Driver/Sql.php +++ b/kronolith/lib/Driver/Sql.php @@ -55,11 +55,7 @@ class Kronolith_Driver_Sql extends Kronolith_Driver public function backgroundColor() { if (isset($GLOBALS['all_calendars'][$this->calendar])) { - $share = $GLOBALS['all_calendars'][$this->calendar]; - $color = $share->get('color'); - if (!empty($color)) { - return $color; - } + return $GLOBALS['all_calendars'][$this->calendar]->background(); } return '#dddddd'; } @@ -512,7 +508,7 @@ class Kronolith_Driver_Sql extends Kronolith_Driver } /* First try the user's own calendars. */ - $ownerCalendars = Kronolith::listCalendars(true, Horde_Perms::READ); + $ownerCalendars = Kronolith::listInternalCalendars(true, Horde_Perms::READ); $event = null; foreach ($eventArray as $ev) { if (isset($ownerCalendars[$ev->calendar])) { @@ -523,7 +519,7 @@ class Kronolith_Driver_Sql extends Kronolith_Driver /* If not successful, try all calendars the user has access too. */ if (empty($event)) { - $readableCalendars = Kronolith::listCalendars(false, Horde_Perms::READ); + $readableCalendars = Kronolith::listInternalCalendars(false, Horde_Perms::READ); foreach ($eventArray as $ev) { if (isset($readableCalendars[$ev->calendar])) { $event = $ev; diff --git a/kronolith/lib/Event.php b/kronolith/lib/Event.php index 4c3780f06..45ae1dd35 100644 --- a/kronolith/lib/Event.php +++ b/kronolith/lib/Event.php @@ -392,7 +392,7 @@ abstract class Kronolith_Event public function getShare() { if (isset($GLOBALS['all_calendars'][$this->calendar])) { - return $GLOBALS['all_calendars'][$this->calendar]; + return $GLOBALS['all_calendars'][$this->calendar]->share(); } throw new Kronolith_Exception('Share not found'); } diff --git a/kronolith/lib/Event/Ical.php b/kronolith/lib/Event/Ical.php index 8e56dc4e3..c0425e7a7 100644 --- a/kronolith/lib/Event/Ical.php +++ b/kronolith/lib/Event/Ical.php @@ -24,7 +24,7 @@ class Kronolith_Event_Ical extends Kronolith_Event * * @var integer */ - public $permission; + public $permission = 0; /** * Imports a backend specific event object. @@ -59,18 +59,7 @@ class Kronolith_Event_Ical extends Kronolith_Event */ public function hasPermission($permission, $user = null) { - if (!is_null($this->permission)) { - return $this->permission & $permission; - } - - switch ($permission) { - case Horde_Perms::SHOW: - case Horde_Perms::READ: - return true; - - default: - return false; - } + return $this->permission & $permission; } /** diff --git a/kronolith/lib/Event/Sql.php b/kronolith/lib/Event/Sql.php index e95b9f99a..0b6dca711 100644 --- a/kronolith/lib/Event/Sql.php +++ b/kronolith/lib/Event/Sql.php @@ -43,12 +43,8 @@ class Kronolith_Event_Sql extends Kronolith_Event if (!empty($this->calendar) && isset($GLOBALS['all_calendars'][$this->calendar])) { - $share = $GLOBALS['all_calendars'][$this->calendar]; - $backgroundColor = $share->get('color'); - if (!empty($backgroundColor)) { - $this->_backgroundColor = $backgroundColor; - $this->_foregroundColor = Horde_Image::brightness($this->_backgroundColor) < 128 ? '#fff' : '#000'; - } + $this->_backgroundColor = $GLOBALS['all_calendars'][$this->calendar]->background(); + $this->_foregroundColor = $GLOBALS['all_calendars'][$this->calendar]->foreground(); } } diff --git a/kronolith/lib/Kronolith.php b/kronolith/lib/Kronolith.php index 8e48279a3..a411c5d98 100644 --- a/kronolith/lib/Kronolith.php +++ b/kronolith/lib/Kronolith.php @@ -130,7 +130,7 @@ class Kronolith $code['conf'] = array( 'URI_AJAX' => (string)Horde::getServiceLink('ajax', 'kronolith'), 'URI_SNOOZE' => (string)Horde::url($registry->get('webroot', 'horde') . '/services/snooze.php', true, -1), - 'URI_CALENDAR_EXPORT' => (string)Horde::url('data.php', true)->add(array('actionID' => 'export', 'all_events' => 1, 'exportID' => Horde_Data::EXPORT_ICALENDAR, 'exportCal' => '')), + 'URI_CALENDAR_EXPORT' => (string)Horde::url('data.php', true)->add(array('actionID' => 'export', 'all_events' => 1, 'exportID' => Horde_Data::EXPORT_ICALENDAR, 'exportCal' => 'internal_')), 'URI_EVENT_EXPORT' => str_replace(array('%23', '%7B', '%7D'), array('#', '{', '}'), Horde::url('event.php', true)->add(array('view' => 'ExportEvent', 'eventID' => '#{id}', 'calendar' => '#{calendar}', 'type' => '#{type}'))), 'SESSION_ID' => defined('SID') ? SID : '', 'images' => array( @@ -192,29 +192,29 @@ class Kronolith // Calendars foreach (array(true, false) as $my) { foreach ($GLOBALS['all_calendars'] as $id => $calendar) { - if ($calendar->get('owner') != $GLOBALS['registry']->getAuth() && + if ($calendar->owner() != $GLOBALS['registry']->getAuth() && !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($calendar->getName(), $GLOBALS['display_calendars'])) { + !in_array($id, $GLOBALS['display_calendars'])) { continue; } $owner = $GLOBALS['registry']->getAuth() && - $calendar->get('owner') == $GLOBALS['registry']->getAuth(); + $calendar->owner() == $GLOBALS['registry']->getAuth(); if (($my && $owner) || (!$my && !$owner)) { $code['conf']['calendars']['internal'][$id] = array( - 'name' => ($owner || !$calendar->get('owner') ? '' : '[' . $GLOBALS['registry']->convertUsername($calendar->get('owner'), false) . '] ') - . $calendar->get('name'), - 'desc' => $calendar->get('desc'), + 'name' => ($owner || !$calendar->owner() ? '' : '[' . $GLOBALS['registry']->convertUsername($calendar->owner(), false) . '] ') + . $calendar->name(), + 'desc' => $calendar->description(), 'owner' => $owner, - 'fg' => self::foregroundColor($calendar), - 'bg' => self::backgroundColor($calendar), + 'fg' => $calendar->foreground(), + 'bg' => $calendar->background(), 'show' => in_array($id, $GLOBALS['display_calendars']), - 'edit' => $calendar->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT), - 'sub' => $subscriptionCals . ($calendar->get('owner') ? $calendar->get('owner') : '-system-') . '/' . $calendar->getName() . '.ics', - 'feed' => (string)Kronolith::feedUrl($calendar->getName()), + 'edit' => $calendar->hasPermission(Horde_Perms::EDIT), + 'sub' => $subscriptionCals . ($calendar->owner() ? $calendar->owner() : '-system-') . '/' . $id . '.ics', + 'feed' => (string)Kronolith::feedUrl($id), 'embed' => self::embedCode($id), - 'tg' => array_values($tagger->getTags($calendar->getName(), 'calendar'))); + 'tg' => array_values($tagger->getTags($id, 'calendar'))); if ($owner) { - $code['conf']['calendars']['internal'][$id]['perms'] = self::permissionToJson($calendar->getPermission()); + $code['conf']['calendars']['internal'][$id]['perms'] = self::permissionToJson($calendar->share()->getPermission()); } } } @@ -250,44 +250,41 @@ class Kronolith } // Timeobjects - foreach ($GLOBALS['all_external_calendars'] as $api => $categories) { - foreach ($categories as $id => $name) { - if ($api == 'tasks') { - continue; - } - if (!empty($GLOBALS['conf']['share']['hidden']) && - !in_array($api . '/' . $id, $GLOBALS['display_external_calendars'])) { - continue; - } - $calendar = $api . '/' . $id; - $code['conf']['calendars']['external'][$calendar] = array( - 'name' => $name, - 'fg' => '#000', - 'bg' => '#ddd', - 'api' => $registry->get('name', $registry->hasInterface($api)), - 'show' => in_array($calendar, $GLOBALS['display_external_calendars'])); + foreach ($GLOBALS['all_external_calendars'] as $id => $calendar) { + if ($calendar->api() == 'tasks') { + continue; + } + if (!empty($GLOBALS['conf']['share']['hidden']) && + !in_array($id, $GLOBALS['display_external_calendars'])) { + continue; } + $code['conf']['calendars']['external'][$id] = array( + 'name' => $calendar->name(), + 'fg' => $calendar->foreground(), + 'bg' => $calendar->background(), + 'api' => $registry->get('name', $registry->hasInterface($calendar->api())), + 'show' => in_array($id, $GLOBALS['display_external_calendars'])); } // Remote calendars - foreach ($GLOBALS['all_remote_calendars'] as $calendar) { - $code['conf']['calendars']['remote'][$calendar['url']] = array_merge( - array('name' => $calendar['name'], - 'desc' => isset($calendar['desc']) ? $calendar['desc'] : '', + foreach ($GLOBALS['all_remote_calendars'] as $url => $calendar) { + $code['conf']['calendars']['remote'][$url] = array_merge( + array('name' => $calendar->name(), + 'desc' => $calendar->description(), 'owner' => true, - 'fg' => self::foregroundColor($calendar), - 'bg' => self::backgroundColor($calendar), - 'show' => in_array($calendar['url'], $GLOBALS['display_remote_calendars'])), - self::getRemoteParams($calendar['url'])); + 'fg' => $calendar->foreground(), + 'bg' => $calendar->background(), + 'show' => in_array($url, $GLOBALS['display_remote_calendars'])), + $calendar->credentials()); } // Holidays - foreach ($GLOBALS['all_holidays'] as $holiday) { - $code['conf']['calendars']['holiday'][$holiday['id']] = array( - 'name' => $holiday['title'], - 'fg' => self::foregroundColor($holiday), - 'bg' => self::backgroundColor($holiday), - 'show' => in_array($holiday['id'], $GLOBALS['display_holidays'])); + foreach ($GLOBALS['all_holidays'] as $id => $calendar) { + $code['conf']['calendars']['holiday'][$id] = array( + 'name' => $calendar->name(), + 'fg' => $calendar->foreground(), + 'bg' => $calendar->background(), + 'show' => in_array($id, $GLOBALS['display_holidays'])); } /* Gettext strings used in core javascript files. */ @@ -862,7 +859,7 @@ class Kronolith } $kronolith_driver = self::getDriver(); - $calendars = self::listCalendars(true, Horde_Perms::ALL); + $calendars = self::listInternalCalendars(true, Horde_Perms::ALL); $current_calendar = $kronolith_driver->calendar; $count = 0; @@ -1049,7 +1046,10 @@ class Kronolith } /* Make sure all shares exists now to save on checking later. */ - $GLOBALS['all_calendars'] = self::listCalendars(); + $GLOBALS['all_calendars'] = array(); + foreach (self::listInternalCalendars() as $id => $calendar) { + $GLOBALS['all_calendars'][$id] = new Kronolith_Calendar_Internal(array('share' => $calendar)); + } $calendar_keys = array_values($GLOBALS['display_calendars']); $GLOBALS['display_calendars'] = array(); foreach ($calendar_keys as $id) { @@ -1061,13 +1061,15 @@ class Kronolith /* Make sure all the remote calendars still exist. */ $_temp = $GLOBALS['display_remote_calendars']; $GLOBALS['display_remote_calendars'] = array(); - $GLOBALS['all_remote_calendars'] = @unserialize($GLOBALS['prefs']->getValue('remote_cals')); - if (!is_array($GLOBALS['all_remote_calendars'])) { - $GLOBALS['all_remote_calendars'] = array(); + $GLOBALS['all_remote_calendars'] = array(); + $calendars = @unserialize($GLOBALS['prefs']->getValue('remote_cals')); + if (!is_array($calendars)) { + $calendars = array(); } - foreach ($GLOBALS['all_remote_calendars'] as $id) { - if (in_array($id['url'], $_temp)) { - $GLOBALS['display_remote_calendars'][] = $id['url']; + foreach ($calendars as $calendar) { + $GLOBALS['all_remote_calendars'][$calendar['url']] = new Kronolith_Calendar_Remote($calendar); + if (in_array($calendar['url'], $_temp)) { + $GLOBALS['display_remote_calendars'][] = $calendar['url']; } } $GLOBALS['prefs']->setValue('display_remote_cals', serialize($GLOBALS['display_remote_calendars'])); @@ -1080,62 +1082,60 @@ class Kronolith if ($driver['id'] == 'Composite') { continue; } - $GLOBALS['all_holidays'][] = $driver; + $GLOBALS['all_holidays'][$driver['id']] = new Kronolith_Calendar_Holiday(array('driver' => $driver)); + ksort($GLOBALS['all_holidays']); } - asort($GLOBALS['all_holidays']); } } $_temp = $GLOBALS['display_holidays']; $GLOBALS['display_holidays'] = array(); - foreach ($GLOBALS['all_holidays'] as $holiday) { - if (in_array($holiday['id'], $_temp)) { - $GLOBALS['display_holidays'][] = $holiday['id']; + foreach (array_keys($GLOBALS['all_holidays']) as $id) { + if (in_array($id, $_temp)) { + $GLOBALS['display_holidays'][] = $id; } } $GLOBALS['prefs']->setValue('holiday_drivers', serialize($GLOBALS['display_holidays'])); /* Get a list of external calendars. */ + $GLOBALS['all_external_calendars'] = array(); if (isset($_SESSION['all_external_calendars'])) { - $GLOBALS['all_external_calendars'] = $_SESSION['all_external_calendars']; + foreach ($_SESSION['all_external_calendars'] as $calendar) { + $GLOBALS['all_external_calendars'][$calendar['a'] . '/' . $calendar['n']] = new Kronolith_Calendar_External(array('api' => $calendar['a'], 'name' => $calendar['d'])); + } } else { - $GLOBALS['all_external_calendars'] = array(); $apis = array_unique($GLOBALS['registry']->listAPIs()); foreach ($apis as $api) { - if ($GLOBALS['registry']->hasMethod($api . '/listTimeObjects')) { - try { - $categories = $GLOBALS['registry']->call($api . '/listTimeObjectCategories'); - } catch (Horde_Exception $e) { - Horde::logMessage($e, 'DEBUG'); - continue; - } - - if (!count($categories)) { - continue; - } + if (!$GLOBALS['registry']->hasMethod($api . '/listTimeObjects')) { + continue; + } + try { + $categories = $GLOBALS['registry']->call($api . '/listTimeObjectCategories'); + } catch (Horde_Exception $e) { + Horde::logMessage($e, 'DEBUG'); + continue; + } - $GLOBALS['all_external_calendars'][$api] = $categories; - } elseif ($api == 'tasks' && $GLOBALS['registry']->hasMethod('tasks/listTasks')) { - $GLOBALS['all_external_calendars'][$api] = array('_listTasks' => $GLOBALS['registry']->get('name', $GLOBALS['registry']->hasInterface($api))); + foreach ($categories as $name => $description) { + $GLOBALS['all_external_calendars'][$api . '/' . $name] = new Kronolith_Calendar_External(array('api' => $api, 'name' => $description)); + $_SESSION['all_external_calendars'][] = array('a' => $api, + 'n' => $name, + 'd' => $description); } } - $_SESSION['all_external_calendars'] = $GLOBALS['all_external_calendars']; } /* Make sure all the external calendars still exist. */ $_temp = $GLOBALS['display_external_calendars']; $GLOBALS['display_external_calendars'] = array(); - foreach ($GLOBALS['all_external_calendars'] as $api => $categories) { - foreach ($categories as $id => $name) { - $calendarId = $api . '/' . $id; - if (in_array($calendarId, $_temp)) { + foreach ($GLOBALS['all_external_calendars'] as $id => $calendar) { + if (in_array($id, $_temp)) { + $GLOBALS['display_external_calendars'][] = $id; + } else { + /* Convert Kronolith 2 preferences. + * @todo: remove in Kronolith 3.1. */ + list(,$oldid,) = explode('/', $id); + if (in_array($calendar->api() . '/' . $oldid, $_temp)) { $GLOBALS['display_external_calendars'][] = $calendarId; - } else { - /* Convert Kronolith 2 preferences. - * @todo: remove in Kronolith 3.1. */ - list($oldid,) = explode('/', $id); - if (in_array($api . '/' . $oldid, $_temp)) { - $GLOBALS['display_external_calendars'][] = $calendarId; - } } } } @@ -1154,7 +1154,7 @@ class Kronolith $share = &$GLOBALS['kronolith_shares']->newShare($GLOBALS['registry']->getAuth()); $share->set('name', sprintf(_("%s's Calendar"), $name)); $GLOBALS['kronolith_shares']->addShare($share); - $GLOBALS['all_calendars'][$GLOBALS['registry']->getAuth()] = &$share; + $GLOBALS['all_calendars'][$GLOBALS['registry']->getAuth()] = new Kronolith_Calendar_Internal(array('share' => $share)); /* Make sure the personal calendar is displayed by default. */ if (!in_array($GLOBALS['registry']->getAuth(), $GLOBALS['display_calendars'])) { @@ -1495,8 +1495,8 @@ class Kronolith } /** - * Returns all calendars a user has access to, according to several - * parameters/permission levels. + * Returns all internal calendars a user has access to, according + * to several parameters/permission levels. * * @param boolean $owneronly Only return calenders that this user owns? * Defaults to false. @@ -1504,7 +1504,7 @@ class Kronolith * * @return array The calendar list. */ - public static function listCalendars($owneronly = false, $permission = Horde_Perms::SHOW) + public static function listInternalCalendars($owneronly = false, $permission = Horde_Perms::SHOW) { if ($owneronly && !$GLOBALS['registry']->getAuth()) { return array(); @@ -1528,6 +1528,63 @@ class Kronolith } /** + * Returns all calendars a user has access to, according to several + * parameters/permission levels. + * + * @param boolean $owneronly Only return calenders that this user owns? + * Defaults to false. + * @param boolean $display Only return calendars that are supposed to + * be displayed per configuration and user + * preference. + * @param integer $permission The permission to filter calendars by. + * + * @return array The calendar list. + */ + public static function listCalendars($permission = Horde_Perms::SHOW, + $display = false, + $flat = true) + { + $calendars = array(); + foreach ($GLOBALS['all_calendars'] as $id => $calendar) { + if ($calendar->hasPermission($permission) && + (!$display || $calendar->display())) { + if ($flat) { + $calendars['internal_' . $id] = $calendar; + } + } + } + + foreach ($GLOBALS['all_remote_calendars'] as $id => $calendar) { + if ($calendar->hasPermission($permission) && + (!$display || $calendar->display())) { + if ($flat) { + $calendars['remote_' . $id] = $calendar; + } + } + } + + foreach ($GLOBALS['all_external_calendars'] as $id => $calendar) { + if ($calendar->hasPermission($permission) && + (!$display || $calendar->display())) { + if ($flat) { + $calendars['external_' . $id] = $calendar; + } + } + } + + foreach ($GLOBALS['all_holidays'] as $id => $calendar) { + if ($calendar->hasPermission($permission) && + (!$display || $calendar->display())) { + if ($flat) { + $calendars['holiday_' . $id] = $calendar; + } + } + } + + return $calendars; + } + + /** * Returns the default calendar for the current user at the specified * permissions level. */ @@ -1536,13 +1593,13 @@ class Kronolith global $prefs; $default_share = $prefs->getValue('default_share'); - $calendars = self::listCalendars(false, $permission); + $calendars = self::listInternalCalendars($permission); if (isset($calendars[$default_share]) || $prefs->isLocked('default_share')) { return $default_share; } elseif (isset($GLOBALS['all_calendars'][$GLOBALS['registry']->getAuth()]) && - $GLOBALS['all_calendars'][$GLOBALS['registry']->getAuth()]->hasPermission($GLOBALS['registry']->getAuth(), $permission)) { + $GLOBALS['all_calendars'][$GLOBALS['registry']->getAuth()]->hasPermission($permission)) { return $GLOBALS['registry']->getAuth(); } elseif (count($calendars)) { return key($calendars); @@ -2876,7 +2933,8 @@ class Kronolith /* Check here for guest calendars so that we don't get multiple * messages after redirects, etc. */ - if (!$GLOBALS['registry']->getAuth() && !count($GLOBALS['all_calendars'])) { + if (!$GLOBALS['registry']->getAuth() && + !count(Kronolith::listCalendars())) { $GLOBALS['notification']->push(_("No calendars are available to guests.")); } diff --git a/kronolith/lib/LoginTasks/Task/PurgeEvents.php b/kronolith/lib/LoginTasks/Task/PurgeEvents.php index 8e4aafa0a..e6011dbed 100644 --- a/kronolith/lib/LoginTasks/Task/PurgeEvents.php +++ b/kronolith/lib/LoginTasks/Task/PurgeEvents.php @@ -43,7 +43,7 @@ class Kronolith_LoginTasks_Task_PurgeEvents extends Horde_LoginTasks_Task /* Need to have Horde_Perms::DELETE on a calendar to delete events * from it */ - $calendars = Kronolith::listCalendars(true, Horde_Perms::DELETE); + $calendars = Kronolith::listInternalCalendars(true, Horde_Perms::DELETE); /* Start building the search */ $kronolith_driver = Kronolith::getDriver(); diff --git a/kronolith/lib/View/Day.php b/kronolith/lib/View/Day.php index 76d85eba3..6c67f623e 100644 --- a/kronolith/lib/View/Day.php +++ b/kronolith/lib/View/Day.php @@ -27,9 +27,9 @@ class Kronolith_View_Day extends Kronolith_Day { $this->_sidebyside = $GLOBALS['prefs']->getValue('show_shared_side_by_side'); if ($this->_sidebyside) { - $allCalendars = Kronolith::listCalendars(); + $allCalendars = Kronolith::listInternalCalendars(); foreach ($GLOBALS['display_calendars'] as $cid) { - $this->_currentCalendars[$cid] = &$allCalendars[$cid]; + $this->_currentCalendars[$cid] = $allCalendars[$cid]; $this->_all_day_events[$cid] = array(); } } else { @@ -43,7 +43,8 @@ class Kronolith_View_Day extends Kronolith_Day { new Horde_Date(array('year' => $this->year, 'month' => $this->month, 'mday' => $this->mday)), - $GLOBALS['display_calendars']); + $GLOBALS['display_calendars'], + true, false, false); $this->_events = array_shift($events); } catch (Exception $e) { $GLOBALS['notification']->push($e, 'horde.error'); @@ -112,7 +113,7 @@ class Kronolith_View_Day extends Kronolith_Day { $rowspan = ($this->_all_day_maxrowspan) ? ' rowspan="' . $this->_all_day_maxrowspan . '"' : ''; for ($k = 0; $k < $this->_all_day_maxrowspan; ++$k) { $row = ''; - foreach ($this->_currentCalendars as $cid => $cal) { + foreach (array_keys($this->_currentCalendars) as $cid) { if (count($this->_all_day_events[$cid]) === $k) { // There are no events or all events for this calendar // have already been printed. @@ -168,7 +169,7 @@ class Kronolith_View_Day extends Kronolith_Day { $row .= ' '; } - foreach ($this->_currentCalendars as $cid => $cal) { + foreach (array_keys($this->_currentCalendars) as $cid) { $hspan = 0; foreach ($this->_event_matrix[$cid][$i] as $key) { $event = &$this->_events[$key]; @@ -295,7 +296,7 @@ class Kronolith_View_Day extends Kronolith_Day { // Separate out all day events and do some initialization/prep // for parsing. - foreach ($this->_currentCalendars as $cid => $cal) { + foreach (array_keys($this->_currentCalendars) as $cid) { $this->_all_day_events[$cid] = array(); $this->_all_day_rowspan[$cid] = 0; } @@ -340,7 +341,7 @@ class Kronolith_View_Day extends Kronolith_Day { // that we have here. for ($i = 0; $i < $this->_slotsPerDay; ++$i) { // Initialize this slot in the event matrix. - foreach ($this->_currentCalendars as $cid => $cal) { + foreach (array_keys($this->_currentCalendars) as $cid) { $this->_event_matrix[$cid][$i] = array(); } diff --git a/kronolith/lib/View/EditEvent.php b/kronolith/lib/View/EditEvent.php index d3a1e9096..549cc4896 100644 --- a/kronolith/lib/View/EditEvent.php +++ b/kronolith/lib/View/EditEvent.php @@ -48,9 +48,9 @@ class Kronolith_View_EditEvent { $identity = $GLOBALS['injector']->getInstance('Horde_Prefs_Identity')->getIdentity(); if ($this->event->hasPermission(Horde_Perms::EDIT)) { - $calendar_id = $this->event->calendar; + $calendar_id = $this->event->calendarType . '_' . $this->event->calendar; } else { - $calendar_id = Kronolith::getDefaultCalendar(Horde_Perms::EDIT); + $calendar_id = 'internal_' . Kronolith::getDefaultCalendar(Horde_Perms::EDIT); } if (!$this->event->hasPermission(Horde_Perms::EDIT)) { try { @@ -74,16 +74,7 @@ class Kronolith_View_EditEvent { if ($this->event->creator == $GLOBALS['registry']->getAuth()) { $perms |= Kronolith::PERMS_DELEGATE; } - $all_calendars = Kronolith::listCalendars(false, $perms); - $calendars = array(); - foreach ($all_calendars as $id => $calendar) { - if ($calendar->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($calendar->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $calendars[$id] = $calendar; - } + $calendars = Kronolith::listCalendars($perms, true); $buttons = array(); if (!$this->event->hasPermission(Horde_Perms::EDIT) && diff --git a/kronolith/lib/View/Month.php b/kronolith/lib/View/Month.php index bcb4a5ecd..b1d828841 100644 --- a/kronolith/lib/View/Month.php +++ b/kronolith/lib/View/Month.php @@ -92,13 +92,13 @@ class Kronolith_View_Month { 'mday' => $this->_startOfView + $this->_daysInView)); if ($prefs->getValue('show_shared_side_by_side')) { - $allCalendars = Kronolith::listCalendars(); + $allCalendars = Kronolith::listInternalCalendars(); $this->_currentCalendars = array(); foreach ($GLOBALS['display_calendars'] as $id) { - $this->_currentCalendars[$id] = &$allCalendars[$id]; + $this->_currentCalendars[$id] = $allCalendars[$id]; } } else { - $this->_currentCalendars = array(true); + $this->_currentCalendars = array('internal_0' => true); } try { diff --git a/kronolith/lib/View/Week.php b/kronolith/lib/View/Week.php index 1aef1c378..3db4bde96 100644 --- a/kronolith/lib/View/Week.php +++ b/kronolith/lib/View/Week.php @@ -70,7 +70,9 @@ class Kronolith_View_Week { } $endDate = new Horde_Date($day); try { - $allevents = Kronolith::listEvents($this->startDate, $endDate); + $allevents = Kronolith::listEvents($this->startDate, $endDate, + $GLOBALS['display_calendars'], + true, false, false); } catch (Exception $e) { $GLOBALS['notification']->push($e, 'horde.error'); $allevents = array(); @@ -111,7 +113,7 @@ class Kronolith_View_Week { $event_count = 0; for ($j = $this->startDay; $j <= $this->endDay; ++$j) { - foreach ($this->_currentCalendars as $cid => $cal) { + foreach (array_keys($this->_currentCalendars) as $cid) { $event_count = max($event_count, count($this->days[$j]->_all_day_events[$cid])); reset($this->days[$j]->_all_day_events[$cid]); } @@ -130,7 +132,7 @@ class Kronolith_View_Week { if ($this->days[$j]->_all_day_maxrowspan > 0) { for ($k = 0; $k < $this->days[$j]->_all_day_maxrowspan; ++$k) { $row .= ''; - foreach ($this->days[$j]->_currentCalendars as $cid => $cal) { + foreach (array_keys($this->days[$j]->_currentCalendars) as $cid) { if (count($this->days[$j]->_all_day_events[$cid]) === $k) { $row .= ' '; } elseif (count($this->days[$j]->_all_day_events[$cid]) > $k) { @@ -193,7 +195,7 @@ class Kronolith_View_Week { $row .= ' '; } - foreach ($this->_currentCalendars as $cid => $cal) { + foreach (array_keys($this->_currentCalendars) as $cid) { // Width (sum of colspans) of events for the current time // slot. $hspan = 0; @@ -331,7 +333,7 @@ class Kronolith_View_Week { $this->span = array(); for ($i = $this->startDay; $i <= $this->endDay; ++$i) { $this->totalspan += $this->days[$i]->_totalspan; - foreach ($this->_currentCalendars as $cid => $key) { + foreach (array_keys($this->_currentCalendars) as $cid) { if (isset($this->span[$cid])) { $this->span[$cid] += $this->days[$i]->_span[$cid]; } else { diff --git a/kronolith/new.php b/kronolith/new.php index 4ce04bdb7..1c5eb55bc 100644 --- a/kronolith/new.php +++ b/kronolith/new.php @@ -32,8 +32,8 @@ if ($perms->hasAppPermission('max_events') !== true && $url->redirect(); } -$calendar_id = Horde_Util::getFormData('calendar', Kronolith::getDefaultCalendar(Horde_Perms::EDIT)); -if (!$calendar_id) { +$calendar_id = Horde_Util::getFormData('calendar', 'internal_' . Kronolith::getDefaultCalendar(Horde_Perms::EDIT)); +if ($calendar_id == 'internal_') { $url->redirect(); } @@ -67,16 +67,7 @@ if (isset($url)) { $cancelurl = Horde::applicationUrl('month.php', true)->add('month', $month); } -$all_calendars = Kronolith::listCalendars(false, Horde_Perms::EDIT | Kronolith::PERMS_DELEGATE); -$calendars = array(); -foreach ($all_calendars as $id => $calendar) { - if ($calendar->get('owner') != $GLOBALS['registry']->getAuth() && - !empty($GLOBALS['conf']['share']['hidden']) && - !in_array($calendar->getName(), $GLOBALS['display_calendars'])) { - continue; - } - $calendars[$id] = $calendar; -} +$calendars = Kronolith::listCalendars(Horde_Perms::EDIT | Kronolith::PERMS_DELEGATE, true); Horde_Core_Ui_JsCalendar::init(array( 'full_weekdays' => true diff --git a/kronolith/search.php b/kronolith/search.php index b6edae8cf..d8e08cb1f 100644 --- a/kronolith/search.php +++ b/kronolith/search.php @@ -71,7 +71,7 @@ if ($search_mode == 'basic') { $optgroup = $GLOBALS['browser']->hasFeature('optgroup'); $current_user = $GLOBALS['registry']->getAuth(); $calendars = array(); - foreach (Kronolith::listCalendars(false, Horde_Perms::READ) as $id => $cal) { + foreach (Kronolith::listInternalCalendars(false, Horde_Perms::READ) as $id => $cal) { if ($cal->get('owner') && $cal->get('owner') == $current_user) { $calendars[_("My Calendars:")]['|' . $id] = $cal->get('name'); } else { @@ -82,21 +82,19 @@ if ($search_mode == 'basic') { $calendars[_("Shared Calendars:")]['|' . $id] = $cal->get('name'); } } - foreach ($GLOBALS['all_external_calendars'] as $api => $categories) { - $app = $GLOBALS['registry']->get('name', $GLOBALS['registry']->hasInterface($api)); - foreach ($categories as $id => $name) { - if (!empty($GLOBALS['conf']['share']['hidden']) && - !in_array($api . '/' . $id, $GLOBALS['display_external_calendars'])) { - continue; - } - $calendars[$app . ':']['Horde|external_' . $api . '/' . $id] = $name; + foreach ($GLOBALS['all_external_calendars'] as $id => $cal) { + $app = $GLOBALS['registry']->get('name', $GLOBALS['registry']->hasInterface($cal->api())); + if (!empty($GLOBALS['conf']['share']['hidden']) && + !in_array($id, $GLOBALS['display_external_calendars'])) { + continue; } + $calendars[$app . ':']['Horde|external_' . $id] = $cal->name(); } - foreach ($GLOBALS['all_remote_calendars'] as $cal) { - $calendars[_("Remote Calendars:")]['Ical|' . $cal['url']] = $cal['name']; + foreach ($GLOBALS['all_remote_calendars'] as $id => $cal) { + $calendars[_("Remote Calendars:")]['Ical|' . $id] = $cal->name(); } - foreach ($GLOBALS['all_holidays'] as $holiday) { - $calendars[_("Holidays:")]['Holidays|' . $holiday['id']] = $holiday['title']; + foreach ($GLOBALS['all_holidays'] as $id => $holiday) { + $calendars[_("Holidays:")]['Holidays|' . $id] = $holiday->name(); } } diff --git a/kronolith/templates/calendar_titles.inc b/kronolith/templates/calendar_titles.inc index e3a5fa314..31b68fc72 100644 --- a/kronolith/templates/calendar_titles.inc +++ b/kronolith/templates/calendar_titles.inc @@ -1,7 +1,7 @@ get('name')); + $calendar_names[] = htmlspecialchars($GLOBALS['all_calendars'][$calendarId]->name()); } if (!empty($GLOBALS['display_resource_calendars'])) { $driver = Kronolith::getDriver('Resource'); diff --git a/kronolith/templates/data/export.inc b/kronolith/templates/data/export.inc index 3e89317e3..3d98807f6 100644 --- a/kronolith/templates/data/export.inc +++ b/kronolith/templates/data/export.inc @@ -18,12 +18,12 @@ 1): ?>


- +
diff --git a/kronolith/templates/data/import.inc b/kronolith/templates/data/import.inc index 747f71aea..39410dcac 100644 --- a/kronolith/templates/data/import.inc +++ b/kronolith/templates/data/import.inc @@ -17,12 +17,12 @@ isLocked('default_share') && count($import_calendars ) > 1): ?>


- +
diff --git a/kronolith/templates/edit/edit.inc b/kronolith/templates/edit/edit.inc index ca88d161d..543cf9eb7 100644 --- a/kronolith/templates/edit/edit.inc +++ b/kronolith/templates/edit/edit.inc @@ -15,7 +15,7 @@ $hide_img = Horde::img('minus.png', _("Hide"), 'style="display:none"'); initialized && $event->hasPermission(Horde_Perms::EDIT)): ?> - + @@ -84,10 +84,10 @@ $hide_img = Horde::img('minus.png', _("Hide"), 'style="display:none"'); // Normal view foreach ($calendars as $id => $cal) { $delegates = array(); - if ($cal->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT, $event->creator)) { - $delegates[$id] = htmlspecialchars($cal->get('name')); + if ($cal->hasPermission(Horde_Perms::EDIT)) { + $delegates[$id] = htmlspecialchars($cal->name()); } else { - $delegates[$id . ':' . $cal->get('owner')] = htmlspecialchars($cal->get('name'). ' (' . sprintf(_("as %s"), Kronolith::getUserName($cal->get('owner'))) . ')'); + $delegates[$id . ':' . $cal->owner()] = htmlspecialchars($cal->name(). ' (' . sprintf(_("as %s"), Kronolith::getUserName($cal->owner())) . ')'); } foreach ($delegates as $delegate_id => $cal_name) { $sel = ($delegate_id == $calendar_id) ? ' selected="selected"' : ''; diff --git a/kronolith/templates/panel.inc b/kronolith/templates/panel.inc index 1a006813d..7d8cf69e7 100644 --- a/kronolith/templates/panel.inc +++ b/kronolith/templates/panel.inc @@ -16,7 +16,7 @@ $info_img = Horde::img('info_icon.png', _("Calendar Information"), array('class' $current_user = $GLOBALS['registry']->getAuth(); $my_calendars = array(); $shared_calendars = array(); -foreach (Kronolith::listCalendars() as $id => $cal) { +foreach (Kronolith::listInternalCalendars() as $id => $cal) { if ($cal->get('owner') && $cal->get('owner') == $current_user) { $my_calendars[$id] = $cal; } else { @@ -29,18 +29,13 @@ foreach (Kronolith::listCalendars() as $id => $cal) { } $externals = array(); -foreach ($all_external_calendars as $api => $categories) { - if (count($categories)) { - $app = $registry->get('name', $registry->hasInterface($api)); - $externals[$app] = array(); - foreach ($categories as $id => $name) { - if (!empty($conf['share']['hidden']) && - !in_array($api . '/' . $id, $display_external_calendars)) { - continue; - } - $externals[$app][$api . '/' . $id] = $name; - } +foreach ($all_external_calendars as $id => $calendar) { + $app = $registry->get('name', $registry->hasInterface($calendar->api())); + if (!empty($conf['share']['hidden']) && + !in_array($id, $display_external_calendars)) { + continue; } + $externals[$app][$id] = $calendar->name(); } $tagger = Kronolith::getTagger(); @@ -152,7 +147,7 @@ $GLOBALS['injector']->getInstance('Horde_Ajax_Imple')->getImple(array('kronolith

@@ -160,8 +155,8 @@ $GLOBALS['injector']->getInstance('Horde_Ajax_Imple')->getImple(array('kronolith

-- 2.11.0