diff --git a/src/Flysystem/Azure.php b/src/Flysystem/Azure.php index 0333f0f..d793c59 100644 --- a/src/Flysystem/Azure.php +++ b/src/Flysystem/Azure.php @@ -32,6 +32,13 @@ final class Azure extends AzureBase { */ private FileUrlGeneratorInterface $fileUrlGenerator; + /** + * List of urls already requested, indexed by uri. + * + * @var string[] + */ + private array $externalUrls = []; + /** * {@inheritdoc} */ @@ -106,6 +113,11 @@ public function getClient(): BlobRestProxy { * {@inheritdoc} */ public function getExternalUrl($uri): string { + // This could get called multiple times in a request, currently 2 times, + // and the file_exists below takes time, so we use a 'static' cache. + if (isset($this->externalUrls[$uri])) { + return $this->externalUrls[$uri]; + } // The original ::getExternalUrl method generates image styles on the fly, // blocking the request until all derivatives on that page are generated. // We use 'responsive_image' module, so each image can generate up to @@ -116,13 +128,15 @@ public function getExternalUrl($uri): string { // copied to Azure blob storage. Each derivative is generated when the // image style URL is called for the first time, allowing the generation // to be decoupled from main request. - $uri = str_replace('azure://', 'public://', $uri); + $localUri = str_replace('azure://', 'public://', $uri); - return UrlHelper::encodePath($this->fileUrlGenerator->generateString($uri)); + return $this->externalUrls[$uri] = UrlHelper::encodePath( + $this->fileUrlGenerator->generateString($localUri)); } $target = $this->getTarget($uri); - return sprintf('%s/%s', $this->calculateUrlPrefix(), UrlHelper::encodePath($target)); + return $this->externalUrls[$uri] = sprintf('%s/%s', + $this->calculateUrlPrefix(), UrlHelper::encodePath($target)); } } diff --git a/tests/src/Unit/AzureTest.php b/tests/src/Unit/AzureTest.php index 966fe1f..9520b83 100644 --- a/tests/src/Unit/AzureTest.php +++ b/tests/src/Unit/AzureTest.php @@ -61,6 +61,10 @@ public function testGetExternalUrl() : void { // Check that file uri is encoded. $this->assertEquals('https://test.blob.core.windows.net/test/test%29.jpg', $azure->getExternalUrl('vfs://test).jpg')); $this->assertEquals('/styles/test%29.jpg', $azure->getExternalUrl('vfs://styles/test).jpg')); + + // Test static cache, as generateString should not be called 3rd time + // and is restricted above to 2 calls. + $this->assertEquals('/styles/test.jpg', $azure->getExternalUrl('vfs://styles/test.jpg')); } /**