123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <?php
- /**
- * @package Grav\Common\Page
- *
- * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
- * @license MIT License; see LICENSE file for details.
- */
- namespace Grav\Common\Page\Medium;
- use Exception;
- use Grav\Common\Config\Config;
- use Grav\Common\Grav;
- use Gregwar\Image\Exceptions\GenerationError;
- use Gregwar\Image\Image;
- use Gregwar\Image\Source;
- use RocketTheme\Toolbox\Event\Event;
- use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
- use RuntimeException;
- use function array_key_exists;
- use function count;
- use function extension_loaded;
- use function in_array;
- /**
- * Class ImageFile
- * @package Grav\Common\Page\Medium
- *
- * @method Image applyExifOrientation($exif_orienation)
- */
- class ImageFile extends Image
- {
- /**
- * Destruct also image object.
- */
- #[\ReturnTypeWillChange]
- public function __destruct()
- {
- $adapter = $this->adapter;
- if ($adapter) {
- $adapter->deinit();
- }
- }
- /**
- * Clear previously applied operations
- *
- * @return void
- */
- public function clearOperations()
- {
- $this->operations = [];
- }
- /**
- * This is the same as the Gregwar Image class except this one fires a Grav Event on creation of new cached file
- *
- * @param string $type the image type
- * @param int $quality the quality (for JPEG)
- * @param bool $actual
- * @param array $extras
- * @return string
- */
- public function cacheFile($type = 'jpg', $quality = 80, $actual = false, $extras = [])
- {
- if ($type === 'guess') {
- $type = $this->guessType();
- }
- if (!$this->forceCache && !count($this->operations) && $type === $this->guessType()) {
- return $this->getFilename($this->getFilePath());
- }
- // Computes the hash
- $this->hash = $this->getHash($type, $quality, $extras);
- /** @var Config $config */
- $config = Grav::instance()['config'];
- // Seo friendly image names
- $seofriendly = $config->get('system.images.seofriendly', false);
- if ($seofriendly) {
- $mini_hash = substr($this->hash, 0, 4) . substr($this->hash, -4);
- $cacheFile = "{$this->prettyName}-{$mini_hash}";
- } else {
- $cacheFile = "{$this->hash}-{$this->prettyName}";
- }
- $cacheFile .= '.' . $type;
- // If the files does not exists, save it
- $image = $this;
- // Target file should be younger than all the current image
- // dependencies
- $conditions = array(
- 'younger-than' => $this->getDependencies()
- );
- // The generating function
- $generate = function ($target) use ($image, $type, $quality) {
- $result = $image->save($target, $type, $quality);
- if ($result !== $target) {
- throw new GenerationError($result);
- }
- Grav::instance()->fireEvent('onImageMediumSaved', new Event(['image' => $target]));
- };
- // Asking the cache for the cacheFile
- try {
- $perms = $config->get('system.images.cache_perms', '0755');
- $perms = octdec($perms);
- $file = $this->getCacheSystem()->setDirectoryMode($perms)->getOrCreateFile($cacheFile, $conditions, $generate, $actual);
- } catch (GenerationError $e) {
- $file = $e->getNewFile();
- }
- // Nulling the resource
- $adapter = $this->getAdapter();
- $adapter->setSource(new Source\File($file));
- $adapter->deinit();
- if ($actual) {
- return $file;
- }
- return $this->getFilename($file);
- }
- /**
- * Gets the hash.
- *
- * @param string $type
- * @param int $quality
- * @param array $extras
- * @return string
- */
- public function getHash($type = 'guess', $quality = 80, $extras = [])
- {
- if (null === $this->hash) {
- $this->generateHash($type, $quality, $extras);
- }
- return $this->hash;
- }
- /**
- * Generates the hash.
- *
- * @param string $type
- * @param int $quality
- * @param array $extras
- */
- public function generateHash($type = 'guess', $quality = 80, $extras = [])
- {
- $inputInfos = $this->source->getInfos();
- $data = [
- $inputInfos,
- $this->serializeOperations(),
- $type,
- $quality,
- $extras
- ];
- $this->hash = sha1(serialize($data));
- }
- /**
- * Read exif rotation from file and apply it.
- */
- public function fixOrientation()
- {
- if (!extension_loaded('exif')) {
- throw new RuntimeException('You need to EXIF PHP Extension to use this function');
- }
- if (!in_array(exif_imagetype($this->source->getInfos()), [IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM], true)) {
- return $this;
- }
- // resolve any streams
- /** @var UniformResourceLocator $locator */
- $locator = Grav::instance()['locator'];
- $filepath = $this->source->getInfos();
- if ($locator->isStream($filepath)) {
- $filepath = $locator->findResource($this->source->getInfos(), true, true);
- }
- // Make sure file exists
- if (!file_exists($filepath)) {
- return $this;
- }
- try {
- $exif = @exif_read_data($filepath);
- } catch (Exception $e) {
- Grav::instance()['log']->error($filepath . ' - ' . $e->getMessage());
- return $this;
- }
- if ($exif === false || !array_key_exists('Orientation', $exif)) {
- return $this;
- }
- return $this->applyExifOrientation($exif['Orientation']);
- }
- }
|