Skip to content

Commit

Permalink
Fully, recursively delete asset data when deleting a volume folder
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonkelly committed Jan 4, 2025
1 parent 7abb868 commit 9c2ab9a
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- Fixed a bug where custom fields could cause validation errors when running the `users/create` command.
- Fixed a bug where deleting a volume folder wasn’t fully deleting asset data in descendant folders.

## 4.13.8 - 2025-01-02

Expand Down
26 changes: 11 additions & 15 deletions src/services/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,16 +306,19 @@ public function renameFolderById(int $folderId, string $newName): string
*/
public function deleteFoldersByIds(int|array $folderIds, bool $deleteDir = true): void
{
$folders = [];
$allFolderIds = [];

foreach ((array)$folderIds as $folderId) {
$folder = $this->getFolderById((int)$folderId);
if (!$folder) {
continue;
}

$folders[] = $folder;
$allFolderIds[] = $folder->id;
$descendants = $this->getAllDescendantFolders($folder, withParent: false);
array_push($allFolderIds, ...array_map(fn(VolumeFolder $folder) => $folder->id, $descendants));

// Delete the directory on the filesystem
if ($folder->path && $deleteDir) {
$volume = $folder->getVolume();
try {
Expand All @@ -327,25 +330,18 @@ public function deleteFoldersByIds(int|array $folderIds, bool $deleteDir = true)
}
}

/** @var Asset[] $assets */
$assets = Asset::find()->folderId($folderIds)->all();

// Delete the elements
$assetQuery = Asset::find()->folderId($allFolderIds);
$elementService = Craft::$app->getElements();

foreach ($assets as $asset) {
foreach ($assetQuery->each() as $asset) {
/** @var Asset $asset */
$asset->keepFileOnDelete = !$deleteDir;
$elementService->deleteElement($asset, true);
}

foreach ($folders as $folder) {
$descendants = $this->getAllDescendantFolders($folder);
usort($descendants, static fn($a, $b) => substr_count($a->path, '/') < substr_count($b->path, '/'));

foreach ($descendants as $descendant) {
VolumeFolderRecord::deleteAll(['id' => $descendant->id]);
}
VolumeFolderRecord::deleteAll(['id' => $folder->id]);
}
// Delete the folder records
VolumeFolderRecord::deleteAll(['id' => $allFolderIds]);
}

/**
Expand Down

0 comments on commit 9c2ab9a

Please sign in to comment.