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 //if file does not exist 59 if (!file_exists($this->getSourceFilepath())) { 60 return false; 61 } 62 $im = new imagick($this->getSourceFilepath()."[0]"); 63 // the following line was in the original code. Issue #6 (https://github.com/ternite/dokuwiki-plugin-mediathumbnails/issues/6) 64 // indicated there might be problems with colors, so I uncommented the line (TS, 2025-10-11) 65 //$im->setImageColorspace(255); 66 $im->setResolution(300, 300); 67 $im->setCompressionQuality(95); 68 $im->setImageFormat('jpeg'); 69 //$im->resizeImage($this->getTargetMaxDimension(),0,imagick::FILTER_LANCZOS,0.9); 70 //$im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 71 $im->writeImage($this->getTargetFilepath()); 72 $im->clear(); 73 $im->destroy(); 74 75 // unfortunately, resizeImage or thumbnailImage leads to a black thumbnail in my setup, so I reopen the file and resize it now. 76 $im = new imagick($this->getTargetFilepath()); 77 $im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 78 $im->writeImage($this->getTargetFilepath()); 79 $im->clear(); 80 $im->destroy(); 81 82 return true; 83 } else { 84 return true; 85 } 86 } 87} 88 89class thumb_img_engine extends thumb_engine { 90 91 public function getFileSuffix() { 92 return getFileSuffix($this->getSourceFilepath()); 93 } 94 95 public function act_internal() { 96 if ($this->thumb_needs_update()) { 97 $im = new imagick( $this->getSourceFilepath() ); 98 $im->thumbnailImage($this->getTargetMaxDimension(),$this->getTargetMaxDimension(),true,false); 99 $im->writeImage($this->getTargetFilepath()); 100 $im->clear(); 101 $im->destroy(); 102 103 return true; 104 } else { 105 return true; 106 } 107 } 108} 109 110class thumb_zip_engine extends thumb_engine { 111 112 private array $thumb_paths; 113 private $file_suffix = ""; 114 115 public function __construct(thumbnail $thumbnail, array $thumb_paths) { 116 parent::__construct($thumbnail); 117 $this->thumb_paths = $thumb_paths; 118 } 119 120 public function getFileSuffix() { 121 return $this->file_suffix; 122 } 123 124 public function act_internal() { 125 126 $zip = new ZipArchive; 127 if ($zip->open($this->getSourceFilepath()) !== true) { 128 // file is no zip or cannot be opened 129 return false; 130 } 131 132 // The media file exists and acts as a zip file! 133 134 // Check all possible paths (configured in configuration key 'thumb_paths') if there is a file available 135 foreach($this->thumb_paths as $thumbnail_path) { 136 $this->file_suffix = substr(strrchr($thumbnail_path,'.'),1); 137 138 if ($zip->locateName($thumbnail_path) !== false) { 139 140 if (!$this->thumb_needs_update()) { 141 return true; 142 } 143 144 // Get the thumbnail file! 145 $fp = $zip->getStream($thumbnail_path); 146 if(!$fp) { 147 return false; 148 } 149 150 $thumbnaildata = ''; 151 while (!feof($fp)) { 152 $thumbnaildata .= fread($fp, 8192); 153 } 154 155 fclose($fp); 156 157 // Write thumbnail file to media folder 158 file_put_contents($this->getTargetFilepath(), $thumbnaildata); 159 160 return true; 161 } 162 } 163 164 return true; 165 } 166}