|
3 | 3 | namespace Statamic\Eloquent\Commands; |
4 | 4 |
|
5 | 5 | use Illuminate\Console\Command; |
| 6 | +use Statamic\Assets\AssetContainerContents; |
6 | 7 | use Statamic\Console\RunsInPlease; |
7 | 8 | use Statamic\Contracts\Assets\AssetContainer; |
8 | 9 | use Statamic\Eloquent\Assets\AssetModel; |
@@ -44,6 +45,12 @@ private function processContainer(AssetContainer $container) |
44 | 45 | $this->info("Container: {$container->handle()}"); |
45 | 46 |
|
46 | 47 | $this->processFolder($container); |
| 48 | + |
| 49 | + $contents = app(AssetContainerContents::class); |
| 50 | + |
| 51 | + $contents->cacheStore()->forget('asset-folder-contents-'.$container->handle()); |
| 52 | + |
| 53 | + $contents->container($container)->directories(); |
47 | 54 | } |
48 | 55 |
|
49 | 56 | private function processFolder(AssetContainer $container, $folder = '/') |
@@ -87,6 +94,45 @@ private function processFolder(AssetContainer $container, $folder = '/') |
87 | 94 | }); |
88 | 95 | }); |
89 | 96 |
|
| 97 | + // delete any sub-folders we have a db entry for that no longer exist |
| 98 | + $filesystemFolders = $contents |
| 99 | + ->reject(fn ($item) => $item['type'] != 'dir') |
| 100 | + ->pluck('path'); |
| 101 | + |
| 102 | + // The folder variable is passed with a leading slash. This must be removed |
| 103 | + // in order to match against the folder column in the database. |
| 104 | + $folderNoLeadingSlash = Str::chopStart($folder, '/'); |
| 105 | + |
| 106 | + AssetModel::query() |
| 107 | + ->where('container', $container->handle()) |
| 108 | + ->when( |
| 109 | + $folder == '/', |
| 110 | + fn ($query) => $query->where('folder', 'not like', '%/'), |
| 111 | + fn ($query) => $query->where('folder', 'like', $folderNoLeadingSlash.'/%') |
| 112 | + ) |
| 113 | + ->select('folder') |
| 114 | + ->distinct() |
| 115 | + ->pluck('folder') |
| 116 | + ->unique() |
| 117 | + ->each(function ($folder) use ($filesystemFolders, $container) { |
| 118 | + if ($filesystemFolders->contains(fn ($fsFolder) => Str::startsWith($folder, $fsFolder.'/'))) { |
| 119 | + return; |
| 120 | + } |
| 121 | + |
| 122 | + $this->error("Deleting assets in {$folder}"); |
| 123 | + AssetModel::query() |
| 124 | + ->where('container', $container->handle()) |
| 125 | + ->where('folder', 'like', $folder) |
| 126 | + ->orWhere('folder', 'like', $folder.'/%') |
| 127 | + ->chunk(100, function ($assets) { |
| 128 | + $assets->each(function ($asset) { |
| 129 | + $this->error("Deleting {$asset->path}"); |
| 130 | + |
| 131 | + $asset->delete(); |
| 132 | + }); |
| 133 | + }); |
| 134 | + }); |
| 135 | + |
90 | 136 | // process any sub-folders of this folder |
91 | 137 | $contents |
92 | 138 | ->reject(fn ($item) => $item['type'] != 'dir') |
|
0 commit comments