Skip to content

Commit

Permalink
Add missing directories (statamic#7205)
Browse files Browse the repository at this point in the history
Co-authored-by: StyleCI Bot <[email protected]>
  • Loading branch information
jasonvarga and StyleCIBot authored Jan 26, 2023
1 parent d8e5bf6 commit 339aa89
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 9 deletions.
32 changes: 28 additions & 4 deletions src/Assets/AssetContainerContents.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,39 @@ public function all()
// and will let us perform more efficient filtering and caching.
$files = $this->filesystem()->listContents('/', true);

// If Flysystem 3.x, re-apply sorting and return a backwards compatible result set.
// See: https://flysystem.thephpleague.com/v2/docs/usage/directory-listings/
if (! is_array($files)) {
return collect($files->sortByPath()->toArray())->keyBy('path')->map(function ($file) {
// Flysystem v3 is a DirectoryListing class, not an array.
$files = collect($files->toArray())->keyBy('path')->map(function ($file) {
return $this->normalizeFlysystemAttributes($file);
});
} else {
// Flysystem 1.x is an array.
$files = collect($files)->keyBy('path');
}

return collect($files)->keyBy('path');
$files
->filter(fn ($item) => $item['type'] === 'file')
->each(function ($file) use ($files) {
$dirname = $file['dirname'];

while ($dirname !== '') {
$parentDir = pathinfo($dirname, PATHINFO_DIRNAME);
$parentDir = $parentDir === '.' ? '' : $parentDir;

$files->put($dirname, [
'type' => 'dir',
'path' => $dirname,
'basename' => $basename = pathinfo($dirname, PATHINFO_BASENAME),
'filename' => $basename,
'timestamp' => null,
'dirname' => $parentDir,
]);

$dirname = $parentDir;
}
});

return $files->sortKeys();
});
}

Expand Down
38 changes: 33 additions & 5 deletions tests/Assets/AssetContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,11 @@ public function it_gets_the_files_from_the_filesystem_only_once()
->with('/', true)
->once()
->andReturn([
'.meta/one.jpg.yaml' => ['type' => 'file', 'path' => '.meta/one.jpg.yaml', 'basename' => 'one.jpg.yaml'],
'.DS_Store' => ['type' => 'file', 'path' => '.DS_Store', 'basename' => '.DS_Store'],
'.gitignore' => ['type' => 'file', 'path' => '.gitignore', 'basename' => '.gitignore'],
'one.jpg' => ['type' => 'file', 'path' => 'one.jpg', 'basename' => 'one.jpg'],
'two.jpg' => ['type' => 'file', 'path' => 'two.jpg', 'basename' => 'two.jpg'],
'.meta/one.jpg.yaml' => ['type' => 'file', 'path' => '.meta/one.jpg.yaml', 'basename' => 'one.jpg.yaml', 'dirname' => '.meta'],
'.DS_Store' => ['type' => 'file', 'path' => '.DS_Store', 'basename' => '.DS_Store', 'dirname' => ''],
'.gitignore' => ['type' => 'file', 'path' => '.gitignore', 'basename' => '.gitignore', 'dirname' => ''],
'one.jpg' => ['type' => 'file', 'path' => 'one.jpg', 'basename' => 'one.jpg', 'dirname' => ''],
'two.jpg' => ['type' => 'file', 'path' => 'two.jpg', 'basename' => 'two.jpg', 'dirname' => ''],
]);

File::shouldReceive('disk')->with('test')->andReturn($disk);
Expand Down Expand Up @@ -563,6 +563,34 @@ public function it_gets_the_folders_from_the_filesystem_only_once()
$this->assertTrue(Cache::has($cacheKey));
}

/** @test */
public function it_gets_the_folders_even_if_some_folders_are_missing()
{
// For example, S3 may not not return a directory as part of the listing in
// some situations, even though there may be a file in those directories.

$disk = $this->mock(Filesystem::class);
$disk->shouldReceive('filesystem->getDriver->listContents')
->with('/', true)
->once()
->andReturn([
'alfa' => ['type' => 'dir', 'path' => 'alfa', 'basename' => 'alfa'],
'bravo' => ['type' => 'dir', 'path' => 'bravo', 'basename' => 'bravo'],
'charlie/delta/echo/foxtrot.jpg' => ['type' => 'file', 'path' => 'charlie/delta/echo/foxtrot.jpg', 'basename' => 'foxtrot', 'dirname' => 'charlie/delta/echo'],
'golf.jpg' => ['type' => 'file', 'path' => 'golf.jpg', 'basename' => 'golf', 'dirname' => ''],
]);

File::shouldReceive('disk')->with('test')->andReturn($disk);

$this->assertFalse(Cache::has($cacheKey = 'asset-list-contents-test'));
$this->assertFalse(Blink::has($cacheKey));

$container = (new AssetContainer)->handle('test')->disk('test');

$expected = ['alfa', 'bravo', 'charlie', 'charlie/delta', 'charlie/delta/echo'];
$this->assertEquals($expected, $container->folders()->all());
}

/** @test */
public function it_gets_the_folders_from_the_cache_and_blink_only_once()
{
Expand Down

0 comments on commit 339aa89

Please sign in to comment.