diff --git a/Classes/Driver/AmazonS3Driver.php b/Classes/Driver/AmazonS3Driver.php index cbb3cd84..fd92f83f 100644 --- a/Classes/Driver/AmazonS3Driver.php +++ b/Classes/Driver/AmazonS3Driver.php @@ -221,7 +221,6 @@ public function initialize() $this->initializeBaseUrl() ->initializeSettings() ->initializeClient(); - $this->resetRequestCache(); // Test connection if we are in the edit view of this storage if ( $this->compatibilityService->isBackend() @@ -1230,32 +1229,34 @@ protected function prefixExists(string $identifier): bool * @param string $identifier * @return array|null Returns an array with the meta info or "null" */ - protected function getMetaInfo($identifier) + protected function getMetaInfo($identifier): ?array { $this->normalizeIdentifier($identifier); $cacheIdentifier = md5($identifier); - if (!$this->metaInfoCache->has($cacheIdentifier)) { - try { - $metadata = $this->s3Client->headObject([ - 'Bucket' => $this->configuration['bucket'], - 'Key' => $identifier - ])->toArray(); - $metaInfoDownloadAdapter = GeneralUtility::makeInstance(MetaInfoDownloadAdapter::class); - $metaInfo = $metaInfoDownloadAdapter->getMetaInfoFromResponse($this, $identifier, $metadata); - $this->metaInfoCache->set($cacheIdentifier, $metaInfo); - return $metaInfo; - } catch (\Exception $exc) { - // Ignore file not found errors - if (!$exc->getPrevious() || $exc->getPrevious()->getCode() !== 404) { - /** @var \TYPO3\CMS\Core\Log\Logger $logger */ - $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); - $logger->log(LogLevel::WARNING, $exc->getMessage(), $exc->getTrace()); - } - $this->metaInfoCache->remove($cacheIdentifier); - return null; + $metaInfo = $this->metaInfoCache->has($cacheIdentifier) ? $this->metaInfoCache->get($cacheIdentifier) : false; + if ($metaInfo) { + return $metaInfo; + } + + try { + $metadata = $this->s3Client->headObject([ + 'Bucket' => $this->configuration['bucket'], + 'Key' => $identifier + ])->toArray(); + $metaInfoDownloadAdapter = GeneralUtility::makeInstance(MetaInfoDownloadAdapter::class); + $metaInfo = $metaInfoDownloadAdapter->getMetaInfoFromResponse($this, $identifier, $metadata); + $this->metaInfoCache->set($cacheIdentifier, $metaInfo); + return $metaInfo; + } catch (\Exception $exc) { + // Ignore file not found errors + if (!$exc->getPrevious() || $exc->getPrevious()->getCode() !== 404) { + /** @var \TYPO3\CMS\Core\Log\Logger $logger */ + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); + $logger->log(LogLevel::WARNING, $exc->getMessage(), $exc->getTrace()); } + $this->metaInfoCache->remove($cacheIdentifier); + return null; } - return $this->metaInfoCache->get($cacheIdentifier); } /** @@ -1268,7 +1269,10 @@ protected function getCachedResponse($function, $parameter) $cacheIdentifier = md5($function) . '-' . md5(serialize($parameter)); if ($this->requestCache->has($cacheIdentifier)) { - return $this->requestCache->get($cacheIdentifier); + $response = $this->requestCache->get($cacheIdentifier); + if (false !== $response) { + return $response; + } } $result = $this->s3Client->$function($parameter)->toArray(); @@ -1282,13 +1286,14 @@ protected function getCachedResponse($function, $parameter) * @param $identifier * @return void */ - protected function flushMetaInfoCache($identifier) + protected function flushMetaInfoCache($identifier): void { $this->normalizeIdentifier($identifier); $cacheIdentifier = md5($identifier); if ($this->metaInfoCache->has($cacheIdentifier)) { - $this->metaInfoCache->flush($cacheIdentifier); + $this->metaInfoCache->remove($cacheIdentifier); } + $this->requestCache->flush(); } /** @@ -1529,7 +1534,7 @@ protected function getListObjects($identifier, $overrideArgs = []) $fileIdentifier = $content['Key']; $this->normalizeIdentifier($fileIdentifier); $cacheIdentifier = md5($fileIdentifier); - if (!$this->metaInfoCache->has($cacheIdentifier)) { + if (!$this->metaInfoCache->has($cacheIdentifier) || !$this->metaInfoCache->get($cacheIdentifier)) { $this->metaInfoCache->set($cacheIdentifier, $metaInfoDownloadAdapter->getMetaInfoFromResponse($this, $fileIdentifier, $content)); } } diff --git a/Classes/Service/MetaDataUpdateService.php b/Classes/Service/MetaDataUpdateService.php index 3f04715b..1831fc20 100644 --- a/Classes/Service/MetaDataUpdateService.php +++ b/Classes/Service/MetaDataUpdateService.php @@ -18,6 +18,7 @@ use AUS\AusDriverAmazonS3\Driver\AmazonS3Driver; use AUS\AusDriverAmazonS3\Index\Extractor; use TYPO3\CMS\Core\Resource\AbstractFile; +use TYPO3\CMS\Core\Resource\Exception\InvalidUidException; use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Resource\ResourceStorage; @@ -29,36 +30,44 @@ */ class MetaDataUpdateService implements SingletonInterface { + /** + * @throws InvalidUidException + */ public function updateMetadata(array $fileProperties): void { - if ($fileProperties['type'] === AbstractFile::FILETYPE_IMAGE) { - $storage = $this->getStorage((int) $fileProperties['storage']); + if ($fileProperties['type'] !== AbstractFile::FILETYPE_IMAGE) { + return; + } + + $storage = $this->getStorage((int)$fileProperties['storage']); - // only process on our driver type where data was missing - if ($storage->getDriverType() !== AmazonS3Driver::DRIVER_TYPE) { - return; - } + // only process on our driver type where data was missing + if ($storage->getDriverType() !== AmazonS3Driver::DRIVER_TYPE) { + return; + } - $file = $storage->getFile($fileProperties['identifier']); - $imageDimensions = $this->getExtractor()->getImageDimensionsOfRemoteFile($file); + $file = $storage->getFile($fileProperties['identifier']); + $imageDimensions = $this->getExtractor()->getImageDimensionsOfRemoteFile($file); - $metaDataRepository = $this->getMetaDataRepository(); - $metaData = $metaDataRepository->findByFileUid($fileProperties['uid']); + $metaDataRepository = $this->getMetaDataRepository(); + $metaData = $metaDataRepository->findByFileUid($fileProperties['uid']); - $create = count($metaData) === 0; - $metaData['width'] = $imageDimensions[0]; - $metaData['height'] = $imageDimensions[1]; - if ($create) { - $metaDataRepository->createMetaDataRecord($fileProperties['uid'], $metaData); - } else { - $metaDataRepository->update($fileProperties['uid'], $metaData); - } + $create = count($metaData) === 0; + $metaData['width'] = $imageDimensions[0]; + $metaData['height'] = $imageDimensions[1]; + if ($create) { + $metaDataRepository->createMetaDataRecord($fileProperties['uid'], $metaData); + } else { + /** @noinspection PhpInternalEntityUsedInspection */ + $metaDataRepository->update($fileProperties['uid'], $metaData); } } protected function getStorage(int $uid): ResourceStorage { - return GeneralUtility::makeInstance(ResourceFactory::class)->getStorageObject($uid); + $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class); + assert($resourceFactory instanceof ResourceFactory); + return $resourceFactory->getStorageObject($uid); } protected function getExtractor(): Extractor diff --git a/README.md b/README.md index c520f534..b0c68c0c 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,30 @@ By default, these caches are transient. However, if you choose to configure a pe Detailed instructions on how to customize these cache backends can be found in the [TYPO3 CachingFramework Configuration Guide](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/CachingFramework/Configuration/Index.html). Remember, thorough testing is essential when modifying cache backends. +Example with simple file backend; all changes through TYPO3 +```php +[ + 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, + 'backend' => \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend::class, + 'groups' => [ + 'pages' + ], +]; +``` +Example with redis +```php +[ + 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, + 'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class, + 'options' => [ + 'defaultLifetime' => 0, // infinite + 'database' => 0, + 'hostname' => 'redis', + 'port' => 6379, + ], +]; +``` + ## Extend Extension ### Initialize S3 Client