Neos\Flow\Command\ResourceCommandController::cleanCommand PHP Method

cleanCommand() public method

This command checks the resource registry (that is the database tables) for orphaned resource objects which don't seem to have any corresponding data anymore (for example: the file in Data/Persistent/Resources has been deleted without removing the related PersistentResource object). If the Neos.Media package is active, this command will also detect any assets referring to broken resources and will remove the respective Asset object from the database when the broken resource is removed. This command will ask you interactively what to do before deleting anything.
public cleanCommand ( ) : void
return void
    public function cleanCommand()
    {
        $this->outputLine('Checking if resource data exists for all known resource objects ...');
        $this->outputLine();
        $mediaPackagePresent = $this->packageManager->isPackageActive('Neos.Media');
        $resourcesCount = $this->resourceRepository->countAll();
        $this->output->progressStart($resourcesCount);
        $brokenResources = [];
        $relatedAssets = new \SplObjectStorage();
        $relatedThumbnails = new \SplObjectStorage();
        $iterator = $this->resourceRepository->findAllIterator();
        foreach ($this->resourceRepository->iterate($iterator, function ($iteration) {
            $this->clearState($iteration);
        }) as $resource) {
            $this->output->progressAdvance(1);
            /* @var PersistentResource $resource */
            $stream = $resource->getStream();
            if (!is_resource($stream)) {
                $brokenResources[] = $resource->getSha1();
            }
        }
        $this->output->progressFinish();
        $this->outputLine();
        if ($mediaPackagePresent && count($brokenResources) > 0) {
            /* @var AssetRepository $assetRepository */
            $assetRepository = $this->objectManager->get(AssetRepository::class);
            /* @var ThumbnailRepository $thumbnailRepository */
            $thumbnailRepository = $this->objectManager->get(ThumbnailRepository::class);
            foreach ($brokenResources as $key => $resourceSha1) {
                $resource = $this->resourceRepository->findOneBySha1($resourceSha1);
                $brokenResources[$key] = $resource;
                $assets = $assetRepository->findByResource($resource);
                if ($assets !== null) {
                    $relatedAssets[$resource] = $assets;
                }
                $thumbnails = $thumbnailRepository->findByResource($resource);
                if ($assets !== null) {
                    $relatedThumbnails[$resource] = $thumbnails;
                }
            }
        }
        if (count($brokenResources) > 0) {
            $this->outputLine('<b>Found %s broken resource(s):</b>', [count($brokenResources)]);
            $this->outputLine();
            foreach ($brokenResources as $resource) {
                $this->outputLine('%s (%s) from "%s" collection', [$resource->getFilename(), $resource->getSha1(), $resource->getCollectionName()]);
                if (isset($relatedAssets[$resource])) {
                    foreach ($relatedAssets[$resource] as $asset) {
                        $this->outputLine(' -> %s (%s)', [get_class($asset), $asset->getIdentifier()]);
                    }
                }
            }
            $response = null;
            while (!in_array($response, ['y', 'n', 'c'])) {
                $response = $this->output->ask('<comment>Do you want to remove all broken resource objects and related assets from the database? (y/n/c) </comment>');
            }
            switch ($response) {
                case 'y':
                    $brokenAssetCounter = 0;
                    $brokenThumbnailCounter = 0;
                    foreach ($brokenResources as $sha1 => $resource) {
                        $this->outputLine('- delete %s (%s) from "%s" collection', [$resource->getFilename(), $resource->getSha1(), $resource->getCollectionName()]);
                        $resource->disableLifecycleEvents();
                        $this->resourceRepository->remove($resource);
                        if (isset($relatedAssets[$resource])) {
                            foreach ($relatedAssets[$resource] as $asset) {
                                $assetRepository->remove($asset);
                                $brokenAssetCounter++;
                            }
                        }
                        if (isset($relatedThumbnails[$resource])) {
                            foreach ($relatedThumbnails[$resource] as $thumbnail) {
                                $thumbnailRepository->remove($thumbnail);
                                $brokenThumbnailCounter++;
                            }
                        }
                        $this->persistenceManager->persistAll();
                    }
                    $brokenResourcesCounter = count($brokenResources);
                    if ($brokenResourcesCounter > 0) {
                        $this->outputLine('Removed %s resource object(s) from the database.', [$brokenResourcesCounter]);
                    }
                    if ($brokenAssetCounter > 0) {
                        $this->outputLine('Removed %s asset object(s) from the database.', [$brokenAssetCounter]);
                    }
                    if ($brokenThumbnailCounter > 0) {
                        $this->outputLine('Removed %s thumbnail object(s) from the database.', [$brokenThumbnailCounter]);
                    }
                    break;
                case 'n':
                    $this->outputLine('Did not delete any resource objects.');
                    break;
                case 'c':
                    $this->outputLine('Stopping. Did not delete any resource objects.');
                    $this->quit(0);
                    break;
            }
        }
    }