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).
This commit is contained in:
parent
cb22497440
commit
27eb706939
2 changed files with 178 additions and 48 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue