diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6380f3da..b8858b11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,12 +22,10 @@ jobs: matrix: varnish-version: ['6.6'] varnish-modules-version: ['0.18.0'] - php: ['7.3', '7.4', '8.0', '8.1'] + php: ['8.0', '8.1', '8.2', '8.3'] include: - - php: '7.4' - symfony-version: '4.3.*' - - php: '7.4' - symfony-version: '5.0.*' + - php: '8.0' + symfony-version: '5.4.*' - php: '8.1' symfony-version: '6.*' - php: '8.1' @@ -71,38 +69,6 @@ jobs: - name: Execute tests run: vendor/bin/simple-phpunit -v - legacyPHP: - name: PHP 7.2 Varnish 6 - runs-on: ubuntu-20.04 - env: - VARNISH_VERSION: '6.6' - VARNISH_MODULES_VERSION: '0.18.0' - - steps: - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.2 - tools: composer:v2 - coverage: none - - - name: Checkout code - uses: actions/checkout@v2 - - - name: Setup Varnish and Nginx - run: | - sh ${GITHUB_WORKSPACE}/.github/workflows/setup-varnish.sh - sh ${GITHUB_WORKSPACE}/.github/workflows/setup-nginx.sh - - - name: Install composer dependencies - run: | - composer require --no-update ${DEPENDENCIES} - composer update --prefer-dist --no-interaction --no-progress - vendor/bin/simple-phpunit install - - - name: Execute tests - run: vendor/bin/simple-phpunit -v - varnish5: name: PHP ${{ matrix.php }} Legacy Varnish 5 runs-on: ubuntu-20.04 @@ -114,7 +80,7 @@ jobs: fail-fast: false matrix: include: - - php: '7.4' + - php: '8.0' steps: - name: Setup PHP @@ -151,7 +117,7 @@ jobs: fail-fast: false matrix: include: - - php: '7.4' + - php: '8.0' steps: - name: Setup PHP @@ -188,7 +154,7 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.2'] + php: ['8.0'] steps: - name: Setup PHP diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 5d9c92cd..8d054526 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -10,15 +10,13 @@ jobs: phpstan-src: name: PHPStan src runs-on: ubuntu-latest - env: - REQUIRE_DEV: "true" steps: - name: Checkout code uses: actions/checkout@v2 - name: Pull in optional dependencies - run: composer require --no-update phpunit/phpunit toflar/psr6-symfony-http-cache-store:^3.0 + run: composer require --no-update phpunit/phpunit toflar/psr6-symfony-http-cache-store:^3.0 symfony/http-kernel:^7.0 - name: PHPStan uses: docker://oskarstark/phpstan-ga @@ -36,7 +34,7 @@ jobs: uses: actions/checkout@v2 - name: Pull in optional dependencies - run: composer require --no-update phpunit/phpunit toflar/psr6-symfony-http-cache-store:^3.0 + run: composer require --no-update phpunit/phpunit toflar/psr6-symfony-http-cache-store:^3.0 symfony/http-kernel:^7.0 - name: PHPStan uses: docker://oskarstark/phpstan-ga diff --git a/composer.json b/composer.json index 8f369e37..60f2105d 100644 --- a/composer.json +++ b/composer.json @@ -21,9 +21,9 @@ } ], "require": { - "php": "^7.2 || ^8.0", - "symfony/event-dispatcher": "^4.3 || ^5.0 || ^6.0 || ^7.0", - "symfony/options-resolver": "^4.3 || ^5.0 || ^6.0 || ^7.0", + "php": "^8.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", "php-http/client-implementation": "^1.0 || ^2.0", "php-http/client-common": "^1.1.0 || ^2.0", "php-http/message": "^1.0 || ^2.0", diff --git a/src/SymfonyCache/AccessControlledListener.php b/src/SymfonyCache/AccessControlledListener.php index c3ef3d5e..ae5e74de 100644 --- a/src/SymfonyCache/AccessControlledListener.php +++ b/src/SymfonyCache/AccessControlledListener.php @@ -26,10 +26,7 @@ */ abstract class AccessControlledListener implements EventSubscriberInterface { - /** - * @var RequestMatcherInterface - */ - private $clientMatcher; + private RequestMatcherInterface $clientMatcher; /** * When creating this event listener, you can configure a number of options. @@ -57,7 +54,7 @@ public function __construct(array $options = []) if (!$clientMatcher) { $clientMatcher = class_exists(IpsRequestMatcher::class) ? new IpsRequestMatcher($options['client_ips'] ?: '127.0.0.1') - : new RequestMatcher(null, null, null, $options['client_ips'] ?: '127.0.0.1') + : new RequestMatcher(null, null, null, $options['client_ips'] ?: '127.0.0.1') /* @phpstan-ignore-line for BC with Symfony < 6.2 */ ; } diff --git a/src/SymfonyCache/CacheEvent.php b/src/SymfonyCache/CacheEvent.php index 7a9e02be..808ee5f7 100644 --- a/src/SymfonyCache/CacheEvent.php +++ b/src/SymfonyCache/CacheEvent.php @@ -23,25 +23,13 @@ */ class CacheEvent extends BaseEvent { - /** - * @var CacheInvalidation - */ - private $kernel; + private CacheInvalidation $kernel; - /** - * @var Request - */ - private $request; + private Request $request; - /** - * @var Response - */ - private $response; + private ?Response $response; - /** - * @var int - */ - private $requestType; + private int $requestType; /** * Make sure your $kernel implements CacheInvalidationInterface. @@ -51,7 +39,7 @@ class CacheEvent extends BaseEvent * @param Response|null $response the response, if available * @param int $requestType the request type (default HttpKernelInterface::MASTER_REQUEST) */ - public function __construct(CacheInvalidation $kernel, Request $request, Response $response = null, $requestType = HttpKernelInterface::MASTER_REQUEST) + public function __construct(CacheInvalidation $kernel, Request $request, Response $response = null, int $requestType = HttpKernelInterface::MAIN_REQUEST) { $this->kernel = $kernel; $this->request = $request; @@ -71,20 +59,16 @@ public function getKernel() /** * Get the request that is being processed. - * - * @return Request */ - public function getRequest() + public function getRequest(): Request { return $this->request; } /** - * One of the constants HttpKernelInterface::MASTER_REQUEST or SUB_REQUEST. - * - * @return int + * One of the constants HttpKernelInterface::MAIN_REQUEST or SUB_REQUEST. */ - public function getRequestType() + public function getRequestType(): int { return $this->requestType; } @@ -92,10 +76,8 @@ public function getRequestType() /** * Events that occur after the response is created provide the default response. * Event listeners can also set the response to make it available here. - * - * @return Response|null the response if one was set */ - public function getResponse() + public function getResponse(): ?Response { return $this->response; } @@ -105,7 +87,7 @@ public function getResponse() * * Setting a response stops propagation of the event to further event handlers. */ - public function setResponse(Response $response) + public function setResponse(Response $response): void { $this->response = $response; diff --git a/src/SymfonyCache/EventDispatchingHttpCache.php b/src/SymfonyCache/EventDispatchingHttpCache.php index adba06eb..267a240e 100644 --- a/src/SymfonyCache/EventDispatchingHttpCache.php +++ b/src/SymfonyCache/EventDispatchingHttpCache.php @@ -40,17 +40,9 @@ */ trait EventDispatchingHttpCache { - /** - * @var EventDispatcherInterface - */ - private $eventDispatcher; + private ?EventDispatcherInterface $eventDispatcher = null; - /** - * Get event dispatcher. - * - * @return EventDispatcherInterface - */ - public function getEventDispatcher() + public function getEventDispatcher(): EventDispatcherInterface { if (!$this->eventDispatcher) { $this->eventDispatcher = new EventDispatcher(); @@ -64,7 +56,7 @@ public function getEventDispatcher() * * @see EventDispatcherInterface::addSubscriber */ - public function addSubscriber(EventSubscriberInterface $subscriber) + public function addSubscriber(EventSubscriberInterface $subscriber): void { $this->getEventDispatcher()->addSubscriber($subscriber); } @@ -74,7 +66,7 @@ public function addSubscriber(EventSubscriberInterface $subscriber) * * @see EventDispatcherInterface::addListener */ - public function addListener($eventName, $listener, $priority = 0) + public function addListener($eventName, $listener, $priority = 0): void { $this->getEventDispatcher()->addListener($eventName, $listener, $priority); } @@ -84,7 +76,7 @@ public function addListener($eventName, $listener, $priority = 0) * * Adding the Events::PRE_HANDLE and Events::POST_HANDLE events. */ - public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true): Response + public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUEST, $catch = true): Response { // trigger loading the CacheEvent to avoid fatal error when HttpKernel::loadClassCache is used. class_exists(CacheEvent::class); @@ -102,10 +94,8 @@ class_exists(CacheEvent::class); * {@inheritdoc} * * Trigger event to alter response before storing it in the cache. - * - * @return void */ - protected function store(Request $request, Response $response) + protected function store(Request $request, Response $response): void { $response = $this->dispatch(Events::PRE_STORE, $request, $response); @@ -135,7 +125,7 @@ protected function invalidate(Request $request, $catch = false): Response * * @return Response|null The response to return, which might be provided/altered by a listener */ - protected function dispatch($name, Request $request, Response $response = null, $requestType = HttpKernelInterface::MASTER_REQUEST): ?Response + protected function dispatch(string $name, Request $request, Response $response = null, int $requestType = HttpKernelInterface::MAIN_REQUEST): ?Response { if ($this->getEventDispatcher()->hasListeners($name)) { $event = new CacheEvent($this, $request, $response, $requestType); diff --git a/src/SymfonyCache/KernelDispatcher.php b/src/SymfonyCache/KernelDispatcher.php index 16e96222..789adf24 100644 --- a/src/SymfonyCache/KernelDispatcher.php +++ b/src/SymfonyCache/KernelDispatcher.php @@ -32,22 +32,19 @@ */ class KernelDispatcher implements Dispatcher { - /** - * @var HttpCacheProvider - */ - private $httpCacheProvider; + private HttpCacheProvider $httpCacheProvider; /** - * @var array + * @var Request[] */ - private $queue = []; + private array $queue = []; public function __construct(HttpCacheProvider $httpCacheProvider) { $this->httpCacheProvider = $httpCacheProvider; } - public function invalidate(RequestInterface $invalidationRequest, $validateHost = true) + public function invalidate(RequestInterface $invalidationRequest, $validateHost = true): void { $request = Request::create( $invalidationRequest->getUri(), @@ -82,7 +79,7 @@ public function invalidate(RequestInterface $invalidationRequest, $validateHost $this->queue[sha1($request)] = $request; } - public function flush() + public function flush(): int { if (!count($this->queue)) { return 0; @@ -98,7 +95,7 @@ public function flush() foreach ($queue as $request) { try { - $httpCache->handle($request, HttpKernelInterface::MASTER_REQUEST, false); + $httpCache->handle($request, HttpKernelInterface::MAIN_REQUEST, false); } catch (\Exception $e) { $exceptions->add($e); } diff --git a/tests/Functional/Fixtures/Symfony/AppKernel.php b/tests/Functional/Fixtures/Symfony/AppKernel.php index 1e606b5b..5adef220 100644 --- a/tests/Functional/Fixtures/Symfony/AppKernel.php +++ b/tests/Functional/Fixtures/Symfony/AppKernel.php @@ -25,7 +25,7 @@ class AppKernel implements HttpKernelInterface * * {@inheritdoc} */ - public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true): Response + public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUEST, $catch = true): Response { switch ($request->getPathInfo()) { case '/cache': diff --git a/tests/Functional/Symfony/EventDispatchingHttpCacheTest.php b/tests/Functional/Symfony/EventDispatchingHttpCacheTest.php index f4a0e703..49a606e7 100644 --- a/tests/Functional/Symfony/EventDispatchingHttpCacheTest.php +++ b/tests/Functional/Symfony/EventDispatchingHttpCacheTest.php @@ -43,7 +43,7 @@ public function testEventListeners() $httpKernel = \Mockery::mock(HttpKernelInterface::class) ->shouldReceive('handle') - ->withArgs([$request, HttpKernelInterface::MASTER_REQUEST, true]) + ->withArgs([$request, HttpKernelInterface::MAIN_REQUEST, true]) ->andReturn($expectedResponse) ->getMock(); $store = \Mockery::mock(StoreInterface::class) diff --git a/tests/Functional/Varnish/UserContextFailureTest.php b/tests/Functional/Varnish/UserContextFailureTest.php index cc256ddf..ff33e556 100644 --- a/tests/Functional/Varnish/UserContextFailureTest.php +++ b/tests/Functional/Varnish/UserContextFailureTest.php @@ -32,7 +32,7 @@ public function setUp(): void { // needs to be decided before doing the setup // phpunit 9 calls the method getName(), phpunit 10 name() - $name = method_exists($this, 'name') ? $this->name() : $this->getName(); /* @phpstan-ignore-line */ + $name = method_exists($this, 'name') ? $this->name() : $this->getName(); $this->mode = 'testHashRequestFailure' === $name ? 'failure' : 'cache'; parent::setUp(); diff --git a/tests/Unit/SymfonyCache/CacheEventTest.php b/tests/Unit/SymfonyCache/CacheEventTest.php index 54507307..a44fcbc3 100644 --- a/tests/Unit/SymfonyCache/CacheEventTest.php +++ b/tests/Unit/SymfonyCache/CacheEventTest.php @@ -40,7 +40,7 @@ public function testEventGetters() $this->assertSame($this->kernel, $event->getKernel()); $this->assertSame($request, $event->getRequest()); $this->assertNull($event->getResponse()); - $this->assertSame(HttpKernelInterface::MASTER_REQUEST, $event->getRequestType()); + $this->assertSame(HttpKernelInterface::MAIN_REQUEST, $event->getRequestType()); $response = new Response(); diff --git a/tests/Unit/SymfonyCache/PurgeListenerTest.php b/tests/Unit/SymfonyCache/PurgeListenerTest.php index bee8f9c2..eb40c6e7 100644 --- a/tests/Unit/SymfonyCache/PurgeListenerTest.php +++ b/tests/Unit/SymfonyCache/PurgeListenerTest.php @@ -190,7 +190,7 @@ private function createRequestMatcher(string $path): RequestMatcherInterface { return class_exists(PathRequestMatcher::class) ? new PathRequestMatcher($path) - : new RequestMatcher($path) + : new RequestMatcher($path) /* @phpstan-ignore-line */ ; } diff --git a/tests/Unit/SymfonyCache/PurgeTagsListenerTest.php b/tests/Unit/SymfonyCache/PurgeTagsListenerTest.php index 56498b46..5077c232 100644 --- a/tests/Unit/SymfonyCache/PurgeTagsListenerTest.php +++ b/tests/Unit/SymfonyCache/PurgeTagsListenerTest.php @@ -19,6 +19,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestMatcher; +use Symfony\Component\HttpFoundation\RequestMatcher\PathRequestMatcher; +use Symfony\Component\HttpFoundation\RequestMatcherInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpCache\StoreInterface; use Toflar\Psr6HttpCacheStore\Psr6Store; @@ -43,7 +45,9 @@ public function testConstructorOverspecified() $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('You may not set both a request matcher and an IP'); new PurgeTagsListener([ - 'client_matcher' => new RequestMatcher('/forbidden'), + 'client_matcher' => class_exists(PathRequestMatcher::class) + ? new PathRequestMatcher('/forbidden') + : new RequestMatcher('/forbidden'), /* @phpstan-ignore-line */ 'client_ips' => ['1.2.3.4'], ]); } @@ -122,7 +126,9 @@ public function testPurgeForbiddenMatcher() { $kernel = $this->getUnusedKernelMock(); - $matcher = new RequestMatcher('/forbidden'); + $matcher = class_exists(PathRequestMatcher::class) + ? new PathRequestMatcher('/forbidden') + : new RequestMatcher('/forbidden'); /* @phpstan-ignore-line */ $purgeTagsListener = new PurgeTagsListener(['client_matcher' => $matcher]); $request = Request::create('http://example.com/foo', 'PURGETAGS'); $event = new CacheEvent($kernel, $request); @@ -155,7 +161,7 @@ public function testPurgeForbiddenIp() public function testOtherMethod() { $kernel = $this->getUnusedKernelMock(); - $matcher = \Mockery::mock(RequestMatcher::class) + $matcher = \Mockery::mock(RequestMatcherInterface::class) ->shouldNotReceive('isRequestAllowed') ->getMock(); diff --git a/tests/Unit/SymfonyCache/RefreshListenerTest.php b/tests/Unit/SymfonyCache/RefreshListenerTest.php index 6e6b8b0f..32588390 100644 --- a/tests/Unit/SymfonyCache/RefreshListenerTest.php +++ b/tests/Unit/SymfonyCache/RefreshListenerTest.php @@ -60,7 +60,7 @@ public function testRefreshForbiddenMatcher() $matcher = class_exists(PathRequestMatcher::class) ? new PathRequestMatcher('/forbidden') - : new RequestMatcher('/forbidden') + : new RequestMatcher('/forbidden') /* @phpstan-ignore-line */ ; $refreshListener = new RefreshListener(['client_matcher' => $matcher]); $request = Request::create('http://example.com/foo');