diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 439fde2..f44b0eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,26 @@ jobs: secrets: inherit cs-stan: - uses: cakephp/.github/.github/workflows/cs-stan.yml@5.x - secrets: inherit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: mbstring, intl + coverage: none + tools: composer:v2 + + - name: Composer install + run: | + composer install --no-progress --prefer-dist --optimize-autoloader + + - name: Install PHPStan + run: | + composer require --dev phpstan/phpstan + + - name: Run phpstan + run: | + vendor/bin/phpstan analyse --error-format=github --configuration=phpstan.neon diff --git a/composer.json b/composer.json index 6ad2f87..523a7aa 100644 --- a/composer.json +++ b/composer.json @@ -30,8 +30,7 @@ }, "require-dev": { "phpunit/phpunit": "^10.1.0", - "cakephp/cakephp-codesniffer": "^5.0", - "vimeo/psalm": "^5.15" + "cakephp/cakephp-codesniffer": "^5.0" }, "autoload": { "psr-4": { diff --git a/phpstan.neon b/phpstan.neon index c538d25..59f7883 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,8 +3,6 @@ includes: parameters: level: 8 - checkMissingIterableValueType: false - checkGenericClassInNonGenericObjectType: false treatPhpDocTypesAsCertain: false paths: - src/ diff --git a/src/Routing/Middleware/CachedRoutingMiddleware.php b/src/Routing/Middleware/CachedRoutingMiddleware.php index 6a1b5a1..6a3b07c 100644 --- a/src/Routing/Middleware/CachedRoutingMiddleware.php +++ b/src/Routing/Middleware/CachedRoutingMiddleware.php @@ -75,9 +75,14 @@ protected function buildRouteCollection(): RouteCollection { if (Cache::enabled() && $this->cacheConfig !== null) { try { - return Cache::remember(static::ROUTE_COLLECTION_CACHE_KEY, function () { + $cached = Cache::remember(static::ROUTE_COLLECTION_CACHE_KEY, function () { return $this->prepareRouteCollection(); }, $this->cacheConfig); + if ($cached instanceof RouteCollection) { + return $cached; + } else { + Cache::delete(static::ROUTE_COLLECTION_CACHE_KEY, $this->cacheConfig); + } } catch (InvalidArgumentException $e) { throw $e; } catch (Exception $e) { @@ -86,7 +91,7 @@ protected function buildRouteCollection(): RouteCollection middleware or other unserializable settings in your routes. The original exception message can show what type of object failed to serialize.', null, - $e + $e, ); } } diff --git a/tests/TestCase/Routing/Middleware/CachedRoutingMiddlewareTest.php b/tests/TestCase/Routing/Middleware/CachedRoutingMiddlewareTest.php index b813832..65d0b9f 100644 --- a/tests/TestCase/Routing/Middleware/CachedRoutingMiddlewareTest.php +++ b/tests/TestCase/Routing/Middleware/CachedRoutingMiddlewareTest.php @@ -14,9 +14,11 @@ namespace CakeDC\CachedRouting\Test\TestCase\Routing\Middleware; use Cake\Cache\Cache; +use Cake\Http\Response; use Cake\Http\ServerRequestFactory; use Cake\Routing\RouteBuilder; use Cake\Routing\RouteCollection; +use Cake\Routing\Router; use Cake\TestSuite\TestCase; use CakeDC\CachedRouting\Routing\Exception\FailedRouteCacheException; use CakeDC\CachedRouting\Routing\Middleware\CachedRoutingMiddleware; @@ -76,4 +78,27 @@ public function testFailedRouteCache(): void $this->expectExceptionMessage('Unable to cache route collection.'); $middleware->process($request, new TestRequestHandler()); } + + /** + * Test that when cache returns a non-RouteCollection value, it gets deleted and a new RouteCollection is created. + */ + public function testInvalidCachedValue(): void + { + $cacheConfigName = '_cake_router_'; + Cache::setConfig($cacheConfigName, [ + 'engine' => 'File', + 'path' => CACHE, + ]); + + Cache::write(CachedRoutingMiddleware::ROUTE_COLLECTION_CACHE_KEY, 'not a route collection', $cacheConfigName); + $this->assertEquals('not a route collection', Cache::read(CachedRoutingMiddleware::ROUTE_COLLECTION_CACHE_KEY, $cacheConfigName)); + + $request = ServerRequestFactory::fromGlobals(['REQUEST_URI' => '/articles']); + $middleware = new CachedRoutingMiddleware(new Application(), $cacheConfigName); + $response = $middleware->process($request, new TestRequestHandler()); + + $this->assertInstanceOf(Response::class, $response); + $this->assertNull(Cache::read(CachedRoutingMiddleware::ROUTE_COLLECTION_CACHE_KEY, $cacheConfigName)); + $this->assertInstanceOf(RouteCollection::class, Router::getRouteCollection()); + } }