From 84ac2c33c57b7c0b79046a76bfafafbd7e2560b4 Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Wed, 4 Jun 2025 16:55:44 +0200 Subject: [PATCH 1/9] 4268: Replaced Psaml with PHPStan --- .github/workflows/pr.yaml | 6 +- .gitignore | 4 + CHANGELOG.md | 2 + Taskfile.yml | 12 +- composer.json | 13 +- composer.lock | 849 ++++++++------------------------------ phpstan.dist.neon | 8 + psalm-baseline.xml | 117 ------ psalm.xml | 25 -- symfony.lock | 12 + 10 files changed, 221 insertions(+), 827 deletions(-) create mode 100644 phpstan.dist.neon delete mode 100644 psalm-baseline.xml delete mode 100644 psalm.xml diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 3c48e79..84ea1fa 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -48,9 +48,9 @@ jobs: - name: Check that nothing has changed run: git diff --exit-code - psalm: + code-analysis-phpstan: runs-on: ubuntu-latest - name: Psalm static analysis + name: PHPStan static analysis steps: - uses: actions/checkout@v4 @@ -63,7 +63,7 @@ jobs: - name: Run code analysis run: | - task --yes code-analysis:psalm + task --yes code-analysis:phpstan apispec: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 69c301b..0f3aac4 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,7 @@ ###< vincentlanglet/twig-cs-fixer ### .phpunit.cache + +###> phpstan/phpstan ### +phpstan.neon +###< phpstan/phpstan ### diff --git a/CHANGELOG.md b/CHANGELOG.md index a31091a..34ac90b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ See [keep a changelog] for information about writing changes to this log. - Added simple API tests and resolved some deprecations - Upgraded to API platform v4 - Updated composer packages (security update) and recipes + - Replaces [Psalm](https://psalm.dev/) with [PHPStan](https://phpstan.org/) (via + ). ## [1.1.1] - 2025-03-28 diff --git a/Taskfile.yml b/Taskfile.yml index 815d089..9c55b4a 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -175,12 +175,18 @@ tasks: COMPOSE_ARGS: run --rm prettier {{.YAML_FILES_GLOB}} --check silent: true - code-analysis:psalm: - desc: "Run PSalm" + code-analysis: + desc: "Run code analysis" + cmds: + - task: code-analysis:phpstan + silent: true + + code-analysis:phpstan: + desc: "Run PHPStan" cmds: - task: compose vars: - COMPOSE_ARGS: exec phpfpm vendor/bin/psalm --no-cache + COMPOSE_ARGS: exec phpfpm vendor/bin/phpstan silent: true apispec:export: diff --git a/composer.json b/composer.json index 7ce3357..11f601a 100644 --- a/composer.json +++ b/composer.json @@ -31,16 +31,15 @@ "require-dev": { "ergebnis/composer-normalize": "^2.47", "friendsofphp/php-cs-fixer": "^3.40", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan-symfony": "^2.0", "phpunit/phpunit": "^10.5", - "psalm/plugin-symfony": "^5.1", "symfony/browser-kit": "~6.4.0", "symfony/maker-bundle": "^1.52", "symfony/phpunit-bridge": "^7.3", "symfony/stopwatch": "~6.4.0", "symfony/web-profiler-bundle": "~6.4.0", - "vimeo/psalm": "^5.16", - "vincentlanglet/twig-cs-fixer": "^3.7", - "weirdan/doctrine-psalm-plugin": "^2.9" + "vincentlanglet/twig-cs-fixer": "^3.7" }, "replace": { "symfony/polyfill-ctype": "*", @@ -70,6 +69,7 @@ "allow-plugins": { "ergebnis/composer-normalize": true, "php-http/discovery": true, + "phpstan/extension-installer": true, "symfony/flex": true, "symfony/runtime": true }, @@ -77,7 +77,7 @@ }, "extra": { "symfony": { - "allow-contrib": false, + "allow-contrib": true, "require": "6.4.*" } }, @@ -100,9 +100,6 @@ ], "coding-standards-check": [ "PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix --dry-run" - ], - "psalm": [ - "./vendor/bin/psalm --no-cache" ] } } diff --git a/composer.lock b/composer.lock index c65c960..ae4d405 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": "8f4a44f5fd1c8a1784ace5dffea1ec95", + "content-hash": "734d7df34f96b86a919c53bf4fe0519b", "packages": [ { "name": "api-platform/core", @@ -5990,166 +5990,6 @@ } ], "packages-dev": [ - { - "name": "amphp/amp", - "version": "v2.6.4", - "source": { - "type": "git", - "url": "https://github.com/amphp/amp.git", - "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", - "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "react/promise": "^2", - "vimeo/psalm": "^3.12" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php", - "lib/Internal/functions.php" - ], - "psr-4": { - "Amp\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", - "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.4" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-03-21T18:52:26+00:00" - }, - { - "name": "amphp/byte-stream", - "version": "v1.8.2", - "source": { - "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc", - "shasum": "" - }, - "require": { - "amphp/amp": "^2", - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" - }, - "type": "library", - "autoload": { - "files": [ - "lib/functions.php" - ], - "psr-4": { - "Amp\\ByteStream\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "https://amphp.org/byte-stream", - "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" - ], - "support": { - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.2" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-04-13T18:00:56+00:00" - }, { "name": "clue/ndjson-react", "version": "v1.3.0", @@ -6440,43 +6280,6 @@ ], "time": "2024-05-06T16:37:16+00:00" }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" - }, - "time": "2019-12-04T15:06:13+00:00" - }, { "name": "ergebnis/composer-normalize", "version": "2.47.0", @@ -6972,107 +6775,6 @@ }, "time": "2023-08-08T05:53:35+00:00" }, - { - "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.1", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "shasum": "" - }, - "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "AdvancedJsonRpc\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "A more advanced JSONRPC implementation", - "support": { - "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" - }, - "time": "2021-06-11T22:34:44+00:00" - }, - { - "name": "felixfbecker/language-server-protocol", - "version": "v1.5.3", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/a9e113dbc7d849e35b8776da39edaf4313b7b6c9", - "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "^3.1", - "vimeo/psalm": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "LanguageServerProtocol\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "PHP classes for the Language Server Protocol", - "keywords": [ - "language", - "microsoft", - "php", - "server" - ], - "support": { - "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", - "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.3" - }, - "time": "2024-04-30T00:40:11+00:00" - }, { "name": "fidry/cpu-core-counter", "version": "1.2.0", @@ -7568,57 +7270,6 @@ ], "time": "2025-04-29T12:36:36+00:00" }, - { - "name": "netresearch/jsonmapper", - "version": "v4.5.0", - "source": { - "type": "git", - "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8e76efb98ee8b6afc54687045e1b8dba55ac76e5", - "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", - "squizlabs/php_codesniffer": "~3.5" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsonMapper": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0" - ], - "authors": [ - { - "name": "Christian Weiske", - "email": "cweiske@cweiske.de", - "homepage": "http://github.com/cweiske/jsonmapper/", - "role": "Developer" - } - ], - "description": "Map nested JSON structures onto PHP classes", - "support": { - "email": "cweiske@cweiske.de", - "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.5.0" - }, - "time": "2024-09-08T10:13:13+00:00" - }, { "name": "nikic/php-parser", "version": "v4.19.4", @@ -7793,6 +7444,183 @@ }, "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.17", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053", + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053", + "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-21T20:55:28+00:00" + }, + { + "name": "phpstan/phpstan-symfony", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-symfony.git", + "reference": "5005288e07583546ea00b52de4a9ac412eb869d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/5005288e07583546ea00b52de4a9ac412eb869d7", + "reference": "5005288e07583546ea00b52de4a9ac412eb869d7", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.13" + }, + "conflict": { + "symfony/framework-bundle": "<3.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "psr/container": "1.1.2", + "symfony/config": "^5.4 || ^6.1", + "symfony/console": "^5.4 || ^6.1", + "symfony/dependency-injection": "^5.4 || ^6.1", + "symfony/form": "^5.4 || ^6.1", + "symfony/framework-bundle": "^5.4 || ^6.1", + "symfony/http-foundation": "^5.4 || ^6.1", + "symfony/messenger": "^5.4", + "symfony/polyfill-php80": "^1.24", + "symfony/serializer": "^5.4", + "symfony/service-contracts": "^2.2.0" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lukáš Unger", + "email": "looky.msc@gmail.com", + "homepage": "https://lookyman.net" + } + ], + "description": "Symfony Framework extensions and rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-symfony/issues", + "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.6" + }, + "time": "2025-05-14T07:00:05+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "10.1.16", @@ -8223,71 +8051,6 @@ ], "time": "2025-05-02T06:46:24+00:00" }, - { - "name": "psalm/plugin-symfony", - "version": "v5.2.6", - "source": { - "type": "git", - "url": "https://github.com/psalm/psalm-plugin-symfony.git", - "reference": "1638f172b4ae5f283ee6b1b58fff3e44aa628742" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-symfony/zipball/1638f172b4ae5f283ee6b1b58fff3e44aa628742", - "reference": "1638f172b4ae5f283ee6b1b58fff3e44aa628742", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "php": "^8.1", - "symfony/framework-bundle": "^5.0 || ^6.0 || ^7.0", - "vimeo/psalm": "^5.16 || dev-master" - }, - "require-dev": { - "doctrine/annotations": "^1.8|^2", - "doctrine/orm": "^2.9", - "phpunit/phpunit": "~7.5 || ~9.5", - "symfony/cache-contracts": "^1.0 || ^2.0", - "symfony/console": "*", - "symfony/form": "^5.0 || ^6.0 || ^7.0", - "symfony/messenger": "^5.0 || ^6.0 || ^7.0", - "symfony/security-core": "*", - "symfony/serializer": "^5.0 || ^6.0 || ^7.0", - "symfony/validator": "*", - "twig/twig": "^2.10 || ^3.0", - "weirdan/codeception-psalm-module": "dev-master" - }, - "suggest": { - "weirdan/doctrine-psalm-plugin": "If Doctrine is used, it is recommended install this plugin" - }, - "type": "psalm-plugin", - "extra": { - "psalm": { - "pluginClass": "Psalm\\SymfonyPsalmPlugin\\Plugin" - } - }, - "autoload": { - "psr-4": { - "Psalm\\SymfonyPsalmPlugin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Farhad Safarov", - "email": "farhad.safarov@gmail.com" - } - ], - "description": "Psalm Plugin for Symfony", - "support": { - "issues": "https://github.com/psalm/psalm-plugin-symfony/issues", - "source": "https://github.com/psalm/psalm-plugin-symfony/tree/v5.2.6" - }, - "time": "2024-12-21T08:46:26+00:00" - }, { "name": "react/cache", "version": "v1.2.0", @@ -9730,74 +9493,6 @@ ], "time": "2023-02-07T11:34:05+00:00" }, - { - "name": "spatie/array-to-xml", - "version": "3.4.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/array-to-xml.git", - "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", - "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "php": "^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.2", - "pestphp/pest": "^1.21", - "spatie/pest-plugin-snapshots": "^1.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Spatie\\ArrayToXml\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://freek.dev", - "role": "Developer" - } - ], - "description": "Convert an array to xml", - "homepage": "https://github.com/spatie/array-to-xml", - "keywords": [ - "array", - "convert", - "xml" - ], - "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.4.0" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2024-12-16T12:45:15+00:00" - }, { "name": "symfony/browser-kit", "version": "v6.4.19", @@ -10429,116 +10124,6 @@ ], "time": "2024-03-03T12:36:25+00:00" }, - { - "name": "vimeo/psalm", - "version": "5.26.1", - "source": { - "type": "git", - "url": "https://github.com/vimeo/psalm.git", - "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", - "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", - "shasum": "" - }, - "require": { - "amphp/amp": "^2.4.2", - "amphp/byte-stream": "^1.5", - "composer-runtime-api": "^2", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^2.0 || ^3.0", - "dnoegel/php-xdg-base-dir": "^0.1.1", - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.1", - "felixfbecker/language-server-protocol": "^1.5.2", - "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "nikic/php-parser": "^4.17", - "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", - "sebastian/diff": "^4.0 || ^5.0 || ^6.0", - "spatie/array-to-xml": "^2.17.0 || ^3.0", - "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0" - }, - "conflict": { - "nikic/php-parser": "4.17.0" - }, - "provide": { - "psalm/psalm": "self.version" - }, - "require-dev": { - "amphp/phpunit-util": "^2.0", - "bamarni/composer-bin-plugin": "^1.4", - "brianium/paratest": "^6.9", - "ext-curl": "*", - "mockery/mockery": "^1.5", - "nunomaduro/mock-final-classes": "^1.1", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpdoc-parser": "^1.6", - "phpunit/phpunit": "^9.6", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^4.4 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "ext-curl": "In order to send data to shepherd", - "ext-igbinary": "^2.0.5 is required, used to serialize caching data" - }, - "bin": [ - "psalm", - "psalm-language-server", - "psalm-plugin", - "psalm-refactor", - "psalter" - ], - "type": "project", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev", - "dev-2.x": "2.x-dev", - "dev-3.x": "3.x-dev", - "dev-4.x": "4.x-dev", - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psalm\\": "src/Psalm/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthew Brown" - } - ], - "description": "A static analysis tool for finding errors in PHP applications", - "keywords": [ - "code", - "inspection", - "php", - "static analysis" - ], - "support": { - "docs": "https://psalm.dev/docs", - "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm" - }, - "time": "2024-09-08T18:53:08+00:00" - }, { "name": "vincentlanglet/twig-cs-fixer", "version": "3.7.1", @@ -10615,84 +10200,6 @@ } ], "time": "2025-05-19T12:24:50+00:00" - }, - { - "name": "weirdan/doctrine-psalm-plugin", - "version": "v2.9.0", - "source": { - "type": "git", - "url": "https://github.com/psalm/psalm-plugin-doctrine.git", - "reference": "3db8e55b2ea15373338d2a3eab71c5f5a31c8b08" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-doctrine/zipball/3db8e55b2ea15373338d2a3eab71c5f5a31c8b08", - "reference": "3db8e55b2ea15373338d2a3eab71c5f5a31c8b08", - "shasum": "" - }, - "require": { - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "php": "^7.2 || ^8", - "vimeo/psalm": "^4.28|^5.0" - }, - "conflict": { - "doctrine/collections": "<1.8", - "doctrine/orm": "<2.6", - "doctrine/persistence": "<2.0" - }, - "require-dev": { - "codeception/codeception": "^4.0", - "doctrine/coding-standard": "^9.0", - "doctrine/collections": "^1.8 || ^2.0", - "doctrine/doctrine-bundle": "^1.11 || ^2.0", - "doctrine/orm": "^2.6", - "doctrine/persistence": "^2.0", - "phly/keep-a-changelog": "^2.1", - "squizlabs/php_codesniffer": "^3.3", - "weirdan/codeception-psalm-module": "^0.13.1" - }, - "type": "psalm-plugin", - "extra": { - "psalm": { - "pluginClass": "Weirdan\\DoctrinePsalmPlugin\\Plugin" - } - }, - "autoload": { - "psr-4": { - "Weirdan\\DoctrinePsalmPlugin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bruce Weirdan", - "email": "weirdan@gmail.com" - } - ], - "description": "Stubs to let Psalm understand Doctrine better", - "keywords": [ - "code", - "dbal", - "doctrine", - "doctrine2", - "extension", - "inspection", - "orm", - "php", - "plugin", - "psalm", - "psalm-plugin", - "static analysis", - "static-analysis" - ], - "support": { - "issues": "https://github.com/psalm/psalm-plugin-doctrine/issues", - "source": "https://github.com/psalm/psalm-plugin-doctrine/tree/v2.9.0" - }, - "time": "2023-07-15T05:44:30+00:00" } ], "aliases": [], diff --git a/phpstan.dist.neon b/phpstan.dist.neon new file mode 100644 index 0000000..e0de575 --- /dev/null +++ b/phpstan.dist.neon @@ -0,0 +1,8 @@ +parameters: + level: 6 + paths: + - bin/ + - config/ + - public/ + - src/ + - tests/ diff --git a/psalm-baseline.xml b/psalm-baseline.xml deleted file mode 100644 index 4710a86..0000000 --- a/psalm-baseline.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - index->get(IndexName::DailyOccurrences->value, $uriVariables['id'])['_source']]]]> - - - - - - index->get(IndexName::DailyOccurrences->value, $uriVariables['id'])['_source']]]> - - - - - index->get(IndexName::Events->value, $uriVariables['id'])['_source']]]]> - - - - - - index->get(IndexName::Events->value, $uriVariables['id'])['_source']]]> - - - - - index->get(IndexName::Locations->value, $uriVariables['id'])['_source']]]]> - - - - - - index->get(IndexName::Locations->value, $uriVariables['id'])['_source']]]> - - - - - index->get(IndexName::Occurrences->value, $uriVariables['id'])['_source']]]]> - - - - - - index->get(IndexName::Occurrences->value, $uriVariables['id'])['_source']]]> - - - - - index->get(IndexName::Organizations->value, $uriVariables['id'])['_source']]]]> - - - - - - index->get(IndexName::Organizations->value, $uriVariables['id'])['_source']]]> - - - - - - - - - - - - - - - - - - - - $indexName, - 'body' => [ - 'settings' => [ - 'number_of_shards' => 5, - 'number_of_replicas' => 0, - ], - ], - ]]]> - - - - - - - - - - - - - - - - - - - - $indexName]]]> - - - - - - - - - diff --git a/psalm.xml b/psalm.xml deleted file mode 100644 index e7fa19e..0000000 --- a/psalm.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - var/cache/dev/App_KernelDevDebugContainer.xml - - - - - diff --git a/symfony.lock b/symfony.lock index 8448a20..b5f3215 100644 --- a/symfony.lock +++ b/symfony.lock @@ -58,6 +58,18 @@ "config/packages/http_discovery.yaml" ] }, + "phpstan/phpstan": { + "version": "2.1", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.0", + "ref": "5e490cc197fb6bb1ae22e5abbc531ddc633b6767" + }, + "files": [ + "phpstan.dist.neon" + ] + }, "phpunit/phpunit": { "version": "10.5", "recipe": { From 263c40058f97865c839a37d3ea165e009e878e44 Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Wed, 4 Jun 2025 23:06:33 +0200 Subject: [PATCH 2/9] 4268: Updated PHPStan config --- Taskfile.yml | 6 +++--- phpstan.dist.neon | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index 9c55b4a..7da4de4 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -10,7 +10,7 @@ vars: DOCKER_COMPOSE: '{{.TASK_DOCKER_COMPOSE | default "docker compose"}}' # We're not yet ready to normalize config files … - YAML_FILES_GLOB: "Taskfile.yml .github/workflows/**.{yml,yaml}" + YAML_FILES_GLOB: "Taskfile.yml .github/workflows/**.{yml,yaml} phpstan.dist.neon" tasks: site:update: @@ -163,7 +163,7 @@ tasks: cmds: - task: compose vars: - COMPOSE_ARGS: run --rm prettier {{.YAML_FILES_GLOB}} --write + COMPOSE_ARGS: run --rm prettier --parser yaml {{.YAML_FILES_GLOB}} --write silent: true coding-standards:yaml:check: @@ -172,7 +172,7 @@ tasks: - task: coding-standards:yaml:apply - task: compose vars: - COMPOSE_ARGS: run --rm prettier {{.YAML_FILES_GLOB}} --check + COMPOSE_ARGS: run --rm prettier --parser yaml {{.YAML_FILES_GLOB}} --check silent: true code-analysis: diff --git a/phpstan.dist.neon b/phpstan.dist.neon index e0de575..3a65ed4 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -6,3 +6,12 @@ parameters: - public/ - src/ - tests/ + + ignoreErrors: + - messages: + - "#Method .+ has parameter .+ with no value type specified in iterable type array.#" + - "#Method .+ return type has no value type specified in iterable type array.#" + - "#Method .+ return type has no value type specified in iterable type iterable.#" + - "#Property .+ type has no value type specified in iterable type array.#" + - messages: + - "#Class .+ implements generic interface .+ but does not specify its types: #" From 248ea02b1d35c088e9b0444ba1e5ddf8397effc7 Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Wed, 4 Jun 2025 23:54:50 +0200 Subject: [PATCH 3/9] 4268: Updated "openid" parameters --- src/Api/Filter/ElasticSearch/BooleanFilter.php | 13 ++++++++----- src/Api/Filter/ElasticSearch/DateFilter.php | 13 ++++++++----- src/Api/Filter/ElasticSearch/IdFilter.php | 14 +++++++++----- src/Api/Filter/ElasticSearch/MatchFilter.php | 13 ++++++++----- src/Api/Filter/ElasticSearch/TagFilter.php | 14 +++++++++----- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/Api/Filter/ElasticSearch/BooleanFilter.php b/src/Api/Filter/ElasticSearch/BooleanFilter.php index 862123a..0d77d94 100644 --- a/src/Api/Filter/ElasticSearch/BooleanFilter.php +++ b/src/Api/Filter/ElasticSearch/BooleanFilter.php @@ -4,6 +4,7 @@ use ApiPlatform\Elasticsearch\Filter\AbstractFilter; use ApiPlatform\Metadata\Operation; +use ApiPlatform\OpenApi\Model\Parameter; use Symfony\Component\PropertyInfo\Type; final class BooleanFilter extends AbstractFilter @@ -39,11 +40,13 @@ public function getDescription(string $resourceClass): array 'required' => false, 'description' => 'Is this a public event', 'is_collection' => false, - 'openapi' => [ - 'allowReserved' => false, - 'allowEmptyValue' => true, - 'explode' => false, - ], + 'openapi' => new Parameter( + name: $filterParameterName, + in: 'query', + allowEmptyValue: true, + explode: false, + allowReserved: false, + ), ]; } diff --git a/src/Api/Filter/ElasticSearch/DateFilter.php b/src/Api/Filter/ElasticSearch/DateFilter.php index 593b0e7..4a6dc22 100644 --- a/src/Api/Filter/ElasticSearch/DateFilter.php +++ b/src/Api/Filter/ElasticSearch/DateFilter.php @@ -7,6 +7,7 @@ use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; use ApiPlatform\Metadata\ResourceClassResolverInterface; +use ApiPlatform\OpenApi\Model\Parameter; use App\Model\DateFilterConfig; use Symfony\Component\PropertyInfo\Type; use Symfony\Component\Serializer\NameConverter\NameConverterInterface; @@ -77,11 +78,13 @@ public function getDescription(string $resourceClass): array 'type' => Type::BUILTIN_TYPE_STRING, 'required' => false, 'description' => 'Filter base on ISO 8601 datetime (yyyy-MM-dd\'T\'HH:mm:ssz), e.g. "2004-02-12T15:19:21+00:00" ('.$this->config[$value]->limit->value.')', - 'openapi' => [ - 'allowReserved' => false, - 'allowEmptyValue' => true, - 'explode' => false, - ], + 'openapi' => new Parameter( + name: $filterParameterName, + in: 'query', + allowEmptyValue: true, + explode: false, + allowReserved: false, + ), ]; } diff --git a/src/Api/Filter/ElasticSearch/IdFilter.php b/src/Api/Filter/ElasticSearch/IdFilter.php index f28543b..dbef06b 100644 --- a/src/Api/Filter/ElasticSearch/IdFilter.php +++ b/src/Api/Filter/ElasticSearch/IdFilter.php @@ -4,6 +4,7 @@ use ApiPlatform\Elasticsearch\Filter\AbstractFilter; use ApiPlatform\Metadata\Operation; +use ApiPlatform\OpenApi\Model\Parameter; use Symfony\Component\PropertyInfo\Type; final class IdFilter extends AbstractFilter @@ -42,11 +43,14 @@ public function getDescription(string $resourceClass): array 'required' => false, 'description' => 'Filter based on given entity ids', 'is_collection' => true, - 'openapi' => [ - 'allowReserved' => false, - 'allowEmptyValue' => true, - 'explode' => false, - ], + 'openapi' => new Parameter( + name: $filterParameterName, + in: 'query', + allowEmptyValue: true, + style: 'deepObject', + explode: false, + allowReserved: false, + ), ]; } diff --git a/src/Api/Filter/ElasticSearch/MatchFilter.php b/src/Api/Filter/ElasticSearch/MatchFilter.php index 762a96d..2f5023a 100644 --- a/src/Api/Filter/ElasticSearch/MatchFilter.php +++ b/src/Api/Filter/ElasticSearch/MatchFilter.php @@ -4,6 +4,7 @@ use ApiPlatform\Elasticsearch\Filter\AbstractFilter; use ApiPlatform\Metadata\Operation; +use ApiPlatform\OpenApi\Model\Parameter; use Symfony\Component\PropertyInfo\Type; /** @@ -39,11 +40,13 @@ public function getDescription(string $resourceClass): array 'type' => Type::BUILTIN_TYPE_STRING, 'required' => false, 'description' => 'Search field based on value given', - 'openapi' => [ - 'allowReserved' => false, - 'allowEmptyValue' => true, - 'explode' => false, - ], + 'openapi' => new Parameter( + name: $filterParameterName, + in: 'query', + allowEmptyValue: true, + explode: false, + allowReserved: false, + ), ]; } diff --git a/src/Api/Filter/ElasticSearch/TagFilter.php b/src/Api/Filter/ElasticSearch/TagFilter.php index 67f2786..ef80ada 100644 --- a/src/Api/Filter/ElasticSearch/TagFilter.php +++ b/src/Api/Filter/ElasticSearch/TagFilter.php @@ -4,6 +4,7 @@ use ApiPlatform\Elasticsearch\Filter\AbstractFilter; use ApiPlatform\Metadata\Operation; +use ApiPlatform\OpenApi\Model\Parameter; use Symfony\Component\PropertyInfo\Type; final class TagFilter extends AbstractFilter @@ -39,11 +40,14 @@ public function getDescription(string $resourceClass): array 'required' => false, 'description' => 'Filter based on given tags', 'is_collection' => true, - 'openapi' => [ - 'allowReserved' => false, - 'allowEmptyValue' => true, - 'explode' => false, - ], + 'openapi' => new Parameter( + name: $filterParameterName, + in: 'query', + allowEmptyValue: true, + style: 'deepObject', + explode: false, + allowReserved: false, + ), ]; } From 81dc01ab6c79d4a444cbfcf08f148ab112917880 Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Wed, 4 Jun 2025 23:55:06 +0200 Subject: [PATCH 4/9] 4268: Fixed return type --- tests/ApiPlatform/AbstractApiTestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ApiPlatform/AbstractApiTestCase.php b/tests/ApiPlatform/AbstractApiTestCase.php index cf3b9b0..fa0ed9c 100644 --- a/tests/ApiPlatform/AbstractApiTestCase.php +++ b/tests/ApiPlatform/AbstractApiTestCase.php @@ -4,7 +4,7 @@ use ApiPlatform\Symfony\Bundle\Test\ApiTestCase; use ApiPlatform\Symfony\Bundle\Test\Client; -use ApiPlatform\Symfony\Bundle\Test\Response; +use Symfony\Contracts\HttpClient\ResponseInterface; abstract class AbstractApiTestCase extends ApiTestCase { @@ -22,7 +22,7 @@ protected static function createAuthenticatedClient(): Client ]); } - protected function get(array $query, ?string $path = null, bool $authenticated = true): Response + protected function get(array $query, ?string $path = null, bool $authenticated = true): ResponseInterface { $path ??= static::$requestPath; From 582854f98603c1df8fd364971ce4a2cf8e7a6028 Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Thu, 5 Jun 2025 00:03:31 +0200 Subject: [PATCH 5/9] 4268: Updated PHPStan config --- phpstan.dist.neon | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpstan.dist.neon b/phpstan.dist.neon index 3a65ed4..b11ebc5 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -7,6 +7,9 @@ parameters: - src/ - tests/ + excludePaths: + - tests/bootstrap.php + ignoreErrors: - messages: - "#Method .+ has parameter .+ with no value type specified in iterable type array.#" From d081e6cac3e548662d770c464169e630d3974787 Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Thu, 5 Jun 2025 00:06:23 +0200 Subject: [PATCH 6/9] 4268: Added function parameter types --- src/Api/Filter/ElasticSearch/DateRangeFilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Api/Filter/ElasticSearch/DateRangeFilter.php b/src/Api/Filter/ElasticSearch/DateRangeFilter.php index 8aff932..7370b08 100644 --- a/src/Api/Filter/ElasticSearch/DateRangeFilter.php +++ b/src/Api/Filter/ElasticSearch/DateRangeFilter.php @@ -80,7 +80,7 @@ public function getDescription(string $resourceClass): array return $description; } - private function getElasticSearchQueryRanges($property, $filter): array + private function getElasticSearchQueryRanges(string $property, string|array $filter): array { if (null === $this->properties) { throw new \InvalidArgumentException('The property must be defined in the filter.'); From f3569d4d3ea9092967670f689a594542258762b2 Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Thu, 5 Jun 2025 00:06:56 +0200 Subject: [PATCH 7/9] 4268: Cleaned up API user provider --- src/Security/ApiUserProvider.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Security/ApiUserProvider.php b/src/Security/ApiUserProvider.php index 840c8e6..2e09fbe 100644 --- a/src/Security/ApiUserProvider.php +++ b/src/Security/ApiUserProvider.php @@ -3,6 +3,7 @@ namespace App\Security; use Symfony\Component\Security\Core\Exception\UserNotFoundException; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface as TUser; use Symfony\Component\Security\Core\User\UserProviderInterface; @@ -13,16 +14,16 @@ class ApiUserProvider implements UserProviderInterface { private array $users = []; - public function __construct(private array $apikeys = []) + public function __construct(array $apikeys = []) { foreach ($apikeys as $apikey) { $this->users[$apikey['apikey']] = new ApiUser($apikey['username']); } } - public function refreshUser(TUser $user): void + public function refreshUser(TUser $user): UserInterface { - // Do nothing + return $user; } public function supportsClass(string $class): bool From 89575456cdb7c388c4e68a8190552bd0dd7dd6db Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Thu, 5 Jun 2025 00:19:47 +0200 Subject: [PATCH 8/9] 4268: Updated PHPStan config --- phpstan.dist.neon | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpstan.dist.neon b/phpstan.dist.neon index b11ebc5..62b59e7 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -18,3 +18,6 @@ parameters: - "#Property .+ type has no value type specified in iterable type array.#" - messages: - "#Class .+ implements generic interface .+ but does not specify its types: #" + - messages: + # The ID properties are set by API Platform. + - "#Property App\\\\Api\\\\Dto\\\\[^\\\\]+::\\$id is unused#" From 6df3792d4d2658b86c26d031a7ea7d80001ac7be Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Thu, 5 Jun 2025 00:39:39 +0200 Subject: [PATCH 9/9] 4268: Removed superfluous property --- src/Api/Dto/Tag.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Api/Dto/Tag.php b/src/Api/Dto/Tag.php index 5b843cd..0676b1f 100644 --- a/src/Api/Dto/Tag.php +++ b/src/Api/Dto/Tag.php @@ -52,9 +52,6 @@ )] readonly class Tag { - #[ApiProperty(identifier: false)] - private ?int $id; - #[ApiProperty(identifier: true)] public string $slug;