Code cleanup: define filters for calendar listing as bitmask instead of individual arguments

This commit is contained in:
Thomas Bruederli 2015-03-10 15:23:52 +01:00
parent 60205136ee
commit 76f50f2d2b
6 changed files with 72 additions and 59 deletions

View file

@ -263,7 +263,7 @@ class calendar extends rcube_plugin
public function get_default_calendar($writeable = false, $confidential = false) public function get_default_calendar($writeable = false, $confidential = false)
{ {
$default_id = $this->rc->config->get('calendar_default_calendar'); $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; $calendar = $calendars[$default_id] ?: null;
if (!$calendar || $confidential || ($writeable && $calendar['readonly'])) { if (!$calendar || $confidential || ($writeable && $calendar['readonly'])) {
foreach ($calendars as $cal) { foreach ($calendars as $cal) {
@ -512,7 +512,7 @@ class calendar extends rcube_plugin
// default calendar selection // default calendar selection
$field_id = 'rcmfd_default_calendar'; $field_id = 'rcmfd_default_calendar';
$select_cal = new html_select(array('name' => '_default_calendar', 'id' => $field_id, 'is_escaped' => true)); $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)); $select_cal->add($prop['name'], strval($id));
if ($prop['default']) if ($prop['default'])
$default_calendar = $id; $default_calendar = $id;
@ -902,7 +902,7 @@ class calendar extends rcube_plugin
// search for event if only UID is given // search for event if only UID is given
if (!isset($event['calendar']) && $event['uid']) { 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; break;
} }
$undo_time = 0; $undo_time = 0;
@ -1174,7 +1174,7 @@ class calendar extends rcube_plugin
if ($success !== true) { if ($success !== true) {
// send update notification on the main event // send update notification on the main event
if ($event['_savemode'] == 'future' && $event['_notify'] && $old['attendees'] && $old['recurrence_id']) { 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']); unset($master['_instance'], $master['recurrence_date']);
$sent = $this->notify_attendees($master, null, $action, $event['_comment']); $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' // 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']))) { 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['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']); unset($event['_instance'], $event['recurrence_date']);
} }
else { else {
// make sure we have the complete record // 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; $event['_savemode'] = $_savemode;
@ -1325,7 +1325,7 @@ class calendar extends rcube_plugin
$counts = array(); $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( $events = $this->driver->load_events(
rcube_utils::get_input_value('start', rcube_utils::INPUT_GPC), rcube_utils::get_input_value('start', rcube_utils::INPUT_GPC),
rcube_utils::get_input_value('end', 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 = $calendars[$calid]['name'] ? $calendars[$calid]['name'] : $calid;
$filename = asciiwords(html_entity_decode($filename)); // to 7bit ascii $filename = asciiwords(html_entity_decode($filename)); // to 7bit ascii
if (!empty($event_id)) { 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']) { 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); $events = array($event);
$filename = asciiwords($event['title']); $filename = asciiwords($event['title']);
@ -1815,7 +1815,7 @@ class calendar extends rcube_plugin
$date = $_REQUEST['_date'] ?: 'now'; $date = $_REQUEST['_date'] ?: 'now';
$dev = $_REQUEST['_dev'] ?: 30; $dev = $_REQUEST['_dev'] ?: 30;
$cats = array_keys($this->driver->list_categories()); $cats = array_keys($this->driver->list_categories());
$cals = $this->driver->list_calendars(true); $cals = $this->driver->list_calendars(calendar_driver::FILTER_ACTIVE);
$count = 0; $count = 0;
while ($count++ < $num) { while ($count++ < $num) {
@ -2447,14 +2447,14 @@ class calendar extends rcube_plugin
// find local copy of the referenced event // find local copy of the referenced event
$this->load_driver(); $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(); $itip = $this->load_itip();
$response = $itip->get_itip_status($data, $existing); $response = $itip->get_itip_status($data, $existing);
// get a list of writeable calendars to save new events to // get a list of writeable calendars to save new events to
if (!$existing && !$data['nosave'] && $response['action'] == 'rsvp' || $response['action'] == 'import') { 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 = new html_select(array('name' => 'calendar', 'id' => 'itip-saveto', 'is_escaped' => true));
$calendar_select->add('--', ''); $calendar_select->add('--', '');
$numcals = 0; $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); $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 // 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)); $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; }); 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); $savemode = rcube_utils::get_input_value('_savemode', rcube_utils::INPUT_POST);
// search for event if only UID is given // 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; $event['_savemode'] = $savemode;
$success = $this->driver->remove_event($event, true); $success = $this->driver->remove_event($event, true);
} }
@ -2789,7 +2789,7 @@ class calendar extends rcube_plugin
// find writeable calendar to store event // find writeable calendar to store event
$cal_id = !empty($_REQUEST['_folder']) ? rcube_utils::get_input_value('_folder', rcube_utils::INPUT_POST) : null; $cal_id = !empty($_REQUEST['_folder']) ? rcube_utils::get_input_value('_folder', rcube_utils::INPUT_POST) : null;
$dontsave = ($_REQUEST['_folder'] === '' && $event['_method'] == 'REQUEST'); $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]; $calendar = $calendars[$cal_id];
// select default calendar except user explicitly selected 'none' // select default calendar except user explicitly selected 'none'
@ -2841,8 +2841,8 @@ class calendar extends rcube_plugin
// save to calendar // save to calendar
if ($calendar && !$calendar['readonly']) { if ($calendar && !$calendar['readonly']) {
// check for existing event with the same UID // check for existing event with the same UID
$existing = $this->driver->get_event($event, true, false, true); $existing = $this->driver->get_event($event, calendar_driver::FILTER_WRITEABLE | calendar_driver::FILTER_PERSONAL);
if ($existing) { if ($existing) {
// forward savemode for correct updates of recurring events // forward savemode for correct updates of recurring events
@ -3102,7 +3102,7 @@ class calendar extends rcube_plugin
if (!empty($events)) { if (!empty($events)) {
// find writeable calendar to store event // find writeable calendar to store event
$cal_id = !empty($_REQUEST['_calendar']) ? rcube_utils::get_input_value('_calendar', rcube_utils::INPUT_POST) : null; $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) { foreach ($events as $event) {
// save to calendar // save to calendar
@ -3110,7 +3110,7 @@ class calendar extends rcube_plugin
if ($calendar && !$calendar['readonly'] && $event['_type'] == 'event') { if ($calendar && !$calendar['readonly'] && $event['_type'] == 'event') {
$event['calendar'] = $calendar['id']; $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); $success += (bool)$this->driver->new_event($event);
} }
else { else {

View file

@ -94,6 +94,12 @@
*/ */
abstract class calendar_driver 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__'; const BIRTHDAY_CALENDAR_ID = '__bdays__';
// features supported by backend // features supported by backend
@ -118,12 +124,11 @@ abstract class calendar_driver
/** /**
* Get a list of available calendars from this source * Get a list of available calendars from this source
* *
* @param bool $active Return only active calendars * @param integer Bitmask defining filter criterias.
* @param bool $personal Return only personal calendars * See FILTER_* constants for possible values.
*
* @return array List of calendars * @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 * Create a new calendar assigned to the current user
@ -269,15 +274,17 @@ abstract class calendar_driver
* Return data of a single event * Return data of a single event
* *
* @param mixed UID string or hash array with event properties: * @param mixed UID string or hash array with event properties:
* id: Event identifier * id: Event identifier
* calendar: Calendar identifier (optional) * uid: Event UID
* @param boolean If true, only writeable calendars shall be searched * _instance: Instance identifier in combination with uid (optional)
* @param boolean If true, only active calendars shall be searched * calendar: Calendar identifier (optional)
* @param boolean If true, only personal calendars shall be searched * @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 * @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. * Get events from source.

View file

@ -99,12 +99,11 @@ class database_driver extends calendar_driver
/** /**
* Get a list of available calendars from this source * Get a list of available calendars from this source
* *
* @param bool $active Return only active calendars * @param integer Bitmask defining filter criterias
* @param bool $personal Return only personal calendars
* *
* @return array List of calendars * @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 // attempt to create a default calendar for this user
if (empty($this->calendars)) { if (empty($this->calendars)) {
@ -115,7 +114,7 @@ class database_driver extends calendar_driver
$calendars = $this->calendars; $calendars = $this->calendars;
// filter active calendars // filter active calendars
if ($active) { if ($filter & self::FILTER_ACTIVE) {
foreach ($calendars as $idx => $cal) { foreach ($calendars as $idx => $cal) {
if (!$cal['active']) { if (!$cal['active']) {
unset($calendars[$idx]); unset($calendars[$idx]);
@ -963,12 +962,11 @@ class database_driver extends calendar_driver
/** /**
* Return data of a specific event * Return data of a specific event
* @param mixed Hash array with event properties or event UID * @param mixed Hash array with event properties or event UID
* @param boolean Only search in writeable calendars (ignored) * @param integer Bitmask defining the scope to search events in
* @param boolean Only search in active calendars * @param boolean If true, recurrence exceptions shall be added
* @param boolean Only search in personal calendars (ignored)
* @return array Hash array with event properties * @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; $id = is_array($event) ? ($event['id'] ?: $event['uid']) : $event;
$cal = is_array($event) ? $event['calendar'] : null; $cal = is_array($event) ? $event['calendar'] : null;
@ -987,7 +985,7 @@ class database_driver extends calendar_driver
return $this->get_birthday_event($id); return $this->get_birthday_event($id);
} }
if ($active) { if ($scope & self::FILTER_ACTIVE) {
$calendars = $this->calendars; $calendars = $this->calendars;
foreach ($calendars as $idx => $cal) { foreach ($calendars as $idx => $cal) {
if (!$cal['active']) { if (!$cal['active']) {
@ -1012,8 +1010,15 @@ class database_driver extends calendar_driver
), ),
$id); $id);
if ($result && ($event = $this->rc->db->fetch_assoc($result)) && $event['event_id']) { if ($result && ($sql_arr = $this->rc->db->fetch_assoc($result)) && $sql_arr['event_id']) {
$this->cache[$id] = $this->_read_postprocess($event); $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]; return $this->cache[$id];
} }

View file

@ -114,13 +114,12 @@ class kolab_driver extends calendar_driver
/** /**
* Get a list of available calendars from this source * Get a list of available calendars from this source
* *
* @param bool $active Return only active calendars * @param integer $filter Bitmask defining filter criterias
* @param bool $personal Return only personal calendars
* @param object $tree Reference to hierarchical folder tree object * @param object $tree Reference to hierarchical folder tree object
* *
* @return array List of calendars * @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 // attempt to create a default calendar for this user
if (!$this->has_writeable) { if (!$this->has_writeable) {
@ -131,7 +130,7 @@ class kolab_driver extends calendar_driver
} }
$delim = $this->rc->get_storage()->get_hierarchy_delimiter(); $delim = $this->rc->get_storage()->get_hierarchy_delimiter();
$folders = $this->filter_calendars(false, $active, $personal); $folders = $this->filter_calendars($filter);
$calendars = array(); $calendars = array();
// include virtual folders for a full folder tree // 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) { foreach (array(self::INVITATIONS_CALENDAR_PENDING, self::INVITATIONS_CALENDAR_DECLINED) as $id) {
$cal = new kolab_invitation_calendar($id, $this->cal); $cal = new kolab_invitation_calendar($id, $this->cal);
$this->calendars[$cal->id] = $cal; $this->calendars[$cal->id] = $cal;
if (!$active || $cal->is_active()) { if (!($filter & self::FILTER_ACTIVE) || $cal->is_active()) {
$calendars[$id] = array( $calendars[$id] = array(
'id' => $cal->id, 'id' => $cal->id,
'name' => $cal->get_name(), 'name' => $cal->get_name(),
@ -258,7 +257,7 @@ class kolab_driver extends calendar_driver
if ($this->rc->config->get('calendar_contact_birthdays', false)) { if ($this->rc->config->get('calendar_contact_birthdays', false)) {
$id = self::BIRTHDAY_CALENDAR_ID; $id = self::BIRTHDAY_CALENDAR_ID;
$prefs = $this->rc->config->get('kolab_calendars', array()); // read local prefs $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( $calendars[$id] = array(
'id' => $id, 'id' => $id,
'name' => $this->cal->gettext('birthdays'), 'name' => $this->cal->gettext('birthdays'),
@ -281,19 +280,21 @@ class kolab_driver extends calendar_driver
/** /**
* Get list of calendars according to specified filters * Get list of calendars according to specified filters
* *
* @param bool $writeable Return only writeable calendars * @param integer Bitmask defining restrictions. See FILTER_* constants for possible values.
* @param bool $active Return only active calendars
* @param bool $personal Return only personal calendars
* *
* @return array List of calendars * @return array List of calendars
*/ */
protected function filter_calendars($writeable = false, $active = false, $personal = false) protected function filter_calendars($filter)
{ {
$calendars = array(); $calendars = array();
$plugin = $this->rc->plugins->exec_hook('calendar_list_filter', array( $plugin = $this->rc->plugins->exec_hook('calendar_list_filter', array(
'list' => $this->calendars, 'calendars' => $calendars, 'list' => $this->calendars,
'writeable' => $writeable, 'active' => $active, 'personal' => $personal, 'calendars' => $calendars,
'filter' => $filter,
'writeable' => ($filter & self::FILTER_WRITEABLE),
'active' => ($filter & self::FILTER_ACTIVE),
'personal' => ($filter & self::FILTER_PERSONAL),
)); ));
if ($plugin['abort']) { if ($plugin['abort']) {
@ -304,13 +305,13 @@ class kolab_driver extends calendar_driver
if (!$cal->ready) { if (!$cal->ready) {
continue; continue;
} }
if ($writeable && $cal->readonly) { if (($filter & self::FILTER_WRITEABLE) && $cal->readonly) {
continue; continue;
} }
if ($active && !$cal->is_active()) { if (($filter & self::FILTER_ACTIVE) && !$cal->is_active()) {
continue; continue;
} }
if ($personal && $cal->get_namespace() != 'personal') { if (($filter & self::FILTER_PERSONAL) && $cal->get_namespace() != 'personal') {
continue; continue;
} }
$calendars[$cal->id] = $cal; $calendars[$cal->id] = $cal;
@ -531,7 +532,7 @@ class kolab_driver extends calendar_driver
* @see calendar_driver::get_event() * @see calendar_driver::get_event()
* @return array Hash array with event properties, false if not found * @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)) { if (is_array($event)) {
$id = $event['id'] ?: $event['uid']; $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 // iterate over all calendar folders and search for the event ID
else { else {
foreach ($this->filter_calendars($writeable, $active, $personal) as $calendar) { foreach ($this->filter_calendars($scope) as $calendar) {
if ($result = $calendar->get_event($id)) { if ($result = $calendar->get_event($id)) {
return self::to_rcube_event($result); return self::to_rcube_event($result);
} }

View file

@ -177,7 +177,7 @@ class kolab_invitation_calendar
public function get_event($id) public function get_event($id)
{ {
// redirect call to kolab_driver::get_event() // 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)) { if (is_array($event)) {
// add pointer to original calendar folder // add pointer to original calendar folder

View file

@ -206,7 +206,7 @@ class calendar_ui
$html = ''; $html = '';
$jsenv = array(); $jsenv = array();
$tree = true; $tree = true;
$calendars = $this->cal->driver->list_calendars(false, false, $tree); $calendars = $this->cal->driver->list_calendars(0, $tree);
// walk folder tree // walk folder tree
if (is_object($tree)) { if (is_object($tree)) {