Use new libkolab XML object reading/writing functions in preparation of adding Kolab format v2 capabilities
This commit is contained in:
parent
06e6c43db0
commit
d55e56c07c
10 changed files with 127 additions and 92 deletions
|
@ -31,38 +31,59 @@ abstract class kolab_format
|
|||
|
||||
public /*abstract*/ $CTYPE;
|
||||
|
||||
protected /*abstract*/ $objclass;
|
||||
protected /*abstract*/ $read_func;
|
||||
protected /*abstract*/ $write_func;
|
||||
|
||||
protected $obj;
|
||||
protected $data;
|
||||
protected $xmldata;
|
||||
protected $xmlobject;
|
||||
protected $loaded = false;
|
||||
protected $version = 3.0;
|
||||
|
||||
const VERSION = '3.0';
|
||||
const KTYPE_PREFIX = 'application/x-vnd.kolab.';
|
||||
const PRODUCT_ID = 'Roundcube-libkolab-0.9';
|
||||
|
||||
/**
|
||||
* Factory method to instantiate a kolab_format object of the given type
|
||||
* Factory method to instantiate a kolab_format object of the given type and version
|
||||
*
|
||||
* @param string Object type to instantiate
|
||||
* @param string Cached xml data to initialize with
|
||||
* @param float Format version
|
||||
* @return object kolab_format
|
||||
*/
|
||||
public static function factory($type, $xmldata = null)
|
||||
public static function factory($type, $xmldata = null, $version = 3.0)
|
||||
{
|
||||
if (!isset(self::$timezone))
|
||||
self::$timezone = new DateTimeZone('UTC');
|
||||
|
||||
if (!self::supports($version))
|
||||
return PEAR::raiseError("No support for Kolab format version " . $version);
|
||||
|
||||
$type = preg_replace('/configuration\.[a-z.]+$/', 'configuration', $type);
|
||||
$suffix = preg_replace('/[^a-z]+/', '', $type);
|
||||
$classname = 'kolab_format_' . $suffix;
|
||||
if (class_exists($classname))
|
||||
return new $classname($xmldata);
|
||||
return new $classname($xmldata, $version);
|
||||
|
||||
return PEAR::raiseError("Failed to load Kolab Format wrapper for type " . $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine support for the given format version
|
||||
*
|
||||
* @param float Format version to check
|
||||
* @return boolean True if supported, False otherwise
|
||||
*/
|
||||
public static function supports($version)
|
||||
{
|
||||
if ($version == 2.0)
|
||||
return class_exists('kolabobject');
|
||||
// default is version 3
|
||||
return class_exists('kolabformat');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given date/time value into a cDateTime object
|
||||
*
|
||||
|
@ -184,6 +205,23 @@ abstract class kolab_format
|
|||
return preg_replace('/dictionary.[a-z.]+$/', 'dictionary', substr($x_kolab_type, strlen(self::KTYPE_PREFIX)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor of all kolab_format_* objects
|
||||
*/
|
||||
public function __construct($xmldata = null, $version = null)
|
||||
{
|
||||
$this->obj = new $this->objclass;
|
||||
$this->xmldata = $xmldata;
|
||||
|
||||
if ($version)
|
||||
$this->version = $version;
|
||||
|
||||
// use libkolab module if available
|
||||
if (class_exists('kolabobject'))
|
||||
$this->xmlobject = new XMLObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for format errors after calling kolabformat::write*()
|
||||
*
|
||||
|
@ -245,6 +283,39 @@ abstract class kolab_format
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constant value for libkolab's version parameter
|
||||
*
|
||||
* @param float Version value to convert
|
||||
* @return int Constant value of either kolabobject::KolabV2 or kolabobject::KolabV3 or false if kolabobject module isn't available
|
||||
*/
|
||||
protected function libversion($v = null)
|
||||
{
|
||||
if (class_exists('kolabobject')) {
|
||||
$version = $v ?: $this->version;
|
||||
if ($version <= 2.0)
|
||||
return kolabobject::KolabV2;
|
||||
else
|
||||
return kolabobject::KolabV3;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the correct libkolab(xml) wrapper function for the given call
|
||||
* depending on the available PHP modules
|
||||
*/
|
||||
protected function libfunc($func)
|
||||
{
|
||||
if (is_array($func) || strpos($func, '::'))
|
||||
return $func;
|
||||
else if (class_exists('kolabobject'))
|
||||
return array($this->xmlobject, $func);
|
||||
else
|
||||
return 'kolabformat::' . $func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direct getter for object properties
|
||||
*/
|
||||
|
@ -257,22 +328,29 @@ abstract class kolab_format
|
|||
* Load Kolab object data from the given XML block
|
||||
*
|
||||
* @param string XML data
|
||||
* @return boolean True on success, False on failure
|
||||
*/
|
||||
public function load($xml)
|
||||
{
|
||||
$this->obj = call_user_func($this->read_func, $xml, false);
|
||||
$r = call_user_func($this->libfunc($this->read_func), $xml, $this->libversion());
|
||||
if (is_resource($r))
|
||||
$this->obj = new $this->objclass($r);
|
||||
else if (is_a($r, $this->objclass))
|
||||
$this->obj = $r;
|
||||
|
||||
$this->loaded = !$this->format_errors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write object data to XML format
|
||||
*
|
||||
* @param float Format version to write
|
||||
* @return string XML data
|
||||
*/
|
||||
public function write()
|
||||
public function write($version = null)
|
||||
{
|
||||
$this->init();
|
||||
$this->xmldata = call_user_func($this->write_func, $this->obj);
|
||||
$this->xmldata = call_user_func($this->libfunc($this->write_func), $this->obj, $this->libversion($version), self::PRODUCT_ID);
|
||||
|
||||
if (!$this->format_errors())
|
||||
$this->update_uid();
|
||||
|
|
|
@ -26,6 +26,7 @@ class kolab_format_configuration extends kolab_format
|
|||
{
|
||||
public $CTYPE = 'application/x-vnd.kolab.configuration';
|
||||
|
||||
protected $objclass = 'Configuration';
|
||||
protected $read_func = 'kolabformat::readConfiguration';
|
||||
protected $write_func = 'kolabformat::writeConfiguration';
|
||||
|
||||
|
@ -35,12 +36,6 @@ class kolab_format_configuration extends kolab_format
|
|||
);
|
||||
|
||||
|
||||
function __construct($xmldata = null)
|
||||
{
|
||||
$this->obj = new Configuration;
|
||||
$this->xmldata = $xmldata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set properties to the kolabformat object
|
||||
*
|
||||
|
|
|
@ -26,8 +26,9 @@ class kolab_format_contact extends kolab_format
|
|||
{
|
||||
public $CTYPE = 'application/vcard+xml';
|
||||
|
||||
protected $read_func = 'kolabformat::readContact';
|
||||
protected $write_func = 'kolabformat::writeContact';
|
||||
protected $objclass = 'Contact';
|
||||
protected $read_func = 'readContact';
|
||||
protected $write_func = 'writeContact';
|
||||
|
||||
public static $fulltext_cols = array('name', 'firstname', 'surname', 'middlename', 'email');
|
||||
|
||||
|
@ -106,10 +107,9 @@ class kolab_format_contact extends kolab_format
|
|||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
function __construct($xmldata = null)
|
||||
function __construct($xmldata = null, $version = 3.0)
|
||||
{
|
||||
$this->obj = new Contact;
|
||||
$this->xmldata = $xmldata;
|
||||
parent::__construct($xmldata, $version);
|
||||
|
||||
// complete phone types
|
||||
$this->phonetypes['homefax'] |= Telephone::Home;
|
||||
|
|
|
@ -26,16 +26,11 @@ class kolab_format_distributionlist extends kolab_format
|
|||
{
|
||||
public $CTYPE = 'application/vcard+xml';
|
||||
|
||||
protected $read_func = 'kolabformat::readDistlist';
|
||||
protected $write_func = 'kolabformat::writeDistlist';
|
||||
protected $objclass = 'DistList';
|
||||
protected $read_func = 'readDistlist';
|
||||
protected $write_func = 'writeDistlist';
|
||||
|
||||
|
||||
function __construct($xmldata = null)
|
||||
{
|
||||
$this->obj = new DistList;
|
||||
$this->xmldata = $xmldata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set properties to the kolabformat object
|
||||
*
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
class kolab_format_event extends kolab_format_xcal
|
||||
{
|
||||
protected $read_func = 'kolabformat::readEvent';
|
||||
protected $write_func = 'kolabformat::writeEvent';
|
||||
protected $objclass = 'Event';
|
||||
protected $read_func = 'readEvent';
|
||||
protected $write_func = 'writeEvent';
|
||||
|
||||
private $kolab2_rolemap = array(
|
||||
'required' => 'REQ-PARTICIPANT',
|
||||
|
@ -43,24 +44,15 @@ class kolab_format_event extends kolab_format_xcal
|
|||
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
* Clones into an instance of libcalendaring's extended EventCal class
|
||||
*
|
||||
* @return mixed EventCal object or false on failure
|
||||
*/
|
||||
function __construct($xmldata = null)
|
||||
public function to_libcal()
|
||||
{
|
||||
$this->obj = new Event;
|
||||
$this->xmldata = $xmldata;
|
||||
return class_exists('kolabcalendaring') ? new EventCal($this->obj) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones into an instance of libcalendaring's extended EventCal class
|
||||
*
|
||||
* @return mixed EventCal object or false on failure
|
||||
*/
|
||||
public function to_libcal()
|
||||
{
|
||||
return class_exists('kolabcalendaring') ? new EventCal($this->obj) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set event properties to the kolabformat object
|
||||
*
|
||||
|
|
|
@ -26,16 +26,11 @@ class kolab_format_journal extends kolab_format
|
|||
{
|
||||
public $CTYPE = 'application/calendar+xml';
|
||||
|
||||
protected $read_func = 'kolabformat::readJournal';
|
||||
protected $write_func = 'kolabformat::writeJournal';
|
||||
protected $objclass = 'Journal';
|
||||
protected $read_func = 'readJournal';
|
||||
protected $write_func = 'writeJournal';
|
||||
|
||||
|
||||
function __construct($xmldata = null)
|
||||
{
|
||||
$this->obj = new Journal;
|
||||
$this->xmldata = $xmldata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set properties to the kolabformat object
|
||||
*
|
||||
|
|
|
@ -26,16 +26,11 @@ class kolab_format_note extends kolab_format
|
|||
{
|
||||
public $CTYPE = 'application/x-vnd.kolab.note';
|
||||
|
||||
protected $read_func = 'kolabformat::readNote';
|
||||
protected $write_func = 'kolabformat::writeNote';
|
||||
protected $objclass = 'Note';
|
||||
protected $read_func = 'readNote';
|
||||
protected $write_func = 'writeNote';
|
||||
|
||||
|
||||
function __construct($xmldata = null)
|
||||
{
|
||||
$this->obj = new Note;
|
||||
$this->xmldata = $xmldata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set properties to the kolabformat object
|
||||
*
|
||||
|
|
|
@ -24,16 +24,11 @@
|
|||
|
||||
class kolab_format_task extends kolab_format_xcal
|
||||
{
|
||||
protected $read_func = 'kolabformat::readTodo';
|
||||
protected $write_func = 'kolabformat::writeTodo';
|
||||
protected $objclass = 'Todo';
|
||||
protected $read_func = 'readTodo';
|
||||
protected $write_func = 'writeTodo';
|
||||
|
||||
|
||||
function __construct($xmldata = null)
|
||||
{
|
||||
$this->obj = new Todo;
|
||||
$this->xmldata = $xmldata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set properties to the kolabformat object
|
||||
*
|
||||
|
|
|
@ -31,6 +31,7 @@ class kolab_storage
|
|||
const SERVERSIDE_SUBSCRIPTION = 0;
|
||||
const CLIENTSIDE_SUBSCRIPTION = 1;
|
||||
|
||||
public static $version = 3.0;
|
||||
public static $last_error;
|
||||
|
||||
private static $ready = false;
|
||||
|
@ -49,6 +50,7 @@ class kolab_storage
|
|||
|
||||
$rcmail = rcube::get_instance();
|
||||
self::$config = $rcmail->config;
|
||||
self::$version = $rcmail->config->get('kolab_format_version', self::$version);
|
||||
self::$imap = $rcmail->get_storage();
|
||||
self::$ready = class_exists('kolabformat') &&
|
||||
(self::$imap->get_capability('METADATA') || self::$imap->get_capability('ANNOTATEMORE') || self::$imap->get_capability('ANNOTATEMORE2'));
|
||||
|
|
|
@ -466,39 +466,27 @@ class kolab_storage_folder
|
|||
return false;
|
||||
}
|
||||
|
||||
$format = kolab_format::factory($object_type);
|
||||
|
||||
if (is_a($format, 'PEAR_Error'))
|
||||
return false;
|
||||
|
||||
// check kolab format version
|
||||
$mime_version = $headers->others['x-kolab-mime-version'];
|
||||
if (empty($mime_version)) {
|
||||
$format_version = $headers->others['x-kolab-mime-version'];
|
||||
if (empty($format_version)) {
|
||||
list($xmltype, $subtype) = explode('.', $object_type);
|
||||
$xmlhead = substr($xml, 0, 512);
|
||||
|
||||
// detect old Kolab 2.0 format
|
||||
if (strpos($xmlhead, '<' . $xmltype) !== false && strpos($xmlhead, 'xmlns=') === false)
|
||||
$mime_version = 2.0;
|
||||
$format_version = 2.0;
|
||||
else
|
||||
$mime_version = 3.0; // assume 3.0
|
||||
$format_version = 3.0; // assume 3.0
|
||||
}
|
||||
|
||||
if ($mime_version <= 2.0) {
|
||||
// read Kolab 2.0 format
|
||||
$handler = class_exists('Horde_Kolab_Format') ? Horde_Kolab_Format::factory('XML', $xmltype, array('subtype' => $subtype)) : null;
|
||||
if (!is_object($handler) || is_a($handler, 'PEAR_Error')) {
|
||||
return false;
|
||||
}
|
||||
// get Kolab format handler for the given type
|
||||
$format = kolab_format::factory($object_type, $format_version);
|
||||
|
||||
// XML-to-array
|
||||
$object = $handler->load($xml);
|
||||
$format->fromkolab2($object);
|
||||
}
|
||||
else {
|
||||
// load Kolab 3 format using libkolabxml
|
||||
$format->load($xml);
|
||||
}
|
||||
if (is_a($format, 'PEAR_Error'))
|
||||
return false;
|
||||
|
||||
// load Kolab object from XML part
|
||||
$format->load($xml);
|
||||
|
||||
if ($format->is_valid()) {
|
||||
$object = $format->to_array();
|
||||
|
@ -696,13 +684,13 @@ class kolab_storage_folder
|
|||
|
||||
// create new kolab_format instance
|
||||
if (!$format)
|
||||
$format = kolab_format::factory($type);
|
||||
$format = kolab_format::factory($type, kolab_storage::$version);
|
||||
|
||||
if (PEAR::isError($format))
|
||||
return false;
|
||||
|
||||
$format->set($object);
|
||||
$xml = $format->write();
|
||||
$xml = $format->write(kolab_storage::$version);
|
||||
$object['uid'] = $format->uid; // read UID from format
|
||||
$object['_formatobj'] = $format;
|
||||
|
||||
|
@ -721,7 +709,7 @@ class kolab_storage_folder
|
|||
}
|
||||
$headers['Date'] = date('r');
|
||||
$headers['X-Kolab-Type'] = kolab_format::KTYPE_PREFIX . $type;
|
||||
$headers['X-Kolab-Mime-Version'] = kolab_format::VERSION;
|
||||
$headers['X-Kolab-Mime-Version'] = kolab_storage::$version;
|
||||
$headers['Subject'] = $object['uid'];
|
||||
// $headers['Message-ID'] = $rcmail->gen_message_id();
|
||||
$headers['User-Agent'] = $rcmail->config->get('useragent');
|
||||
|
|
Loading…
Add table
Reference in a new issue