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

/app/lib/core/Plugins/Media/PDFWand.php

https://bitbucket.org/Sinfin/pawtucket
PHP | 744 lines | 675 code | 26 blank | 43 comment | 16 complexity | e6f5ea9930a599a118260d820e432a8b MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. <?php
  2. /** ---------------------------------------------------------------------
  3. * app/lib/core/Plugins/Media/PDFWand.php :
  4. * ----------------------------------------------------------------------
  5. * CollectiveAccess
  6. * Open-source collections management software
  7. * ----------------------------------------------------------------------
  8. *
  9. * Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
  10. * Copyright 2006-2011 Whirl-i-Gig
  11. *
  12. * For more information visit http://www.CollectiveAccess.org
  13. *
  14. * This program is free software; you may redistribute it and/or modify it under
  15. * the terms of the provided license as published by Whirl-i-Gig
  16. *
  17. * CollectiveAccess is distributed in the hope that it will be useful, but
  18. * WITHOUT ANY WARRANTIES whatsoever, including any implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  20. *
  21. * This source code is free and modifiable under the terms of
  22. * GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See
  23. * the "license.txt" file for details, or visit the CollectiveAccess web site at
  24. * http://www.CollectiveAccess.org
  25. *
  26. * @package CollectiveAccess
  27. * @subpackage Media
  28. * @license http://www.gnu.org/copyleft/gpl.html GNU Public License version 3
  29. *
  30. * ----------------------------------------------------------------------
  31. */
  32. /**
  33. *
  34. */
  35. /**
  36. * Plugin for processing PDF documents
  37. */
  38. include_once(__CA_LIB_DIR__."/core/Plugins/WLPlug.php");
  39. include_once(__CA_LIB_DIR__."/core/Plugins/IWLPlugMedia.php");
  40. include_once(__CA_LIB_DIR__."/core/Configuration.php");
  41. include_once(__CA_LIB_DIR__."/core/Media.php");
  42. include_once(__CA_APP_DIR__."/helpers/mediaPluginHelpers.php");
  43. class WLPlugMediaPDFWand Extends WLPlug implements IWLPlugMedia {
  44. var $errors = array();
  45. var $filepath;
  46. var $handle;
  47. var $ohandle;
  48. var $properties;
  49. var $opo_config;
  50. var $opo_external_app_config;
  51. var $ops_ghostscript_path;
  52. var $ops_pdftotext_path;
  53. var $info = array(
  54. "IMPORT" => array(
  55. "application/pdf" => "pdf"
  56. ),
  57. "EXPORT" => array(
  58. "application/pdf" => "pdf",
  59. "image/jpeg" => "jpg",
  60. "image/png" => "png",
  61. "image/gif" => "gif",
  62. "image/tiff" => "tiff",
  63. "application/postscript" => "ps"
  64. ),
  65. "TRANSFORMATIONS" => array(
  66. "SCALE" => array("width", "height", "mode", "antialiasing"),
  67. "ANNOTATE" => array("text", "font", "size", "color", "position", "inset"), // dummy
  68. "WATERMARK" => array("image", "width", "height", "position", "opacity"), // dummy
  69. "SET" => array("property", "value")
  70. ),
  71. "PROPERTIES" => array(
  72. "width" => 'W', # in pixels
  73. "height" => 'W', # in pixels
  74. "version_width" => 'R', // width version icon should be output at (set by transform())
  75. "version_height" => 'R', // height version icon should be output at (set by transform())
  76. "mimetype" => 'W',
  77. "quality" => 'W',
  78. "pages" => 'R',
  79. "page" => 'W', # page to output as JPEG or TIFF
  80. "resolution" => 'W', # resolution of graphic in pixels per inch
  81. "filesize" => 'R',
  82. "antialiasing" => 'W', # amount of antialiasing to apply to final output; 0 means none, 1 means lots; a good value is 0.5
  83. "crop" => 'W', # if set to geometry value (eg. 72x72) image will be cropped to those dimensions; set by transform() to support fill_box SCALE mode
  84. "scaling_correction"=> 'W', # percent scaling required to correct sizing of image output by Ghostscript (Ghostscript does not do fractional resolutions)
  85. "target_width" => 'W',
  86. "target_height" => 'W',
  87. "colors" => 'W', # number of colors in output PNG-format image; default is 256
  88. 'version' => 'W' // required of all plug-ins
  89. ),
  90. "NAME" => "PDF",
  91. "MULTIPAGE_CONVERSION" => true, // if true, means plug-in support methods to transform and return all pages of a multipage document file (ex. a PDF)
  92. "NO_CONVERSION" => false
  93. );
  94. var $typenames = array(
  95. "application/pdf" => "PDF",
  96. "image/jpeg" => "JPEG",
  97. "image/tiff" => "TIFF",
  98. "image/png" => "PNG",
  99. "image/gif" => "GIF",
  100. "application/postscript" => "Postscript"
  101. );
  102. var $magick_names = array(
  103. "image/jpeg" => "JPEG",
  104. "image/gif" => "GIF",
  105. "image/tiff" => "TIFF",
  106. "image/png" => "PNG",
  107. "image/x-bmp" => "BMP",
  108. "image/x-psd" => "PSD",
  109. "application/pdf" => "PDF",
  110. "application/postscript" => "Postscript"
  111. );
  112. # ------------------------------------------------
  113. public function __construct() {
  114. $this->description = _t('Provides PDF conversion services using ImageMagick or the Zend_PDF library. Will use Ghostscript to generate image-previews of PDF files.');
  115. }
  116. # ------------------------------------------------
  117. # Tell WebLib what kinds of media this plug-in supports
  118. # for import and export
  119. public function register() {
  120. $this->opo_config = Configuration::load();
  121. $vs_external_app_config_path = $this->opo_config->get('external_applications');
  122. $this->opo_external_app_config = Configuration::load($vs_external_app_config_path);
  123. $this->ops_ghostscript_path = $this->opo_external_app_config->get('ghostscript_app');
  124. $this->ops_pdftotext_path = $this->opo_external_app_config->get('pdftotext_app');
  125. $this->ops_imagemagick_path = $this->opo_external_app_config->get('imagemagick_path');
  126. $this->info["INSTANCE"] = $this;
  127. return $this->info;
  128. }
  129. # ------------------------------------------------
  130. public function checkStatus() {
  131. $va_status = parent::checkStatus();
  132. if ($this->register()) {
  133. $va_status['available'] = true;
  134. }
  135. if (!caMediaPluginGhostscriptInstalled($this->ops_ghostscript_path)) {
  136. $va_status['warnings'][] = _t("Ghostscript cannot be found: image previews will not be created");
  137. }
  138. if (!caMediaPluginPdftotextInstalled($this->ops_pdftotext_path)) {
  139. $va_status['warnings'][] = _t("PDFToText cannot be found: indexing of text in PDF files will not be performed; you can obtain PDFToText at http://www.foolabs.com/xpdf/download.html");
  140. }
  141. return $va_status;
  142. }
  143. # ------------------------------------------------
  144. public function divineFileFormat($ps_filepath) {
  145. if ($ps_filepath == '') {
  146. return '';
  147. }
  148. if ((!$this->opo_config->get('dont_use_imagemagick_to_identify_pdfs')) && caMediaPluginImageMagickInstalled($this->ops_imagemagick_path)) {
  149. if(is_array($va_info = $this->_imageMagickIdentify($ps_filepath)) && sizeof($va_info)) {
  150. $vn_width = $va_info['width'];
  151. $vn_height = $va_info['height'];
  152. $vn_res = 72;
  153. $vn_pages = $va_info['pages'];
  154. } else {
  155. return null;
  156. }
  157. } else {
  158. try {
  159. include_once(__CA_LIB_DIR__."/core/Zend/Pdf.php");
  160. $o_pdf = Zend_Pdf::load($ps_filepath);
  161. if (sizeof($o_pdf->pages) == 0) { return ''; }
  162. } catch(Exception $e){
  163. return null;
  164. }
  165. $o_page = $o_pdf->pages[0];
  166. $vn_width = $o_page->getWidth();
  167. $vn_height = $o_page->getHeight();
  168. $vn_res = 72;
  169. $vn_pages = sizeof($o_pdf->pages);
  170. }
  171. $vs_mimetype = "application/pdf";
  172. if (($vs_mimetype) && $this->info["IMPORT"][$vs_mimetype]) {
  173. $this->handle = $this->ohandle = array(
  174. "filepath" => $ps_filepath,
  175. "width" => $vn_width,
  176. "height" => $vn_height,
  177. "mimetype" => $vs_mimetype,
  178. "resolution" => $vn_res,
  179. "pages" => $vn_pages,
  180. "page" => 1,
  181. "quality" => 75,
  182. "filesize" => filesize($ps_filepath),
  183. "content" => ''
  184. );
  185. $this->properties = array(
  186. "width" => $this->handle["width"],
  187. "height" => $this->handle["height"],
  188. "mimetype" => $vs_mimetype,
  189. "quality" => 75,
  190. "pages" => $this->handle["pages"],
  191. "page" => 1,
  192. "resolution" => 72,
  193. "filesize" => $this->handle["filesize"],
  194. "typename" => "PDF"
  195. );
  196. return $vs_mimetype;
  197. } else {
  198. return '';
  199. }
  200. }
  201. # ------------------------------------------------
  202. private function _imageMagickIdentify($ps_filepath) {
  203. exec($this->ops_imagemagick_path.'/identify -format "%m;%w;%h;%p\n" "'.$ps_filepath."\" 2> /dev/null", $va_output, $vn_return);
  204. array_pop($va_output); // last line is blank
  205. if (is_array($va_output) && (sizeof($va_output) > 0)) {
  206. $va_tmp = explode(';', $va_output[0]);
  207. if ($va_tmp[0] === 'PDF') {
  208. return array(
  209. 'width' => intval($va_tmp[1]),
  210. 'height' => intval($va_tmp[1]),
  211. 'pages' => sizeof($va_output)
  212. );
  213. }
  214. }
  215. return null;
  216. }
  217. # ----------------------------------------------------------
  218. public function get($property) {
  219. if ($this->handle) {
  220. if ($this->info["PROPERTIES"][$property]) {
  221. return $this->properties[$property];
  222. } else {
  223. //print "Invalid property";
  224. return '';
  225. }
  226. } else {
  227. return '';
  228. }
  229. }
  230. # ----------------------------------------------------------
  231. public function set($property, $value) {
  232. if ($this->handle) {
  233. if ($this->info["PROPERTIES"][$property]) {
  234. switch($property) {
  235. case 'quality':
  236. if (($value < 1) || ($value > 100)) {
  237. $this->postError(1650, _t("Quality property must be between 1 and 100"), "WLPlugPDFWand->set()");
  238. return '';
  239. }
  240. $this->properties["quality"] = $value;
  241. break;
  242. case 'antialiasing':
  243. if (($value < 0) || ($value > 100)) {
  244. $this->postError(1650, _t("Antialiasing property must be between 0 and 100"), "WLPlugPDFWand->set()");
  245. return '';
  246. }
  247. $this->properties["antialiasing"] = $value;
  248. break;
  249. default:
  250. if ($this->info["PROPERTIES"][$property] == 'W') {
  251. $this->properties[$property] = $value;
  252. } else {
  253. # read only
  254. return '';
  255. }
  256. break;
  257. }
  258. } else {
  259. # invalid property
  260. $this->postError(1650, _t("Can't set property %1", $property), "WLPlugPDFWand->set()");
  261. return '';
  262. }
  263. } else {
  264. return '';
  265. }
  266. return true;
  267. }
  268. # ------------------------------------------------
  269. /**
  270. * Returns text content for indexing, or empty string if plugin doesn't support text extraction
  271. *
  272. * @return String Extracted text
  273. */
  274. public function getExtractedText() {
  275. return isset($this->handle['content']) ? $this->handle['content'] : '';
  276. }
  277. # ------------------------------------------------
  278. /**
  279. * Returns array of extracted metadata, key'ed by metadata type or empty array if plugin doesn't support metadata extraction
  280. *
  281. * @return Array Extracted metadata
  282. */
  283. public function getExtractedMetadata() {
  284. return array();
  285. }
  286. # ------------------------------------------------
  287. public function read ($ps_filepath) {
  288. if (is_array($this->handle) && ($this->handle["filepath"] == $ps_filepath)) {
  289. // noop
  290. } else {
  291. if (!file_exists($ps_filepath)) {
  292. $this->postError(1650, _t("File %1 does not exist", $ps_filepath), "WLPlugPDFWand->read()");
  293. $this->handle = "";
  294. $this->filepath = "";
  295. return false;
  296. }
  297. if (!($this->divineFileFormat($ps_filepath))) {
  298. $this->postError(1650, _t("File %1 is not a PDF", $ps_filepath), "WLPlugPDFWand->read()");
  299. $this->handle = "";
  300. $this->filepath = "";
  301. return false;
  302. }
  303. }
  304. //try to extract text
  305. if (caMediaPluginPdftotextInstalled($this->ops_pdftotext_path)) {
  306. $vs_tmp_filename = tempnam('/tmp', 'CA_PDF_TEXT');
  307. exec($this->ops_pdftotext_path.' -q -enc UTF-8 '.$ps_filepath.' '.$vs_tmp_filename);
  308. $vs_extracted_text = file_get_contents($vs_tmp_filename);
  309. $this->handle['content'] = $this->ohandle['content'] = $vs_extracted_text;
  310. @unlink($vs_tmp_filename);
  311. }
  312. return true;
  313. }
  314. # ----------------------------------------------------------
  315. public function transform($ps_operation, $pa_parameters) {
  316. if (!$this->handle) { return false; }
  317. if (!($this->info["TRANSFORMATIONS"][$ps_operation])) {
  318. # invalid transformation
  319. $this->postError(1655, _t("Invalid transformation %1", $ps_operation), "WLPlugPDFWand->transform()");
  320. return false;
  321. }
  322. # get parameters for this operation
  323. $sparams = $this->info["TRANSFORMATIONS"][$ps_operation];
  324. $this->properties["version_width"] = $w = $pa_parameters["width"];
  325. $this->properties["version_height"] = $h = $pa_parameters["height"];
  326. $cw = $this->get("width");
  327. $ch = $this->get("height");
  328. switch($ps_operation) {
  329. # -----------------------
  330. case "SET":
  331. while(list($k, $v) = each($pa_parameters)) {
  332. $this->set($k, $v);
  333. }
  334. break;
  335. # -----------------------
  336. case "SCALE":
  337. $vn_width_ratio = $w/$cw;
  338. $vn_height_ratio = $h/$ch;
  339. $vn_orig_resolution = $this->get("resolution");
  340. switch($pa_parameters["mode"]) {
  341. # ----------------
  342. case "width":
  343. $vn_resolution = ceil($vn_orig_resolution * $vn_width_ratio);
  344. $vn_scaling_correction = $w/ceil($vn_resolution * ($cw/$vn_orig_resolution));
  345. break;
  346. # ----------------
  347. case "height":
  348. $vn_resolution = ceil($vn_orig_resolution * $vn_height_ratio);
  349. $vn_scaling_correction = $h/ceil($vn_resolution * ($ch/$vn_orig_resolution));
  350. break;
  351. # ----------------
  352. case "fill_box":
  353. if ($vn_width_ratio < $vn_height_ratio) {
  354. $vn_resolution = ceil($vn_orig_resolution * $vn_width_ratio);
  355. $vn_scaling_correction = $w/ceil($vn_resolution * ($cw/$vn_orig_resolution));
  356. } else {
  357. $vn_resolution = ceil($vn_orig_resolution * $vn_height_ratio);
  358. $vn_scaling_correction = $h/ceil($vn_resolution * ($ch/$vn_orig_resolution));
  359. }
  360. $this->set("crop",$w."x".$h);
  361. break;
  362. # ----------------
  363. case "bounding_box":
  364. default:
  365. if ($vn_width_ratio > $vn_height_ratio) {
  366. $vn_resolution = ceil($vn_orig_resolution * $vn_height_ratio);
  367. $vn_scaling_correction = $h/ceil($vn_resolution * ($ch/$vn_orig_resolution));
  368. } else {
  369. $vn_resolution = ceil($vn_orig_resolution * $vn_width_ratio);
  370. $vn_scaling_correction = $w/ceil($vn_resolution * ($cw/$vn_orig_resolution));
  371. }
  372. break;
  373. # ----------------
  374. }
  375. $this->properties["scaling_correction"] = $vn_scaling_correction;
  376. $this->properties["resolution"] = $vn_resolution;
  377. $this->properties["width"] = ceil($vn_resolution * ($cw/$vn_orig_resolution));
  378. $this->properties["height"] = ceil($vn_resolution * ($ch/$vn_orig_resolution));
  379. $this->properties["target_width"] = $w;
  380. $this->properties["target_height"] = $h;
  381. $this->properties["antialiasing"] = ($pa_parameters["antialiasing"]) ? 1 : 0;
  382. break;
  383. # -----------------------
  384. }
  385. return true;
  386. }
  387. # ----------------------------------------------------------
  388. public function write($ps_filepath, $ps_mimetype) {
  389. if (!$this->handle) { return false; }
  390. # is mimetype valid?
  391. if (!($vs_ext = $this->info["EXPORT"][$ps_mimetype])) {
  392. $this->postError(1610, _t("Can't convert file to %1", $ps_mimetype), "WLPlugPDFWand->write()");
  393. return false;
  394. }
  395. # write the file
  396. if ($ps_mimetype == "application/pdf") {
  397. if ( !copy($this->filepath, $ps_filepath.".pdf") ) {
  398. $this->postError(1610, _t("Couldn't write file to '%1'", $ps_filepath), "WLPlugPDFWand->write()");
  399. return false;
  400. }
  401. } else {
  402. $vb_use_default_icon = true;
  403. if (caMediaPluginGhostscriptInstalled($this->ops_ghostscript_path)) {
  404. $vn_scaling_correction = $this->get("scaling_correction");
  405. $vs_res = "72x72";
  406. if (ceil($this->get("resolution")) > 0) {
  407. $vn_res= $this->get("resolution");
  408. if ($vn_scaling_correction) { $vn_res *= 2; }
  409. $vs_res = ceil($vn_res)."x".ceil($vn_res);
  410. }
  411. $vn_page = ceil($this->get("page"));
  412. $vn_quality = ceil($this->get("quality"));
  413. if ($vn_quality > 100) { $vn_quality = 100; }
  414. if ($vn_quality < 1) { $vn_quality = 50; }
  415. if ($vn_page < 1) { $vn_page = 1; }
  416. if ($this->get("antialiasing")) {
  417. $vs_antialiasing = "-dTextAlphaBits=4 -dGraphicsAlphaBits=4";
  418. } else {
  419. $vs_antialiasing = "";
  420. }
  421. $vb_processed_preview = false;
  422. switch($ps_mimetype) {
  423. case 'image/jpeg':
  424. exec(escapeshellcmd($this->ops_ghostscript_path." -dNOPAUSE -dBATCH -sDEVICE=".($vn_scaling_correction ? "tiff24nc" : "jpeg")." $vs_antialiasing -dJPEGQ=".$vn_quality." -dFirstPage=".$vn_page." -dLastPage=".$vn_page." -sOutputFile=\"".$ps_filepath.".".$vs_ext."\" -r".$vs_res." \"".$this->handle["filepath"]."\""), $va_output, $vn_return);
  425. if ($vn_return == 0) {
  426. $vb_processed_preview = true;
  427. }
  428. break;
  429. case 'image/tiff':
  430. case 'image/png':
  431. case 'image/gif':
  432. exec(escapeshellcmd($this->ops_ghostscript_path." -dNOPAUSE -dBATCH -sDEVICE=tiff24nc $vs_antialiasing -dFirstPage=".$vn_page." -dLastPage=".$vn_page." -sOutputFile=\"".$ps_filepath.".".$vs_ext."\" -r".$vs_res." \"".$this->handle["filepath"]."\""), $va_output, $vn_return);
  433. if ($vn_return == 0) {
  434. $vb_processed_preview = true;
  435. }
  436. break;
  437. default:
  438. //die("Unsupported output type in PDF plug-in: $ps_mimetype [this shouldn't happen]");
  439. break;
  440. }
  441. if ($vb_processed_preview) {
  442. if ($vs_crop = $this->get("crop")) {
  443. $o_media = new Media();
  444. list($vn_w, $vn_h) = explode("x", $vs_crop);
  445. if (($vn_w > 0) && ($vn_h > 0)) {
  446. $o_media->read($ps_filepath.".".$vs_ext);
  447. if (!$o_media->numErrors()) {
  448. $o_media->transform('SCALE', array('mode' => 'fill_box', 'antialiasing' => 0.5, 'width' => $vn_w, 'height' => $vn_h));
  449. $o_media->write($ps_filepath, $ps_mimetype, array());
  450. if (!$o_media->numErrors()) {
  451. $this->properties["width"] = $vn_w;
  452. $this->properties["height"] = $vn_h;
  453. $vb_use_default_icon = false;
  454. }
  455. }
  456. }
  457. } else {
  458. if ($vn_scaling_correction) {
  459. $o_media = new Media(true);
  460. $o_media->read($ps_filepath.".".$vs_ext);
  461. if (!$o_media->numErrors()) {
  462. $vn_w = ($o_media->get('width') * $vn_scaling_correction);
  463. $vn_h = ($o_media->get('height') * $vn_scaling_correction);
  464. if (($vn_w > $vn_h) || ($this->get("target_height") == 0)) {
  465. $vn_r = $this->get("target_width")/$vn_w;
  466. $vn_w = $this->get("target_width");
  467. $vn_h *= $vn_r;
  468. } else {
  469. $vn_r = $this->get("target_height")/$vn_h;
  470. $vn_h = $this->get("target_height");
  471. $vn_w *= $vn_r;
  472. }
  473. $vn_w = ceil($vn_w);
  474. $vn_h = ceil($vn_h);
  475. $this->properties["width"] = $vn_w;
  476. $this->properties["height"] = $vn_h;
  477. $o_media->transform('SCALE', array('mode' => 'bounding_box', 'antialiasing' => 0.5, 'width' => $vn_w, 'height' => $vn_h));
  478. $o_media->transform('UNSHARPEN_MASK', array('sigma' => 0.5, 'radius' => 1, 'threshold' => 1.0, 'amount' => 0.1));
  479. $o_media->write($ps_filepath, $ps_mimetype, array());
  480. if (!$o_media->numErrors()) {
  481. $vb_use_default_icon = false;
  482. }
  483. }
  484. } else {
  485. $vb_use_default_icon = false;
  486. }
  487. }
  488. }
  489. }
  490. if ($vb_use_default_icon) {
  491. # use default media icons
  492. if (file_exists($this->opo_config->get("default_media_icons"))) {
  493. $o_icon_info = Configuration::load($this->opo_config->get("default_media_icons"));
  494. if ($va_icon_info = $o_icon_info->getAssoc('application/pdf')) {
  495. $vs_icon_path = $o_icon_info->get("icon_folder_path");
  496. if ($vs_icon_filename = trim($va_icon_info[$this->get("version")])) {
  497. if (!copy($vs_icon_path."/".$vs_icon_filename,$ps_filepath.'.'.$vs_ext)) {
  498. $this->postError(1610, _t("Can't copy icon file from %1 to %2", $vs_icon_path."/".trim($va_icon_info[$this->get("version")]), $ps_filepath.'.'.$vs_ext), "WLPlugPDFWand->write()");
  499. return false;
  500. }
  501. } else {
  502. $this->postError(1610, _t("Icon for version %1 available for this media type (system misconfiguration)", $this->get("version")), "WLPlugPDFWand->write()");
  503. return false;
  504. }
  505. } else {
  506. $this->postError(1610, _t("No icons available for this media type (system misconfiguration)"), "WLPlugPDFWand->write()");
  507. return false;
  508. }
  509. } else {
  510. $this->postError(1610, _t("No icons available (system misconfiguration)"), "WLPlugPDFWand->write()");
  511. return false;
  512. }
  513. }
  514. }
  515. $this->properties["mimetype"] = $ps_mimetype;
  516. $this->properties["filesize"] = filesize($ps_filepath.".".$vs_ext);
  517. $this->properties["typename"] = $this->typenames[$ps_mimetype];
  518. return $ps_filepath.".".$vs_ext;
  519. }
  520. # ------------------------------------------------
  521. /**
  522. * Options:
  523. * width
  524. * height
  525. * numberOfPages
  526. * pageInterval
  527. * startAtPage
  528. * outputDirectory
  529. * force = ignore setting of "document_preview_generate_pages" app.conf directive and generate previews no matter what
  530. */
  531. # This method must be implemented for plug-ins that can output preview frames for videos or pages for documents
  532. public function &writePreviews($ps_filepath, $pa_options) {
  533. if (!(bool)$this->opo_config->get("document_preview_generate_pages") && (!isset($pa_options['force']) || !$pa_options['force'])) { return false; }
  534. if (!isset($pa_options['outputDirectory']) || !$pa_options['outputDirectory'] || !file_exists($pa_options['outputDirectory'])) {
  535. if (!($vs_tmp_dir = $this->opo_config->get("taskqueue_tmp_directory"))) {
  536. // no dir
  537. return false;
  538. }
  539. } else {
  540. $vs_tmp_dir = $pa_options['outputDirectory'];
  541. }
  542. if (($vn_max_number_of_pages = $pa_options['numberOfPages']) < 1) {
  543. $vn_max_number_of_pages = 5000;
  544. }
  545. if (!($vn_page_interval = (int)$pa_options['pageInterval'])) {
  546. $vn_page_interval = 1;
  547. }
  548. if (!($vn_start_at = (int)$pa_options['startAtPage'])) {
  549. $vn_start_at = 1;
  550. }
  551. if ($vn_start_at < 1) {
  552. $vn_start_at = 1;
  553. }
  554. $vn_tot_pages = $this->get('pages');
  555. if ($vn_start_at > $vn_tot_pages) { $vn_start_at = 1; }
  556. $vn_preview_width = (isset($pa_options['width']) && ((int)$pa_options['width'] > 0)) ? (int)$pa_options['width'] : 320;
  557. $vn_preview_height= (isset($pa_options['height']) && ((int)$pa_options['height'] > 0)) ? (int)$pa_options['height'] : 320;
  558. $vs_output_file_prefix = tempnam($vs_tmp_dir, 'caDocumentPreview');
  559. $va_files = array();
  560. $vn_old_res = $this->get('resolution');
  561. for($vn_i=$vn_start_at; $vn_i <= $vn_tot_pages; $vn_i++) {
  562. $this->set("page", $vn_i);
  563. if (($vn_res = (int)$this->opo_config->get("document_preview_resolution")) < 72) {
  564. $vn_res = 72;
  565. }
  566. $this->set('resolution', $vn_res);
  567. if ($vs_filename = $this->write($vs_output_file_prefix.sprintf("%05d", $vn_i), 'image/jpeg')) {
  568. $va_files[$vn_i] = $vs_filename;
  569. }
  570. }
  571. $this->set("page", 1);
  572. $this->set('resolution', $vn_old_res);
  573. if (!sizeof($va_files)) {
  574. $this->postError(1610, _t("Couldn't not write document preview frames to tmp directory (%1)", $vs_tmp_dir), "WLPlugPDFWand->write()");
  575. }
  576. @unlink($vs_output_file_prefix);
  577. return $va_files;
  578. }
  579. # ------------------------------------------------
  580. public function getOutputFormats() {
  581. return $this->info["EXPORT"];
  582. }
  583. # ------------------------------------------------
  584. public function getTransformations() {
  585. return $this->info["TRANSFORMATIONS"];
  586. }
  587. # ------------------------------------------------
  588. public function getProperties() {
  589. return $this->info["PROPERTIES"];
  590. }
  591. # ------------------------------------------------
  592. public function mimetype2extension($ps_mimetype) {
  593. return $this->info["EXPORT"][$ps_mimetype];
  594. }
  595. # ------------------------------------------------
  596. public function mimetype2typename($ps_mimetype) {
  597. return $this->typenames[$ps_mimetype];
  598. }
  599. # ------------------------------------------------
  600. public function extension2mimetype($ps_extension) {
  601. reset($this->info["EXPORT"]);
  602. while(list($k, $v) = each($this->info["EXPORT"])) {
  603. if ($v === $ps_extension) {
  604. return $k;
  605. }
  606. }
  607. return '';
  608. }
  609. # ------------------------------------------------
  610. public function reset() {
  611. return $this->init();
  612. }
  613. # ------------------------------------------------
  614. public function init() {
  615. $this->errors = array();
  616. $this->handle = $this->ohandle;
  617. $this->properties = array(
  618. "width" => $this->ohandle["width"],
  619. "height" => $this->ohandle["height"],
  620. "mimetype" => $this->ohandle["mimetype"],
  621. "quality" => 75,
  622. "pages" => $this->ohandle["pages"],
  623. "page" => 1,
  624. "resolution" => 72,
  625. "filesize" => $this->ohandle["filesize"],
  626. "typename" => "PDF"
  627. );
  628. }
  629. # ------------------------------------------------
  630. public function htmlTag($ps_url, $pa_properties, $pa_options=null, $pa_volume_info=null) {
  631. if (!is_array($pa_options)) { $pa_options = array(); }
  632. foreach(array(
  633. 'name', 'url', 'viewer_width', 'viewer_height', 'idname',
  634. 'viewer_base_url', 'width', 'height',
  635. 'vspace', 'hspace', 'alt', 'title', 'usemap', 'align', 'border', 'class', 'style',
  636. 'embed'
  637. ) as $vs_k) {
  638. if (!isset($pa_options[$vs_k])) { $pa_options[$vs_k] = null; }
  639. }
  640. $vn_viewer_width = intval($pa_options['viewer_width']);
  641. if ($vn_viewer_width < 100) { $vn_viewer_width = 400; }
  642. $vn_viewer_height = intval($pa_options['viewer_height']);
  643. if ($vn_viewer_height < 100) { $vn_viewer_height = 400; }
  644. if (!($vs_id = isset($pa_options['id']) ? $pa_options['id'] : $pa_options['name'])) {
  645. $vs_id = '_pdf';
  646. }
  647. if(preg_match("/\.pdf\$/", $ps_url)) {
  648. if ($vs_poster_frame_url = $pa_options["poster_frame_url"]) {
  649. $vs_poster_frame = "<img src='{$vs_poster_frame_url}'/ alt='"._t("Click to download document")." title='"._t("Click to download document")."''>";
  650. } else {
  651. $vs_poster_frame = _t("View PDF document");
  652. }
  653. $vs_buf = "<script type='text/javascript'>jQuery(document).ready(function() {
  654. new PDFObject({
  655. url: '{$ps_url}',
  656. id: '{$vs_id}',
  657. width: '{$vn_viewer_width}px',
  658. height: '{$vn_viewer_height}px',
  659. }).embed('{$vs_id}_div');
  660. });</script>
  661. <div id='{$vs_id}_div'><a href='$ps_url' target='_pdf'>".$vs_poster_frame."</a></div>
  662. ";
  663. return $vs_buf;
  664. } else {
  665. if (!is_array($pa_options)) { $pa_options = array(); }
  666. if (!is_array($pa_properties)) { $pa_properties = array(); }
  667. return caHTMLImage($ps_url, array_merge($pa_options, $pa_properties));
  668. }
  669. }
  670. # ------------------------------------------------
  671. #
  672. # ------------------------------------------------
  673. public function cleanup() {
  674. return;
  675. }
  676. # ------------------------------------------------
  677. }
  678. ?>