diff --git a/config/config.php b/config/config.php index 62f551a..b891077 100755 --- a/config/config.php +++ b/config/config.php @@ -18,6 +18,15 @@ */ 'crops_disk' => 'public', + /* + * The (optional) disk where remote source images are temporarily copied + * to allow correct EXIF image rotation to occur. + * (The Intervention Image library can't correctly orientate remote images - + * see: https://image.intervention.io/v2/api/orientate) + * Set to false/null/empty-string to disable. + */ + 'tmp_disk' => 'public', + /* * Maximum number of sizes to allow for a particular source file. This is to * limit scripts from filling up your hard drive with images. Set to false or diff --git a/src/Storage.php b/src/Storage.php index 0a782f4..4ebdce6 100644 --- a/src/Storage.php +++ b/src/Storage.php @@ -28,6 +28,16 @@ final class Storage */ private $srcDisk; + /** + * @var ?FilesystemAdapter + */ + private $tmpDisk; + + /** + * @var bool + */ + private $tmpPath = ''; + /** * Inject dependencies. */ @@ -84,6 +94,26 @@ public function getSrcDisk(): FilesystemAdapter return $this->srcDisk; } + /** + * Set the tmp disk. + */ + public function setTmpDisk(FilesystemAdapter $disk): void + { + $this->tmpDisk = $disk; + } + + /** + * Get the tmp disk or make via the config. + */ + public function getTmpDisk(): FilesystemAdapter + { + if (empty($this->tmpDisk)) { + $this->setTmpDisk($this->makeDisk($this->config['tmp_disk'])); + } + + return $this->tmpDisk; + } + /** * "Mount" disks given the config. */ @@ -124,13 +154,21 @@ public function cropExists(string $path): bool */ public function path(string $path): string { - $disk = $this->getSrcDisk(); - if ($disk->fileExists($path)) { - if ($disk->getAdapter() instanceof LocalFilesystemAdapter) { - return $disk->path($path); + $srcDisk = $this->getSrcDisk(); + if ($srcDisk->fileExists($path)) { + if ($srcDisk->getAdapter() instanceof LocalFilesystemAdapter) { + return $srcDisk->path($path); + } + + // If the src_disk is a remote disk, and a tmp_disk has been configured, copy file to tmp_disk - otherwise EXIF auto-rotation won't work) + if ($this->config['tmp_disk']) { + $tmpDisk = $this->getTmpDisk(); + $tmpDisk->writeStream($path, $srcDisk->readStream($path)); + $this->tmpPath = $path; + return $tmpDisk->path($path); } - return $disk->url($path); + return $srcDisk->url($path); } throw new NotFoundHttpException('Croppa: Src image is missing'); @@ -148,6 +186,18 @@ public function writeCrop(string $path, string $contents): void } catch (FilesystemException $e) { // don't throw exception anymore as mentioned in PR #164 } + $this->cleanup(); + } + + /** + * Cleanup: delete tmp file if required. + */ + public function cleanup(): void + { + if ($this->tmpPath <> '') { + $this->getTmpDisk()->delete($this->tmpPath); + $this->tmpPath = ''; + } } /**