1<?php 2/** 3 * DokuWiki Plugin mediathumbnails (thumb_engine class and subclasses) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Thomas Schäfer <thomas.schaefer@itschert.net> 7 */ 8 9abstract class thumb_engine { 10 11 private ?thumbnail $thumbnail = null; 12 13 public function __construct(thumbnail $thumbnail) { 14 $this->thumbnail = $thumbnail; 15 } 16 17 protected function getSourceFilepath() { 18 return $this->thumbnail->getSourceFilepath(); 19 } 20 21 protected function getTargetFilepath() { 22 return $this->thumbnail->getFilepath(); 23 } 24 25 protected function getTargetMaxDimension() { 26 return $this->thumbnail->getMaxDimension(); 27 } 28 29 public function act() { 30 if ($this->act_internal()) { 31 // Set timestamp to the source file's timestamp (this is used to check in later passes if the file already exists in the correct version). 32 if (filemtime($this->getSourceFilepath()) !== filemtime($this->getTargetFilepath())) { 33 touch($this->getTargetFilepath(), filemtime($this->getSourceFilepath())); 34 } 35 return true; 36 } 37 return false; 38 } 39 40 // Checks if a thumbnail file for the current file version has already been created 41 protected function thumb_needs_update() { 42 return !file_exists($this->getTargetFilepath()) || filemtime($this->getTargetFilepath()) !== filemtime($this->getSourceFilepath()); 43 } 44 45 public abstract function act_internal(); 46 47 public abstract function getFileSuffix(); 48} 49 50class thumb_pdf_engine extends thumb_engine { 51 52 public function getFileSuffix() { 53 return "jpg"; 54 } 55 56 public function act_internal() { 57 if ($this->thumb_needs_update()) { 58 $im = new imagick($this->getSourceFilepath()."[0]"); 59 $im->setImageColorspace(255); 60 $im->setResolution(300, 300); 61 $im->setCompressionQuality(95); 62 $im->setImageFormat('jpeg'); 63 //$im->resizeImage($this->getTargetMaxDimension(),0,imagick::FILTER_LANCZOS,0.9); 64 //$im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 65 $im->writeImage($this->getTargetFilepath()); 66 $im->clear(); 67 $im->destroy(); 68 69 // unfortunately, resizeImage or thumbnailImage leads to a black thumbnail in my setup, so I reopen the file and resize it now. 70 $im = new imagick($this->getTargetFilepath()); 71 $im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 72 $im->writeImage($this->getTargetFilepath()); 73 $im->clear(); 74 $im->destroy(); 75 76 return true; 77 } else { 78 return true; 79 } 80 } 81} 82 83class thumb_img_engine extends thumb_engine { 84 85 public function getFileSuffix() { 86 return getFileSuffix($this->getSourceFilepath()); 87 } 88 89 public function act_internal() { 90 if ($this->thumb_needs_update()) { 91 $im = new imagick( $this->getSourceFilepath() ); 92 $im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 93 $im->writeImage($this->getTargetFilepath()); 94 $im->clear(); 95 $im->destroy(); 96 97 return true; 98 } else { 99 return true; 100 } 101 } 102} 103 104class thumb_zip_engine extends thumb_engine { 105 106 private array $thumb_paths; 107 private $file_suffix = ""; 108 109 public function __construct(thumbnail $thumbnail, array $thumb_paths) { 110 parent::__construct($thumbnail); 111 $this->thumb_paths = $thumb_paths; 112 } 113 114 public function getFileSuffix() { 115 return $this->file_suffix; 116 } 117 118 public function act_internal() { 119 120 $zip = new ZipArchive; 121 if ($zip->open($this->getSourceFilepath()) !== true) { 122 // file is no zip or cannot be opened 123 return false; 124 } 125 126 // The media file exists and acts as a zip file! 127 128 // Check all possible paths (configured in configuration key 'thumb_paths') if there is a file available 129 foreach($this->thumb_paths as $thumbnail_path) { 130 $this->file_suffix = substr(strrchr($thumbnail_path,'.'),1); 131 132 if ($zip->locateName($thumbnail_path) !== false) { 133 134 if (!$this->thumb_needs_update()) { 135 return true; 136 } 137 138 // Get the thumbnail file! 139 $fp = $zip->getStream($thumbnail_path); 140 if(!$fp) { 141 return false; 142 } 143 144 $thumbnaildata = ''; 145 while (!feof($fp)) { 146 $thumbnaildata .= fread($fp, 8192); 147 } 148 149 fclose($fp); 150 151 // Write thumbnail file to media folder 152 file_put_contents($this->getTargetFilepath(), $thumbnaildata); 153 154 return true; 155 } 156 } 157 158 return true; 159 } 160}