diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 816bf699..cf55d999 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -27,6 +27,7 @@ class kolab_calendar private $events; private $id2uid; private $imap_folder = 'INBOX/Calendar'; + private $namespace; private $sensitivity_map = array('public', 'private', 'confidential'); private $priority_map = array('low', 'normal', 'high'); @@ -61,6 +62,19 @@ class kolab_calendar $this->storage = rcube_kolab::get_storage($this->imap_folder); $this->ready = !PEAR::isError($this->storage); + + // Set readonly and editable flags according to folder permissions + if ($this->ready) { + if ($this->get_owner() == $_SESSION['username']) { + $this->readonly = false; + } + else { + $acl = $this->storage->_folder->getACL(); + $acl = $acl[$_SESSION['username']]; + if (strpos($acl, 'i') !== false) + $this->readonly = false; + } + } } @@ -72,9 +86,8 @@ class kolab_calendar */ public function get_name() { - // @TODO: get namespace prefixes from IMAP - $dispname = preg_replace(array('!INBOX/Calendar/!', '!^INBOX/!', '!^shared/!', '!^user/([^/]+)/!'), array('','','','(\\1) '), $this->imap_folder); - return rcube_charset_convert(strlen($dispname) ? $dispname : $this->imap_folder, "UTF7-IMAP"); + $folder = rcube_kolab::object_name($this->imap_folder, $this->namespace); + return $folder; } @@ -89,6 +102,31 @@ class kolab_calendar } + /** + * Getter for the IMAP folder owner + * + * @return string Name of the folder owner + */ + public function get_owner() + { + return $this->storage->_folder->getOwner(); + } + + + /** + * Getter for the name of the namespace to which the IMAP folder belongs + * + * @return string Name of the namespace (personal, other, shared) + */ + public function get_namespace() + { + if ($this->namespace === null) { + $this->namespace = rcube_kolab::folder_namespace($this->imap_folder); + } + return $this->namespace; + } + + /** * Getter for the top-end calendar folder name (not the entire path) * @@ -195,18 +233,15 @@ class kolab_calendar { if (!is_array($event)) return false; - - - + //generate new event from RC input $object = $this->_from_rcube_event($event); - + //generate new UID $object['uid'] = $this->storage->generateUID(); - - + $saved = $this->storage->save($object); - + return $saved; } diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index b6114c58..c58ef345 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -29,7 +29,6 @@ class kolab_driver extends calendar_driver private $rc; private $cal; private $calendars; - private $folders; /** * Default constructor @@ -49,49 +48,37 @@ class kolab_driver extends calendar_driver { // already read sources if (isset($this->calendars)) - return $this->calendars; + return $this->calendars; // get all folders that have "event" type $folders = rcube_kolab::get_folders('event'); - $this->folders = $this->calendars = array(); + $this->calendars = array(); if (PEAR::isError($folders)) { - raise_error(array( - 'code' => 600, 'type' => 'php', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Failed to list calendar folders from Kolab server:" . $folders->getMessage()), - true, false); + raise_error(array( + 'code' => 600, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Failed to list calendar folders from Kolab server:" . $folders->getMessage()), + true, false); } else { - foreach ($folders as $c_folder) { - $calendar = new kolab_calendar($c_folder->name, $this->cal); - $this->folders[$calendar->id] = $calendar; - if ($calendar->ready) { - $this->calendars[$calendar->id] = array( - 'id' => $calendar->id, - 'name' => $calendar->get_name(), - 'editname' => $calendar->get_foldername(), - 'color' => $calendar->get_color(), - 'readonly' => $c_folder->_owner != $_SESSION['username'], - ); - } - } + // convert to UTF8 and sort + $names = array(); + foreach ($folders as $folder) + $names[$folder->name] = rcube_charset_convert($folder->name, 'UTF7-IMAP'); + + asort($names, SORT_LOCALE_STRING); + + foreach ($names as $utf7name => $name) { + $calendar = new kolab_calendar($utf7name, $this->cal); + $this->calendars[$calendar->id] = $calendar; + } } return $this->calendars; } - private function _get_storage($cid, $readonly = false) - { - if ($readonly) - return $this->folders[$cid]; - else if (!$this->calendars[$cid]['readonly']) - return $this->folders[$cid]; - return false; - } - - /** * Get a list of available calendars from this source */ @@ -99,11 +86,41 @@ class kolab_driver extends calendar_driver { // attempt to create a default calendar for this user if (empty($this->calendars)) { - if ($this->create_calendar(array('name' => 'Default', 'color' => 'cc0000'))) + if ($this->create_calendar(array('name' => 'Calendar', 'color' => 'cc0000'))) $this->_read_calendars(); } - return $this->calendars; + $calendars = $names = array(); + + foreach ($this->calendars as $id => $cal) { + if ($cal->ready) { + $name = $origname = $cal->get_name(); + + // find folder prefix to truncate (the same code as in kolab_addressbook plugin) + for ($i = count($names)-1; $i >= 0; $i--) { + if (strpos($name, $names[$i].' » ') === 0) { + $length = strlen($names[$i].' » '); + $prefix = substr($name, 0, $length); + $count = count(explode(' » ', $prefix)); + $name = str_repeat('  ', $count-1) . '» ' . substr($name, $length); + break; + } + } + + $names[] = $origname; + + $calendars[$cal->id] = array( + 'id' => $cal->id, + 'name' => $name, + 'editname' => $cal->get_foldername(), + 'color' => $cal->get_color(), + 'readonly' => $cal->readonly, + 'class_name' => $cal->get_namespace(), + ); + } + } + + return $calendars; } @@ -148,7 +165,7 @@ class kolab_driver extends calendar_driver */ public function edit_calendar($prop) { - if ($prop['id'] && ($cal = $this->folders[$prop['id']])) { + if ($prop['id'] && ($cal = $this->calendars[$prop['id']])) { $newfolder = rcube_charset_convert($prop['name'], RCMAIL_CHARSET, 'UTF7-IMAP'); $oldfolder = $cal->get_realname(); // add namespace prefix (when needed) @@ -185,7 +202,7 @@ class kolab_driver extends calendar_driver */ public function remove_calendar($prop) { - if ($prop['id'] && ($cal = $this->folders[$prop['id']])) { + if ($prop['id'] && ($cal = $this->calendars[$prop['id']])) { $folder = $cal->get_realname(); if (rcube_kolab::folder_delete($folder)) { // remove color in user prefs (temp. solution) @@ -209,7 +226,7 @@ class kolab_driver extends calendar_driver public function new_event($event) { $cid = $event['calendar'] ? $event['calendar'] : reset(array_keys($this->calendars)); - if ($storage = $this->_get_storage($cid)) + if ($storage = $this->calendars($cid)) return $storage->insert_event($event); return false; @@ -223,7 +240,7 @@ class kolab_driver extends calendar_driver */ public function edit_event($event) { - if ($storage = $this->_get_storage($event['calendar'])) + if ($storage = $this->calendars[$event['calendar']]) return $storage->update_event($event); return false; @@ -237,7 +254,7 @@ class kolab_driver extends calendar_driver */ public function move_event($event) { - if (($storage = $this->_get_storage($event['calendar'])) && ($ev = $storage->get_event($event['id']))) + if (($storage = $this->calendars[$event['calendar']]) && ($ev = $storage->get_event($event['id']))) return $storage->update_event($event + $ev); return false; @@ -266,9 +283,9 @@ class kolab_driver extends calendar_driver */ public function remove_event($event) { - if (($storage = $this->_get_storage($event['calendar'])) && ($ev = $storage->get_event($event['id']))) + if (($storage = $this->calendars[$event['calendar']]) && ($ev = $storage->get_event($event['id']))) return $storage->delete_event($event); - + return false; } @@ -285,15 +302,15 @@ class kolab_driver extends calendar_driver { if ($calendars && is_string($calendars)) $calendars = explode(',', $calendars); - + $events = array(); foreach ($this->calendars as $cid => $calendar) { if ($calendars && !in_array($cid, $calendars)) continue; - - $events = array_merge($this->folders[$cid]->list_events($start, $end, $search)); + + $events = array_merge($this->calendars[$cid]->list_events($start, $end, $search)); } - + return $events; } diff --git a/plugins/calendar/skins/default/calendar.css b/plugins/calendar/skins/default/calendar.css index dfa94948..304bebfc 100644 --- a/plugins/calendar/skins/default/calendar.css +++ b/plugins/calendar/skins/default/calendar.css @@ -92,10 +92,11 @@ pre { #calendarslist li { margin: 0; - padding: 2px; + padding: 1px; display: block; background: #fff; border-bottom: 1px solid #EBEBEB; + white-space: nowrap; } #calendarslist li label { @@ -104,6 +105,8 @@ pre { #calendarslist li span { cursor: default; + background: url(images/calendars.png) 0 -3px no-repeat; + padding-left: 18px; } #calendarslist li input { @@ -119,6 +122,26 @@ pre { font-weight: bold; } +#calendarslist li.readonly span { + background-position: 0 -21px; +} + +#calendarslist li.other span { + background-position: 0 -39px; +} + +#calendarslist li.other.readonly span { + background-position: 0 -57px; +} + +#calendarslist li.shared span { + background-position: 0 -75px; +} + +#calendarslist li.shared.readonly span { + background-position: 0 -93px; +} + #agendalist { width: 100%; margin: 0 auto; diff --git a/plugins/calendar/skins/default/images/calendars.png b/plugins/calendar/skins/default/images/calendars.png new file mode 100644 index 00000000..305daaa0 Binary files /dev/null and b/plugins/calendar/skins/default/images/calendars.png differ