Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F9785410
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/plugins/kolab_config/kolab_config.php b/plugins/kolab_config/kolab_config.php
index b785306b..518c0011 100644
--- a/plugins/kolab_config/kolab_config.php
+++ b/plugins/kolab_config/kolab_config.php
@@ -1,138 +1,189 @@
<?php
/**
* Kolab configuration storage.
*
* Plugin to use Kolab server as a configuration storage. Provides an API to handle
* configuration according to http://wiki.kolab.org/KEP:9.
*
* @version @package_version@
* @author Machniak Aleksander <machniak@kolabsys.com>
+ * @author Thomas Bruederli <bruederli@kolabsys.com>
*
- * Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
+ * Copyright (C) 2011-2012, Kolab Systems AG <contact@kolabsys.com>
*
* 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.
*
* 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
* GNU Affero General Public License for more details.
*
* 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/>.
*/
class kolab_config extends rcube_plugin
{
public $task = 'utils';
- private $config;
private $enabled;
+ private $default;
+ private $folders;
+ private $dicts = array();
/**
* Required startup method of a Roundcube plugin
*/
public function init()
{
$rcmail = rcmail::get_instance();
// Register spellchecker dictionary handlers
if (strtolower($rcmail->config->get('spellcheck_dictionary')) != 'shared') {
$this->add_hook('spell_dictionary_save', array($this, 'dictionary_save'));
$this->add_hook('spell_dictionary_get', array($this, 'dictionary_get'));
}
/*
// Register addressbook saved searches handlers
$this->add_hook('saved_search_create', array($this, 'saved_search_create'));
$this->add_hook('saved_search_delete', array($this, 'saved_search_delete'));
$this->add_hook('saved_search_list', array($this, 'saved_search_list'));
$this->add_hook('saved_search_get', array($this, 'saved_search_get'));
*/
}
/**
* Initializes config object and dependencies
*/
private function load()
{
- if ($this->config)
+ // nothing to be done here
+ if (isset($this->folders))
return;
- return; // CURRENTLY DISABLED until libkolabxml has support for config objects
-
$this->require_plugin('libkolab');
- $this->config = new kolab_configuration();
+ $this->folders = kolab_storage::get_folders('configuration');
+ foreach ($this->folders as $i => $folder) {
+ if ($folder->default) {
+ $this->default = $folder;
+ break;
+ }
+ }
+
+ // if no folder is set as default, choose the first one
+ if (!$this->default)
+ $this->default = $this->folders[0];
// check if configuration folder exist
- if (strlen($this->config->dir)) {
+ if ($this->default && $this->default->name) {
$this->enabled = true;
}
}
/**
* Saves spellcheck dictionary.
*
* @param array $args Hook arguments
*
* @return array Hook arguments
*/
public function dictionary_save($args)
{
$this->load();
if (!$this->enabled) {
return $args;
}
$lang = $args['language'];
- $dict = $this->dict;
+ $dict = $this->read_dictionary($lang, true);
$dict['type'] = 'dictionary';
$dict['language'] = $args['language'];
$dict['e'] = $args['dictionary'];
if (empty($dict['e'])) {
// Delete the object
- $this->config->del($dict);
+ $this->default->delete($dict);
}
else {
// Update the object
- $this->config->set($dict);
+ // $this->default->save($dict);
}
$args['abort'] = true;
- return $args;
+ return $args;
}
/**
* Returns spellcheck dictionary.
*
* @param array $args Hook arguments
*
* @return array Hook arguments
*/
public function dictionary_get($args)
{
$this->load();
if (!$this->enabled) {
return $args;
}
$lang = $args['language'];
- $this->dict = $this->config->get('dictionary.'.$lang);
+ $dict = $this->read_dictionary($lang);
- if (!empty($this->dict)) {
- $args['dictionary'] = $this->dict['e'];
+ if (!empty($dict)) {
+ $args['dictionary'] = (array)$dict['e'];
}
$args['abort'] = true;
- return $args;
+ return $args;
+ }
+
+ /**
+ * Load dictionary config objects from Kolab storage
+ *
+ * @param string The language (2 chars) to load
+ * @param boolean Only load objects from default folder
+ * @return array Dictionary object as hash array
+ */
+ private function read_dictionary($lang, $default = false)
+ {
+ if (isset($this->dicts[$lang]))
+ return $this->dicts[$lang];
+
+ $query = array(array('type','=','configuration.dictionary'), array('tags','=',' '.$lang.' '));
+
+ foreach ($this->folders as $folder) {
+ // we only want to read from default folder
+ if ($default && !$folder->default)
+ continue;
+
+ foreach ((array)$folder->select($query) as $object) {
+ if ($object['type'] == 'dictionary' && $object['language'] == $lang) {
+
+ if (is_array($this->dicts[$lang]))
+ $this->dicts[$lang]['e'] = array_merge((array)$this->dicts[$lang]['e'], $object['e']);
+ else
+ $this->dicts[$lang] = $object;
+
+ // make sure the default object is cached
+ if ($folder->default) {
+ $object['e'] = $this->dicts[$lang]['e'];
+ $this->dicts[$lang] = $object;
+ }
+ }
+ }
+ }
+
+ return $this->dicts[$lang];
}
}
diff --git a/plugins/kolab_config/lib/configuration.php b/plugins/kolab_config/lib/configuration.php
deleted file mode 100644
index c80fbd3d..00000000
--- a/plugins/kolab_config/lib/configuration.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-
-/**
- * Kolab XML handler for configuration (KEP:9).
- *
- * @author Aleksander Machniak <machniak@kolabsys.com>
- *
- * Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
- *
- * 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.
- *
- * 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
- * GNU Affero General Public License for more details.
- *
- * 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/>.
- */
-class Horde_Kolab_Format_XML_configuration extends Horde_Kolab_Format_XML {
- /**
- * Specific data fields for the configuration object
- *
- * @var Kolab
- */
- var $_fields_specific;
-
- var $_root_version = 2.1;
-
- /**
- * Constructor
- */
- function Horde_Kolab_Format_XML_configuration($params = array())
- {
- $this->_root_name = 'configuration';
-
- // Specific configuration fields, in kolab format specification order
- $this->_fields_specific = array(
- 'application' => array (
- 'type' => HORDE_KOLAB_XML_TYPE_STRING,
- 'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
- ),
- 'type' => array(
- 'type' => HORDE_KOLAB_XML_TYPE_STRING,
- 'value' => HORDE_KOLAB_XML_VALUE_NOT_EMPTY,
- ),
- );
-
- // Dictionary fields
- if (!empty($params['subtype']) && preg_match('/^dictionary.*/', $params['subtype'])) {
- $this->_fields_specific = array_merge($this->_fields_specific, array(
- 'language' => array (
- 'type' => HORDE_KOLAB_XML_TYPE_STRING,
- 'value' => HORDE_KOLAB_XML_VALUE_NOT_EMPTY,
- ),
- 'e' => array(
- 'type' => HORDE_KOLAB_XML_TYPE_MULTIPLE,
- 'value' => HORDE_KOLAB_XML_VALUE_NOT_EMPTY,
- 'array' => array(
- 'type' => HORDE_KOLAB_XML_TYPE_STRING,
- 'value' => HORDE_KOLAB_XML_VALUE_NOT_EMPTY,
- ),
- ),
- ));
- }
-
- parent::Horde_Kolab_Format_XML($params);
-
- unset($this->_fields_basic['body']);
- unset($this->_fields_basic['categories']);
- unset($this->_fields_basic['sensitivity']);
- }
-}
diff --git a/plugins/kolab_config/lib/kolab_configuration.php b/plugins/kolab_config/lib/kolab_configuration.php
deleted file mode 100644
index c936432c..00000000
--- a/plugins/kolab_config/lib/kolab_configuration.php
+++ /dev/null
@@ -1,241 +0,0 @@
-<?php
-
-/**
- * Kolab configuration storage handler.
- *
- * @author Machniak Aleksander <machniak@kolabsys.com>
- *
- * Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
- *
- * 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.
- *
- * 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
- * GNU Affero General Public License for more details.
- *
- * 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/>.
- */
-class kolab_configuration
-{
- public $dir;
- private $rc;
- private $imap_data = array();
-
- /**
- * Class constructor. Establishes IMAP connection.
- */
- public function __construct()
- {
- $this->rc = rcmail::get_instance();
-
- // Connect to IMAP
- $this->rc->imap_connect();
-
- // Get default configuration directory
- // @TODO: handle many config directories, according to KEP:9
- $dirs = $this->rc->imap->list_unsubscribed('', '*', 'configuration');
- $this->dir = array_shift($dirs);
- }
-
- /**
- * Returns configuration object
- *
- * @param string $type Configuration object type
- *
- * @return array Configuration object
- */
- public function get($type)
- {
- // If config folder exists
- if (isset($this->dir[0])) {
- // search by object type
- // @TODO: configuration folders shouldn't be big, consider
- // caching of all objects, then if we extend cache with object type
- // column we could simply search in cache.
- // @TODO: handle many config directories, according to KEP:9
- $ctype = 'application/x-vnd.kolab.configuration' . ($type ? '.'.$type : '');
- $search = 'HEADER X-Kolab-Type ' . $ctype;
-
- $this->set_imap_props();
- $this->rc->imap->search($this->dir, $search, 'US-ASCII', 'date');
-
- $list = $this->rc->imap->list_headers($this->dir, 1, 'date', 'DESC');
- $this->reset_imap_props();
-
- foreach ($list as $idx => $obj) {
- // @TODO: maybe we could skip parsing the message structure and
- // get second part's body directly
- $msg = new rcube_message($obj->uid);
- $xml = null;
-
- // get XML part
- foreach ((array)$msg->attachments as $part) {
- if ($part->mimetype == 'application/xml') {
- if (!$part->body)
- $part->body = $msg->get_part_content($part->mime_id);
- $xml = $part->body;
- break;
- }
- }
-
- // that shouldn't happen
- if ($xml === null) {
- continue;
- }
-
- // Load XML object parser
- $handler = Horde_Kolab_Format::factory('XML', 'configuration', array('subtype' => $type));
- if (is_object($handler) && is_a($handler, 'PEAR_Error')) {
- return null;
- }
-
- // XML-to-array
- $object = $handler->load($xml);
-
- if (is_object($object) && is_a($object, 'PEAR_Error')) {
- return null;
- }
-
- $object['mailbox'] = $this->dir;
- $object['msguid'] = $obj->uid;
-
- return $object;
- }
- }
- }
-
- /**
- * Saves configuration object
- *
- * @param array $object Configuration object
- *
- * @return bool True on success, False on failre
- */
- public function set($object)
- {
- $object['uid'] = md5(uniqid(mt_rand(), true));
- $raw_msg = $this->build_message($object);
-
- if ($raw_msg && isset($this->dir[0])) {
- $result = $this->rc->imap->save_message($this->dir, $raw_msg, '', false);
- }
-
- // delete old message
- if ($result && !empty($object['msguid'])) {
- $this->rc->imap->delete_message($object['msguid'], $object['mailbox']);
- }
-
- return $result;
- }
-
- /**
- * Deletes configuration object
- *
- * @param array $object Configuration object
- *
- * @return bool True on success, False on failre
- */
- public function del($object)
- {
- if (!empty($object['msguid'])) {
- return $this->rc->imap->delete_message($object['msguid'], $object['mailbox']);
- }
-
- return true;
- }
-
- /**
- * Sets some rcube_imap settings before searching for config objects
- */
- private function set_imap_props()
- {
- // Save old settings
- $this->imap_data = array(
- 'skip_deleted' => $skip_deleted,
- 'page_size' => $page_size,
- 'list_page' => $list_page,
- 'threading' => $threading,
- );
-
- // Configure for configuration folder
- $this->rc->imap->skip_deleted = true;
- $this->rc->imap->threading = false;
- $this->rc->imap->page_size = 100;
- $this->rc->imap->list_page = 1;
- }
-
- /**
- * Resets rcube_imap settings after searching for config objects
- */
- private function reset_imap_props()
- {
- // Reset to old settings
- foreach ($this->imap_data as $key => $val) {
- $this->rc->imap->$key = $val;
- }
- // reset saved search
- $this->rc->imap->search_set = null;
- }
-
- /**
- * Creates source of the configuration object message
- */
- private function build_message($object)
- {
- $MAIL_MIME = new Mail_mime("\r\n");
-
- $name = 'configuration';
-
- if (!empty($object['type'])) {
- $name .= '.' . $object['type'];
- if ($object['type'] == 'dictionary' && !empty($object['language'])) {
- $name .= '.' . $object['language'];
- }
- }
-
- $handler = Horde_Kolab_Format::factory('XML', 'configuration',
- array('subtype' => $object['type']));
-
- if (is_object($handler) && is_a($handler, 'PEAR_Error')) {
- return false;
- }
-
- $xml = $handler->save($object);
-
- if (is_object($xml) && is_a($xml, 'PEAR_Error')) {
- return false;
- }
-
- if ($ident = $this->rc->user->get_identity()) {
- $headers['From'] = $ident['email'];
- $headers['To'] = $ident['email'];
- }
- $headers['Date'] = date('r');
- $headers['X-Kolab-Type'] = 'application/x-vnd.kolab.'.$name;
- $headers['Subject'] = $object['uid'];
- $headers['Message-ID'] = rcmail_gen_message_id();
- $headers['User-Agent'] = $this->rc->config->get('useragent');
-
- $MAIL_MIME->headers($headers);
- $MAIL_MIME->setTXTBody('This is a Kolab Groupware object. '
- .'To view this object you will need an email client that understands the Kolab Groupware format. '
- .'For a list of such email clients please visit http://www.kolab.org/kolab2-clients.html');
-
- $MAIL_MIME->addAttachment($xml,
- 'application/xml',
- $name . '.xml',
- false, '8bit', 'attachment', RCMAIL_CHARSET, '', '',
- $this->rc->config->get('mime_param_folding') ? 'quoted-printable' : null,
- $this->rc->config->get('mime_param_folding') == 2 ? 'quoted-printable' : null,
- '', RCMAIL_CHARSET
- );
-
- return $MAIL_MIME->getMessage();
- }
-
-}
diff --git a/plugins/kolab_config/package.xml b/plugins/kolab_config/package.xml
index a0a29796..ac293b0e 100644
--- a/plugins/kolab_config/package.xml
+++ b/plugins/kolab_config/package.xml
@@ -1,57 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd">
<name>kolab_config</name>
<uri>http://git.kolab.org/roundcubemail-plugins-kolab/</uri>
<summary>Kolab configuration storage</summary>
<description>
Plugin to use Kolab server as a configuration storage. Provides an API to handle
configuration according to http://wiki.kolab.org/KEP:9.
</description>
<lead>
<name>Aleksander Machniak</name>
<user>machniak</user>
<email>machniak@kolabsys.com</email>
<active>yes</active>
</lead>
- <date>2011-11-01</date>
+ <date>2012-05-23</date>
<version>
- <release>1.0</release>
- <api>1.0</api>
+ <release>2.0</release>
+ <api>2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.gnu.org/licenses/agpl.html">GNU AGPLv3</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
<file name="kolab_config.php" role="php">
<tasks:replace from="@name@" to="name" type="package-info"/>
<tasks:replace from="@package_version@" to="version" type="package-info"/>
</file>
<file name="LICENSE" role="data"></file>
- <file name="lib/configuration.php" role="php"></file>
- <file name="lib/kolab_configuration.php" role="php"></file>
</dir>
<!-- / -->
</contents>
<dependencies>
<required>
<php>
<min>5.2.1</min>
</php>
<pearinstaller>
<min>1.7.0</min>
</pearinstaller>
<package>
- <name>kolab_folders</name>
+ <name>libkolab</name>
<uri>http://kolabsys.com</uri>
</package>
</required>
</dependencies>
<phprelease/>
</package>
diff --git a/plugins/libkolab/lib/kolab_format_configuration.php b/plugins/libkolab/lib/kolab_format_configuration.php
new file mode 100644
index 00000000..5ef0fa77
--- /dev/null
+++ b/plugins/libkolab/lib/kolab_format_configuration.php
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * Kolab Configuration data model class
+ *
+ * @version @package_version@
+ * @author Thomas Bruederli <bruederli@kolabsys.com>
+ *
+ * Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
+ *
+ * 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.
+ *
+ * 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
+ * GNU Affero General Public License for more details.
+ *
+ * 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/>.
+ */
+
+class kolab_format_configuration extends kolab_format
+{
+ public $CTYPE = 'application/x-vnd.kolab.configuration';
+
+ protected $read_func = 'kolabformat::readConfiguration';
+ protected $write_func = 'kolabformat::writeConfiguration';
+
+
+ function __construct($xmldata = null)
+ {
+ $this->obj = new Configuration;
+ $this->xmldata = $xmldata;
+ }
+
+ /**
+ * Set properties to the kolabformat object
+ *
+ * @param array Object data as hash array
+ */
+ public function set(&$object)
+ {
+ $this->init();
+
+ // set some automatic values if missing
+# if (!empty($object['uid']))
+# $this->obj->setUid($object['uid']);
+
+ // TODO: set object propeties
+
+ // cache this data
+ $this->data = $object;
+ unset($this->data['_formatobj']);
+ }
+
+ /**
+ *
+ */
+ public function is_valid()
+ {
+ return $this->data || (is_object($this->obj)/* && $this->obj->isValid()*/);
+ }
+
+ /**
+ * Load data from old Kolab2 format
+ */
+ public function fromkolab2($record)
+ {
+ $object = array(
+ 'uid' => $record['uid'],
+ 'changed' => $record['last-modification-date'],
+ );
+
+ $this->data = $object + $record;
+ }
+
+ /**
+ * Convert the Configuration object into a hash array data structure
+ *
+ * @return array Config object data as hash array
+ */
+ public function to_array()
+ {
+ // return cached result
+ if (!empty($this->data))
+ return $this->data;
+
+ $this->init();
+
+ // read object properties
+ $object = array(
+# 'uid' => $this->obj->uid(),
+# 'changed' => $this->obj->lastModified(),
+ );
+
+
+ // TODO: read object properties
+
+ $this->data = $object;
+ return $this->data;
+ }
+
+ /**
+ * Callback for kolab_storage_cache to get object specific tags to cache
+ *
+ * @return array List of tags to save in cache
+ */
+ public function get_tags()
+ {
+ $tags = array();
+
+ if ($this->data['type'] == 'dictionary')
+ $tags = array($this->data['language']);
+
+ return $tags;
+ }
+
+}
diff --git a/plugins/libkolab/libkolab.php b/plugins/libkolab/libkolab.php
index 5d64dfb4..4ecab46a 100644
--- a/plugins/libkolab/libkolab.php
+++ b/plugins/libkolab/libkolab.php
@@ -1,74 +1,75 @@
<?php
/**
* Kolab core library
*
* Plugin to setup a basic environment for the interaction with a Kolab server.
* Other Kolab-related plugins will depend on it and can use the library classes
*
* @version @package_version@
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
*
* 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.
*
* 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
* GNU Affero General Public License for more details.
*
* 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/>.
*/
class libkolab extends rcube_plugin
{
/**
* Required startup method of a Roundcube plugin
*/
public function init()
{
// load local config
$this->load_config();
$this->add_hook('storage_init', array($this, 'storage_init'));
// extend include path to load bundled lib classes
$include_path = $this->home . '/lib' . PATH_SEPARATOR . ini_get('include_path');
set_include_path($include_path);
$rcmail = rcmail::get_instance();
try {
kolab_format::$timezone = new DateTimeZone($rcmail->config->get('timezone', 'GMT'));
}
catch (Exception $e) {
raise_error($e, true);
kolab_format::$timezone = new DateTimeZone('GMT');
}
// load (old) dependencies if available
if (@include_once('Horde/Util.php')) {
include_once 'Horde/Kolab/Format.php';
include_once 'Horde/Kolab/Format/XML.php';
include_once 'Horde/Kolab/Format/XML/contact.php';
include_once 'Horde/Kolab/Format/XML/event.php';
+ include_once 'Horde_Kolab_Format_XML_configuration.php';
String::setDefaultCharset('UTF-8');
}
}
/**
* Hook into IMAP FETCH HEADER.FIELDS command and request Kolab-specific headers
*/
function storage_init($p)
{
$p['fetch_headers'] = trim($p['fetch_headers'] .' X-KOLAB-TYPE');
return $p;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Aug 17, 2:21 PM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1256999
Default Alt Text
(25 KB)
Attached To
Mode
R14 roundcubemail-plugins-kolab
Attached
Detach File
Event Timeline
Log In to Comment