You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
7.6 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Pdf
  17. * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id$
  20. */
  21. /** Internally used classes */
  22. // require_once 'Zend/Pdf/Element/Null.php';
  23. /** Zend_Pdf_Element */
  24. // require_once 'Zend/Pdf/Element.php';
  25. /**
  26. * PDF file 'reference' element implementation
  27. *
  28. * @category Zend
  29. * @package Zend_Pdf
  30. * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Pdf_Element_Reference extends Zend_Pdf_Element
  34. {
  35. /**
  36. * Object value
  37. * The reference to the object
  38. *
  39. * @var mixed
  40. */
  41. private $_ref;
  42. /**
  43. * Object number within PDF file
  44. *
  45. * @var integer
  46. */
  47. private $_objNum;
  48. /**
  49. * Generation number
  50. *
  51. * @var integer
  52. */
  53. private $_genNum;
  54. /**
  55. * Reference context
  56. *
  57. * @var Zend_Pdf_Element_Reference_Context
  58. */
  59. private $_context;
  60. /**
  61. * Reference to the factory.
  62. *
  63. * It's the same as referenced object factory, but we save it here to avoid
  64. * unnecessary dereferencing, whech can produce cascade dereferencing and parsing.
  65. * The same for duplication of getFactory() function. It can be processed by __call()
  66. * method, but we catch it here.
  67. *
  68. * @var Zend_Pdf_ElementFactory
  69. */
  70. private $_factory;
  71. /**
  72. * Object constructor:
  73. *
  74. * @param integer $objNum
  75. * @param integer $genNum
  76. * @param Zend_Pdf_Element_Reference_Context $context
  77. * @param Zend_Pdf_ElementFactory $factory
  78. * @throws Zend_Pdf_Exception
  79. */
  80. public function __construct($objNum, $genNum = 0, Zend_Pdf_Element_Reference_Context $context, Zend_Pdf_ElementFactory $factory)
  81. {
  82. if ( !(is_integer($objNum) && $objNum > 0) ) {
  83. // require_once 'Zend/Pdf/Exception.php';
  84. throw new Zend_Pdf_Exception('Object number must be positive integer');
  85. }
  86. if ( !(is_integer($genNum) && $genNum >= 0) ) {
  87. // require_once 'Zend/Pdf/Exception.php';
  88. throw new Zend_Pdf_Exception('Generation number must be non-negative integer');
  89. }
  90. $this->_objNum = $objNum;
  91. $this->_genNum = $genNum;
  92. $this->_ref = null;
  93. $this->_context = $context;
  94. $this->_factory = $factory;
  95. }
  96. /**
  97. * Check, that object is generated by specified factory
  98. *
  99. * @return Zend_Pdf_ElementFactory
  100. */
  101. public function getFactory()
  102. {
  103. return $this->_factory;
  104. }
  105. /**
  106. * Return type of the element.
  107. *
  108. * @return integer
  109. */
  110. public function getType()
  111. {
  112. if ($this->_ref === null) {
  113. $this->_dereference();
  114. }
  115. return $this->_ref->getType();
  116. }
  117. /**
  118. * Return reference to the object
  119. *
  120. * @param Zend_Pdf_Factory $factory
  121. * @return string
  122. */
  123. public function toString($factory = null)
  124. {
  125. if ($factory === null) {
  126. $shift = 0;
  127. } else {
  128. $shift = $factory->getEnumerationShift($this->_factory);
  129. }
  130. return $this->_objNum + $shift . ' ' . $this->_genNum . ' R';
  131. }
  132. /**
  133. * Dereference.
  134. * Take inderect object, take $value member of this object (must be Zend_Pdf_Element),
  135. * take reference to the $value member of this object and assign it to
  136. * $value member of current PDF Reference object
  137. * $obj can be null
  138. *
  139. * @throws Zend_Pdf_Exception
  140. */
  141. private function _dereference()
  142. {
  143. if (($obj = $this->_factory->fetchObject($this->_objNum . ' ' . $this->_genNum)) === null) {
  144. $obj = $this->_context->getParser()->getObject(
  145. $this->_context->getRefTable()->getOffset($this->_objNum . ' ' . $this->_genNum . ' R'),
  146. $this->_context
  147. );
  148. }
  149. if ($obj === null ) {
  150. $this->_ref = new Zend_Pdf_Element_Null();
  151. return;
  152. }
  153. if ($obj->toString() != $this->_objNum . ' ' . $this->_genNum . ' R') {
  154. // require_once 'Zend/Pdf/Exception.php';
  155. throw new Zend_Pdf_Exception('Incorrect reference to the object');
  156. }
  157. $this->_ref = $obj;
  158. }
  159. /**
  160. * Detach PDF object from the factory (if applicable), clone it and attach to new factory.
  161. *
  162. * @param Zend_Pdf_ElementFactory $factory The factory to attach
  163. * @param array &$processed List of already processed indirect objects, used to avoid objects duplication
  164. * @param integer $mode Cloning mode (defines filter for objects cloning)
  165. * @returns Zend_Pdf_Element
  166. */
  167. public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
  168. {
  169. if ($this->_ref === null) {
  170. $this->_dereference();
  171. }
  172. // This code duplicates code in Zend_Pdf_Element_Object class,
  173. // but allows to avoid unnecessary method call in most cases
  174. $id = spl_object_hash($this->_ref);
  175. if (isset($processed[$id])) {
  176. // Do nothing if object is already processed
  177. // return it
  178. return $processed[$id];
  179. }
  180. return $this->_ref->makeClone($factory, $processed, $mode);
  181. }
  182. /**
  183. * Mark object as modified, to include it into new PDF file segment.
  184. */
  185. public function touch()
  186. {
  187. if ($this->_ref === null) {
  188. $this->_dereference();
  189. }
  190. $this->_ref->touch();
  191. }
  192. /**
  193. * Return object, which can be used to identify object and its references identity
  194. *
  195. * @return Zend_Pdf_Element_Object
  196. */
  197. public function getObject()
  198. {
  199. if ($this->_ref === null) {
  200. $this->_dereference();
  201. }
  202. return $this->_ref;
  203. }
  204. /**
  205. * Get handler
  206. *
  207. * @param string $property
  208. * @return mixed
  209. */
  210. public function __get($property)
  211. {
  212. if ($this->_ref === null) {
  213. $this->_dereference();
  214. }
  215. return $this->_ref->$property;
  216. }
  217. /**
  218. * Set handler
  219. *
  220. * @param string $property
  221. * @param mixed $value
  222. */
  223. public function __set($property, $value)
  224. {
  225. if ($this->_ref === null) {
  226. $this->_dereference();
  227. }
  228. $this->_ref->$property = $value;
  229. }
  230. /**
  231. * Call handler
  232. *
  233. * @param string $method
  234. * @param array $args
  235. * @return mixed
  236. */
  237. public function __call($method, $args)
  238. {
  239. if ($this->_ref === null) {
  240. $this->_dereference();
  241. }
  242. return call_user_func_array(array($this->_ref, $method), $args);
  243. }
  244. /**
  245. * Clean up resources
  246. */
  247. public function cleanUp()
  248. {
  249. $this->_ref = null;
  250. }
  251. /**
  252. * Convert PDF element to PHP type.
  253. *
  254. * @return mixed
  255. */
  256. public function toPhp()
  257. {
  258. if ($this->_ref === null) {
  259. $this->_dereference();
  260. }
  261. return $this->_ref->toPhp();
  262. }
  263. }