From 76f50f2d2bda86c6e11f59f1524af2a92d05202f Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Tue, 10 Mar 2015 15:23:52 +0100 Subject: [PATCH] Code cleanup: define filters for calendar listing as bitmask instead of individual arguments --- plugins/calendar/calendar.php | 38 +++++++++---------- plugins/calendar/drivers/calendar_driver.php | 27 ++++++++----- .../drivers/database/database_driver.php | 27 +++++++------ .../calendar/drivers/kolab/kolab_driver.php | 35 ++++++++--------- .../kolab/kolab_invitation_calendar.php | 2 +- plugins/calendar/lib/calendar_ui.php | 2 +- 6 files changed, 72 insertions(+), 59 deletions(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 3a35e1ef..da281143 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -263,7 +263,7 @@ class calendar extends rcube_plugin public function get_default_calendar($writeable = false, $confidential = false) { $default_id = $this->rc->config->get('calendar_default_calendar'); - $calendars = $this->driver->list_calendars(false, true); + $calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL); $calendar = $calendars[$default_id] ?: null; if (!$calendar || $confidential || ($writeable && $calendar['readonly'])) { foreach ($calendars as $cal) { @@ -512,7 +512,7 @@ class calendar extends rcube_plugin // default calendar selection $field_id = 'rcmfd_default_calendar'; $select_cal = new html_select(array('name' => '_default_calendar', 'id' => $field_id, 'is_escaped' => true)); - foreach ((array)$this->driver->list_calendars(false, true) as $id => $prop) { + foreach ((array)$this->driver->list_calendars(calendar_driver::FILTER_PERSONAL) as $id => $prop) { $select_cal->add($prop['name'], strval($id)); if ($prop['default']) $default_calendar = $id; @@ -902,7 +902,7 @@ class calendar extends rcube_plugin // search for event if only UID is given if (!isset($event['calendar']) && $event['uid']) { - if (!($event = $this->driver->get_event($event, true))) { + if (!($event = $this->driver->get_event($event, calendar_driver::FILTER_WRITEABLE))) { break; } $undo_time = 0; @@ -1174,7 +1174,7 @@ class calendar extends rcube_plugin if ($success !== true) { // send update notification on the main event if ($event['_savemode'] == 'future' && $event['_notify'] && $old['attendees'] && $old['recurrence_id']) { - $master = $this->driver->get_event(array('id' => $old['recurrence_id'], 'calendar' => $old['calendar'])); + $master = $this->driver->get_event(array('id' => $old['recurrence_id'], 'calendar' => $old['calendar']), 0, true); unset($master['_instance'], $master['recurrence_date']); $sent = $this->notify_attendees($master, null, $action, $event['_comment']); @@ -1200,12 +1200,12 @@ class calendar extends rcube_plugin // send notification for the main event when savemode is 'all' if ($action != 'remove' && $_savemode == 'all' && ($event['recurrence_id'] || $old['recurrence_id'] || ($old && $old['id'] != $event['id']))) { $event['id'] = $event['recurrence_id'] ?: ($old['recurrence_id'] ?: $old['id']); - $event = $this->driver->get_event($event); + $event = $this->driver->get_event($event, 0, true); unset($event['_instance'], $event['recurrence_date']); } else { // make sure we have the complete record - $event = $action == 'remove' ? $old : $this->driver->get_event($event); + $event = $action == 'remove' ? $old : $this->driver->get_event($event, 0, true); } $event['_savemode'] = $_savemode; @@ -1325,7 +1325,7 @@ class calendar extends rcube_plugin $counts = array(); - foreach ($this->driver->list_calendars(true) as $cal) { + foreach ($this->driver->list_calendars(calendar_driver::FILTER_ACTIVE) as $cal) { $events = $this->driver->load_events( rcube_utils::get_input_value('start', rcube_utils::INPUT_GPC), rcube_utils::get_input_value('end', rcube_utils::INPUT_GPC), @@ -1578,9 +1578,9 @@ class calendar extends rcube_plugin $filename = $calendars[$calid]['name'] ? $calendars[$calid]['name'] : $calid; $filename = asciiwords(html_entity_decode($filename)); // to 7bit ascii if (!empty($event_id)) { - if ($event = $this->driver->get_event(array('calendar' => $calid, 'id' => $event_id))) { + if ($event = $this->driver->get_event(array('calendar' => $calid, 'id' => $event_id), 0, true)) { if ($event['recurrence_id']) { - $event = $this->driver->get_event(array('calendar' => $calid, 'id' => $event['recurrence_id'])); + $event = $this->driver->get_event(array('calendar' => $calid, 'id' => $event['recurrence_id']), 0, true); } $events = array($event); $filename = asciiwords($event['title']); @@ -1815,7 +1815,7 @@ class calendar extends rcube_plugin $date = $_REQUEST['_date'] ?: 'now'; $dev = $_REQUEST['_dev'] ?: 30; $cats = array_keys($this->driver->list_categories()); - $cals = $this->driver->list_calendars(true); + $cals = $this->driver->list_calendars(calendar_driver::FILTER_ACTIVE); $count = 0; while ($count++ < $num) { @@ -2447,14 +2447,14 @@ class calendar extends rcube_plugin // find local copy of the referenced event $this->load_driver(); - $existing = $this->driver->get_event($data, true, false, true); + $existing = $this->driver->get_event($data, calendar_driver::FILTER_WRITEABLE | calendar_driver::FILTER_PERSONAL); $itip = $this->load_itip(); $response = $itip->get_itip_status($data, $existing); // get a list of writeable calendars to save new events to if (!$existing && !$data['nosave'] && $response['action'] == 'rsvp' || $response['action'] == 'import') { - $calendars = $this->driver->list_calendars(false, true); + $calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL); $calendar_select = new html_select(array('name' => 'calendar', 'id' => 'itip-saveto', 'is_escaped' => true)); $calendar_select->add('--', ''); $numcals = 0; @@ -2484,7 +2484,7 @@ class calendar extends rcube_plugin $day_end = new Datetime(gmdate('Y-m-d 23:59', $data['date']), $this->lib->timezone); // get events on that day from the user's personal calendars - $calendars = $this->driver->list_calendars(false, true); + $calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL); $events = $this->driver->load_events($day_start->format('U'), $day_end->format('U'), null, array_keys($calendars)); usort($events, function($a, $b) { return $a['start'] > $b['start'] ? 1 : -1; }); @@ -2522,7 +2522,7 @@ class calendar extends rcube_plugin $savemode = rcube_utils::get_input_value('_savemode', rcube_utils::INPUT_POST); // search for event if only UID is given - if ($event = $this->driver->get_event(array('uid' => $uid, '_instance' => $instance), true)) { + if ($event = $this->driver->get_event(array('uid' => $uid, '_instance' => $instance), calendar_driver::FILTER_WRITEABLE)) { $event['_savemode'] = $savemode; $success = $this->driver->remove_event($event, true); } @@ -2789,7 +2789,7 @@ class calendar extends rcube_plugin // find writeable calendar to store event $cal_id = !empty($_REQUEST['_folder']) ? rcube_utils::get_input_value('_folder', rcube_utils::INPUT_POST) : null; $dontsave = ($_REQUEST['_folder'] === '' && $event['_method'] == 'REQUEST'); - $calendars = $this->driver->list_calendars(false, true); + $calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL); $calendar = $calendars[$cal_id]; // select default calendar except user explicitly selected 'none' @@ -2841,8 +2841,8 @@ class calendar extends rcube_plugin // save to calendar if ($calendar && !$calendar['readonly']) { - // check for existing event with the same UID - $existing = $this->driver->get_event($event, true, false, true); + // check for existing event with the same UID + $existing = $this->driver->get_event($event, calendar_driver::FILTER_WRITEABLE | calendar_driver::FILTER_PERSONAL); if ($existing) { // forward savemode for correct updates of recurring events @@ -3102,7 +3102,7 @@ class calendar extends rcube_plugin if (!empty($events)) { // find writeable calendar to store event $cal_id = !empty($_REQUEST['_calendar']) ? rcube_utils::get_input_value('_calendar', rcube_utils::INPUT_POST) : null; - $calendars = $this->driver->list_calendars(false, true); + $calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL); foreach ($events as $event) { // save to calendar @@ -3110,7 +3110,7 @@ class calendar extends rcube_plugin if ($calendar && !$calendar['readonly'] && $event['_type'] == 'event') { $event['calendar'] = $calendar['id']; - if (!$this->driver->get_event($event['uid'], true, false)) { + if (!$this->driver->get_event($event['uid'], calendar_driver::FILTER_WRITEABLE)) { $success += (bool)$this->driver->new_event($event); } else { diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php index 1cd69561..959bddf7 100644 --- a/plugins/calendar/drivers/calendar_driver.php +++ b/plugins/calendar/drivers/calendar_driver.php @@ -94,6 +94,12 @@ */ abstract class calendar_driver { + const FILTER_ALL = 0; + const FILTER_WRITEABLE = 1; + const FILTER_ACTIVE = 2; + const FILTER_PERSONAL = 4; + const FILTER_PRIVATE = 8; + const FILTER_CONFIDENTIAL = 16; const BIRTHDAY_CALENDAR_ID = '__bdays__'; // features supported by backend @@ -118,12 +124,11 @@ abstract class calendar_driver /** * Get a list of available calendars from this source * - * @param bool $active Return only active calendars - * @param bool $personal Return only personal calendars - * + * @param integer Bitmask defining filter criterias. + * See FILTER_* constants for possible values. * @return array List of calendars */ - abstract function list_calendars($active = false, $personal = false); + abstract function list_calendars($filter = 0); /** * Create a new calendar assigned to the current user @@ -269,15 +274,17 @@ abstract class calendar_driver * Return data of a single event * * @param mixed UID string or hash array with event properties: - * id: Event identifier - * calendar: Calendar identifier (optional) - * @param boolean If true, only writeable calendars shall be searched - * @param boolean If true, only active calendars shall be searched - * @param boolean If true, only personal calendars shall be searched + * id: Event identifier + * uid: Event UID + * _instance: Instance identifier in combination with uid (optional) + * calendar: Calendar identifier (optional) + * @param integer Bitmask defining the scope to search events in. + * See FILTER_* constants for possible values. + * @param boolean If true, recurrence exceptions shall be added * * @return array Event object as hash array */ - abstract function get_event($event, $writeable = false, $active = false, $personal = false); + abstract function get_event($event, $scope = 0, $full = false); /** * Get events from source. diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php index 402e0c30..10eae038 100644 --- a/plugins/calendar/drivers/database/database_driver.php +++ b/plugins/calendar/drivers/database/database_driver.php @@ -99,12 +99,11 @@ class database_driver extends calendar_driver /** * Get a list of available calendars from this source * - * @param bool $active Return only active calendars - * @param bool $personal Return only personal calendars + * @param integer Bitmask defining filter criterias * * @return array List of calendars */ - public function list_calendars($active = false, $personal = false) + public function list_calendars($filter = 0) { // attempt to create a default calendar for this user if (empty($this->calendars)) { @@ -115,7 +114,7 @@ class database_driver extends calendar_driver $calendars = $this->calendars; // filter active calendars - if ($active) { + if ($filter & self::FILTER_ACTIVE) { foreach ($calendars as $idx => $cal) { if (!$cal['active']) { unset($calendars[$idx]); @@ -963,12 +962,11 @@ class database_driver extends calendar_driver /** * Return data of a specific event * @param mixed Hash array with event properties or event UID - * @param boolean Only search in writeable calendars (ignored) - * @param boolean Only search in active calendars - * @param boolean Only search in personal calendars (ignored) + * @param integer Bitmask defining the scope to search events in + * @param boolean If true, recurrence exceptions shall be added * @return array Hash array with event properties */ - public function get_event($event, $writeable = false, $active = false, $personal = false) + public function get_event($event, $scope = 0, $full = false) { $id = is_array($event) ? ($event['id'] ?: $event['uid']) : $event; $cal = is_array($event) ? $event['calendar'] : null; @@ -987,7 +985,7 @@ class database_driver extends calendar_driver return $this->get_birthday_event($id); } - if ($active) { + if ($scope & self::FILTER_ACTIVE) { $calendars = $this->calendars; foreach ($calendars as $idx => $cal) { if (!$cal['active']) { @@ -1012,8 +1010,15 @@ class database_driver extends calendar_driver ), $id); - if ($result && ($event = $this->rc->db->fetch_assoc($result)) && $event['event_id']) { - $this->cache[$id] = $this->_read_postprocess($event); + if ($result && ($sql_arr = $this->rc->db->fetch_assoc($result)) && $sql_arr['event_id']) { + $event = $this->_read_postprocess($sql_arr); + + // also load recurrence exceptions + if (!empty($event['recurrence']) && $full) { + $event['recurrence']['EXCEPTIONS'] = array_values($this->_load_exceptions($event)); + } + + $this->cache[$id] = $event; return $this->cache[$id]; } diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index f494e397..7cbeec72 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -114,13 +114,12 @@ class kolab_driver extends calendar_driver /** * Get a list of available calendars from this source * - * @param bool $active Return only active calendars - * @param bool $personal Return only personal calendars + * @param integer $filter Bitmask defining filter criterias * @param object $tree Reference to hierarchical folder tree object * * @return array List of calendars */ - public function list_calendars($active = false, $personal = false, &$tree = null) + public function list_calendars($filter = 0, &$tree = null) { // attempt to create a default calendar for this user if (!$this->has_writeable) { @@ -131,7 +130,7 @@ class kolab_driver extends calendar_driver } $delim = $this->rc->get_storage()->get_hierarchy_delimiter(); - $folders = $this->filter_calendars(false, $active, $personal); + $folders = $this->filter_calendars($filter); $calendars = array(); // include virtual folders for a full folder tree @@ -225,7 +224,7 @@ class kolab_driver extends calendar_driver foreach (array(self::INVITATIONS_CALENDAR_PENDING, self::INVITATIONS_CALENDAR_DECLINED) as $id) { $cal = new kolab_invitation_calendar($id, $this->cal); $this->calendars[$cal->id] = $cal; - if (!$active || $cal->is_active()) { + if (!($filter & self::FILTER_ACTIVE) || $cal->is_active()) { $calendars[$id] = array( 'id' => $cal->id, 'name' => $cal->get_name(), @@ -258,7 +257,7 @@ class kolab_driver extends calendar_driver if ($this->rc->config->get('calendar_contact_birthdays', false)) { $id = self::BIRTHDAY_CALENDAR_ID; $prefs = $this->rc->config->get('kolab_calendars', array()); // read local prefs - if (!$active || $prefs[$id]['active']) { + if (!($filter & self::FILTER_ACTIVE) || $prefs[$id]['active']) { $calendars[$id] = array( 'id' => $id, 'name' => $this->cal->gettext('birthdays'), @@ -281,19 +280,21 @@ class kolab_driver extends calendar_driver /** * Get list of calendars according to specified filters * - * @param bool $writeable Return only writeable calendars - * @param bool $active Return only active calendars - * @param bool $personal Return only personal calendars + * @param integer Bitmask defining restrictions. See FILTER_* constants for possible values. * * @return array List of calendars */ - protected function filter_calendars($writeable = false, $active = false, $personal = false) + protected function filter_calendars($filter) { $calendars = array(); $plugin = $this->rc->plugins->exec_hook('calendar_list_filter', array( - 'list' => $this->calendars, 'calendars' => $calendars, - 'writeable' => $writeable, 'active' => $active, 'personal' => $personal, + 'list' => $this->calendars, + 'calendars' => $calendars, + 'filter' => $filter, + 'writeable' => ($filter & self::FILTER_WRITEABLE), + 'active' => ($filter & self::FILTER_ACTIVE), + 'personal' => ($filter & self::FILTER_PERSONAL), )); if ($plugin['abort']) { @@ -304,13 +305,13 @@ class kolab_driver extends calendar_driver if (!$cal->ready) { continue; } - if ($writeable && $cal->readonly) { + if (($filter & self::FILTER_WRITEABLE) && $cal->readonly) { continue; } - if ($active && !$cal->is_active()) { + if (($filter & self::FILTER_ACTIVE) && !$cal->is_active()) { continue; } - if ($personal && $cal->get_namespace() != 'personal') { + if (($filter & self::FILTER_PERSONAL) && $cal->get_namespace() != 'personal') { continue; } $calendars[$cal->id] = $cal; @@ -531,7 +532,7 @@ class kolab_driver extends calendar_driver * @see calendar_driver::get_event() * @return array Hash array with event properties, false if not found */ - public function get_event($event, $writeable = false, $active = false, $personal = false) + public function get_event($event, $scope = 0, $full = false) { if (is_array($event)) { $id = $event['id'] ?: $event['uid']; @@ -558,7 +559,7 @@ class kolab_driver extends calendar_driver } // iterate over all calendar folders and search for the event ID else { - foreach ($this->filter_calendars($writeable, $active, $personal) as $calendar) { + foreach ($this->filter_calendars($scope) as $calendar) { if ($result = $calendar->get_event($id)) { return self::to_rcube_event($result); } diff --git a/plugins/calendar/drivers/kolab/kolab_invitation_calendar.php b/plugins/calendar/drivers/kolab/kolab_invitation_calendar.php index d63a77d8..0d4c987a 100644 --- a/plugins/calendar/drivers/kolab/kolab_invitation_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_invitation_calendar.php @@ -177,7 +177,7 @@ class kolab_invitation_calendar public function get_event($id) { // redirect call to kolab_driver::get_event() - $event = $this->cal->driver->get_event($id, true); + $event = $this->cal->driver->get_event($id, calendar_driver::FILTER_WRITEABLE); if (is_array($event)) { // add pointer to original calendar folder diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index 33ff37a5..00b74cd1 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -206,7 +206,7 @@ class calendar_ui $html = ''; $jsenv = array(); $tree = true; - $calendars = $this->cal->driver->list_calendars(false, false, $tree); + $calendars = $this->cal->driver->list_calendars(0, $tree); // walk folder tree if (is_object($tree)) {