PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

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

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