2011-05-21 12:25:39 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
2011-11-18 15:55:08 +01:00
|
|
|
* Kolab address book
|
2011-06-08 11:33:18 +02:00
|
|
|
*
|
2011-05-21 12:25:39 +02:00
|
|
|
* Sample plugin to add a new address book source with data from Kolab storage
|
2011-06-27 13:44:27 +02:00
|
|
|
* It provides also a possibilities to manage contact folders
|
|
|
|
* (create/rename/delete/acl) directly in Addressbook UI.
|
2011-05-21 12:25:39 +02:00
|
|
|
*
|
2011-11-18 15:55:08 +01:00
|
|
|
* @version @package_version@
|
2011-12-07 12:51:23 +01:00
|
|
|
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
2011-06-08 11:33:18 +02:00
|
|
|
* @author Aleksander Machniak <machniak@kolabsys.com>
|
|
|
|
*
|
2011-10-27 10:20:46 +02:00
|
|
|
* Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
|
2011-06-08 11:33:18 +02:00
|
|
|
*
|
2011-10-27 10:20:46 +02:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
2011-06-08 11:33:18 +02:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2011-10-27 10:20:46 +02:00
|
|
|
* GNU Affero General Public License for more details.
|
2011-06-08 11:33:18 +02:00
|
|
|
*
|
2011-10-27 10:20:46 +02:00
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2011-05-21 12:25:39 +02:00
|
|
|
*/
|
2011-10-27 10:20:46 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
class kolab_addressbook extends rcube_plugin
|
|
|
|
{
|
2014-03-27 19:22:48 +01:00
|
|
|
public $task = '?(?!login|logout).*';
|
2011-06-27 13:44:27 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
private $sources;
|
2014-06-24 15:07:48 +02:00
|
|
|
private $folders;
|
2011-06-08 11:33:18 +02:00
|
|
|
private $rc;
|
2011-06-27 13:44:27 +02:00
|
|
|
private $ui;
|
2011-06-08 11:33:18 +02:00
|
|
|
|
2014-11-26 06:38:31 -05:00
|
|
|
const GLOBAL_FIRST = 0;
|
2011-06-08 11:33:18 +02:00
|
|
|
const PERSONAL_FIRST = 1;
|
2014-11-26 06:38:31 -05:00
|
|
|
const GLOBAL_ONLY = 2;
|
|
|
|
const PERSONAL_ONLY = 3;
|
2011-05-21 12:25:39 +02:00
|
|
|
|
|
|
|
/**
|
2011-06-08 11:33:18 +02:00
|
|
|
* Startup method of a Roundcube plugin
|
2011-05-21 12:25:39 +02:00
|
|
|
*/
|
|
|
|
public function init()
|
|
|
|
{
|
2011-06-27 13:44:27 +02:00
|
|
|
require_once(dirname(__FILE__) . '/lib/rcube_kolab_contacts.php');
|
|
|
|
|
2012-10-17 11:54:25 +02:00
|
|
|
$this->rc = rcube::get_instance();
|
2011-06-08 11:33:18 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
// load required plugin
|
2012-03-07 11:02:51 +01:00
|
|
|
$this->require_plugin('libkolab');
|
2011-06-02 09:45:04 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
// register hooks
|
|
|
|
$this->add_hook('addressbooks_list', array($this, 'address_sources'));
|
|
|
|
$this->add_hook('addressbook_get', array($this, 'get_address_book'));
|
2011-07-25 12:49:46 +02:00
|
|
|
$this->add_hook('config_get', array($this, 'config_get'));
|
2011-06-02 10:33:29 +02:00
|
|
|
|
2011-06-08 11:33:18 +02:00
|
|
|
if ($this->rc->task == 'addressbook') {
|
2011-06-02 10:33:29 +02:00
|
|
|
$this->add_texts('localization');
|
2011-06-08 11:33:18 +02:00
|
|
|
$this->add_hook('contact_form', array($this, 'contact_form'));
|
2014-06-24 15:07:48 +02:00
|
|
|
$this->add_hook('template_object_directorylist', array($this, 'directorylist_html'));
|
2011-06-27 13:44:27 +02:00
|
|
|
|
|
|
|
// Plugin actions
|
|
|
|
$this->register_action('plugin.book', array($this, 'book_actions'));
|
|
|
|
$this->register_action('plugin.book-save', array($this, 'book_save'));
|
2014-06-25 17:09:04 +02:00
|
|
|
$this->register_action('plugin.book-search', array($this, 'book_search'));
|
|
|
|
$this->register_action('plugin.book-subscribe', array($this, 'book_subscribe'));
|
2011-06-27 13:44:27 +02:00
|
|
|
|
|
|
|
// Load UI elements
|
|
|
|
if ($this->api->output->type == 'html') {
|
2014-01-21 16:34:31 +01:00
|
|
|
$this->load_config();
|
2011-06-27 13:44:27 +02:00
|
|
|
require_once($this->home . '/lib/kolab_addressbook_ui.php');
|
|
|
|
$this->ui = new kolab_addressbook_ui($this);
|
|
|
|
}
|
2011-06-08 11:33:18 +02:00
|
|
|
}
|
|
|
|
else if ($this->rc->task == 'settings') {
|
|
|
|
$this->add_texts('localization');
|
|
|
|
$this->add_hook('preferences_list', array($this, 'prefs_list'));
|
|
|
|
$this->add_hook('preferences_save', array($this, 'prefs_save'));
|
2011-06-02 10:33:29 +02:00
|
|
|
}
|
2014-08-14 12:41:08 +02:00
|
|
|
|
|
|
|
$this->add_hook('folder_delete', array($this, 'prefs_folder_delete'));
|
|
|
|
$this->add_hook('folder_rename', array($this, 'prefs_folder_rename'));
|
|
|
|
$this->add_hook('folder_update', array($this, 'prefs_folder_update'));
|
2011-05-21 12:25:39 +02:00
|
|
|
}
|
|
|
|
|
2011-06-08 11:33:18 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
/**
|
|
|
|
* Handler for the addressbooks_list hook.
|
|
|
|
*
|
|
|
|
* This will add all instances of available Kolab-based address books
|
|
|
|
* to the list of address sources of Roundcube.
|
2011-06-08 11:33:18 +02:00
|
|
|
* This will also hide some addressbooks according to kolab_addressbook_prio setting.
|
|
|
|
*
|
|
|
|
* @param array $p Hash array with hook parameters
|
2011-05-21 12:25:39 +02:00
|
|
|
*
|
|
|
|
* @return array Hash array with modified hook parameters
|
|
|
|
*/
|
|
|
|
public function address_sources($p)
|
|
|
|
{
|
2013-08-07 09:39:21 +02:00
|
|
|
$abook_prio = $this->addressbook_prio();
|
2011-06-08 11:33:18 +02:00
|
|
|
|
|
|
|
// Disable all global address books
|
|
|
|
// Assumes that all non-kolab_addressbook sources are global
|
|
|
|
if ($abook_prio == self::PERSONAL_ONLY) {
|
|
|
|
$p['sources'] = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
$sources = array();
|
2011-05-21 12:25:39 +02:00
|
|
|
foreach ($this->_list_sources() as $abook_id => $abook) {
|
|
|
|
// register this address source
|
2014-06-24 15:07:48 +02:00
|
|
|
$sources[$abook_id] = $this->abook_prop($abook_id, $abook);
|
2011-05-21 12:25:39 +02:00
|
|
|
}
|
|
|
|
|
2011-06-08 11:33:18 +02:00
|
|
|
// Add personal address sources to the list
|
|
|
|
if ($abook_prio == self::PERSONAL_FIRST) {
|
2011-07-27 19:13:38 +02:00
|
|
|
// $p['sources'] = array_merge($sources, $p['sources']);
|
|
|
|
// Don't use array_merge(), because if you have folders name
|
|
|
|
// that resolve to numeric identifier it will break output array keys
|
|
|
|
foreach ($p['sources'] as $idx => $value)
|
|
|
|
$sources[$idx] = $value;
|
|
|
|
$p['sources'] = $sources;
|
2011-06-08 11:33:18 +02:00
|
|
|
}
|
|
|
|
else {
|
2011-07-27 19:13:38 +02:00
|
|
|
// $p['sources'] = array_merge($p['sources'], $sources);
|
|
|
|
foreach ($sources as $idx => $value)
|
|
|
|
$p['sources'][$idx] = $value;
|
2011-06-08 11:33:18 +02:00
|
|
|
}
|
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
return $p;
|
|
|
|
}
|
|
|
|
|
2014-06-24 15:07:48 +02:00
|
|
|
/**
|
|
|
|
* Helper method to build a hash array of address book properties
|
|
|
|
*/
|
|
|
|
protected function abook_prop($id, $abook)
|
|
|
|
{
|
2014-06-25 17:09:04 +02:00
|
|
|
if ($abook->virtual) {
|
|
|
|
return array(
|
|
|
|
'id' => $id,
|
|
|
|
'name' => $abook->get_name(),
|
|
|
|
'listname' => $abook->get_foldername(),
|
|
|
|
'group' => $abook instanceof kolab_storage_folder_user ? 'user' : $abook->get_namespace(),
|
|
|
|
'readonly' => true,
|
|
|
|
'editable' => false,
|
|
|
|
'kolab' => true,
|
|
|
|
'virtual' => true,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return array(
|
|
|
|
'id' => $id,
|
|
|
|
'name' => $abook->get_name(),
|
|
|
|
'listname' => $abook->get_foldername(),
|
|
|
|
'readonly' => $abook->readonly,
|
|
|
|
'editable' => $abook->editable,
|
|
|
|
'groups' => $abook->groups,
|
|
|
|
'undelete' => $abook->undelete && $this->rc->config->get('undo_timeout'),
|
|
|
|
'realname' => rcube_charset::convert($abook->get_realname(), 'UTF7-IMAP'), // IMAP folder name
|
|
|
|
'group' => $abook->get_namespace(),
|
|
|
|
'subscribed' => $abook->is_subscribed(),
|
|
|
|
'carddavurl' => $abook->get_carddav_url(),
|
2014-09-11 14:45:34 +02:00
|
|
|
'removable' => true,
|
2014-06-25 17:09:04 +02:00
|
|
|
'kolab' => true,
|
|
|
|
);
|
|
|
|
}
|
2014-06-24 15:07:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public function directorylist_html($args)
|
|
|
|
{
|
|
|
|
$out = '';
|
|
|
|
$jsdata = array();
|
|
|
|
$sources = (array)$this->rc->get_address_sources();
|
|
|
|
|
|
|
|
// list all non-kolab sources first
|
|
|
|
foreach (array_filter($sources, function($source){ return empty($source['kolab']); }) as $j => $source) {
|
|
|
|
$id = strval(strlen($source['id']) ? $source['id'] : $j);
|
|
|
|
$out .= $this->addressbook_list_item($id, $source, $jsdata) . '</li>';
|
|
|
|
}
|
|
|
|
|
|
|
|
// render a hierarchical list of kolab contact folders
|
|
|
|
kolab_storage::folder_hierarchy($this->folders, $tree);
|
|
|
|
$out .= $this->folder_tree_html($tree, $sources, $jsdata);
|
|
|
|
|
2014-06-25 17:09:04 +02:00
|
|
|
$this->rc->output->set_env('contactgroups', array_filter($jsdata, function($src){ return $src['type'] == 'group'; }));
|
|
|
|
$this->rc->output->set_env('address_sources', array_filter($jsdata, function($src){ return $src['type'] != 'group'; }));
|
2014-06-24 15:07:48 +02:00
|
|
|
|
|
|
|
$args['content'] = html::tag('ul', $args, $out, html::$common_attrib);
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return html for a structured list <ul> for the folder tree
|
|
|
|
*/
|
|
|
|
public function folder_tree_html($node, $data, &$jsdata)
|
|
|
|
{
|
|
|
|
$out = '';
|
|
|
|
foreach ($node->children as $folder) {
|
|
|
|
$id = $folder->id;
|
|
|
|
$source = $data[$id];
|
|
|
|
$is_collapsed = strpos($this->rc->config->get('collapsed_abooks',''), '&'.rawurlencode($id).'&') !== false;
|
|
|
|
|
|
|
|
if ($folder->virtual) {
|
2014-06-25 17:09:04 +02:00
|
|
|
$source = $this->abook_prop($folder->id, $folder);
|
|
|
|
}
|
|
|
|
else if (empty($source)) {
|
|
|
|
$this->sources[$id] = new rcube_kolab_contacts($folder->name);
|
|
|
|
$source = $this->abook_prop($id, $this->sources[$id]);
|
2014-06-24 15:07:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$content = $this->addressbook_list_item($id, $source, $jsdata);
|
|
|
|
|
|
|
|
if (!empty($folder->children)) {
|
|
|
|
$child_html = $this->folder_tree_html($folder, $data, $jsdata);
|
|
|
|
|
|
|
|
if (!empty($child_html) && preg_match('!</ul>\n*$!', $content)) {
|
|
|
|
$content = preg_replace('!</ul>\n*$!', $child_html . '</ul>', $content);
|
|
|
|
}
|
|
|
|
else if (!empty($child_html)) {
|
|
|
|
$content .= html::tag('ul', array('style' => ($is_collapsed ? "display:none;" : null)), $child_html);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$out .= $content . '</li>';
|
|
|
|
}
|
|
|
|
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2014-06-25 17:09:04 +02:00
|
|
|
protected function addressbook_list_item($id, $source, &$jsdata, $search_mode = false)
|
2014-06-24 15:07:48 +02:00
|
|
|
{
|
|
|
|
$current = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC);
|
|
|
|
|
2014-06-25 17:09:04 +02:00
|
|
|
if (!$source['virtual']) {
|
|
|
|
$jsdata[$id] = $source;
|
2014-11-17 08:54:16 -05:00
|
|
|
$jsdata[$id]['name'] = html_entity_decode($source['name'], ENT_NOQUOTES, RCUBE_CHARSET);
|
2014-06-25 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
2014-06-24 15:07:48 +02:00
|
|
|
// set class name(s)
|
2014-11-14 08:47:38 -05:00
|
|
|
$classes = array('addressbook');
|
|
|
|
if ($source['group'])
|
|
|
|
$classes[] = $source['group'];
|
2014-06-24 15:07:48 +02:00
|
|
|
if ($current === $id)
|
|
|
|
$classes[] = 'selected';
|
|
|
|
if ($source['readonly'])
|
|
|
|
$classes[] = 'readonly';
|
|
|
|
if ($source['virtual'])
|
|
|
|
$classes[] = 'virtual';
|
|
|
|
if ($source['class_name'])
|
|
|
|
$classes[] = $source['class_name'];
|
|
|
|
|
|
|
|
$name = !empty($source['listname']) ? $source['listname'] : (!empty($source['name']) ? $source['name'] : $id);
|
2014-06-25 17:09:04 +02:00
|
|
|
$label_id = 'kabt:' . $id;
|
|
|
|
$inner = ($source['virtual'] ?
|
|
|
|
html::a(array('tabindex' => '0'), $name) :
|
|
|
|
html::a(array(
|
|
|
|
'href' => $this->rc->url(array('_source' => $id)),
|
|
|
|
'rel' => $source['id'],
|
|
|
|
'id' => $label_id,
|
|
|
|
'onclick' => "return " . rcmail_output::JS_OBJECT_NAME.".command('list','" . rcube::JQ($id) . "',this)",
|
|
|
|
), $name)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (isset($source['subscribed'])) {
|
|
|
|
$inner .= html::span(array(
|
|
|
|
'class' => 'subscribed',
|
|
|
|
'title' => $this->gettext('foldersubscribe'),
|
|
|
|
'role' => 'checkbox',
|
|
|
|
'aria-checked' => $source['subscribed'] ? 'true' : 'false',
|
|
|
|
), '');
|
|
|
|
}
|
|
|
|
|
|
|
|
// don't wrap in <li> but add a checkbox for search results listing
|
|
|
|
if ($search_mode) {
|
|
|
|
$jsdata[$id]['group'] = join(' ', $classes);
|
|
|
|
|
|
|
|
if (!$source['virtual']) {
|
|
|
|
$inner .= html::tag('input', array(
|
|
|
|
'type' => 'checkbox',
|
|
|
|
'name' => '_source[]',
|
|
|
|
'value' => $id,
|
|
|
|
'checked' => $prop['active'],
|
|
|
|
'aria-labelledby' => $label_id,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
return html::div(null, $inner);
|
|
|
|
}
|
|
|
|
|
2014-06-24 15:07:48 +02:00
|
|
|
$out .= html::tag('li', array(
|
|
|
|
'id' => 'rcmli' . rcube_utils::html_identifier($id, true),
|
|
|
|
'class' => join(' ', $classes),
|
|
|
|
'noclose' => true,
|
|
|
|
),
|
2014-06-25 17:09:04 +02:00
|
|
|
html::div($source['subscribed'] ? 'subscribed' : null, $inner)
|
2014-06-24 15:07:48 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
$groupdata = array('out' => '', 'jsdata' => $jsdata, 'source' => $id);
|
|
|
|
if ($source['groups'] && function_exists('rcmail_contact_groups')) {
|
|
|
|
$groupdata = rcmail_contact_groups($groupdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
$jsdata = $groupdata['jsdata'];
|
|
|
|
$out .= $groupdata['out'];
|
|
|
|
|
|
|
|
return $out;
|
|
|
|
}
|
2011-05-21 12:25:39 +02:00
|
|
|
|
2011-06-08 11:33:18 +02:00
|
|
|
/**
|
2011-07-25 12:49:46 +02:00
|
|
|
* Sets autocomplete_addressbooks option according to
|
|
|
|
* kolab_addressbook_prio setting extending list of address sources
|
|
|
|
* to be used for autocompletion.
|
2011-06-08 11:33:18 +02:00
|
|
|
*/
|
2011-07-25 12:49:46 +02:00
|
|
|
public function config_get($args)
|
2011-06-08 11:33:18 +02:00
|
|
|
{
|
2011-07-25 12:49:46 +02:00
|
|
|
if ($args['name'] != 'autocomplete_addressbooks') {
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
2013-08-07 09:39:21 +02:00
|
|
|
$abook_prio = $this->addressbook_prio();
|
2011-07-25 12:49:46 +02:00
|
|
|
// here we cannot use rc->config->get()
|
|
|
|
$sources = $GLOBALS['CONFIG']['autocomplete_addressbooks'];
|
2011-06-08 11:33:18 +02:00
|
|
|
|
|
|
|
// Disable all global address books
|
|
|
|
// Assumes that all non-kolab_addressbook sources are global
|
|
|
|
if ($abook_prio == self::PERSONAL_ONLY) {
|
|
|
|
$sources = array();
|
|
|
|
}
|
|
|
|
|
2011-07-25 12:49:46 +02:00
|
|
|
if (!is_array($sources)) {
|
|
|
|
$sources = array();
|
|
|
|
}
|
|
|
|
|
2011-06-08 11:33:18 +02:00
|
|
|
$kolab_sources = array();
|
2013-05-07 12:16:11 +02:00
|
|
|
foreach (array_keys($this->_list_sources()) as $abook_id) {
|
2011-06-08 11:33:18 +02:00
|
|
|
if (!in_array($abook_id, $sources))
|
|
|
|
$kolab_sources[] = $abook_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add personal address sources to the list
|
|
|
|
if (!empty($kolab_sources)) {
|
|
|
|
if ($abook_prio == self::PERSONAL_FIRST) {
|
|
|
|
$sources = array_merge($kolab_sources, $sources);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$sources = array_merge($sources, $kolab_sources);
|
|
|
|
}
|
|
|
|
}
|
2011-07-25 12:49:46 +02:00
|
|
|
|
|
|
|
$args['result'] = $sources;
|
|
|
|
|
|
|
|
return $args;
|
2011-06-08 11:33:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
/**
|
|
|
|
* Getter for the rcube_addressbook instance
|
2011-06-08 11:33:18 +02:00
|
|
|
*
|
|
|
|
* @param array $p Hash array with hook parameters
|
|
|
|
*
|
|
|
|
* @return array Hash array with modified hook parameters
|
2011-05-21 12:25:39 +02:00
|
|
|
*/
|
|
|
|
public function get_address_book($p)
|
|
|
|
{
|
2011-08-04 11:56:13 +02:00
|
|
|
if ($p['id']) {
|
2014-11-26 06:25:14 -05:00
|
|
|
$id = kolab_storage::id_decode($p['id']);
|
|
|
|
|
|
|
|
// check for falsely base64 decoded identifier
|
|
|
|
if (preg_match('![^A-Za-z0-9=/+&._ -]!', $id)) {
|
|
|
|
$id = $p['id'];
|
2011-08-04 11:56:13 +02:00
|
|
|
}
|
2014-11-26 06:25:14 -05:00
|
|
|
|
|
|
|
$folder = kolab_storage::get_folder($id);
|
|
|
|
|
|
|
|
// try with unencoded (old-style) identifier
|
2014-11-26 06:38:31 -05:00
|
|
|
if ((!$folder || $folder->type != 'contact') && $id != $p['id']) {
|
2014-11-26 06:25:14 -05:00
|
|
|
$folder = kolab_storage::get_folder($p['id']);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($folder && $folder->type == 'contact') {
|
|
|
|
$p['instance'] = new rcube_kolab_contacts($folder->name);
|
2014-06-24 15:07:48 +02:00
|
|
|
}
|
2011-05-21 12:25:39 +02:00
|
|
|
}
|
2011-06-02 09:45:04 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
return $p;
|
|
|
|
}
|
2011-06-02 09:45:04 +02:00
|
|
|
|
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
private function _list_sources()
|
|
|
|
{
|
|
|
|
// already read sources
|
|
|
|
if (isset($this->sources))
|
|
|
|
return $this->sources;
|
|
|
|
|
2014-06-24 15:07:48 +02:00
|
|
|
kolab_storage::$encode_ids = true;
|
2011-06-08 11:33:18 +02:00
|
|
|
$this->sources = array();
|
2014-06-24 15:07:48 +02:00
|
|
|
$this->folders = array();
|
2011-07-08 17:39:03 +02:00
|
|
|
|
2013-08-07 09:39:21 +02:00
|
|
|
$abook_prio = $this->addressbook_prio();
|
2011-06-08 11:33:18 +02:00
|
|
|
|
|
|
|
// Personal address source(s) disabled?
|
|
|
|
if ($abook_prio == self::GLOBAL_ONLY) {
|
|
|
|
return $this->sources;
|
|
|
|
}
|
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
// get all folders that have "contact" type
|
2013-08-07 09:39:21 +02:00
|
|
|
$folders = kolab_storage::sort_folders(kolab_storage::get_folders('contact'));
|
2011-07-08 17:39:03 +02:00
|
|
|
|
2013-08-07 09:39:21 +02:00
|
|
|
if (PEAR::isError($folders)) {
|
2012-11-06 11:46:15 +01:00
|
|
|
rcube::raise_error(array(
|
2011-05-21 12:25:39 +02:00
|
|
|
'code' => 600, 'type' => 'php',
|
|
|
|
'file' => __FILE__, 'line' => __LINE__,
|
2013-08-07 09:39:21 +02:00
|
|
|
'message' => "Failed to list contact folders from Kolab server:" . $folders->getMessage()),
|
2011-05-21 12:25:39 +02:00
|
|
|
true, false);
|
|
|
|
}
|
|
|
|
else {
|
2013-08-07 09:39:21 +02:00
|
|
|
// 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'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-27 13:44:27 +02:00
|
|
|
// convert to UTF8 and sort
|
2013-08-07 09:39:21 +02:00
|
|
|
foreach ($folders as $folder) {
|
2011-05-21 12:25:39 +02:00
|
|
|
// create instance of rcube_contacts
|
2014-06-24 15:07:48 +02:00
|
|
|
$abook_id = $folder->id;
|
2013-07-18 17:47:49 +02:00
|
|
|
$abook = new rcube_kolab_contacts($folder->name);
|
2011-05-21 12:25:39 +02:00
|
|
|
$this->sources[$abook_id] = $abook;
|
2014-06-24 15:07:48 +02:00
|
|
|
$this->folders[$abook_id] = $folder;
|
2011-05-21 12:25:39 +02:00
|
|
|
}
|
|
|
|
}
|
2011-07-08 17:39:03 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
return $this->sources;
|
|
|
|
}
|
2011-06-02 09:45:04 +02:00
|
|
|
|
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
/**
|
|
|
|
* Plugin hook called before rendering the contact form or detail view
|
2011-06-08 11:33:18 +02:00
|
|
|
*
|
|
|
|
* @param array $p Hash array with hook parameters
|
|
|
|
*
|
|
|
|
* @return array Hash array with modified hook parameters
|
2011-05-21 12:25:39 +02:00
|
|
|
*/
|
|
|
|
public function contact_form($p)
|
|
|
|
{
|
|
|
|
// none of our business
|
2011-09-10 13:40:56 +02:00
|
|
|
if (!is_object($GLOBALS['CONTACTS']) || !is_a($GLOBALS['CONTACTS'], 'rcube_kolab_contacts'))
|
2011-05-21 12:25:39 +02:00
|
|
|
return $p;
|
2011-06-02 09:45:04 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
// extend the list of contact fields to be displayed in the 'personal' section
|
|
|
|
if (is_array($p['form']['personal'])) {
|
2011-06-02 10:33:29 +02:00
|
|
|
$p['form']['personal']['content']['profession'] = array('size' => 40);
|
|
|
|
$p['form']['personal']['content']['children'] = array('size' => 40);
|
|
|
|
$p['form']['personal']['content']['freebusyurl'] = array('size' => 40);
|
2012-04-25 14:12:09 +02:00
|
|
|
$p['form']['personal']['content']['pgppublickey'] = array('size' => 70);
|
|
|
|
$p['form']['personal']['content']['pkcs7publickey'] = array('size' => 70);
|
2011-06-02 09:45:04 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
// re-order fields according to the coltypes list
|
2014-11-28 07:10:16 -05:00
|
|
|
$p['form']['contact']['content'] = $this->_sort_form_fields($p['form']['contact']['content'], $GLOBALS['CONTACTS']);
|
|
|
|
$p['form']['personal']['content'] = $this->_sort_form_fields($p['form']['personal']['content'], $GLOBALS['CONTACTS']);
|
2011-06-02 09:45:04 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
/* define a separate section 'settings'
|
|
|
|
$p['form']['settings'] = array(
|
2011-06-02 10:33:29 +02:00
|
|
|
'name' => $this->gettext('settings'),
|
2011-05-21 12:25:39 +02:00
|
|
|
'content' => array(
|
|
|
|
'freebusyurl' => array('size' => 40, 'visible' => true),
|
2012-04-25 14:12:09 +02:00
|
|
|
'pgppublickey' => array('size' => 70, 'visible' => true),
|
|
|
|
'pkcs7publickey' => array('size' => 70, 'visible' => false),
|
2011-05-21 12:25:39 +02:00
|
|
|
)
|
|
|
|
);
|
|
|
|
*/
|
|
|
|
}
|
2011-06-02 09:45:04 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
return $p;
|
|
|
|
}
|
2011-06-02 09:45:04 +02:00
|
|
|
|
|
|
|
|
2014-11-28 07:10:16 -05:00
|
|
|
private function _sort_form_fields($contents, $source)
|
2011-05-21 12:25:39 +02:00
|
|
|
{
|
2014-11-28 07:10:16 -05:00
|
|
|
$block = array();
|
2013-05-07 12:16:11 +02:00
|
|
|
|
2014-11-28 07:10:16 -05:00
|
|
|
foreach (array_keys($source->coltypes) as $col) {
|
2011-05-21 12:25:39 +02:00
|
|
|
if (isset($contents[$col]))
|
|
|
|
$block[$col] = $contents[$col];
|
|
|
|
}
|
2011-06-02 09:45:04 +02:00
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
return $block;
|
|
|
|
}
|
|
|
|
|
2011-06-08 11:33:18 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for user preferences form (preferences_list hook)
|
|
|
|
*
|
|
|
|
* @param array $args Hash array with hook parameters
|
|
|
|
*
|
|
|
|
* @return array Hash array with modified hook parameters
|
|
|
|
*/
|
|
|
|
public function prefs_list($args)
|
|
|
|
{
|
|
|
|
if ($args['section'] != 'addressbook') {
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
2013-08-07 09:39:21 +02:00
|
|
|
$ldap_public = $this->rc->config->get('ldap_public');
|
|
|
|
$abook_type = $this->rc->config->get('address_book_type');
|
2011-06-08 11:33:18 +02:00
|
|
|
|
2013-08-07 09:39:21 +02:00
|
|
|
// Hide option if there's no global addressbook
|
|
|
|
if (empty($ldap_public) || $abook_type != 'ldap') {
|
|
|
|
return $args;
|
|
|
|
}
|
2011-06-08 11:33:18 +02:00
|
|
|
|
|
|
|
// Check that configuration is not disabled
|
2013-08-07 09:39:21 +02:00
|
|
|
$dont_override = (array) $this->rc->config->get('dont_override', array());
|
|
|
|
$prio = $this->addressbook_prio();
|
2011-06-08 11:33:18 +02:00
|
|
|
|
|
|
|
if (!in_array('kolab_addressbook_prio', $dont_override)) {
|
2013-08-07 09:39:21 +02:00
|
|
|
// Load localization
|
|
|
|
$this->add_texts('localization');
|
|
|
|
|
2011-06-08 11:33:18 +02:00
|
|
|
$field_id = '_kolab_addressbook_prio';
|
|
|
|
$select = new html_select(array('name' => $field_id, 'id' => $field_id));
|
|
|
|
|
|
|
|
$select->add($this->gettext('globalfirst'), self::GLOBAL_FIRST);
|
|
|
|
$select->add($this->gettext('personalfirst'), self::PERSONAL_FIRST);
|
|
|
|
$select->add($this->gettext('globalonly'), self::GLOBAL_ONLY);
|
|
|
|
$select->add($this->gettext('personalonly'), self::PERSONAL_ONLY);
|
|
|
|
|
|
|
|
$args['blocks']['main']['options']['kolab_addressbook_prio'] = array(
|
|
|
|
'title' => html::label($field_id, Q($this->gettext('addressbookprio'))),
|
2013-08-07 09:39:21 +02:00
|
|
|
'content' => $select->show($prio),
|
2011-06-08 11:33:18 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for user preferences save (preferences_save hook)
|
|
|
|
*
|
|
|
|
* @param array $args Hash array with hook parameters
|
|
|
|
*
|
|
|
|
* @return array Hash array with modified hook parameters
|
|
|
|
*/
|
|
|
|
public function prefs_save($args)
|
|
|
|
{
|
|
|
|
if ($args['section'] != 'addressbook') {
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that configuration is not disabled
|
2013-08-07 09:39:21 +02:00
|
|
|
$dont_override = (array) $this->rc->config->get('dont_override', array());
|
|
|
|
$key = 'kolab_addressbook_prio';
|
2011-06-08 11:33:18 +02:00
|
|
|
|
2013-08-07 09:39:21 +02:00
|
|
|
if (!in_array('kolab_addressbook_prio', $dont_override) || !isset($_POST['_'.$key])) {
|
2014-10-06 09:19:26 +02:00
|
|
|
$args['prefs'][$key] = (int) rcube_utils::get_input_value('_'.$key, rcube_utils::INPUT_POST);
|
2011-06-08 11:33:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
2011-06-27 13:44:27 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for plugin actions
|
|
|
|
*/
|
|
|
|
public function book_actions()
|
|
|
|
{
|
2014-10-06 09:19:26 +02:00
|
|
|
$action = trim(rcube_utils::get_input_value('_act', rcube_utils::INPUT_GPC));
|
2011-06-27 13:44:27 +02:00
|
|
|
|
|
|
|
if ($action == 'create') {
|
|
|
|
$this->ui->book_edit();
|
|
|
|
}
|
|
|
|
else if ($action == 'edit') {
|
|
|
|
$this->ui->book_edit();
|
|
|
|
}
|
|
|
|
else if ($action == 'delete') {
|
|
|
|
$this->book_delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for address book create/edit form submit
|
|
|
|
*/
|
|
|
|
public function book_save()
|
|
|
|
{
|
2012-06-21 21:34:08 +02:00
|
|
|
$prop = array(
|
2014-10-06 09:19:26 +02:00
|
|
|
'name' => trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST)),
|
|
|
|
'oldname' => trim(rcube_utils::get_input_value('_oldname', rcube_utils::INPUT_POST, true)), // UTF7-IMAP
|
|
|
|
'parent' => trim(rcube_utils::get_input_value('_parent', rcube_utils::INPUT_POST, true)), // UTF7-IMAP
|
2013-05-27 19:05:04 +02:00
|
|
|
'type' => 'contact',
|
|
|
|
'subscribed' => true,
|
2012-06-21 21:34:08 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
$result = $error = false;
|
|
|
|
$type = strlen($prop['oldname']) ? 'update' : 'create';
|
|
|
|
$prop = $this->rc->plugins->exec_hook('addressbook_'.$type, $prop);
|
|
|
|
|
|
|
|
if (!$prop['abort']) {
|
|
|
|
if ($newfolder = kolab_storage::folder_update($prop)) {
|
|
|
|
$folder = $newfolder;
|
|
|
|
$result = true;
|
2011-06-27 13:44:27 +02:00
|
|
|
}
|
|
|
|
else {
|
2012-06-21 21:34:08 +02:00
|
|
|
$error = kolab_storage::$last_error;
|
2011-08-10 19:23:00 +02:00
|
|
|
}
|
|
|
|
}
|
2012-06-21 21:34:08 +02:00
|
|
|
else {
|
|
|
|
$result = $prop['result'];
|
|
|
|
$folder = $prop['name'];
|
2011-06-27 13:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($result) {
|
2014-06-24 15:07:48 +02:00
|
|
|
$kolab_folder = kolab_storage::get_folder($folder);
|
2011-06-27 13:44:27 +02:00
|
|
|
|
2014-09-03 12:23:48 +02:00
|
|
|
// get folder/addressbook properties
|
|
|
|
$abook = new rcube_kolab_contacts($folder);
|
|
|
|
$props = $this->abook_prop(kolab_storage::folder_id($folder, true), $abook);
|
|
|
|
$props['parent'] = kolab_storage::folder_id($kolab_folder->get_parent(), true);
|
|
|
|
|
2011-06-27 13:44:27 +02:00
|
|
|
$this->rc->output->show_message('kolab_addressbook.book'.$type.'d', 'confirmation');
|
2014-09-03 12:23:48 +02:00
|
|
|
$this->rc->output->command('book_update', $props, kolab_storage::folder_id($prop['oldname'], true));
|
2011-06-27 13:44:27 +02:00
|
|
|
$this->rc->output->send('iframe');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$error)
|
|
|
|
$error = $plugin['message'] ? $plugin['message'] : 'kolab_addressbook.book'.$type.'error';
|
|
|
|
|
|
|
|
$this->rc->output->show_message($error, 'error');
|
|
|
|
// display the form again
|
|
|
|
$this->ui->book_edit();
|
|
|
|
}
|
|
|
|
|
2014-06-25 17:09:04 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public function book_search()
|
|
|
|
{
|
|
|
|
$results = array();
|
2014-10-06 09:19:26 +02:00
|
|
|
$query = rcube_utils::get_input_value('q', rcube_utils::INPUT_GPC);
|
|
|
|
$source = rcube_utils::get_input_value('source', rcube_utils::INPUT_GPC);
|
2014-06-25 17:09:04 +02:00
|
|
|
|
|
|
|
kolab_storage::$encode_ids = true;
|
|
|
|
$search_more_results = false;
|
|
|
|
$this->sources = array();
|
|
|
|
$this->folders = array();
|
2014-10-06 09:19:26 +02:00
|
|
|
|
2014-06-25 17:09:04 +02:00
|
|
|
// find unsubscribed IMAP folders that have "event" type
|
|
|
|
if ($source == 'folders') {
|
|
|
|
foreach ((array)kolab_storage::search_folders('contact', $query, array('other')) as $folder) {
|
|
|
|
$this->folders[$folder->id] = $folder;
|
|
|
|
$this->sources[$folder->id] = new rcube_kolab_contacts($folder->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// search other user's namespace via LDAP
|
|
|
|
else if ($source == 'users') {
|
|
|
|
$limit = $this->rc->config->get('autocomplete_max', 15) * 2; // we have slightly more space, so display twice the number
|
|
|
|
foreach (kolab_storage::search_users($query, 0, array(), $limit * 10) as $user) {
|
|
|
|
$folders = array();
|
|
|
|
// search for contact folders shared by this user
|
|
|
|
foreach (kolab_storage::list_user_folders($user, 'contact', false) as $foldername) {
|
|
|
|
$folders[] = new kolab_storage_folder($foldername, 'contact');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count($folders)) {
|
|
|
|
$userfolder = new kolab_storage_folder_user($user['kolabtargetfolder'], '', $user);
|
|
|
|
$this->folders[$userfolder->id] = $userfolder;
|
|
|
|
$this->sources[$userfolder->id] = $userfolder;
|
|
|
|
|
|
|
|
foreach ($folders as $folder) {
|
|
|
|
$this->folders[$folder->id] = $folder;
|
|
|
|
$this->sources[$folder->id] = new rcube_kolab_contacts($folder->name);;
|
|
|
|
$count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($count >= $limit) {
|
|
|
|
$search_more_results = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$delim = $this->rc->get_storage()->get_hierarchy_delimiter();
|
|
|
|
|
|
|
|
// build results list
|
|
|
|
foreach ($this->sources as $id => $source) {
|
|
|
|
$folder = $this->folders[$id];
|
|
|
|
$imap_path = explode($delim, $folder->name);
|
|
|
|
|
|
|
|
// find parent
|
|
|
|
do {
|
|
|
|
array_pop($imap_path);
|
|
|
|
$parent_id = kolab_storage::folder_id(join($delim, $imap_path));
|
|
|
|
}
|
|
|
|
while (count($imap_path) > 1 && !$this->folders[$parent_id]);
|
|
|
|
|
|
|
|
// restore "real" parent ID
|
|
|
|
if ($parent_id && !$this->folders[$parent_id]) {
|
|
|
|
$parent_id = kolab_storage::folder_id($folder->get_parent());
|
|
|
|
}
|
|
|
|
|
|
|
|
$prop = $this->abook_prop($id, $source);
|
|
|
|
$prop['parent'] = $parent_id;
|
|
|
|
|
|
|
|
$html = $this->addressbook_list_item($id, $prop, $jsdata, true);
|
2014-06-27 10:43:46 +02:00
|
|
|
unset($prop['group']);
|
2014-06-25 17:09:04 +02:00
|
|
|
$prop += (array)$jsdata[$id];
|
|
|
|
$prop['html'] = $html;
|
|
|
|
|
|
|
|
$results[] = $prop;
|
|
|
|
}
|
|
|
|
|
|
|
|
// report more results available
|
|
|
|
if ($search_more_results) {
|
|
|
|
$this->rc->output->show_message('autocompletemore', 'info');
|
|
|
|
}
|
|
|
|
|
2014-10-06 09:19:26 +02:00
|
|
|
$this->rc->output->command('multi_thread_http_response', $results, rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC));
|
2014-06-25 17:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public function book_subscribe()
|
|
|
|
{
|
|
|
|
$success = false;
|
2014-10-06 09:19:26 +02:00
|
|
|
$id = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC);
|
2014-06-25 17:09:04 +02:00
|
|
|
|
|
|
|
if ($id && ($folder = kolab_storage::get_folder(kolab_storage::id_decode($id)))) {
|
|
|
|
if (isset($_POST['_permanent']))
|
|
|
|
$success |= $folder->subscribe(intval($_POST['_permanent']));
|
|
|
|
if (isset($_POST['_active']))
|
|
|
|
$success |= $folder->activate(intval($_POST['_active']));
|
2014-06-27 11:15:17 +02:00
|
|
|
|
|
|
|
// list groups for this address book
|
|
|
|
if (!empty($_POST['_groups'])) {
|
|
|
|
$abook = new rcube_kolab_contacts($folder->name);
|
|
|
|
foreach ((array)$abook->list_groups() as $prop) {
|
|
|
|
$prop['source'] = $id;
|
|
|
|
$prop['id'] = $prop['ID'];
|
|
|
|
unset($prop['ID']);
|
|
|
|
$this->rc->output->command('insert_contact_group', $prop);
|
|
|
|
}
|
|
|
|
}
|
2014-06-25 17:09:04 +02:00
|
|
|
}
|
2014-09-03 10:36:53 +02:00
|
|
|
|
2014-06-25 17:09:04 +02:00
|
|
|
if ($success) {
|
|
|
|
$this->rc->output->show_message('successfullysaved', 'confirmation');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$this->rc->output->show_message($this->gettext('errorsaving'), 'error');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->rc->output->send();
|
|
|
|
}
|
|
|
|
|
2011-06-27 13:44:27 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for address book delete action (AJAX)
|
|
|
|
*/
|
|
|
|
private function book_delete()
|
|
|
|
{
|
2014-10-06 09:19:26 +02:00
|
|
|
$folder = trim(rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC, true, 'UTF7-IMAP'));
|
2011-06-27 13:44:27 +02:00
|
|
|
|
2012-03-07 11:02:51 +01:00
|
|
|
if (kolab_storage::folder_delete($folder)) {
|
2013-06-07 10:39:35 +02:00
|
|
|
$storage = $this->rc->get_storage();
|
|
|
|
$delimiter = $storage->get_hierarchy_delimiter();
|
|
|
|
|
2011-06-27 13:44:27 +02:00
|
|
|
$this->rc->output->show_message('kolab_addressbook.bookdeleted', 'confirmation');
|
|
|
|
$this->rc->output->set_env('pagecount', 0);
|
|
|
|
$this->rc->output->command('set_rowcount', rcmail_get_rowcount_text(new rcube_result_set()));
|
2013-06-07 10:39:35 +02:00
|
|
|
$this->rc->output->command('set_env', 'delimiter', $delimiter);
|
2011-06-27 13:44:27 +02:00
|
|
|
$this->rc->output->command('list_contacts_clear');
|
2014-09-03 10:36:53 +02:00
|
|
|
$this->rc->output->command('book_delete_done', kolab_storage::folder_id($folder, true));
|
2011-06-27 13:44:27 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
$this->rc->output->show_message('kolab_addressbook.bookdeleteerror', 'error');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->rc->output->send();
|
|
|
|
}
|
2013-08-07 09:39:21 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
2014-08-14 12:41:08 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook for (contact) folder deletion
|
|
|
|
*/
|
|
|
|
function prefs_folder_delete($args)
|
|
|
|
{
|
|
|
|
// ignore...
|
|
|
|
if ($args['abort'] && !$args['result']) {
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->_contact_folder_rename($args['name'], false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook for (contact) folder renaming
|
|
|
|
*/
|
|
|
|
function prefs_folder_rename($args)
|
|
|
|
{
|
|
|
|
// ignore...
|
|
|
|
if ($args['abort'] && !$args['result']) {
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->_contact_folder_rename($args['oldname'], $args['newname']);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook for (contact) folder updates. Forward to folder_rename handler if name was changed
|
|
|
|
*/
|
|
|
|
function prefs_folder_update($args)
|
|
|
|
{
|
|
|
|
// ignore...
|
|
|
|
if ($args['abort'] && !$args['result']) {
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($args['record']['name'] != $args['record']['oldname']) {
|
|
|
|
$this->_contact_folder_rename($args['record']['oldname'], $args['record']['name']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Apply folder renaming or deletion to the registered birthday calendar address books
|
|
|
|
*/
|
|
|
|
private function _contact_folder_rename($oldname, $newname = false)
|
|
|
|
{
|
|
|
|
$update = false;
|
|
|
|
$delimiter = $this->rc->get_storage()->get_hierarchy_delimiter();
|
|
|
|
$bday_addressbooks = (array)$this->rc->config->get('calendar_birthday_adressbooks', array());
|
|
|
|
|
|
|
|
foreach ($bday_addressbooks as $i => $id) {
|
|
|
|
$folder_name = kolab_storage::id_decode($id);
|
|
|
|
if ($oldname === $folder_name || strpos($folder_name, $oldname.$delimiter) === 0) {
|
|
|
|
if ($newname) { // rename
|
|
|
|
$new_folder = $newname . substr($folder_name, strlen($oldname));
|
|
|
|
$bday_addressbooks[$i] = kolab_storage::id_encode($new_folder);
|
|
|
|
}
|
|
|
|
else { // delete
|
|
|
|
unset($bday_addressbooks[$i]);
|
|
|
|
}
|
|
|
|
$update = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($update) {
|
|
|
|
$this->rc->user->save_prefs(array('calendar_birthday_adressbooks' => $bday_addressbooks));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-21 12:25:39 +02:00
|
|
|
}
|