PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/common/libraries/plugin/odtPHP/library/Segment.php

https://bitbucket.org/renaatdemuynck/chamilo
PHP | 263 lines | 160 code | 15 blank | 88 comment | 12 complexity | 58256759f771812c601154797d6e0a37 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT, GPL-2.0
  1. <?php
  2. require 'SegmentIterator.php';
  3. class SegmentException extends Exception
  4. {
  5. }
  6. /**
  7. * Class for handling templating segments with odt files
  8. * You need PHP 5.2 at least
  9. * You need Zip Extension or PclZip library
  10. * Encoding : ISO-8859-1
  11. * Last commit by $Author: neveldo $
  12. * Date - $Date: 2009-06-17 12:12:59 +0200 (mer., 17 juin 2009) $
  13. * SVN Revision - $Rev: 44 $
  14. * Id : $Id: Segment.php 44 2009-06-17 10:12:59Z neveldo $
  15. *
  16. * @copyright GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
  17. * @license http://www.gnu.org/copyleft/gpl.html GPL License
  18. * @version 1.3
  19. */
  20. class Segment implements IteratorAggregate, Countable
  21. {
  22. protected $xml;
  23. protected $xmlParsed = '';
  24. protected $name;
  25. protected $children = array();
  26. protected $vars = array();
  27. protected $images = array();
  28. protected $odf;
  29. protected $file;
  30. protected $max_image_size = 8;
  31. /**
  32. * Constructor
  33. *
  34. * @param string $name name of the segment to construct
  35. * @param string $xml XML tree of the segment
  36. */
  37. public function __construct($name, $xml, $odf)
  38. {
  39. $this->name = (string) $name;
  40. $this->xml = (string) $xml;
  41. $this->odf = $odf;
  42. $zipHandler = $this->odf->getConfig('ZIP_PROXY');
  43. $this->file = new $zipHandler();
  44. $this->_analyseChildren($this->xml);
  45. }
  46. /**
  47. * Returns the name of the segment
  48. *
  49. * @return string
  50. */
  51. public function getName()
  52. {
  53. return $this->name;
  54. }
  55. /**
  56. * Does the segment have children ?
  57. *
  58. * @return bool
  59. */
  60. public function hasChildren()
  61. {
  62. return $this->getIterator()->hasChildren();
  63. }
  64. /**
  65. * Countable interface
  66. *
  67. * @return int
  68. */
  69. public function count()
  70. {
  71. return count($this->children);
  72. }
  73. /**
  74. * IteratorAggregate interface
  75. *
  76. * @return Iterator
  77. */
  78. public function getIterator()
  79. {
  80. return new RecursiveIteratorIterator(new SegmentIterator($this->children), 1);
  81. }
  82. /**
  83. * Replace variables of the template in the XML code
  84. * All the children are also called
  85. *
  86. * @return string
  87. */
  88. public function merge()
  89. {
  90. $this->xmlParsed .= str_replace(array_keys($this->vars), array_values($this->vars), $this->xml);
  91. if ($this->hasChildren())
  92. {
  93. foreach ($this->children as $child)
  94. {
  95. $this->xmlParsed = str_replace($child->xml, ($child->xmlParsed == "") ? $child->merge() : $child->xmlParsed, $this->xmlParsed);
  96. $child->xmlParsed = '';
  97. }
  98. }
  99. $reg = "/\[!--\sBEGIN\s$this->name\s--\](.*)\[!--\sEND\s$this->name\s--\]/sm";
  100. $this->xmlParsed = preg_replace($reg, '$1', $this->xmlParsed);
  101. $this->file->open($this->odf->getTmpfile());
  102. foreach ($this->images as $imageKey => $imageValue)
  103. {
  104. if ($this->file->getFromName('Pictures/' . $imageValue) === false)
  105. {
  106. $this->file->addFile($imageKey, 'Pictures/' . $imageValue);
  107. }
  108. $this->odf->addImageToManifest($imageValue);
  109. }
  110. $this->file->close();
  111. return $this->xmlParsed;
  112. }
  113. /**
  114. * Analyse the XML code in order to find children
  115. *
  116. * @param string $xml
  117. * @return Segment
  118. */
  119. protected function _analyseChildren($xml)
  120. {
  121. // $reg2 = "#\[!--\sBEGIN\s([\S]*)\s--\](?:<\/text:p>)?(.*)(?:<text:p\s.*>)?\[!--\sEND\s(\\1)\s--\]#sm";
  122. $reg2 = "#\[!--\sBEGIN\s([\S]*)\s--\](.*)\[!--\sEND\s(\\1)\s--\]#sm";
  123. preg_match_all($reg2, $xml, $matches);
  124. for($i = 0, $size = count($matches[0]); $i < $size; $i ++)
  125. {
  126. if ($matches[1][$i] != $this->name)
  127. {
  128. $this->children[$matches[1][$i]] = new self($matches[1][$i], $matches[0][$i], $this->odf);
  129. }
  130. else
  131. {
  132. $this->_analyseChildren($matches[2][$i]);
  133. }
  134. }
  135. return $this;
  136. }
  137. /**
  138. * Assign a template variable to replace
  139. *
  140. * @param string $key
  141. * @param string $value
  142. * @throws SegmentException
  143. * @return Segment
  144. */
  145. public function setVars($key, $value, $encode = true, $charset = 'ISO-8859')
  146. {
  147. if (strpos($this->xml, $this->odf->getConfig('DELIMITER_LEFT') . $key . $this->odf->getConfig('DELIMITER_RIGHT')) === false)
  148. {
  149. throw new SegmentException("var $key not found in {$this->getName()}");
  150. }
  151. $value = $encode ? htmlspecialchars($value) : $value;
  152. $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
  153. $this->vars[$this->odf->getConfig('DELIMITER_LEFT') . $key . $this->odf->getConfig('DELIMITER_RIGHT')] = str_replace("\n", "<text:line-break/>", $value);
  154. return $this;
  155. }
  156. /**
  157. * Assign a template variable as a picture
  158. *
  159. * @param string $key name of the variable within the template
  160. * @param string $value path to the picture
  161. * @throws OdfException
  162. * @return Segment
  163. */
  164. public function setImage($key, $value)
  165. {
  166. $filename = strtok(strrchr($value, '/'), '/.');
  167. $file = substr(strrchr($value, '/'), 1);
  168. $size = @getimagesize($value);
  169. if ($size === false)
  170. {
  171. throw new OdfException("Invalid image");
  172. }
  173. list($width, $height) = $size;
  174. $width *= Odf :: PIXEL_TO_CM;
  175. $height *= Odf :: PIXEL_TO_CM;
  176. if ($width > $this->max_image_size)
  177. {
  178. $factor = $width / $this->max_image_size;
  179. $width = $width / $factor;
  180. $height = $height / $factor;
  181. }
  182. $xml = <<<IMG
  183. <draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="as-char" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
  184. IMG;
  185. $this->images[$value] = $file;
  186. $this->setVars($key, $xml, false);
  187. return $this;
  188. }
  189. public function setImageReplace($key, $value)
  190. {
  191. $filename = strtok(strrchr($value, '/'), '/.');
  192. $file = substr(strrchr($value, '/'), 1);
  193. $size = @getimagesize($value);
  194. if ($size === false)
  195. {
  196. throw new OdfException("Invalid image");
  197. }
  198. $this->images[$value] = $file;
  199. $this->vars[$key] = $file;
  200. return $this;
  201. }
  202. /**
  203. * Shortcut to retrieve a child
  204. *
  205. * @param string $prop
  206. * @return Segment
  207. * @throws SegmentException
  208. */
  209. public function __get($prop)
  210. {
  211. if (array_key_exists($prop, $this->children))
  212. {
  213. return $this->children[$prop];
  214. }
  215. else
  216. {
  217. throw new SegmentException('child ' . $prop . ' does not exist');
  218. }
  219. }
  220. /**
  221. * Proxy for setVars
  222. *
  223. * @param string $meth
  224. * @param array $args
  225. * @return Segment
  226. */
  227. public function __call($meth, $args)
  228. {
  229. try
  230. {
  231. return $this->setVars($meth, $args[0]);
  232. }
  233. catch (SegmentException $e)
  234. {
  235. throw new SegmentException("method $meth nor var $meth exist");
  236. }
  237. }
  238. /**
  239. * Returns the parsed XML
  240. *
  241. * @return string
  242. */
  243. public function getXmlParsed()
  244. {
  245. return $this->xmlParsed;
  246. }
  247. }
  248. ?>