Skip to content
Merged
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
40 changes: 26 additions & 14 deletions src/Fieldtypes/Assets/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,27 +238,39 @@ public function preload()

return [
'data' => $this->getItemData($this->field->value() ?? $this->defaultValue),
'container' => [
'id' => $container->id(),
'title' => $container->title(),
'edit_url' => $container->editUrl(),
'delete_url' => $container->deleteUrl(),
'blueprint_url' => cp_route('blueprints.asset-containers.edit', $container->handle()),
'can_view' => User::current()->can('view', $container),
'can_upload' => User::current()->can('store', [\Statamic\Contracts\Assets\Asset::class, $container]),
'can_edit' => User::current()->can('edit', $container),
'can_delete' => User::current()->can('delete', $container),
'can_create_folders' => User::current()->can('create', [\Statamic\Contracts\Assets\AssetFolder::class, $container]),
'sort_field' => $container->sortField(),
'sort_direction' => $container->sortDirection(),
],
'container' => $this->containerForPreload($container),
'dynamicFolder' => $dynamicFolder = $this->dynamicFolder(),
'rename_folder' => $this->renameFolderAction($dynamicFolder),
'columns' => $this->getColumns(),
];
}

private function containerForPreload($container)
{
// It's the same for every assets field that uses the container, and a page can have a lot of them.
return Blink::once('assets-fieldtype-container-'.$container->handle().'-'.User::current()?->id(), fn () => [
'id' => $container->id(),
'title' => $container->title(),
'edit_url' => $container->editUrl(),
'delete_url' => $container->deleteUrl(),
'blueprint_url' => cp_route('blueprints.asset-containers.edit', $container->handle()),
'can_view' => User::current()->can('view', $container),
'can_upload' => User::current()->can('store', [\Statamic\Contracts\Assets\Asset::class, $container]),
'can_edit' => User::current()->can('edit', $container),
'can_delete' => User::current()->can('delete', $container),
'can_create_folders' => User::current()->can('create', [\Statamic\Contracts\Assets\AssetFolder::class, $container]),
'sort_field' => $container->sortField(),
'sort_direction' => $container->sortDirection(),
]);
}

protected function getColumns()
{
return Blink::once('assets-fieldtype-columns-'.$this->container()->handle().'-'.User::current()?->id(), fn () => $this->makeColumns())
->map(fn ($column) => clone $column);
}

private function makeColumns()
{
$columns = $this->container()->blueprint()->columns()->map(fn ($column) => clone $column);

Expand Down
49 changes: 49 additions & 0 deletions tests/Fieldtypes/AssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
class AssetsTest extends TestCase
{
use PreventSavingStacheItemsToDisk;
use \Tests\FakesRoles;
use TestsQueryableValueWithMaxItems;

public function setUp(): void
Expand Down Expand Up @@ -257,6 +258,54 @@ public function it_doesnt_replace_non_image_related_rule()
$this->assertEquals('file', $replaced[0]);
}

#[Test]
public function what_it_preloads_about_a_container_is_worked_out_once_however_many_fields_use_it()
{
$this->setTestRoles(['test' => ['access cp', 'view test assets']]);
$this->actingAs(tap(\Statamic\Facades\User::make()->assignRole('test'))->save());

$checks = 0;
\Illuminate\Support\Facades\Gate::after(function () use (&$checks) {
$checks++;
});

$first = $this->fieldtype(['container' => 'test'])->preload();
$checksForOne = $checks;
$second = $this->fieldtype(['container' => 'test'])->preload();

$this->assertGreaterThan(0, $checksForOne);
$this->assertSame($checksForOne, $checks);
$this->assertSame($first['container'], $second['container']);
$this->assertTrue($first['container']['can_view']);
$this->assertFalse($first['container']['can_delete']);
$this->assertEquals($first['columns']->map->toArray()->all(), $second['columns']->map->toArray()->all());
}

#[Test]
public function each_field_gets_columns_of_its_own()
{
$this->actingAs(tap(\Statamic\Facades\User::make()->makeSuper())->save());

$first = $this->fieldtype(['container' => 'test'])->preload()['columns'];
$first->first()->label('Changed');
$second = $this->fieldtype(['container' => 'test'])->preload()['columns'];

$this->assertNotSame($first->first(), $second->first());
$this->assertSame('Alt Text', $second->first()->label());
}

#[Test]
public function what_it_preloads_about_a_container_is_each_users_own()
{
$this->setTestRoles(['test' => ['access cp', 'view test assets']]);

$this->actingAs(tap(\Statamic\Facades\User::make()->id('one')->assignRole('test'))->save());
$this->assertFalse($this->fieldtype(['container' => 'test'])->preload()['container']['can_edit']);

$this->actingAs(tap(\Statamic\Facades\User::make()->id('two')->makeSuper())->save());
$this->assertTrue($this->fieldtype(['container' => 'test'])->preload()['container']['can_edit']);
}

public function fieldtype($config = [])
{
return (new Assets)->setField(new Field('test', array_merge([
Expand Down
Loading