diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -788,6 +788,22 @@ case "subscribe": if (!$this->driver->subscribe_calendar($cal)) $this->rc->output->show_message($this->gettext('errorsaving'), 'error'); + else { + $calendars = $this->driver->list_calendars(); + $calendar = $calendars[$cal['id']]; + + // find parent folder and check if it's a "user calendar" + // if it's also activated we need to refresh it (#5340) + while ($calendar['parent']) { + if (isset($calendars[$calendar['parent']])) + $calendar = $calendars[$calendar['parent']]; + else + break; + } + + if ($calendar['id'] != $cal['id'] && $calendar['active'] && $calendar['group'] == "other user") + $this->rc->output->command('plugin.refresh_source', $calendar['id']); + } return; case "search": $results = array(); diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -2958,6 +2958,15 @@ return false; }; + this.calendar_refresh_source = function(id) + { + // got race-conditions fc.currentFetchID when using refetchEvents, + // so we remove and add the source instead + // fc.fullCalendar('refetchEvents', me.calendars[id]); + fc.fullCalendar('removeEventSource', me.calendars[id]); + fc.fullCalendar('addEventSource', me.calendars[id]); + }; + this.calendar_destroy_source = function(id) { var delete_ids = []; @@ -4235,6 +4244,7 @@ rcmail.register_command('add-resource', function(){ cal.add_resource2event(); }, false); // register callback commands + rcmail.addEventListener('plugin.refresh_source', function(data) { cal.calendar_refresh_source(data); }); rcmail.addEventListener('plugin.destroy_source', function(p){ cal.calendar_destroy_source(p.id); }); rcmail.addEventListener('plugin.unlock_saving', function(p){ cal.unlock_saving(); }); rcmail.addEventListener('plugin.refresh_calendar', function(p){ cal.refresh(p); }); diff --git a/plugins/calendar/drivers/kolab/kolab_user_calendar.php b/plugins/calendar/drivers/kolab/kolab_user_calendar.php --- a/plugins/calendar/drivers/kolab/kolab_user_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_user_calendar.php @@ -223,11 +223,11 @@ } } - // aggregate all calendar folders the user shares (but are not subscribed) - foreach (kolab_storage::list_user_folders($this->userdata, 'event', false) as $foldername) { + // aggregate all calendar folders the user shares (but are not activated) + foreach (kolab_storage::list_user_folders($this->userdata, 'event', 2) as $foldername) { $cal = new kolab_calendar($foldername, $this->cal); foreach ($cal->list_events($start, $end, $search, 1) as $event) { - $this->events[$event['id']] = $event; + $this->events[$event['id'] ?: $event['uid']] = $event; $this->timeindex[$this->time_key($event)] = $event['id']; } } diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php --- a/plugins/libkolab/lib/kolab_storage.php +++ b/plugins/libkolab/lib/kolab_storage.php @@ -825,11 +825,7 @@ if (!$filter) { // Get ALL folders list, standard way if ($subscribed) { - $folders = self::$imap->list_folders_subscribed($root, $mbox); - // add temporarily subscribed folders - if (self::$with_tempsubs && is_array($_SESSION['kolab_subscribed_folders'])) { - $folders = array_unique(array_merge($folders, $_SESSION['kolab_subscribed_folders'])); - } + $folders = self::_imap_list_subscribed($root, $mbox); } else { $folders = self::_imap_list_folders($root, $mbox); @@ -866,12 +862,7 @@ // Get folders list if ($subscribed) { - $folders = self::$imap->list_folders_subscribed($root, $mbox); - - // add temporarily subscribed folders - if (self::$with_tempsubs && is_array($_SESSION['kolab_subscribed_folders'])) { - $folders = array_unique(array_merge($folders, $_SESSION['kolab_subscribed_folders'])); - } + $folders = self::_imap_list_subscribed($root, $mbox); } else { $folders = self::_imap_list_folders($root, $mbox); @@ -934,6 +925,21 @@ return $folders; } + /** + * Wrapper for rcube_imap::list_folders_subscribed() + * with support for temporarily subscribed folders + */ + protected static function _imap_list_subscribed($root, $mbox) + { + $folders = self::$imap->list_folders_subscribed($root, $mbox); + + // add temporarily subscribed folders + if (self::$with_tempsubs && is_array($_SESSION['kolab_subscribed_folders'])) { + $folders = array_unique(array_merge($folders, $_SESSION['kolab_subscribed_folders'])); + } + + return $folders; + } /** * Search for shared or otherwise not listed groupware folders the user has access @@ -1538,12 +1544,12 @@ * * @param array User entry from LDAP * @param string Data type to list folders for (contact,event,task,journal,file,note,mail,configuration) - * @param boolean Return subscribed folders only (null to use configured subscription mode) + * @param int 1 - subscribed folders only, 0 - all folders, 2 - all non-active * @param array Will be filled with folder-types data * * @return array List of folders */ - public static function list_user_folders($user, $type, $subscribed = null, &$folderdata = array()) + public static function list_user_folders($user, $type, $subscribed = 0, &$folderdata = array()) { self::setup(); @@ -1554,9 +1560,19 @@ if (!empty($user[$user_attrib])) { list($mbox) = explode('@', $user[$user_attrib]); - $delimiter = self::$imap->get_hierarchy_delimiter(); - $other_ns = self::namespace_root('other'); - $folders = self::list_folders($other_ns . $mbox . $delimiter, '*', $type, $subscribed, $folderdata); + $delimiter = self::$imap->get_hierarchy_delimiter(); + $other_ns = self::namespace_root('other'); + $prefix = $other_ns . $mbox . $delimiter; + $subscribed = (int) $subscribed; + $subs = $subscribed < 2 ? (bool) $subscribed : false; + $folders = self::list_folders($prefix, '*', $type, $subs, $folderdata); + + if ($subscribed === 2 && !empty($folders)) { + $active = self::get_states(); + if (!empty($active)) { + $folders = array_diff($folders, $active); + } + } } return $folders;