diff --git a/src/Module.php b/src/Module.php index 024c59a..b22bf16 100644 --- a/src/Module.php +++ b/src/Module.php @@ -97,7 +97,7 @@ public function bootstrap($app): void Asset::class, Asset::EVENT_BEFORE_GENERATE_TRANSFORM, function(GenerateTransformEvent $event) { - if (!$event->transform || !$event->asset?->fs instanceof AssetsFs) { + if (!$this->shouldUseAssetCdnTransform($event)) { return; } @@ -119,6 +119,19 @@ function(GenerateTransformEvent $event) { } } + protected function shouldUseAssetCdnTransform(GenerateTransformEvent $event): bool + { + if (!$event->transform || !$event->asset?->fs instanceof AssetsFs) { + return false; + } + + if (!(Craft::$app instanceof WebApplication)) { + return true; + } + + return !Craft::$app->getRequest()->getIsActionRequest(); + } + public function getConfig(): Config { if (isset($this->_config)) { diff --git a/src/fs/Fs.php b/src/fs/Fs.php index 5bdbd44..448c1c2 100644 --- a/src/fs/Fs.php +++ b/src/fs/Fs.php @@ -94,7 +94,7 @@ public function createUrl(string $path = ''): UriInterface { if ($this->useLocalFs) { return Modifier::wrap($this->getLocalFs()->getRootUrl() ?? '/') - ->appendSegment($this->createPath($path)) + ->appendPath($this->createPath($path)) ->unwrap(); } diff --git a/tests/unit/ImageTransformTest.php b/tests/unit/ImageTransformTest.php index aa2be32..67cd6c8 100644 --- a/tests/unit/ImageTransformTest.php +++ b/tests/unit/ImageTransformTest.php @@ -5,10 +5,13 @@ use Codeception\Test\Unit; use Craft; use craft\cloud\Module as CloudModule; +use craft\cloud\fs\AssetsFs; use craft\cloud\imagetransforms\ImageTransformBehavior; use craft\cloud\imagetransforms\ImageTransformer; use craft\elements\Asset; +use craft\events\GenerateTransformEvent; use craft\models\ImageTransform; +use craft\models\Volume; class ImageTransformTest extends Unit { @@ -123,6 +126,27 @@ public function testGetTransformUrlDoesNotLeakGravityBetweenAssets(): void $this->assertStringNotContainsString('gravity%5Bx%5D=0.57', $secondUrl); } + public function testActionRequestsUseNativeTransforms(): void + { + $module = new TestCloudModule('cloud-test'); + $event = new GenerateTransformEvent([ + 'asset' => new TransformDecisionAsset(), + 'transform' => new ImageTransform(['width' => 100]), + ]); + $request = Craft::$app->getRequest(); + $isActionRequest = $request->getIsActionRequest(); + + try { + $request->setIsActionRequest(true); + $this->assertFalse($module->usesAssetCdnTransform($event)); + + $request->setIsActionRequest(false); + $this->assertTrue($module->usesAssetCdnTransform($event)); + } finally { + $request->setIsActionRequest($isActionRequest); + } + } + private function makeAssetStub(array $focalPoint): Asset { return new class($focalPoint) extends Asset { @@ -176,7 +200,7 @@ public function getFocalPoint(bool $asCss = false): array|string|null return $this->focalPointValue; } - public function getWidth(array|string|\craft\models\ImageTransform $transform = null): ?int + public function getWidth(array|string|\craft\models\ImageTransform|null $transform = null): ?int { return $this->widthValue; } @@ -234,3 +258,24 @@ public function buildTransformQuery(Asset $asset, ImageTransform $imageTransform return (string) \League\Uri\Components\Query::fromVariable($behavior->toOptions($gravity)); } } + +class TestCloudModule extends CloudModule +{ + public function usesAssetCdnTransform(GenerateTransformEvent $event): bool + { + return $this->shouldUseAssetCdnTransform($event); + } +} + +class TransformDecisionAsset extends Asset +{ + public function getVolume(): Volume + { + return new class() extends Volume { + public function getFs(): AssetsFs + { + return new AssetsFs(); + } + }; + } +}