From fcabc296d21d42423e3bedbcec67fce963b170fa Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Mon, 28 Oct 2024 18:44:14 +0100 Subject: [PATCH] Read attributes as provided by the event object, and pass on attributes to other event handlers (#53) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR uses the new API introduced in https://github.com/symfony/symfony/pull/46001 to read controller attributes through the `ControllerEvent`, and to make them available to other event handlers when replacing the controller. This is necessary when using the ´Send304IfNotModified` attribute in combination with `\Symfony\Component\HttpKernel\Attribute\Cache`. Without this change, `\Symfony\Component\HttpKernel\EventListener\CacheAttributeListener` will not set `Cache` headers accordingly. The result is that you may get `304 Not Modified` responses on conditional requests with `If-Modified-Since`, but these are treated as `stale/cache` only in the HttpCache and have a `Cache-Control: must-revalidate, private` header. --- .github/workflows/tests.yml | 1 - composer.json | 2 +- src/Caching/EventListener.php | 30 +++++------------------------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b7f7768..c895728 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,7 +19,6 @@ jobs: matrix: include: - { php-version: 8.1, symfony-locked-version: none, dependency-version: prefer-lowest } - - { php-version: 8.2, symfony-locked-version: 5.4.*, dependency-version: prefer-stable } - { php-version: 8.2, symfony-locked-version: 6.4.*, dependency-version: prefer-stable } - { php-version: 8.3, symfony-locked-version: none, dependency-version: prefer-stable } name: PHPUnit (PHP ${{matrix.php-version}}, Symfony Version Lock ${{ matrix.symfony-locked-version }}, ${{ matrix.dependency-version }}) diff --git a/composer.json b/composer.json index 48c0936..a2f9fc9 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "symfony/filesystem": "^5.4|^6.4|^7.0", "symfony/finder": "^5.4|^6.4|^7.0", "symfony/http-foundation": "^5.4|^6.4|^7.0", - "symfony/http-kernel": "^5.4|^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", "symfony/lock": "^5.4|^6.4|^7.0", "symfony/twig-bundle": "^5.4|^6.4|^7.0", "twig/twig": "^2.0|^3.0" diff --git a/src/Caching/EventListener.php b/src/Caching/EventListener.php index ee8dc11..fc3db5e 100644 --- a/src/Caching/EventListener.php +++ b/src/Caching/EventListener.php @@ -8,7 +8,6 @@ namespace Webfactory\Bundle\WfdMetaBundle\Caching; -use ReflectionObject; use SplObjectStorage; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ControllerEvent; @@ -38,21 +37,19 @@ public function __construct(MetaQueryFactory $metaQueryFactory, $debug) public function onKernelController(ControllerEvent $event) { - $controller = $event->getController(); - $request = $event->getRequest(); - - $attribute = $this->findAttribute($controller); + $attributes = $event->getAttributes(Send304IfNotModified::class); - if (!$attribute) { + if (!$attributes) { return; } - $lastTouched = $attribute->calculateLastModified($this->metaQueryFactory); + $lastTouched = $attributes[0]->calculateLastModified($this->metaQueryFactory); if (!$lastTouched) { return; } + $request = $event->getRequest(); $this->lastTouchedResults[$request] = $lastTouched; /* @@ -73,7 +70,7 @@ public function onKernelController(ControllerEvent $event) if ($response->isNotModified($request)) { $event->setController(function () use ($response) { return $response; - }); + }, $event->getAttributes()); } } @@ -86,21 +83,4 @@ public function onKernelResponse(ResponseEvent $event) $response->setLastModified($this->lastTouchedResults[$request]); } } - - /** - * @param $callback array A PHP callback (array) pointing to the method to reflect on. - */ - protected function findAttribute($callback): ?Send304IfNotModified - { - if (!\is_array($callback)) { - return null; - } - - $object = new ReflectionObject($callback[0]); - $method = $object->getMethod($callback[1]); - - $attributes = $method->getAttributes(Send304IfNotModified::class); - - return $attributes ? $attributes[0]->newInstance() : null; - } }