/** * Checks if recently imported resources really have been persisted - and if not, removes its data from the * respective storage. * * @return void */ public function shutdownObject() { foreach ($this->resourceRepository->getAddedResources() as $resource) { if ($this->persistenceManager->isNewObject($resource)) { $this->deleteResource($resource, FALSE); } } }
/** * Unpublishes the given persistent resource * * @param \TYPO3\Flow\Resource\Resource $resource The resource to unpublish * @return void */ public function unpublishResource(Resource $resource) { $resources = $this->resourceRepository->findSimilarResources($resource); if (count($resources) > 1) { return; } $this->unpublishFile($this->getRelativePublicationPathAndFilename($resource)); }
/** * Retrieve all Objects stored in this storage, filtered by the given collection name * * @param CollectionInterface $collection * @internal param string $collectionName * @return array<\TYPO3\Flow\Resource\Storage\Object> * @api */ public function getObjectsByCollection(CollectionInterface $collection) { $objects = array(); $that = $this; $bucketName = $this->bucketName; foreach ($this->resourceRepository->findByCollectionName($collection->getName()) as $resource) { /** @var \TYPO3\Flow\Resource\Resource $resource */ $object = new Object(); $object->setFilename($resource->getFilename()); $object->setSha1($resource->getSha1()); $object->setStream(function () use($that, $bucketName, $resource) { return fopen('s3://' . $bucketName . '/' . $this->keyPrefix . $resource->getSha1(), 'r'); }); $objects[] = $object; } return $objects; }
/** * Retrieve all Objects stored in this storage, filtered by the given collection name * * @param CollectionInterface $collection * @return array<\TYPO3\Flow\Resource\Storage\Object> */ public function getObjectsByCollection(CollectionInterface $collection) { $objects = array(); $that = $this; foreach ($this->resourceRepository->findByCollectionName($collection->getName()) as $resource) { /** @var \TYPO3\Flow\Resource\Resource $resource */ $object = new Object(); $object->setFilename($resource->getFilename()); $object->setSha1($resource->getSha1()); $object->setMd5($resource->getMd5()); $object->setFileSize($resource->getFileSize()); $object->setStream(function () use($that, $resource) { return $that->getStreamByResource($resource); }); $objects[] = $object; } return $objects; }
/** * Retrieve all Objects stored in this storage, filtered by the given collection name * * @param callable $callback Function called after each iteration * @param CollectionInterface $collection * @return \Generator<Object> */ public function getObjectsByCollection(CollectionInterface $collection, callable $callback = null) { $iterator = $this->resourceRepository->findByCollectionNameIterator($collection->getName()); $iteration = 0; foreach ($this->resourceRepository->iterate($iterator, $callback) as $resource) { /** @var PersistentResource $resource */ $object = new Object(); $object->setFilename($resource->getFilename()); $object->setSha1($resource->getSha1()); $object->setMd5($resource->getMd5()); $object->setFileSize($resource->getFileSize()); $object->setStream(function () use($resource) { return $this->getStreamByResource($resource); }); (yield $object); if (is_callable($callback)) { call_user_func($callback, $iteration, $object); } $iteration++; } }
/** * 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 = array(); $relatedAssets = new \SplObjectStorage(); foreach ($this->resourceRepository->findAll() as $resource) { $this->output->progressAdvance(1); /* @var \TYPO3\Flow\Resource\Resource $resource */ $stream = $resource->getStream(); if (!is_resource($stream)) { $brokenResources[] = $resource; } } $this->output->progressFinish(); $this->outputLine(); if ($mediaPackagePresent && count($brokenResources) > 0) { $assetRepository = $this->objectManager->get('TYPO3\\Media\\Domain\\Repository\\AssetRepository'); /* @var \TYPO3\Media\Domain\Repository\AssetRepository $assetRepository */ foreach ($brokenResources as $resource) { $assets = $assetRepository->findByResource($resource); if ($assets !== NULL) { $relatedAssets[$resource] = $assets; } } } if (count($brokenResources) > 0) { $this->outputLine('<b>Found %s broken resource(s):</b>', array(count($brokenResources))); $this->outputLine(); foreach ($brokenResources as $resource) { $this->outputLine('%s (%s) %s', array($resource->getFilename(), $resource->getSha1(), $resource->getCollectionName())); if (isset($relatedAssets[$resource])) { foreach ($relatedAssets[$resource] as $asset) { $this->outputLine(' -> %s (%s)', array(get_class($asset), $asset->getIdentifier())); } } } $response = NULL; while (!in_array($response, array('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': foreach ($brokenResources as $resource) { $resource->disableLifecycleEvents(); $this->persistenceManager->remove($resource); if (isset($relatedAssets[$resource])) { foreach ($relatedAssets[$resource] as $asset) { $assetRepository->remove($asset); } } } $this->outputLine('Removed %s resource object(s) from the database.', array(count($brokenResources))); 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; } } }
/** * @param array $source * @param PropertyMappingConfigurationInterface $configuration * @return Resource|Error * @throws Exception * @throws InvalidPropertyMappingConfigurationException */ protected function handleHashAndData(array $source, PropertyMappingConfigurationInterface $configuration = null) { $hash = null; $resource = false; $givenResourceIdentity = null; if (isset($source['__identity'])) { $givenResourceIdentity = $source['__identity']; unset($source['__identity']); $resource = $this->resourceRepository->findByIdentifier($givenResourceIdentity); if ($resource instanceof Resource) { return $resource; } if ($configuration->getConfigurationValue(\TYPO3\Flow\Resource\ResourceTypeConverter::class, self::CONFIGURATION_IDENTITY_CREATION_ALLOWED) !== true) { throw new InvalidPropertyMappingConfigurationException('Creation of resource objects with identity not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_IDENTITY_CREATION_ALLOWED" to TRUE'); } } if (isset($source['hash']) && preg_match('/[0-9a-f]{40}/', $source['hash'])) { $hash = $source['hash']; } if ($hash !== null && count($source) === 1) { $resource = $this->resourceManager->getResourceBySha1($hash); } if ($resource === null) { $collectionName = $this->getCollectionName($source, $configuration); if (isset($source['data'])) { $resource = $this->resourceManager->importResourceFromContent($source['data'], $source['filename'], $collectionName, $givenResourceIdentity); } elseif ($hash !== null) { $resource = $this->resourceManager->importResource($configuration->getConfigurationValue(\TYPO3\Flow\Resource\ResourceTypeConverter::class, self::CONFIGURATION_RESOURCE_LOAD_PATH) . '/' . $hash, $collectionName, $givenResourceIdentity); if (is_array($source) && isset($source['filename'])) { $resource->setFilename($source['filename']); } } } if ($resource instanceof Resource) { return $resource; } else { return new Error('The resource manager could not create a Resource instance.', 1404312901); } }
/** * 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; } } }
/** * Retrieve all Objects stored in this storage, filtered by the given collection name * * @param CollectionInterface $collection * @internal param string $collectionName * @return array<\TYPO3\Flow\Resource\Storage\Object> * @api */ public function getObjectsByCollection(CollectionInterface $collection) { if ($this->debug) { $this->systemLogger->log('storage ' . $this->name . ': getObjectsByCollection, $collection->getName(): ' . $collection->getName()); } $objects = array(); $that = $this; $containerName = $this->containerName; foreach ($this->resourceRepository->findByCollectionName($collection->getName()) as $resource) { /** @var \TYPO3\Flow\Resource\Resource $resource */ if ($this->debug) { $this->systemLogger->log('storage ' . $this->name . ': - getObjectsByCollection $resource->getFilename(): ' . $resource->getFilename()); } $object = new Object(); $object->setFilename($resource->getFilename()); $object->setSha1($resource->getSha1()); $object->setStream(function () use($that, $containerName, $resource) { return 'http://' . $this->zoneDomain . '/_' . $resource->getSha1(); }); $objects[] = $object; } return $objects; }