2 commits - plugins/kolab_config plugins/libkolab

Thomas Brüderli bruederli at kolabsys.com
Wed May 23 14:41:51 CEST 2012


 plugins/kolab_config/kolab_config.php                         |   81 ++-
 plugins/kolab_config/lib/configuration.php                    |   76 ---
 plugins/kolab_config/lib/kolab_configuration.php              |  241 ----------
 plugins/kolab_config/package.xml                              |   10 
 plugins/libkolab/lib/Horde_Kolab_Format_XML_configuration.php |   76 +++
 plugins/libkolab/lib/kolab_format.php                         |    3 
 plugins/libkolab/lib/kolab_format_configuration.php           |  121 +++++
 plugins/libkolab/lib/kolab_storage_folder.php                 |   35 -
 plugins/libkolab/libkolab.php                                 |    1 
 9 files changed, 292 insertions(+), 352 deletions(-)

New commits:
commit eca8ebafc32cf3261f5d91d7ac5ba8f7bfe836c1
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed May 23 14:41:32 2012 +0200

    Read (old) configuration.dictionary objects with new kolab_storage layer; writing not implemented yet, until libkolabxml supports it

diff --git a/plugins/kolab_config/kolab_config.php b/plugins/kolab_config/kolab_config.php
index b785306..518c001 100644
--- a/plugins/kolab_config/kolab_config.php
+++ b/plugins/kolab_config/kolab_config.php
@@ -8,8 +8,9 @@
  *
  * @version @package_version@
  * @author Machniak Aleksander <machniak at kolabsys.com>
+ * @author Thomas Bruederli <bruederli at kolabsys.com>
  *
- * Copyright (C) 2011, Kolab Systems AG <contact at kolabsys.com>
+ * Copyright (C) 2011-2012, Kolab Systems AG <contact at 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
@@ -29,8 +30,10 @@ 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
@@ -58,17 +61,26 @@ class kolab_config extends rcube_plugin
      */
     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;
         }
     }
@@ -89,7 +101,7 @@ class kolab_config extends rcube_plugin
         }
 
         $lang = $args['language'];
-        $dict = $this->dict;
+        $dict = $this->read_dictionary($lang, true);
 
         $dict['type']     = 'dictionary';
         $dict['language'] = $args['language'];
@@ -97,16 +109,16 @@ class kolab_config extends rcube_plugin
 
         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;
     }
 
     /**
@@ -125,14 +137,53 @@ class kolab_config extends rcube_plugin
         }
 
         $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 c80fbd3..0000000
--- 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 at kolabsys.com>
- *
- * Copyright (C) 2011, Kolab Systems AG <contact at 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 c936432..0000000
--- a/plugins/kolab_config/lib/kolab_configuration.php
+++ /dev/null
@@ -1,241 +0,0 @@
-<?php
-
-/**
- * Kolab configuration storage handler.
- *
- * @author Machniak Aleksander <machniak at kolabsys.com>
- *
- * Copyright (C) 2011, Kolab Systems AG <contact at 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 a0a2979..ac293b0 100644
--- a/plugins/kolab_config/package.xml
+++ b/plugins/kolab_config/package.xml
@@ -16,10 +16,10 @@
 		<email>machniak at 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>
@@ -34,8 +34,6 @@
 				<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>
@@ -48,7 +46,7 @@
 				<min>1.7.0</min>
 			</pearinstaller>
             <package>
-                <name>kolab_folders</name>
+                <name>libkolab</name>
                 <uri>http://kolabsys.com</uri>
             </package>
 		</required>
diff --git a/plugins/libkolab/lib/kolab_format_configuration.php b/plugins/libkolab/lib/kolab_format_configuration.php
new file mode 100644
index 0000000..5ef0fa7
--- /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 at kolabsys.com>
+ *
+ * Copyright (C) 2012, Kolab Systems AG <contact at 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 5d64dfb..4ecab46 100644
--- a/plugins/libkolab/libkolab.php
+++ b/plugins/libkolab/libkolab.php
@@ -56,6 +56,7 @@ class libkolab extends rcube_plugin
             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');
         }


commit 2cd801f7d0e779c1518e296dfc2740707f0c0c2c
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed May 23 14:34:08 2012 +0200

    Prepare to handle configuration objects

diff --git a/plugins/libkolab/lib/Horde_Kolab_Format_XML_configuration.php b/plugins/libkolab/lib/Horde_Kolab_Format_XML_configuration.php
new file mode 100644
index 0000000..c80fbd3
--- /dev/null
+++ b/plugins/libkolab/lib/Horde_Kolab_Format_XML_configuration.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * Kolab XML handler for configuration (KEP:9).
+ *
+ * @author  Aleksander Machniak <machniak at kolabsys.com>
+ *
+ * Copyright (C) 2011, Kolab Systems AG <contact at 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/libkolab/lib/kolab_format.php b/plugins/libkolab/lib/kolab_format.php
index b7ce057..883eb7f 100644
--- a/plugins/libkolab/lib/kolab_format.php
+++ b/plugins/libkolab/lib/kolab_format.php
@@ -51,12 +51,13 @@ abstract class kolab_format
         if (!isset(self::$timezone))
             self::$timezone = new DateTimeZone('UTC');
 
+        $type = preg_replace('/configuration\.[a-z.]+$/', 'configuration', $type);
         $suffix = preg_replace('/[^a-z]+/', '', $type);
         $classname = 'kolab_format_' . $suffix;
         if (class_exists($classname))
             return new $classname($xmldata);
 
-        return PEAR::raiseError(sprintf("Failed to load Kolab Format wrapper for type %s", $type));
+        return PEAR::raiseError("Failed to load Kolab Format wrapper for type " . $type);
     }
 
     /**
diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index da0718a..3d4c168 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -38,8 +38,14 @@ class kolab_storage_folder
     public $type;
 
     /**
-    * The attached cache object
-    * @var kolab_storage_cache
+     * Is this folder set to be the default for its type
+     * @var boolean
+     */
+    public $default = false;
+
+    /**
+     * Is this folder set to be default
+     * @var boolean
      */
     public $cache;
 
@@ -69,17 +75,20 @@ class kolab_storage_folder
      * @param string The folder name/path
      * @param string Optional folder type if known
      */
-    public function set_folder($name, $type = null)
+    public function set_folder($name, $ftype = null)
     {
-        if (!$type) {
+        if (!$ftype) {
             $metadata = $this->imap->get_metadata($name, array(kolab_storage::CTYPE_KEY));
-            $type     = $metadata[$name][kolab_storage::CTYPE_KEY];
+            $this->type_annotation = $metadata[$name][kolab_storage::CTYPE_KEY];
+        }
+        else {
+            $this->type_annotation = $ftype;
         }
 
-        $this->name            = $name;
-        $this->type_annotation = $type;
-        $this->type            = reset(explode('.', $type));
-        $this->resource_uri    = null;
+        list($this->type, $suffix) = explode('.', $this->type_annotation);
+        $this->default      = $suffix == 'default';
+        $this->name         = $name;
+        $this->resource_uri = null;
 
         $this->imap->set_folder($this->name);
         $this->cache->set_folder($this);
@@ -216,7 +225,6 @@ class kolab_storage_folder
         return $this->resource_uri;
     }
 
-
     /**
      * Check subscription status of this folder
      *
@@ -388,7 +396,7 @@ class kolab_storage_folder
         $this->imap->set_folder($folder);
 
         $headers = $this->imap->get_message_headers($msguid);
-        $object_type = substr($headers->others['x-kolab-type'], strlen(self::KTYPE_PREFIX));
+        $object_type = preg_replace('/dictionary.[a-z]+$/', 'dictionary', substr($headers->others['x-kolab-type'], strlen(self::KTYPE_PREFIX)));
         $content_type  = self::KTYPE_PREFIX . $object_type;
 
         // check object type header and abort on mismatch
@@ -430,9 +438,10 @@ class kolab_storage_folder
             return false;
 
         // check kolab format version
-        if (strpos($xml, '<' . $object_type) !== false) {
+        list($xmltype, $subtype) = explode('.', $object_type);
+        if (strpos($xml, '<' . $xmltype) !== false) {
             // old Kolab 2.0 format detected
-            $handler = class_exists('Horde_Kolab_Format') ? Horde_Kolab_Format::factory('XML', $object_type) : null;
+            $handler = class_exists('Horde_Kolab_Format') ? Horde_Kolab_Format::factory('XML', $xmltype, array('subtype' => $subtype)) : null;
             if (!is_object($handler) || is_a($handler, 'PEAR_Error')) {
                 return false;
             }





More information about the commits mailing list