From 6740d5cb0b6f664cd3808b07dd0cc3feff57c372 Mon Sep 17 00:00:00 2001 From: Filis Futsarov Date: Fri, 21 Mar 2025 20:10:19 +0100 Subject: [PATCH 1/4] php8.4 support among other improvements --- .gitattributes | 16 ++++++++-------- .gitignore | 2 ++ .phpstan-baseline.neon | 33 ++++++++++++++++++++++++++++++++ .phpstan.neon | 11 +++++++++++ LICENSE | 2 +- composer.json | 16 ++++++++-------- phpcs.xml | 16 ++++++++++++++++ phpunit.xml | 18 +++++++++++++++++ src/CallableHandler.php | 2 ++ src/Dispatcher.php | 6 +++++- src/Factory.php | 3 ++- src/FactoryDiscovery.php | 11 +++++++---- src/HttpErrorException.php | 8 ++++++-- src/RequestHandlerContainer.php | 11 +++++++++-- tests/CallableHandlerTest.php | 5 +++-- tests/DispatcherTest.php | 1 + tests/HttpErrorExceptionTest.php | 2 ++ 17 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 .phpstan-baseline.neon create mode 100644 .phpstan.neon create mode 100644 phpcs.xml create mode 100644 phpunit.xml diff --git a/.gitattributes b/.gitattributes index c540470..b67c7ca 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,10 +1,10 @@ * text=auto eol=lf -/tests export-ignore -.editorconfig export-ignore -.gitattributes export-ignore -.gitignore export-ignore -.php_cs export-ignore -.travis.yml export-ignore -phpcs.xml.dist export-ignore -phpunit.xml.dist export-ignore +/tests export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.php-cs-fixer.php export-ignore +phpcs.xml.dist export-ignore +phpunit.xml.dist export-ignore +.phpstan.neon export-ignore diff --git a/.gitignore b/.gitignore index 364d1a4..5ae8693 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ vendor composer.lock coverage *.cache +.idea +kit diff --git a/.phpstan-baseline.neon b/.phpstan-baseline.neon new file mode 100644 index 0000000..e33e0d8 --- /dev/null +++ b/.phpstan-baseline.neon @@ -0,0 +1,33 @@ +parameters: + ignoreErrors: + - + identifier: "new.static" + - + message: "#^Negated boolean expression is always false\\.$#" + count: 1 + path: src/Factory.php + + - + message: "#^Method Middlewares\\\\Utils\\\\FactoryDiscovery\\:\\:getFactory\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FactoryDiscovery.php + + - + message: "#^Parameter \\#1 \\$class of function class_exists expects string, array\\\\|string given\\.$#" + count: 1 + path: src/FactoryDiscovery.php + + - + message: "#^Property Middlewares\\\\Utils\\\\FactoryDiscovery\\:\\:\\$factory has no type specified\\.$#" + count: 1 + path: src/FactoryDiscovery.php + + - + message: "#^Unsafe usage of new static\\(\\)\\.$#" + count: 1 + path: src/HttpErrorException.php + + - + message: "#^Method Middlewares\\\\Utils\\\\RequestHandlerContainer\\:\\:resolve\\(\\) has no return type specified\\.$#" + count: 1 + path: src/RequestHandlerContainer.php diff --git a/.phpstan.neon b/.phpstan.neon new file mode 100644 index 0000000..e67734d --- /dev/null +++ b/.phpstan.neon @@ -0,0 +1,11 @@ +parameters: + treatPhpDocTypesAsCertain: false + reportUnmatchedIgnoredErrors: false + inferPrivatePropertyTypeFromConstructor: true + level: 8 + paths: + - src + - tests + +includes: + - .phpstan-baseline.neon diff --git a/LICENSE b/LICENSE index 017c0cd..374fb13 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2019 +Copyright (c) 2019-2025 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/composer.json b/composer.json index cb08d2b..84a01b4 100644 --- a/composer.json +++ b/composer.json @@ -18,17 +18,17 @@ "require": { "php": ">=8.1", "psr/http-message": "^1.0 || ^2.0", - "psr/http-server-middleware": "^1.0", + "psr/http-server-middleware": "^1", "psr/container": "^1.0 || ^2.0", "psr/http-factory": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^10.5", - "phpstan/phpstan": "^1.10", - "laminas/laminas-diactoros": "^3.3", - "friendsofphp/php-cs-fixer": "^3.41", - "oscarotero/php-cs-fixer-config": "^2.0", - "squizlabs/php_codesniffer": "^3.8", + "phpunit/phpunit": "^10", + "phpstan/phpstan": "^2", + "laminas/laminas-diactoros": "^3", + "friendsofphp/php-cs-fixer": "^3", + "oscarotero/php-cs-fixer-config": "^2", + "squizlabs/php_codesniffer": "^3", "slim/psr7": "^1.6", "guzzlehttp/psr7": "^2.6", "sunrise/http-message": "^3.0", @@ -52,4 +52,4 @@ "coverage": "phpunit --coverage-text", "coverage-html": "phpunit --coverage-html=coverage" } -} +} \ No newline at end of file diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..7814331 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,16 @@ + + + Middlewares coding standard + + + + + + + + + + + src + tests + diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..9d272da --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,18 @@ + + + + + + tests + + + + + ./src + + + ./tests + ./vendor + + + diff --git a/src/CallableHandler.php b/src/CallableHandler.php index 52dd551..2f2eccc 100644 --- a/src/CallableHandler.php +++ b/src/CallableHandler.php @@ -58,6 +58,8 @@ public function __invoke(): ResponseInterface /** * Execute the callable. + * + * @param array $arguments */ private function execute(array $arguments = []): ResponseInterface { diff --git a/src/Dispatcher.php b/src/Dispatcher.php index 2669983..33f4558 100644 --- a/src/Dispatcher.php +++ b/src/Dispatcher.php @@ -12,11 +12,12 @@ class Dispatcher implements RequestHandlerInterface { - /** @var array */ private $stack; /** * Static helper to create and dispatch a request. + * + * @param CallableHandler[]|MiddlewareInterface[]|callable[] $stack */ public static function run(array $stack, ?ServerRequestInterface $request = null): ResponseInterface { @@ -27,6 +28,9 @@ public static function run(array $stack, ?ServerRequestInterface $request = null return (new static($stack))->dispatch($request); } + /** + * @param CallableHandler[]|MiddlewareInterface[]|callable[] $stack + */ public function __construct(array $stack) { $this->stack = $stack; diff --git a/src/Factory.php b/src/Factory.php index db72538..384270d 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -67,7 +67,8 @@ public static function getServerRequestFactory(): ServerRequestFactoryInterface } /** - * @param UriInterface|string $uri + * @param UriInterface|string $uri + * @param array $serverParams */ public static function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface { diff --git a/src/FactoryDiscovery.php b/src/FactoryDiscovery.php index 87c7484..b284c49 100644 --- a/src/FactoryDiscovery.php +++ b/src/FactoryDiscovery.php @@ -52,7 +52,7 @@ class FactoryDiscovery implements FactoryInterface 'uri' => '\Sunrise\Http\Message\UriFactory', ]; - /** @var array|string> */ + /** @var array */ private $strategies = [ self::DIACTOROS, self::GUZZLE, @@ -63,11 +63,11 @@ class FactoryDiscovery implements FactoryInterface private $factory; - /** @var array */ + /** @var array */ private $factories = []; /** - * @param array $strategies + * @param array $strategies */ public function __construct(...$strategies) { @@ -78,6 +78,8 @@ public function __construct(...$strategies) /** * Get the strategies + * + * @return array */ public function getStrategies(): array { @@ -149,6 +151,7 @@ public function getUriFactory(): UriFactoryInterface */ private function getFactory(string $type) { + var_dump($this->factories); if (!empty($this->factories[$type])) { return $this->factories[$type]; } @@ -160,7 +163,6 @@ private function getFactory(string $type) foreach ($this->strategies as $className) { if (is_array($className) && isset($className[$type])) { $className = $className[$type]; - if (class_exists($className)) { return $this->factories[$type] = new $className(); } @@ -168,6 +170,7 @@ private function getFactory(string $type) continue; } + /* @phpstan-ignore-next-line */ if (!class_exists($className)) { continue; } diff --git a/src/HttpErrorException.php b/src/HttpErrorException.php index e542388..a852e17 100644 --- a/src/HttpErrorException.php +++ b/src/HttpErrorException.php @@ -58,13 +58,14 @@ class HttpErrorException extends Exception 599 => 'Network Connect Timeout Error', ]; - /** @var array */ + /** @var array */ private $context = []; /** * Create and returns a new instance * - * @param int $code A valid http error code + * @param int $code A valid http error code + * @param array $context */ public static function create(int $code = 500, array $context = [], ?Throwable $previous = null): self { @@ -78,6 +79,9 @@ public static function create(int $code = 500, array $context = [], ?Throwable $ return $exception; } + /** + * @return array + */ public function getContext(): array { return $this->context; diff --git a/src/RequestHandlerContainer.php b/src/RequestHandlerContainer.php index 346437a..0befd1f 100644 --- a/src/RequestHandlerContainer.php +++ b/src/RequestHandlerContainer.php @@ -16,9 +16,12 @@ */ class RequestHandlerContainer implements ContainerInterface { - /** @var array */ + /** @var mixed[] */ protected $constructorArguments; + /** + * @param mixed[] $constructorArguments + */ public function __construct(array $constructorArguments = []) { $this->constructorArguments = $constructorArguments; @@ -36,7 +39,7 @@ public function has($id): bool } /** - * @param string $id + * @param class-string|string $id * @return RequestHandlerInterface */ public function get($id) @@ -58,6 +61,10 @@ public function get($id) } } + /** + * @param class-string|string $handler + * @return mixed + */ protected function resolve(string $handler) { $handler = $this->split($handler); diff --git a/tests/CallableHandlerTest.php b/tests/CallableHandlerTest.php index 4e7b963..6644616 100644 --- a/tests/CallableHandlerTest.php +++ b/tests/CallableHandlerTest.php @@ -3,6 +3,7 @@ namespace Middlewares\Tests; +use Exception; use Middlewares\Utils\CallableHandler; use Middlewares\Utils\Factory; use PHPUnit\Framework\TestCase; @@ -53,7 +54,7 @@ public function testOb(): void echo 'Hello'; ob_start(); echo 'Hello'; - throw new \Exception('Error Processing Request'); + throw new Exception('Error Processing Request'); }); ob_start(); @@ -61,7 +62,7 @@ public function testOb(): void try { $callable(); - } catch (\Exception $e) { + } catch (Exception $e) { } self::assertSame($level, ob_get_level()); diff --git a/tests/DispatcherTest.php b/tests/DispatcherTest.php index 58b1eea..99eabc4 100644 --- a/tests/DispatcherTest.php +++ b/tests/DispatcherTest.php @@ -54,6 +54,7 @@ public function testMiddlewareException(): void { $this->expectException('UnexpectedValueException'); + /** @phpstan-ignore-next-line */ $response = Dispatcher::run(['']); } } diff --git a/tests/HttpErrorExceptionTest.php b/tests/HttpErrorExceptionTest.php index 0cfbf15..4c2f999 100644 --- a/tests/HttpErrorExceptionTest.php +++ b/tests/HttpErrorExceptionTest.php @@ -1,5 +1,7 @@ Date: Fri, 21 Mar 2025 20:24:51 +0100 Subject: [PATCH 2/4] cleanup --- src/FactoryDiscovery.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/FactoryDiscovery.php b/src/FactoryDiscovery.php index b284c49..362e17a 100644 --- a/src/FactoryDiscovery.php +++ b/src/FactoryDiscovery.php @@ -151,7 +151,6 @@ public function getUriFactory(): UriFactoryInterface */ private function getFactory(string $type) { - var_dump($this->factories); if (!empty($this->factories[$type])) { return $this->factories[$type]; } From e02dae12b215ca399b2657f8202d850b7a692e3c Mon Sep 17 00:00:00 2001 From: Filis Futsarov Date: Fri, 21 Mar 2025 22:12:46 +0100 Subject: [PATCH 3/4] update github workflow --- .github/workflows/main.yaml | 39 +++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index ed44f76..5d14a59 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -1,10 +1,10 @@ name: "testing" on: - push: - branches: [ master ] - pull_request: - branches: [ master ] + push: + branches: [ master ] + pull_request: + branches: [ master ] jobs: qa: @@ -20,16 +20,16 @@ jobs: - name: Cache Composer packages id: composer-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: - path: vendor - key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-php- + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer install --prefer-dist --no-progress --no-suggest + run: composer install --prefer-dist --no-progress - name: Coding Standard run: composer run-script cs @@ -40,11 +40,15 @@ jobs: strategy: matrix: - php: - - 8.1 - - 8.2 - - 8.3 - - 8.4 + php: + - 7.2 + - 7.3 + - 7.4 + - 8.0 + - 8.1 + - 8.2 + - 8.3 + - 8.4 steps: - name: Checkout @@ -63,10 +67,7 @@ jobs: restore-keys: ${{ runner.os }}-php-${{ matrix.php }}-composer- - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-suggest + run: composer install --prefer-dist --no-progress - name: Tests run: composer test - - - name: Tests coverage - run: composer coverage From a4d84482dcbefe778530ebedac3167a7dba1bb5a Mon Sep 17 00:00:00 2001 From: Filis Futsarov Date: Fri, 21 Mar 2025 22:28:36 +0100 Subject: [PATCH 4/4] update workflow --- .github/workflows/main.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 5d14a59..a2458c8 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -41,10 +41,6 @@ jobs: strategy: matrix: php: - - 7.2 - - 7.3 - - 7.4 - - 8.0 - 8.1 - 8.2 - 8.3