preview.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. <?php
  2. /**
  3. * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org
  4. * Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
  5. * This file is licensed under the Affero General Public License version 3 or
  6. * later.
  7. * See the COPYING-README file.
  8. *
  9. * Thumbnails:
  10. * structure of filename:
  11. * /data/user/thumbnails/pathhash/x-y.png
  12. *
  13. */
  14. namespace OC;
  15. use OC\Files\Filesystem;
  16. use OC\Preview\Provider;
  17. require_once 'preview/image.php';
  18. require_once 'preview/movies.php';
  19. require_once 'preview/mp3.php';
  20. require_once 'preview/pdf.php';
  21. require_once 'preview/svg.php';
  22. require_once 'preview/txt.php';
  23. require_once 'preview/unknown.php';
  24. require_once 'preview/office.php';
  25. class Preview {
  26. //the thumbnail folder
  27. const THUMBNAILS_FOLDER = 'thumbnails';
  28. //config
  29. private $maxScaleFactor;
  30. private $configMaxX;
  31. private $configMaxY;
  32. //fileview object
  33. private $fileView = null;
  34. private $userView = null;
  35. //vars
  36. private $file;
  37. private $maxX;
  38. private $maxY;
  39. private $scalingUp;
  40. private $mimeType;
  41. private $keepAspect = false;
  42. //filemapper used for deleting previews
  43. // index is path, value is fileinfo
  44. static public $deleteFileMapper = array();
  45. /**
  46. * preview images object
  47. *
  48. * @var \OC_Image
  49. */
  50. private $preview;
  51. //preview providers
  52. static private $providers = array();
  53. static private $registeredProviders = array();
  54. /**
  55. * @var \OCP\Files\FileInfo
  56. */
  57. protected $info;
  58. /**
  59. * check if thumbnail or bigger version of thumbnail of file is cached
  60. * @param string $user userid - if no user is given, OC_User::getUser will be used
  61. * @param string $root path of root
  62. * @param string $file The path to the file where you want a thumbnail from
  63. * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image
  64. * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
  65. * @param bool $scalingUp Disable/Enable upscaling of previews
  66. * @throws \Exception
  67. * @return mixed (bool / string)
  68. * false if thumbnail does not exist
  69. * path to thumbnail if thumbnail exists
  70. */
  71. public function __construct($user = '', $root = '/', $file = '', $maxX = 1, $maxY = 1, $scalingUp = true) {
  72. //init fileviews
  73. if ($user === '') {
  74. $user = \OC_User::getUser();
  75. }
  76. $this->fileView = new \OC\Files\View('/' . $user . '/' . $root);
  77. $this->userView = new \OC\Files\View('/' . $user);
  78. //set config
  79. $this->configMaxX = \OC_Config::getValue('preview_max_x', null);
  80. $this->configMaxY = \OC_Config::getValue('preview_max_y', null);
  81. $this->maxScaleFactor = \OC_Config::getValue('preview_max_scale_factor', 2);
  82. //save parameters
  83. $this->setFile($file);
  84. $this->setMaxX($maxX);
  85. $this->setMaxY($maxY);
  86. $this->setScalingUp($scalingUp);
  87. $this->preview = null;
  88. //check if there are preview backends
  89. if (empty(self::$providers)) {
  90. self::initProviders();
  91. }
  92. if (empty(self::$providers)) {
  93. \OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR);
  94. throw new \Exception('No preview providers');
  95. }
  96. }
  97. /**
  98. * returns the path of the file you want a thumbnail from
  99. * @return string
  100. */
  101. public function getFile() {
  102. return $this->file;
  103. }
  104. /**
  105. * returns the max width of the preview
  106. * @return integer
  107. */
  108. public function getMaxX() {
  109. return $this->maxX;
  110. }
  111. /**
  112. * returns the max height of the preview
  113. * @return integer
  114. */
  115. public function getMaxY() {
  116. return $this->maxY;
  117. }
  118. /**
  119. * returns whether or not scalingup is enabled
  120. * @return bool
  121. */
  122. public function getScalingUp() {
  123. return $this->scalingUp;
  124. }
  125. /**
  126. * returns the name of the thumbnailfolder
  127. * @return string
  128. */
  129. public function getThumbnailsFolder() {
  130. return self::THUMBNAILS_FOLDER;
  131. }
  132. /**
  133. * returns the max scale factor
  134. * @return string
  135. */
  136. public function getMaxScaleFactor() {
  137. return $this->maxScaleFactor;
  138. }
  139. /**
  140. * returns the max width set in ownCloud's config
  141. * @return string
  142. */
  143. public function getConfigMaxX() {
  144. return $this->configMaxX;
  145. }
  146. /**
  147. * returns the max height set in ownCloud's config
  148. * @return string
  149. */
  150. public function getConfigMaxY() {
  151. return $this->configMaxY;
  152. }
  153. /**
  154. * @return false|Files\FileInfo|\OCP\Files\FileInfo
  155. */
  156. protected function getFileInfo() {
  157. $absPath = $this->fileView->getAbsolutePath($this->file);
  158. $absPath = Files\Filesystem::normalizePath($absPath);
  159. if(array_key_exists($absPath, self::$deleteFileMapper)) {
  160. $this->info = self::$deleteFileMapper[$absPath];
  161. } else if (!$this->info) {
  162. $this->info = $this->fileView->getFileInfo($this->file);
  163. }
  164. return $this->info;
  165. }
  166. /**
  167. * set the path of the file you want a thumbnail from
  168. * @param string $file
  169. * @return \OC\Preview $this
  170. */
  171. public function setFile($file) {
  172. $this->file = $file;
  173. $this->info = null;
  174. if ($file !== '') {
  175. $this->getFileInfo();
  176. if($this->info !== null && $this->info !== false) {
  177. $this->mimeType = $this->info->getMimetype();
  178. }
  179. }
  180. return $this;
  181. }
  182. /**
  183. * set mime type explicitly
  184. * @param string $mimeType
  185. */
  186. public function setMimetype($mimeType) {
  187. $this->mimeType = $mimeType;
  188. }
  189. /**
  190. * set the the max width of the preview
  191. * @param int $maxX
  192. * @throws \Exception
  193. * @return \OC\Preview $this
  194. */
  195. public function setMaxX($maxX = 1) {
  196. if ($maxX <= 0) {
  197. throw new \Exception('Cannot set width of 0 or smaller!');
  198. }
  199. $configMaxX = $this->getConfigMaxX();
  200. if (!is_null($configMaxX)) {
  201. if ($maxX > $configMaxX) {
  202. \OC_Log::write('core', 'maxX reduced from ' . $maxX . ' to ' . $configMaxX, \OC_Log::DEBUG);
  203. $maxX = $configMaxX;
  204. }
  205. }
  206. $this->maxX = $maxX;
  207. return $this;
  208. }
  209. /**
  210. * set the the max height of the preview
  211. * @param int $maxY
  212. * @throws \Exception
  213. * @return \OC\Preview $this
  214. */
  215. public function setMaxY($maxY = 1) {
  216. if ($maxY <= 0) {
  217. throw new \Exception('Cannot set height of 0 or smaller!');
  218. }
  219. $configMaxY = $this->getConfigMaxY();
  220. if (!is_null($configMaxY)) {
  221. if ($maxY > $configMaxY) {
  222. \OC_Log::write('core', 'maxX reduced from ' . $maxY . ' to ' . $configMaxY, \OC_Log::DEBUG);
  223. $maxY = $configMaxY;
  224. }
  225. }
  226. $this->maxY = $maxY;
  227. return $this;
  228. }
  229. /**
  230. * set whether or not scalingup is enabled
  231. * @param bool $scalingUp
  232. * @return \OC\Preview $this
  233. */
  234. public function setScalingup($scalingUp) {
  235. if ($this->getMaxScaleFactor() === 1) {
  236. $scalingUp = false;
  237. }
  238. $this->scalingUp = $scalingUp;
  239. return $this;
  240. }
  241. public function setKeepAspect($keepAspect) {
  242. $this->keepAspect = $keepAspect;
  243. return $this;
  244. }
  245. /**
  246. * check if all parameters are valid
  247. * @return bool
  248. */
  249. public function isFileValid() {
  250. $file = $this->getFile();
  251. if ($file === '') {
  252. \OC_Log::write('core', 'No filename passed', \OC_Log::DEBUG);
  253. return false;
  254. }
  255. if (!$this->fileView->file_exists($file)) {
  256. \OC_Log::write('core', 'File:"' . $file . '" not found', \OC_Log::DEBUG);
  257. return false;
  258. }
  259. return true;
  260. }
  261. /**
  262. * deletes previews of a file with specific x and y
  263. * @return bool
  264. */
  265. public function deletePreview() {
  266. $file = $this->getFile();
  267. $fileInfo = $this->getFileInfo($file);
  268. if($fileInfo !== null && $fileInfo !== false) {
  269. $fileId = $fileInfo->getId();
  270. $previewPath = $this->buildCachePath($fileId);
  271. return $this->userView->unlink($previewPath);
  272. }
  273. return false;
  274. }
  275. /**
  276. * deletes all previews of a file
  277. * @return bool
  278. */
  279. public function deleteAllPreviews() {
  280. $file = $this->getFile();
  281. $fileInfo = $this->getFileInfo($file);
  282. if($fileInfo !== null && $fileInfo !== false) {
  283. $fileId = $fileInfo->getId();
  284. $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
  285. $this->userView->deleteAll($previewPath);
  286. return $this->userView->rmdir($previewPath);
  287. }
  288. return false;
  289. }
  290. /**
  291. * check if thumbnail or bigger version of thumbnail of file is cached
  292. * @param int $fileId fileId of the original image
  293. * @return string|false path to thumbnail if it exists or false
  294. */
  295. public function isCached($fileId) {
  296. if (is_null($fileId)) {
  297. return false;
  298. }
  299. $preview = $this->buildCachePath($fileId);
  300. //does a preview with the wanted height and width already exist?
  301. if ($this->userView->file_exists($preview)) {
  302. return $preview;
  303. }
  304. return $this->isCachedBigger($fileId);
  305. }
  306. /**
  307. * check if a bigger version of thumbnail of file is cached
  308. * @param int $fileId fileId of the original image
  309. * @return string|false path to bigger thumbnail if it exists or false
  310. */
  311. private function isCachedBigger($fileId) {
  312. if (is_null($fileId)) {
  313. return false;
  314. }
  315. // in order to not loose quality we better generate aspect preserving previews from the original file
  316. if ($this->keepAspect) {
  317. return false;
  318. }
  319. $maxX = $this->getMaxX();
  320. //array for usable cached thumbnails
  321. $possibleThumbnails = $this->getPossibleThumbnails($fileId);
  322. foreach ($possibleThumbnails as $width => $path) {
  323. if ($width < $maxX) {
  324. continue;
  325. } else {
  326. return $path;
  327. }
  328. }
  329. return false;
  330. }
  331. /**
  332. * get possible bigger thumbnails of the given image
  333. * @param int $fileId fileId of the original image
  334. * @return array an array of paths to bigger thumbnails
  335. */
  336. private function getPossibleThumbnails($fileId) {
  337. if (is_null($fileId)) {
  338. return array();
  339. }
  340. $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
  341. $wantedAspectRatio = (float) ($this->getMaxX() / $this->getMaxY());
  342. //array for usable cached thumbnails
  343. $possibleThumbnails = array();
  344. $allThumbnails = $this->userView->getDirectoryContent($previewPath);
  345. foreach ($allThumbnails as $thumbnail) {
  346. $name = rtrim($thumbnail['name'], '.png');
  347. list($x, $y, $aspectRatio) = $this->getDimensionsFromFilename($name);
  348. if (abs($aspectRatio - $wantedAspectRatio) >= 0.000001
  349. || $this->unscalable($x, $y)
  350. ) {
  351. continue;
  352. }
  353. $possibleThumbnails[$x] = $thumbnail['path'];
  354. }
  355. ksort($possibleThumbnails);
  356. return $possibleThumbnails;
  357. }
  358. /**
  359. * @param string $name
  360. * @return array
  361. */
  362. private function getDimensionsFromFilename($name) {
  363. $size = explode('-', $name);
  364. $x = (int) $size[0];
  365. $y = (int) $size[1];
  366. $aspectRatio = (float) ($x / $y);
  367. return array($x, $y, $aspectRatio);
  368. }
  369. /**
  370. * @param int $x
  371. * @param int $y
  372. * @return bool
  373. */
  374. private function unscalable($x, $y) {
  375. $maxX = $this->getMaxX();
  376. $maxY = $this->getMaxY();
  377. $scalingUp = $this->getScalingUp();
  378. $maxScaleFactor = $this->getMaxScaleFactor();
  379. if ($x < $maxX || $y < $maxY) {
  380. if ($scalingUp) {
  381. $scalefactor = $maxX / $x;
  382. if ($scalefactor > $maxScaleFactor) {
  383. return true;
  384. }
  385. } else {
  386. return true;
  387. }
  388. }
  389. return false;
  390. }
  391. /**
  392. * return a preview of a file
  393. * @return \OC_Image
  394. */
  395. public function getPreview() {
  396. if (!is_null($this->preview) && $this->preview->valid()) {
  397. return $this->preview;
  398. }
  399. $this->preview = null;
  400. $file = $this->getFile();
  401. $maxX = $this->getMaxX();
  402. $maxY = $this->getMaxY();
  403. $scalingUp = $this->getScalingUp();
  404. $fileInfo = $this->getFileInfo($file);
  405. if($fileInfo === null || $fileInfo === false) {
  406. return new \OC_Image();
  407. }
  408. $fileId = $fileInfo->getId();
  409. $cached = $this->isCached($fileId);
  410. if ($cached) {
  411. $stream = $this->userView->fopen($cached, 'r');
  412. $image = new \OC_Image();
  413. $image->loadFromFileHandle($stream);
  414. $this->preview = $image->valid() ? $image : null;
  415. $this->resizeAndCrop();
  416. fclose($stream);
  417. }
  418. if (is_null($this->preview)) {
  419. $preview = null;
  420. foreach (self::$providers as $supportedMimeType => $provider) {
  421. if (!preg_match($supportedMimeType, $this->mimeType)) {
  422. continue;
  423. }
  424. \OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG);
  425. /** @var $provider Provider */
  426. $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView);
  427. if (!($preview instanceof \OC_Image)) {
  428. continue;
  429. }
  430. $this->preview = $preview;
  431. $this->resizeAndCrop();
  432. $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
  433. $cachePath = $this->buildCachePath($fileId);
  434. if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) {
  435. $this->userView->mkdir($this->getThumbnailsFolder() . '/');
  436. }
  437. if ($this->userView->is_dir($previewPath) === false) {
  438. $this->userView->mkdir($previewPath);
  439. }
  440. $this->userView->file_put_contents($cachePath, $preview->data());
  441. break;
  442. }
  443. }
  444. if (is_null($this->preview)) {
  445. $this->preview = new \OC_Image();
  446. }
  447. return $this->preview;
  448. }
  449. /**
  450. * show preview
  451. * @return void
  452. */
  453. public function showPreview($mimeType = null) {
  454. \OCP\Response::enableCaching(3600 * 24); // 24 hours
  455. if (is_null($this->preview)) {
  456. $this->getPreview();
  457. }
  458. $this->preview->show($mimeType);
  459. }
  460. /**
  461. * resize, crop and fix orientation
  462. * @return void
  463. */
  464. private function resizeAndCrop() {
  465. $image = $this->preview;
  466. $x = $this->getMaxX();
  467. $y = $this->getMaxY();
  468. $scalingUp = $this->getScalingUp();
  469. $maxScaleFactor = $this->getMaxScaleFactor();
  470. if (!($image instanceof \OC_Image)) {
  471. \OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG);
  472. return;
  473. }
  474. $image->fixOrientation();
  475. $realX = (int)$image->width();
  476. $realY = (int)$image->height();
  477. // compute $maxY and $maxX using the aspect of the generated preview
  478. if ($this->keepAspect) {
  479. $ratio = $realX / $realY;
  480. if($x / $ratio < $y) {
  481. // width restricted
  482. $y = $x / $ratio;
  483. } else {
  484. $x = $y * $ratio;
  485. }
  486. }
  487. if ($x === $realX && $y === $realY) {
  488. $this->preview = $image;
  489. return;
  490. }
  491. $factorX = $x / $realX;
  492. $factorY = $y / $realY;
  493. if ($factorX >= $factorY) {
  494. $factor = $factorX;
  495. } else {
  496. $factor = $factorY;
  497. }
  498. if ($scalingUp === false) {
  499. if ($factor > 1) {
  500. $factor = 1;
  501. }
  502. }
  503. if (!is_null($maxScaleFactor)) {
  504. if ($factor > $maxScaleFactor) {
  505. \OC_Log::write('core', 'scale factor reduced from ' . $factor . ' to ' . $maxScaleFactor, \OC_Log::DEBUG);
  506. $factor = $maxScaleFactor;
  507. }
  508. }
  509. $newXSize = (int)($realX * $factor);
  510. $newYSize = (int)($realY * $factor);
  511. $image->preciseResize($newXSize, $newYSize);
  512. if ($newXSize === $x && $newYSize === $y) {
  513. $this->preview = $image;
  514. return;
  515. }
  516. if ($newXSize >= $x && $newYSize >= $y) {
  517. $cropX = floor(abs($x - $newXSize) * 0.5);
  518. //don't crop previews on the Y axis, this sucks if it's a document.
  519. //$cropY = floor(abs($y - $newYsize) * 0.5);
  520. $cropY = 0;
  521. $image->crop($cropX, $cropY, $x, $y);
  522. $this->preview = $image;
  523. return;
  524. }
  525. if (($newXSize < $x || $newYSize < $y) && $scalingUp) {
  526. if ($newXSize > $x) {
  527. $cropX = floor(($newXSize - $x) * 0.5);
  528. $image->crop($cropX, 0, $x, $newYSize);
  529. }
  530. if ($newYSize > $y) {
  531. $cropY = floor(($newYSize - $y) * 0.5);
  532. $image->crop(0, $cropY, $newXSize, $y);
  533. }
  534. $newXSize = (int)$image->width();
  535. $newYSize = (int)$image->height();
  536. //create transparent background layer
  537. $backgroundLayer = imagecreatetruecolor($x, $y);
  538. $white = imagecolorallocate($backgroundLayer, 255, 255, 255);
  539. imagefill($backgroundLayer, 0, 0, $white);
  540. $image = $image->resource();
  541. $mergeX = floor(abs($x - $newXSize) * 0.5);
  542. $mergeY = floor(abs($y - $newYSize) * 0.5);
  543. imagecopy($backgroundLayer, $image, $mergeX, $mergeY, 0, 0, $newXSize, $newYSize);
  544. //$black = imagecolorallocate(0,0,0);
  545. //imagecolortransparent($transparentlayer, $black);
  546. $image = new \OC_Image($backgroundLayer);
  547. $this->preview = $image;
  548. return;
  549. }
  550. }
  551. /**
  552. * register a new preview provider to be used
  553. * @param array $options
  554. * @return void
  555. */
  556. public static function registerProvider($class, $options = array()) {
  557. self::$registeredProviders[] = array('class' => $class, 'options' => $options);
  558. }
  559. /**
  560. * create instances of all the registered preview providers
  561. * @return void
  562. */
  563. private static function initProviders() {
  564. if (!\OC_Config::getValue('enable_previews', true)) {
  565. $provider = new Preview\Unknown(array());
  566. self::$providers = array($provider->getMimeType() => $provider);
  567. return;
  568. }
  569. if (count(self::$providers) > 0) {
  570. return;
  571. }
  572. foreach (self::$registeredProviders as $provider) {
  573. $class = $provider['class'];
  574. $options = $provider['options'];
  575. /** @var $object Provider */
  576. $object = new $class($options);
  577. self::$providers[$object->getMimeType()] = $object;
  578. }
  579. $keys = array_map('strlen', array_keys(self::$providers));
  580. array_multisort($keys, SORT_DESC, self::$providers);
  581. }
  582. public static function post_write($args) {
  583. self::post_delete($args, 'files/');
  584. }
  585. public static function prepare_delete_files($args) {
  586. self::prepare_delete($args, 'files/');
  587. }
  588. public static function prepare_delete($args, $prefix='') {
  589. $path = $args['path'];
  590. if (substr($path, 0, 1) === '/') {
  591. $path = substr($path, 1);
  592. }
  593. $view = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $prefix);
  594. $info = $view->getFileInfo($path);
  595. \OC\Preview::$deleteFileMapper = array_merge(
  596. \OC\Preview::$deleteFileMapper,
  597. array(
  598. Files\Filesystem::normalizePath($view->getAbsolutePath($path)) => $info,
  599. )
  600. );
  601. }
  602. public static function post_delete_files($args) {
  603. self::post_delete($args, 'files/');
  604. }
  605. public static function post_delete($args, $prefix='') {
  606. $path = Files\Filesystem::normalizePath($args['path']);
  607. $preview = new Preview(\OC_User::getUser(), $prefix, $path);
  608. $preview->deleteAllPreviews();
  609. }
  610. /**
  611. * Check if a preview can be generated for a file
  612. *
  613. * @param \OC\Files\FileInfo $file
  614. * @return bool
  615. */
  616. public static function isAvailable($file) {
  617. if (!\OC_Config::getValue('enable_previews', true)) {
  618. return false;
  619. }
  620. //check if there are preview backends
  621. if (empty(self::$providers)) {
  622. self::initProviders();
  623. }
  624. //remove last element because it has the mimetype *
  625. $providers = array_slice(self::$providers, 0, -1);
  626. foreach ($providers as $supportedMimeType => $provider) {
  627. /**
  628. * @var \OC\Preview\Provider $provider
  629. */
  630. if (preg_match($supportedMimeType, $file->getMimetype())) {
  631. return $provider->isAvailable($file);
  632. }
  633. }
  634. return false;
  635. }
  636. /**
  637. * @param string $mimeType
  638. * @return bool
  639. */
  640. public static function isMimeSupported($mimeType) {
  641. if (!\OC_Config::getValue('enable_previews', true)) {
  642. return false;
  643. }
  644. //check if there are preview backends
  645. if (empty(self::$providers)) {
  646. self::initProviders();
  647. }
  648. //remove last element because it has the mimetype *
  649. $providers = array_slice(self::$providers, 0, -1);
  650. foreach ($providers as $supportedMimeType => $provider) {
  651. if (preg_match($supportedMimeType, $mimeType)) {
  652. return true;
  653. }
  654. }
  655. return false;
  656. }
  657. /**
  658. * @param int $fileId
  659. * @return string
  660. */
  661. private function buildCachePath($fileId) {
  662. $maxX = $this->getMaxX();
  663. $maxY = $this->getMaxY();
  664. $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
  665. $preview = $previewPath . $maxX . '-' . $maxY . '.png';
  666. if ($this->keepAspect) {
  667. $preview = $previewPath . $maxX . '-with-aspect.png';
  668. return $preview;
  669. }
  670. return $preview;
  671. }
  672. }