PageRenderTime 26ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/framework/Kolab_Format/lib/Horde/Kolab/Format/Xml.php

https://github.com/wrobel/horde
PHP | 332 lines | 110 code | 35 blank | 187 comment | 7 complexity | 1f903abff5b6a40bee2816467851346d MD5 | raw file
Possible License(s): BSD-2-Clause, AGPL-1.0, LGPL-2.1, LGPL-3.0, BSD-3-Clause, LGPL-2.0, GPL-2.0
  1. <?php
  2. /**
  3. * Implementation of the Kolab XML format.
  4. *
  5. * PHP version 5
  6. *
  7. * @category Kolab
  8. * @package Kolab_Format
  9. * @author Thomas Jarosch <thomas.jarosch@intra2net.com>
  10. * @author Gunnar Wrobel <wrobel@pardus.de>
  11. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  12. * @link http://www.horde.org/libraries/Horde_Kolab_Format
  13. */
  14. /**
  15. * Kolab XML to array hash converter.
  16. *
  17. * For implementing a new format type you will have to inherit this
  18. * class and provide a _load/_save function.
  19. *
  20. * Copyright 2007-2009 Klarälvdalens Datakonsult AB
  21. * Copyright 2010-2012 Horde LLC (http://www.horde.org/)
  22. *
  23. * See the enclosed file COPYING for license information (LGPL). If you did not
  24. * receive this file, see
  25. * http://www.horde.org/licenses/lgpl21.
  26. *
  27. * @category Kolab
  28. * @package Kolab_Format
  29. * @author Thomas Jarosch <thomas.jarosch@intra2net.com>
  30. * @author Gunnar Wrobel <wrobel@pardus.de>
  31. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  32. * @link http://www.horde.org/libraries/Horde_Kolab_Format
  33. */
  34. class Horde_Kolab_Format_Xml implements Horde_Kolab_Format
  35. {
  36. /**
  37. * Defines a XML value that should get a default value if missing
  38. */
  39. const PRODUCT_ID = __CLASS__;
  40. /**
  41. * Defines a XML value that should get a default value if missing
  42. */
  43. const VALUE_DEFAULT = 0;
  44. /**
  45. * Defines a XML value that may be missing
  46. */
  47. const VALUE_MAYBE_MISSING = 1;
  48. /**
  49. * Defines a XML value that may not be missing
  50. */
  51. const VALUE_NOT_EMPTY = 2;
  52. /**
  53. * Defines a XML value that will be calculated by its own function
  54. */
  55. const VALUE_CALCULATED = 3;
  56. /**
  57. * Defines a XML value as string type
  58. */
  59. const TYPE_STRING = 'Horde_Kolab_Format_Xml_Type_String';
  60. /**
  61. * Defines a XML value as integer type
  62. */
  63. const TYPE_INTEGER = 'Horde_Kolab_Format_Xml_Type_Integer';
  64. /**
  65. * Defines a XML value as boolean type
  66. */
  67. const TYPE_BOOLEAN = 'Horde_Kolab_Format_Xml_Type_Boolean';
  68. /**
  69. * Defines a XML value as date type
  70. */
  71. const TYPE_DATE = 'Horde_Kolab_Format_Xml_Type_Date';
  72. /**
  73. * Defines a XML value as datetime type
  74. */
  75. const TYPE_DATETIME = 'Horde_Kolab_Format_Xml_Type_DateTime';
  76. /**
  77. * Defines a XML value as date or datetime type
  78. */
  79. const TYPE_DATE_OR_DATETIME = 'Horde_Kolab_Format_Xml_Type_DateTime';
  80. /**
  81. * Defines a XML value as color type
  82. */
  83. const TYPE_COLOR = 'Horde_Kolab_Format_Xml_Type_Color';
  84. /**
  85. * Defines a XML value as composite value type
  86. */
  87. const TYPE_COMPOSITE = 'Horde_Kolab_Format_Xml_Type_Composite';
  88. /**
  89. * Defines a XML value as array type
  90. */
  91. const TYPE_MULTIPLE = 'Horde_Kolab_Format_Xml_Type_Multiple';
  92. /**
  93. * Defines a XML value as raw XML
  94. */
  95. const TYPE_XML = 'Horde_Kolab_Format_Xml_Type_XmlAppend';
  96. /**
  97. * Represents the Kolab format root node
  98. */
  99. const TYPE_ROOT = 'Horde_Kolab_Format_Xml_Type_Root';
  100. /**
  101. * The parser dealing with the input.
  102. *
  103. * @var Horde_Kolab_Format_Xml_Parser
  104. */
  105. protected $_parser;
  106. /**
  107. * The factory for additional objects.
  108. *
  109. * @var Horde_Kolab_Format_Factory
  110. */
  111. protected $_factory;
  112. /**
  113. * Requested version of the data array to return
  114. *
  115. * @var int
  116. */
  117. protected $_version = 2;
  118. /**
  119. * The XML document this driver works with.
  120. *
  121. * @var DOMDocument
  122. */
  123. protected $_xmldoc = null;
  124. /**
  125. * The name of the root element.
  126. *
  127. * @var string
  128. */
  129. protected $_root_name = 'kolab';
  130. /**
  131. * Kolab format version of the root element.
  132. *
  133. * @var string
  134. */
  135. protected $_root_version = '1.0';
  136. /**
  137. * Specific data fields for the contact object
  138. *
  139. * @var array
  140. */
  141. protected $_fields_specific;
  142. /**
  143. * Constructor
  144. *
  145. * @param Horde_Kolab_Format_Xml_Parser $parser The XML parser.
  146. * @param Horde_Kolab_Format_Factory $factory The factory for helper
  147. * objects.
  148. * @param array $params Any additional options.
  149. */
  150. public function __construct(
  151. Horde_Kolab_Format_Xml_Parser $parser,
  152. Horde_Kolab_Format_Factory $factory,
  153. $params = null
  154. )
  155. {
  156. $this->_parser = $parser;
  157. $this->_factory = $factory;
  158. if (is_array($params) && isset($params['version'])) {
  159. $this->_version = $params['version'];
  160. } else {
  161. $this->_version = 2;
  162. }
  163. }
  164. /**
  165. * Throw the parser instance away.
  166. *
  167. * @return NULL
  168. */
  169. private function _refreshParser()
  170. {
  171. $this->_parser = null;
  172. }
  173. /**
  174. * Fetch the XML parser.
  175. *
  176. * @return Horde_Kolab_Format_Xml_Parser The parser.
  177. */
  178. private function _getParser()
  179. {
  180. if ($this->_parser === null) {
  181. $this->_parser = $this->_factory->createXmlParser();
  182. }
  183. return $this->_parser;
  184. }
  185. /**
  186. * Load an object based on the given XML stream. The stream may only contain
  187. * UTF-8 data.
  188. *
  189. * @param resource $xml The XML stream of the message.
  190. * @param array $options Additional options when parsing the XML.
  191. * <pre>
  192. * - relaxed: Relaxed error checking (default: false)
  193. * </pre>
  194. *
  195. * @return array The data array representing the object.
  196. *
  197. * @throws Horde_Kolab_Format_Exception If parsing the XML data failed.
  198. *
  199. * @todo Check encoding of the returned array. It seems to be ISO-8859-1 at
  200. * the moment and UTF-8 would seem more appropriate.
  201. */
  202. public function load($xml, $options = array())
  203. {
  204. $this->_xmldoc = $this->_getParser()->parse($xml, $options);
  205. $this->_refreshParser();
  206. $params = $this->_getParameters($options);
  207. $this->_getRoot($params)->load(
  208. $this->_root_name,
  209. $object,
  210. $this->_xmldoc,
  211. $this->_factory->createXmlHelper($this->_xmldoc),
  212. $params
  213. );
  214. return $object;
  215. }
  216. /**
  217. * Convert the data to a XML stream. Strings contained in the data array may
  218. * only be provided as UTF-8 data.
  219. *
  220. * @param array $object The data array representing the object.
  221. * @param array $options Additional options when writing the XML.
  222. * <pre>
  223. * - previos: The previous XML text (default: empty string)
  224. * - relaxed: Relaxed error checking (default: false)
  225. * </pre>
  226. *
  227. * @return resource The data as XML stream.
  228. *
  229. * @throws Horde_Kolab_Format_Exception If converting the data to XML failed.
  230. */
  231. public function save($object, $options = array())
  232. {
  233. if (!isset($options['previous'])) {
  234. $this->_xmldoc = $this->_getParser()->getDocument();
  235. } else {
  236. $parse_options = $options;
  237. unset($parse_options['previous']);
  238. $this->_xmldoc = $this->_getParser()->parse(
  239. $options['previous'], $parse_options
  240. );
  241. }
  242. $this->_refreshParser();
  243. $params = $this->_getParameters($options);
  244. $this->_getRoot($params)->save(
  245. $this->_root_name,
  246. $object,
  247. $this->_xmldoc,
  248. $this->_factory->createXmlHelper($this->_xmldoc),
  249. $params
  250. );
  251. return $this->_xmldoc->saveXML();
  252. }
  253. /**
  254. * Return the API version of the data structures that are being used for in-
  255. * and output.
  256. *
  257. * @since Horde_Kolab_Format 1.1.0
  258. *
  259. * @return int The version number;
  260. */
  261. public function getVersion()
  262. {
  263. return $this->_version;
  264. }
  265. /**
  266. * Generate the internal parameter list for this operation.
  267. *
  268. * @param array $options The options for this operation.
  269. *
  270. * @return array
  271. */
  272. private function _getParameters($options)
  273. {
  274. $params = array_merge(
  275. $options,
  276. array(
  277. 'expected-version' => $this->_root_version,
  278. 'api-version' => $this->_version
  279. )
  280. );
  281. if (!empty($this->_fields_specific)) {
  282. $params['attributes-specific'] = $this->_fields_specific;
  283. }
  284. return $params;
  285. }
  286. /**
  287. * Return the root handler.
  288. *
  289. * @param array $params Additional parameters.
  290. *
  291. * @return Horde_Kolab_Xml_Type_Root The root handler.
  292. */
  293. private function _getRoot($params = array())
  294. {
  295. return $this->_factory->createXmlType(self::TYPE_ROOT, $params);
  296. }
  297. }