plugins/kolab_addressbook plugins/libkolab
Aleksander Machniak
machniak at kolabsys.com
Wed Aug 7 09:42:35 CEST 2013
plugins/kolab_addressbook/kolab_addressbook.php | 87 +++++++++------
plugins/libkolab/lib/kolab_storage.php | 139 ++++++++++++++++++++----
2 files changed, 178 insertions(+), 48 deletions(-)
New commits:
commit 27eb70693985a5e8aa8033b95b70433ff68aec71
Author: Aleksander Machniak <machniak at kolabsys.com>
Date: Wed Aug 7 09:39:21 2013 +0200
Fixed bug where Error No.700 was thrown by Roundcube in cases
when there's no addressbook (no subscribed contact folders and no
global addressbooks). It's fixed by forcing folder creation/subscription
and forcing of kolab_addressbook_prio value accordingly (Bug #2086).
diff --git a/plugins/kolab_addressbook/kolab_addressbook.php b/plugins/kolab_addressbook/kolab_addressbook.php
index 2059dea..d6f0d6d 100644
--- a/plugins/kolab_addressbook/kolab_addressbook.php
+++ b/plugins/kolab_addressbook/kolab_addressbook.php
@@ -31,7 +31,6 @@ class kolab_addressbook extends rcube_plugin
{
public $task = 'mail|settings|addressbook|calendar';
- private $folders;
private $sources;
private $rc;
private $ui;
@@ -93,11 +92,8 @@ class kolab_addressbook extends rcube_plugin
*/
public function address_sources($p)
{
- // Load configuration
- $this->load_config();
-
- $abook_prio = (int) $this->rc->config->get('kolab_addressbook_prio');
- $undelete = $this->rc->config->get('undo_timeout');
+ $abook_prio = $this->addressbook_prio();
+ $undelete = $this->rc->config->get('undo_timeout');
// Disable all global address books
// Assumes that all non-kolab_addressbook sources are global
@@ -155,10 +151,7 @@ class kolab_addressbook extends rcube_plugin
return $args;
}
- // Load configuration
- $this->load_config();
-
- $abook_prio = (int) $this->rc->config->get('kolab_addressbook_prio');
+ $abook_prio = $this->addressbook_prio();
// here we cannot use rc->config->get()
$sources = $GLOBALS['CONFIG']['autocomplete_addressbooks'];
@@ -222,10 +215,7 @@ class kolab_addressbook extends rcube_plugin
$this->sources = array();
- // Load configuration
- $this->load_config();
-
- $abook_prio = (int) $this->rc->config->get('kolab_addressbook_prio');
+ $abook_prio = $this->addressbook_prio();
// Personal address source(s) disabled?
if ($abook_prio == self::GLOBAL_ONLY) {
@@ -233,19 +223,27 @@ class kolab_addressbook extends rcube_plugin
}
// get all folders that have "contact" type
- $this->folders = kolab_storage::sort_folders(kolab_storage::get_folders('contact'));
+ $folders = kolab_storage::sort_folders(kolab_storage::get_folders('contact'));
- if (PEAR::isError($this->folders)) {
+ if (PEAR::isError($folders)) {
rcube::raise_error(array(
'code' => 600, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Failed to list contact folders from Kolab server:" . $this->folders->getMessage()),
+ 'message' => "Failed to list contact folders from Kolab server:" . $folders->getMessage()),
true, false);
}
else {
+ // we need at least one folder to prevent from errors in Roundcube core
+ // when there's also no sql nor ldap addressbook (Bug #2086)
+ if (empty($folders)) {
+ if ($folder = kolab_storage::create_default_folder('contact')) {
+ $folders = array(new kolab_storage_folder($folder, 'contact'));
+ }
+ }
+
// convert to UTF8 and sort
$names = array();
- foreach ($this->folders as $folder) {
+ foreach ($folders as $folder) {
// create instance of rcube_contacts
$abook_id = kolab_storage::folder_id($folder->name);
$abook = new rcube_kolab_contacts($folder->name);
@@ -325,16 +323,22 @@ class kolab_addressbook extends rcube_plugin
return $args;
}
- // Load configuration
- $this->load_config();
+ $ldap_public = $this->rc->config->get('ldap_public');
+ $abook_type = $this->rc->config->get('address_book_type');
- // Load localization
- $this->add_texts('localization');
+ // Hide option if there's no global addressbook
+ if (empty($ldap_public) || $abook_type != 'ldap') {
+ return $args;
+ }
// Check that configuration is not disabled
- $dont_override = (array) $this->rc->config->get('dont_override', array());
+ $dont_override = (array) $this->rc->config->get('dont_override', array());
+ $prio = $this->addressbook_prio();
if (!in_array('kolab_addressbook_prio', $dont_override)) {
+ // Load localization
+ $this->add_texts('localization');
+
$field_id = '_kolab_addressbook_prio';
$select = new html_select(array('name' => $field_id, 'id' => $field_id));
@@ -345,7 +349,7 @@ class kolab_addressbook extends rcube_plugin
$args['blocks']['main']['options']['kolab_addressbook_prio'] = array(
'title' => html::label($field_id, Q($this->gettext('addressbookprio'))),
- 'content' => $select->show((int)$this->rc->config->get('kolab_addressbook_prio')),
+ 'content' => $select->show($prio),
);
}
@@ -365,14 +369,11 @@ class kolab_addressbook extends rcube_plugin
return $args;
}
- // Load configuration
- $this->load_config();
-
// Check that configuration is not disabled
- $dont_override = (array) $this->rc->config->get('dont_override', array());
+ $dont_override = (array) $this->rc->config->get('dont_override', array());
+ $key = 'kolab_addressbook_prio';
- if (!in_array('kolab_addressbook_prio', $dont_override)) {
- $key = 'kolab_addressbook_prio';
+ if (!in_array('kolab_addressbook_prio', $dont_override) || !isset($_POST['_'.$key])) {
$args['prefs'][$key] = (int) get_input_value('_'.$key, RCUBE_INPUT_POST);
}
@@ -506,4 +507,30 @@ class kolab_addressbook extends rcube_plugin
$this->rc->output->send();
}
+
+ /**
+ * Returns value of kolab_addressbook_prio setting
+ */
+ private function addressbook_prio()
+ {
+ // Load configuration
+ if (!$this->config_loaded) {
+ $this->load_config();
+ $this->config_loaded = true;
+ }
+
+ $abook_prio = (int) $this->rc->config->get('kolab_addressbook_prio');
+
+ // Make sure any global addressbooks are defined
+ if ($abook_prio == 0 || $abook_prio == 2) {
+ $ldap_public = $this->rc->config->get('ldap_public');
+ $abook_type = $this->rc->config->get('address_book_type');
+
+ if (empty($ldap_public) || $abook_type != 'ldap') {
+ $abook_prio = 1;
+ }
+ }
+
+ return $abook_prio;
+ }
}
diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php
index 777702d..ee6ede0 100644
--- a/plugins/libkolab/lib/kolab_storage.php
+++ b/plugins/libkolab/lib/kolab_storage.php
@@ -41,6 +41,23 @@ class kolab_storage
private static $config;
private static $imap;
+ // Default folder names
+ private static $default_folders = array(
+ 'event' => 'Calendar',
+ 'contact' => 'Contacts',
+ 'task' => 'Tasks',
+ 'note' => 'Notes',
+ 'file' => 'Files',
+ 'configuration' => 'Configuration',
+ 'journal' => 'Journal',
+ 'mail.inbox' => 'INBOX',
+ 'mail.drafts' => 'Drafts',
+ 'mail.sentitems' => 'Sent',
+ 'mail.wastebasket' => 'Trash',
+ 'mail.outbox' => 'Outbox',
+ 'mail.junkemail' => 'Junk',
+ );
+
/**
* Setup the environment needed by the libs
@@ -349,25 +366,8 @@ class kolab_storage
$result = self::folder_create($folder, $prop['type'], $prop['subscribed'], $prop['active']);
}
- // save displayname and color in METADATA
- // TODO: also save 'showalarams' and other properties here
if ($result) {
- $ns = null;
- foreach (array('color' => array(self::COLOR_KEY_SHARED,self::COLOR_KEY_PRIVATE),
- 'displayname' => array(self::NAME_KEY_SHARED,self::NAME_KEY_PRIVATE)) as $key => $metakeys) {
- if (!empty($prop[$key])) {
- if (!isset($ns))
- $ns = self::$imap->folder_namespace($folder);
-
- $meta_saved = false;
- if ($ns == 'personal') // save in shared namespace for personal folders
- $meta_saved = self::$imap->set_metadata($folder, array($metakeys[0] => $prop[$key]));
- if (!$meta_saved) // try in private namespace
- $meta_saved = self::$imap->set_metadata($folder, array($metakeys[1] => $prop[$key]));
- if ($meta_saved)
- unset($prop[$key]); // unsetting will prevent fallback to local user prefs
- }
- }
+ self::set_folder_props($folder, $prop);
}
return $result ? $folder : false;
@@ -913,4 +913,107 @@ class kolab_storage
$rcube = rcube::get_instance();
return $rcube->user->save_prefs(array('kolab_active_folders' => $folders));
}
+
+ /**
+ * Creates default folder of specified type
+ * To be run when none of subscribed folders (of specified type) is found
+ *
+ * @param string $type Folder type
+ * @param string $props Folder properties (color, etc)
+ *
+ * @return string Folder name
+ */
+ public static function create_default_folder($type, $props = array())
+ {
+ if (!self::setup()) {
+ return;
+ }
+
+ $folders = self::$imap->get_metadata('*', array(kolab_storage::CTYPE_KEY_PRIVATE));
+
+ // from kolab_folders config
+ $folder_type = strpos($type, '.') ? str_replace('.', '_', $type) : $type . '_default';
+ $default_name = self::$config->get('kolab_folders_' . $folder_type);
+ $folder_type = str_replace('_', '.', $folder_type);
+
+ // check if we have any folder in personal namespace
+ // folder(s) may exist but not subscribed
+ foreach ($folders as $f => $data) {
+ if (strpos($data[self::CTYPE_KEY_PRIVATE], $type) === 0) {
+ $folder = $f;
+ break;
+ }
+ }
+
+ if (!$folder) {
+ if (!$default_name) {
+ $default_name = self::$default_folders[$type];
+ }
+
+ if (!$default_name) {
+ return;
+ }
+
+ $folder = rcube_charset::convert($default_name, RCUBE_CHARSET, 'UTF7-IMAP');
+ $prefix = self::$imap->get_namespace('prefix');
+
+ // add personal namespace prefix if needed
+ if ($prefix && strpos($folder, $prefix) !== 0 && $folder != 'INBOX') {
+ $folder = $prefix . $folder;
+ }
+
+ if (!self::$imap->folder_exists($folder)) {
+ if (!self::$imap->folder_create($folder)) {
+ return;
+ }
+ }
+
+ self::set_folder_type($folder, $folder_type);
+ }
+
+ self::folder_subscribe($folder);
+
+ if ($props['active']) {
+ self::set_state($folder, true);
+ }
+
+ if (!empty($props)) {
+ self::set_folder_props($folder, $props);
+ }
+
+ return $folder;
+ }
+
+ /**
+ * Sets folder metadata properties
+ *
+ * @param string $folder Folder name
+ * @param array $prop Folder properties
+ */
+ public static function set_folder_props($folder, &$prop)
+ {
+ if (!self::setup()) {
+ return;
+ }
+
+ // TODO: also save 'showalarams' and other properties here
+ $ns = self::$imap->folder_namespace($folder);
+ $supported = array(
+ 'color' => array(self::COLOR_KEY_SHARED, self::COLOR_KEY_PRIVATE),
+ 'displayname' => array(self::NAME_KEY_SHARED, self::NAME_KEY_PRIVATE),
+ );
+
+ foreach ($supported as $key => $metakeys) {
+ if (array_key_exists($key, $prop)) {
+ $meta_saved = false;
+ if ($ns == 'personal') // save in shared namespace for personal folders
+ $meta_saved = self::$imap->set_metadata($folder, array($metakeys[0] => $prop[$key]));
+ if (!$meta_saved) // try in private namespace
+ $meta_saved = self::$imap->set_metadata($folder, array($metakeys[1] => $prop[$key]));
+ if ($meta_saved)
+ unset($prop[$key]); // unsetting will prevent fallback to local user prefs
+ }
+ }
+ }
+
}
More information about the commits
mailing list