Skip to content
Open
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
9 changes: 7 additions & 2 deletions src/Assets/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ public function url()
return null;
}

return URL::assemble($this->container()->url(), $this->path());
return URL::assemble($this->container()->url(), $this->encodedPath());
}

public function absoluteUrl()
Expand All @@ -426,7 +426,12 @@ public function absoluteUrl()
return null;
}

return URL::assemble($this->container()->absoluteUrl(), $this->path());
return URL::assemble($this->container()->absoluteUrl(), $this->encodedPath());
}

private function encodedPath()
{
return implode('/', array_map('rawurlencode', explode('/', $this->path())));
}

public function thumbnailUrl($preset = null)
Expand Down
2 changes: 1 addition & 1 deletion src/Assets/AssetRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function findByUrl(string $url)
$url = $siteUrl.$url;
}

$path = Str::after($url, $containerUrl);
$path = rawurldecode(Str::after($url, $containerUrl));

return $container->asset($path);
}
Expand Down
27 changes: 27 additions & 0 deletions tests/Assets/AssetRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Storage;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Assets\AssetRepository;
use Statamic\Contracts\Assets\Asset as AssetContract;
Expand Down Expand Up @@ -106,6 +107,32 @@ public function it_finds_assets_using_find_or_fail()
$this->assertEquals($assetShortUrl->id(), $asset->id());
}

#[Test]
#[DataProvider('encodedUrlProvider')]
public function it_finds_assets_by_an_encoded_url($path, $expectedUrl)
{
Storage::fake('test', ['url' => 'test']);
Storage::disk('test')->put($path, UploadedFile::fake()->image('bar.jpg')->getContent());

$container = tap(AssetContainer::make('test_container')->disk('test'))->save();
$asset = tap($container->makeAsset($path))->save();

$this->assertEquals($expectedUrl, $asset->url());

$found = Asset::findByUrl($asset->url());

$this->assertInstanceOf(AssetContract::class, $found);
$this->assertEquals($asset->id(), $found->id());
}

public static function encodedUrlProvider()
{
return [
'spaces and accents' => ['foo/Dún Laoghaire_18 2.jpg', '/test/foo/D%C3%BAn%20Laoghaire_18%202.jpg'],
'literal percent sequences' => ['foo/photo%20one.jpg', '/test/foo/photo%2520one.jpg'],
];
}

#[Test]
public function it_finds_assets_by_id_when_the_path_contains_windows_separators()
{
Expand Down
26 changes: 26 additions & 0 deletions tests/Assets/AssetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2375,6 +2375,32 @@ public function it_gets_the_absolute_url()
$this->assertEquals('http://example.com/path/to/test.txt', $asset->absoluteUrl());
}

#[Test]
#[DataProvider('urlEncodingProvider')]
public function it_encodes_the_url($path, $expected)
{
$container = $this->mock(AssetContainer::class);
$container->shouldReceive('private')->andReturnFalse();
$container->shouldReceive('url')->andReturn('http://example.com/container');
$container->shouldReceive('absoluteUrl')->andReturn('http://example.com/container');
$asset = (new Asset)->container($container)->path($path);

$this->assertEquals('http://example.com/container'.$expected, $asset->url());
$this->assertEquals('http://example.com/container'.$expected, $asset->absoluteUrl());
$this->assertEquals('http://example.com/container'.$expected, (string) $asset);
}

public static function urlEncodingProvider()
{
return [
'nothing to encode' => ['path/to/test.txt', '/path/to/test.txt'],
'spaces' => ['path/to/Image X - Whatever_17.jpg', '/path/to/Image%20X%20-%20Whatever_17.jpg'],
'accents' => ['path/to/Dún Laoghaire_18 2.jpg', '/path/to/D%C3%BAn%20Laoghaire_18%202.jpg'],
'spaces in folders' => ['path to/my folder/test.txt', '/path%20to/my%20folder/test.txt'],
'literal percent sequences' => ['path/to/photo%20one.jpg', '/path/to/photo%2520one.jpg'],
];
}

#[Test]
public function there_is_no_url_for_a_private_asset()
{
Expand Down
Loading