Skip to content

Commit 6eccbb6

Browse files
authored
Fix issues with directory listing not returning all folders (#224)
* Fix issues with directory listing not returning all folders * Also cache meta exists queries * StyleCI * Update meta exists on save * Don't process subfolder if its the same as folder * Prevent infinite recursion * handle dotfile ignoring properly * Ignore any .meta folders * Dont info unless we are actually processing it * Seems we can't rely on getFolders to actually recurse properly, so make our own * Make sure we dont return lower level folders
1 parent bf039e9 commit 6eccbb6

File tree

3 files changed

+75
-14
lines changed

3 files changed

+75
-14
lines changed

src/Assets/Asset.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Support\Facades\Cache;
77
use Statamic\Assets\Asset as FileAsset;
88
use Statamic\Assets\AssetUploader as Uploader;
9+
use Statamic\Facades\Blink;
910
use Statamic\Facades\Path;
1011
use Statamic\Support\Arr;
1112
use Statamic\Support\Str;
@@ -71,12 +72,14 @@ public function exists()
7172

7273
public function metaExists()
7374
{
74-
return app('statamic.eloquent.assets.model')::query()
75+
return Blink::once('eloquent-asset-meta-exists-'.$this->id(), function () {
76+
return app('statamic.eloquent.assets.model')::query()
7577
->where([
7678
'container' => $this->containerHandle(),
7779
'folder' => $this->folder(),
7880
'basename' => $this->basename(),
7981
])->count() > 0;
82+
});
8083
}
8184

8285
private function metaValue($key)
@@ -130,6 +133,8 @@ public function writeMeta($meta)
130133
}
131134

132135
$model->save();
136+
137+
Blink::put('eloquent-asset-meta-exists-'.$this->id(), true);
133138
}
134139

135140
public function metaPath()

src/Assets/AssetContainerContents.php

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,28 @@ public function directories()
4040
}
4141

4242
$this->folders = Cache::remember($this->key(), $this->ttl(), function () {
43-
return $this->container->disk()->getFolders('/', true)
43+
return collect($this->directoryRecurse(''))
4444
->map(fn ($dir) => ['path' => $dir]);
4545
});
4646

4747
return $this->folders;
4848
}
4949

50+
private function directoryRecurse($directory)
51+
{
52+
$rootFolders = $this->container->disk()->getFolders($directory, false);
53+
54+
$folders = [];
55+
foreach ($rootFolders as $folder) {
56+
$folders[] = $folder;
57+
if ($subfolders = $this->directoryRecurse($folder)) {
58+
$folders = array_merge($folders, $subfolders);
59+
}
60+
}
61+
62+
return $folders;
63+
}
64+
5065
public function metaFilesIn($folder, $recursive)
5166
{
5267
return $this->query()
@@ -67,13 +82,48 @@ public function filteredDirectoriesIn($folder, $recursive)
6782
{
6883
$folder = $folder == '/' ? '' : $folder;
6984

70-
return $this->directories()->filter(function ($dir) use ($folder, $recursive) {
71-
if ($folder && ! Str::startsWith($dir, $folder)) {
72-
return false;
73-
}
74-
75-
return ! $recursive ? Str::of($dir)->after($folder.'/')->contains('/') == false : true;
76-
})->flip();
85+
return $this->directories()
86+
->filter(function ($dir) use ($folder) {
87+
if ($folder && ! Str::startsWith($dir['path'], $folder)) {
88+
return false;
89+
}
90+
91+
if ($folder == $dir['path']) {
92+
return false;
93+
}
94+
95+
return true;
96+
})
97+
->map(function ($dir) {
98+
$dirs = [];
99+
$tmp = '';
100+
foreach (explode('/', $dir['path']) as $dir) {
101+
$tmp .= '/'.$dir;
102+
$dirs[] = substr($tmp, 1);
103+
}
104+
105+
return $dirs;
106+
})
107+
->flatten()
108+
->unique()
109+
->filter(function ($dir) use ($folder, $recursive) {
110+
if ($folder == $dir || strlen($folder) > strlen($dir)) {
111+
return false;
112+
}
113+
114+
if ($recursive) {
115+
return true;
116+
}
117+
118+
$dir = Str::of($dir);
119+
if ($folder) {
120+
$dir = $dir->after($folder.'/');
121+
}
122+
123+
return ! $dir->contains('/');
124+
})
125+
->sort()
126+
->flip();
77127
}
78128

79129
public function save()

src/Commands/SyncAssets.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ private function processFolder(AssetContainer $container, $folder = '')
5757

5858
// ensure we have an asset for any paths
5959
$files->each(function ($file) use ($container) {
60-
$this->info($file);
61-
62-
if (Str::startsWith($file, '.')) {
60+
if (Str::of($file)->afterLast('/')->startsWith('.')) {
6361
return;
6462
}
6563

64+
$this->info($file);
65+
6666
$asset = Facades\Asset::make()
6767
->container($container->handle())
6868
->path($file)
@@ -85,8 +85,14 @@ private function processFolder(AssetContainer $container, $folder = '')
8585

8686
// process any sub-folders of this folder
8787
$container->folders($folder)
88-
->each(function ($folder) use ($container) {
89-
$this->processFolder($container, $folder);
88+
->each(function ($subfolder) use ($container, $folder) {
89+
if (str_contains($subfolder.'/', '.meta/')) {
90+
return;
91+
}
92+
93+
if ($folder != $subfolder && (strlen($subfolder) > strlen($folder))) {
94+
$this->processFolder($container, $subfolder);
95+
}
9096
});
9197
}
9298
}

0 commit comments

Comments
 (0)