From 3a2240a13d87eb6d6ac781f0b60f2f638249ed0e Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 26 Apr 2019 07:30:45 +0000 Subject: [PATCH] Fix inconsistency in handling other users "root" folders (Bifrost#T203416) Refactored some code to make sure we always deal with kolab_calendar instances. --- .../calendar/drivers/kolab/kolab_driver.php | 142 +++++++++--------- 1 file changed, 73 insertions(+), 69 deletions(-) diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 5a77256b..dbfd87a9 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -91,24 +91,38 @@ class kolab_driver extends calendar_driver $this->calendars = array(); foreach ($folders as $folder) { - if ($folder instanceof kolab_storage_folder_user) { - $calendar = new kolab_user_calendar($folder, $this->cal); - $calendar->subscriptions = count($folder->children) > 0; - } - else { - $calendar = new kolab_calendar($folder->name, $this->cal); - } - + $calendar = $this->_to_calendar($folder); if ($calendar->ready) { $this->calendars[$calendar->id] = $calendar; - if ($calendar->editable) + if ($calendar->editable) { $this->has_writeable = true; + } } } return $this->calendars; } + /** + * Convert kolab_storage_folder into kolab_calendar + */ + private function _to_calendar($folder) + { + if ($folder instanceof kolab_calendar) { + return $folder; + } + + if ($folder instanceof kolab_storage_folder_user) { + $calendar = new kolab_user_calendar($folder, $this->cal); + $calendar->subscriptions = count($folder->children) > 0; + } + else { + $calendar = new kolab_calendar($folder->name, $this->cal); + } + + return $calendar; + } + /** * Get a list of available calendars from this source * @@ -129,17 +143,17 @@ class kolab_driver extends calendar_driver } } - $delim = $this->rc->get_storage()->get_hierarchy_delimiter(); - $folders = $this->filter_calendars($filter); + $delim = $this->rc->get_storage()->get_hierarchy_delimiter(); + $folders = $this->filter_calendars($filter); $calendars = array(); // include virtual folders for a full folder tree if (!is_null($tree)) $folders = kolab_storage::folder_hierarchy($folders, $tree); + $parents = array_keys($this->calendars); + foreach ($folders as $id => $cal) { - $fullname = $cal->get_name(); - $listname = $cal->get_foldername(); $imap_path = explode($delim, $cal->name); // find parent @@ -147,72 +161,60 @@ class kolab_driver extends calendar_driver array_pop($imap_path); $parent_id = kolab_storage::folder_id(join($delim, $imap_path)); } - while (count($imap_path) > 1 && !$this->calendars[$parent_id]); + while (count($imap_path) > 1 && !in_array($parent_id, $parents)); // restore "real" parent ID - if ($parent_id && !$this->calendars[$parent_id]) { + if ($parent_id && !in_array($parent_id, $parents)) { $parent_id = kolab_storage::folder_id($cal->get_parent()); } - // turn a kolab_storage_folder object into a kolab_calendar - if ($cal instanceof kolab_storage_folder) { - $cal = new kolab_calendar($cal->name, $this->cal); - $this->calendars[$cal->id] = $cal; - } + $parents[] = $cal->id; - // special handling for user or virtual folders - if ($cal instanceof kolab_storage_folder_user) { + if ($cal->virtual) { $calendars[$cal->id] = array( 'id' => $cal->id, - 'name' => $fullname, - 'listname' => $listname, - 'editname' => $cal->get_foldername(), - 'color' => $cal->get_color(), - 'active' => $cal->is_active(), - 'title' => $cal->get_title(), - 'owner' => $cal->get_owner(), - 'history' => false, - 'virtual' => false, - 'editable' => false, - 'group' => 'other', - 'class' => 'user', - 'removable' => true, - ); - } - else if ($cal->virtual) { - $calendars[$cal->id] = array( - 'id' => $cal->id, - 'name' => $fullname, - 'listname' => $listname, + 'name' => $cal->get_name(), + 'listname' => $cal->get_foldername(), 'editname' => $cal->get_foldername(), 'virtual' => true, 'editable' => false, - 'group' => $cal->get_namespace(), - 'class' => 'folder', + 'group' => $cal->get_namespace(), ); } else { + // additional folders may come from kolab_storage::folder_hierarchy() above + // make sure we deal with kolab_calendar instances + $cal = $this->_to_calendar($cal); + $this->calendars[$cal->id] = $cal; + + $is_user = ($cal instanceof kolab_user_calendar); + $calendars[$cal->id] = array( - 'id' => $cal->id, - 'name' => $fullname, - 'listname' => $listname, - 'editname' => $cal->get_foldername(), - 'title' => $cal->get_title(), - 'color' => $cal->get_color(), - 'editable' => $cal->editable, - 'rights' => $cal->rights, - 'showalarms' => $cal->alarms, - 'history' => !empty($this->bonnie_api), - 'group' => $cal->get_namespace(), - 'default' => $cal->default, - 'active' => $cal->is_active(), - 'owner' => $cal->get_owner(), - 'children' => true, // TODO: determine if that folder indeed has child folders - 'parent' => $parent_id, - 'subtype' => $cal->subtype, - 'caldavurl' => $cal->get_caldav_url(), + 'id' => $cal->id, + 'name' => $cal->get_name(), + 'listname' => $cal->get_foldername(), + 'editname' => $cal->get_foldername(), + 'title' => $cal->get_title(), + 'color' => $cal->get_color(), + 'editable' => $cal->editable, + 'group' => $is_user ? 'other user' : $cal->get_namespace(), + 'active' => $cal->is_active(), + 'owner' => $cal->get_owner(), 'removable' => !$cal->default, ); + + if (!$is_user) { + $calendars[$cal->id] += array( + 'default' => $cal->default, + 'rights' => $cal->rights, + 'showalarms' => $cal->alarms, + 'history' => !empty($this->bonnie_api), + 'children' => true, // TODO: determine if that folder indeed has child folders + 'parent' => $parent_id, + 'subtype' => $cal->subtype, + 'caldavurl' => $cal->get_caldav_url(), + ); + } } if ($cal->subscriptions) { @@ -224,7 +226,6 @@ class kolab_driver extends calendar_driver if ($this->rc->config->get('kolab_invitation_calendars') && !($filter & self::FILTER_INSERTABLE)) { 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 (!($filter & self::FILTER_ACTIVE) || $cal->is_active()) { $calendars[$id] = array( 'id' => $cal->id, @@ -268,7 +269,7 @@ class kolab_driver extends calendar_driver 'active' => (bool)$prefs[$id]['active'], 'showalarms' => (bool)$this->rc->config->get('calendar_birthdays_alarm_type'), 'group' => 'x-birthdays', - 'editable' => false, + 'editable' => false, 'default' => false, 'children' => false, 'history' => false, @@ -337,11 +338,11 @@ class kolab_driver extends calendar_driver return $calendars; } - /** * Get the kolab_calendar instance for the given calendar ID * * @param string Calendar identifier (encoded imap folder name) + * * @return object kolab_calendar Object nor null if calendar doesn't exist */ public function get_calendar($id) @@ -351,9 +352,10 @@ class kolab_driver extends calendar_driver // create calendar object if necesary if (!$this->calendars[$id]) { if (in_array($id, array(self::INVITATIONS_CALENDAR_PENDING, self::INVITATIONS_CALENDAR_DECLINED))) { - $this->calendars[$id] = new kolab_invitation_calendar($id, $this->cal); + return new kolab_invitation_calendar($id, $this->cal); } - else if ($id !== self::BIRTHDAY_CALENDAR_ID) { + // for unsubscribed calendar folders + if ($id !== self::BIRTHDAY_CALENDAR_ID) { $calendar = kolab_calendar::factory($id, $this->cal); if ($calendar->ready) { $this->calendars[$calendar->id] = $calendar; @@ -370,13 +372,15 @@ class kolab_driver extends calendar_driver * @param array Hash array with calendar properties * name: Calendar name * color: The color of the calendar + * * @return mixed ID of the calendar on success, False on error */ public function create_calendar($prop) { - $prop['type'] = 'event'; - $prop['active'] = true; + $prop['type'] = 'event'; + $prop['active'] = true; $prop['subscribed'] = true; + $folder = kolab_storage::folder_update($prop); if ($folder === false) {