xref: /plugin/mediathumbnails/thumbnail.php (revision 47d2d32a51e008f2a2fbe2231b85ab1545824cca)
1*47d2d32aSternite<?php
2*47d2d32aSternite/**
3*47d2d32aSternite * DokuWiki Plugin mediathumbnails (thumbnail class)
4*47d2d32aSternite *
5*47d2d32aSternite * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6*47d2d32aSternite * @author  Thomas Schäfer <thomas.schaefer@itschert.net>
7*47d2d32aSternite */
8*47d2d32aSternite
9*47d2d32aSterniterequire('thumb_engines.php');
10*47d2d32aSternite
11*47d2d32aSternitefunction getFileSuffix(string $file) {
12*47d2d32aSternite	return substr(strrchr($file,'.'),1);
13*47d2d32aSternite}
14*47d2d32aSternite
15*47d2d32aSterniteclass thumbnail {
16*47d2d32aSternite
17*47d2d32aSternite	private $source_filepath;
18*47d2d32aSternite	private $source_mediapath;
19*47d2d32aSternite	private ?thumb_engine $thumb_engine = null;
20*47d2d32aSternite	private int $max_dimension;
21*47d2d32aSternite
22*47d2d32aSternite	private static $formats;
23*47d2d32aSternite	private static ?bool $pdf_support = null;
24*47d2d32aSternite	private static ?bool $image_support = null;
25*47d2d32aSternite	private static ?bool $no_ghostscript_support = null;
26*47d2d32aSternite
27*47d2d32aSternite	private static function testDependencies() {
28*47d2d32aSternite		// TODO: move support tests to a Singleton
29*47d2d32aSternite		self::$image_support = false;
30*47d2d32aSternite		self::$pdf_support = false;
31*47d2d32aSternite		self::$no_ghostscript_support = false;
32*47d2d32aSternite		if (class_exists ("Imagick")) {
33*47d2d32aSternite			// determine file formats supported by ImageMagick
34*47d2d32aSternite			self::$formats = \Imagick::queryformats();
35*47d2d32aSternite
36*47d2d32aSternite			if (count(self::$formats) > 0) {
37*47d2d32aSternite				self::$image_support = true;
38*47d2d32aSternite				if (in_array("PDF", self::$formats)) {
39*47d2d32aSternite					// Check if GhostScript will answer!
40*47d2d32aSternite					try {
41*47d2d32aSternite						// blank.pdf is an empty reference PDF file to test if GhostScript will react upon loading the file into ImageMagick
42*47d2d32aSternite						$im = new imagick(realpath("lib/plugins/mediathumbnails/blank.pdf")."[0]");
43*47d2d32aSternite						$im->clear();
44*47d2d32aSternite						$im->destroy();
45*47d2d32aSternite						self::$pdf_support = true;
46*47d2d32aSternite					} catch (ImagickException $e) {
47*47d2d32aSternite						if (strpos($e,"PDFDelegateFailed") !== false) {
48*47d2d32aSternite							self::$no_ghostscript_support = true;
49*47d2d32aSternite						}
50*47d2d32aSternite						self::$pdf_support = false;
51*47d2d32aSternite					}
52*47d2d32aSternite
53*47d2d32aSternite				}
54*47d2d32aSternite			}
55*47d2d32aSternite
56*47d2d32aSternite		}
57*47d2d32aSternite	}
58*47d2d32aSternite	public static function supportsPDF() {
59*47d2d32aSternite		if (self::$pdf_support === null) {
60*47d2d32aSternite			self::testDependencies();
61*47d2d32aSternite		}
62*47d2d32aSternite		return self::$pdf_support;
63*47d2d32aSternite	}
64*47d2d32aSternite	public static function supportsImages() {
65*47d2d32aSternite		if (self::$image_support === null) {
66*47d2d32aSternite			self::testDependencies();
67*47d2d32aSternite		}
68*47d2d32aSternite		return self::$image_support;
69*47d2d32aSternite	}
70*47d2d32aSternite	public static function ghostScriptFailed() {
71*47d2d32aSternite		if (self::$no_ghostscript_support === null) {
72*47d2d32aSternite			self::testDependencies();
73*47d2d32aSternite		}
74*47d2d32aSternite		return self::$no_ghostscript_support;
75*47d2d32aSternite	}
76*47d2d32aSternite
77*47d2d32aSternite	public function __construct(string $source_filepath, DokuWiki_Syntax_Plugin $plugin, bool $ismediapath = true) {
78*47d2d32aSternite
79*47d2d32aSternite		if ($ismediapath) {
80*47d2d32aSternite			$this->source_mediapath = $source_filepath;
81*47d2d32aSternite			$this->source_filepath = mediaFN($source_filepath);
82*47d2d32aSternite		} else {
83*47d2d32aSternite			$this->source_mediapath = false;
84*47d2d32aSternite			$this->source_filepath = $source_filepath;
85*47d2d32aSternite		}
86*47d2d32aSternite
87*47d2d32aSternite		$this->max_dimension = $plugin->getConf('thumb_max_dimension');
88*47d2d32aSternite
89*47d2d32aSternite		// Now attach the correct thumb_engine for the file type of the source file
90*47d2d32aSternite		//TODO: check for extension "fileinfo", then check for MIME type: if (mime_content_type($filepath_local_file) == "application/pdf") {
91*47d2d32aSternite		$sourceFileSuffix = getFileSuffix($this->source_filepath);
92*47d2d32aSternite		if ($sourceFileSuffix == "pdf") {
93*47d2d32aSternite			// file suffix is pdf, so assume it's a PDF file
94*47d2d32aSternite			if (self::supportsPDF()) {
95*47d2d32aSternite				$this->thumb_engine = new thumb_pdf_engine($this);
96*47d2d32aSternite			} else {
97*47d2d32aSternite				if (self::ghostScriptFailed()) {
98*47d2d32aSternite					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.\nPlease refer to the plugin documentation for a description of the dependencies.");
99*47d2d32aSternite				} else {
100*47d2d32aSternite					dbg("plugin mediathumbnails: PDF files are supported, but not on this system.\nMost likely, ImageMagick or its PHP extension imagick are not installed properly.\nPlease refer to the plugin documentation for a description of the dependencies.");
101*47d2d32aSternite				}
102*47d2d32aSternite			}
103*47d2d32aSternite		} else if (self::supportsImages() && in_array(strtoupper($sourceFileSuffix), self::$formats)) {
104*47d2d32aSternite			// file suffix is in support list of ImageMagick
105*47d2d32aSternite			$this->thumb_engine = new thumb_img_engine($this);
106*47d2d32aSternite		} else if (!self::supportsImages()) {
107*47d2d32aSternite			dbg("plugin mediathumbnails: Image files are supported, but not on this system.\nPlease refer to the plugin documentation for a description of the dependencies.");
108*47d2d32aSternite		} else {
109*47d2d32aSternite			// last resort: check if the source file is a ZIP file and look for thumbnails, therein
110*47d2d32aSternite			$this->thumb_engine = new thumb_zip_engine($this,$plugin->getConf('thumb_paths'));
111*47d2d32aSternite		}
112*47d2d32aSternite	}
113*47d2d32aSternite
114*47d2d32aSternite	public function getMaxDimension() {
115*47d2d32aSternite		return $this->max_dimension;
116*47d2d32aSternite	}
117*47d2d32aSternite
118*47d2d32aSternite	public function create() {
119*47d2d32aSternite		if (!$this->thumb_engine) {
120*47d2d32aSternite			return false;
121*47d2d32aSternite		}
122*47d2d32aSternite
123*47d2d32aSternite		return $this->thumb_engine->act();
124*47d2d32aSternite	}
125*47d2d32aSternite
126*47d2d32aSternite	public function getSourceFilepath() {
127*47d2d32aSternite		return $this->source_filepath;
128*47d2d32aSternite	}
129*47d2d32aSternite
130*47d2d32aSternite	protected function getFilename() {
131*47d2d32aSternite
132*47d2d32aSternite		return basename($this->source_filepath) . ".thumb".$this->max_dimension.".".$this->thumb_engine->getFileSuffix();
133*47d2d32aSternite	}
134*47d2d32aSternite
135*47d2d32aSternite	public function getFilepath() {
136*47d2d32aSternite		return dirname($this->source_filepath) . DIRECTORY_SEPARATOR . $this->getFilename();
137*47d2d32aSternite	}
138*47d2d32aSternite
139*47d2d32aSternite	public function getMediapath() {
140*47d2d32aSternite		if ($this->source_mediapath !== false) {
141*47d2d32aSternite			return substr($this->source_mediapath,0,strrpos($this->source_mediapath,':')) . ":" . $this->getFilename();
142*47d2d32aSternite		} else {
143*47d2d32aSternite			return false;
144*47d2d32aSternite		}
145*47d2d32aSternite	}
146*47d2d32aSternite
147*47d2d32aSternite	public function getTimestamp() {
148*47d2d32aSternite		return file_exists($this->getFilepath()) ? filemtime($this->getFilepath()) : false;
149*47d2d32aSternite	}
150*47d2d32aSternite}