147d2d32aSternite<?php 247d2d32aSternite/** 347d2d32aSternite * DokuWiki Plugin mediathumbnails (thumbnail class) 447d2d32aSternite * 547d2d32aSternite * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 647d2d32aSternite * @author Thomas Schäfer <thomas.schaefer@itschert.net> 747d2d32aSternite */ 847d2d32aSternite 947d2d32aSterniterequire('thumb_engines.php'); 1047d2d32aSternite 1147d2d32aSternitefunction getFileSuffix(string $file) { 1247d2d32aSternite return substr(strrchr($file,'.'),1); 1347d2d32aSternite} 1447d2d32aSternite 1547d2d32aSterniteclass thumbnail { 1647d2d32aSternite 17*e19533e1Sternite private string $source_filepath; 18*e19533e1Sternite private string $source_mediapath; 1947d2d32aSternite private ?thumb_engine $thumb_engine = null; 2047d2d32aSternite private int $max_dimension; 2147d2d32aSternite 2247d2d32aSternite private static $formats; 2347d2d32aSternite private static ?bool $pdf_support = null; 2447d2d32aSternite private static ?bool $image_support = null; 2547d2d32aSternite private static ?bool $no_ghostscript_support = null; 265fa23922Sternite private static ?bool $no_imagick_pdf_readwrite = null; 27a99f1509Sternite private static ?string $dependency_problem = null; 2847d2d32aSternite 2947d2d32aSternite private static function testDependencies() { 30086d90eeSternite 3147d2d32aSternite self::$image_support = false; 3247d2d32aSternite self::$pdf_support = false; 3347d2d32aSternite self::$no_ghostscript_support = false; 345fa23922Sternite self::$no_imagick_pdf_readwrite = false; 35a99f1509Sternite self::$dependency_problem = null; 36086d90eeSternite 3747d2d32aSternite if (class_exists ("Imagick")) { 3847d2d32aSternite // determine file formats supported by ImageMagick 3947d2d32aSternite self::$formats = \Imagick::queryformats(); 4047d2d32aSternite 4147d2d32aSternite if (count(self::$formats) > 0) { 4247d2d32aSternite self::$image_support = true; 4347d2d32aSternite if (in_array("PDF", self::$formats)) { 4447d2d32aSternite // Check if GhostScript will answer! 4547d2d32aSternite try { 4647d2d32aSternite // blank.pdf is an empty reference PDF file to test if GhostScript will react upon loading the file into ImageMagick 4747d2d32aSternite $im = new imagick(realpath("lib/plugins/mediathumbnails/blank.pdf")."[0]"); 4847d2d32aSternite $im->clear(); 4947d2d32aSternite $im->destroy(); 5047d2d32aSternite self::$pdf_support = true; 5147d2d32aSternite } catch (ImagickException $e) { 5247d2d32aSternite if (strpos($e,"PDFDelegateFailed") !== false) { 5347d2d32aSternite self::$no_ghostscript_support = true; 5447d2d32aSternite } 555fa23922Sternite if (strpos($e,"security policy") !== false) { 565fa23922Sternite self::$no_imagick_pdf_readwrite = true; 575fa23922Sternite } 5847d2d32aSternite self::$pdf_support = false; 59a99f1509Sternite self::$dependency_problem = "Catched ImagickException: ".$e->getMessage(); 60a99f1509Sternite } 61a99f1509Sternite } else { 62a99f1509Sternite self::$dependency_problem = "Imagick reports it does not support PDF files."; 63a99f1509Sternite } 64a99f1509Sternite } else { 65a99f1509Sternite self::$dependency_problem = "Imagick reports it doesn't support any output formats."; 6647d2d32aSternite } 6747d2d32aSternite 68a99f1509Sternite } else { 69a99f1509Sternite self::$dependency_problem = "Imagick class not found: ImageMagick PHP extension is not installed."; 7047d2d32aSternite } 7147d2d32aSternite } 7247d2d32aSternite public static function supportsPDF() { 7347d2d32aSternite if (self::$pdf_support === null) { 7447d2d32aSternite self::testDependencies(); 7547d2d32aSternite } 7647d2d32aSternite return self::$pdf_support; 7747d2d32aSternite } 7847d2d32aSternite public static function supportsImages() { 7947d2d32aSternite if (self::$image_support === null) { 8047d2d32aSternite self::testDependencies(); 8147d2d32aSternite } 8247d2d32aSternite return self::$image_support; 8347d2d32aSternite } 8447d2d32aSternite public static function ghostScriptFailed() { 8547d2d32aSternite if (self::$no_ghostscript_support === null) { 8647d2d32aSternite self::testDependencies(); 8747d2d32aSternite } 8847d2d32aSternite return self::$no_ghostscript_support; 8947d2d32aSternite } 905fa23922Sternite public static function imagickPDFpolicyFailed() { 915fa23922Sternite if (self::$no_imagick_pdf_readwrite === null) { 925fa23922Sternite self::testDependencies(); 935fa23922Sternite } 945fa23922Sternite return self::$no_imagick_pdf_readwrite; 955fa23922Sternite } 9647d2d32aSternite 9747d2d32aSternite public function __construct(string $source_filepath, DokuWiki_Syntax_Plugin $plugin, bool $ismediapath = true) { 9847d2d32aSternite 9947d2d32aSternite if ($ismediapath) { 10047d2d32aSternite $this->source_mediapath = $source_filepath; 10147d2d32aSternite $this->source_filepath = mediaFN($source_filepath); 10247d2d32aSternite } else { 10347d2d32aSternite $this->source_mediapath = false; 10447d2d32aSternite $this->source_filepath = $source_filepath; 10547d2d32aSternite } 10647d2d32aSternite 10747d2d32aSternite $this->max_dimension = $plugin->getConf('thumb_max_dimension'); 10847d2d32aSternite 10947d2d32aSternite // Now attach the correct thumb_engine for the file type of the source file 11047d2d32aSternite //TODO: check for extension "fileinfo", then check for MIME type: if (mime_content_type($filepath_local_file) == "application/pdf") { 11147d2d32aSternite $sourceFileSuffix = getFileSuffix($this->source_filepath); 11247d2d32aSternite if ($sourceFileSuffix == "pdf") { 11347d2d32aSternite // file suffix is pdf, so assume it's a PDF file 11447d2d32aSternite if (self::supportsPDF()) { 11547d2d32aSternite $this->thumb_engine = new thumb_pdf_engine($this); 11647d2d32aSternite } else { 117a99f1509Sternite 118a99f1509Sternite $hint = self::$dependency_problem ? " Hint: '".self::$dependency_problem."'\n" : ""; 119a99f1509Sternite 12047d2d32aSternite if (self::ghostScriptFailed()) { 121a99f1509Sternite dbg("plugin mediathumbnails: PDF files are supported, but not on this system.\nMost likely, ImageMagick and its PHP extension imagick are installed properly, but GhostScript is not.\n".$hint."Please refer to the plugin documentation for a description of the dependencies. ".self::$dependency_problem); 1225fa23922Sternite } else if(self::imagickPDFpolicyFailed()) { 123a99f1509Sternite dbg("plugin mediathumbnails: PDF files are supported, but not on this system.\nMost likely, ImageMagick is configured so that PDF conversion is not allowed due to security policies.\n".$hint."Please refer to the plugin documentation for a description of the dependencies. ".self::$dependency_problem); 12447d2d32aSternite } else { 125a99f1509Sternite dbg("plugin mediathumbnails: PDF files are supported, but not on this system.\nMost likely, ImageMagick or its PHP extension imagick are not installed properly.\n".$hint."Please refer to the plugin documentation for a description of the dependencies."); 12647d2d32aSternite } 12747d2d32aSternite } 12847d2d32aSternite } else if (self::supportsImages() && in_array(strtoupper($sourceFileSuffix), self::$formats)) { 12947d2d32aSternite // file suffix is in support list of ImageMagick 13047d2d32aSternite $this->thumb_engine = new thumb_img_engine($this); 13147d2d32aSternite } else if (!self::supportsImages()) { 13247d2d32aSternite dbg("plugin mediathumbnails: Image files are supported, but not on this system.\nPlease refer to the plugin documentation for a description of the dependencies."); 13347d2d32aSternite } else { 13447d2d32aSternite // last resort: check if the source file is a ZIP file and look for thumbnails, therein 13547d2d32aSternite $this->thumb_engine = new thumb_zip_engine($this,$plugin->getConf('thumb_paths')); 13647d2d32aSternite } 13747d2d32aSternite } 13847d2d32aSternite 139*e19533e1Sternite public function getMaxDimension(): int { 14047d2d32aSternite return $this->max_dimension; 14147d2d32aSternite } 14247d2d32aSternite 143*e19533e1Sternite public function create_if_missing(): bool { 14447d2d32aSternite if (!$this->thumb_engine) { 14547d2d32aSternite return false; 14647d2d32aSternite } 14747d2d32aSternite 14847d2d32aSternite return $this->thumb_engine->act(); 14947d2d32aSternite } 15047d2d32aSternite 151*e19533e1Sternite public function creation_has_failed(): bool { 152*e19533e1Sternite if (!$this->thumb_engine) { 153*e19533e1Sternite return true; 154*e19533e1Sternite } 155*e19533e1Sternite 156*e19533e1Sternite return $this->thumb_engine->has_failed(); 157*e19533e1Sternite } 158*e19533e1Sternite 15947d2d32aSternite public function getSourceFilepath() { 16047d2d32aSternite return $this->source_filepath; 16147d2d32aSternite } 16247d2d32aSternite 163*e19533e1Sternite public function getSourceFileExists(): bool { 164a99f1509Sternite return file_exists($this->source_filepath); 165a99f1509Sternite } 166a99f1509Sternite 167*e19533e1Sternite protected function getFilename(): string { 16847d2d32aSternite 16947d2d32aSternite return basename($this->source_filepath) . ".thumb".$this->max_dimension.".".$this->thumb_engine->getFileSuffix(); 17047d2d32aSternite } 17147d2d32aSternite 172*e19533e1Sternite public function getFilepath(): string { 17347d2d32aSternite return dirname($this->source_filepath) . DIRECTORY_SEPARATOR . $this->getFilename(); 17447d2d32aSternite } 17547d2d32aSternite 176*e19533e1Sternite public function getMediapath(): string|null { 17747d2d32aSternite if ($this->source_mediapath !== false) { 17847d2d32aSternite return substr($this->source_mediapath,0,strrpos($this->source_mediapath,':')) . ":" . $this->getFilename(); 17947d2d32aSternite } else { 180*e19533e1Sternite return null; 18147d2d32aSternite } 18247d2d32aSternite } 18347d2d32aSternite 184*e19533e1Sternite public function getTimestamp(): bool|int { 18547d2d32aSternite return file_exists($this->getFilepath()) ? filemtime($this->getFilepath()) : false; 18647d2d32aSternite } 18747d2d32aSternite}