summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthomasb <thomasb@208e9e7b-5314-0410-a742-e7e81cd9613c>2011-05-21 10:29:57 +0000
committerthomasb <thomasb@208e9e7b-5314-0410-a742-e7e81cd9613c>2011-05-21 10:29:57 +0000
commitfa2d393cc420adec1bb6d9a44aa2071a29f412af (patch)
treefd67c0d8602e903069abbb44a5dc329a5d15d790
parentce076e953378e1c3867d9ebf64fc614b56281a22 (diff)
Removed kolab plugins; they will be maintaied and published in the Kolab project
git-svn-id: https://svn.roundcube.net/trunk@4797 208e9e7b-5314-0410-a742-e7e81cd9613c
-rw-r--r--plugins/kolab_addressbook/kolab_addressbook.php164
-rw-r--r--plugins/kolab_addressbook/localization/en_US.inc12
-rw-r--r--plugins/kolab_addressbook/localization/ja_JP.inc14
-rw-r--r--plugins/kolab_addressbook/localization/ru_RU.inc29
-rw-r--r--plugins/kolab_addressbook/rcube_kolab_contacts.php886
-rw-r--r--plugins/kolab_core/README.txt32
-rw-r--r--plugins/kolab_core/config.inc.php.dist8
-rw-r--r--plugins/kolab_core/kolab_core.php30
-rw-r--r--plugins/kolab_core/rcube_kolab.php107
9 files changed, 0 insertions, 1282 deletions
diff --git a/plugins/kolab_addressbook/kolab_addressbook.php b/plugins/kolab_addressbook/kolab_addressbook.php
deleted file mode 100644
index d824c8944..000000000
--- a/plugins/kolab_addressbook/kolab_addressbook.php
+++ /dev/null
@@ -1,164 +0,0 @@
-<?php
-
-require_once(dirname(__FILE__) . '/rcube_kolab_contacts.php');
-
-/**
- * Kolab address book
- *
- * Sample plugin to add a new address book source with data from Kolab storage
- * This is work-in-progress for the Roundcube+Kolab integration.
- *
- * @author Thomas Bruederli <roundcube@gmail.com>
- *
- */
-class kolab_addressbook extends rcube_plugin
-{
- private $folders;
- private $sources;
-
- /**
- * Required startup method of a Roundcube plugin
- */
- public function init()
- {
- // load required plugin
- $this->require_plugin('kolab_core');
-
- $this->add_texts('localization');
-
- // register hooks
- $this->add_hook('addressbooks_list', array($this, 'address_sources'));
- $this->add_hook('addressbook_get', array($this, 'get_address_book'));
- $this->add_hook('contact_form', array($this, 'contact_form'));
-
- // extend list of address sources to be used for autocompletion
- $rcmail = rcmail::get_instance();
- if ($rcmail->action == 'autocomplete' || $rcmail->action == 'group-expand') {
- $sources = (array) $rcmail->config->get('autocomplete_addressbooks', array());
- foreach ($this->_list_sources() as $abook_id => $abook) {
- if (!in_array($abook_id, $sources))
- $sources[] = $abook_id;
- }
- $rcmail->config->set('autocomplete_addressbooks', $sources);
- }
- }
-
- /**
- * 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.
- *
- * @param array Hash array with hook parameters
- * @return array Hash array with modified hook parameters
- */
- public function address_sources($p)
- {
- foreach ($this->_list_sources() as $abook_id => $abook) {
- // register this address source
- $p['sources'][$abook_id] = array(
- 'id' => $abook_id,
- 'name' => $abook->get_name(),
- 'readonly' => $abook->readonly,
- 'groups' => $abook->groups,
- );
- }
-
- return $p;
- }
-
-
- /**
- * Getter for the rcube_addressbook instance
- */
- public function get_address_book($p)
- {
- if ($this->sources[$p['id']]) {
- $p['instance'] = $this->sources[$p['id']];
- }
-
- return $p;
- }
-
-
- private function _list_sources()
- {
- // already read sources
- if (isset($this->sources))
- return $this->sources;
-
- // get all folders that have "contact" type
- $this->folders = rcube_kolab::get_folders('contact');
- $this->sources = array();
-
- if (PEAR::isError($this->folders)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Failed to list contact folders from Kolab server:" . $this->folders->getMessage()),
- true, false);
- }
- else {
- foreach ($this->folders as $c_folder) {
- // create instance of rcube_contacts
- $abook_id = strtolower(asciiwords(strtr($c_folder->name, '/.', '--')));
- $abook = new rcube_kolab_contacts($c_folder->name);
- $this->sources[$abook_id] = $abook;
- }
- }
-
- return $this->sources;
- }
-
-
- /**
- * Plugin hook called before rendering the contact form or detail view
- */
- public function contact_form($p)
- {
- // none of our business
- if (!is_a($GLOBALS['CONTACTS'], 'rcube_kolab_contacts'))
- return $p;
-
- // extend the list of contact fields to be displayed in the 'personal' section
- if (is_array($p['form']['personal'])) {
- $p['form']['contact']['content']['officelocation'] = array('size' => 40);
-
- $p['form']['personal']['content']['initials'] = array('size' => 6);
- $p['form']['personal']['content']['profession'] = array('size' => 40);
- $p['form']['personal']['content']['children'] = array('size' => 40);
- $p['form']['personal']['content']['pgppublickey'] = array('size' => 40);
- $p['form']['personal']['content']['freebusyurl'] = array('size' => 40);
-
- // re-order fields according to the coltypes list
- $p['form']['contact']['content'] = $this->_sort_form_fields($p['form']['contact']['content']);
- $p['form']['personal']['content'] = $this->_sort_form_fields($p['form']['personal']['content']);
-
- /* define a separate section 'settings'
- $p['form']['settings'] = array(
- 'name' => rcube_label('kolab_addressbook.settings'),
- 'content' => array(
- 'pgppublickey' => array('size' => 40, 'visible' => true),
- 'freebusyurl' => array('size' => 40, 'visible' => true),
- )
- );
- */
- }
-
- return $p;
- }
-
-
- private function _sort_form_fields($contents)
- {
- $block = array();
- $contacts = reset($this->sources);
- foreach ($contacts->coltypes as $col => $prop) {
- if (isset($contents[$col]))
- $block[$col] = $contents[$col];
- }
-
- return $block;
- }
-
-}
diff --git a/plugins/kolab_addressbook/localization/en_US.inc b/plugins/kolab_addressbook/localization/en_US.inc
deleted file mode 100644
index 968d9e691..000000000
--- a/plugins/kolab_addressbook/localization/en_US.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-$labels = array();
-$labels['initials'] = 'Initials';
-$labels['profession'] = 'Profession';
-$labels['officelocation'] = 'Office location';
-$labels['children'] = 'Children';
-$labels['pgppublickey'] = 'PGP publickey';
-$labels['freebusyurl'] = 'Free-busy URL';
-$labels['settings'] = 'Settings';
-
-?> \ No newline at end of file
diff --git a/plugins/kolab_addressbook/localization/ja_JP.inc b/plugins/kolab_addressbook/localization/ja_JP.inc
deleted file mode 100644
index 7f1a7c5e7..000000000
--- a/plugins/kolab_addressbook/localization/ja_JP.inc
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-// EN-Revision: 4383
-
-$labels = array();
-$labels['initials'] = 'イニシャル';
-$labels['profession'] = '職業';
-$labels['officelocation'] = 'オフィスの所在地';
-$labels['children'] = '子供';
-$labels['pgppublickey'] = 'PGP 公開鍵';
-$labels['freebusyurl'] = 'Free-busy URL';
-$labels['settings'] = '設定';
-
-?> \ No newline at end of file
diff --git a/plugins/kolab_addressbook/localization/ru_RU.inc b/plugins/kolab_addressbook/localization/ru_RU.inc
deleted file mode 100644
index 28526319c..000000000
--- a/plugins/kolab_addressbook/localization/ru_RU.inc
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/*
-
-+-----------------------------------------------------------------------+
-| plugins/kolab_addressbook/localization/ru_RU.inc |
-| |
-| Russian translation for roundcube/kolab_addressbook plugin |
-| Copyright (C) 2008-2011 |
-| Licensed under the GNU GPL |
-| |
-+-----------------------------------------------------------------------+
-| Author: Sergey Dukachev <iam@dukess.ru> |
-| Updates: |
-+-----------------------------------------------------------------------+
-
-@version 2011-05-11
-
-*/
-
-$labels = array();
-$labels['initials'] = 'Инициалы';
-$labels['profession'] = 'Профессия';
-$labels['officelocation'] = 'Адрес офиса';
-$labels['children'] = 'Дети';
-$labels['pgppublickey'] = 'Публичный ключ PGP';
-$labels['freebusyurl'] = 'URL свободен/занят';
-$labels['settings'] = 'Настройки';
-
-?> \ No newline at end of file
diff --git a/plugins/kolab_addressbook/rcube_kolab_contacts.php b/plugins/kolab_addressbook/rcube_kolab_contacts.php
deleted file mode 100644
index 8ecb6a402..000000000
--- a/plugins/kolab_addressbook/rcube_kolab_contacts.php
+++ /dev/null
@@ -1,886 +0,0 @@
-<?php
-
-
-/**
- * Backend class for a custom address book
- *
- * This part of the Roundcube+Kolab integration and connects the
- * rcube_addressbook interface with the rcube_kolab wrapper for Kolab_Storage
- *
- * @author Thomas Bruederli
- * @see rcube_addressbook
- */
-class rcube_kolab_contacts extends rcube_addressbook
-{
- public $primary_key = 'ID';
- public $readonly = false;
- public $groups = true;
- public $coltypes = array(
- 'name' => array('limit' => 1),
- 'firstname' => array('limit' => 1),
- 'surname' => array('limit' => 1),
- 'middlename' => array('limit' => 1),
- 'prefix' => array('limit' => 1),
- 'suffix' => array('limit' => 1),
- 'nickname' => array('limit' => 1),
- 'jobtitle' => array('limit' => 1),
- 'organization' => array('limit' => 1),
- 'department' => array('limit' => 1),
- 'email' => array('subtypes' => null),
- 'phone' => array(),
- 'address' => array('limit' => 2, 'subtypes' => array('home','business')),
- 'officelocation' => array('type' => 'text', 'size' => 40, 'limit' => 1, 'label' => 'kolab_addressbook.officelocation'),
- 'website' => array('limit' => 1, 'subtypes' => null),
- 'im' => array('limit' => 1, 'subtypes' => null),
- 'gender' => array('limit' => 1),
- 'initials' => array('type' => 'text', 'size' => 6, 'limit' => 1, 'label' => 'kolab_addressbook.initials'),
- 'birthday' => array('limit' => 1),
- 'anniversary' => array('limit' => 1),
- 'profession' => array('type' => 'text', 'size' => 40, 'limit' => 1, 'label' => 'kolab_addressbook.profession'),
- 'manager' => array('limit' => 1),
- 'assistant' => array('limit' => 1),
- 'spouse' => array('limit' => 1),
- 'children' => array('type' => 'text', 'size' => 40, 'limit' => 1, 'label' => 'kolab_addressbook.children'),
- 'pgppublickey' => array('type' => 'text', 'size' => 40, 'limit' => 1, 'label' => 'kolab_addressbook.pgppublickey'),
- 'freebusyurl' => array('type' => 'text', 'size' => 40, 'limit' => 1, 'label' => 'kolab_addressbook.freebusyurl'),
- 'notes' => array(),
- 'photo' => array(),
- // TODO: define more Kolab-specific fields such as: language, latitude, longitude
- );
-
- private $gid;
- private $imap;
- private $kolab;
- private $folder;
- private $contactstorage;
- private $liststorage;
- private $contacts;
- private $distlists;
- private $groupmembers;
- private $id2uid;
- private $filter;
- private $result;
- private $imap_folder = 'INBOX/Contacts';
- private $gender_map = array(0 => 'male', 1 => 'female');
- private $phonetypemap = array('home' => 'home1', 'work' => 'business1', 'work2' => 'business2', 'workfax' => 'businessfax');
- private $addresstypemap = array('work' => 'business');
- private $fieldmap = array(
- // kolab => roundcube
- 'full-name' => 'name',
- 'given-name' => 'firstname',
- 'middle-names' => 'middlename',
- 'last-name' => 'surname',
- 'prefix' => 'prefix',
- 'suffix' => 'suffix',
- 'nick-name' => 'nickname',
- 'organization' => 'organization',
- 'department' => 'department',
- 'job-title' => 'jobtitle',
- 'initials' => 'initials',
- 'birthday' => 'birthday',
- 'anniversary' => 'anniversary',
- 'im-address' => 'im',
- 'web-page' => 'website',
- 'office-location' => 'officelocation',
- 'profession' => 'profession',
- 'manager-name' => 'manager',
- 'assistant' => 'assistant',
- 'spouse-name' => 'spouse',
- 'children' => 'children',
- 'body' => 'notes',
- 'pgp-publickey' => 'pgppublickey',
- 'free-busy-url' => 'freebusyurl',
- );
-
-
- public function __construct($imap_folder = null)
- {
- if ($imap_folder)
- $this->imap_folder = $imap_folder;
-
- // extend coltypes configuration
- $format = rcube_kolab::get_format('contact');
- $this->coltypes['phone']['subtypes'] = $format->_phone_types;
- $this->coltypes['address']['subtypes'] = $format->_address_types;
-
- // set localized labels for proprietary cols
- foreach ($this->coltypes as $col => $prop) {
- if (is_string($prop['label']))
- $this->coltypes[$col]['label'] = rcube_label($prop['label']);
- }
-
- // fetch objects from the given IMAP folder
- $this->contactstorage = rcube_kolab::get_storage($this->imap_folder);
- $this->liststorage = rcube_kolab::get_storage($this->imap_folder, 'distributionlist');
-
- $this->ready = !PEAR::isError($this->contactstorage) && !PEAR::isError($this->liststorage);
- }
-
-
- /**
- * Getter for the address book name to be displayed
- *
- * @return string Name of this address book
- */
- public function get_name()
- {
- return strtr(preg_replace('!^(INBOX|user)/!i', '', $this->imap_folder), '/', ':');
- }
-
-
- /**
- * Setter for the current group
- */
- public function set_group($gid)
- {
- $this->gid = $gid;
- }
-
-
- /**
- * Save a search string for future listings
- *
- * @param mixed Search params to use in listing method, obtained by get_search_set()
- */
- public function set_search_set($filter)
- {
- $this->filter = $filter;
- }
-
-
- /**
- * Getter for saved search properties
- *
- * @return mixed Search properties used by this class
- */
- public function get_search_set()
- {
- return $this->filter;
- }
-
-
- /**
- * Reset saved results and search parameters
- */
- public function reset()
- {
- $this->result = null;
- $this->filter = null;
- }
-
-
- /**
- * List all active contact groups of this source
- *
- * @param string Optional search string to match group name
- * @return array Indexed list of contact groups, each a hash array
- */
- function list_groups($search = null)
- {
- $this->_fetch_groups();
- $groups = array();
- foreach ((array)$this->distlists as $group) {
- if (!$search || strstr(strtolower($group['last-name']), strtolower($search)))
- $groups[] = array('ID' => $group['ID'], 'name' => $group['last-name']);
- }
- return $groups;
- }
-
- /**
- * List the current set of contact records
- *
- * @param array List of cols to show
- * @param int Only return this number of records, use negative values for tail
- * @return array Indexed list of contact records, each a hash array
- */
- public function list_records($cols=null, $subset=0)
- {
- $this->result = $this->count();
-
- // list member of the selected group
- if ($this->gid) {
- $seen = array();
- $this->result->count = 0;
- foreach ((array)$this->distlists[$this->gid]['member'] as $member) {
- // skip member that don't match the search filter
- if (is_array($this->filter['ids']) && array_search($member['ID'], $this->filter['ids']) === false)
- continue;
- if ($this->contacts[$member['ID']] && !$seen[$member['ID']]++)
- $this->result->count++;
- }
- $ids = array_keys($seen);
- }
- else
- $ids = is_array($this->filter['ids']) ? $this->filter['ids'] : array_keys($this->contacts);
-
- // fill contact data into the current result set
- $start_row = $subset < 0 ? $this->result->first + $this->page_size + $subset : $this->result->first;
- $last_row = min($subset != 0 ? $start_row + abs($subset) : $this->result->first + $this->page_size, count($ids));
-
- for ($i = $start_row; $i < $last_row; $i++) {
- if ($id = $ids[$i])
- $this->result->add($this->contacts[$id]);
- }
-
- return $this->result;
- }
-
-
- /**
- * Search records
- *
- * @param array List of fields to search in
- * @param string Search value
- * @param boolean True if results are requested, False if count only
- * @param boolean True to skip the count query (select only)
- * @param array List of fields that cannot be empty
- * @return object rcube_result_set List of contact records and 'count' value
- */
- public function search($fields, $value, $strict=false, $select=true, $nocount=false, $required=array())
- {
- $this->_fetch_contacts();
-
- // search by ID
- if ($fields == $this->primary_key) {
- return $this->get_record($value);
- }
-
- $value = strtolower($value);
- if (!is_array($fields))
- $fields = array($fields);
- if (!is_array($required) && !empty($required))
- $required = array($required);
-
- $this->filter = array('fields' => $fields, 'value' => $value, 'strict' => $strict, 'ids' => array());
-
- // search be iterating over all records in memory
- foreach ($this->contacts as $id => $contact) {
- // check if current contact has required values, otherwise skip it
- if ($required) {
- foreach ($required as $f)
- if (empty($contact[$f]))
- continue 2;
- }
- foreach ($fields as $f) {
- foreach ((array)$contact[$f] as $val) {
- $val = strtolower($val);
- if (($strict && $val == $value) || (!$strict && strstr($val, $value))) {
- $this->filter['ids'][] = $id;
- break 2;
- }
- }
- }
- }
-
- // list records (now limited by $this->filter)
- return $this->list_records();
- }
-
-
- /**
- * Refresh saved search results after data has changed
- */
- public function refresh_search()
- {
- if ($this->filter)
- $this->search($this->filter['fields'], $this->filter['value'], $this->filter['strict']);
-
- return $this->get_search_set();
- }
-
-
- /**
- * Count number of available contacts in database
- *
- * @return rcube_result_set Result set with values for 'count' and 'first'
- */
- public function count()
- {
- $this->_fetch_contacts();
- $this->_fetch_groups();
- $count = $this->gid ? count($this->distlists[$this->gid]['member']) : (is_array($this->filter['ids']) ? count($this->filter['ids']) : count($this->contacts));
- return new rcube_result_set($count, ($this->list_page-1) * $this->page_size);
- }
-
-
- /**
- * Return the last result set
- *
- * @return rcube_result_set Current result set or NULL if nothing selected yet
- */
- public function get_result()
- {
- return $this->result;
- }
-
- /**
- * Get a specific contact record
- *
- * @param mixed record identifier(s)
- * @param boolean True to return record as associative array, otherwise a result set is returned
- * @return mixed Result object with all record fields or False if not found
- */
- public function get_record($id, $assoc=false)
- {
- $this->_fetch_contacts();
- if ($this->contacts[$id]) {
- $this->result = new rcube_result_set(1);
- $this->result->add($this->contacts[$id]);
- return $assoc ? $this->contacts[$id] : $this->result;
- }
-
- return false;
- }
-
-
- /**
- * Get group assignments of a specific contact record
- *
- * @param mixed Record identifier
- * @return array List of assigned groups as ID=>Name pairs
- */
- public function get_record_groups($id)
- {
- $out = array();
- $this->_fetch_groups();
-
- foreach ((array)$this->groupmembers[$id] as $gid) {
- if ($group = $this->distlists[$gid])
- $out[$gid] = $group['last-name'];
- }
-
- return $out;
- }
-
-
- /**
- * Create a new contact record
- *
- * @param array Assoziative array with save data
- * Keys: Field name with optional section in the form FIELD:SECTION
- * Values: Field value. Can be either a string or an array of strings for multiple values
- * @param boolean True to check for duplicates first
- * @return mixed The created record ID on success, False on error
- */
- public function insert($save_data, $check=false)
- {
- if (!is_array($save_data))
- return false;
-
- $insert_id = $existing = false;
-
- // check for existing records by e-mail comparison
- if ($check) {
- foreach ($this->get_col_values('email', $save_data, true) as $email) {
- if (($res = $this->search('email', $email, true, false)) && $res->count) {
- $existing = true;
- break;
- }
- }
- }
-
- if (!$existing) {
- // generate new Kolab contact item
- $object = $this->_from_rcube_contact($save_data);
- $object['uid'] = $this->contactstorage->generateUID();
-
- $saved = $this->contactstorage->save($object);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving contact object to Kolab server:" . $saved->getMessage()),
- true, false);
- }
- else {
- $contact = $this->_to_rcube_contact($object);
- $id = $contact['ID'];
- $this->contacts[$id] = $contact;
- $this->id2uid[$id] = $object['uid'];
- $insert_id = $id;
- }
- }
-
- return $insert_id;
- }
-
-
- /**
- * Update a specific contact record
- *
- * @param mixed Record identifier
- * @param array Assoziative array with save data
- * Keys: Field name with optional section in the form FIELD:SECTION
- * Values: Field value. Can be either a string or an array of strings for multiple values
- * @return boolean True on success, False on error
- */
- public function update($id, $save_data)
- {
- $updated = false;
- $this->_fetch_contacts();
- if ($this->contacts[$id] && ($uid = $this->id2uid[$id])) {
- $old = $this->contactstorage->getObject($uid);
- $object = array_merge($old, $this->_from_rcube_contact($save_data));
-
- $saved = $this->contactstorage->save($object, $uid);
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving contact object to Kolab server:" . $saved->getMessage()),
- true, false);
- }
- else {
- $this->contacts[$id] = $this->_to_rcube_contact($object);
- $updated = true;
- }
- }
-
- return $updated;
- }
-
- /**
- * Mark one or more contact records as deleted
- *
- * @param array Record identifiers
- */
- public function delete($ids)
- {
- $this->_fetch_contacts();
- $this->_fetch_groups();
-
- if (!is_array($ids))
- $ids = explode(',', $ids);
-
- $count = 0;
- foreach ($ids as $id) {
- if ($uid = $this->id2uid[$id]) {
- $deleted = $this->contactstorage->delete($uid);
-
- if (PEAR::isError($deleted)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error deleting a contact object from the Kolab server:" . $deleted->getMessage()),
- true, false);
- }
- else {
- // remove from distribution lists
- foreach ((array)$this->groupmembers[$id] as $gid)
- $this->remove_from_group($gid, $id);
-
- // clear internal cache
- unset($this->contacts[$id], $this->id2uid[$id], $this->groupmembers[$id]);
- $count++;
- }
- }
- }
-
- return $count;
- }
-
- /**
- * Remove all records from the database
- */
- public function delete_all()
- {
- if (!PEAR::isError($this->contactstorage->deleteAll())) {
- $this->contacts = array();
- $this->id2uid = array();
- $this->result = null;
- }
- }
-
-
- /**
- * Close connection to source
- * Called on script shutdown
- */
- public function close()
- {
- rcube_kolab::shutdown();
- }
-
-
- /**
- * Create a contact group with the given name
- *
- * @param string The group name
- * @return mixed False on error, array with record props in success
- */
- function create_group($name)
- {
- $this->_fetch_groups();
- $result = false;
-
- $list = array(
- 'uid' => $this->liststorage->generateUID(),
- 'last-name' => $name,
- 'member' => array(),
- );
- $saved = $this->liststorage->save($list);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
- true, false);
- return false;
- }
- else {
- $id = md5($list['uid']);
- $this->distlists[$record['ID']] = $list;
- $result = array('id' => $id, 'name' => $name);
- }
-
- return $result;
- }
-
- /**
- * Delete the given group and all linked group members
- *
- * @param string Group identifier
- * @return boolean True on success, false if no data was changed
- */
- function delete_group($gid)
- {
- $this->_fetch_groups();
- $result = false;
-
- if ($list = $this->distlists[$gid])
- $deleted = $this->liststorage->delete($list['uid']);
-
- if (PEAR::isError($deleted)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error deleting distribution-list object from the Kolab server:" . $deleted->getMessage()),
- true, false);
- }
- else
- $result = true;
-
- return $result;
- }
-
- /**
- * Rename a specific contact group
- *
- * @param string Group identifier
- * @param string New name to set for this group
- * @return boolean New name on success, false if no data was changed
- */
- function rename_group($gid, $newname)
- {
- $this->_fetch_groups();
- $list = $this->distlists[$gid];
-
- if ($newname != $list['last-name']) {
- $list['last-name'] = $newname;
- $saved = $this->liststorage->save($list, $list['uid']);
- }
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
- true, false);
- return false;
- }
-
- return $newname;
- }
-
- /**
- * Add the given contact records the a certain group
- *
- * @param string Group identifier
- * @param array List of contact identifiers to be added
- * @return int Number of contacts added
- */
- function add_to_group($gid, $ids)
- {
- if (!is_array($ids))
- $ids = explode(',', $ids);
-
- $added = 0;
- $exists = array();
-
- $this->_fetch_groups();
- $this->_fetch_contacts();
- $list = $this->distlists[$gid];
-
- foreach ((array)$list['member'] as $i => $member)
- $exists[] = $member['ID'];
-
- // substract existing assignments from list
- $ids = array_diff($ids, $exists);
-
- foreach ($ids as $contact_id) {
- if ($uid = $this->id2uid[$contact_id]) {
- $contact = $this->contacts[$contact_id];
- foreach ($this->get_col_values('email', $contact, true) as $email) {
- $list['member'][] = array(
- 'uid' => $uid,
- 'display-name' => $contact['name'],
- 'smtp-address' => $email,
- );
- }
- $this->groupmembers[$contact_id][] = $gid;
- $added++;
- }
- }
-
- if ($added)
- $saved = $this->liststorage->save($list, $list['uid']);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list to Kolab server:" . $saved->getMessage()),
- true, false);
- $added = false;
- }
- else {
- $this->distlists[$gid] = $list;
- }
-
- return $added;
- }
-
- /**
- * Remove the given contact records from a certain group
- *
- * @param string Group identifier
- * @param array List of contact identifiers to be removed
- * @return int Number of deleted group members
- */
- function remove_from_group($gid, $ids)
- {
- if (!is_array($ids))
- $ids = explode(',', $ids);
-
- $this->_fetch_groups();
- if (!($list = $this->distlists[$gid]))
- return false;
-
- $new_member = array();
- foreach ((array)$list['member'] as $member) {
- if (!in_array($member['ID'], $ids))
- $new_member[] = $member;
- }
-
- // write distribution list back to server
- $list['member'] = $new_member;
- $saved = $this->liststorage->save($list, $list['uid']);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
- true, false);
- }
- else {
- // remove group assigments in local cache
- foreach ($ids as $id) {
- $j = array_search($gid, $this->groupmembers[$id]);
- unset($this->groupmembers[$id][$j]);
- }
- $this->distlists[$gid] = $list;
- return true;
- }
-
- return false;
- }
-
-
- /**
- * Simply fetch all records and store them in private member vars
- */
- private function _fetch_contacts()
- {
- if (!isset($this->contacts)) {
- // read contacts
- $this->contacts = $this->id2uid = array();
- foreach ((array)$this->contactstorage->getObjects() as $record) {
- $contact = $this->_to_rcube_contact($record);
- $id = $contact['ID'];
- $this->contacts[$id] = $contact;
- $this->id2uid[$id] = $record['uid'];
- }
-
- // sort data arrays according to desired list sorting
- uasort($this->contacts, array($this, '_sort_contacts_comp'));
- }
- }
-
-
- /**
- * Callback function for sorting contacts
- */
- private function _sort_contacts_comp($a, $b)
- {
- return strcasecmp($a['name'], $b['name']);
- }
-
-
- /**
- * Read distribution-lists AKA groups from server
- */
- private function _fetch_groups()
- {
- if (!isset($this->distlists)) {
- $this->distlists = $this->groupmembers = array();
- foreach ((array)$this->liststorage->getObjects() as $record) {
- // FIXME: folders without any distribution-list objects return contacts instead ?!
- if ($record['__type'] != 'Group')
- continue;
- $record['ID'] = md5($record['uid']);
- foreach ((array)$record['member'] as $i => $member) {
- $mid = md5($member['uid']);
- $record['member'][$i]['ID'] = $mid;
- $this->groupmembers[$mid][] = $record['ID'];
- }
- $this->distlists[$record['ID']] = $record;
- }
- }
- }
-
-
- /**
- * Map fields from internal Kolab_Format to Roundcube contact format
- */
- private function _to_rcube_contact($record)
- {
- $out = array(
- 'ID' => md5($record['uid']),
- 'email' => array(),
- 'phone' => array(),
- );
-
- foreach ($this->fieldmap as $kolab => $rcube) {
- if (strlen($record[$kolab]))
- $out[$rcube] = $record[$kolab];
- }
-
- if (isset($record['gender']))
- $out['gender'] = $this->gender_map[$record['gender']];
-
- foreach ((array)$record['email'] as $i => $email)
- $out['email'][] = $email['smtp-address'];
-
- if (!$record['email'] && $record['emails'])
- $out['email'] = preg_split('/,\s*/', $record['emails']);
-
- foreach ((array)$record['phone'] as $i => $phone)
- $out['phone:'.$phone['type']][] = $phone['number'];
-
- if (is_array($record['address'])) {
- foreach ($record['address'] as $i => $adr) {
- $key = 'address:' . $adr['type'];
- $out[$key][] = array(
- 'street' => $adr['street'],
- 'locality' => $adr['locality'],
- 'zipcode' => $adr['postal-code'],
- 'region' => $adr['region'],
- 'country' => $adr['country'],
- );
- }
- }
-
- // photo is stored as separate attachment
- if ($record['picture'] && ($att = $record['_attachments'][$record['picture']])) {
- $out['photo'] = $att['content'] ? $att['content'] : $this->contactstorage->getAttachment($att['key']);
- }
-
- // remove empty fields
- return array_filter($out);
- }
-
- private function _from_rcube_contact($contact)
- {
- $object = array();
-
- foreach (array_flip($this->fieldmap) as $rcube => $kolab) {
- if (isset($contact[$rcube]))
- $object[$kolab] = is_array($contact[$rcube]) ? $contact[$rcube][0] : $contact[$rcube];
- else if ($values = $this->get_col_values($rcube, $contact, true))
- $object[$kolab] = is_array($values) ? $values[0] : $values;
- }
-
- // format dates
- if ($object['birthday'] && ($date = @strtotime($object['birthday'])))
- $object['birthday'] = date('Y-m-d', $date);
- if ($object['anniversary'] && ($date = @strtotime($object['anniversary'])))
- $object['anniversary'] = date('Y-m-d', $date);
-
- $gendermap = array_flip($this->gender_map);
- if (isset($contact['gender']))
- $object['gender'] = $gendermap[$contact['gender']];
-
- $emails = $this->get_col_values('email', $contact, true);
- $object['emails'] = join(', ', array_filter($emails));
-
- foreach ($this->get_col_values('phone', $contact) as $type => $values) {
- if ($this->phonetypemap[$type])
- $type = $this->phonetypemap[$type];
- foreach ((array)$values as $phone) {
- if (!empty($phone)) {
- $object['phone-' . $type] = $phone;
- $object['phone'][] = array('number' => $phone, 'type' => $type);
- }
- }
- }
-
- foreach ($this->get_col_values('address', $contact) as $type => $values) {
- if ($this->addresstypemap[$type])
- $type = $this->addresstypemap[$type];
-
- $basekey = 'addr-' . $type . '-';
- foreach ((array)$values as $adr) {
- // switch type if slot is already taken
- if (isset($object[$basekey . 'type'])) {
- $type = $type == 'home' ? 'business' : 'home';
- $basekey = 'addr-' . $type . '-';
- }
-
- if (!isset($object[$basekey . 'type'])) {
- $object[$basekey . 'type'] = $type;
- $object[$basekey . 'street'] = $adr['street'];
- $object[$basekey . 'locality'] = $adr['locality'];
- $object[$basekey . 'postal-code'] = $adr['zipcode'];
- $object[$basekey . 'region'] = $adr['region'];
- $object[$basekey . 'country'] = $adr['country'];
- }
- else {
- $object['address'][] = array(
- 'type' => $type,
- 'street' => $adr['street'],
- 'locality' => $adr['locality'],
- 'postal-code' => $adr['zipcode'],
- 'region' => $adr['region'],
- 'country' => $adr['country'],
- );
- }
- }
- }
-
- // save new photo as attachment
- if ($contact['photo']) {
- $attkey = 'photo.attachment';
- $object['_attachments'][$attkey] = array(
- 'type' => rc_image_content_type($contact['photo']),
- 'content' => preg_match('![^a-z0-9/=+-]!i', $contact['photo']) ? $contact['photo'] : base64_decode($contact['photo']),
- );
- $object['picture'] = $attkey;
- }
-
- return $object;
- }
-
-}
diff --git a/plugins/kolab_core/README.txt b/plugins/kolab_core/README.txt
deleted file mode 100644
index 87537c0b8..000000000
--- a/plugins/kolab_core/README.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-Kolab Integration Plugin README
--------------------------------
-
-This plugin relies on classes from the Horde project. In order to have all
-the required files available you need to install the following packages from
-Horde:
- Horde_Framework
- Kolab_Format
- Kolab_Storage
- Horde_NLS
- Horde_DOM
-
-This is best done using PEAR. Make sure that the local PEAR directory is in
-the PHP isntall path and execute the following commands to install the
-required packages:
-
-pear channel-discover pear.horde.org
-
-pear install horde/Horde_Framework
-pear install horde/Horde_DOM
-pear install horde/Horde_NLS
-pear install horde/Horde_Share
-pear install horde/Log
-pear install horde/Kolab_Format
-pear install horde/Kolab_Storage
-
-
-Configuration
--------------
-
-Rename the config.inc.php.dist to config.inc.php within this plugin directory
-and add the corresponding values for your local Kolab server.
diff --git a/plugins/kolab_core/config.inc.php.dist b/plugins/kolab_core/config.inc.php.dist
deleted file mode 100644
index b6ac25a4d..000000000
--- a/plugins/kolab_core/config.inc.php.dist
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-// Sample configuration for Kolab LDAP binding used by Kolab_Storage
-$rcmail_config['kolab']['ldap']['basedn'] = 'dc=kolabserver,dc=local';
-$rcmail_config['kolab']['ldap']['phpdn'] = 'cn=nobody,cn=internal,dc=kolabserver,dc=local';
-$rcmail_config['kolab']['ldap']['phppw'] = '<ldap-pwd-goes-here>';
-
-?>
diff --git a/plugins/kolab_core/kolab_core.php b/plugins/kolab_core/kolab_core.php
deleted file mode 100644
index e98b02dcd..000000000
--- a/plugins/kolab_core/kolab_core.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/**
- * Kolab core library
- *
- * Plugin to setup a basic environment for interaction with a Kolab server.
- * Other Kolab-related plugins will depend on it and can use the static API rcube_core
- *
- * This is work-in-progress for the Roundcube+Kolab integration.
- *
- * @author Thomas Bruederli <roundcube@gmail.com>
- *
- */
-class kolab_core extends rcube_plugin
-{
- /**
- * Required startup method of a Roundcube plugin
- */
- public function init()
- {
- // load local config
- $this->load_config();
-
- // extend include path to load bundled Horde classes
- $include_path = $this->home . PATH_SEPARATOR . ini_get('include_path');
- set_include_path($include_path);
- }
-
-}
-
diff --git a/plugins/kolab_core/rcube_kolab.php b/plugins/kolab_core/rcube_kolab.php
deleted file mode 100644
index a69a90365..000000000
--- a/plugins/kolab_core/rcube_kolab.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-
-require_once 'Horde/Kolab/Storage/List.php';
-require_once 'Horde/Kolab/Format.php';
-require_once 'Horde/Auth.php';
-require_once 'Horde/Auth/kolab.php';
-require_once 'Horde/Perms.php';
-
-/**
- * Glue class to handle access to the Kolab data using the Kolab_* classes
- * from the Horde project.
- *
- * @author Thomas Bruederli
- */
-class rcube_kolab
-{
- private static $horde_auth;
- private static $ready = false;
-
-
- /**
- * Setup the environment needed by the Kolab_* classes to access Kolab data
- */
- public static function setup()
- {
- global $conf;
-
- // setup already done
- if (self::$horde_auth)
- return;
-
- $rcmail = rcmail::get_instance();
-
- // load ldap credentials from local config
- $conf['kolab'] = $rcmail->config->get('kolab');
-
- $conf['kolab']['ldap']['server'] = 'ldap://' . $_SESSION['imap_host'] . ':389';
- $conf['kolab']['imap']['server'] = $_SESSION['imap_host'];
- $conf['kolab']['imap']['port'] = $_SESSION['imap_port'];
-
- // pass the current IMAP authentication credentials to the Horde auth system
- self::$horde_auth = Auth::singleton('kolab');
- if (self::$horde_auth->authenticate($_SESSION['username'], array('password' => ($pwd = $rcmail->decrypt($_SESSION['password']))), false)) {
- $_SESSION['__auth'] = array(
- 'authenticated' => true,
- 'userId' => $_SESSION['username'],
- 'timestamp' => time(),
- 'remote_addr' => $_SERVER['REMOTE_ADDR'],
- );
- Auth::setCredential('password', $pwd);
- self::$ready = true;
- }
-
- NLS::setCharset('UTF-8');
- String::setDefaultCharset('UTF-8');
- }
-
-
- /**
- * Get instance of a Kolab (XML) format object
- *
- * @param string Data type (contact,event,task,note)
- * @return object Horde_Kolab_Format_XML The format object
- */
- public static function get_format($type)
- {
- self::setup();
- return Horde_Kolab_Format::factory('XML', $type);
- }
-
- /**
- * Get a list of storage folders for the given data type
- *
- * @param string Data type to list folders for (contact,event,task,note)
- * @return array List of Kolab_Folder objects
- */
- public static function get_folders($type)
- {
- self::setup();
- $kolab = Kolab_List::singleton();
- return self::$ready ? $kolab->getByType($type) : array();
- }
-
- /**
- * Get storage object for read/write access to the Kolab backend
- *
- * @param string IMAP folder to access
- * @param string Object type to deal with (leave empty for auto-detection using annotations)
- * @return object Kolab_Data The data storage object
- */
- public static function get_storage($folder, $data_type = null)
- {
- self::setup();
- $kolab = Kolab_List::singleton();
- return self::$ready ? $kolab->getFolder($folder)->getData($data_type) : null;
- }
-
- /**
- * Cleanup session data when done
- */
- public static function shutdown()
- {
- // unset auth data from session. no need to store it persistantly
- if (isset($_SESSION['__auth']))
- unset($_SESSION['__auth']);
- }
-}