Skip to content

Commit 8b23d00

Browse files
committed
Merge branch '5.x' into 6.x
# Conflicts: # CHANGELOG.md # resources/js/components/entries/PublishForm.vue # resources/js/components/terms/PublishForm.vue # routes/cp.php # src/Http/Controllers/CP/Assets/FoldersController.php
2 parents 5bc4666 + 41cc8b2 commit 8b23d00

11 files changed

Lines changed: 287 additions & 19 deletions

File tree

resources/js/components/entries/PublishForm.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ export default {
507507
},
508508
509509
afterSaveOption() {
510-
return this.getPreference('after_save');
510+
return this.getPreference('after_save') ?? 'listing';
511511
},
512512
513513
originOptions() {
@@ -591,8 +591,8 @@ export default {
591591
this.redirectTo(this.createAnotherUrl);
592592
}
593593
594-
// If the user has opted to go to listing (default/null option), redirect them there.
595-
else if (!this.isInline && nextAction === null) {
594+
// If the user has opted to go to listing, redirect them there.
595+
else if (!this.isInline && nextAction === 'listing') {
596596
this.redirectTo(this.listingUrl);
597597
}
598598
@@ -760,8 +760,8 @@ export default {
760760
this.redirectTo(this.createAnotherUrl);
761761
}
762762
763-
// If the user has opted to go to listing (default/null option), redirect them there.
764-
else if (!this.isInline && nextAction === null) {
763+
// If the user has opted to go to listing, redirect them there.
764+
else if (!this.isInline && nextAction === 'listing') {
765765
this.redirectTo(this.listingUrl);
766766
}
767767

resources/js/components/publish/SaveButtonOptions.vue

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ export default {
6565
setPreference(value) {
6666
if (value === this.$preferences.get(this.preferencesKey)) return;
6767
68-
value === 'listing'
69-
? this.$preferences.remove(this.preferencesKey)
70-
: this.$preferences.set(this.preferencesKey, value);
68+
this.$preferences.set(this.preferencesKey, value);
7169
},
7270
},
7371
};

resources/js/components/terms/PublishForm.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ export default {
301301
},
302302
303303
afterSaveOption() {
304-
return this.getPreference('after_save');
304+
return this.getPreference('after_save') ?? 'listing';
305305
},
306306
307307
direction() {
@@ -368,8 +368,8 @@ export default {
368368
this.redirectTo(this.createAnotherUrl);
369369
}
370370
371-
// If the user has opted to go to listing (default/null option), redirect them there.
372-
else if (!this.isInline && nextAction === null) {
371+
// If the user has opted to go to listing, redirect them there.
372+
else if (!this.isInline && nextAction === 'listing') {
373373
this.redirectTo(this.listingUrl);
374374
}
375375

routes/cp.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@
251251

252252
Route::resource('asset-containers', AssetContainersController::class)->except('index');
253253
Route::post('asset-containers/{asset_container}/folders', [FoldersController::class, 'store']);
254-
Route::patch('asset-containers/{asset_container}/folders/{path}', [FoldersController::class, 'update'])->where('path', '.*');
255254
Route::post('assets/actions', [AssetActionController::class, 'run'])->name('assets.actions.run');
256255
Route::post('assets/actions/list', [AssetActionController::class, 'bulkActions'])->name('assets.actions.bulk');
257256
Route::get('assets/browse', [BrowserController::class, 'index'])->name('assets.browse.index');

src/Entries/Entry.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ public function save()
445445

446446
$this->taxonomize();
447447

448-
if ($this->isDirty('slug')) {
448+
if ($this->shouldUpdateUris()) {
449449
optional(Collection::findByMount($this))->updateEntryUris();
450450
$this->updateChildPageUris();
451451
}
@@ -477,6 +477,21 @@ public function save()
477477
return true;
478478
}
479479

480+
private function shouldUpdateUris(): bool
481+
{
482+
if (! $this->route()) {
483+
return false;
484+
}
485+
486+
$antlersRoute = preg_replace_callback('/{\s*([a-zA-Z0-9_\-]+)\s*}/', function ($match) {
487+
return "{{ {$match[1]} }}";
488+
}, $this->route());
489+
490+
return collect(Antlers::identifiers($antlersRoute))
491+
->filter(fn (string $identifier) => $this->isDirty($identifier))
492+
->isNotEmpty();
493+
}
494+
480495
private function updateChildPageUris()
481496
{
482497
$collection = $this->collection();

src/Http/Controllers/CP/Assets/PdfController.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ class PdfController extends Controller
1515
*/
1616
public function show($encodedAssetId)
1717
{
18-
if (! $contents = $this->asset($encodedAssetId)->contents()) {
19-
abort(500);
20-
}
18+
$asset = $this->asset($encodedAssetId);
19+
20+
abort_if(! $contents = $asset->contents(), 500);
21+
22+
$this->authorize('view', $asset);
2123

2224
return response($contents)->header('Content-Type', 'application/pdf');
2325
}

src/Http/Controllers/CP/Assets/SvgController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public function show($asset)
1717
{
1818
$asset = $this->asset($asset);
1919

20-
if (! $contents = $asset->disk()->get($asset->path())) {
21-
abort(500);
22-
}
20+
abort_if(! $contents = $asset->disk()->get($asset->path()), 500);
21+
22+
$this->authorize('view', $asset);
2323

2424
return response($contents)->header('Content-Type', 'image/svg+xml');
2525
}

src/Http/Controllers/CP/Assets/ThumbnailController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public function show($asset, $size = null, $orientation = null)
6565
$this->orientation = $orientation;
6666
$this->asset = $this->asset($asset);
6767

68+
$this->authorize('view', $this->asset);
69+
6870
if ($placeholder = $this->getPlaceholderResponse()) {
6971
return $placeholder;
7072
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace Feature\Assets;
4+
5+
use Illuminate\Http\UploadedFile;
6+
use PHPUnit\Framework\Attributes\Test;
7+
use Statamic\Facades\AssetContainer;
8+
use Statamic\Facades\User;
9+
use Tests\FakesRoles;
10+
use Tests\PreventSavingStacheItemsToDisk;
11+
use Tests\TestCase;
12+
13+
class ImageThumbnailTest extends TestCase
14+
{
15+
use FakesRoles;
16+
use PreventSavingStacheItemsToDisk;
17+
18+
private $tempDir;
19+
20+
public function setUp(): void
21+
{
22+
parent::setUp();
23+
24+
config(['filesystems.disks.test' => [
25+
'driver' => 'local',
26+
'root' => $this->tempDir = __DIR__.'/tmp',
27+
]]);
28+
}
29+
30+
public function tearDown(): void
31+
{
32+
app('files')->deleteDirectory($this->tempDir);
33+
34+
parent::tearDown();
35+
}
36+
37+
#[Test]
38+
public function it_returns_thumbnail()
39+
{
40+
$container = AssetContainer::make('test')->disk('test')->save();
41+
$container
42+
->makeAsset('one.png')
43+
->upload(UploadedFile::fake()->image('one.png'));
44+
45+
$this->setTestRoles(['test' => ['access cp', 'view test assets']]);
46+
$user = User::make()->assignRole('test')->save();
47+
48+
$this
49+
->actingAs($user)
50+
->getJson('/cp/thumbnails/'.base64_encode('test::one.png'))
51+
->assertSuccessful();
52+
}
53+
54+
#[Test]
55+
public function it_404s_when_the_asset_doesnt_exist()
56+
{
57+
$container = AssetContainer::make('test')->disk('test')->save();
58+
59+
$this->setTestRoles(['test' => ['access cp', 'view test assets']]);
60+
$user = User::make()->assignRole('test')->save();
61+
62+
$this
63+
->actingAs($user)
64+
->getJson('/cp/thumbnails/'.base64_encode('test::unknown.png'))
65+
->assertNotFound();
66+
}
67+
68+
#[Test]
69+
public function it_denies_access_without_permission_to_view_asset()
70+
{
71+
$container = AssetContainer::make('test')->disk('test')->save();
72+
$container
73+
->makeAsset('one.png')
74+
->upload(UploadedFile::fake()->image('one.png'));
75+
76+
$this->setTestRoles(['test' => ['access cp']]);
77+
$user = User::make()->assignRole('test')->save();
78+
79+
$this
80+
->actingAs($user)
81+
->getJson('/cp/thumbnails/'.base64_encode('test::one.png'))
82+
->assertForbidden();
83+
}
84+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace Feature\Assets;
4+
5+
use Illuminate\Http\UploadedFile;
6+
use PHPUnit\Framework\Attributes\Test;
7+
use Statamic\Facades\AssetContainer;
8+
use Statamic\Facades\User;
9+
use Tests\FakesRoles;
10+
use Tests\PreventSavingStacheItemsToDisk;
11+
use Tests\TestCase;
12+
13+
class PdfThumbnailTest extends TestCase
14+
{
15+
use FakesRoles;
16+
use PreventSavingStacheItemsToDisk;
17+
18+
private $tempDir;
19+
20+
public function setUp(): void
21+
{
22+
parent::setUp();
23+
24+
config(['filesystems.disks.test' => [
25+
'driver' => 'local',
26+
'root' => $this->tempDir = __DIR__.'/tmp',
27+
]]);
28+
}
29+
30+
public function tearDown(): void
31+
{
32+
app('files')->deleteDirectory($this->tempDir);
33+
34+
parent::tearDown();
35+
}
36+
37+
#[Test]
38+
public function it_returns_thumbnail()
39+
{
40+
$container = AssetContainer::make('test')->disk('test')->save();
41+
$container
42+
->makeAsset('one.pdf')
43+
->upload(UploadedFile::fake()->createWithContent('one.pdf', ' '));
44+
45+
$this->setTestRoles(['test' => ['access cp', 'view test assets']]);
46+
$user = User::make()->assignRole('test')->save();
47+
48+
$this
49+
->actingAs($user)
50+
->getJson('/cp/pdfs/'.base64_encode('test::one.pdf'))
51+
->assertSuccessful();
52+
}
53+
54+
#[Test]
55+
public function it_404s_when_the_asset_doesnt_exist()
56+
{
57+
$container = AssetContainer::make('test')->disk('test')->save();
58+
59+
$this->setTestRoles(['test' => ['access cp', 'view test assets']]);
60+
$user = User::make()->assignRole('test')->save();
61+
62+
$this
63+
->actingAs($user)
64+
->getJson('/cp/pdfs/'.base64_encode('test::unknown.pdf'))
65+
->assertNotFound();
66+
}
67+
68+
#[Test]
69+
public function it_denies_access_without_permission_to_view_asset()
70+
{
71+
$container = AssetContainer::make('test')->disk('test')->save();
72+
$container
73+
->makeAsset('one.pdf')
74+
->upload(UploadedFile::fake()->createWithContent('one.pdf', ' '));
75+
76+
$this->setTestRoles(['test' => ['access cp']]);
77+
$user = User::make()->assignRole('test')->save();
78+
79+
$this
80+
->actingAs($user)
81+
->getJson('/cp/pdfs/'.base64_encode('test::one.pdf'))
82+
->assertForbidden();
83+
}
84+
}

0 commit comments

Comments
 (0)