Loading core/core.services.yml +5 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,11 @@ services: arguments: ['@request_stack'] tags: - { name: cache.context } cache_context.exception_status_code: class: Drupal\Core\Cache\Context\ExceptionStatusCodeCacheContext arguments: ['@request_stack'] tags: - { name: cache.context } cache_context.url: class: Drupal\Core\Cache\Context\UrlCacheContext arguments: ['@request_stack'] Loading core/lib/Drupal/Core/Cache/Context/ExceptionStatusCodeCacheContext.php 0 → 100644 +44 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\Core\Cache\Context; use Drupal\Core\Cache\CacheableMetadata; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; /** * Defines the ExceptionStatusCodeCacheContext service. * * Cache context ID: 'exception_status_code'. */ class ExceptionStatusCodeCacheContext extends RequestStackCacheContextBase { /** * {@inheritdoc} */ public static function getLabel(): \Stringable { return t('Exception status code'); } /** * {@inheritdoc} */ public function getContext(): string { $exception = $this->requestStack->getCurrentRequest()->attributes->get('exception'); if ($exception instanceof HttpExceptionInterface) { return (string) $exception->getStatusCode(); } // If there's no exception status code, usually a 200, return '0' because we // don't know what might be set by response subscribers. return '0'; } /** * {@inheritdoc} */ public function getCacheableMetadata(): CacheableMetadata { return new CacheableMetadata(); } } core/modules/system/src/Plugin/Condition/ResponseStatus.php +1 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,7 @@ public function evaluate(): bool { */ public function getCacheContexts(): array { $contexts = parent::getCacheContexts(); $contexts[] = 'url.path'; $contexts[] = 'exception_status_code'; return $contexts; } Loading core/tests/Drupal/Tests/Core/Cache/Context/ExceptionStatusCodeCacheContextTest.php 0 → 100644 +54 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\Tests\Core\Cache\Context; use Drupal\Core\Cache\Context\ExceptionStatusCodeCacheContext; use Drupal\Tests\UnitTestCase; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; /** * Tests Drupal\Core\Cache\Context\CookiesCacheContext. */ #[CoversClass(ExceptionStatusCodeCacheContext::class)] #[Group('Cache')] class ExceptionStatusCodeCacheContextTest extends UnitTestCase { /** * Tests get context. */ #[DataProvider('providerTestGetContext')] public function testGetContext(?\Exception $exception, string $result): void { $request_stack = new RequestStack(); $request = Request::create('/', 'GET'); if (isset($exception)) { $request->attributes->set('exception', $exception); } $request_stack->push($request); $cache_context = new ExceptionStatusCodeCacheContext($request_stack); $this->assertSame($cache_context->getContext(), $result); } /** * Provides a list of cookies and expected cache contexts. */ public static function providerTestGetContext(): array { return [ [new NotFoundHttpException(), '404'], [new AccessDeniedHttpException(), '403'], [new BadRequestHttpException(), '400'], [new MethodNotAllowedHttpException(['POST']), '405'], [NULL, '0'], ]; } } Loading
core/core.services.yml +5 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,11 @@ services: arguments: ['@request_stack'] tags: - { name: cache.context } cache_context.exception_status_code: class: Drupal\Core\Cache\Context\ExceptionStatusCodeCacheContext arguments: ['@request_stack'] tags: - { name: cache.context } cache_context.url: class: Drupal\Core\Cache\Context\UrlCacheContext arguments: ['@request_stack'] Loading
core/lib/Drupal/Core/Cache/Context/ExceptionStatusCodeCacheContext.php 0 → 100644 +44 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\Core\Cache\Context; use Drupal\Core\Cache\CacheableMetadata; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; /** * Defines the ExceptionStatusCodeCacheContext service. * * Cache context ID: 'exception_status_code'. */ class ExceptionStatusCodeCacheContext extends RequestStackCacheContextBase { /** * {@inheritdoc} */ public static function getLabel(): \Stringable { return t('Exception status code'); } /** * {@inheritdoc} */ public function getContext(): string { $exception = $this->requestStack->getCurrentRequest()->attributes->get('exception'); if ($exception instanceof HttpExceptionInterface) { return (string) $exception->getStatusCode(); } // If there's no exception status code, usually a 200, return '0' because we // don't know what might be set by response subscribers. return '0'; } /** * {@inheritdoc} */ public function getCacheableMetadata(): CacheableMetadata { return new CacheableMetadata(); } }
core/modules/system/src/Plugin/Condition/ResponseStatus.php +1 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,7 @@ public function evaluate(): bool { */ public function getCacheContexts(): array { $contexts = parent::getCacheContexts(); $contexts[] = 'url.path'; $contexts[] = 'exception_status_code'; return $contexts; } Loading
core/tests/Drupal/Tests/Core/Cache/Context/ExceptionStatusCodeCacheContextTest.php 0 → 100644 +54 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\Tests\Core\Cache\Context; use Drupal\Core\Cache\Context\ExceptionStatusCodeCacheContext; use Drupal\Tests\UnitTestCase; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; /** * Tests Drupal\Core\Cache\Context\CookiesCacheContext. */ #[CoversClass(ExceptionStatusCodeCacheContext::class)] #[Group('Cache')] class ExceptionStatusCodeCacheContextTest extends UnitTestCase { /** * Tests get context. */ #[DataProvider('providerTestGetContext')] public function testGetContext(?\Exception $exception, string $result): void { $request_stack = new RequestStack(); $request = Request::create('/', 'GET'); if (isset($exception)) { $request->attributes->set('exception', $exception); } $request_stack->push($request); $cache_context = new ExceptionStatusCodeCacheContext($request_stack); $this->assertSame($cache_context->getContext(), $result); } /** * Provides a list of cookies and expected cache contexts. */ public static function providerTestGetContext(): array { return [ [new NotFoundHttpException(), '404'], [new AccessDeniedHttpException(), '403'], [new BadRequestHttpException(), '400'], [new MethodNotAllowedHttpException(['POST']), '405'], [NULL, '0'], ]; } }