diff --git a/composer.json b/composer.json index d7506f891..0cc6b3a51 100644 --- a/composer.json +++ b/composer.json @@ -5,8 +5,9 @@ }, "config": { "allow-plugins": { - "sculpin/sculpin-theme-composer-plugin": true - } + "sculpin/sculpin-theme-composer-plugin": true, + "phpstan/extension-installer": true + } }, "autoload": { "psr-4": { @@ -19,6 +20,9 @@ } }, "require-dev": { - "phpunit/phpunit": "^12.1" + "phpunit/phpunit": "^12.1", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-strict-rules": "^2.0", + "phpstan/extension-installer": "^1.4" } } diff --git a/composer.lock b/composer.lock index 534b5ea08..c4b484ca1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c72e9dc8c2e53aee1883b80259d8890f", + "content-hash": "c0c52dda2be448215af08587bbcd86c5", "packages": [ { "name": "dflydev/ant-path-matcher", @@ -3792,6 +3792,160 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "phpstan/extension-installer", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.4.3" + }, + "time": "2024-09-04T20:21:43+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.14", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "8f2e03099cac24ff3b379864d171c5acbfc6b9a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8f2e03099cac24ff3b379864d171c5acbfc6b9a2", + "reference": "8f2e03099cac24ff3b379864d171c5acbfc6b9a2", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-05-02T15:32:28+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/3e139cbe67fafa3588e1dbe27ca50f31fdb6236a", + "reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0.4" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.4" + }, + "time": "2025-03-18T11:42:40+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "12.2.1", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 000000000..3a319e890 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,19 @@ +parameters: + ignoreErrors: + - + message: '#^Dynamic call to static method PHPUnit\\Framework\\Assert\:\:identicalTo\(\)\.$#' + identifier: staticMethod.dynamicCall + count: 1 + path: tests/Presentation/TwigExtension/PresentationTwigExtensionTest.php + + - + message: '#^Static method PHPUnit\\Framework\\Assert\:\:assertSame\(\) invoked with named argument \$actual, but it''s not allowed because of @no\-named\-arguments\.$#' + identifier: argument.named + count: 1 + path: tests/Presentation/TwigExtension/PresentationTwigExtensionTest.php + + - + message: '#^Static method PHPUnit\\Framework\\Assert\:\:assertSame\(\) invoked with named argument \$expected, but it''s not allowed because of @no\-named\-arguments\.$#' + identifier: argument.named + count: 1 + path: tests/Presentation/TwigExtension/PresentationTwigExtensionTest.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 000000000..550f66f59 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,7 @@ +parameters: + level: 5 + paths: + - src + - tests +includes: + - phpstan-baseline.neon diff --git a/src/Presentation/Collection/AbstractCollection.php b/src/Presentation/Collection/Collection.php similarity index 73% rename from src/Presentation/Collection/AbstractCollection.php rename to src/Presentation/Collection/Collection.php index eba26ba3b..a4a0801a0 100644 --- a/src/Presentation/Collection/AbstractCollection.php +++ b/src/Presentation/Collection/Collection.php @@ -9,9 +9,15 @@ use Countable; use Iterator; use IteratorAggregate; -abstract class AbstractCollection implements Countable, IteratorAggregate +/** + * @template TItem + */ +class Collection implements Countable, IteratorAggregate { - public function __construct(protected array $items = []) + /** + * @param TItem[] $items + */ + final public function __construct(protected array $items = []) { } @@ -35,6 +41,9 @@ abstract class AbstractCollection implements Countable, IteratorAggregate return new ArrayIterator($this->items); } + /** + * @return TItem[] + */ public function toArray(): array { return $this->items; diff --git a/src/Presentation/Collection/EventCollection.php b/src/Presentation/Collection/EventCollection.php deleted file mode 100644 index 47bd86b26..000000000 --- a/src/Presentation/Collection/EventCollection.php +++ /dev/null @@ -1,9 +0,0 @@ -items, @@ -21,10 +21,10 @@ final class PresentationCollection extends AbstractCollection initial: [], ); - return new EventCollection(array_merge(...$events)); + return new Collection(array_merge(...$events)); } - public function getPastEvents(): EventCollection + public function getPastEvents(): Collection { $today = new DateTimeImmutable('today');