/** * Returns the web accessible URI for the resource object specified by the * given SHA1 hash. * * @param string $resourceHash The SHA1 hash identifying the resource content * @param string $collectionName Name of the collection the resource is part of * @return string A URI as a string * @throws Exception * @api */ public function getPublicPersistentResourceUriByHash($resourceHash, $collectionName = self::DEFAULT_PERSISTENT_COLLECTION_NAME) { if (!isset($this->collections[$collectionName])) { throw new Exception(sprintf('Could not determine persistent resource URI for "%s" because the specified collection "%s" does not exist.', $resourceHash, $collectionName), 1375197875); } /** @var TargetInterface $target */ $target = $this->collections[$collectionName]->getTarget(); $resource = $this->resourceRepository->findOneBySha1($resourceHash); if ($resource === NULL) { throw new Exception(sprintf('Could not determine persistent resource URI for "%s" because no Resource object with that SHA1 hash could be found.', $resourceHash), 1375347691); } return $target->getPublicPersistentResourceUri($resourceHash); }
/** * Clean up resource registry * * 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 Resource object). * * If the TYPO3.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. * * @return void */ public function cleanCommand() { $this->outputLine('Checking if resource data exists for all known resource objects ...'); $this->outputLine(); $mediaPackagePresent = $this->packageManager->isPackageActive('TYPO3.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 Resource $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; } } }