PageRenderTime 49ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/demos/Zend/Service/LiveDocx/MailMerge/license-agreement/generate-document-concat.php

https://bitbucket.org/aboozar/zf2
PHP | 257 lines | 115 code | 66 blank | 76 comment | 15 complexity | 9f0fd60590fe8d3a454e6304abe3d61b MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. set_time_limit(0);
  3. require_once dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'Bootstrap.php';
  4. /**
  5. * Concatenating PDF files locally - advanced
  6. *
  7. * In the case that you wish to generate one output document that contains
  8. * several thousand populated templates, it is more efficient to use LiveDocx to
  9. * generate a large number of singular PDF files and then to concatenate them
  10. * locally, than it is to use the backend service directly.
  11. *
  12. * As the size of the output document in such cases can be several hundred
  13. * megabytes in size, it would take a long time to transfer all data from the
  14. * backend service to the local server. Hence, a local concatenation approach is
  15. * more desirable and considerably faster.
  16. *
  17. * In this example, the backend service is used to populate a template and
  18. * create a large number of documents (see variable $iterations). Then, using a
  19. * 3rd party external command line tool - either pdftk (http://is.gd/4KO72) or
  20. * ghostscript (http://is.gd/4LK3N) - the singular PDF files are concatenated
  21. * together locally to create one large output PDF file.
  22. *
  23. * NOTE: This sample application depends upon either pdftk or ghostscript being
  24. * install on your system. Both are available for Linux and Microsoft
  25. * Windows. Please take a look at the constants EXEC_PDFTK and
  26. * EXEC_GHOSTSCRIPT. You may need to redefine these, if you are running
  27. * Windows, or if your Linux distribution installs the tools at a different
  28. * location. The specified paths are correct for Debian 5.0.3.
  29. */
  30. use DateTime;
  31. use Zend\Log\Logger;
  32. use Zend\Log\Writer\Stream as Writer;
  33. use Zend\Service\LiveDocx\Helper;
  34. use Zend\Service\LiveDocx\MailMerge;
  35. define('EXEC_PDFTK', '/usr/bin/pdftk');
  36. define('EXEC_GHOSTSCRIPT', '/usr/bin/gs');
  37. define('PROCESSOR_PDFTK', 1);
  38. define('PROCESSOR_GHOSTSCRIPT', 2);
  39. // -----------------------------------------------------------------------------
  40. // Processor to use for concatenation.
  41. //
  42. // There are 2 options (only):
  43. //
  44. // o PROCESSOR_PDFTK
  45. // - Faster
  46. // - Requires little memory (RAM)
  47. // - No reduction in file size
  48. //
  49. // o PROCESSOR_GHOSTSCRIPT
  50. // - Slower
  51. // - Requires lots of memory (RAM)
  52. // - Reduction in file size
  53. //
  54. // If you have both installed on your system, PROCESSOR_PDFTK is recommended.
  55. $processor = PROCESSOR_PDFTK;
  56. // Number of documents (populated with random strings) to concatenate.
  57. $iterations = 3;
  58. // -----------------------------------------------------------------------------
  59. // Logger to output status messages
  60. $logger = new Logger(new Writer('php://stdout'));
  61. // -----------------------------------------------------------------------------
  62. // Create temporary directory
  63. $tempDirectory = sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5(rand(1, 10000) . __FILE__);
  64. if (is_dir($tempDirectory)) {
  65. recursiveRemoveDirectory($tempDirectory);
  66. }
  67. $logger->log(sprintf('Making temporary directory %s.', $tempDirectory), Logger::INFO);
  68. mkdir($tempDirectory);
  69. // -----------------------------------------------------------------------------
  70. // Generate temporary documents
  71. $tempFilenames = array();
  72. $mailMerge = new MailMerge();
  73. $mailMerge->setUsername(DEMOS_ZEND_SERVICE_LIVEDOCX_USERNAME)
  74. ->setPassword(DEMOS_ZEND_SERVICE_LIVEDOCX_PASSWORD);
  75. $mailMerge->setLocalTemplate('template.docx');
  76. $date = new DateTime();
  77. for ($iteration = 1; $iteration <= $iterations; $iteration ++) {
  78. $tempFilename = sprintf('%s%s%010s.pdf', $tempDirectory, DIRECTORY_SEPARATOR, $iteration);
  79. $tempFilenames[] = $tempFilename;
  80. $mailMerge->assign('software', randomString())
  81. ->assign('licensee', randomString())
  82. ->assign('company', randomString())
  83. ->assign('date', $date->format('Y-m-d'))
  84. ->assign('time', $date->format('H:i:s'))
  85. ->assign('city', randomString())
  86. ->assign('country', randomString());
  87. $mailMerge->createDocument();
  88. file_put_contents($tempFilename, $mailMerge->retrieveDocument('pdf'));
  89. $logger->log(sprintf('Generating temporary document %s.', $tempFilename), Logger::INFO);
  90. }
  91. unset($mailMerge);
  92. // -----------------------------------------------------------------------------
  93. // Concatenate temporary documents and write output document
  94. $outputFilename = __DIR__ . DIRECTORY_SEPARATOR . 'document-concat.pdf';
  95. $logger->log('Concatenating temporary documents...', Logger::INFO);
  96. if (true === concatenatePdfFilenames($tempFilenames, $outputFilename, $processor)) {
  97. $logger->log(sprintf('...DONE. Saved output document as %s.', basename($outputFilename)), Logger::INFO);
  98. } else {
  99. $logger->log(sprintf('...ERROR.'), Logger::ERR);
  100. }
  101. // -----------------------------------------------------------------------------
  102. // Delete temporary directory
  103. $logger->log(sprintf('Deleting temporary directory %s.', $tempDirectory), Logger::INFO);
  104. if (is_dir($tempDirectory)) {
  105. recursiveRemoveDirectory($tempDirectory);
  106. }
  107. // =============================================================================
  108. // Helper functions
  109. /**
  110. * Create a random string
  111. *
  112. * @return string
  113. */
  114. function randomString()
  115. {
  116. $ret = '';
  117. $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  118. $poolLen = strlen($pool);
  119. $stringLen = rand(5, 25);
  120. for ($i = 0; $i < $stringLen; $i ++) {
  121. $pos = (rand() % $poolLen);
  122. $ret .= $pool{$pos};
  123. }
  124. return $ret;
  125. }
  126. /**
  127. * Recursively remove directory
  128. *
  129. * @param $dir
  130. * @return void
  131. */
  132. function recursiveRemoveDirectory($dir)
  133. {
  134. $files = glob($dir . '*', GLOB_MARK);
  135. foreach ($files as $file) {
  136. if (DIRECTORY_SEPARATOR === substr($file, - 1)) {
  137. recursiveRemoveDirectory($file);
  138. } else {
  139. unlink($file);
  140. }
  141. }
  142. if (is_dir($dir)) {
  143. rmdir($dir);
  144. }
  145. }
  146. /**
  147. * Concatenate the files in passed array $inputFilenames into one file
  148. * $outputFilename, using concatenation processor (external 3rd party command
  149. * line tool) specified in $processor
  150. *
  151. * @param $inputFilenames
  152. * @param $outputFilename
  153. * @param $processor
  154. * @return boolean
  155. */
  156. function concatenatePdfFilenames($inputFilenames, $outputFilename, $processor = EXEC_PDFTK)
  157. {
  158. $ret = false;
  159. $logger = new Logger(new Writer('php://stdout'));
  160. if (! (is_file(EXEC_PDFTK) || is_file(EXEC_GHOSTSCRIPT))) {
  161. $logger->log('Either pdftk or ghostscript are required for this sample application.', Logger::CRIT);
  162. exit();
  163. }
  164. if (is_file($outputFilename)) {
  165. unlink($outputFilename);
  166. }
  167. switch ($processor) {
  168. case PROCESSOR_PDFTK :
  169. $format = '%s %s cat output %s';
  170. $command = sprintf($format, EXEC_PDFTK, implode($inputFilenames, ' '), $outputFilename);
  171. break;
  172. case PROCESSOR_GHOSTSCRIPT :
  173. $format = '%s -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dAutoFilterColorImages=false ';
  174. $format .= '-dAutoFilterGrayImages=false -dAutoFilterMonoImages=false ';
  175. $format .= '-dColorImageFilter=/FlateEncode -dCompatibilityLevel=1.3 -dEmbedAllFonts=true ';
  176. $format .= '-dGrayImageFilter=/FlateEncode -dMaxSubsetPct=100 -dMonoImageFilter=/CCITTFaxEncode ';
  177. $format .= '-dSubsetFonts=true -sOUTPUTFILE=%s %s';
  178. $command = sprintf($format, EXEC_GHOSTSCRIPT, $outputFilename, implode($inputFilenames, ' '));
  179. break;
  180. default:
  181. $logger->log('Invalid concatenation processor - use PROCESSOR_PDFTK or PROCESSOR_GHOSTSCRIPT only.', Logger::CRIT);
  182. exit();
  183. break;
  184. }
  185. $command = escapeshellcmd($command);
  186. exec($command);
  187. if (is_file($outputFilename) && filesize($outputFilename) > 0) {
  188. $ret = true;
  189. }
  190. return $ret;
  191. }