diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 51b40fbe..53ffbf05 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -229,23 +229,26 @@ class calendar extends rcube_plugin } /** - * + * Get properties of the calendar this user has specified as default */ public function get_default_calendar($writeable = false) { - $cal_id = $this->rc->config->get('calendar_default_calendar'); + $default_id = $this->rc->config->get('calendar_default_calendar'); $calendars = $this->driver->list_calendars(); - $calendar = $calendars[$cal_id] ? $calendars[$cal_id] : null; + $calendar = $calendars[$default_id] ?: null; if (!$calendar || ($writeable && $calendar['readonly'])) { foreach ($calendars as $cal) { - if (!$writeable || !$cal['readonly']) { + if ($cal['default']) { $calendar = $cal; break; } + if (!$writeable || !$cal['readonly']) { + $first = $cal; + } } } - - return $calendar; + + return $calendar ?: $first; } @@ -398,14 +401,16 @@ 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)); + $select_cal = new html_select(array('name' => '_default_calendar', 'id' => $field_id, 'is_escaped' => true)); foreach ((array)$this->driver->list_calendars() as $id => $prop) { if (!$prop['readonly']) $select_cal->add($prop['name'], strval($id)); + if ($prop['default']) + $default_calendar = $id; } $p['blocks']['view']['options']['defaultcalendar'] = array( 'title' => html::label($field_id . 'value', Q($this->gettext('defaultcalendar'))), - 'content' => $select_cal->show($this->rc->config->get('calendar_default_calendar', '')), + 'content' => $select_cal->show($this->rc->config->get('calendar_default_calendar', $default_calendar)), ); @@ -703,7 +708,7 @@ class calendar extends rcube_plugin else { // get a list of writeable calendars $calendars = $this->driver->list_calendars(); - $calendar_select = new html_select(array('name' => 'calendar', 'id' => 'calendar-saveto')); + $calendar_select = new html_select(array('name' => 'calendar', 'id' => 'calendar-saveto', 'is_escaped' => true)); $numcals = 0; foreach ($calendars as $calendar) { if (!$calendar['readonly']) { @@ -726,13 +731,14 @@ class calendar extends rcube_plugin } } + $default_calendar = $calendar_select ? $this->get_default_calendar(true) : null; $this->rc->output->command('plugin.update_event_rsvp_status', array( 'uid' => $event['uid'], 'id' => asciiwords($event['uid'], true), 'status' => $status, 'action' => $action, 'html' => $html, - 'select' => $calendar_select ? html::span('calendar-select', $this->gettext('saveincalendar') . ' ' . $calendar_select->show($this->rc->config->get('calendar_default_calendar'))) : '', + 'select' => $calendar_select ? html::span('calendar-select', $this->gettext('saveincalendar') . ' ' . $calendar_select->show($this->rc->config->get('calendar_default_calendar', $default_calendar['id']))) : '', )); return; @@ -1768,17 +1774,9 @@ class calendar extends rcube_plugin // successfully parsed events? if (!empty($events) && ($event = $events[$index])) { // find writeable calendar to store event - $cal_id = !empty($_REQUEST['_calendar']) ? get_input_value('_calendar', RCUBE_INPUT_POST) : $this->rc->config->get('calendar_default_calendar'); + $cal_id = !empty($_REQUEST['_calendar']) ? get_input_value('_calendar', RCUBE_INPUT_POST) : null; $calendars = $this->driver->list_calendars(); - $calendar = $calendars[$cal_id] ? $calendars[$cal_id] : null; - if (!$calendar || $calendar['readonly']) { - foreach ($calendars as $cal) { - if (!$cal['readonly']) { - $calendar = $cal; - break; - } - } - } + $calendar = $calendars[$cal_id] ?: $this->get_default_calendar(true); // update my attendee status according to submitted method if (!empty($status)) { diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php index 6d3a5a88..e3d9d51e 100644 --- a/plugins/calendar/drivers/database/database_driver.php +++ b/plugins/calendar/drivers/database/database_driver.php @@ -92,7 +92,8 @@ class database_driver extends calendar_driver ); while ($result && ($arr = $this->rc->db->fetch_assoc($result))) { $arr['showalarms'] = intval($arr['showalarms']); - $arr['active'] = !in_array($arr['id'], $hidden); + $arr['active'] = !in_array($arr['id'], $hidden); + $arr['name'] = html::quote($arr['name']); $this->calendars[$arr['calendar_id']] = $arr; $calendar_ids[] = $this->rc->db->quote($arr['calendar_id']); } diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 5cb0dc2b..18e51949 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -116,6 +116,7 @@ class kolab_driver extends calendar_driver 'readonly' => $cal->readonly, 'showalarms' => $cal->alarms, 'class_name' => $cal->get_namespace(), + 'default' => $cal->storage->default, 'active' => $cal->storage->is_subscribed(kolab_storage::SERVERSIDE_SUBSCRIPTION), ); } diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index cfa66846..63038e87 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -206,7 +206,7 @@ class calendar_ui $li .= html::tag('li', array('id' => 'rcmlical' . $html_id, 'class' => $class), html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active']), '') . html::span('handle', ' ') . - html::span('calname', Q($prop['name']))); + html::span('calname', $prop['name'])); } $this->rc->output->set_env('calendars', $jsenv); @@ -248,8 +248,10 @@ class calendar_ui */ function calendar_select($attrib = array()) { - $attrib['name'] = 'calendar'; + $attrib['name'] = 'calendar'; + $attrib['is_escaped'] = true; $select = new html_select($attrib); + foreach ((array)$this->cal->driver->list_calendars() as $id => $prop) { if (!$prop['readonly']) $select->add($prop['name'], $id); diff --git a/plugins/kolab_activesync/kolab_activesync_ui.php b/plugins/kolab_activesync/kolab_activesync_ui.php index 9e4fe5ce..a3ca623d 100644 --- a/plugins/kolab_activesync/kolab_activesync_ui.php +++ b/plugins/kolab_activesync/kolab_activesync_ui.php @@ -171,14 +171,14 @@ class kolab_activesync_ui $classes = array('mailbox'); if ($folder_class = rcmail_folder_classname($folder)) { - $foldername = rcube_label($folder_class); + $foldername = html::quote(rcube_label($folder_class)); $classes[] = $folder_class; } $folder_id = 'rcmf' . html_identifier($folder); $padding = str_repeat('    ', $level); - $table->add_row(array('class' => (($level+1) * $idx++) % 2 == 0 ? 'even' : 'odd')); + $table->add_row(); $table->add('subscription', $checkbox_sync->show( !empty($subscribed[$folder]) ? $folder : null, array('value' => $folder, 'id' => $folder_id))); @@ -189,7 +189,7 @@ class kolab_activesync_ui array('value' => $folder, 'id' => $folder_id.'_alarm'))); } - $table->add(join(' ', $classes), html::label($folder_id, $padding . Q($foldername))); + $table->add(join(' ', $classes), html::label($folder_id, $padding . $foldername)); } return $table->show(); diff --git a/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php b/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php index d2d0aad9..f04a1c26 100644 --- a/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php +++ b/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php @@ -1105,12 +1105,16 @@ class rcube_kolab_contacts extends rcube_addressbook $contact['uid'] = $old['uid']; $contact['email'] = array_filter($this->get_col_values('email', $contact, true)); - $contact['im'] = array_filter($this->get_col_values('im', $contact, true)); - + $contact['im'] = array_filter($this->get_col_values('im', $contact, true)); + + $websites = array(); + $phones = array(); + $addresses = array(); + foreach ($this->get_col_values('website', $contact) as $type => $values) { foreach ((array)$values as $url) { if (!empty($url)) { - $contact['website'][] = array('url' => $url, 'type' => $type); + $websites[] = array('url' => $url, 'type' => $type); } } unset($contact['website:'.$type]); @@ -1119,13 +1123,12 @@ class rcube_kolab_contacts extends rcube_addressbook foreach ($this->get_col_values('phone', $contact) as $type => $values) { foreach ((array)$values as $phone) { if (!empty($phone)) { - $contact['phone'][] = array('number' => $phone, 'type' => $type); + $phones[] = array('number' => $phone, 'type' => $type); } } unset($contact['phone:'.$type]); } - $addresses = array(); foreach ($this->get_col_values('address', $contact) as $type => $values) { foreach ((array)$values as $adr) { // skip empty address @@ -1145,6 +1148,9 @@ class rcube_kolab_contacts extends rcube_addressbook unset($contact['address:'.$type]); } + + $contact['website'] = $websites; + $contact['phone'] = $phones; $contact['address'] = $addresses; // copy meta data (starting with _) from old object diff --git a/plugins/kolab_auth/config.inc.php.dist b/plugins/kolab_auth/config.inc.php.dist index d14a3b92..d28ff08d 100644 --- a/plugins/kolab_auth/config.inc.php.dist +++ b/plugins/kolab_auth/config.inc.php.dist @@ -12,7 +12,6 @@ $rcmail_config['kolab_auth_login'] = 'email'; // Use this fields (from fieldmap configuration) for default identity $rcmail_config['kolab_auth_name'] = 'name'; -$rcmail_config['kolab_auth_alias'] = 'alias'; $rcmail_config['kolab_auth_email'] = 'email'; // Login and password of the admin user. Enables "Login As" feature. @@ -20,10 +19,10 @@ $rcmail_config['kolab_auth_admin_login'] = ''; $rcmail_config['kolab_auth_admin_password'] = ''; // Enable audit logging for abuse of administrative privileges. -$rcmail_config['kolab_auth_auditlog'] = true; +$rcmail_config['kolab_auth_auditlog'] = true; // Role field (from fieldmap configuration) -$rcmail_config['kolab_auth_role'] = 'role'; +$rcmail_config['kolab_auth_role'] = 'role'; // The required value for the role attribute to contain should the user be allowed // to login as another user. $rcmail_config['kolab_auth_role_value'] = ''; diff --git a/plugins/kolab_auth/kolab_auth.php b/plugins/kolab_auth/kolab_auth.php index 691f5422..00b9f8b4 100644 --- a/plugins/kolab_auth/kolab_auth.php +++ b/plugins/kolab_auth/kolab_auth.php @@ -203,8 +203,6 @@ class kolab_auth extends rcube_plugin $args['user_email'] = $this->data['user_email']; if (!empty($this->data['user_name'])) $args['user_name'] = $this->data['user_name']; - if (!empty($this->data['user_alias'])) - $args['user_alias'] = $this->data['user_alias']; return $args; } @@ -253,7 +251,6 @@ class kolab_auth extends rcube_plugin $admin_login = $rcmail->config->get('kolab_auth_admin_login'); $admin_pass = $rcmail->config->get('kolab_auth_admin_password'); $login_attr = $rcmail->config->get('kolab_auth_login'); - $alias_attr = $rcmail->config->get('kolab_auth_alias'); $name_attr = $rcmail->config->get('kolab_auth_name'); // get username and host @@ -351,8 +348,6 @@ class kolab_auth extends rcube_plugin if ($login_attr) $this->data['user_login'] = is_array($record[$login_attr]) ? $record[$login_attr][0] : $record[$login_attr]; - if ($alias_attr) - $this->data['user_alias'] = is_array($record[$alias_attr]) ? $record[$alias_attr][0] : $record[$alias_attr]; if ($name_attr) $this->data['user_name'] = is_array($record[$name_attr]) ? $record[$name_attr][0] : $record[$name_attr]; diff --git a/plugins/kolab_folders/kolab_folders.php b/plugins/kolab_folders/kolab_folders.php index 9e008470..297c858d 100644 --- a/plugins/kolab_folders/kolab_folders.php +++ b/plugins/kolab_folders/kolab_folders.php @@ -28,7 +28,9 @@ class kolab_folders extends rcube_plugin public $types = array('mail', 'event', 'journal', 'task', 'note', 'contact', 'configuration'); public $mail_types = array('inbox', 'drafts', 'sentitems', 'outbox', 'wastebasket', 'junkemail'); + private $rc; + private static $instance; /** @@ -36,6 +38,7 @@ class kolab_folders extends rcube_plugin */ function init() { + self::$instance = $this; $this->rc = rcmail::get_instance(); // load required plugin @@ -335,9 +338,13 @@ class kolab_folders extends rcube_plugin function get_folder_type($folder) { $storage = $this->rc->get_storage(); - $folderdata = $storage->get_metadata($folder, kolab_storage::CTYPE_KEY); + $folderdata = $storage->get_metadata($folder, array(kolab_storage::CTYPE_KEY_PRIVATE, kolab_storage::CTYPE_KEY)); - return explode('.', $folderdata[$folder][kolab_storage::CTYPE_KEY]); + if (!($ctype = $folderdata[$folder][kolab_storage::CTYPE_KEY_PRIVATE])) { + $ctype = $folderdata[$folder][kolab_storage::CTYPE_KEY]; + } + + return explode('.', $ctype); } /** @@ -351,8 +358,14 @@ class kolab_folders extends rcube_plugin function set_folder_type($folder, $type='mail') { $storage = $this->rc->get_storage(); + list($ctype, $subtype) = explode('.', $type); - return $storage->set_metadata($folder, array(kolab_storage::CTYPE_KEY => $type)); + $success = $storage->set_metadata($folder, array(kolab_storage::CTYPE_KEY => $ctype, kolab_storage::CTYPE_KEY_PRIVATE => $subtype ? $type : null)); + + if (!$success) // fallback: only set private annotation + $success |= $storage->set_metadata($folder, array(kolab_storage::CTYPE_KEY_PRIVATE => $type)); + + return $uccess; } /** @@ -365,7 +378,7 @@ class kolab_folders extends rcube_plugin function get_default_folder($type) { $storage = $this->rc->get_storage(); - $folderdata = $storage->get_metadata('*', kolab_storage::CTYPE_KEY); + $folderdata = $storage->get_metadata('*', array(kolab_storage::CTYPE_KEY_PRIVATE, kolab_storage::CTYPE_KEY)); if (!is_array($folderdata)) { return null; @@ -375,9 +388,8 @@ class kolab_folders extends rcube_plugin $namespace = $storage->get_namespace(); // get all folders of specified type - $folderdata = array_map('implode', $folderdata); + $folderdata = array_map(array($this, 'folder_select_metadata'), $folderdata); $folderdata = array_intersect($folderdata, array($type)); - unset($folders[0]); foreach ($folderdata as $folder => $data) { // check if folder is in personal namespace @@ -398,6 +410,14 @@ class kolab_folders extends rcube_plugin return null; } + /** + * Callback for array_map to select the correct annotation value + */ + private function folder_select_metadata($types) + { + return $types[kolab_storage::CTYPE_KEY_PRIVATE] ?: $types[kolab_storage::CTYPE_KEY]; + } + /** * Returns CSS class name for specified folder type * @@ -517,4 +537,15 @@ class kolab_folders extends rcube_plugin } } + + /** + * Static getter for default folder of the given type + * + * @param string $type Folder type + * @return string Folder name + */ + public static function default_folder($type) + { + return self::$instance->get_default_folder($type); + } } diff --git a/plugins/ldap_authentication/config.inc.php.dist b/plugins/ldap_authentication/config.inc.php.dist index ca745201..ff8e5120 100644 --- a/plugins/ldap_authentication/config.inc.php.dist +++ b/plugins/ldap_authentication/config.inc.php.dist @@ -12,7 +12,6 @@ $rcmail_config['ldap_authentication_login'] = 'email'; // Use this fields (from fieldmap configuration) for default identity $rcmail_config['ldap_authentication_name'] = 'name'; -$rcmail_config['ldap_authentication_alias'] = 'alias'; -$rcmail_config['ldap_authentication_email'] = 'email'; +$rcmail_config['ldap_authentication_email'] = 'email'; ?> diff --git a/plugins/ldap_authentication/ldap_authentication.php b/plugins/ldap_authentication/ldap_authentication.php index eee9a1db..d1561185 100644 --- a/plugins/ldap_authentication/ldap_authentication.php +++ b/plugins/ldap_authentication/ldap_authentication.php @@ -32,23 +32,21 @@ class ldap_authentication extends rcube_plugin private $ldap; private $data = array(); - function init() - { - $this->add_hook('authenticate', array($this, 'authenticate')); - $this->add_hook('user_create', array($this, 'user_create')); - } + function init() + { + $this->add_hook('authenticate', array($this, 'authenticate')); + $this->add_hook('user_create', array($this, 'user_create')); + } - function user_create($args) - { - if (!empty($this->data['user_email'])) - $args['user_email'] = $this->data['user_email']; - if (!empty($this->data['user_name'])) - $args['user_name'] = $this->data['user_name']; - if (!empty($this->data['user_alias'])) - $args['user_alias'] = $this->data['user_alias']; + function user_create($args) + { + if (!empty($this->data['user_email'])) + $args['user_email'] = $this->data['user_email']; + if (!empty($this->data['user_name'])) + $args['user_name'] = $this->data['user_name']; - return $args; - } + return $args; + } function authenticate($args) { @@ -83,13 +81,10 @@ class ldap_authentication extends rcube_plugin $record = $results->records[0]; $login_attr = $rcmail->config->get('ldap_authentication_login'); - $alias_attr = $rcmail->config->get('ldap_authentication_alias'); $name_attr = $rcmail->config->get('ldap_authentication_name'); if ($login_attr) $this->data['user_login'] = is_array($record[$login_attr]) ? $record[$login_attr][0] : $record[$login_attr]; - if ($alias_attr) - $this->data['user_alias'] = is_array($record[$alias_attr]) ? $record[$alias_attr][0] : $record[$alias_attr]; if ($name_attr) $this->data['user_name'] = is_array($record[$name_attr]) ? $record[$name_attr][0] : $record[$name_attr]; diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php index 68a8e817..546d19ab 100644 --- a/plugins/libkolab/lib/kolab_storage.php +++ b/plugins/libkolab/lib/kolab_storage.php @@ -25,8 +25,9 @@ class kolab_storage { const CTYPE_KEY = '/shared/vendor/kolab/folder-type'; + const CTYPE_KEY_PRIVATE = '/private/vendor/kolab/folder-type'; const COLOR_KEY_SHARED = '/shared/vendor/kolab/color'; - const COLOR_KEY_PRIVATE = '/shared/vendor/kolab/color'; + const COLOR_KEY_PRIVATE = '/private/vendor/kolab/color'; const SERVERSIDE_SUBSCRIPTION = 0; const CLIENTSIDE_SUBSCRIPTION = 1; @@ -389,10 +390,11 @@ class kolab_storage $delim = self::$imap->get_hierarchy_delimiter(); $folder = rcube_charset::convert($folder, 'UTF7-IMAP'); - $folder = str_replace($delim, ' » ', $folder); + $folder = html::quote($folder); + $folder = str_replace(html::quote($delim), ' » ', $folder); if ($prefix) - $folder = $prefix . ' ' . $folder; + $folder = html::quote($prefix) . ' ' . $folder; if (!$folder_ns) $folder_ns = 'personal'; @@ -480,6 +482,7 @@ class kolab_storage $names = array(); // Build SELECT field of parent folder + $attrs['is_escaped'] = true; $select = new html_select($attrs); $select->add('---', ''); @@ -536,13 +539,13 @@ class kolab_storage $prefix = $root . $mbox; // get folders types - $folderdata = self::$imap->get_metadata($prefix, self::CTYPE_KEY); + $folderdata = self::$imap->get_metadata($prefix, array(self::CTYPE_KEY, self::CTYPE_KEY_PRIVATE)); if (!is_array($folderdata)) { return array(); } - $folderdata = array_map('implode', $folderdata); + $folderdata = array_map(array('kolab_storage', 'folder_select_metadata'), $folderdata); $regexp = '/^' . preg_quote($filter, '/') . '(\..+)?$/'; // In some conditions we can skip LIST command (?) @@ -583,4 +586,13 @@ class kolab_storage return $folders; } + + /** + * Callback for array_map to select the correct annotation value + */ + static function folder_select_metadata($types) + { + return $types[self::CTYPE_KEY_PRIVATE] ?: $types[self::CTYPE_KEY]; + } + } diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php index 9a97fec2..daa988ff 100644 --- a/plugins/libkolab/lib/kolab_storage_folder.php +++ b/plugins/libkolab/lib/kolab_storage_folder.php @@ -76,8 +76,8 @@ class kolab_storage_folder public function set_folder($name, $ftype = null) { if (!$ftype) { - $metadata = $this->imap->get_metadata($name, array(kolab_storage::CTYPE_KEY)); - $this->type_annotation = $metadata[$name][kolab_storage::CTYPE_KEY]; + $metadata = $this->imap->get_metadata($name, array(kolab_storage::CTYPE_KEY, kolab_storage::CTYPE_KEY_PRIVATE)); + $this->type_annotation = $metadata[$name][kolab_storage::CTYPE_KEY_PRIVATE] ?: $metadata[$name][kolab_storage::CTYPE_KEY]; } else { $this->type_annotation = $ftype; diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php index a3a20ab3..60f9ccbb 100644 --- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php +++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php @@ -63,13 +63,23 @@ class tasklist_kolab_driver extends tasklist_driver // convert to UTF8 and sort $names = array(); + $default_folder = null; foreach ($this->folders as $i => $folder) { $names[$folder->name] = rcube_charset::convert($folder->name, 'UTF7-IMAP'); $this->folders[$folder->name] = $folder; + if ($folder->default) + $default_folder = $folder->name; } asort($names, SORT_LOCALE_STRING); + // put default folder (aka INBOX) on top of the list + if ($default_folder) { + $default_name = $names[$default_folder]; + unset($names[$default_folder]); + $names = array_merge(array($default_folder => $default_name), $names); + } + $delim = $this->rc->get_storage()->get_hierarchy_delimiter(); $listnames = array(); @@ -107,7 +117,8 @@ class tasklist_kolab_driver extends tasklist_driver 'editable' => !$readonly, 'active' => $folder->is_subscribed(kolab_storage::SERVERSIDE_SUBSCRIPTION), 'parentfolder' => $path_imap, - 'class_name' => $folder->get_namespace(), + 'default' => $folder->default, + 'class_name' => trim($folder->get_namespace() . ($folder->default ? ' default' : '')), ); $this->lists[$tasklist['id']] = $tasklist; $this->folders[$tasklist['id']] = $folder;