Completed Kolab_Format PHP5 cleanup.
authorGunnar Wrobel <p@rdus.de>
Mon, 29 Jun 2009 03:52:03 +0000 (05:52 +0200)
committerGunnar Wrobel <p@rdus.de>
Mon, 29 Jun 2009 03:55:27 +0000 (05:55 +0200)
17 files changed:
framework/Kolab_Format/lib/Horde/Kolab/Format.php
framework/Kolab_Format/lib/Horde/Kolab/Format/Date.php
framework/Kolab_Format/lib/Horde/Kolab/Format/XML.php
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Annotation.php [new file with mode: 0644]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Contact.php [new file with mode: 0644]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Distributionlist.php [new file with mode: 0644]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Event.php [new file with mode: 0644]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Hprefs.php [new file with mode: 0644]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Note.php [new file with mode: 0644]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Task.php [new file with mode: 0644]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/annotation.php [deleted file]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/contact.php [deleted file]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/distributionlist.php [deleted file]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/event.php [deleted file]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/hprefs.php [deleted file]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/note.php [deleted file]
framework/Kolab_Format/lib/Horde/Kolab/Format/XML/task.php [deleted file]

index d2dd7e5..98fc90d 100644 (file)
@@ -2,38 +2,46 @@
 /**
  * A library for reading/writing the Kolab format.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format.php,v 1.7 2008/12/12 11:25:52 wrobel Exp $
+ * PHP version 5
  *
- * @package Kolab_Format
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
  */
 
-/** We need PEAR */
-require_once 'PEAR.php';
+/**
+ * The Autoloader allows us to omit "require/include" statements.
+ */
+require_once 'Horde/Autoloader.php';
 
 /**
  * The Horde_Kolab_Format:: class provides the means to read/write the
  * Kolab format.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format.php,v 1.7 2008/12/12 11:25:52 wrobel Exp $
- *
- * Copyright 2007-2008 Klarälvdalens Datakonsult AB
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
- * @since   Horde 3.2
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
  */
-class Horde_Kolab_Format
+abstract class Horde_Kolab_Format
 {
 
     /**
-     * Attempts to return a concrete Horde_Kolab_Format instance based on $format_type.
+     * Attempts to return a concrete Horde_Kolab_Format instance based on
+     * $format_type.
      *
-     * @param string    $format_type    The format type that should be handled.
-     * @param string    $object_type    The object type that should be handled.
-     * @param array     $params         An array of  additional parameters.
+     * @param string $format_type The format type that should be handled.
+     * @param string $object_type The object type that should be handled.
+     * @param array  $params      An array of  additional parameters.
      *
      *                                  Supported parameters:
      *
@@ -41,18 +49,65 @@ class Horde_Kolab_Format
      *
      * @return mixed    The newly created concrete Horde_Kolab_Format_XML instance, or
      *                  a PEAR error.
+     *
+     * @throws Horde_Exception If the specified driver could not be loaded.
      */
-    function &factory($format_type = '', $object_type = '', $params = null)
+    static public function &factory($format_type = '', $object_type = '',
+                                    $params = null)
     {
-        @include_once dirname(__FILE__) . '/Format/' . $format_type . '.php';
         $class = 'Horde_Kolab_Format_' . $format_type;
         if (class_exists($class)) {
-            $driver = call_user_func(array($class, 'factory'), $object_type, $params);
+            $driver = call_user_func(array($class, 'factory'), $object_type,
+                                     $params);
         } else {
-            return PEAR::raiseError(sprintf(_("Failed to load Kolab Format driver %s"), $format_type));
+            throw new Horde_Exception(sprintf(_("Failed to load Kolab Format driver %s"),
+                                              $format_type));
         }
 
         return $driver;
     }
 
+    /**
+     * Return the name of the resulting document.
+     *
+     * @return string The name that may be used as filename.
+     */
+    abstract public function getName();
+
+    /**
+     * Return the mime type of the resulting document.
+     *
+     * @return string The mime type of the result.
+     */
+    abstract public function getMimeType();
+
+    /**
+     * Return the disposition of the resulting document.
+     *
+     * @return string The disportion of this document.
+     */
+    abstract public function getDisposition();
+
+    /**
+     * Load an object based on the given XML string.
+     *
+     * @param string &$xmltext The XML of the message as string.
+     *
+     * @return array The data array representing the object.
+     *
+     * @throws Horde_Exception
+     */
+    abstract public function load(&$xmltext);
+
+    /**
+     * Convert the data to a XML string.
+     *
+     * @param array $object The data array representing the note.
+     *
+     * @return string The data as XML string.
+     *
+     * @throws Horde_Exception
+     */
+    abstract public function save($object);
+
 }
index 8a1a622..a07226c 100644 (file)
@@ -2,24 +2,30 @@
 /**
  * Helper functions to handle format conversions.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/Date.php,v 1.6 2009/01/06 17:49:22 jan Exp $
+ * PHP version 5
  *
- * @package Kolab_Format
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Stuart Binge <omicron@mighty.co.za>
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
  */
 
 /**
  * Kolab date handling functions. Based upon Kolab.php from Stuart Binge.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/Date.php,v 1.6 2009/01/06 17:49:22 jan Exp $
- *
  * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
- * @author  Stuart Binge <omicron@mighty.co.za>
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @package Kolab_Format
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Stuart Binge <omicron@mighty.co.za>
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @license  http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
  */
 class Horde_Kolab_Format_Date
 {
@@ -27,11 +33,11 @@ class Horde_Kolab_Format_Date
      * Returns a UNIX timestamp corresponding the given date string which is in
      * the format prescribed by the Kolab Format Specification.
      *
-     * @param string $date  The string representation of the date.
+     * @param string $date The string representation of the date.
      *
      * @return integer  The unix timestamp corresponding to $date.
      */
-    function decodeDate($date)
+    static public function decodeDate($date)
     {
         if (empty($date)) {
             return 0;
@@ -46,18 +52,18 @@ class Horde_Kolab_Format_Date
      * Returns a UNIX timestamp corresponding the given date-time string which
      * is in the format prescribed by the Kolab Format Specification.
      *
-     * @param string $datetime  The string representation of the date & time.
+     * @param string $datetime The string representation of the date & time.
      *
      * @return integer  The unix timestamp corresponding to $datetime.
      */
-    function decodeDateTime($datetime)
+    static public function decodeDateTime($datetime)
     {
         if (empty($datetime)) {
             return 0;
         }
 
-        list($year, $month, $day, $hour, $minute, $second)
-            = sscanf($datetime, '%d-%d-%dT%d:%d:%dZ');
+        list($year, $month, $day, $hour, $minute, $second) = sscanf($datetime,
+                                                                    '%d-%d-%dT%d:%d:%dZ');
         return gmmktime($hour, $minute, $second, $month, $day, $year);
     }
 
@@ -66,11 +72,11 @@ class Horde_Kolab_Format_Date
      * string which is in either format prescribed by the Kolab Format
      * Specification.
      *
-     * @param string $date  The string representation of the date (& time).
+     * @param string $date The string representation of the date (& time).
      *
      * @return integer  The unix timestamp corresponding to $date.
      */
-    function decodeDateOrDateTime($date)
+    static public function decodeDateOrDateTime($date)
     {
         if (empty($date)) {
             return 0;
@@ -83,9 +89,11 @@ class Horde_Kolab_Format_Date
      * Returns a string containing the current UTC date in the format
      * prescribed by the Kolab Format Specification.
      *
+     * @param int $date The integer representation of the date.
+     *
      * @return string  The current UTC date in the format 'YYYY-MM-DD'.
      */
-    function encodeDate($date = false)
+    static public function encodeDate($date = false)
     {
         if ($date === false) {
             $date = time();
@@ -98,11 +106,13 @@ class Horde_Kolab_Format_Date
      * Returns a string containing the current UTC date and time in the format
      * prescribed by the Kolab Format Specification.
      *
+     * @param int $datetime The integer representation of the date.
+     *
      * @return string    The current UTC date and time in the format
      *                   'YYYY-MM-DDThh:mm:ssZ', where the T and Z are literal
      *                   characters.
      */
-    function encodeDateTime($datetime = false)
+    static public function encodeDateTime($datetime = false)
     {
         if ($datetime === false) {
             $datetime = time();
index 755e9a6..41be0fa 100644 (file)
 /**
  * Implementation of the Kolab XML format.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML.php,v 1.16 2009/04/08 18:32:15 wrobel Exp $
+ * PHP version 5
  *
- * @package Kolab_Format
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
  */
 
 /** We need the DOM library for XML access. */
 require_once 'Horde/DOM.php';
 
-/** We need the String library for string conversions. */
-require_once 'Horde/String.php';
-
 /** We need the NLS library for language support. */
 require_once 'Horde/NLS.php';
 
-/** Kolab date handling functions. */
-require_once 'Horde/Kolab/Format/Date.php';
-
 /**
- * Defines a XML value that should get a default value if missing
+ * Kolab XML to array hash converter.
+ *
+ * For implementing a new format type you will have to inherit this
+ * class and provide a _load/_save function.
+ *
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
  */
-define('HORDE_KOLAB_XML_PRODUCT_ID', 'Horde::Kolab');
+class Horde_Kolab_Format_XML
+{
 
-/**
- * Defines a XML value that should get a default value if missing
- */
-define('HORDE_KOLAB_XML_VALUE_DEFAULT', 0);
+    /**
    * Defines a XML value that should get a default value if missing
    */
+    const PRODUCT_ID = 'Horde::Kolab';
 
-/**
* Defines a XML value that may be missing
- */
-define('HORDE_KOLAB_XML_VALUE_MAYBE_MISSING', 1);
+    /**
    * Defines a XML value that should get a default value if missing
    */
+    const VALUE_DEFAULT = 0;
 
-/**
* Defines a XML value that may not be missing
- */
-define('HORDE_KOLAB_XML_VALUE_NOT_EMPTY', 2);
+    /**
    * Defines a XML value that may be missing
    */
+    const VALUE_MAYBE_MISSING = 1;
 
-/**
- * Defines a XML value that will be calculated by its own function
- */
-define('HORDE_KOLAB_XML_VALUE_CALCULATED', 3);
+    /**
+     * Defines a XML value that may not be missing
    */
+    const VALUE_NOT_EMPTY = 2;
 
-/**
- * Defines a XML value as string type
- */
-define('HORDE_KOLAB_XML_TYPE_STRING', 0);
+    /**
+     * Defines a XML value that will be calculated by its own function
    */
+    const VALUE_CALCULATED = 3;
 
-/**
* Defines a XML value as integer type
- */
-define('HORDE_KOLAB_XML_TYPE_INTEGER', 1);
+    /**
    * Defines a XML value as string type
    */
+    const TYPE_STRING = 0;
 
-/**
* Defines a XML value as boolean type
- */
-define('HORDE_KOLAB_XML_TYPE_BOOLEAN', 2);
+    /**
    * Defines a XML value as integer type
    */
+    const TYPE_INTEGER = 1;
 
-/**
* Defines a XML value as date type
- */
-define('HORDE_KOLAB_XML_TYPE_DATE', 3);
+    /**
    * Defines a XML value as boolean type
    */
+    const TYPE_BOOLEAN = 2;
 
-/**
* Defines a XML value as datetime type
- */
-define('HORDE_KOLAB_XML_TYPE_DATETIME', 4);
+    /**
    * Defines a XML value as date type
    */
+    const TYPE_DATE = 3;
 
-/**
* Defines a XML value as date or datetime type
- */
-define('HORDE_KOLAB_XML_TYPE_DATE_OR_DATETIME', 5);
+    /**
    * Defines a XML value as datetime type
    */
+    const TYPE_DATETIME = 4;
 
-/**
* Defines a XML value as color type
- */
-define('HORDE_KOLAB_XML_TYPE_COLOR', 6);
+    /**
    * Defines a XML value as date or datetime type
    */
+    const TYPE_DATE_OR_DATETIME = 5;
 
-/**
* Defines a XML value as composite value type
- */
-define('HORDE_KOLAB_XML_TYPE_COMPOSITE', 7);
+    /**
    * Defines a XML value as color type
    */
+    const TYPE_COLOR = 6;
 
-/**
- * Defines a XML value as array type
- */
-define('HORDE_KOLAB_XML_TYPE_MULTIPLE', 8);
+    /**
+     * Defines a XML value as composite value type
+     */
+    const TYPE_COMPOSITE = 7;
+
+    /**
+     * Defines a XML value as array type
+     */
+    const TYPE_MULTIPLE = 8;
 
-/**
- * Kolab XML to array hash converter.
- *
- * For implementing a new format type you will have to inherit this
- * class and provide a _load/_save function.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML.php,v 1.16 2009/04/08 18:32:15 wrobel Exp $
- *
- * Copyright 2007-2008 Klarälvdalens Datakonsult AB
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML
-{
     /**
      * Requested version of the data array to return
      *
      * @var int
      */
-    var $_version = 1;
+    protected $_version = 1;
 
     /**
      * The name of the resulting document.
      *
      * @var string
      */
-    var $_name = 'kolab.xml';
+    protected $_name = 'kolab.xml';
 
     /**
      * The XML document this driver works with.
      *
      * @var Horde_DOM_Document
      */
-        var $_xmldoc = null;
+    protected $_xmldoc = null;
 
     /**
      * The name of the root element.
      *
      * @var string
      */
-    var $_root_name = 'kolab';
+    protected $_root_name = 'kolab';
 
     /**
      * Kolab format version of the root element.
      *
      * @var string
      */
-    var $_root_version = '1.0';
+    protected $_root_version = '1.0';
 
     /**
      * Basic fields in any Kolab object
      *
      * @var array
      */
-    var $_fields_basic;
+    protected $_fields_basic;
 
     /**
      * Automatically create categories if they are missing?
      *
      * @var boolean
      */
-    var $_create_categories = true;
+    protected $_create_categories = true;
 
     /**
      * Fields for a simple person
      *
      * @var array
      */
-    var $_fields_simple_person = array(
-        'type'    => HORDE_KOLAB_XML_TYPE_COMPOSITE,
-        'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+    protected $_fields_simple_person = array(
+        'type'    => self::TYPE_COMPOSITE,
+        'value'   => self::VALUE_MAYBE_MISSING,
         'array'   => array(
             'display-name' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
                 'default' => '',
             ),
             'smtp-address' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
                 'default' => '',
             ),
             'uid' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
                 'default' => '',
             ),
         ),
@@ -190,37 +191,37 @@ class Horde_Kolab_Format_XML
      *
      * @var array
      */
-    var $_fields_attendee = array(
-        'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-        'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+    protected $_fields_attendee = array(
+        'type'    => self::TYPE_MULTIPLE,
+        'value'   => self::VALUE_DEFAULT,
         'default' => array(),
         'array'   => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_COMPOSITE,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            'type'    => self::TYPE_COMPOSITE,
+            'value'   => self::VALUE_MAYBE_MISSING,
             'array'   => array(
                 'display-name' => array(
-                    'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                    'type'    => self::TYPE_STRING,
+                    'value'   => self::VALUE_DEFAULT,
                     'default' => '',
                 ),
                 'smtp-address' => array(
-                    'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                    'type'    => self::TYPE_STRING,
+                    'value'   => self::VALUE_DEFAULT,
                     'default' => '',
                 ),
                 'status' => array(
-                    'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                    'type'    => self::TYPE_STRING,
+                    'value'   => self::VALUE_DEFAULT,
                     'default' => 'none',
                 ),
                 'request-response' => array(
-                    'type'    => HORDE_KOLAB_XML_TYPE_BOOLEAN,
-                    'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                    'type'    => self::TYPE_BOOLEAN,
+                    'value'   => self::VALUE_DEFAULT,
                     'default' => true,
                 ),
                 'role' => array(
-                    'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                    'type'    => self::TYPE_STRING,
+                    'value'   => self::VALUE_DEFAULT,
                     'default' => 'required',
                 ),
             ),
@@ -232,59 +233,59 @@ class Horde_Kolab_Format_XML
      *
      * @var array
      */
-    var $_fields_recurrence = array(
+    protected $_fields_recurrence = array(
         // Attribute on root node: cycle
         // Attribute on root node: type
         'interval' => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_INTEGER,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            'type'    => self::TYPE_INTEGER,
+            'value'   => self::VALUE_MAYBE_MISSING,
         ),
         'day' => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            'type'    => self::TYPE_MULTIPLE,
+            'value'   => self::VALUE_MAYBE_MISSING,
             'array'   => array(
-                'type' => HORDE_KOLAB_XML_TYPE_STRING,
-                'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                'type' => self::TYPE_STRING,
+                'value' => self::VALUE_MAYBE_MISSING,
             ),
         ),
         'daynumber' => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_INTEGER,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            'type'    => self::TYPE_INTEGER,
+            'value'   => self::VALUE_MAYBE_MISSING,
         ),
         'month' => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
         ),
         // Attribute on range: type
         'range' => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_DEFAULT,
             'default' => '',
         ),
         'exclusion' => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            'type'    => self::TYPE_MULTIPLE,
+            'value'   => self::VALUE_MAYBE_MISSING,
             'array'   => array(
-                'type' => HORDE_KOLAB_XML_TYPE_STRING,
-                'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                'type' => self::TYPE_STRING,
+                'value' => self::VALUE_MAYBE_MISSING,
             ),
         ),
         'complete' => array(
-            'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            'type'    => self::TYPE_MULTIPLE,
+            'value'   => self::VALUE_MAYBE_MISSING,
             'array'   => array(
-                'type' => HORDE_KOLAB_XML_TYPE_STRING,
-                'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                'type' => self::TYPE_STRING,
+                'value' => self::VALUE_MAYBE_MISSING,
             ),
         ),
     );
 
-   /**
+    /**
      * Constructor
      *
-     * @param array       $params        Any additional options
+     * @param array $params Any additional options
      */
-    function Horde_Kolab_Format_XML($params = null)
+    public function __construct($params = null)
     {
         if (is_array($params) && isset($params['version'])) {
             $this->_version = $params['version'];
@@ -295,55 +296,55 @@ class Horde_Kolab_Format_XML
         /* Generic fields, in kolab format specification order */
         $this->_fields_basic = array(
             'uid' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_NOT_EMPTY,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_NOT_EMPTY,
             ),
             'body' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
                 'default' => '',
             ),
             'categories' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
                 'default' => '',
             ),
             'creation-date' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_DATETIME,
-                'value'   => HORDE_KOLAB_XML_VALUE_CALCULATED,
+                'type'    => self::TYPE_DATETIME,
+                'value'   => self::VALUE_CALCULATED,
                 'load'    => 'CreationDate',
                 'save'    => 'CreationDate',
             ),
             'last-modification-date' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_DATETIME,
-                'value'   => HORDE_KOLAB_XML_VALUE_CALCULATED,
+                'type'    => self::TYPE_DATETIME,
+                'value'   => self::VALUE_CALCULATED,
                 'load'    => 'ModificationDate',
                 'save'    => 'ModificationDate',
             ),
             'sensitivity' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
                 'default' => 'public',
             ),
             'inline-attachment' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                'type'    => self::TYPE_MULTIPLE,
+                'value'   => self::VALUE_MAYBE_MISSING,
                 'array'   => array(
-                    'type'  => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                    'type'  => self::TYPE_STRING,
+                    'value' => self::VALUE_MAYBE_MISSING,
                 ),
             ),
             'link-attachment' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                'type'    => self::TYPE_MULTIPLE,
+                'value'   => self::VALUE_MAYBE_MISSING,
                 'array'   => array(
-                    'type'  => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                    'type'  => self::TYPE_STRING,
+                    'value' => self::VALUE_MAYBE_MISSING,
                 ),
             ),
             'product-id' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_CALCULATED,
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_CALCULATED,
                 'load'    => 'ProductId',
                 'save'    => 'ProductId',
             ),
@@ -354,23 +355,23 @@ class Horde_Kolab_Format_XML
      * Attempts to return a concrete Horde_Kolab_Format_XML instance.
      * based on $object_type.
      *
-     * @param string    $object_type    The object type that should be handled.
-     * @param array     $params         Any additional parameters.
+     * @param string    $object_type The object type that should be handled.
+     * @param array     $params      Any additional parameters.
      *
      * @return Horde_Kolab_Format_XML|PEAR_Error The newly created concrete
      *                                           Horde_Kolab_Format_XML
      *                                           instance.
      */
-    function &factory($object_type = '', $params = null)
+    public function &factory($object_type = '', $params = null)
     {
         $object_type = str_replace('-', '', $object_type);
-        @include_once dirname(__FILE__) . '/XML/' . $object_type . '.php';
-        $class = 'Horde_Kolab_Format_XML_' . $object_type;
+        $class       = 'Horde_Kolab_Format_XML_' . $object_type;
 
         if (class_exists($class)) {
             $driver = &new $class($params);
         } else {
-            return PEAR::raiseError(sprintf(_("Failed to load Kolab XML driver %s"), $object_type));
+            throw new Horde_Exception(sprintf(_("Failed to load Kolab XML driver %s"),
+                                              $object_type));
         }
 
         return $driver;
@@ -381,7 +382,7 @@ class Horde_Kolab_Format_XML
      *
      * @return string The name that may be used as filename.
      */
-    function getName()
+    public function getName()
     {
         return $this->_name;
     }
@@ -391,7 +392,7 @@ class Horde_Kolab_Format_XML
      *
      * @return string The mime type of the result.
      */
-    function getMimeType()
+    public function getMimeType()
     {
         return 'application/x-vnd.kolab.' . $this->_root_name;
     }
@@ -401,7 +402,7 @@ class Horde_Kolab_Format_XML
      *
      * @return string The disportion of this document.
      */
-    function getDisposition()
+    public function getDisposition()
     {
         return 'attachment';
     }
@@ -412,11 +413,13 @@ class Horde_Kolab_Format_XML
      * @todo Check encoding of the returned array. It seems to be ISO-8859-1 at
      * the moment and UTF-8 would seem more appropriate.
      *
-     * @param string $xmltext  The XML of the message as string.
+     * @param string $xmltext The XML of the message as string.
      *
-     * @return array|PEAR_Error The data array representing the object.
+     * @return array The data array representing the object.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
      */
-    function load(&$xmltext)
+    public function load(&$xmltext)
     {
         $noderoot = $this->_parseXml($xmltext);
         if (is_a($noderoot, 'PEAR_Error') || empty($noderoot)) {
@@ -427,21 +430,22 @@ class Horde_Kolab_Format_XML
              * next section starts a second attempt by guessing the encoding and
              * trying again.
              */
-            if (strcasecmp(mb_detect_encoding($xmltext, 'UTF-8, ISO-8859-1'), 'UTF-8') !== 0) {
+            if (strcasecmp(mb_detect_encoding($xmltext,
+                                              'UTF-8, ISO-8859-1'), 'UTF-8') !== 0) {
                 $xmltext = mb_convert_encoding($xmltext, 'UTF-8', 'ISO-8859-1');
             }
             $noderoot = $this->_parseXml($xmltext);
         }
 
         if (is_a($noderoot, 'PEAR_Error')) {
-            return $noderoot;
+            throw new Horde_Exception($noderoot);
         }
         if (empty($noderoot)) {
             return false;
         }
 
         if (!$noderoot->has_child_nodes()) {
-            return PEAR::raiseError(_("No or unreadable content in Kolab XML object"));
+            throw new Horde_Exception(_("No or unreadable content in Kolab XML object"));
         }
 
         $children = $noderoot->child_nodes();
@@ -450,21 +454,15 @@ class Horde_Kolab_Format_XML
         $object = array();
 
         $result = $this->_loadArray($children, $this->_fields_basic);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
         $object = array_merge($object, $result);
         $this->_loadMultipleCategories($object);
 
         $result = $this->_load($children);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
         $object = array_merge($object, $result);
 
         // uid is vital
         if (!isset($object['uid'])) {
-            return PEAR::raiseError(_("UID not found in Kolab XML object"));
+            throw new Horde_Exception(_("UID not found in Kolab XML object"));
         }
 
         return $object;
@@ -473,14 +471,13 @@ class Horde_Kolab_Format_XML
     /**
      * Load the groupware object based on the specifc XML values.
      *
-     * @access protected
-     *
      * @param array $children An array of XML nodes.
      *
      * @return array|PEAR_Error The data array representing the object.
      *
+     * @throws Horde_Exception If parsing the XML data failed.
      */
-    function _load(&$children)
+    protected function _load(&$children)
     {
         if (!empty($this->_fields_specific)) {
             return $this->_loadArray($children, $this->_fields_specific);
@@ -492,24 +489,21 @@ class Horde_Kolab_Format_XML
     /**
      * Load an array with data from the XML nodes.
      *
-     * @access private
-     *
      * @param array $object   The resulting data array.
      * @param array $children An array of XML nodes.
      * @param array $fields   The fields to populate in the object array.
      *
-     * @return boolean|PEAR_Error True on success.
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
      */
-    function _loadArray(&$children, $fields)
+    protected function _loadArray(&$children, $fields)
     {
         $object = array();
 
         // basic fields below the root node
         foreach($fields as $field => $params) {
             $result = $this->_getXmlData($children, $field, $params);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
             if (isset($result)) {
                 $object[$field] = $result;
             }
@@ -521,18 +515,18 @@ class Horde_Kolab_Format_XML
      * Get the text content of the named data node among the specified
      * children.
      *
-     * @access private
-     *
      * @param array  $children     The children to search.
      * @param string $name         The name of the node to return.
      * @param array  $params       Parameters for the data conversion.
      *
-     * @return string|PEAR_Error The content of the specified node or an empty
-     *                           string.
+     * @return string The content of the specified node or an empty
+     *                string.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
      */
-    function _getXmlData($children, $name, $params)
+    protected function _getXmlData($children, $name, $params)
     {
-        $value = null;
+        $value   = null;
         $missing = false;
 
         // identify the child node
@@ -540,38 +534,38 @@ class Horde_Kolab_Format_XML
 
         // Handle empty values
         if (!$child) {
-            if ($params['value'] == HORDE_KOLAB_XML_VALUE_MAYBE_MISSING) {
+            if ($params['value'] == self::VALUE_MAYBE_MISSING) {
                 // 'MAYBE_MISSING' means we should return null
                 return null;
-            } elseif ($params['value'] == HORDE_KOLAB_XML_VALUE_NOT_EMPTY) {
+            } elseif ($params['value'] == self::VALUE_NOT_EMPTY) {
                 // May not be empty. Return an error
-                return PEAR::raiseError(sprintf(_("Data value for %s is empty in Kolab XML object!"), $name));
-            } elseif ($params['value'] == HORDE_KOLAB_XML_VALUE_DEFAULT) {
+                throw new Horde_Exception(sprintf(_("Data value for %s is empty in Kolab XML object!"),
+                                                  $name));
+            } elseif ($params['value'] == self::VALUE_DEFAULT) {
                 // Return the default
                 return $params['default'];
-            } elseif ($params['value'] == HORDE_KOLAB_XML_VALUE_CALCULATED) {
+            } elseif ($params['value'] == self::VALUE_CALCULATED) {
                 $missing = true;
             }
         }
 
         // Do we need to calculate the value?
-        if ($params['value'] == HORDE_KOLAB_XML_VALUE_CALCULATED && isset($params['load'])) {
+        if ($params['value'] == self::VALUE_CALCULATED && isset($params['load'])) {
             if (method_exists($this, '_load' . $params['load'])) {
                 $value = call_user_func(array($this, '_load' . $params['load']),
                                         $child, $missing);
             } else {
-                return PEAR::raiseError(sprintf("Kolab XML: Missing function %s!", $params['load']));
+                throw new Horde_Exception(sprintf("Kolab XML: Missing function %s!",
+                                                  $params['load']));
             }
-        } elseif ($params['type'] == HORDE_KOLAB_XML_TYPE_COMPOSITE) {
+        } elseif ($params['type'] == self::TYPE_COMPOSITE) {
             return $this->_loadArray($child->child_nodes(), $params['array']);
-        } elseif ($params['type'] == HORDE_KOLAB_XML_TYPE_MULTIPLE) {
+        } elseif ($params['type'] == self::TYPE_MULTIPLE) {
             $result = array();
             foreach($children as $child) {
                 if ($child->type == XML_ELEMENT_NODE && $child->tagname == $name) {
-                    $value = $this->_getXmlData(array($child), $name, $params['array']);
-                    if (is_a($value, 'PEAR_Error')) {
-                        return $value;
-                    }
+                    $value    = $this->_getXmlData(array($child), $name,
+                              1                  $params['array']);
                     $result[] = $value;
                 }
             }
@@ -587,13 +581,13 @@ class Horde_Kolab_Format_XML
     /**
      * Parse the XML string. The root node is returned on success.
      *
-     * @access private
+     * @param string $xmltext The XML of the message as string.
      *
-     * @param string $xmltext  The XML of the message as string.
+     * @return Horde_DOM_Node The root node of the document.
      *
-     * @return Horde_DOM_Node|PEAR_Error  The root node of the document.
+     * @throws Horde_Exception If parsing the XML data failed.
      */
-    function _parseXml(&$xmltext)
+    protected function _parseXml(&$xmltext)
     {
         $params = array(
             'xml' => $xmltext,
@@ -602,7 +596,7 @@ class Horde_Kolab_Format_XML
 
         $result = Horde_DOM_Document::factory($params);
         if (is_a($result, 'PEAR_Error')) {
-            return $result;
+            throw new Horde_Exception($result);
         }
         $this->_xmldoc = $result;
         return $this->_xmldoc->document_element();
@@ -613,22 +607,17 @@ class Horde_Kolab_Format_XML
      *
      * @param array $attributes  The data array representing the note.
      *
-     * @return string|PEAR_Error The data as XML string.
+     * @return string The data as XML string.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
      */
-    function save($object)
+    public function save($object)
     {
         $root = $this->_prepareSave();
 
         $this->_saveMultipleCategories($object);
-        $result = $this->_saveArray($root, $object, $this->_fields_basic);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-
-        $result = $this->_save($root, $object);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
+        $this->_saveArray($root, $object, $this->_fields_basic);
+        $this->_save($root, $object);
 
         return $this->_xmldoc->dump_mem(true);
     }
@@ -636,20 +625,17 @@ class Horde_Kolab_Format_XML
     /**
      * Save the specific XML values.
      *
-     * @access protected
-     *
      * @param array $root     The XML document root.
      * @param array $object   The resulting data array.
      *
-     * @return boolean|PEAR_Error True on success.
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
      */
-    function _save($root, $object)
+    protected function _save($root, $object)
     {
         if (!empty($this->_fields_specific)) {
-            $result = $this->_saveArray($root, $object, $this->_fields_specific);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
+            $this->_saveArray($root, $object, $this->_fields_specific);
         }
         return true;
     }
@@ -657,21 +643,19 @@ class Horde_Kolab_Format_XML
     /**
      * Creates a new XML document if necessary.
      *
-     * @access private
-     *
      * @param string $xmltext  The XML of the message as string.
      *
      * @return Horde_DOM_Node The root node of the document.
      */
-    function _prepareSave()
+    protected function _prepareSave()
     {
         if ($this->_xmldoc != null) {
             $root = $this->_xmldoc->document_element();
         } else {
             // create new XML
             $this->_xmldoc = Horde_DOM_Document::factory();
-            $root = $this->_xmldoc->create_element($this->_root_name);
-            $root = $this->_xmldoc->append_child($root);
+            $root          = $this->_xmldoc->create_element($this->_root_name);
+            $root          = $this->_xmldoc->append_child($root);
             $root->set_attribute("version", $this->_root_version);
         }
 
@@ -681,23 +665,20 @@ class Horde_Kolab_Format_XML
     /**
      * Save a data array to XML nodes.
      *
-     * @access private
-     *
      * @param array   $root     The XML document root.
      * @param array   $object   The data array.
      * @param array   $fields   The fields to write into the XML object.
      * @param boolean $append   Should the nodes be appended?
      *
-     * @return boolean|PEAR_Error True on success.
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
      */
-    function _saveArray($root, $object, $fields, $append = false)
+    protected function _saveArray($root, $object, $fields, $append = false)
     {
         // basic fields below the root node
         foreach($fields as $field => $params) {
-            $result = $this->_updateNode($root, $object, $field, $params, $append);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
+            $this->_updateNode($root, $object, $field, $params, $append);
         }
         return true;
     }
@@ -705,8 +686,6 @@ class Horde_Kolab_Format_XML
     /**
      * Update the specified node.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent_node  The parent node of the node that
      *                                     should be updated.
      * @param array          $attributes   The data array that holds all
@@ -716,45 +695,50 @@ class Horde_Kolab_Format_XML
      * @param array          $params       Parameters for saving the node
      * @param boolean        $append       Should the node be appended?
      *
-     * @return Horde_DOM_Node|PEAR_Error The new/updated child node.
+     * @return Horde_DOM_Node The new/updated child node.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
      */
-    function _updateNode($parent_node, $attributes, $name, $params, $append = false)
+    protected function _updateNode($parent_node, $attributes, $name, $params,
+                                   $append = false)
     {
-        $value = null;
+        $value   = null;
         $missing = false;
 
         // Handle empty values
         if (!isset($attributes[$name])) {
             // Do we have information if this may be empty?
-            if ($params['value'] == HORDE_KOLAB_XML_VALUE_DEFAULT) {
+            if ($params['value'] == self::VALUE_DEFAULT) {
                 // Use the default
                 $value = $params['default'];
-            } elseif ($params['value'] == HORDE_KOLAB_XML_VALUE_NOT_EMPTY) {
+            } elseif ($params['value'] == self::VALUE_NOT_EMPTY) {
                 // May not be empty. Return an error
-                return PEAR::raiseError(sprintf(_("Data value for %s is empty in Kolab XML object!"), $name));
-            } elseif ($params['value'] == HORDE_KOLAB_XML_VALUE_MAYBE_MISSING) {
+                throw new Horde_Exception(sprintf(_("Data value for %s is empty in Kolab XML object!"),
+                                                  $name));
+            } elseif ($params['value'] == self::VALUE_MAYBE_MISSING) {
                 /**
                  * 'MAYBE_MISSING' means we should not create an XML
                  * node here
                  */
                 $this->_removeNodes($parent_node, $name);
                 return false;
-            } elseif ($params['value'] == HORDE_KOLAB_XML_VALUE_CALCULATED) {
+            } elseif ($params['value'] == self::VALUE_CALCULATED) {
                 $missing = true;
             }
         } else {
             $value = $attributes[$name];
         }
 
-        if ($params['value'] == HORDE_KOLAB_XML_VALUE_CALCULATED) {
+        if ($params['value'] == self::VALUE_CALCULATED) {
             // Calculate the value
             if (method_exists($this, '_save' . $params['save'])) {
                 return call_user_func(array($this, '_save' . $params['save']),
                                       $parent_node, $name, $value, $missing);
             } else {
-                return PEAR::raiseError(sprintf("Kolab XML: Missing function %s!", $params['save']));
+                throw new Horde_Exception(sprintf("Kolab XML: Missing function %s!",
+                                                  $params['save']));
             }
-        } elseif ($params['type'] == HORDE_KOLAB_XML_TYPE_COMPOSITE) {
+        } elseif ($params['type'] == self::TYPE_COMPOSITE) {
             // Possibly remove the old node first
             if (!$append) {
                 $this->_removeNodes($parent_node, $name);
@@ -764,38 +748,34 @@ class Horde_Kolab_Format_XML
             $composite_node = $this->_xmldoc->create_element($name);
             $composite_node = $parent_node->append_child($composite_node);
             return $this->_saveArray($composite_node, $value, $params['array']);
-        } elseif ($params['type'] == HORDE_KOLAB_XML_TYPE_MULTIPLE) {
+        } elseif ($params['type'] == self::TYPE_MULTIPLE) {
             // Remove the old nodes first
             $this->_removeNodes($parent_node, $name);
 
             // Add the new nodes
             foreach($value as $add_node) {
-                $result = $this->_saveArray($parent_node,
-                                           array($name => $add_node),
-                                           array($name => $params['array']),
-                                           true);
-                if (is_a($result, 'PEAR_Error')) {
-                    return $result;
-                }
+                $this->_saveArray($parent_node,
+                                  array($name => $add_node),
+                                  array($name => $params['array']),
+                                  true);
             }
             return true;
         } else {
-            return $this->_saveDefault($parent_node, $name, $value, $params, $append);
+            return $this->_saveDefault($parent_node, $name, $value, $params,
+                                       $append);
         }
     }
 
     /**
      * Create a text node.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node  $parent   The parent of the new node.
      * @param string          $name     The name of the child node to create.
      * @param string          $value    The value of the child node to create.
      *
      * @return Horde_DOM_Node The new node.
      */
-    function _createTextNode($parent, $name, $value)
+    protected function _createTextNode($parent, $name, $value)
     {
         $value = String::convertCharset($value, NLS::getCharset(), 'utf-8');
 
@@ -813,20 +793,18 @@ class Horde_Kolab_Format_XML
     /**
      * Return the named node among a list of nodes.
      *
-     * @access private
-     *
      * @param array  $nodes  The list of nodes.
      * @param string $name   The name of the node to return.
      *
      * @return mixed The named Horde_DOM_Node or false if no node was found.
      */
-    function _findNode($nodes, $name)
+    protected function _findNode($nodes, $name)
     {
-        foreach($nodes as $node)
+        foreach($nodes as $node) {
             if ($node->type == XML_ELEMENT_NODE && $node->tagname == $name) {
                 return $node;
             }
-
+        }
         return false;
     }
 
@@ -834,8 +812,6 @@ class Horde_Kolab_Format_XML
      * Retrieve a named child from a named parent if it has the given
      * value.
      *
-     * @access private
-     *
      * @param array  $nodes       The list of nodes.
      * @param string $parent_name The name of the parent node.
      * @param string $child_name  The name of the child node.
@@ -843,14 +819,17 @@ class Horde_Kolab_Format_XML
      *
      * @return mixed The specified Horde_DOM_Node or false if no node was found.
      */
-    function _findNodeByChildData($nodes, $parent_name, $child_name, $value)
+    protected function _findNodeByChildData($nodes, $parent_name, $child_name,
+                                            $value)
     {
         foreach($nodes as $node)
         {
             if ($node->type == XML_ELEMENT_NODE && $node->tagname == $parent_name) {
                 $children = $node->child_nodes();
-                foreach($children as $child)
-                    if ($child->type == XML_ELEMENT_NODE && $child->tagname == $child_name && $child->get_content() == $value) {
+                foreach ($children as $child)
+                    if ($child->type == XML_ELEMENT_NODE
+                        && $child->tagname == $child_name
+                        && $child->get_content() == $value) {
                         return $node;
                     }
             }
@@ -862,33 +841,25 @@ class Horde_Kolab_Format_XML
     /**
      * Retrieve the content of a Horde_DOM_Node.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node  $nodes  The node that should be read.
      *
-     * @return string|PEAR_Error The content of the node.
+     * @return string The content of the node.
      */
-    function _getNodeContent($node)
+    protected function _getNodeContent($node)
     {
-        $value = String::convertCharset($node->get_content(), 'utf-8');
-        if (is_a($value, 'PEAR_Error')) {
-            return $value;
-        }
-        return $value;
+        return String::convertCharset($node->get_content(), 'utf-8');
     }
 
 
     /**
      * Create a new named node on a parent node.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent  The parent node.
      * @param string         $name    The name of the new child node.
      *
      * @return Horde_DOM_Node The new child node.
      */
-    function _createChildNode($parent, $name)
+    protected function _createChildNode($parent, $name)
     {
         $node = $this->_xmldoc->createElement($name);
         $node = $parent->appendChild($node);
@@ -899,12 +870,10 @@ class Horde_Kolab_Format_XML
     /**
      * Remove named nodes from a parent node.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent  The parent node.
      * @param string         $name    The name of the children to be removed.
      */
-    function _removeNodes($parent_node, $name)
+    protected function _removeNodes($parent_node, $name)
     {
         while ($old_node = $this->_findNode($parent_node->child_nodes(), $name)) {
             $parent_node->remove_child($old_node);
@@ -915,8 +884,6 @@ class Horde_Kolab_Format_XML
      * Create a new named node on a parent node if it is not already
      * present in the given children.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent    The parent node.
      * @param array          $children  The children that might already
      *                                  contain the node.
@@ -924,7 +891,7 @@ class Horde_Kolab_Format_XML
      *
      * @return Horde_DOM_Node The new or already existing child node.
      */
-    function _createOrFindChildNode($parent, $children, $name)
+    protected function _createOrFindChildNode($parent, $children, $name)
     {
         // look for existing node
         $old_node = $this->_findNode($children, $name);
@@ -939,34 +906,31 @@ class Horde_Kolab_Format_XML
     /**
      * Load the different XML types.
      *
-     * @access private
-     *
      * @param string $node    The node to load the data from
      * @param array  $params  Parameters for loading the value
      *
-     * @return string|PEAR_Error The loaded value.
+     * @return string The loaded value.
+     *
+     * @throws Horde_Exception If converting the data from XML failed.
      */
-    function _loadDefault($node, $params)
+    protected function _loadDefault($node, $params)
     {
         $content = $this->_getNodeContent($node);
-        if (is_a($content, 'PEAR_Error')) {
-            return $content;
-        }
 
         switch($params['type']) {
-        case HORDE_KOLAB_XML_TYPE_DATE:
+        case self::TYPE_DATE:
             return Horde_Kolab_Format_Date::decodeDate($content);
 
-        case HORDE_KOLAB_XML_TYPE_DATETIME:
+        case self::TYPE_DATETIME:
             return Horde_Kolab_Format_Date::decodeDateTime($content);
 
-        case HORDE_KOLAB_XML_TYPE_DATE_OR_DATETIME:
+        case self::TYPE_DATE_OR_DATETIME:
             return Horde_Kolab_Format_Date::decodeDateOrDateTime($content);
 
-        case HORDE_KOLAB_XML_TYPE_INTEGER:
+        case self::TYPE_INTEGER:
             return (int) $content;
 
-        case HORDE_KOLAB_XML_TYPE_BOOLEAN:
+        case self::TYPE_BOOLEAN:
             return (bool) $content;
 
         default:
@@ -978,8 +942,6 @@ class Horde_Kolab_Format_XML
     /**
      * Save a data array as a XML node attached to the given parent node.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent_node The parent node to attach
      *                                    the child to
      * @param string         $name        The name of the node
@@ -988,28 +950,31 @@ class Horde_Kolab_Format_XML
      * @param boolean        $append      Should the node be appended?
      *
      * @return Horde_DOM_Node The new child node.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
      */
-    function _saveDefault($parent_node, $name, $value, $params, $append = false)
+    protected function _saveDefault($parent_node, $name, $value, $params,
+                                    $append = false)
     {
         if (!$append) {
             $this->_removeNodes($parent_node, $name);
         }
 
         switch ($params['type']) {
-        case HORDE_KOLAB_XML_TYPE_DATE:
+        case self::TYPE_DATE:
             $value = Horde_Kolab_Format_Date::encodeDate($value);
             break;
 
-        case HORDE_KOLAB_XML_TYPE_DATETIME:
-        case HORDE_KOLAB_XML_TYPE_DATE_OR_DATETIME:
+        case self::TYPE_DATETIME:
+        case self::TYPE_DATE_OR_DATETIME:
             $value = Horde_Kolab_Format_Date::encodeDateTime($value);
             break;
 
-        case HORDE_KOLAB_XML_TYPE_INTEGER:
+        case self::TYPE_INTEGER:
             $value = (string) $value;
             break;
 
-        case HORDE_KOLAB_XML_TYPE_BOOLEAN:
+        case self::TYPE_BOOLEAN:
             if ($value) {
                 $value = 'true';
             } else {
@@ -1027,11 +992,11 @@ class Horde_Kolab_Format_XML
      * Handle loading of categories. Preserve multiple categories in a hidden
      * object field. Optionally creates categories unknown to the Horde user.
      *
-     * @access private
+     * @param array $object Array of strings, containing the 'categories' field.
      *
-     * @param array  $object Array of strings, containing the 'categories' field.
+     * @return NULL
      */
-    function _loadMultipleCategories(&$object)
+    protected function _loadMultipleCategories(&$object)
     {
         global $prefs;
 
@@ -1044,10 +1009,10 @@ class Horde_Kolab_Format_XML
         if ($this->_create_categories
             && class_exists('Prefs_CategoryManager')
             && isset($prefs) && is_a($prefs, 'Prefs')) {
-            $cManager = new Prefs_CategoryManager();
+            $cManager         = new Prefs_CategoryManager();
             $horde_categories = $cManager->get();
         } else {
-            $cManager = null;
+            $cManager         = null;
             $horde_categories = null;
         }
 
@@ -1075,7 +1040,7 @@ class Horde_Kolab_Format_XML
 
         // Backup multiple categories
         if (count($kolab_categories) > 1) {
-            $object['_categories_all'] = $object['categories'];
+            $object['_categories_all']     = $object['categories'];
             $object['_categories_primary'] = $primary_category;
         }
         // Make default category visible to Horde
@@ -1086,14 +1051,15 @@ class Horde_Kolab_Format_XML
      * Preserve multiple categories on save if "categories" didn't change.
      * The name "categories" currently refers to one primary category.
      *
-     * @access private
-     *
      * @param array  $object Array of strings, containing the 'categories' field.
+     *
+     * @return NULL
      */
-    function _saveMultipleCategories(&$object)
+    protected function _saveMultipleCategories(&$object)
     {
         // Check for multiple categories.
-        if (!isset($object['_categories_all']) || !isset($object['_categories_primary'])
+        if (!isset($object['_categories_all'])
+            || !isset($object['_categories_primary'])
             || !isset($object['categories']))
         {
             return;
@@ -1108,28 +1074,26 @@ class Horde_Kolab_Format_XML
     /**
      * Load the object creation date.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node  $node    The original node if set.
      * @param boolean         $missing Has the node been missing?
      *
-     * @return string|PEAR_Error The creation date.
+     * @return string The creation date.
+     *
+     * @throws Horde_Exception If converting the data from XML failed.
      */
-    function _loadCreationDate($node, $missing)
+    protected function _loadCreationDate($node, $missing)
     {
         if ($missing) {
             // Be gentle and accept a missing creation date.
             return time();
         }
         return $this->_loadDefault($node,
-                                   array('type' => HORDE_KOLAB_XML_TYPE_DATETIME));
+                                   array('type' => self::TYPE_DATETIME));
     }
 
     /**
      * Save the object creation date.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent_node The parent node to attach the child
      *                                    to.
      * @param string         $name        The name of the node.
@@ -1138,7 +1102,7 @@ class Horde_Kolab_Format_XML
      *
      * @return Horde_DOM_Node The new child node.
      */
-    function _saveCreationDate($parent_node, $name, $value, $missing)
+    protected function _saveCreationDate($parent_node, $name, $value, $missing)
     {
         // Only create the creation date if it has not been set before
         if ($missing) {
@@ -1147,34 +1111,30 @@ class Horde_Kolab_Format_XML
         return $this->_saveDefault($parent_node,
                                    $name,
                                    $value,
-                                   array('type' => HORDE_KOLAB_XML_TYPE_DATETIME));
+                                   array('type' => self::TYPE_DATETIME));
     }
 
     /**
      * Load the object modification date.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node  $node    The original node if set.
      * @param boolean         $missing Has the node been missing?
      *
      * @return string The last modification date.
      */
-    function _loadModificationDate($node, $missing)
+    protected function _loadModificationDate($node, $missing)
     {
         if ($missing) {
             // Be gentle and accept a missing modification date.
             return time();
         }
         return $this->_loadDefault($node,
-                                   array('type' => HORDE_KOLAB_XML_TYPE_DATETIME));
+                                   array('type' => self::TYPE_DATETIME));
     }
 
     /**
      * Save the object modification date.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent_node The parent node to attach
      *                                    the child to.
      * @param string         $name        The name of the node.
@@ -1183,26 +1143,24 @@ class Horde_Kolab_Format_XML
      *
      * @return Horde_DOM_Node The new child node.
      */
-    function _saveModificationDate($parent_node, $name, $value, $missing)
+    protected function _saveModificationDate($parent_node, $name, $value, $missing)
     {
         // Always store now as modification date
         return $this->_saveDefault($parent_node,
                                    $name,
                                    time(),
-                                   array('type' => HORDE_KOLAB_XML_TYPE_DATETIME));
+                                   array('type' => self::TYPE_DATETIME));
     }
 
     /**
      * Load the name of the last client that modified this object
      *
-     * @access private
-     *
      * @param Horde_DOM_Node  $node    The original node if set.
      * @param boolean         $missing Has the node been missing?
      *
      * @return string The last modification date.
      */
-    function _loadProductId($node, $missing)
+    protected function _loadProductId($node, $missing)
     {
         if ($missing) {
             // Be gentle and accept a missing product id
@@ -1214,8 +1172,6 @@ class Horde_Kolab_Format_XML
     /**
      * Save the name of the last client that modified this object.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent_node The parent node to attach
      *                                    the child to.
      * @param string         $name        The name of the node.
@@ -1224,26 +1180,26 @@ class Horde_Kolab_Format_XML
      *
      * @return Horde_DOM_Node The new child node.
      */
-    function _saveProductId($parent_node, $name, $value, $missing)
+    protected function _saveProductId($parent_node, $name, $value, $missing)
     {
         // Always store now as modification date
         return $this->_saveDefault($parent_node,
                                    $name,
-                                   HORDE_KOLAB_XML_PRODUCT_ID,
-                                   array('type' => HORDE_KOLAB_XML_TYPE_STRING));
+                                   self::PRODUCT_ID,
+                                   array('type' => self::TYPE_STRING));
     }
 
     /**
      * Load recurrence information.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node  $node    The original node if set.
      * @param boolean         $missing Has the node been missing?
      *
-     * @return array|PEAR_Error The recurrence information.
+     * @return array The recurrence information.
+     *
+     * @throws Horde_Exception If converting the data from XML failed.
      */
-    function _loadRecurrence($node, $missing)
+    protected function _loadRecurrence($node, $missing)
     {
         if ($missing) {
             return null;
@@ -1257,7 +1213,7 @@ class Horde_Kolab_Format_XML
         // Get the cycle type (must be present)
         $recurrence['cycle'] = $node->get_attribute('cycle');
         // Get the sub type (may be present)
-        $recurrence['type']  = $node->get_attribute('type');
+        $recurrence['type'] = $node->get_attribute('type');
 
         // Exclusions.
         if (isset($recurrence['exclusion'])) {
@@ -1265,6 +1221,7 @@ class Horde_Kolab_Format_XML
             foreach($recurrence['exclusion'] as $exclusion) {
                 if (!empty($exclusion)) {
                     list($year, $month, $mday) = sscanf($exclusion, '%04d-%02d-%02d');
+
                     $exceptions[] = sprintf('%04d%02d%02d', $year, $month, $mday);
                 }
             }
@@ -1277,6 +1234,7 @@ class Horde_Kolab_Format_XML
             foreach($recurrence['complete'] as $complete) {
                 if (!empty($complete)) {
                     list($year, $month, $mday) = sscanf($complete, '%04d-%02d-%02d');
+
                     $completions[] = sprintf('%04d%02d%02d', $year, $month, $mday);
                 }
             }
@@ -1297,9 +1255,6 @@ class Horde_Kolab_Format_XML
 
         // Sanity check
         $valid = $this->_validateRecurrence($recurrence);
-        if (is_a($valid, 'PEAR_Error')) {
-            return $valid;
-        }
 
         return $recurrence;
     }
@@ -1307,85 +1262,88 @@ class Horde_Kolab_Format_XML
     /**
      * Validate recurrence hash information.
      *
-     * @access private
-     *
      * @param array  $recurrence  Recurrence hash loaded from XML.
      *
-     * @return boolean|PEAR_Error True on success.
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If the recurrence data is invalid.
      */
-    function _validateRecurrence(&$recurrence)
+    protected function _validateRecurrence(&$recurrence)
     {
         if (!isset($recurrence['cycle'])) {
-              return PEAR::raiseError('recurrence tag error: cycle attribute missing');
+              throw new Horde_Exception('recurrence tag error: cycle attribute missing');
         }
 
         if (!isset($recurrence['interval'])) {
-              return PEAR::raiseError('recurrence tag error: interval tag missing');
+              throw new Horde_Exception('recurrence tag error: interval tag missing');
         }
         $interval = $recurrence['interval'];
         if ($interval < 0) {
-            return PEAR::raiseError('recurrence tag error: interval cannot be below zero: ' . $interval);
+            throw new Horde_Exception('recurrence tag error: interval cannot be below zero: '
+                                      . $interval);
         }
 
         if ($recurrence['cycle'] == 'weekly') {
             // Check for <day>
             if (!isset($recurrence['day']) || count($recurrence['day']) == 0) {
-                return PEAR::raiseError('recurrence tag error: day tag missing for weekly recurrence');
+                throw new Horde_Exception('recurrence tag error: day tag missing for weekly recurrence');
             }
         }
 
         // The code below is only for monthly or yearly recurrences
-        if ($recurrence['cycle'] != 'monthly' && $recurrence['cycle'] != 'yearly')
+        if ($recurrence['cycle'] != 'monthly'
+            && $recurrence['cycle'] != 'yearly')
             return true;
 
         if (!isset($recurrence['type'])) {
-            return PEAR::raiseError('recurrence tag error: type attribute missing');
+            throw new Horde_Exception('recurrence tag error: type attribute missing');
         }
 
         if (!isset($recurrence['daynumber'])) {
-            return PEAR::raiseError('recurrence tag error: daynumber tag missing');
+            throw new Horde_Exception('recurrence tag error: daynumber tag missing');
         }
         $daynumber = $recurrence['daynumber'];
         if ($daynumber < 0) {
-            return PEAR::raiseError('recurrence tag error: daynumber cannot be below zero: ' . $daynumber);
+            throw new Horde_Exception('recurrence tag error: daynumber cannot be below zero: '
+                                      . $daynumber);
         }
 
         if ($recurrence['type'] == 'daynumber') {
             if ($recurrence['cycle'] == 'yearly' && $daynumber > 366) {
-                return PEAR::raiseError('recurrence tag error: daynumber cannot be larger than 366 for yearly recurrences: ' . $daynumber);
+                throw new Horde_Exception('recurrence tag error: daynumber cannot be larger than 366 for yearly recurrences: ' . $daynumber);
             } else if ($recurrence['cycle'] == 'monthly' && $daynumber > 31) {
-                return PEAR::raiseError('recurrence tag error: daynumber cannot be larger than 31 for monthly recurrences: ' . $daynumber);
+                throw new Horde_Exception('recurrence tag error: daynumber cannot be larger than 31 for monthly recurrences: ' . $daynumber);
             }
         } else if ($recurrence['type'] == 'weekday') {
             // daynumber is the week of the month
             if ($daynumber > 5) {
-                return PEAR::raiseError('recurrence tag error: daynumber cannot be larger than 5 for type weekday: ' . $daynumber);
+                throw new Horde_Exception('recurrence tag error: daynumber cannot be larger than 5 for type weekday: ' . $daynumber);
             }
 
             // Check for <day>
             if (!isset($recurrence['day']) || count($recurrence['day']) == 0) {
-                return PEAR::raiseError('recurrence tag error: day tag missing for type weekday');
+                throw new Horde_Exception('recurrence tag error: day tag missing for type weekday');
             }
         }
 
         if (($recurrence['type'] == 'monthday' || $recurrence['type'] == 'yearday')
             && $recurrence['cycle'] == 'monthly')
         {
-            return PEAR::raiseError('recurrence tag error: type monthday/yearday is only allowed for yearly recurrences');
+            throw new Horde_Exception('recurrence tag error: type monthday/yearday is only allowed for yearly recurrences');
         }
 
         if ($recurrence['cycle'] == 'yearly') {
             if ($recurrence['type'] == 'monthday') {
                 // daynumber and month
                 if (!isset($recurrence['month'])) {
-                    return PEAR::raiseError('recurrence tag error: month tag missing for type monthday');
+                    throw new Horde_Exception('recurrence tag error: month tag missing for type monthday');
                 }
                 if ($daynumber > 31) {
-                    return PEAR::raiseError('recurrence tag error: daynumber cannot be larger than 31 for type monthday: ' . $daynumber);
+                    throw new Horde_Exception('recurrence tag error: daynumber cannot be larger than 31 for type monthday: ' . $daynumber);
                 }
             } else if ($recurrence['type'] == 'yearday') {
                 if ($daynumber > 366) {
-                    return PEAR::raiseError('recurrence tag error: daynumber cannot be larger than 366 for type yearday: ' . $daynumber);
+                    throw new Horde_Exception('recurrence tag error: daynumber cannot be larger than 366 for type yearday: ' . $daynumber);
                 }
             }
         }
@@ -1396,8 +1354,6 @@ class Horde_Kolab_Format_XML
     /**
      * Save recurrence information.
      *
-     * @access private
-     *
      * @param Horde_DOM_Node $parent_node The parent node to attach
      *                                    the child to.
      * @param string         $name        The name of the node.
@@ -1406,7 +1362,7 @@ class Horde_Kolab_Format_XML
      *
      * @return Horde_DOM_Node The new child node.
      */
-    function _saveRecurrence($parent_node, $name, $value, $missing)
+    protected function _saveRecurrence($parent_node, $name, $value, $missing)
     {
         $this->_removeNodes($parent_node, $name);
 
@@ -1420,7 +1376,7 @@ class Horde_Kolab_Format_XML
             foreach($value['exceptions'] as $exclusion) {
                 if (!empty($exclusion)) {
                     list($year, $month, $mday) = sscanf($exclusion, '%04d%02d%02d');
-                    $exclusions[] = "$year-$month-$mday";
+                    $exclusions[]              = "$year-$month-$mday";
                 }
             }
             $value['exclusion'] = $exclusions;
@@ -1432,7 +1388,7 @@ class Horde_Kolab_Format_XML
             foreach($value['completions'] as $complete) {
                 if (!empty($complete)) {
                     list($year, $month, $mday) = sscanf($complete, '%04d%02d%02d');
-                    $completions[] = "$year-$month-$mday";
+                    $completions[]             = "$year-$month-$mday";
                 }
             }
             $value['complete'] = $completions;
@@ -1447,10 +1403,7 @@ class Horde_Kolab_Format_XML
         $r_node = $parent_node->append_child($r_node);
 
         // Save normal fields
-        $result = $this->_saveArray($r_node, $value, $this->_fields_recurrence);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
+        $this->_saveArray($r_node, $value, $this->_fields_recurrence);
 
         // Add attributes
         $r_node->set_attribute("cycle", $value['cycle']);
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Annotation.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Annotation.php
new file mode 100644 (file)
index 0000000..8bd784e
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Implementation for IMAP folder annotations in the Kolab XML format.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Kolab XML handler for IMAP folder annotations.
+ *
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
+ */
+class Horde_Kolab_Format_XML_Annotation extends Horde_Kolab_Format_XML
+{
+    /**
+     * Specific data fields for the prefs object
+     *
+     * @var Kolab
+     */
+    protected $_fields_specific;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_root_name = 'annotations';
+
+        /**
+         * Specific preferences fields, in kolab format specification order
+         */
+        $this->_fields_specific = array(
+            'annotation' => array(
+                'type'    => self::TYPE_MULTIPLE,
+                'value'   => self::VALUE_MAYBE_MISSING,
+                'array'   => array(
+                    'type' => self::TYPE_STRING,
+                    'value' => self::VALUE_MAYBE_MISSING,
+                ),
+            ),
+        );
+
+        parent::Horde_Kolab_Format_XML();
+    }
+
+    /**
+     * Load the groupware object based on the specifc XML values.
+     *
+     * @param array &$children An array of XML nodes.
+     *
+     * @return array Array with the object data
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
+     */
+    protected function _load(&$children)
+    {
+        $object = $this->_loadArray($children, $this->_fields_specific);
+        if (is_a($object, 'PEAR_Error')) {
+            return $object;
+        }
+
+        $result = array();
+        foreach ($object['annotation'] as $annotation) {
+            list($key, $value)           = split('#', $annotation, 2);
+            $result[base64_decode($key)] = base64_decode($value);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Save the specific XML values.
+     *
+     * @param array $root   The XML document root.
+     * @param array $object The resulting data array.
+     *
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
+     */
+    protected function _save($root, $object)
+    {
+        $annotations = array();
+        foreach ($object as $key => $value) {
+            if ($key != 'uid') {
+                $annotations['annotation'][] = base64_encode($key) .
+                    '#' . base64_encode($value);
+            }
+        }
+
+        return $this->_saveArray($root, $annotations, $this->_fields_specific);
+    }
+}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Contact.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Contact.php
new file mode 100644 (file)
index 0000000..fc9e448
--- /dev/null
@@ -0,0 +1,528 @@
+<?php
+/**
+ * Implementation for contacts in the Kolab XML format.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Kolab XML handler for contact groupware objects
+ *
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
+ */
+class Horde_Kolab_Format_XML_Contact extends Horde_Kolab_Format_XML
+{
+    /**
+     * Specific data fields for the contact object
+     *
+     * @var array
+     */
+    protected $_fields_specific;
+
+    /**
+     * Structure of the name field
+     *
+     * @var array
+     */
+    protected $_fields_name = array(
+        'given-name' => array (
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
+        ),
+        'middle-names' => array (
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
+        ),
+        'last-name' => array (
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
+        ),
+        'full-name' => array (
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
+        ),
+        'initials' => array (
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
+        ),
+        'prefix' => array (
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
+        ),
+        'suffix' => array (
+            'type'    => self::TYPE_STRING,
+            'value'   => self::VALUE_MAYBE_MISSING,
+        )
+    );
+
+    /**
+     * Structure of an address field
+     *
+     * @var array
+     */
+    protected $_fields_address = array(
+        'type'    => self::TYPE_COMPOSITE,
+        'value'   => self::VALUE_MAYBE_MISSING,
+        'array'   => array(
+            'type' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => 'home',
+            ),
+            'street' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'locality' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'region' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'postal-code' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'country' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+        )
+    );
+
+    /**
+     * Structure of a phone field
+     *
+     * @var array
+     */
+    protected $_fields_phone = array(
+        'type'    => self::TYPE_COMPOSITE,
+        'value'   => self::VALUE_MAYBE_MISSING,
+        'array'   => array(
+            'type' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => '',
+            ),
+            'number' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+        ),
+    );
+
+    /**
+     * Address types
+     *
+     * @var array
+     */
+    protected $_address_types = array(
+        'business',
+        'home',
+        'other',
+    );
+
+    /**
+     * Phone types
+     *
+     * @var array
+     */
+    protected $_phone_types = array(
+        'business1',
+        'business2',
+        'businessfax',
+        'callback',
+        'car',
+        'company',
+        'home1',
+        'home2',
+        'homefax',
+        'isdn',
+        'mobile',
+        'pager',
+        'primary',
+        'radio',
+        'telex',
+        'ttytdd',
+        'assistant',
+        'other',
+    );
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_root_name = "contact";
+
+        /** Specific task fields, in kolab format specification order
+         */
+        $this->_fields_specific = array(
+            'name' => array (
+                'type'    => self::TYPE_COMPOSITE,
+                'value'   => self::VALUE_MAYBE_MISSING,
+                'array'   => $this->_fields_name,
+            ),
+            'free-busy-url' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'organization' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'web-page' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'im-address' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'department' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'office-location' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'profession' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'job-title' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'manager-name' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'assistant' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'nick-name' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'spouse-name' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'birthday' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'anniversary' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'picture' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'children' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'gender' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'language' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'address' => array(
+                'type'    => self::TYPE_MULTIPLE,
+                'value'   => self::VALUE_MAYBE_MISSING,
+                'array'   => $this->_fields_address,
+            ),
+            'email' => array (
+                'type'    => self::TYPE_MULTIPLE,
+                'value'   => self::VALUE_MAYBE_MISSING,
+                'array'   => $this->_fields_simple_person,
+            ),
+            'phone' => array(
+                'type'    => self::TYPE_MULTIPLE,
+                'value'   => self::VALUE_MAYBE_MISSING,
+                'array'   => $this->_fields_phone,
+            ),
+            'preferred-address' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'latitude' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'longitude' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            // Horde specific fields
+            'pgp-publickey' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            // Support for broken clients
+            'website' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'im-adress' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+        );
+
+        parent::Horde_Kolab_Format_XML();
+    }
+
+    /**
+     * Load the groupware object based on the specifc XML values.
+     *
+     * @param array &$children An array of XML nodes.
+     *
+     * @return array Array with the object data.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
+     */
+    protected function _load(&$children)
+    {
+        $object = $this->_loadArray($children, $this->_fields_specific);
+        if (is_a($object, 'PEAR_Error')) {
+            return $object;
+        }
+
+        // Handle name fields
+        if (isset($object['name'])) {
+            $object = array_merge($object['name'], $object);
+            unset($object['name']);
+        }
+
+        // Handle email fields
+        $emails = array();
+        if (isset($object['email'])) {
+            foreach ($object['email'] as $email) {
+                $smtp_address = $email['smtp-address'];
+                if (!empty($smtp_address)) {
+                    $emails[] = $smtp_address;
+                }
+            }
+        }
+        $object['emails'] = implode(', ', $emails);
+
+        // Handle phone fields
+        if (isset($object['phone'])) {
+            foreach ($object['phone'] as $phone) {
+                if (isset($phone['number']) &&
+                    in_array($phone['type'], $this->_phone_types)) {
+                    $object["phone-" . $phone['type']] = $phone['number'];
+                }
+            }
+        }
+
+        // Handle address fields
+        if (isset($object['address'])) {
+            foreach ($object['address'] as $address) {
+                if (in_array($address['type'], $this->_address_types)) {
+                    foreach ($address as $name => $value) {
+                        $object["addr-" . $address['type'] . "-" . $name] = $value;
+                    }
+                }
+            }
+        }
+
+        // Handle gender field
+        if (isset($object['gender'])) {
+            $gender = $object['gender'];
+
+            if ($gender == "female") {
+                $object['gender'] = 1;
+            } else if ($gender == "male") {
+                $object['gender'] = 0;
+            } else {
+                // unspecified gender
+                unset($object['gender']);
+            }
+        }
+
+        // Compatibility with broken clients
+        $broken_fields = array("website" => "web-page",
+                               "im-adress" => "im-address");
+        foreach ($broken_fields as $broken_field => $real_field) {
+            if (!empty($object[$broken_field]) && empty($object[$real_field])) {
+                $object[$real_field] = $object[$broken_field];
+            }
+            unset($object[$broken_field]);
+        }
+
+        $object['__type'] = 'Object';
+
+        return $object;
+    }
+
+    /**
+     * Save the  specifc XML values.
+     *
+     * @param array $root   The XML document root.
+     * @param array $object The resulting data array.
+     *
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
+     */
+    protected function _save($root, $object)
+    {
+        // Handle name fields
+        $name = array();
+        foreach (array_keys($this->_fields_name) as $key) {
+            if (isset($object[$key])) {
+                $name[$key] = $object[$key];
+                unset($object[$key]);
+            }
+        }
+        $object['name'] = $name;
+
+        // Handle email fields
+        if (!isset($object['emails'])) {
+            $emails = array();
+        } else {
+            $emails = explode(',', $object['emails']);
+        }
+
+        if (isset($object['email']) && 
+            !in_array($object['email'], $emails)) {
+            $emails[] = $object['email'];
+        }
+
+        $object['email'] = array();
+
+        foreach ($emails as $email) {
+            $email = trim($email);
+            if (!empty($email)) {
+                $new_email = array('display-name' => $object['name']['full-name'],
+                                   'smtp-address' => $email);
+
+                $object['email'][] = $new_email;
+            }
+        }
+
+        // Handle phone fields
+        if (!isset($object['phone'])) {
+            $object['phone'] = array();
+        }
+        foreach ($this->_phone_types as $type) {
+            $key = 'phone-' . $type;
+            if (array_key_exists($key, $object)) {
+                $new_phone = array('type'   => $type,
+                                   'number' => $object[$key]);
+
+                // Update existing phone entry of this type
+                $updated = false;
+                foreach ($object['phone'] as $index => $phone) {
+                    if ($phone['type'] == $type) {
+                        $object['phone'][$index] = $new_phone;
+
+                        $updated = true;
+                        break;
+                    }
+                }
+                if (!$updated) {
+                    $object['phone'][] = $new_phone;
+                }
+            }
+        }
+
+        // Phone cleanup: remove empty numbers
+        foreach ($object['phone'] as $index => $phone) {
+            if (empty($phone['number'])) {
+                unset($object['phone'][$index]);
+            }
+        }
+
+        // Handle address fields
+        if (!isset($object['address'])) {
+            $object['address'] = array();
+        }
+
+        foreach ($this->_address_types as $type) {
+            $basekey     = 'addr-' . $type . '-';
+            $new_address = array('type'   => $type);
+            foreach (array_keys($this->_fields_address['array']) as $subkey) {
+                $key = $basekey . $subkey;
+                if (array_key_exists($key, $object)) {
+                    $new_address[$subkey] = $object[$key];
+                }
+            }
+
+            // Update existing address entry of this type
+            $updated = false;
+            foreach ($object['address'] as $index => $address) {
+                if ($address['type'] == $type) {
+                    $object['address'][$index] = $new_address;
+
+                    $updated = true;
+                }
+            }
+            if (!$updated) {
+                $object['address'][] = $new_address;
+            }
+        }
+
+        // Address cleanup: remove empty addresses
+        foreach ($object['address'] as $index => $address) {
+            $all_empty = true;
+            foreach ($address as $name => $value) {
+                if (!empty($value) && $name != "type") {
+                    $all_empty = false;
+                    break;
+                }
+            }
+
+            if ($all_empty) {
+                unset($object['address'][$index]);
+            }
+        }
+
+        // Handle gender field
+        if (isset($object['gender'])) {
+            $gender = $object['gender'];
+
+            if ($gender == "0") {
+                $object['gender'] = "male";
+            } else if ($gender == "1") {
+                $object['gender'] = "female";
+            } else {
+                // unspecified gender
+                unset($object['gender']);
+            }
+        }
+
+        // Do the actual saving
+        return $this->_saveArray($root, $object, $this->_fields_specific);
+    }
+}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Distributionlist.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Distributionlist.php
new file mode 100644 (file)
index 0000000..2584247
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Implementation for distributionlists in the Kolab XML format.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Kolab XML handler for distributionlist groupware objects
+ *
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
+ */
+class Horde_Kolab_Format_XML_Distributionlist extends Horde_Kolab_Format_XML
+{
+    /**
+     * Specific data fields for the contact object
+     *
+     * @var array
+     */
+    protected $_fields_specific;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_root_name = "distribution-list";
+
+        /** Specific task fields, in kolab format specification order
+         */
+        $this->_fields_specific = array(
+                'display-name' => array(
+                    'type'    => self::TYPE_STRING,
+                    'value'   => self::VALUE_NOT_EMPTY
+                ),
+                'member' => array(
+                    'type'    => self::TYPE_MULTIPLE,
+                    'value'   => self::VALUE_MAYBE_MISSING,
+                    'array'   => $this->_fields_simple_person,
+                )
+            );
+
+        parent::Horde_Kolab_Format_XML();
+    }
+
+    /**
+     * Load the groupware object based on the specifc XML values.
+     *
+     * @param array &$children An array of XML nodes.
+     *
+     * @return array Array with data.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
+     */
+    protected function _load(&$children)
+    {
+        $object = $this->_loadArray($children, $this->_fields_specific);
+        if (is_a($object, 'PEAR_Error')) {
+            return $object;
+        }
+
+        // Map the display-name of a kolab dist list to horde's lastname attribute
+        if (isset($object['display-name'])) {
+            $object['last-name'] = $object['display-name'];
+            unset($object['display-name']);
+        }
+
+        /**
+         * The mapping from $object['member'] as stored in XML back to
+         * Turba_Objects (contacts) must be performed in the
+         * Kolab_IMAP storage driver as we need access to the search
+         * facilities of the kolab storage driver.
+         */
+        $object['__type'] = 'Group';
+        return $object;
+    }
+
+    /**
+     * Save the  specifc XML values.
+     *
+     * @param array $root   The XML document root.
+     * @param array $object The resulting data array.
+     *
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
+     */
+    protected function _save($root, $object)
+    {
+        // Map the display-name of a kolab dist list to horde's lastname attribute
+        if (isset($object['last-name'])) {
+            $object['display-name'] = $object['last-name'];
+            unset($object['last-name']);
+        }
+
+        return $this->_saveArray($root, $object, $this->_fields_specific);
+    }
+}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Event.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Event.php
new file mode 100644 (file)
index 0000000..54bbd53
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Implementation for events in the Kolab XML format.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Kolab XML handler for event groupware objects.
+ *
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
+ */
+class Horde_Kolab_Format_XML_Event extends Horde_Kolab_Format_XML
+{
+    /**
+     * Specific data fields for the contact object
+     *
+     * @var array
+     */
+    protected $_fields_specific;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_root_name = 'event';
+
+        /** Specific event fields, in kolab format specification order
+         */
+        $this->_fields_specific = array(
+            'summary' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'location' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'organizer' => $this->_fields_simple_person,
+            'start-date' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_NOT_EMPTY,
+            ),
+            'alarm' => array(
+                'type'    => self::TYPE_INTEGER,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'recurrence' => array(
+                'type'    => self::TYPE_COMPOSITE,
+                'value'   => self::VALUE_CALCULATED,
+                'load'    => 'Recurrence',
+                'save'    => 'Recurrence',
+            ),
+            'attendee' => $this->_fields_attendee,
+            'show-time-as' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'color-label' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'end-date' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_NOT_EMPTY,
+            ),
+        );
+
+        parent::Horde_Kolab_Format_XML();
+    }
+
+    /**
+     * Load event XML values and translate start/end date.
+     *
+     * @param array &$children An array of XML nodes.
+     *
+     * @return array Array with the object data.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
+     */
+    protected function _load(&$children)
+    {
+        $object = parent::_load($children);
+        if (is_a($object, 'PEAR_Error')) {
+            return $object;
+        }
+
+        // Translate start/end date including full day events
+        if (strlen($object['start-date']) == 10) {
+            $object['start-date'] = Horde_Kolab_Format_Date::decodeDate($object['start-date']);
+            $object['end-date']   = Horde_Kolab_Format_Date::decodeDate($object['end-date']) + 24*60*60;
+        } else {
+            $object['start-date'] = Horde_Kolab_Format_Date::decodeDateTime($object['start-date']);
+            $object['end-date']   = Horde_Kolab_Format_Date::decodeDateTime($object['end-date']);
+        }
+
+        return $object;
+    }
+
+    /**
+     * Save event XML values and translate start/end date.
+     *
+     * @param array $root   The XML document root.
+     * @param array $object The resulting data array.
+     *
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
+     */
+    function _save($root, $object)
+    {
+        // Translate start/end date including full day events
+        if (!empty($object['_is_all_day'])) {
+            $object['start-date'] = Horde_Kolab_Format_Date::encodeDate($object['start-date']);
+            $object['end-date']   = Horde_Kolab_Format_Date::encodeDate($object['end-date'] - 24*60*60);
+        } else {
+            $object['start-date'] = Horde_Kolab_Format_Date::encodeDateTime($object['start-date']);
+            $object['end-date']   = Horde_Kolab_Format_Date::encodeDateTime($object['end-date']);
+        }
+
+        return parent::_save($root, $object);
+    }
+}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Hprefs.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Hprefs.php
new file mode 100644 (file)
index 0000000..ee04ad0
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Implementation for horde user preferences in the Kolab XML format.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Kolab XML handler for client preferences.
+ *
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
+ */
+class Horde_Kolab_Format_XML_Hprefs extends Horde_Kolab_Format_XML
+{
+    /**
+     * Specific data fields for the prefs object
+     *
+     * @var Kolab
+     */
+    protected $_fields_specific;
+
+    /**
+     * Automatically create categories if they are missing?
+     *
+     * @var boolean
+     */
+    protected $_create_categories = false;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_root_name = 'h-prefs';
+
+        /** Specific preferences fields, in kolab format specification order
+         */
+        $this->_fields_specific = array(
+            'application' => array (
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'pref' => array(
+                'type'    => self::TYPE_MULTIPLE,
+                'value'   => self::VALUE_MAYBE_MISSING,
+                'array'   => array(
+                    'type' => self::TYPE_STRING,
+                    'value' => self::VALUE_MAYBE_MISSING,
+                ),
+            ),
+        );
+
+        parent::Horde_Kolab_Format_XML();
+    }
+
+    /**
+     * Load an object based on the given XML string.
+     *
+     * @param string &$xmltext The XML of the message as string.
+     *
+     * @return array The data array representing the object.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
+     */
+    protected function load(&$xmltext)
+    {
+        $object = parent::load($xmltext);
+
+        if (empty($object['application'])) {
+            if (!empty($object['categories'])) {
+                $object['application'] = $object['categories'];
+                unset($object['categories']);
+            } else {
+                return PEAR::raiseError('Preferences XML object is missing an application setting.');
+            }
+        }
+
+        return $object;
+    }
+
+    /**
+     * Convert the data to a XML string.
+     *
+     * @param array $object The data array representing the note.
+     *
+     * @return string The data as XML string.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
+     */
+    protected function save($object)
+    {
+        if (empty($object['application'])) {
+            if (!empty($object['categories'])) {
+                $object['application'] = $object['categories'];
+                unset($object['categories']);
+            } else {
+                return PEAR::raiseError('Preferences XML object is missing an application setting.');
+            }
+        }
+
+        return parent::save($object);
+    }
+}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Note.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Note.php
new file mode 100644 (file)
index 0000000..63e17bb
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Implementation for notes in the Kolab XML format.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Kolab XML handler for note groupware objects.
+ *
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
+ */
+class Horde_Kolab_Format_XML_Note extends Horde_Kolab_Format_XML
+{
+    /**
+     * Specific data fields for the note object
+     *
+     * @var Kolab
+     */
+    protected $_fields_specific;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_root_name = 'note';
+
+        /** Specific note fields, in kolab format specification order
+         */
+        $this->_fields_specific = array(
+            'summary' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => '',
+            ),
+            'background-color' => array(
+                'type'    => self::TYPE_COLOR,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => '#000000',
+            ),
+            'foreground-color' => array(
+                'type'    => self::TYPE_COLOR,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => '#ffff00',
+            ),
+        );
+
+        parent::Horde_Kolab_Format_XML();
+    }
+
+    /**
+     * Load the groupware object based on the specifc XML values.
+     *
+     * @param array &$children An array of XML nodes.
+     *
+     * @return array Array with the object data
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
+     */
+    protected function _load(&$children)
+    {
+        $object = $this->_loadArray($children, $this->_fields_specific);
+        if (is_a($object, 'PEAR_Error')) {
+            return $object;
+        }
+
+        $object['desc'] = $object['summary'];
+        unset($object['summary']);
+
+        return $object;
+    }
+
+    /**
+     * Save the specific XML values.
+     *
+     * @param array $root   The XML document root.
+     * @param array $object The resulting data array.
+     *
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
+     */
+    protected function _save($root, $object)
+    {
+        $object['summary'] = $object['desc'];
+        unset($object['desc']);
+
+        return $this->_saveArray($root, $object, $this->_fields_specific);
+    }
+}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Task.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/Task.php
new file mode 100644 (file)
index 0000000..eee684b
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+/**
+ * Implementation for tasks in the Kolab XML format.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Kolab XML handler for task groupware objects.
+ *
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Format
+ * @author   Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ * @since    Horde 3.2
+ */
+class Horde_Kolab_Format_XML_Task extends Horde_Kolab_Format_XML
+{
+    /**
+     * Specific data fields for the note object
+     *
+     * @var array
+     */
+    protected $_fields_specific;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_root_name = 'task';
+
+        /** Specific task fields, in kolab format specification order
+         */
+        $this->_fields_specific = array(
+            'summary' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => '',
+            ),
+            'location' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => '',
+            ),
+            'creator'   => $this->_fields_simple_person,
+            'organizer' => $this->_fields_simple_person,
+            'start-date' => array(
+                'type'    => self::TYPE_DATE_OR_DATETIME,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'alarm' => array(
+                'type'    => self::TYPE_INTEGER,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'recurrence' => array(
+                'type'    => self::TYPE_COMPOSITE,
+                'value'   => self::VALUE_CALCULATED,
+                'load'    => 'Recurrence',
+                'save'    => 'Recurrence',
+            ),
+            'attendee' => $this->_fields_attendee,
+            'priority' => array(
+                'type'    => self::TYPE_INTEGER,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => 3,
+            ),
+            'completed' => array(
+                'type'    => self::TYPE_INTEGER,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => 0,
+            ),
+            'status' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_DEFAULT,
+                'default' => 'not-started',
+            ),
+            'due-date' => array(
+                'type'    => self::TYPE_DATE_OR_DATETIME,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'parent' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            // These are not part of the Kolab specification but it is
+            // ok if the client supports additional entries
+            'estimate' => array(
+                'type'    => self::TYPE_STRING,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+            'completed_date' => array(
+                'type'    => self::TYPE_DATE_OR_DATETIME,
+                'value'   => self::VALUE_MAYBE_MISSING,
+            ),
+        );
+
+        parent::Horde_Kolab_Format_XML();
+    }
+
+    /**
+     * Load the groupware object based on the specifc XML values.
+     *
+     * @param array &$children An array of XML nodes.
+     *
+     * @return array Array with data.
+     *
+     * @throws Horde_Exception If parsing the XML data failed.
+     */
+    protected function _load(&$children)
+    {
+        $object = $this->_loadArray($children, $this->_fields_specific);
+        if (is_a($object, 'PEAR_Error')) {
+            return $object;
+        }
+
+        $object['name'] = $object['summary'];
+        unset($object['summary']);
+
+        if (empty($object['completed-date'])) {
+            $object['completed-date'] = null;
+        }
+
+        if (empty($object['alarm'])) {
+            $object['alarm'] = null;
+        }
+
+        if (isset($object['due-date'])) {
+            $object['due'] = $object['due-date'];
+            unset($object['due-date']);
+        } else {
+            $object['due'] = null;
+        }
+
+        if (isset($object['start-date'])) {
+            $object['start'] = $object['start-date'];
+            unset($object['start-date']);
+        } else {
+            $object['start'] = null;
+        }
+
+        if (!isset($object['estimate'])) {
+            $object['estimate'] = null;
+        } else {
+            $object['estimate'] = (float) $object['estimate'];
+        }
+
+        if (!isset($object['parent'])) {
+            $object['parent'] = null;
+        }
+
+        $object['completed'] = (bool) Kolab::percentageToBoolean($object['completed']);
+
+        if (isset($object['organizer']) && isset($object['organizer']['smtp-address'])) {
+            $object['assignee'] = $object['organizer']['smtp-address'];
+        }
+
+        return $object;
+    }
+
+    /**
+     * Save the specific XML values.
+     *
+     * @param array $root   The XML document root.
+     * @param array $object The resulting data array.
+     *
+     * @return boolean True on success.
+     *
+     * @throws Horde_Exception If converting the data to XML failed.
+     */
+    protected function _save($root, $object)
+    {
+        $object['summary'] = $object['name'];
+        unset($object['name']);
+
+        $object['due-date'] = $object['due'];
+        unset($object['due']);
+
+        $object['start-date'] = $object['start'];
+        unset($object['start']);
+
+        $object['estimate'] = number_format($object['estimate'], 2);
+
+        $object['completed'] = Kolab::BooleanToPercentage($object['completed']);
+
+        return $this->_saveArray($root, $object, $this->_fields_specific);
+    }
+}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/annotation.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/annotation.php
deleted file mode 100644 (file)
index 77c733d..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-/**
- * Implementation for IMAP folder annotations in the Kolab XML format.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/annotation.php,v 1.5 2009/01/06 17:49:23 jan Exp $
- *
- * @package Kolab_Format
- */
-
-/**
- * Kolab XML handler for IMAP folder annotations.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/annotation.php,v 1.5 2009/01/06 17:49:23 jan Exp $
- *
- * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML_annotation extends Horde_Kolab_Format_XML {
-    /**
-     * Specific data fields for the prefs object
-     *
-     * @var Kolab
-     */
-    var $_fields_specific;
-
-    /**
-     * Constructor
-     */
-    function Horde_Kolab_Format_XML_annotation()
-    {
-        $this->_root_name = 'annotations';
-
-        /** Specific preferences fields, in kolab format specification order
-         */
-        $this->_fields_specific = array(
-            'annotation' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                'array'   => array(
-                    'type' => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                ),
-            ),
-        );
-
-        parent::Horde_Kolab_Format_XML();
-    }
-
-    /**
-     * Load the groupware object based on the specifc XML values.
-     *
-     * @access protected
-     *
-     * @param array $children An array of XML nodes.
-     *
-     * @return array|PEAR_Error Array with the object data
-     */
-    function _load(&$children)
-    {
-        $object = $this->_loadArray($children, $this->_fields_specific);
-        if (is_a($object, 'PEAR_Error')) {
-            return $object;
-        }
-
-        $result = array();
-        foreach ($object['annotation'] as $annotation) {
-            list($key, $value) = split('#', $annotation, 2);
-            $result[base64_decode($key)] = base64_decode($value);
-        }
-
-        return $result;
-    }
-
-    /**
-     * Save the specific XML values.
-     *
-     * @access protected
-     *
-     * @param array $root     The XML document root.
-     * @param array $object   The resulting data array.
-     *
-     * @return boolean|PEAR_Error True on success.
-     */
-    function _save($root, $object)
-    {
-        $annotations = array();
-        foreach ($object as $key => $value) {
-            if ($key != 'uid') {
-                $annotations['annotation'][] = base64_encode($key) . '#' . base64_encode($value);
-            }
-        }
-
-        return $this->_saveArray($root, $annotations, $this->_fields_specific);
-    }
-}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/contact.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/contact.php
deleted file mode 100644 (file)
index ffae144..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-<?php
-/**
- * Implementation for contacts in the Kolab XML format.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/contact.php,v 1.7 2008/12/12 11:25:52 wrobel Exp $
- *
- * @package Kolab_Format
- */
-
-/**
- * Kolab XML handler for contact groupware objects
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/contact.php,v 1.7 2008/12/12 11:25:52 wrobel Exp $
- *
- * Copyright 2007-2008 Klarälvdalens Datakonsult AB
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML_contact extends Horde_Kolab_Format_XML {
-
-    /**
-     * Specific data fields for the contact object
-     *
-     * @var array
-     */
-    var $_fields_specific;
-
-    /**
-     * Structure of the name field
-     *
-     * @var array
-     */
-    var $_fields_name = array(
-        'given-name' => array (
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        ),
-        'middle-names' => array (
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        ),
-        'last-name' => array (
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        ),
-        'full-name' => array (
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        ),
-        'initials' => array (
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        ),
-        'prefix' => array (
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        ),
-        'suffix' => array (
-            'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-            'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        )
-    );
-
-    /**
-     * Structure of an address field
-     *
-     * @var array
-     */
-    var $_fields_address = array(
-        'type'    => HORDE_KOLAB_XML_TYPE_COMPOSITE,
-        'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        'array'   => array(
-            'type' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => 'home',
-            ),
-            'street' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'locality' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'region' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'postal-code' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'country' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-        )
-    );
-
-    /**
-     * Structure of a phone field
-     *
-     * @var array
-     */
-    var $_fields_phone = array(
-        'type'    => HORDE_KOLAB_XML_TYPE_COMPOSITE,
-        'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-        'array'   => array(
-            'type' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => '',
-            ),
-            'number' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-        ),
-    );
-
-    /**
-     * Address types
-     *
-     * @var array
-     */
-    var $_address_types = array(
-        'business',
-        'home',
-        'other',
-    );
-
-    /**
-     * Phone types
-     *
-     * @var array
-     */
-    var $_phone_types = array(
-        'business1',
-        'business2',
-        'businessfax',
-        'callback',
-        'car',
-        'company',
-        'home1',
-        'home2',
-        'homefax',
-        'isdn',
-        'mobile',
-        'pager',
-        'primary',
-        'radio',
-        'telex',
-        'ttytdd',
-        'assistant',
-        'other',
-    );
-
-    /**
-     * Constructor
-     */
-    function Horde_Kolab_Format_XML_contact()
-    {
-        $this->_root_name = "contact";
-
-        /** Specific task fields, in kolab format specification order
-         */
-        $this->_fields_specific = array(
-            'name' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_COMPOSITE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                'array'   => $this->_fields_name,
-            ),
-            'free-busy-url' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'organization' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'web-page' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'im-address' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'department' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'office-location' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'profession' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'job-title' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'manager-name' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'assistant' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'nick-name' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'spouse-name' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'birthday' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'anniversary' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'picture' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'children' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'gender' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'language' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'address' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                'array'   => $this->_fields_address,
-            ),
-            'email' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                'array'   => $this->_fields_simple_person,
-            ),
-            'phone' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                'array'   => $this->_fields_phone,
-            ),
-            'preferred-address' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'latitude' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'longitude' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            // Horde specific fields
-            'pgp-publickey' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            // Support for broken clients
-            'website' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'im-adress' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-        );
-
-        parent::Horde_Kolab_Format_XML();
-    }
-
-    /**
-     * Load the groupware object based on the specifc XML values.
-     *
-     * @access protected
-     *
-     * @param array $children An array of XML nodes.
-     *
-     * @return array|PEAR_Error Array with the object data.
-     */
-    function _load(&$children)
-    {
-        $object = $this->_loadArray($children, $this->_fields_specific);
-        if (is_a($object, 'PEAR_Error')) {
-            return $object;
-        }
-
-        // Handle name fields
-        if (isset($object['name'])) {
-            $object = array_merge($object['name'], $object);
-            unset($object['name']);
-        }
-
-        // Handle email fields
-        $emails = array();
-        if (isset($object['email'])) {
-            foreach ($object['email'] as $email) {
-                $smtp_address = $email['smtp-address'];
-                if (!empty($smtp_address)) {
-                    $emails[] = $smtp_address;
-                }
-            }
-        }
-        $object['emails'] = implode(', ', $emails);
-
-        // Handle phone fields
-        if (isset($object['phone'])) {
-            foreach ($object['phone'] as $phone) {
-                if (isset($phone['number']) &&
-                    in_array($phone['type'], $this->_phone_types)) {
-                    $object["phone-" . $phone['type']] = $phone['number'];
-                }
-            }
-        }
-
-        // Handle address fields
-        if (isset($object['address'])) {
-            foreach ($object['address'] as $address) {
-                if (in_array($address['type'], $this->_address_types)) {
-                    foreach ($address as $name => $value) {
-                        $object["addr-" . $address['type'] . "-" . $name] = $value;
-                    }
-                }
-            }
-        }
-
-        // Handle gender field
-        if (isset($object['gender'])) {
-            $gender = $object['gender'];
-
-            if ($gender == "female") {
-                $object['gender'] = 1;
-            } else if ($gender == "male") {
-                $object['gender'] = 0;
-            } else {
-                // unspecified gender
-                unset($object['gender']);
-            }
-        }
-
-        // Compatibility with broken clients
-        $broken_fields = array("website" => "web-page",
-                               "im-adress" => "im-address");
-        foreach ($broken_fields as $broken_field => $real_field) {
-            if (!empty($object[$broken_field]) && empty($object[$real_field])) {
-                $object[$real_field] = $object[$broken_field];
-            }
-            unset($object[$broken_field]);
-        }
-
-        $object['__type'] = 'Object';
-
-        return $object;
-    }
-
-    /**
-     * Save the  specifc XML values.
-     *
-     * @access protected
-     *
-     * @param array $root     The XML document root.
-     * @param array $object   The resulting data array.
-     *
-     * @return boolean|PEAR_Error True on success.
-     */
-    function _save($root, $object)
-    {
-        // Handle name fields
-        $name = array();
-        foreach (array_keys($this->_fields_name) as $key) {
-            if (isset($object[$key])) {
-                $name[$key] = $object[$key];
-                unset($object[$key]);
-            }
-        }
-        $object['name'] = $name;
-
-        // Handle email fields
-        if (!isset($object['emails'])) {
-            $emails = array();
-        } else {
-            $emails = explode(',', $object['emails']);
-        }
-
-        if (isset($object['email']) && 
-            !in_array($object['email'], $emails)) {
-            $emails[] = $object['email'];
-        }
-
-        $object['email'] = array();
-
-        foreach ($emails as $email) {
-            $email = trim($email);
-            if (!empty($email)) {
-                $new_email = array('display-name' => $object['name']['full-name'],
-                                   'smtp-address' => $email);
-                $object['email'][] = $new_email;
-            }
-        }
-
-        // Handle phone fields
-        if (!isset($object['phone'])) {
-            $object['phone'] = array();
-        }
-        foreach ($this->_phone_types as $type) {
-            $key = 'phone-' . $type;
-            if (array_key_exists($key, $object)) {
-                $new_phone = array('type'   => $type,
-                                   'number' => $object[$key]);
-
-                // Update existing phone entry of this type
-                $updated = false;
-                foreach($object['phone'] as $index => $phone) {
-                    if ($phone['type'] == $type) {
-                        $object['phone'][$index] = $new_phone;
-                        $updated = true;
-                        break;
-                    }
-                }
-                if (!$updated) {
-                    $object['phone'][] = $new_phone;
-                }
-            }
-        }
-
-        // Phone cleanup: remove empty numbers
-        foreach($object['phone'] as $index => $phone) {
-            if (empty($phone['number'])) {
-                unset($object['phone'][$index]);
-            }
-        }
-
-        // Handle address fields
-        if (!isset($object['address'])) {
-            $object['address'] = array();
-        }
-
-        foreach ($this->_address_types as $type) {
-            $basekey = 'addr-' . $type . '-';
-            $new_address = array('type'   => $type);
-            foreach (array_keys($this->_fields_address['array']) as $subkey) {
-                $key = $basekey . $subkey;
-                if (array_key_exists($key, $object)) {
-                    $new_address[$subkey] = $object[$key];
-                }
-            }
-
-            // Update existing address entry of this type
-            $updated = false;
-            foreach($object['address'] as $index => $address) {
-                if ($address['type'] == $type) {
-                    $object['address'][$index] = $new_address;
-                    $updated = true;
-                }
-            }
-            if (!$updated) {
-                $object['address'][] = $new_address;
-            }
-        }
-
-        // Address cleanup: remove empty addresses
-        foreach($object['address'] as $index => $address) {
-            $all_empty = true;
-            foreach($address as $name => $value) {
-                if (!empty($value) && $name != "type") {
-                    $all_empty = false;
-                    break;
-                }
-            }
-
-            if ($all_empty) {
-                unset($object['address'][$index]);
-            }
-        }
-
-        // Handle gender field
-        if (isset($object['gender'])) {
-            $gender = $object['gender'];
-
-            if ($gender == "0") {
-                $object['gender'] = "male";
-            } else if ($gender == "1") {
-                $object['gender'] = "female";
-            } else {
-                // unspecified gender
-                unset($object['gender']);
-            }
-        }
-
-        // Do the actual saving
-        return $this->_saveArray($root, $object, $this->_fields_specific);
-    }
-}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/distributionlist.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/distributionlist.php
deleted file mode 100644 (file)
index b81573f..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-/**
- * Implementation for distributionlists in the Kolab XML format.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/distributionlist.php,v 1.6 2008/12/12 11:25:52 wrobel Exp $
- *
- * @package Kolab_Format
- */
-
-/**
- * Kolab XML handler for distributionlist groupware objects
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/distributionlist.php,v 1.6 2008/12/12 11:25:52 wrobel Exp $
- *
- * Copyright 2007-2008 Klarälvdalens Datakonsult AB
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @author  Mike Gabriel <m.gabriel@das-netzwerkteam.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML_distributionlist extends Horde_Kolab_Format_XML {
-
-    /**
-     * Specific data fields for the contact object
-     *
-     * @var array
-     */
-    var $_fields_specific;
-
-    /**
-     * Constructor
-     */
-    function Horde_Kolab_Format_XML_distributionlist()
-    {
-        $this->_root_name = "distribution-list";
-
-        /** Specific task fields, in kolab format specification order
-         */
-        $this->_fields_specific = array(
-                'display-name' => array(
-                    'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value'   => HORDE_KOLAB_XML_VALUE_NOT_EMPTY
-                ),
-                'member' => array(
-                    'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                    'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                    'array'   => $this->_fields_simple_person,
-                )
-            );
-
-        parent::Horde_Kolab_Format_XML();
-    }
-
-    /**
-     * Load the groupware object based on the specifc XML values.
-     *
-     * @access protected
-     *
-     * @param array $children An array of XML nodes.
-     *
-     * @return array|PEAR_Error Array with data.
-     */
-    function _load(&$children)
-    {
-        $object = $this->_loadArray($children, $this->_fields_specific);
-        if (is_a($object, 'PEAR_Error')) {
-            return $object;
-        }
-
-        // Map the display-name of a kolab dist list to horde's lastname attribute
-        if (isset($object['display-name'])) {
-            $object['last-name'] = $object['display-name'];
-            unset($object['display-name']);
-        }
-
-        // the mapping from $object['member'] as stored in XML back to Turba_Objects (contacts)
-        // must be performed in the Kolab_IMAP storage driver as we need access to the search
-        // facilities of the kolab storage driver.
-
-        $object['__type'] = 'Group';
-        return $object;
-    }
-
-    /**
-     * Save the  specifc XML values.
-     *
-     * @access protected
-     *
-     * @param array $root     The XML document root.
-     * @param array $object   The resulting data array.
-     *
-     * @return boolean|PEAR_Error True on success.
-     */
-    function _save($root, $object)
-    {
-        // Map the display-name of a kolab dist list to horde's lastname attribute
-        if (isset($object['last-name'])) {
-            $object['display-name'] = $object['last-name'];
-            unset($object['last-name']);
-        }
-
-        return $this->_saveArray($root, $object, $this->_fields_specific);
-    }
-}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/event.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/event.php
deleted file mode 100644 (file)
index 24fc8b9..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-<?php
-/**
- * Implementation for events in the Kolab XML format.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/event.php,v 1.4 2008/12/12 11:25:52 wrobel Exp $
- *
- * @package Kolab_Format
- */
-
-/** Kolab date handling functions. */
-require_once 'Horde/Kolab/Format/Date.php';
-
-/**
- * Kolab XML handler for event groupware objects.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/event.php,v 1.4 2008/12/12 11:25:52 wrobel Exp $
- *
- * Copyright 2007-2008 Klarälvdalens Datakonsult AB
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML_event extends Horde_Kolab_Format_XML {
-    /**
-     * Specific data fields for the contact object
-     *
-     * @var array
-     */
-    var $_fields_specific;
-
-    /**
-     * Constructor
-     */
-    function Horde_Kolab_Format_XML_event()
-    {
-        $this->_root_name = 'event';
-
-        /** Specific event fields, in kolab format specification order
-         */
-        $this->_fields_specific = array(
-            'summary' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'location' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'organizer' => $this->_fields_simple_person,
-            'start-date' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_NOT_EMPTY,
-            ),
-            'alarm' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_INTEGER,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'recurrence' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_COMPOSITE,
-                'value'   => HORDE_KOLAB_XML_VALUE_CALCULATED,
-                'load'    => 'Recurrence',
-                'save'    => 'Recurrence',
-            ),
-            'attendee' => $this->_fields_attendee,
-            'show-time-as' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'color-label' => array (
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'end-date' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_NOT_EMPTY,
-            ),
-        );
-
-        parent::Horde_Kolab_Format_XML();
-    }
-
-    /**
-     * Load event XML values and translate start/end date.
-     *
-     * @access protected
-     *
-     * @param array $children An array of XML nodes.
-     *
-     * @return array|PEAR_Error Array with the object data.
-     */
-    function _load(&$children)
-    {
-        $object = parent::_load($children);
-        if (is_a($object, 'PEAR_Error')) {
-            return $object;
-        }
-
-        // Translate start/end date including full day events
-        if (strlen($object['start-date']) == 10) {
-            $object['start-date'] = Horde_Kolab_Format_Date::decodeDate($object['start-date']);
-            $object['end-date'] = Horde_Kolab_Format_Date::decodeDate($object['end-date']) + 24*60*60;
-        } else {
-            $object['start-date'] = Horde_Kolab_Format_Date::decodeDateTime($object['start-date']);
-            $object['end-date'] = Horde_Kolab_Format_Date::decodeDateTime($object['end-date']);
-        }
-
-        return $object;
-    }
-
-    /**
-     * Save event XML values and translate start/end date.
-     *
-     * @access protected
-     *
-     * @param array $root     The XML document root.
-     * @param array $object   The resulting data array.
-     *
-     * @return boolean|PEAR_Error True on success.
-     */
-    function _save($root, $object)
-    {
-        // Translate start/end date including full day events
-        if (!empty($object['_is_all_day'])) {
-            $object['start-date'] = Horde_Kolab_Format_Date::encodeDate($object['start-date']);
-            $object['end-date'] = Horde_Kolab_Format_Date::encodeDate($object['end-date'] - 24*60*60);
-        } else {
-            $object['start-date'] = Horde_Kolab_Format_Date::encodeDateTime($object['start-date']);
-            $object['end-date'] = Horde_Kolab_Format_Date::encodeDateTime($object['end-date']);
-        }
-
-        return parent::_save($root, $object);
-    }
-}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/hprefs.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/hprefs.php
deleted file mode 100644 (file)
index 58b0137..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-/**
- * Implementation for horde user preferences in the Kolab XML format.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/hprefs.php,v 1.8 2009/01/06 17:49:23 jan Exp $
- *
- * @package Kolab_Format
- */
-
-/**
- * Kolab XML handler for client preferences.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/hprefs.php,v 1.8 2009/01/06 17:49:23 jan Exp $
- *
- * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML_hprefs extends Horde_Kolab_Format_XML {
-    /**
-     * Specific data fields for the prefs object
-     *
-     * @var Kolab
-     */
-    var $_fields_specific;
-
-    /**
-     * Automatically create categories if they are missing?
-     *
-     * @var boolean
-     */
-    var $_create_categories = false;
-
-    /**
-     * Constructor
-     */
-    function Horde_Kolab_Format_XML_hprefs()
-    {
-        $this->_root_name = 'h-prefs';
-
-        /** Specific preferences 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,
-            ),
-            'pref' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                'array'   => array(
-                    'type' => HORDE_KOLAB_XML_TYPE_STRING,
-                    'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-                ),
-            ),
-        );
-
-        parent::Horde_Kolab_Format_XML();
-    }
-
-    /**
-     * Load an object based on the given XML string.
-     *
-     * @param string $xmltext  The XML of the message as string.
-     *
-     * @return array|PEAR_Error The data array representing the object.
-     */
-    function load(&$xmltext)
-    {
-        $object = parent::load($xmltext);
-
-        if (empty($object['application'])) {
-            if (!empty($object['categories'])) {
-                $object['application'] = $object['categories'];
-                unset($object['categories']);
-            } else {
-                return PEAR::raiseError('Preferences XML object is missing an application setting.');
-            }
-        }
-
-        return $object;
-    }
-
-    /**
-     * Convert the data to a XML string.
-     *
-     * @param array $attributes  The data array representing the note.
-     *
-     * @return string|PEAR_Error The data as XML string.
-     */
-    function save($object)
-    {
-        if (empty($object['application'])) {
-            if (!empty($object['categories'])) {
-                $object['application'] = $object['categories'];
-                unset($object['categories']);
-            } else {
-                return PEAR::raiseError('Preferences XML object is missing an application setting.');
-            }
-        }
-
-        return parent::save($object);
-    }
-}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/note.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/note.php
deleted file mode 100644 (file)
index bb69c2e..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-/**
- * Implementation for notes in the Kolab XML format.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/note.php,v 1.6 2008/12/12 11:25:52 wrobel Exp $
- *
- * @package Kolab_Format
- */
-
-/**
- * Kolab XML handler for note groupware objects.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/note.php,v 1.6 2008/12/12 11:25:52 wrobel Exp $
- *
- * Copyright 2007-2008 Klarälvdalens Datakonsult AB
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML_note extends Horde_Kolab_Format_XML {
-    /**
-     * Specific data fields for the note object
-     *
-     * @var Kolab
-     */
-    var $_fields_specific;
-
-    /**
-     * Constructor
-     */
-    function Horde_Kolab_Format_XML_note()
-    {
-        $this->_root_name = 'note';
-
-        /** Specific note fields, in kolab format specification order
-         */
-        $this->_fields_specific = array(
-            'summary' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => '',
-            ),
-            'background-color' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_COLOR,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => '#000000',
-            ),
-            'foreground-color' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_COLOR,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => '#ffff00',
-            ),
-        );
-
-        parent::Horde_Kolab_Format_XML();
-    }
-
-    /**
-     * Load the groupware object based on the specifc XML values.
-     *
-     * @access protected
-     *
-     * @param array $children An array of XML nodes.
-     *
-     * @return array|PEAR_Error Array with the object data
-     */
-    function _load(&$children)
-    {
-        $object = $this->_loadArray($children, $this->_fields_specific);
-        if (is_a($object, 'PEAR_Error')) {
-            return $object;
-        }
-
-        $object['desc'] = $object['summary'];
-        unset($object['summary']);
-
-        return $object;
-    }
-
-    /**
-     * Save the specific XML values.
-     *
-     * @access protected
-     *
-     * @param array $root     The XML document root.
-     * @param array $object   The resulting data array.
-     *
-     * @return boolean|PEAR_Error True on success.
-     */
-    function _save($root, $object)
-    {
-        $object['summary'] = $object['desc'];
-        unset($object['desc']);
-
-        return $this->_saveArray($root, $object, $this->_fields_specific);
-    }
-}
diff --git a/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/task.php b/framework/Kolab_Format/lib/Horde/Kolab/Format/XML/task.php
deleted file mode 100644 (file)
index 50d516f..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-/**
- * Implementation for tasks in the Kolab XML format.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/task.php,v 1.7 2008/12/12 11:25:52 wrobel Exp $
- *
- * @package Kolab_Format
- */
-
-/**
- * Kolab XML handler for task groupware objects.
- *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/task.php,v 1.7 2008/12/12 11:25:52 wrobel Exp $
- *
- * Copyright 2007-2008 Klarälvdalens Datakonsult AB
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- *
- * @since   Horde 3.2
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @author  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Format
- */
-class Horde_Kolab_Format_XML_task extends Horde_Kolab_Format_XML {
-    /**
-     * Specific data fields for the note object
-     *
-     * @var array
-     */
-    var $_fields_specific;
-
-    /**
-     * Constructor
-     */
-    function Horde_Kolab_Format_XML_task()
-    {
-        $this->_root_name = 'task';
-
-        /** Specific task fields, in kolab format specification order
-         */
-        $this->_fields_specific = array(
-            'summary' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => '',
-            ),
-            'location' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => '',
-            ),
-            'creator'   => $this->_fields_simple_person,
-            'organizer' => $this->_fields_simple_person,
-            'start-date' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_DATE_OR_DATETIME,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'alarm' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_INTEGER,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'recurrence' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_COMPOSITE,
-                'value'   => HORDE_KOLAB_XML_VALUE_CALCULATED,
-                'load'    => 'Recurrence',
-                'save'    => 'Recurrence',
-            ),
-            'attendee' => $this->_fields_attendee,
-            'priority' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_INTEGER,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => 3,
-            ),
-            'completed' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_INTEGER,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => 0,
-            ),
-            'status' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_DEFAULT,
-                'default' => 'not-started',
-            ),
-            'due-date' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_DATE_OR_DATETIME,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'parent' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            // These are not part of the Kolab specification but it is
-            // ok if the client supports additional entries
-            'estimate' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-            'completed_date' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_DATE_OR_DATETIME,
-                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
-            ),
-        );
-
-        parent::Horde_Kolab_Format_XML();
-    }
-
-    /**
-     * Load the groupware object based on the specifc XML values.
-     *
-     * @param array $children An array of XML nodes.
-     *
-     * @return array|PEAR_Error Array with data.
-     */
-    function _load(&$children)
-    {
-        $object = $this->_loadArray($children, $this->_fields_specific);
-        if (is_a($object, 'PEAR_Error')) {
-            return $object;
-        }
-
-        $object['name'] = $object['summary'];
-        unset($object['summary']);
-
-        if (empty($object['completed-date'])) {
-            $object['completed-date'] = null;
-        }
-
-        if (empty($object['alarm'])) {
-            $object['alarm'] = null;
-        }
-
-        if (isset($object['due-date'])) {
-            $object['due'] = $object['due-date'];
-            unset($object['due-date']);
-        } else {
-            $object['due'] = null;
-        }
-
-        if (isset($object['start-date'])) {
-            $object['start'] = $object['start-date'];
-            unset($object['start-date']);
-        } else {
-            $object['start'] = null;
-        }
-
-        if (!isset($object['estimate'])) {
-            $object['estimate'] = null;
-        } else {
-            $object['estimate'] = (float) $object['estimate'];
-        }
-
-        if (!isset($object['parent'])) {
-            $object['parent'] = null;
-        }
-
-        $object['completed'] = (bool) Kolab::percentageToBoolean($object['completed']);
-
-        if (isset($object['organizer']) && isset($object['organizer']['smtp-address'])) {
-            $object['assignee'] = $object['organizer']['smtp-address'];
-        }
-
-        return $object;
-    }
-
-    /**
-     * Save the specific XML values.
-     *
-     * @param array $root     The XML document root.
-     * @param array $object   The resulting data array.
-     *
-     * @return boolean|PEAR_Error True on success.
-     */
-    function _save($root, $object)
-    {
-        $object['summary'] = $object['name'];
-        unset($object['name']);
-
-        $object['due-date'] = $object['due'];
-        unset($object['due']);
-
-        $object['start-date'] = $object['start'];
-        unset($object['start']);
-
-        $object['estimate'] = number_format($object['estimate'], 2);
-
-        $object['completed'] = Kolab::BooleanToPercentage($object['completed']);
-
-        return $this->_saveArray($root, $object, $this->_fields_specific);
-    }
-}