diff --git a/src/Assets/Asset.php b/src/Assets/Asset.php index bc9ca65a8a..bab46f0a82 100644 --- a/src/Assets/Asset.php +++ b/src/Assets/Asset.php @@ -744,7 +744,9 @@ public function containerHandle() */ public function rename($filename, $unique = false) { - $filename = $unique ? $this->ensureUniqueFilename($this->folder(), $filename) : $filename; + if ($unique) { + return $this->moveUnique($this->folder(), $filename); + } return $this->move($this->folder(), $filename); } @@ -777,6 +779,21 @@ public function move($folder, $filename = null) return $this; } + /** + * Move the asset to a different location with a unique filename. + * + * @param string $folder The folder relative to the container. + * @param string|null $filename The new filename, if renaming. + * @return $this + */ + public function moveUnique($folder, $filename = null) + { + $filename = Uploader::getSafeFilename($filename ?: $this->filename()); + $filename = $this->ensureUniqueFilename($folder, $filename); + + return $this->move($folder, $filename); + } + public function moveQuietly($folder, $filename = null) { $this->withEvents = false; diff --git a/tests/Assets/AssetTest.php b/tests/Assets/AssetTest.php index 00046ae0f5..07504afa1a 100644 --- a/tests/Assets/AssetTest.php +++ b/tests/Assets/AssetTest.php @@ -1260,6 +1260,70 @@ public function it_doesnt_lowercase_moved_files_when_configured() ], $container->assets('/', true)->map->path()->all()); } + #[Test] + public function it_can_be_moved_uniquely_to_another_folder_when_conflict_exists() + { + Storage::fake('local'); + $disk = Storage::disk('local'); + $disk->put('old/asset.txt', 'The asset contents'); + $disk->put('new/asset.txt', 'Existing asset'); + $disk->put('new/asset-1.txt', 'Another existing asset'); + $container = Facades\AssetContainer::make('test')->disk('local'); + Facades\AssetContainer::shouldReceive('save')->with($container); + Facades\AssetContainer::shouldReceive('findByHandle')->with('test')->andReturn($container); + $asset = $container->makeAsset('old/asset.txt')->data(['foo' => 'bar']); + $asset->save(); + + $return = $asset->moveUnique('new'); + + $this->assertEquals($asset, $return); + $disk->assertMissing('old/asset.txt'); + $disk->assertExists('new/asset-2.txt'); + $this->assertEquals('new/asset-2.txt', $asset->path()); + } + + #[Test] + public function it_can_be_moved_uniquely_to_another_folder_without_renaming_when_no_conflict() + { + Storage::fake('local'); + $disk = Storage::disk('local'); + $disk->put('old/asset.txt', 'The asset contents'); + $container = Facades\AssetContainer::make('test')->disk('local'); + Facades\AssetContainer::shouldReceive('save')->with($container); + Facades\AssetContainer::shouldReceive('findByHandle')->with('test')->andReturn($container); + $asset = $container->makeAsset('old/asset.txt')->data(['foo' => 'bar']); + $asset->save(); + + $return = $asset->moveUnique('new'); + + $this->assertEquals($asset, $return); + $disk->assertMissing('old/asset.txt'); + $disk->assertExists('new/asset.txt'); + $this->assertEquals('new/asset.txt', $asset->path()); + } + + #[Test] + public function it_does_not_ensure_unique_filename_when_moving_by_default() + { + Storage::fake('local'); + $disk = Storage::disk('local'); + $disk->put('old/asset.txt', 'The asset contents'); + $disk->put('new/asset.txt', 'Existing asset'); + $container = Facades\AssetContainer::make('test')->disk('local'); + Facades\AssetContainer::shouldReceive('save')->with($container); + Facades\AssetContainer::shouldReceive('findByHandle')->with('test')->andReturn($container); + $asset = $container->makeAsset('old/asset.txt')->data(['foo' => 'bar']); + $asset->save(); + + $return = $asset->move('new'); + + $this->assertEquals($asset, $return); + $disk->assertMissing('old/asset.txt'); + // Without unique flag, it overwrites the existing file + $disk->assertExists('new/asset.txt'); + $this->assertEquals('new/asset.txt', $asset->path()); + } + #[Test] public function it_renames() {