--- a/web/lib/Zend/Pdf.php Thu May 07 15:10:09 2015 +0200
+++ b/web/lib/Zend/Pdf.php Thu May 07 15:16:02 2015 +0200
@@ -14,9 +14,9 @@
*
* @category Zend
* @package Zend_Pdf
- * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Pdf.php 24593 2012-01-05 20:35:02Z matthew $
+ * @version $Id$
*/
@@ -78,7 +78,7 @@
*
* @category Zend
* @package Zend_Pdf
- * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf
@@ -95,7 +95,12 @@
*/
const PDF_HEADER = "%PDF-1.4\n%\xE2\xE3\xCF\xD3\n";
-
+ /**
+ * Form field options
+ */
+ const PDF_FORM_FIELD_READONLY = 1;
+ const PDF_FORM_FIELD_REQUIRED = 2;
+ const PDF_FORM_FIELD_NOEXPORT = 4;
/**
* Pages collection
@@ -201,7 +206,6 @@
*/
protected $_parser;
-
/**
* List of inheritable attributesfor pages tree
*
@@ -210,6 +214,13 @@
protected static $_inheritableAttributes = array('Resources', 'MediaBox', 'CropBox', 'Rotate');
/**
+ * List of form fields
+ *
+ * @var array - Associative array, key: name of form field, value: Zend_Pdf_Element
+ */
+ protected $_formFields = array();
+
+ /**
* True if the object is a newly created PDF document (affects save() method behavior)
* False otherwise
*
@@ -299,12 +310,12 @@
*
* If $source is a string and $load is true, then it loads document
* from a file.
-
* $revision used to roll back document to specified version
* (0 - current version, 1 - previous version, 2 - ...)
*
* @param string $source - PDF file to load
* @param integer $revision
+ * @param bool $load
* @throws Zend_Pdf_Exception
* @return Zend_Pdf
*/
@@ -330,6 +341,8 @@
$this->_loadNamedDestinations($this->_trailer->Root, $this->_parser->getPDFVersion());
$this->_loadOutlines($this->_trailer->Root);
+ $this->_loadJavaScript($this->_trailer->Root);
+ $this->_loadFormFields($this->_trailer->Root);
if ($this->_trailer->Info !== null) {
$this->properties = $this->_trailer->Info->toPhp();
@@ -442,12 +455,12 @@
$this->_loadPages($this->_trailer->Root->Pages);
}
-
/**
* Load pages recursively
*
* @param Zend_Pdf_Element_Reference $pages
- * @param array|null $attributes
+ * @param array|null $attributes
+ * @throws Zend_Pdf_Exception
*/
protected function _loadPages(Zend_Pdf_Element_Reference $pages, $attributes = array())
{
@@ -536,6 +549,7 @@
* Load outlines recursively
*
* @param Zend_Pdf_Element_Reference $root Document catalog entry
+ * @throws Zend_Pdf_Exception
*/
protected function _loadOutlines(Zend_Pdf_Element_Reference $root)
{
@@ -576,6 +590,130 @@
}
/**
+ * Load JavaScript
+ *
+ * Populates the _javaScript string, for later use of getJavaScript method.
+ *
+ * @param Zend_Pdf_Element_Reference $root Document catalog entry
+ */
+ protected function _loadJavaScript(Zend_Pdf_Element_Reference $root)
+ {
+ if (null === $root->Names || null === $root->Names->JavaScript
+ || null === $root->Names->JavaScript->Names
+ ) {
+ return;
+ }
+
+ foreach ($root->Names->JavaScript->Names->items as $item) {
+ if ($item instanceof Zend_Pdf_Element_Reference
+ && $item->S->value === 'JavaScript'
+ ) {
+ $this->_javaScript[] = $item->JS->value;
+ }
+ }
+ }
+
+ /**
+ * Load form fields
+ *
+ * Populates the _formFields array, for later lookup of fields by name
+ *
+ * @param Zend_Pdf_Element_Reference $root Document catalog entry
+ */
+ protected function _loadFormFields(Zend_Pdf_Element_Reference $root)
+ {
+ if ($root->AcroForm === null || $root->AcroForm->Fields === null) {
+ return;
+ }
+
+ foreach ($root->AcroForm->Fields->items as $field) {
+ /* We only support fields that are textfields and have a name */
+ if ($field->FT && $field->FT->value == 'Tx' && $field->T
+ && $field->T !== null
+ ) {
+ $this->_formFields[$field->T->value] = $field;
+ }
+ }
+
+ if (!$root->AcroForm->NeedAppearances
+ || !$root->AcroForm->NeedAppearances->value
+ ) {
+ /* Ask the .pdf viewer to generate its own appearance data, so we do not have to */
+ $root->AcroForm->add(
+ new Zend_Pdf_Element_Name('NeedAppearances'),
+ new Zend_Pdf_Element_Boolean(true)
+ );
+ $root->AcroForm->touch();
+ }
+ }
+
+ /**
+ * Retrieves a list with the names of the AcroForm textfields in the PDF
+ *
+ * @return array of strings
+ */
+ public function getTextFieldNames()
+ {
+ return array_keys($this->_formFields);
+ }
+
+ /**
+ * Sets the value of an AcroForm text field
+ *
+ * @param string $name Name of textfield
+ * @param string $value Value
+ * @throws Zend_Pdf_Exception if the textfield does not exist in the pdf
+ */
+ public function setTextField($name, $value)
+ {
+ if (!isset($this->_formFields[$name])) {
+ throw new Zend_Pdf_Exception(
+ "Field '$name' does not exist or is not a textfield"
+ );
+ }
+
+ /** @var Zend_Pdf_Element $field */
+ $field = $this->_formFields[$name];
+ $field->add(
+ new Zend_Pdf_Element_Name('V'), new Zend_Pdf_Element_String($value)
+ );
+ $field->touch();
+ }
+
+ /**
+ * Sets the properties for an AcroForm text field
+ *
+ * @param string $name
+ * @param mixed $bitmask
+ * @throws Zend_Pdf_Exception
+ */
+ public function setTextFieldProperties($name, $bitmask)
+ {
+ if (!isset($this->_formFields[$name])) {
+ throw new Zend_Pdf_Exception(
+ "Field '$name' does not exist or is not a textfield"
+ );
+ }
+
+ $field = $this->_formFields[$name];
+ $field->add(
+ new Zend_Pdf_Element_Name('Ff'),
+ new Zend_Pdf_Element_Numeric($bitmask)
+ );
+ $field->touch();
+ }
+
+ /**
+ * Marks an AcroForm text field as read only
+ *
+ * @param string $name
+ */
+ public function markTextFieldAsReadOnly($name)
+ {
+ $this->setTextFieldProperties($name, self::PDF_FORM_FIELD_READONLY);
+ }
+
+ /**
* Orginize pages to tha pages tree structure.
*
* @todo atomatically attach page to the document, if it's not done yet.
@@ -916,8 +1054,9 @@
/**
* Set specified named destination
*
- * @param string $name
- * @param Zend_Pdf_Destination_Explicit|Zend_Pdf_Action_GoTo $target
+ * @param string $name
+ * @param Zend_Pdf_Destination_Explicit|Zend_Pdf_Action_GoTo $destination
+ * @throws Zend_Pdf_Exception
*/
public function setNamedDestination($name, $destination = null)
{
@@ -975,8 +1114,8 @@
*
* Returns Zend_Pdf_Page page object or null if destination is not found within PDF document.
*
- * @param Zend_Pdf_Destination $destination Destination to resolve
- * @param boolean $refreshPagesHash Refresh page collection hashes before processing
+ * @param Zend_Pdf_Destination $destination Destination to resolve
+ * @param bool $refreshPageCollectionHashes Refresh page collection hashes before processing
* @return Zend_Pdf_Page|null
* @throws Zend_Pdf_Exception
*/
@@ -1034,7 +1173,7 @@
* @todo Give appropriate name and make method public
*
* @param Zend_Pdf_Action $action
- * @param boolean $refreshPagesHash Refresh page collection hashes before processing
+ * @param bool $refreshPageCollectionHashes Refresh page collection hashes before processing
* @return Zend_Pdf_Action|null
*/
protected function _cleanUpAction(Zend_Pdf_Action $action, $refreshPageCollectionHashes = true)
@@ -1129,6 +1268,7 @@
*
* $fontName should be specified in UTF-8 encoding
*
+ * @param string $fontName
* @return Zend_Pdf_Resource_Font_Extracted|null
* @throws Zend_Pdf_Exception
*/
@@ -1386,18 +1526,85 @@
}
}
+ /**
+ * Sets the document-level JavaScript
+ *
+ * Resets and appends
+ *
+ * @param string|array $javaScript
+ */
+ public function setJavaScript($javaScript)
+ {
+ $this->resetJavaScript();
+
+ $this->addJavaScript($javaScript);
+ }
+
+ /**
+ * Resets the document-level JavaScript
+ */
+ public function resetJavaScript()
+ {
+ $this->_javaScript = null;
+
+ $root = $this->_trailer->Root;
+ if (null === $root->Names || null === $root->Names->JavaScript) {
+ return;
+ }
+ $root->Names->JavaScript = null;
+ }
/**
- * Set the document-level JavaScript
+ * Appends JavaScript to the document-level JavaScript
*
- * @param string $javascript
+ * @param string|array $javaScript
+ * @throws Zend_Pdf_Exception
*/
- public function setJavaScript($javascript)
+ public function addJavaScript($javaScript)
{
- $this->_javaScript = $javascript;
+ if (empty($javaScript)) {
+ throw new Zend_Pdf_Exception(
+ 'JavaScript must be a non empty string or array of strings'
+ );
+ }
+
+ if (!is_array($javaScript)) {
+ $javaScript = array($javaScript);
+ }
+
+ if (null === $this->_javaScript) {
+ $this->_javaScript = $javaScript;
+ } else {
+ $this->_javaScript = array_merge($this->_javaScript, $javaScript);
+ }
+
+ if (!empty($this->_javaScript)) {
+ $items = array();
+
+ foreach ($this->_javaScript as $javaScript) {
+ $jsCode = array(
+ 'S' => new Zend_Pdf_Element_Name('JavaScript'),
+ 'JS' => new Zend_Pdf_Element_String($javaScript)
+ );
+ $items[] = new Zend_Pdf_Element_String('EmbeddedJS');
+ $items[] = $this->_objFactory->newObject(
+ new Zend_Pdf_Element_Dictionary($jsCode)
+ );
+ }
+
+ $jsRef = $this->_objFactory->newObject(
+ new Zend_Pdf_Element_Dictionary(
+ array('Names' => new Zend_Pdf_Element_Array($items))
+ )
+ );
+
+ if (null === $this->_trailer->Root->Names) {
+ $this->_trailer->Root->Names = new Zend_Pdf_Element_Dictionary();
+ }
+ $this->_trailer->Root->Names->JavaScript = $jsRef;
+ }
}
-
/**
* Convert date to PDF format (it's close to ASN.1 (Abstract Syntax Notation
* One) defined in ISO/IEC 8824).