From edc4c21b9bfda657f640913099b0eca087e6147f Mon Sep 17 00:00:00 2001 From: Kamil Iskra Date: Tue, 16 Feb 2021 04:43:45 -0600 Subject: [PATCH] Use file checksum as file name prefix (#907) * Alternative implementation using file checksums * truncate checksum to 32 char for file names: thus no need for migration Co-authored-by: ildyria --- app/Actions/Photo/Create.php | 4 ++-- app/Actions/Photo/Rotate.php | 36 +++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/Actions/Photo/Create.php b/app/Actions/Photo/Create.php index 5aeee55ad11..2d848c90bc2 100644 --- a/app/Actions/Photo/Create.php +++ b/app/Actions/Photo/Create.php @@ -83,15 +83,15 @@ public function add( // Set paths $this->tmp_name = $file['tmp_name']; $this->is_uploaded = is_uploaded_file($file['tmp_name']); - $this->photo_Url = md5(microtime()) . $this->extension; $this->path_prefix = ($this->kind != 'raw') ? 'big/' : 'raw/'; - $this->path = Storage::path($this->path_prefix . $this->photo_Url); // Calculate checksum $this->photo->checksum = $this->checksum($this->tmp_name); $duplicate = $this->get_duplicate($this->photo->checksum); $exists = ($duplicate !== null); + $this->photo_Url = substr($this->photo->checksum, 0, 32) . $this->extension; + $this->path = Storage::path($this->path_prefix . $this->photo_Url); /* * ! From here we need to use a Strategy depending if we have * ! a duplicate diff --git a/app/Actions/Photo/Rotate.php b/app/Actions/Photo/Rotate.php index ab9897584c0..6ca2f0040b7 100644 --- a/app/Actions/Photo/Rotate.php +++ b/app/Actions/Photo/Rotate.php @@ -2,6 +2,7 @@ namespace App\Actions\Photo; +use App\Actions\Photo\Extensions\Checksum; use App\Actions\Photo\Extensions\Constants; use App\Actions\Photo\Extensions\ImageEditing; use App\Assets\Helpers; @@ -13,6 +14,7 @@ class Rotate { + use Checksum; use Constants; use ImageEditing; @@ -59,21 +61,40 @@ public function do(Photo $photo, int $direction) return false; } - // We will use new names to avoid problems with image caching. - $new_prefix = md5(microtime()); - $url = $photo->url; - $new_url = $new_prefix . Helpers::getExtension($url); + // Generate a temporary name for the rotated file. $big_folder = Storage::path('big/'); + $url = $photo->url; $path = $big_folder . $url; - $new_path = $big_folder . $new_url; + $extension = Helpers::getExtension($url); + if ( + !($new_tmp = tempnam($big_folder, 'lychee')) || + !@rename($new_tmp, $new_tmp . $extension) + ) { + Logs::notice(__METHOD__, __LINE__, 'Could not create a temporary file.'); + + return false; + } + $new_tmp .= $extension; // Rotate the original image. - if ($this->imageHandler->rotate($path, ($direction == 1) ? 90 : -90, $new_path) === false) { + if ($this->imageHandler->rotate($path, ($direction == 1) ? 90 : -90, $new_tmp) === false) { Logs::error(__METHOD__, __LINE__, 'Failed to rotate ' . $path); return false; } + // We will use new names to avoid problems with image caching. + $new_prefix = substr($this->checksum($new_tmp), 0, 32); + $new_url = $new_prefix . $extension; + $new_path = $big_folder . $new_url; + + // Rename the temporary file, now that we know its final name. + if (!@rename($new_tmp, $new_path)) { + Logs::error(__METHOD__, __LINE__, 'Failed to rename ' . $new_tmp); + + return false; + } + $photo->url = $new_url; $old_width = $photo->width; $photo->width = $photo->height; @@ -140,7 +161,8 @@ public function do(Photo $photo, int $direction) 'small2x' => $photo->small2x, 'medium' => $photo->medium, 'medium2x' => $photo->medium2x, - ]); + ] + ); return true; }