Skip to content

Commit

Permalink
utils/delete-empty-volume-folders command
Browse files Browse the repository at this point in the history
Resolves #16388
  • Loading branch information
brandonkelly committed Jan 4, 2025
1 parent feb3f22 commit f3708d2
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- The global sidebar no longer shows “Failed” for queue jobs, for users that don’t have access to the Queue Manager. ([#16184](https://github.com/craftcms/cms/issues/16184))

## Administration
- Added the `utils/delete-empty-volume-folders` command. ([#16388](https://github.com/craftcms/cms/issues/16388))
- The Queue Manager utility now shows jobs’ class names. ([#16228](https://github.com/craftcms/cms/pull/16228))

## Development
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\console\controllers\utils;

use Craft;
use craft\console\Controller;
use craft\db\Query;
use craft\db\Table;
use yii\console\ExitCode;

/**
* Deletes empty volume folders.
*
* @author Pixel & Tonic, Inc. <[email protected]>
* @since 4.14.0
*/
class DeleteEmptyVolumeFoldersController extends Controller
{
/**
* @var string|null The volume handle(s) to delete folders from. Can be set to multiple comma-separated volumes.
*/
public ?string $volume = null;

/**
* @inheritdoc
*/
public function options($actionID): array
{
return [
...parent::options($actionID),
'volume',
];
}

/**
* Deletes empty volume folders.
*
* @return int
*/
public function actionIndex(): int
{
$query = (new Query())
->select(['folders.id'])
->from(['folders' => Table::VOLUMEFOLDERS])
->leftJoin(['assets' => Table::ASSETS], '[[assets.folderId]] = [[folders.id]]')
->where(['assets.id' => null])
->andWhere(['not', ['folders.parentId' => null]])
->andWhere(['not', ['folders.path' => null]]);

if ($this->volume) {
$volumeHandles = explode(',', $this->volume);
$volumeIds = [];
$volumesService = Craft::$app->getVolumes();
foreach ($volumeHandles as $handle) {
$volume = $volumesService->getVolumeByHandle($handle);
if (!$volume) {
$this->stderr("Invalid volume handle: $handle\n");
return ExitCode::UNSPECIFIED_ERROR;
}
$volumeIds[] = $volume->id;
}

$query->andWhere(['folders.volumeId' => $volumeIds]);
}

$emptyFolderIds = $query->column();

if (empty($emptyFolderIds)) {
$this->stdout("No empty folders found.\n");
return ExitCode::OK;
}

$message = sprintf(
'Deleting %s empty %s',
count($emptyFolderIds),
count($emptyFolderIds) === 1 ? 'folder' : 'folders',
);

$this->do($message, function() use ($emptyFolderIds) {
Craft::$app->getAssets()->deleteFoldersByIds($emptyFolderIds);
});

return ExitCode::OK;
}
}

0 comments on commit f3708d2

Please sign in to comment.