Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 5 additions & 22 deletions src/Assets/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -754,23 +754,21 @@ public function containerHandle()
*/
public function rename($filename, $unique = false)
{
if ($unique) {
return $this->moveUnique($this->folder(), $filename);
}

return $this->move($this->folder(), $filename);
return $this->move($this->folder(), $filename, $unique);
}

/**
* Move the asset to a different location.
*
* @param string $folder The folder relative to the container.
* @param string|null $filename The new filename, if renaming.
* @param bool $unique Whether to ensure the filename is unique.
* @return $this
*/
public function move($folder, $filename = null)
public function move($folder, $filename = null, $unique = false)
{
$filename = Uploader::getSafeFilename($filename ?: $this->filename());
$filename = $unique ? $this->ensureUniqueFilename($folder, $filename) : $filename;
$oldPath = $this->path();
$oldMetaPath = $this->metaPath();
$newPath = Str::removeLeft(Path::tidy($folder.'/'.$filename.'.'.pathinfo($oldPath, PATHINFO_EXTENSION)), '/');
Expand All @@ -789,22 +787,7 @@ 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)
public function moveQuietly($folder, $filename = null, $unique = false)
{
$this->withEvents = false;

Expand Down
9 changes: 8 additions & 1 deletion src/Imaging/ImageGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Statamic\Imaging;

use Facades\Statamic\Imaging\ImageValidator;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use League\Flysystem\UnableToReadFile;
Expand Down Expand Up @@ -150,11 +151,17 @@ public function generateVideoThumbnail($asset, array $params)
/**
* Generate a manipulated image by an asset.
*
* @param \Statamic\Contracts\Assets\Asset $asset
* @param \Statamic\Contracts\Assets\Asset|null $asset
* @return mixed
*/
public function generateByAsset($asset, array $params)
{
if (! $asset) {

This comment was marked as outdated.

This comment was marked as outdated.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Log::error('Cannot generate an image for a missing asset.') carries no identifying context (no item, path, or asset ID). The original issue's complaint was that a bad asset silently 500'd for a day before anyone noticed; this line does add a log, but by the time generateByAsset() sees $asset === null, the identifying info from the caller ($item in Glide::generateGlideUrl/generateImage) is already gone. Every other failure path in Glide::generate() logs $e->getMessage(), which carries exception context — this one is a flat string that will look identical for every occurrence, so it's still not possible to tell which asset/URL is failing without reproducing it.\n\nWorth either passing/logging the original $item reference here, or (per the earlier thread on this line) throwing from Glide::generateImage() so the existing catch (\\Exception $e) logs a message that includes the offending item.

This comment was marked as outdated.

Log::error('Cannot generate an image for a missing asset.');

return '';
}

if ($asset->isVideo() && ThumbnailExtractor::available()) {
return $this->generateVideoThumbnail($asset, $params);
}
Expand Down
8 changes: 4 additions & 4 deletions tests/Assets/AssetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1321,7 +1321,7 @@ public function it_doesnt_lowercase_moved_files_when_configured()
}

#[Test]
public function it_can_be_moved_uniquely_to_another_folder_when_conflict_exists()
public function it_can_be_moved_to_another_folder_with_a_unique_filename_when_conflict_exists()
{
Storage::fake('local');
$disk = Storage::disk('local');
Expand All @@ -1334,7 +1334,7 @@ public function it_can_be_moved_uniquely_to_another_folder_when_conflict_exists(
$asset = $container->makeAsset('old/asset.txt')->data(['foo' => 'bar']);
$asset->save();

$return = $asset->moveUnique('new');
$return = $asset->move('new', null, true);

$this->assertEquals($asset, $return);
$disk->assertMissing('old/asset.txt');
Expand All @@ -1343,7 +1343,7 @@ public function it_can_be_moved_uniquely_to_another_folder_when_conflict_exists(
}

#[Test]
public function it_can_be_moved_uniquely_to_another_folder_without_renaming_when_no_conflict()
public function it_can_be_moved_to_another_folder_with_a_unique_filename_without_renaming_when_no_conflict()
{
Storage::fake('local');
$disk = Storage::disk('local');
Expand All @@ -1354,7 +1354,7 @@ public function it_can_be_moved_uniquely_to_another_folder_without_renaming_when
$asset = $container->makeAsset('old/asset.txt')->data(['foo' => 'bar']);
$asset->save();

$return = $asset->moveUnique('new');
$return = $asset->move('new', null, true);

$this->assertEquals($asset, $return);
$disk->assertMissing('old/asset.txt');
Expand Down
6 changes: 6 additions & 0 deletions tests/Imaging/ImageGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ public function it_generates_an_image_by_asset()
Event::assertDispatchedTimes(GlideImageGenerated::class, 1);
}

#[Test]
public function it_does_not_generate_an_image_for_a_missing_asset()
{
$this->assertSame('', $this->makeGenerator()->generateByAsset(null, ['w' => 100]));
}

#[Test]
public function it_does_not_check_ffmpeg_availability_for_non_video_assets()
{
Expand Down
20 changes: 20 additions & 0 deletions tests/Tags/GlideTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Tests\Tags;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Log;
use Orchestra\Testbench\Attributes\DefineEnvironment;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades\File;
Expand All @@ -11,6 +12,25 @@

class GlideTest extends TestCase
{
#[Test]
/**
* https://github.com/statamic/cms/pull/15447
*/
public function it_logs_the_item_when_the_asset_cannot_be_resolved()
{
Log::shouldReceive('error')
->once()
->with(\Mockery::pattern('/Could not generate a manipulated image from asset.*nonexistent\.jpg/'));

$result = (string) Parse::template(
'{{ glide:foo width="100" }}',
['foo' => 'nonexistent.jpg'],
trusted: true
);

$this->assertSame('', $result);
}

#[Test]
#[DefineEnvironment('relativeRouteUrl')]
public function it_outputs_a_relative_url_by_default_when_the_glide_route_is_relative()
Expand Down
Loading