Skip to content

Commit

Permalink
Use database to build asset folder list (#311)
Browse files Browse the repository at this point in the history
* Use database to build asset folder list

* Fix bug with adding folders

* Remove debugging

* Test coverage

* 🍺
  • Loading branch information
ryanmitchell authored Jun 26, 2024
1 parent 1cd16ac commit 8172d10
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 19 deletions.
21 changes: 4 additions & 17 deletions src/Assets/AssetContainerContents.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,15 @@ public function directories()
}

$this->folders = Cache::remember($this->key(), $this->ttl(), function () {
return collect($this->directoryRecurse(''))
->map(fn ($dir) => ['path' => $dir, 'type' => 'dir']);
return $this->query()->select(['folder'])
->distinct()
->get()
->map(fn ($model) => ['path' => $model->folder, 'type' => 'dir']);
});

return $this->folders;
}

private function directoryRecurse($directory)
{
$rootFolders = $this->container->disk()->getFolders($directory, false);

$folders = [];
foreach ($rootFolders as $folder) {
$folders[] = $folder;
if ($subfolders = $this->directoryRecurse($folder)) {
$folders = array_merge($folders, $subfolders);
}
}

return $folders;
}

public function metaFilesIn($folder, $recursive)
{
return $this->query()
Expand Down
8 changes: 6 additions & 2 deletions src/Commands/SyncAssets.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ private function processFolder(AssetContainer $container, $folder = '')
$this->line("Processing folder: {$folder}");

// get raw listing of this folder, avoiding any of statamic's asset container caching
$files = collect($container->disk()->filesystem()->listContents($folder))
$contents = collect($container->disk()->filesystem()->listContents($folder));

$files = $contents
->reject(fn ($item) => $item['type'] != 'file')
->pluck('path');

Expand Down Expand Up @@ -86,7 +88,9 @@ private function processFolder(AssetContainer $container, $folder = '')
});

// process any sub-folders of this folder
$container->folders($folder)
$contents
->reject(fn ($item) => $item['type'] != 'dir')
->pluck('path')
->each(function ($subfolder) use ($container, $folder) {
if (str_contains($subfolder.'/', '.meta/')) {
return;
Expand Down
87 changes: 87 additions & 0 deletions tests/Assets/AssetContainerContentsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace Tests\Assets;

use Illuminate\Http\UploadedFile;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades\AssetContainer;
use Statamic\Testing\Concerns\PreventsSavingStacheItemsToDisk;
use Tests\TestCase;

class AssetContainerContentsTest extends TestCase
{
use PreventsSavingStacheItemsToDisk;

public function setUp(): void
{
parent::setUp();

config(['filesystems.disks.test' => [
'driver' => 'local',
'root' => __DIR__.'/tmp',
]]);
}

public function tearDown(): void
{
app('files')->deleteDirectory(__DIR__.'/tmp');

parent::tearDown();
}

#[Test]
public function it_gets_a_folder_listing()
{
$container = tap(AssetContainer::make('test')->disk('test'))->save();
$container->makeAsset('one/one.txt')->upload(UploadedFile::fake()->create('one.txt'));
$container->makeAsset('two/two.txt')->upload(UploadedFile::fake()->create('two.txt'));

$this->assertSame([
[
'path' => 'one',
'type' => 'dir',
],
[
'path' => 'two',
'type' => 'dir',
],
], $container->contents()->directories()->all());
}

#[Test]
public function it_adds_to_a_folder_listing()
{
$container = tap(AssetContainer::make('test')->disk('test'))->save();
$container->makeAsset('one/one.txt')->upload(UploadedFile::fake()->create('one.txt'));
$container->makeAsset('two/two.txt')->upload(UploadedFile::fake()->create('two.txt'));

$this->assertCount(2, $container->contents()->directories()->all());

$container->contents()->add('three');

$this->assertCount(3, $container->contents()->directories()->all());
}

#[Test]
public function it_forgets_a_folder_listing()
{
$container = tap(AssetContainer::make('test')->disk('test'))->save();
$container->makeAsset('one/one.txt')->upload(UploadedFile::fake()->create('one.txt'));
$container->makeAsset('two/two.txt')->upload(UploadedFile::fake()->create('two.txt'));

$this->assertCount(2, $container->contents()->directories()->all());

$container->contents()->forget('one');

$this->assertCount(1, $container->contents()->directories()->all());
}

#[Test]
public function it_creates_parent_folders_where_they_dont_exist()
{
$container = tap(AssetContainer::make('test')->disk('test'))->save();
$container->makeAsset('one/two/three/file.txt')->upload(UploadedFile::fake()->create('one.txt'));

$this->assertCount(3, $container->contents()->filteredDirectoriesIn('', true));
}
}

0 comments on commit 8172d10

Please sign in to comment.