PageRenderTime 70ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/php/ims/common/writer/ims_xml_writer.class.php

https://bitbucket.org/chamilo/chamilo-dev/
PHP | 362 lines | 288 code | 47 blank | 27 comment | 24 complexity | a70f52b709e182b572e34c92d7333963 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. namespace common\libraries;
  3. use DOMDocument;
  4. use DOMText;
  5. use Exception;
  6. require_once dirname(__FILE__) . '/../ims_id_factory.class.php';
  7. /**
  8. * Base class for XML writers. Helper class create XML file.
  9. * Magic methods:
  10. *
  11. * - add_tagname() add an element with tagname
  12. *
  13. * Magic property
  14. *
  15. * - attributename returns/set the attribute value
  16. *
  17. *
  18. * @copyright (c) 2010 University of Geneva
  19. * @author laurent.opprecht@unige.ch
  20. *
  21. */
  22. class ImsXmlWriter
  23. {
  24. public static function format_datetime($timestamp)
  25. {
  26. if (empty($timestamp))
  27. {
  28. return $timestamp;
  29. }
  30. return date('Y-m-d', $timestamp) . 'T' . date('H:i:s', $timestamp);
  31. }
  32. private $id_factory;
  33. private $doc; //DOM document
  34. private $current; //current DOM element
  35. private $default_prefix = '';
  36. function __construct($item = null, $prefix = '')
  37. {
  38. if ($item instanceof ImsXmlWriter)
  39. {
  40. $this->doc = $item->get_doc();
  41. $this->current = $item->get_current();
  42. $this->id_factory = $item->get_id_factory();
  43. $this->default_prefix = $item->get_default_prefix();
  44. }
  45. else
  46. if ($item instanceof DOMDocument)
  47. {
  48. $this->doc = $item;
  49. $this->id_factory = new ImsIdFactory();
  50. }
  51. else
  52. if (is_null($item))
  53. {
  54. $this->doc = $this->create_doc();
  55. $this->id_factory = new ImsIdFactory();
  56. }
  57. else
  58. {
  59. throw new Exception('Unknown type');
  60. }
  61. if (! empty($prefix))
  62. {
  63. $this->default_prefix = $prefix;
  64. }
  65. }
  66. protected function create_doc()
  67. {
  68. return new DOMDocument('1.0', 'UTF-8');
  69. }
  70. public function get_format_version()
  71. {
  72. return '';
  73. }
  74. public function get_format_name()
  75. {
  76. return '';
  77. }
  78. public function get_format_full_name()
  79. {
  80. $result = $this->get_format_name() . ' ' . $this->get_format_version();
  81. return $result;
  82. }
  83. public function get_doc()
  84. {
  85. return $this->doc;
  86. }
  87. public function get_root()
  88. {
  89. return $this->doc->documentElement;
  90. }
  91. public function get_current()
  92. {
  93. return $this->current;
  94. }
  95. public function get_id_factory()
  96. {
  97. return $this->id_factory;
  98. }
  99. protected function create_unique_id($prefix = '')
  100. {
  101. return $this->id_factory->create_unique_id($prefix);
  102. }
  103. protected function create_local_id($prefix = '')
  104. {
  105. return $this->id_factory->create_local_id($prefix);
  106. }
  107. public function get_default_prefix()
  108. {
  109. return $this->default_prefix;
  110. }
  111. public function set_default_prefix($value)
  112. {
  113. $this->default_prefix = $value;
  114. }
  115. protected function prefix($name)
  116. {
  117. if (empty($this->default_prefix))
  118. {
  119. return $name;
  120. }
  121. else
  122. if (strpos($name, ':') !== false)
  123. {
  124. return $name;
  125. }
  126. else
  127. {
  128. return "$this->default_prefix:$name";
  129. }
  130. }
  131. public function copy($current)
  132. {
  133. $result = clone $this;
  134. $result->current = $current;
  135. return $result;
  136. }
  137. protected function copy_node($node, $prefix = '', $deep = true)
  138. {
  139. if ($node instanceof DOMText)
  140. {
  141. return $this->doc->createTextNode($node->nodeValue);
  142. }
  143. $name = empty($prefix) ? $node->nodeName : $prefix . ':' . $node->nodeName;
  144. $result = $this->doc->createElement($name);
  145. foreach ($node->attributes as $a)
  146. {
  147. $name = empty($prefix) ? $a->nodeName : $prefix . ':' . $a->nodeName;
  148. $result->setAttribute($name, $a->value);
  149. }
  150. if (! $deep)
  151. return $result;
  152. foreach ($node->childNodes as $child)
  153. {
  154. if ($new_node = $this->copy_node($child, $prefix, $deep))
  155. {
  156. $result->appendChild($new_node);
  157. }
  158. }
  159. return $result;
  160. }
  161. /**
  162. * Add an XSL stylesheet reference.
  163. *
  164. * @param $href
  165. */
  166. public function add_stylesheet($href)
  167. {
  168. $i = 'type="text/xsl" href="' . $href . '"';
  169. $result = $this->get_doc()->createProcessingInstruction('xml-stylesheet', $i);
  170. $this->get_doc()->appendChild($result);
  171. return $this->copy($result);
  172. }
  173. public function add($item, $value = '')
  174. {
  175. if (is_array($item))
  176. {
  177. return $this->add_elements($item);
  178. }
  179. else
  180. {
  181. return $this->add_element($item, $value);
  182. }
  183. }
  184. /**
  185. * @param $tag
  186. * @param $value
  187. * @return ImsXmlWriter
  188. */
  189. public function add_element($tag, $value = '')
  190. {
  191. $tag = $this->prefix($tag);
  192. $result = $this->doc->createElement($tag, $value);
  193. $this->append_child($result);
  194. return $this->copy($result);
  195. }
  196. public function add_text($data)
  197. {
  198. $doc = new DOMDocument();
  199. $result = $this->doc->createTextNode($data);
  200. $this->append_child($result);
  201. }
  202. public function add_xml($xml)
  203. {
  204. if (trim($xml) === '')
  205. {
  206. return $this;
  207. }
  208. $fragment = $this->doc->createDocumentFragment();
  209. if ($fragment->appendXML("<root>$xml</root>"))
  210. {
  211. $child = $fragment->firstChild->firstChild;
  212. while ($child)
  213. {
  214. $next_child = $child->nextSibling; //should be done before append child
  215. $this->append_child($child);
  216. $child = $next_child;
  217. }
  218. return $this;
  219. }
  220. else
  221. {
  222. return $this;
  223. }
  224. }
  225. public function add_xhml($xml)
  226. {
  227. if (empty($xml))
  228. {
  229. return $this;
  230. }
  231. //unknown named html entities are rejected by load xml
  232. //we replace named entities by their digital counterparts
  233. $xml = str_replace('&nbsp;', '&#160;', $xml);
  234. $result = $this->add_xml($xml);
  235. return $result;
  236. }
  237. public function add_elements($tags)
  238. {
  239. $result = $this;
  240. foreach ($tags as $name => $value)
  241. {
  242. $result = $this->add_element($name, $value);
  243. }
  244. return $result;
  245. }
  246. public function get_attribute($name)
  247. {
  248. return $this->current->getAttribute($name);
  249. }
  250. public function set_attribute($tag, $value, $write_empty = true)
  251. {
  252. $tag = $this->prefix($tag);
  253. if ($write_empty || ! empty($value))
  254. {
  255. $this->current->setAttribute($tag, $value);
  256. }
  257. }
  258. public function save($path)
  259. {
  260. return $this->doc->save($path);
  261. }
  262. public function saveXML($declaration = true)
  263. {
  264. if ($declaration)
  265. {
  266. $result = $this->doc->saveXML();
  267. }
  268. else
  269. {
  270. $doc = $this->doc;
  271. $result = $doc->saveXML($doc->documentElement, LIBXML_NOENT);
  272. }
  273. return $result;
  274. }
  275. public function validate()
  276. {
  277. return $this->doc->validate();
  278. }
  279. public function schema_validate($filename)
  280. {
  281. return $this->doc->schemaValidate($filename);
  282. }
  283. public function __call($name, $arguments)
  284. {
  285. $n = explode('_', $name);
  286. $action = $n[0];
  287. $name = $n[1];
  288. $method = array($this, $action);
  289. $arguments = array_merge(array($name), $arguments);
  290. if ($action == 'add')
  291. {
  292. call_user_func_array($method, $arguments);
  293. }
  294. }
  295. public function __get($name)
  296. {
  297. return $this->get_attribute($name);
  298. }
  299. public function __set($name, $value)
  300. {
  301. $this->set_attribute($name, $value);
  302. }
  303. protected function append_child($child)
  304. {
  305. if (empty($this->current))
  306. {
  307. return $this->doc->appendChild($child);
  308. }
  309. else
  310. {
  311. return $this->current->appendChild($child);
  312. }
  313. }
  314. }
  315. ?>