--- /dev/null
+<?php
+/**
+ * Indicates a parse error when reading a Kolab Format object.
+ *
+ * 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_Format
+ */
+
+/**
+ * Indicates a parse error when reading a Kolab Format object.
+ *
+ * Copyright 2009-2010 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.fsf.org/copyleft/lgpl.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_Format
+ */
+class Horde_Kolab_Format_Exception_ParseError extends Horde_Kolab_Format_Exception
+{
+ /**
+ * Constructor.
+ *
+ * @param string $input The input that failed to parse.
+ */
+ public function __construct($input)
+ {
+ if (strlen((string) $input) > 50) {
+ $output = substr((string) $input, 50) . '... [shortened to 50 characters]';
+ } else {
+ $output = (string) $input;
+ }
+ parent::__construct(
+ sprintf(
+ "Failed parsing Kolab object input data of type %s! Input was:\n%s",
+ gettype($input), $output
+ )
+ );
+ }
+}
\ No newline at end of file
* @throws Horde_Kolab_Format_Exception If the specified handler does not
* exist.
*/
- public function create($format_type = '', $object_type = '', $params = null)
+ public function create($format = 'Xml', $object = '', $params = null)
{
- $class = 'Horde_Kolab_Format_' . ucfirst(strtolower($format_type)) . '_'
- . ucfirst(strtolower(str_replace('-', '', $object_type)));
+ $parser = ucfirst(strtolower($format));
+ $class = basename(
+ 'Horde_Kolab_Format_' . $parser . '_'
+ . ucfirst(strtolower(str_replace('-', '', $object)))
+ );
if (!isset($this->_instances[$class])) {
if (class_exists($class)) {
- $this->_instances[$class] = new $class($params);
+ switch ($parser) {
+ case 'Xml':
+ $this->_instances[$class] = new $class(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ ),
+ $params
+ );
+ break;
+ default:
+ throw new Horde_Kolab_Format_Exception(
+ sprintf(
+ 'Failed to initialize the specified parser (Parser type %s does not exist)!',
+ $parser
+ )
+ );
+ }
} else {
throw new Horde_Kolab_Format_Exception(
sprintf(
* @throws Horde_Kolab_Format_Exception If the specified handler does not
* exist.
*/
- public function createTimed($format_type = '', $object_type = '', $params = null)
+ public function createTimed($format = 'Xml', $object = '', $params = null)
{
if (isset($params['handler'])) {
$handler = $params['handler'];
} else {
- $handler = $this->create($format_type, $object_type, $params);
+ $handler = $this->create($format, $object, $params);
}
if (!class_exists('Horde_Support_Timer')) {
throw new Horde_Kolab_Format_Exception('The Horde_Support package seems to be missing (Class Horde_Support_Timer is missing)!');
const TYPE_MULTIPLE = 8;
/**
+ * The parser dealing with the input.
+ *
+ * @var int
+ */
+ protected $_parser;
+
+ /**
* Requested version of the data array to return
*
* @var int
*
* @param array $params Any additional options
*/
- public function __construct($params = null)
- {
+ public function __construct(
+ Horde_Kolab_Format_Xml_Parser $parser,
+ $params = null
+ ) {
+ $this->_parser = $parser;
+
if (is_array($params) && isset($params['version'])) {
$this->_version = $params['version'];
} else {
*/
public function load(&$xmltext)
{
- try {
- $this->_parseXml($xmltext);
- } catch (Horde_Kolab_Format_Exception $e) {
- /**
- * If the first call does not return successfully this might mean we
- * got an attachment with broken encoding. There are some Kolab
- * client versions in the wild that might have done that. So the
- * 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) {
- $xmltext = mb_convert_encoding($xmltext, 'UTF-8', 'ISO-8859-1');
- }
- $this->_parseXml($xmltext);
- }
- if (!$this->_xmldoc->documentElement->hasChildNodes()) {
- throw new Horde_Kolab_Format_Exception(Horde_Kolab_Format_Translation::t("No or unreadable content in Kolab XML object"));
- }
+ $this->_xmldoc = $this->_parser->parse($xmltext);
// fresh object data
$object = array();
}
/**
- * Parse the XML string. The root node is returned on success.
- *
- * @param string &$xmltext The XML of the message as string.
- *
- * @return NULL
- *
- * @throws Horde_Kolab_Format_Exception If parsing the XML data failed.
- *
- * @todo Make protected (fix the XmlTest for that)
- */
- public function _parseXml(&$xmltext)
- {
- $this->_xmldoc = new DOMDocument('1.0', 'UTF-8');
-
- $this->_xmldoc->preserveWhiteSpace = false;
- $this->_xmldoc->formatOutput = true;
-
- @$this->_xmldoc->loadXML($xmltext);
- if (empty($this->_xmldoc->documentElement)) {
- throw new Horde_Kolab_Format_Exception(Horde_Kolab_Format_Translation::t("No or unreadable content in Kolab XML object"));
- }
-
- }
-
- /**
* Convert the data to a XML string.
*
* @param array $object The data array representing the note.
/**
* Constructor
*/
- public function __construct()
+ public function __construct($parser, $params = array())
{
$this->_root_name = 'annotations';
),
);
- parent::__construct();
+ parent::__construct($parser, $params);
}
/**
/**
* Constructor
*/
- public function __construct()
+ public function __construct($parser, $params = array())
{
$this->_root_name = "contact";
),
);
- parent::__construct();
+ parent::__construct($parser, $params);
}
/**
/**
* Constructor
*/
- public function __construct()
+ public function __construct($parser, $params = array())
{
$this->_root_name = "distribution-list";
)
);
- parent::__construct();
+ parent::__construct($parser, $params);
}
/**
/**
* Constructor
*/
- public function __construct()
+ public function __construct($parser, $params = array())
{
$this->_root_name = 'event';
),
);
- parent::__construct();
+ parent::__construct($parser, $params);
}
/**
/**
* Constructor
*/
- public function __construct()
+ public function __construct($parser, $params = array())
{
$this->_root_name = 'h-prefs';
),
);
- parent::__construct();
+ parent::__construct($parser, $params);
}
/**
/**
* Constructor
*/
- public function __construct()
+ public function __construct($parser, $params = array())
{
$this->_root_name = 'note';
),
);
- parent::__construct();
+ parent::__construct($parser, $params);
}
/**
--- /dev/null
+<?php
+/**
+ * Handles parsing the provided XML input.
+ *
+ * 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_Format
+ */
+
+/**
+ * Handles parsing the provided XML input.
+ *
+ * Copyright 2007-2009 Klarälvdalens Datakonsult AB
+ * Copyright 2010 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_Format
+ */
+class Horde_Kolab_Format_Xml_Parser
+{
+ /**
+ * The XML parser.
+ *
+ * @var DOMDocument
+ */
+ private $_document;
+
+ /**
+ * Constructor.
+ *
+ * @param DOMDocument $document The XML parser.
+ */
+ public function __construct(DOMDocument $document)
+ {
+ $this->_document = $document;
+ $this->_document->preserveWhiteSpace = false;
+ $this->_document->formatOutput = true;
+ }
+
+ /**
+ * Load an object based on the given XML string.
+ *
+ * @param string $input The XML of the message as string.
+ *
+ * @return array The data array representing the object.
+ *
+ * @throws Horde_Kolab_Format_Exception If parsing the XML data failed.
+ *
+ * @todo Check encoding of the returned array. It seems to be ISO-8859-1 at
+ * the moment and UTF-8 would seem more appropriate.
+ */
+ public function parse($input)
+ {
+ try {
+ return $this->_parseXml($input);
+ } catch (Horde_Kolab_Format_Exception_ParseError $e) {
+ /**
+ * If the first call does not return successfully this might mean we
+ * got an attachment with broken encoding. There are some Kolab
+ * client versions in the wild that might have done that. So the
+ * next section starts a second attempt by guessing the encoding and
+ * trying again.
+ */
+ if (0 !== strcasecmp(
+ mb_detect_encoding($input, 'UTF-8, ISO-8859-1'), 'UTF-8'
+ )) {
+ $input = mb_convert_encoding($input, 'UTF-8', 'ISO-8859-1');
+ }
+ return $this->_parseXml($input);
+ }
+ }
+
+ /**
+ * Parse the XML string. The root node is returned on success.
+ *
+ * @param string $input The XML of the message as string.
+ *
+ * @return NULL
+ *
+ * @throws Horde_Kolab_Format_Exception If parsing the XML data failed.
+ *
+ * @todo Make protected (fix the XmlTest for that)
+ */
+ private function _parseXml($input)
+ {
+ @$this->_document->loadXML($input);
+ if (empty($this->_document->documentElement) || !$this->_document->documentElement->hasChildNodes()) {
+ throw new Horde_Kolab_Format_Exception_ParseError($input);
+ }
+ return $this->_document;
+ }
+}
/**
* Constructor
*/
- public function __construct()
+ public function __construct($parser, $params = array())
{
$this->_root_name = 'task';
),
);
- parent::__construct();
+ parent::__construct($parser, $params);
}
/**
<active>yes</active>
</lead>
<date>2010-12-10</date>
- <time>06:10:51</time>
+ <time>12:02:39</time>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
<file name="Base.php" role="php" />
<file name="Timed.php" role="php" />
</dir> <!-- /lib/Horde/Kolab/Format/Decorator -->
+ <dir name="Exception">
+ <file name="ParseError.php" role="php" />
+ </dir> <!-- /lib/Horde/Kolab/Format/Exception -->
<dir name="Xml">
<file name="Annotation.php" role="php" />
<file name="Contact.php" role="php" />
<file name="Event.php" role="php" />
<file name="Hprefs.php" role="php" />
<file name="Note.php" role="php" />
+ <file name="Parser.php" role="php" />
<file name="Task.php" role="php" />
</dir> <!-- /lib/Horde/Kolab/Format/Xml -->
<file name="Cli.php" role="php" />
<install as="Horde/Kolab/Format/Xml.php" name="lib/Horde/Kolab/Format/Xml.php" />
<install as="Horde/Kolab/Format/Decorator/Base.php" name="lib/Horde/Kolab/Format/Decorator/Base.php" />
<install as="Horde/Kolab/Format/Decorator/Timed.php" name="lib/Horde/Kolab/Format/Decorator/Timed.php" />
+ <install as="Horde/Kolab/Format/Exception/ParseError.php" name="lib/Horde/Kolab/Format/Exception/ParseError.php" />
<install as="Horde/Kolab/Format/Xml/Annotation.php" name="lib/Horde/Kolab/Format/Xml/Annotation.php" />
<install as="Horde/Kolab/Format/Xml/Contact.php" name="lib/Horde/Kolab/Format/Xml/Contact.php" />
<install as="Horde/Kolab/Format/Xml/Distributionlist.php" name="lib/Horde/Kolab/Format/Xml/Distributionlist.php" />
<install as="Horde/Kolab/Format/Xml/Event.php" name="lib/Horde/Kolab/Format/Xml/Event.php" />
<install as="Horde/Kolab/Format/Xml/Hprefs.php" name="lib/Horde/Kolab/Format/Xml/Hprefs.php" />
<install as="Horde/Kolab/Format/Xml/Note.php" name="lib/Horde/Kolab/Format/Xml/Note.php" />
+ <install as="Horde/Kolab/Format/Xml/Parser.php" name="lib/Horde/Kolab/Format/Xml/Parser.php" />
<install as="Horde/Kolab/Format/Xml/Task.php" name="lib/Horde/Kolab/Format/Xml/Task.php" />
<install as="locale/Horde_Kolab_Format.pot" name="locale/Horde_Kolab_Format.pot" />
<install as="locale/ar/LC_MESSAGES/Horde_Kolab_Format.mo" name="locale/ar/LC_MESSAGES/Horde_Kolab_Format.mo" />
*/
public function testSingleEmail()
{
- $contact = new Horde_Kolab_Format_Xml_contact_Dummy();
+ $contact = new Horde_Kolab_Format_Xml_Contact_Dummy(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$object = array('uid' => '1',
'full-name' => 'User Name',
'email' => 'user@example.org');
*/
public function testPGP()
{
- $contact = new Horde_Kolab_Format_Xml_contact_Dummy();
+ $contact = new Horde_Kolab_Format_Xml_Contact_Dummy(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$object = array('uid' => '1',
'full-name' => 'User Name',
'pgp-publickey' => 'PGP Test Key',
{
global $prefs;
- $contact = new Horde_Kolab_Format_Xml_contact();
+ $contact = new Horde_Kolab_Format_Xml_Contact(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$xml = file_get_contents(dirname(__FILE__)
. '/fixtures/contact_category.xml');
$object = $contact->load($xml);
/* Monkey patch to allw the value to be set. */
$prefs->_prefs['categories'] = array('v' => '');
- $contact = new Horde_Kolab_Format_Xml_contact();
+ $contact = new Horde_Kolab_Format_Xml_Contact(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$xml = file_get_contents(dirname(__FILE__)
. '/fixtures/contact_category.xml');
$object = $contact->load($xml);
$result = $xml->load($event);
// Check that the xml loads fine
- $this->assertEquals(mb_convert_encoding($result['body'], 'UTF-8',
- 'ISO-8859-1'), '...übbe...');
+ $this->assertEquals('...übbe...', $result['body']);
// Load XML
$event = file_get_contents(dirname(__FILE__)
. '/fixtures/event_umlaut_broken.xml');
$result = $xml->load($event);
- /**
- * FIXME: Why does Kolab Format return ISO-8859-1? UTF-8 would seem more
- * appropriate
- */
- $this->assertEquals(mb_convert_encoding($result['body'], 'UTF-8',
- 'ISO-8859-1'), '...übbe...');
+ $this->assertEquals('...übbe...', $result['body']);
}
}
*/
public function testConversionFromOld()
{
- $preferences = new Horde_Kolab_Format_Xml_hprefs_Dummy();
+ $preferences = new Horde_Kolab_Format_Xml_hprefs_Dummy(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$xml = file_get_contents(dirname(__FILE__)
. '/fixtures/preferences_read_old.xml');
*/
public function testBasic()
{
- $xml = new Horde_Kolab_Format_XML();
+ $xml = new Horde_Kolab_Format_XML(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$xml->_prepareSave();
$base = $xml->_xmldoc->saveXML();
$this->assertEquals("<?xml version=\"1.0\"?>\n<kolab version=\"1.0\"/>\n",
*/
public function testReadable()
{
- $xml = new Horde_Kolab_Format_XML();
+ $this->markTestIncomplete('Roundtrip makes sense, but how to handle empty document?');
+ $xml = new Horde_Kolab_Format_XML(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$xml->_prepareSave();
$base = $xml->_xmldoc->saveXML();
- $xml->_parseXml($base);
+ $xml->load($base);
$this->assertEquals($base, $xml->_xmldoc->saveXML());
}
*/
public function testAdd()
{
- $xml = new Horde_Kolab_Format_XML();
+ $xml = new Horde_Kolab_Format_XML(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$root = $xml->_prepareSave();
$base = $xml->_xmldoc->saveXML();
*/
public function testNodeOps()
{
- $dxml = new Horde_Kolab_Format_Xml_Dummy();
+ $dxml = new Horde_Kolab_Format_Xml_Dummy(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$droot = $dxml->_prepareSave();
// Test calculated nodes
$this->assertEquals("<?xml version=\"1.0\"?>\n<kolab version=\"1.0\">\n <empty2>empty2: , missing</empty2>\n <present1>present1: present1</present1>\n</kolab>\n",
$dxml->_xmldoc->saveXML());
- $xml = new Horde_Kolab_Format_Xml();
+ $xml = new Horde_Kolab_Format_Xml(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$root = $xml->_prepareSave();
$xml->_updateNode($root,
array(),
public function testReleod()
{
// Save an object and reload it
- $xml = new Horde_Kolab_Format_Xml();
+ $xml = new Horde_Kolab_Format_Xml(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$result = $xml->save(array('uid'=>'test',
'body' => 'body',
'dummy' => 'hello',
public function testComplex()
{
// Continue with complex values
- $xml = new Horde_Kolab_Format_Xml();
+ $xml = new Horde_Kolab_Format_Xml(
+ new Horde_Kolab_Format_Xml_Parser(
+ new DOMDocument('1.0', 'UTF-8')
+ )
+ );
$root = $xml->_prepareSave();
// Test saving a composite value