diff --git a/classes/Image.php b/classes/Image.php index 907ac8e..eb6448a 100644 --- a/classes/Image.php +++ b/classes/Image.php @@ -7,6 +7,8 @@ class Image { + use RemoteImageTrait; + /** * Original path of image */ @@ -53,6 +55,11 @@ public function __construct($filePath = false) return; } + // If file path is a remote image, download and use as local file + if ($this->isRemoteFile($filePath)) { + $filePath = $this->getRemoteFile($filePath); + } + $this->file->file_name = $filePath; $this->filePath = (file_exists($filePath)) diff --git a/classes/RemoteImageTrait.php b/classes/RemoteImageTrait.php new file mode 100644 index 0000000..a8b0ee4 --- /dev/null +++ b/classes/RemoteImageTrait.php @@ -0,0 +1,126 @@ +generateStoragePath($filePath); + $tempFullPath = storage_path('app/' . $tempImage); + + // Check if remote image was already downloaded + if (Storage::exists($tempImage)) { + return $tempFullPath; + } + + // If URL doesn't have extension, check if exists a file with one of the allowed extensions + $imageExists = $this->checkLocalRemoteImage($tempImage); + + // If found, use already downloaded image + if ($imageExists) { + return storage_path('app/' . $imageExists); + } + + // Download image from remote location + Http::get($filePath, function ($http) use ($tempFullPath) { + $http->toFile($tempFullPath); + }); + + // If URL doesn't have extension, discover extension and rename local image + if (!FileHelper::extension($tempFullPath)) { + $extension = $this->discoverImageExtension($tempFullPath); + $newFullPath = sprintf('%s%s', $tempFullPath, $extension); + rename($tempFullPath, $newFullPath); + $tempFullPath = $newFullPath; + } + + return $tempFullPath; + } + + /** + * Generate storage path to store cached remote images + * + * @param string $filePath + * @return string + */ + protected function generateStoragePath($filePath) + { + $extension = $this->getRemoteFileExtension($filePath); + $tempPath = $this->file->getStorageDirectory() . $this->getPartitionDirectory(); + $tempFilename = md5($filePath); + + Storage::makeDirectory($tempPath); + + $fileMask = $extension ? '%s%s.%s' : '%s%s'; + + return sprintf($fileMask, $tempPath, $tempFilename, $extension); + } + + /** + * Get file extension from remote image URL + * + * @param string $filePath + * @return string + */ + protected function getRemoteFileExtension($filePath) + { + // Remove query string from url + if (parse_url($filePath, PHP_URL_QUERY)) { + $filePath = strtok($filePath, '?'); + } + + return FileHelper::extension($filePath); + } + + /** + * If remote image doesn't expose file extension, discover by looking downloaded file + * + * @param string $filePath + * @return string + */ + protected function discoverImageExtension($filePath) + { + $imageType = exif_imagetype($filePath); + $extension = image_type_to_extension($imageType); + return $extension; + } + + /** + * If URL doesn't have extension, check if exists a file with one of the allowed extensions + * + * @param $string $filePath + * @return Collection + */ + protected function checkLocalRemoteImage($filePath) + { + $allowedExtensions = File::$imageExtensions; + + return collect($allowedExtensions)->map(function ($imageType) use ($filePath) { + $findImage = sprintf('%s.%s', $filePath, $imageType); + return Storage::exists($findImage) ? $findImage : false; + })->filter()->first(); + } +}