diff --git a/.github/workflows/lockfiles.yaml b/.github/workflows/lockfiles.yaml index 41998c67e..746d9d301 100644 --- a/.github/workflows/lockfiles.yaml +++ b/.github/workflows/lockfiles.yaml @@ -19,5 +19,5 @@ jobs: uses: xalvarez/prevent-file-change-action@v1 with: githubToken: ${{ secrets.GITHUB_TOKEN }} - pattern: .*.lock + pattern: .*\.lock$ trustedAuthors: kevinpapst, dependabot diff --git a/composer.json b/composer.json index 9dc7dac94..a12207bb9 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "onelogin/php-saml": "^4.0", "pagerfanta/pagerfanta": "^3.0", "phpoffice/phpspreadsheet": "^1.16", - "phpoffice/phpword": "^1.0", + "phpoffice/phpword": "1.1.*", "psr/container": "^2.0", "psr/log": "^3.0", "scheb/2fa-backup-code": "^6.2", @@ -174,6 +174,7 @@ "bin/console lint:container", "bin/console lint:yaml config --parse-tags", "bin/console lint:twig templates --show-deprecations", + "bin/console doctrine:schema:validate --skip-sync -vvv --no-interaction", "bin/console lint:xliff translations" ], "tests": "vendor/bin/phpunit tests/", diff --git a/composer.lock b/composer.lock index 598c153f8..804572e79 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": "a307b9a36c22711439283a3e5bc3249c", + "content-hash": "7b0ed62d4f9b4d06a6748c700fd04238", "packages": [ { "name": "azuyalabs/yasumi", @@ -1464,16 +1464,16 @@ }, { "name": "doctrine/orm", - "version": "2.17.1", + "version": "2.17.2", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1" + "reference": "393679a4795e49b0b3ac317dce84d0f8888f2b77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/1a4fe6e0bb67762370937a7e6cee3da40a9122d1", - "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1", + "url": "https://api.github.com/repos/doctrine/orm/zipball/393679a4795e49b0b3ac317dce84d0f8888f2b77", + "reference": "393679a4795e49b0b3ac317dce84d0f8888f2b77", "shasum": "" }, "require": { @@ -1506,10 +1506,10 @@ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.15.0" + "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "vimeo/psalm": "4.30.0 || 5.16.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -1559,9 +1559,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.17.1" + "source": "https://github.com/doctrine/orm/tree/2.17.2" }, - "time": "2023-11-17T06:25:40+00:00" + "time": "2023-12-20T21:47:52+00:00" }, { "name": "doctrine/persistence", @@ -2583,16 +2583,16 @@ }, { "name": "league/csv", - "version": "9.13.0", + "version": "9.14.0", "source": { "type": "git", "url": "https://github.com/thephpleague/csv.git", - "reference": "3690cc71bfe8dc3b6daeef356939fac95348f0a8" + "reference": "34bf0df7340b60824b9449b5c526fcc3325070d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/csv/zipball/3690cc71bfe8dc3b6daeef356939fac95348f0a8", - "reference": "3690cc71bfe8dc3b6daeef356939fac95348f0a8", + "url": "https://api.github.com/repos/thephpleague/csv/zipball/34bf0df7340b60824b9449b5c526fcc3325070d5", + "reference": "34bf0df7340b60824b9449b5c526fcc3325070d5", "shasum": "" }, "require": { @@ -2668,7 +2668,7 @@ "type": "github" } ], - "time": "2023-12-16T11:03:20+00:00" + "time": "2023-12-29T07:34:53+00:00" }, { "name": "lorenzo/pinky", @@ -3246,64 +3246,64 @@ }, { "name": "nelmio/api-doc-bundle", - "version": "v4.12.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioApiDocBundle.git", - "reference": "b9fc542143a4c38dc1a302b798a1caeb7d33484f" + "reference": "bef8b654ed410d16bf1086e2319ab215e5f36193" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/b9fc542143a4c38dc1a302b798a1caeb7d33484f", - "reference": "b9fc542143a4c38dc1a302b798a1caeb7d33484f", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/bef8b654ed410d16bf1086e2319ab215e5f36193", + "reference": "bef8b654ed410d16bf1086e2319ab215e5f36193", "shasum": "" }, "require": { - "doctrine/annotations": "^2.0", "ext-json": "*", "php": ">=7.2", "phpdocumentor/reflection-docblock": "^3.1|^4.0|^5.0", "psr/cache": "^1.0|^2.0|^3.0", "psr/container": "^1.0|^2.0", "psr/log": "^1.0|^2.0|^3.0", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/framework-bundle": "^5.4.24|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/options-resolver": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/routing": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4.24|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/options-resolver": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", "zircote/swagger-php": "^4.2.15" }, - "conflict": { - "symfony/framework-bundle": "4.2.7" - }, "require-dev": { - "api-platform/core": "^2.7.0|^3@dev", + "api-platform/core": "^2.7.0|^3", "composer/package-versions-deprecated": "1.11.99.1", + "doctrine/annotations": "^2.0", "friendsofsymfony/rest-bundle": "^2.8|^3.0", "jms/serializer": "^1.14|^3.0", - "jms/serializer-bundle": "^2.3|^3.0|^4.0|^5.0@beta", + "jms/serializer-bundle": "^2.3|^3.0|^4.0|^5.0", + "phpunit/phpunit": "^8.5|^9.6", "sensio/framework-extra-bundle": "^5.4|^6.0", - "symfony/asset": "^5.4|^6.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/cache": "^5.4|^6.0", + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/cache": "^5.4|^6.0|^7.0", "symfony/deprecation-contracts": "^2.1|^3", - "symfony/dom-crawler": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", - "symfony/phpunit-bridge": "^5.4.23", - "symfony/property-access": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/templating": "^5.4|^6.0", - "symfony/twig-bundle": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^6.4", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/templating": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/validator": "^5.4|^6.0|^7.0", "willdurand/hateoas-bundle": "^1.0|^2.0" }, "suggest": { "api-platform/core": "For using an API oriented framework.", + "doctrine/annotations": "For using doctrine annotations", "friendsofsymfony/rest-bundle": "For using the parameters annotations.", "jms/serializer-bundle": "For describing your models.", "symfony/asset": "For using the Swagger UI.", @@ -3352,9 +3352,9 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", - "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.12.0" + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.15.1" }, - "time": "2023-06-16T10:39:21+00:00" + "time": "2024-01-02T14:56:33+00:00" }, { "name": "nelmio/cors-bundle", @@ -5016,16 +5016,16 @@ }, { "name": "symfony/cache", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "ac2d25f97b17eec6e19760b6b9962a4f7c44356a" + "reference": "14a75869bbb41cb35bc5d9d322473928c6f3f978" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/ac2d25f97b17eec6e19760b6b9962a4f7c44356a", - "reference": "ac2d25f97b17eec6e19760b6b9962a4f7c44356a", + "url": "https://api.github.com/repos/symfony/cache/zipball/14a75869bbb41cb35bc5d9d322473928c6f3f978", + "reference": "14a75869bbb41cb35bc5d9d322473928c6f3f978", "shasum": "" }, "require": { @@ -5092,7 +5092,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.4.0" + "source": "https://github.com/symfony/cache/tree/v6.4.2" }, "funding": [ { @@ -5108,7 +5108,7 @@ "type": "tidelift" } ], - "time": "2023-11-24T19:28:07+00:00" + "time": "2023-12-29T15:34:34+00:00" }, { "name": "symfony/cache-contracts", @@ -5188,16 +5188,16 @@ }, { "name": "symfony/clock", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "48102bcc56b26d453c7f5e7f72829abc9df25a16" + "reference": "0639710e65f73cc504167958ea29be6de5c7177a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/48102bcc56b26d453c7f5e7f72829abc9df25a16", - "reference": "48102bcc56b26d453c7f5e7f72829abc9df25a16", + "url": "https://api.github.com/repos/symfony/clock/zipball/0639710e65f73cc504167958ea29be6de5c7177a", + "reference": "0639710e65f73cc504167958ea29be6de5c7177a", "shasum": "" }, "require": { @@ -5242,7 +5242,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v6.4.0" + "source": "https://github.com/symfony/clock/tree/v6.4.2" }, "funding": [ { @@ -5258,7 +5258,7 @@ "type": "tidelift" } ], - "time": "2023-10-13T14:46:14+00:00" + "time": "2023-12-27T00:32:33+00:00" }, { "name": "symfony/config", @@ -5337,16 +5337,16 @@ }, { "name": "symfony/console", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd" + "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a550a7c99daeedef3f9d23fb82e3531525ff11fd", - "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd", + "url": "https://api.github.com/repos/symfony/console/zipball/0254811a143e6bc6c8deea08b589a7e68a37f625", + "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625", "shasum": "" }, "require": { @@ -5411,7 +5411,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.1" + "source": "https://github.com/symfony/console/tree/v6.4.2" }, "funding": [ { @@ -5427,7 +5427,7 @@ "type": "tidelift" } ], - "time": "2023-11-30T10:54:28+00:00" + "time": "2023-12-10T16:15:48+00:00" }, { "name": "symfony/css-selector", @@ -5496,16 +5496,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f88ff6428afbeb17cc648c8003bd608534750baf" + "reference": "226ea431b1eda6f0d9f5a4b278757171960bb195" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f88ff6428afbeb17cc648c8003bd608534750baf", - "reference": "f88ff6428afbeb17cc648c8003bd608534750baf", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/226ea431b1eda6f0d9f5a4b278757171960bb195", + "reference": "226ea431b1eda6f0d9f5a4b278757171960bb195", "shasum": "" }, "require": { @@ -5557,7 +5557,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.1" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.2" }, "funding": [ { @@ -5573,7 +5573,7 @@ "type": "tidelift" } ], - "time": "2023-12-01T14:56:37+00:00" + "time": "2023-12-28T19:16:56+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5644,16 +5644,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "bd181daf2851821c3aef20b779d37002cfd2e833" + "reference": "da33f27c1dd9946afecfd1585b867551df71bf53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/bd181daf2851821c3aef20b779d37002cfd2e833", - "reference": "bd181daf2851821c3aef20b779d37002cfd2e833", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/da33f27c1dd9946afecfd1585b867551df71bf53", + "reference": "da33f27c1dd9946afecfd1585b867551df71bf53", "shasum": "" }, "require": { @@ -5732,7 +5732,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.4.0" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.4.2" }, "funding": [ { @@ -5748,20 +5748,20 @@ "type": "tidelift" } ], - "time": "2023-10-31T08:40:20+00:00" + "time": "2023-12-27T00:32:33+00:00" }, { "name": "symfony/dotenv", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "d0d584a91422ddaa2c94317200d4c4e5b935555f" + "reference": "835f8d2d1022934ac038519de40b88158798c96f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/d0d584a91422ddaa2c94317200d4c4e5b935555f", - "reference": "d0d584a91422ddaa2c94317200d4c4e5b935555f", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/835f8d2d1022934ac038519de40b88158798c96f", + "reference": "835f8d2d1022934ac038519de40b88158798c96f", "shasum": "" }, "require": { @@ -5806,7 +5806,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v6.4.0" + "source": "https://github.com/symfony/dotenv/tree/v6.4.2" }, "funding": [ { @@ -5822,7 +5822,7 @@ "type": "tidelift" } ], - "time": "2023-10-26T18:19:48+00:00" + "time": "2023-12-28T19:16:56+00:00" }, { "name": "symfony/error-handler", @@ -5901,16 +5901,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6" + "reference": "e95216850555cd55e71b857eb9d6c2674124603a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d76d2632cfc2206eecb5ad2b26cd5934082941b6", - "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e95216850555cd55e71b857eb9d6c2674124603a", + "reference": "e95216850555cd55e71b857eb9d6c2674124603a", "shasum": "" }, "require": { @@ -5961,7 +5961,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.2" }, "funding": [ { @@ -5977,7 +5977,7 @@ "type": "tidelift" } ], - "time": "2023-07-27T06:52:43+00:00" + "time": "2023-12-27T22:16:42+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -6057,16 +6057,16 @@ }, { "name": "symfony/expression-language", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "6c8b12f1e5ee5d91b812fb8628fca86e2fe5d152" + "reference": "7d63ccd5331d4164961776eced5524e891e30ad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/6c8b12f1e5ee5d91b812fb8628fca86e2fe5d152", - "reference": "6c8b12f1e5ee5d91b812fb8628fca86e2fe5d152", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/7d63ccd5331d4164961776eced5524e891e30ad3", + "reference": "7d63ccd5331d4164961776eced5524e891e30ad3", "shasum": "" }, "require": { @@ -6101,7 +6101,7 @@ "description": "Provides an engine that can compile and evaluate expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/expression-language/tree/v6.4.0" + "source": "https://github.com/symfony/expression-language/tree/v6.4.2" }, "funding": [ { @@ -6117,7 +6117,7 @@ "type": "tidelift" } ], - "time": "2023-07-27T06:52:43+00:00" + "time": "2023-12-10T16:15:48+00:00" }, { "name": "symfony/filesystem", @@ -6248,16 +6248,16 @@ }, { "name": "symfony/flex", - "version": "v2.4.2", + "version": "v2.4.3", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "67ee785f1aedada76461de7a7ec10cd7f8ff8d36" + "reference": "6b44ac75c7f07f48159ec36c2d21ef8cf48a21b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/67ee785f1aedada76461de7a7ec10cd7f8ff8d36", - "reference": "67ee785f1aedada76461de7a7ec10cd7f8ff8d36", + "url": "https://api.github.com/repos/symfony/flex/zipball/6b44ac75c7f07f48159ec36c2d21ef8cf48a21b1", + "reference": "6b44ac75c7f07f48159ec36c2d21ef8cf48a21b1", "shasum": "" }, "require": { @@ -6293,7 +6293,7 @@ "description": "Composer plugin for Symfony", "support": { "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v2.4.2" + "source": "https://github.com/symfony/flex/tree/v2.4.3" }, "funding": [ { @@ -6309,7 +6309,7 @@ "type": "tidelift" } ], - "time": "2023-12-05T14:09:35+00:00" + "time": "2024-01-02T11:08:32+00:00" }, { "name": "symfony/form", @@ -6410,16 +6410,16 @@ }, { "name": "symfony/framework-bundle", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "ac22d760bf9ff4440a1b6c7caef34d38b44290aa" + "reference": "c26a221e0462027d1f9d4a802ed63f8ab07a43d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/ac22d760bf9ff4440a1b6c7caef34d38b44290aa", - "reference": "ac22d760bf9ff4440a1b6c7caef34d38b44290aa", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/c26a221e0462027d1f9d4a802ed63f8ab07a43d0", + "reference": "c26a221e0462027d1f9d4a802ed63f8ab07a43d0", "shasum": "" }, "require": { @@ -6447,7 +6447,7 @@ "symfony/asset": "<5.4", "symfony/asset-mapper": "<6.4", "symfony/clock": "<6.3", - "symfony/console": "<5.4", + "symfony/console": "<5.4|>=7.0", "symfony/dom-crawler": "<6.4", "symfony/dotenv": "<5.4", "symfony/form": "<5.4", @@ -6538,7 +6538,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v6.4.1" + "source": "https://github.com/symfony/framework-bundle/tree/v6.4.2" }, "funding": [ { @@ -6554,20 +6554,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T16:35:22+00:00" + "time": "2023-12-29T15:34:34+00:00" }, { "name": "symfony/http-client", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "5c584530b77aa10ae216989ffc48b4bedc9c0b29" + "reference": "fc0944665bd932cf32a7b8a1d009466afc16528f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/5c584530b77aa10ae216989ffc48b4bedc9c0b29", - "reference": "5c584530b77aa10ae216989ffc48b4bedc9c0b29", + "url": "https://api.github.com/repos/symfony/http-client/zipball/fc0944665bd932cf32a7b8a1d009466afc16528f", + "reference": "fc0944665bd932cf32a7b8a1d009466afc16528f", "shasum": "" }, "require": { @@ -6631,7 +6631,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.0" + "source": "https://github.com/symfony/http-client/tree/v6.4.2" }, "funding": [ { @@ -6647,7 +6647,7 @@ "type": "tidelift" } ], - "time": "2023-11-28T20:55:58+00:00" + "time": "2023-12-02T12:49:56+00:00" }, { "name": "symfony/http-client-contracts", @@ -6729,16 +6729,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "44a6d39a9cc11e154547d882d5aac1e014440771" + "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/44a6d39a9cc11e154547d882d5aac1e014440771", - "reference": "44a6d39a9cc11e154547d882d5aac1e014440771", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/172d807f9ef3fc3fbed8377cc57c20d389269271", + "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271", "shasum": "" }, "require": { @@ -6786,7 +6786,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.0" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.2" }, "funding": [ { @@ -6802,20 +6802,20 @@ "type": "tidelift" } ], - "time": "2023-11-20T16:41:16+00:00" + "time": "2023-12-27T22:16:42+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "2953274c16a229b3933ef73a6898e18388e12e1b" + "reference": "13e8387320b5942d0dc408440c888e2d526efef4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2953274c16a229b3933ef73a6898e18388e12e1b", - "reference": "2953274c16a229b3933ef73a6898e18388e12e1b", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/13e8387320b5942d0dc408440c888e2d526efef4", + "reference": "13e8387320b5942d0dc408440c888e2d526efef4", "shasum": "" }, "require": { @@ -6899,7 +6899,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.1" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.2" }, "funding": [ { @@ -6915,20 +6915,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T17:02:02+00:00" + "time": "2023-12-30T15:31:44+00:00" }, { "name": "symfony/intl", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "41d16f0294b9ca6e5540728580c65cfa3848fbf5" + "reference": "4f45148f7eb984ef12b1f7e123205ab904828839" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/41d16f0294b9ca6e5540728580c65cfa3848fbf5", - "reference": "41d16f0294b9ca6e5540728580c65cfa3848fbf5", + "url": "https://api.github.com/repos/symfony/intl/zipball/4f45148f7eb984ef12b1f7e123205ab904828839", + "reference": "4f45148f7eb984ef12b1f7e123205ab904828839", "shasum": "" }, "require": { @@ -6981,7 +6981,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v6.4.0" + "source": "https://github.com/symfony/intl/tree/v6.4.2" }, "funding": [ { @@ -6997,20 +6997,20 @@ "type": "tidelift" } ], - "time": "2023-10-28T23:12:08+00:00" + "time": "2023-12-26T18:38:00+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba" + "reference": "6da89e5c9202f129717a770a03183fb140720168" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", - "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", + "url": "https://api.github.com/repos/symfony/mailer/zipball/6da89e5c9202f129717a770a03183fb140720168", + "reference": "6da89e5c9202f129717a770a03183fb140720168", "shasum": "" }, "require": { @@ -7061,7 +7061,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.0" + "source": "https://github.com/symfony/mailer/tree/v6.4.2" }, "funding": [ { @@ -7077,7 +7077,7 @@ "type": "tidelift" } ], - "time": "2023-11-12T18:02:22+00:00" + "time": "2023-12-19T09:12:31+00:00" }, { "name": "symfony/mime", @@ -8043,16 +8043,16 @@ }, { "name": "symfony/rate-limiter", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "b598ae785a3b3ee932c1fb638b1df86f0d36f81e" + "reference": "c32471a8ebe613f6856db4b0544fcf5429d12511" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/b598ae785a3b3ee932c1fb638b1df86f0d36f81e", - "reference": "b598ae785a3b3ee932c1fb638b1df86f0d36f81e", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/c32471a8ebe613f6856db4b0544fcf5429d12511", + "reference": "c32471a8ebe613f6856db4b0544fcf5429d12511", "shasum": "" }, "require": { @@ -8094,7 +8094,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v6.4.0" + "source": "https://github.com/symfony/rate-limiter/tree/v6.4.2" }, "funding": [ { @@ -8110,20 +8110,20 @@ "type": "tidelift" } ], - "time": "2023-11-10T07:41:05+00:00" + "time": "2023-12-30T09:55:02+00:00" }, { "name": "symfony/routing", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "0c95c164fdba18b12523b75e64199ca3503e6d40" + "reference": "98eab13a07fddc85766f1756129c69f207ffbc21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/0c95c164fdba18b12523b75e64199ca3503e6d40", - "reference": "0c95c164fdba18b12523b75e64199ca3503e6d40", + "url": "https://api.github.com/repos/symfony/routing/zipball/98eab13a07fddc85766f1756129c69f207ffbc21", + "reference": "98eab13a07fddc85766f1756129c69f207ffbc21", "shasum": "" }, "require": { @@ -8177,7 +8177,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.1" + "source": "https://github.com/symfony/routing/tree/v6.4.2" }, "funding": [ { @@ -8193,7 +8193,7 @@ "type": "tidelift" } ], - "time": "2023-12-01T14:54:37+00:00" + "time": "2023-12-29T15:34:34+00:00" }, { "name": "symfony/runtime", @@ -8276,16 +8276,16 @@ }, { "name": "symfony/security-bundle", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "4fd31b7cb2a18f62c5a8588b82a44fd240b41a9e" + "reference": "97d4fb6dbee700937738036ec54b0fcb0641d7d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/4fd31b7cb2a18f62c5a8588b82a44fd240b41a9e", - "reference": "4fd31b7cb2a18f62c5a8588b82a44fd240b41a9e", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/97d4fb6dbee700937738036ec54b0fcb0641d7d6", + "reference": "97d4fb6dbee700937738036ec54b0fcb0641d7d6", "shasum": "" }, "require": { @@ -8368,7 +8368,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v6.4.0" + "source": "https://github.com/symfony/security-bundle/tree/v6.4.2" }, "funding": [ { @@ -8384,7 +8384,7 @@ "type": "tidelift" } ], - "time": "2023-10-31T14:46:20+00:00" + "time": "2023-12-24T09:11:31+00:00" }, { "name": "symfony/security-core", @@ -8629,16 +8629,16 @@ }, { "name": "symfony/serializer", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "7ead272e62c9567df619ef3c49809bf934ddbc1f" + "reference": "f87ea9d7bfd4cf2f7b72be554607e6c96e6664af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/7ead272e62c9567df619ef3c49809bf934ddbc1f", - "reference": "7ead272e62c9567df619ef3c49809bf934ddbc1f", + "url": "https://api.github.com/repos/symfony/serializer/zipball/f87ea9d7bfd4cf2f7b72be554607e6c96e6664af", + "reference": "f87ea9d7bfd4cf2f7b72be554607e6c96e6664af", "shasum": "" }, "require": { @@ -8707,7 +8707,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.4.1" + "source": "https://github.com/symfony/serializer/tree/v6.4.2" }, "funding": [ { @@ -8723,25 +8723,25 @@ "type": "tidelift" } ], - "time": "2023-12-01T14:54:37+00:00" + "time": "2023-12-29T15:34:34+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.0", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^2.0" + "psr/container": "^1.1|^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -8789,7 +8789,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" }, "funding": [ { @@ -8805,7 +8805,7 @@ "type": "tidelift" } ], - "time": "2023-07-30T20:28:31+00:00" + "time": "2023-12-26T14:02:43+00:00" }, { "name": "symfony/stopwatch", @@ -8871,16 +8871,16 @@ }, { "name": "symfony/string", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809" + "reference": "7cb80bc10bfcdf6b5492741c0b9357dac66940bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/b45fcf399ea9c3af543a92edf7172ba21174d809", - "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809", + "url": "https://api.github.com/repos/symfony/string/zipball/7cb80bc10bfcdf6b5492741c0b9357dac66940bc", + "reference": "7cb80bc10bfcdf6b5492741c0b9357dac66940bc", "shasum": "" }, "require": { @@ -8937,7 +8937,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.0" + "source": "https://github.com/symfony/string/tree/v6.4.2" }, "funding": [ { @@ -8953,20 +8953,20 @@ "type": "tidelift" } ], - "time": "2023-11-28T20:41:49+00:00" + "time": "2023-12-10T16:15:48+00:00" }, { "name": "symfony/translation", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37" + "reference": "a2ab2ec1a462e53016de8e8d5e8912bfd62ea681" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", - "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", + "url": "https://api.github.com/repos/symfony/translation/zipball/a2ab2ec1a462e53016de8e8d5e8912bfd62ea681", + "reference": "a2ab2ec1a462e53016de8e8d5e8912bfd62ea681", "shasum": "" }, "require": { @@ -9032,7 +9032,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.0" + "source": "https://github.com/symfony/translation/tree/v6.4.2" }, "funding": [ { @@ -9048,20 +9048,20 @@ "type": "tidelift" } ], - "time": "2023-11-29T08:14:36+00:00" + "time": "2023-12-18T09:25:29+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.4.0", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" + "reference": "06450585bf65e978026bda220cdebca3f867fde7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/06450585bf65e978026bda220cdebca3f867fde7", + "reference": "06450585bf65e978026bda220cdebca3f867fde7", "shasum": "" }, "require": { @@ -9110,7 +9110,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.1" }, "funding": [ { @@ -9126,20 +9126,20 @@ "type": "tidelift" } ], - "time": "2023-07-25T15:08:44+00:00" + "time": "2023-12-26T14:02:43+00:00" }, { "name": "symfony/twig-bridge", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf" + "reference": "97af829e4733125ee70e806694d56165c60b4ee1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", - "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/97af829e4733125ee70e806694d56165c60b4ee1", + "reference": "97af829e4733125ee70e806694d56165c60b4ee1", "shasum": "" }, "require": { @@ -9219,7 +9219,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v6.4.0" + "source": "https://github.com/symfony/twig-bridge/tree/v6.4.2" }, "funding": [ { @@ -9235,7 +9235,7 @@ "type": "tidelift" } ], - "time": "2023-11-25T08:25:13+00:00" + "time": "2023-12-15T12:36:48+00:00" }, { "name": "symfony/twig-bundle", @@ -9323,16 +9323,16 @@ }, { "name": "symfony/validator", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "33e1f3bb76ef70e3170e12f878aefb9c69b0fc4c" + "reference": "15fe2c6ed815b06b6b8636d8ba3ef9807ee1a75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/33e1f3bb76ef70e3170e12f878aefb9c69b0fc4c", - "reference": "33e1f3bb76ef70e3170e12f878aefb9c69b0fc4c", + "url": "https://api.github.com/repos/symfony/validator/zipball/15fe2c6ed815b06b6b8636d8ba3ef9807ee1a75c", + "reference": "15fe2c6ed815b06b6b8636d8ba3ef9807ee1a75c", "shasum": "" }, "require": { @@ -9399,7 +9399,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.4.0" + "source": "https://github.com/symfony/validator/tree/v6.4.2" }, "funding": [ { @@ -9415,20 +9415,20 @@ "type": "tidelift" } ], - "time": "2023-11-29T07:47:42+00:00" + "time": "2023-12-29T16:34:12+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6" + "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c40f7d17e91d8b407582ed51a2bbf83c52c367f6", - "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", + "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", "shasum": "" }, "require": { @@ -9484,7 +9484,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.0" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.2" }, "funding": [ { @@ -9500,20 +9500,20 @@ "type": "tidelift" } ], - "time": "2023-11-09T08:28:32+00:00" + "time": "2023-12-28T19:16:56+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "2d08ca6b9cc704dce525615d1e6d1788734f36d9" + "reference": "5fe9a0021b8d35e67d914716ec8de50716a68e7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/2d08ca6b9cc704dce525615d1e6d1788734f36d9", - "reference": "2d08ca6b9cc704dce525615d1e6d1788734f36d9", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/5fe9a0021b8d35e67d914716ec8de50716a68e7e", + "reference": "5fe9a0021b8d35e67d914716ec8de50716a68e7e", "shasum": "" }, "require": { @@ -9559,7 +9559,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.1" + "source": "https://github.com/symfony/var-exporter/tree/v6.4.2" }, "funding": [ { @@ -9575,7 +9575,7 @@ "type": "tidelift" } ], - "time": "2023-11-30T10:32:10+00:00" + "time": "2023-12-27T08:18:35+00:00" }, { "name": "symfony/webpack-encore-bundle", @@ -10340,16 +10340,16 @@ }, { "name": "zircote/swagger-php", - "version": "4.8.1", + "version": "4.8.2", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "2a2ae434965f5c497713e05d1398fc9476dfdeb0" + "reference": "a70a5dc5db26183c86f589ff3d76fb11e141fc58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/2a2ae434965f5c497713e05d1398fc9476dfdeb0", - "reference": "2a2ae434965f5c497713e05d1398fc9476dfdeb0", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/a70a5dc5db26183c86f589ff3d76fb11e141fc58", + "reference": "a70a5dc5db26183c86f589ff3d76fb11e141fc58", "shasum": "" }, "require": { @@ -10415,9 +10415,9 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/4.8.1" + "source": "https://github.com/zircote/swagger-php/tree/4.8.2" }, - "time": "2023-12-11T08:35:08+00:00" + "time": "2023-12-19T19:59:07+00:00" } ], "packages-dev": [ @@ -10798,16 +10798,16 @@ }, { "name": "fakerphp/faker", - "version": "v1.23.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01" + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", - "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", "shasum": "" }, "require": { @@ -10833,11 +10833,6 @@ "ext-mbstring": "Required for multibyte Unicode string functionality." }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "v1.21-dev" - } - }, "autoload": { "psr-4": { "Faker\\": "src/Faker/" @@ -10860,22 +10855,22 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.23.0" + "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" }, - "time": "2023-06-12T08:44:38+00:00" + "time": "2024-01-02T13:46:09+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.41.1", + "version": "v3.45.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6" + "reference": "c0daa33cb2533cd73f48dde1c70c2afa3e7953b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8b6ae8dcbaf23f09680643ab832a4a3a260265f6", - "reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/c0daa33cb2533cd73f48dde1c70c2afa3e7953b5", + "reference": "c0daa33cb2533cd73f48dde1c70c2afa3e7953b5", "shasum": "" }, "require": { @@ -10905,8 +10900,7 @@ "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", - "phpunit/phpunit": "^9.6", - "symfony/phpunit-bridge": "^6.3.8 || ^7.0", + "phpunit/phpunit": "^9.6 || ^10.5.5", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { @@ -10945,7 +10939,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.1" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.45.0" }, "funding": [ { @@ -10953,7 +10947,7 @@ "type": "github" } ], - "time": "2023-12-10T19:59:27+00:00" + "time": "2023-12-30T02:07:07+00:00" }, { "name": "masterminds/html5", @@ -11424,16 +11418,16 @@ }, { "name": "phpstan/phpstan-symfony", - "version": "1.3.5", + "version": "1.3.6", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "27ff6339f83796a7e0dd963cf445cd3c456fc620" + "reference": "34b3c43684834f6a20aa51af8d455480d9de8b88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/27ff6339f83796a7e0dd963cf445cd3c456fc620", - "reference": "27ff6339f83796a7e0dd963cf445cd3c456fc620", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/34b3c43684834f6a20aa51af8d455480d9de8b88", + "reference": "34b3c43684834f6a20aa51af8d455480d9de8b88", "shasum": "" }, "require": { @@ -11490,29 +11484,29 @@ "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/1.3.5" + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.3.6" }, - "time": "2023-10-30T14:52:15+00:00" + "time": "2023-12-22T11:22:34+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -11562,7 +11556,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" }, "funding": [ { @@ -11570,7 +11564,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -12158,20 +12152,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -12203,7 +12197,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -12211,7 +12205,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -12485,20 +12479,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -12530,7 +12524,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -12538,7 +12532,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", @@ -13090,16 +13084,16 @@ }, { "name": "symfony/phpunit-bridge", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "cca5373a41d45edbeaf38b7b67f376da2205ff95" + "reference": "bd0455b7888e4adac29cf175d819c51f88fed942" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/cca5373a41d45edbeaf38b7b67f376da2205ff95", - "reference": "cca5373a41d45edbeaf38b7b67f376da2205ff95", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/bd0455b7888e4adac29cf175d819c51f88fed942", + "reference": "bd0455b7888e4adac29cf175d819c51f88fed942", "shasum": "" }, "require": { @@ -13151,7 +13145,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.1" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.2" }, "funding": [ { @@ -13167,20 +13161,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T09:25:07+00:00" + "time": "2023-12-19T09:12:31+00:00" }, { "name": "symfony/process", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa" + "reference": "c4b1ef0bc80533d87a2e969806172f1c2a980241" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/191703b1566d97a5425dc969e4350d32b8ef17aa", - "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa", + "url": "https://api.github.com/repos/symfony/process/zipball/c4b1ef0bc80533d87a2e969806172f1c2a980241", + "reference": "c4b1ef0bc80533d87a2e969806172f1c2a980241", "shasum": "" }, "require": { @@ -13212,7 +13206,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.0" + "source": "https://github.com/symfony/process/tree/v6.4.2" }, "funding": [ { @@ -13228,20 +13222,20 @@ "type": "tidelift" } ], - "time": "2023-11-17T21:06:49+00:00" + "time": "2023-12-22T16:42:54+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "14752d3fb77c3c69b6cee7c03c06e2d6494a196b" + "reference": "38462d16856740ec0d1ba2cb902eebf09100dde2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/14752d3fb77c3c69b6cee7c03c06e2d6494a196b", - "reference": "14752d3fb77c3c69b6cee7c03c06e2d6494a196b", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/38462d16856740ec0d1ba2cb902eebf09100dde2", + "reference": "38462d16856740ec0d1ba2cb902eebf09100dde2", "shasum": "" }, "require": { @@ -13294,7 +13288,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.0" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.2" }, "funding": [ { @@ -13310,7 +13304,7 @@ "type": "tidelift" } ], - "time": "2023-11-07T14:57:07+00:00" + "time": "2023-12-27T08:18:35+00:00" }, { "name": "theseer/tokenizer", diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index cad3a4373..9848d766c 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -1,9 +1,12 @@ framework: # Deprecations for 7.0 handle_all_throwables: true - # cannot be disabled, because of https://github.com/nelmio/NelmioApiDocBundle/pull/2164 annotations: - enabled: true + enabled: false + + serializer: + enable_attributes: true + # --------------------------- exceptions: @@ -32,6 +35,7 @@ framework: validation: email_validation_mode: html5 + enable_attributes: true when@dev: framework: diff --git a/src/API/ActionsController.php b/src/API/ActionsController.php index e561d0e53..03d1e56d2 100644 --- a/src/API/ActionsController.php +++ b/src/API/ActionsController.php @@ -15,14 +15,13 @@ use App\Entity\Customer; use App\Entity\Project; use App\Entity\Timesheet; use App\Event\PageActionsEvent; -use FOS\RestBundle\Controller\Annotations as Rest; use FOS\RestBundle\View\View; use FOS\RestBundle\View\ViewHandlerInterface; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity; use OpenApi\Attributes as OA; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -73,7 +72,7 @@ final class ActionsController extends BaseApiController #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet ID to fetch', required: true)] #[OA\Parameter(name: 'view', in: 'path', description: 'View to display the actions at (e.g. index, custom)', required: true)] #[OA\Parameter(name: 'locale', in: 'path', description: 'Language to translate the action title to (e.g. de, en)', required: true)] - #[Rest\Get(path: '/timesheet/{id}/{view}/{locale}', name: 'get_timesheet_actions', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/timesheet/{id}/{view}/{locale}', name: 'get_timesheet_actions', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getTimesheetActions(Timesheet $timesheet, string $view, string $locale): Response @@ -93,7 +92,7 @@ final class ActionsController extends BaseApiController #[OA\Parameter(name: 'id', in: 'path', description: 'Activity ID to fetch', required: true)] #[OA\Parameter(name: 'view', in: 'path', description: 'View to display the actions at (e.g. index, custom)', required: true)] #[OA\Parameter(name: 'locale', in: 'path', description: 'Language to translate the action title to (e.g. de, en)', required: true)] - #[Rest\Get(path: '/activity/{id}/{view}/{locale}', name: 'get_activity_actions', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/activity/{id}/{view}/{locale}', name: 'get_activity_actions', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getActivityActions(Activity $activity, string $view, string $locale): Response @@ -113,7 +112,7 @@ final class ActionsController extends BaseApiController #[OA\Parameter(name: 'id', in: 'path', description: 'Project ID to fetch', required: true)] #[OA\Parameter(name: 'view', in: 'path', description: 'View to display the actions at (e.g. index, custom)', required: true)] #[OA\Parameter(name: 'locale', in: 'path', description: 'Language to translate the action title to (e.g. de, en)', required: true)] - #[Rest\Get(path: '/project/{id}/{view}/{locale}', name: 'get_project_actions', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/project/{id}/{view}/{locale}', name: 'get_project_actions', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getProjectActions(Project $project, string $view, string $locale): Response @@ -133,7 +132,7 @@ final class ActionsController extends BaseApiController #[OA\Parameter(name: 'id', in: 'path', description: 'Customer ID to fetch', required: true)] #[OA\Parameter(name: 'view', in: 'path', description: 'View to display the actions at (e.g. index, custom)', required: true)] #[OA\Parameter(name: 'locale', in: 'path', description: 'Language to translate the action title to (e.g. de, en)', required: true)] - #[Rest\Get(path: '/customer/{id}/{view}/{locale}', name: 'get_customer_actions', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/customer/{id}/{view}/{locale}', name: 'get_customer_actions', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getCustomerActions(Customer $customer, string $view, string $locale): Response diff --git a/src/API/ActivityController.php b/src/API/ActivityController.php index fe72917e4..b1b652ffb 100644 --- a/src/API/ActivityController.php +++ b/src/API/ActivityController.php @@ -30,7 +30,7 @@ use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[Route(path: '/activities')] @@ -55,7 +55,7 @@ final class ActivityController extends BaseApiController * Returns a collection of activities (which are visible to the user) */ #[OA\Response(response: 200, description: 'Returns a collection of activities', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/ActivityCollection')))] - #[Rest\Get(path: '', name: 'get_activities')] + #[Route(methods: ['GET'], path: '', name: 'get_activities')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'project', requirements: '\d+', strict: true, nullable: true, description: 'Project ID to filter activities')] @@ -125,7 +125,7 @@ final class ActivityController extends BaseApiController */ #[OA\Response(response: 200, description: 'Returns one activity entity', content: new OA\JsonContent(ref: '#/components/schemas/ActivityEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Activity ID to fetch', required: true)] - #[Rest\Get(path: '/{id}', name: 'get_activity', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}', name: 'get_activity', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getAction(Activity $activity): Response @@ -141,7 +141,7 @@ final class ActivityController extends BaseApiController */ #[OA\Post(description: 'Creates a new activity and returns it afterwards', responses: [new OA\Response(response: 200, description: 'Returns the new created activity', content: new OA\JsonContent(ref: '#/components/schemas/ActivityEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/ActivityEditForm'))] - #[Rest\Post(path: '', name: 'post_activity')] + #[Route(methods: ['POST'], path: '', name: 'post_activity')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postAction(Request $request): Response @@ -184,7 +184,7 @@ final class ActivityController extends BaseApiController #[OA\Patch(description: 'Update an existing activity, you can pass all or just a subset of all attributes', responses: [new OA\Response(response: 200, description: 'Returns the updated activity', content: new OA\JsonContent(ref: '#/components/schemas/ActivityEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/ActivityEditForm'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Activity ID to update', required: true)] - #[Rest\Patch(path: '/{id}', name: 'patch_activity', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}', name: 'patch_activity', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function patchAction(Request $request, Activity $activity): Response @@ -221,7 +221,7 @@ final class ActivityController extends BaseApiController #[IsGranted('edit', 'activity')] #[OA\Response(response: 200, description: 'Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.', content: new OA\JsonContent(ref: '#/components/schemas/ActivityEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Activity record ID to set the meta-field value for', required: true)] - #[Rest\Patch(path: '/{id}/meta', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/meta', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\RequestParam(name: 'name', strict: true, nullable: false, description: 'The meta-field name')] @@ -254,7 +254,7 @@ final class ActivityController extends BaseApiController #[IsGranted('edit', 'activity')] #[OA\Response(response: 200, description: 'Returns a collection of activity rate entities', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/ActivityRate')))] #[OA\Parameter(name: 'id', in: 'path', description: 'The activity whose rates will be returned', required: true)] - #[Rest\Get(path: '/{id}/rates', name: 'get_activity_rates', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}/rates', name: 'get_activity_rates', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getRatesAction(Activity $activity): Response @@ -276,7 +276,7 @@ final class ActivityController extends BaseApiController #[OA\Parameter(name: 'rateId', in: 'path', description: 'The rate to remove', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}/rates/{rateId}', name: 'delete_activity_rate', requirements: ['id' => '\d+', 'rateId' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}/rates/{rateId}', name: 'delete_activity_rate', requirements: ['id' => '\d+', 'rateId' => '\d+'])] public function deleteRateAction(Activity $activity, #[MapEntity(mapping: ['rateId' => 'id'])] ActivityRate $rate): Response { if ($rate->getActivity() !== $activity) { @@ -297,7 +297,7 @@ final class ActivityController extends BaseApiController #[OA\Post(responses: [new OA\Response(response: 200, description: 'Returns the new created rate', content: new OA\JsonContent(ref: '#/components/schemas/ActivityRate'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'The activity to add the rate for', required: true)] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/ActivityRateForm'))] - #[Rest\Post(path: '/{id}/rates', name: 'post_activity_rate', requirements: ['id' => '\d+'])] + #[Route(methods: ['POST'], path: '/{id}/rates', name: 'post_activity_rate', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postRateAction(Activity $activity, Request $request): Response diff --git a/src/API/ConfigurationController.php b/src/API/ConfigurationController.php index 6db094d5a..a02438ecb 100644 --- a/src/API/ConfigurationController.php +++ b/src/API/ConfigurationController.php @@ -11,13 +11,13 @@ namespace App\API; use App\API\Model\TimesheetConfig; use App\Configuration\SystemConfiguration; -use FOS\RestBundle\Controller\Annotations as Rest; use FOS\RestBundle\View\View; use FOS\RestBundle\View\ViewHandlerInterface; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity; use OpenApi\Attributes as OA; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[IsGranted('IS_AUTHENTICATED_REMEMBERED')] @@ -32,7 +32,7 @@ final class ConfigurationController extends BaseApiController * Returns the timesheet configuration */ #[OA\Response(response: 200, description: 'Returns the instance specific timesheet configuration', content: new OA\JsonContent(ref: new Model(type: TimesheetConfig::class)))] - #[Rest\Get(path: '/config/timesheet')] + #[Route(methods: ['GET'], path: '/config/timesheet')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function timesheetConfigAction(SystemConfiguration $configuration): Response diff --git a/src/API/CustomerController.php b/src/API/CustomerController.php index 55cab78d8..6daf608e2 100644 --- a/src/API/CustomerController.php +++ b/src/API/CustomerController.php @@ -30,7 +30,7 @@ use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[Route(path: '/customers')] @@ -55,7 +55,7 @@ final class CustomerController extends BaseApiController * Returns a collection of customers (which are visible to the user) */ #[OA\Response(response: 200, description: 'Returns a collection of customers', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/CustomerCollection')))] - #[Rest\Get(path: '', name: 'get_customers')] + #[Route(methods: ['GET'], path: '', name: 'get_customers')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'visible', requirements: '1|2|3', default: 1, strict: true, nullable: true, description: 'Visibility status to filter customers: 1=visible, 2=hidden, 3=both')] @@ -102,7 +102,7 @@ final class CustomerController extends BaseApiController * Returns one customer */ #[OA\Response(response: 200, description: 'Returns one customer entity', content: new OA\JsonContent(ref: '#/components/schemas/CustomerEntity'))] - #[Rest\Get(path: '/{id}', name: 'get_customer', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}', name: 'get_customer', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getAction(Customer $customer): Response @@ -118,7 +118,7 @@ final class CustomerController extends BaseApiController */ #[OA\Post(description: 'Creates a new customer and returns it afterwards', responses: [new OA\Response(response: 200, description: 'Returns the new created customer', content: new OA\JsonContent(ref: '#/components/schemas/CustomerEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/CustomerEditForm'))] - #[Rest\Post(path: '', name: 'post_customer')] + #[Route(methods: ['POST'], path: '', name: 'post_customer')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postAction(Request $request, CustomerService $customerService): Response @@ -161,7 +161,7 @@ final class CustomerController extends BaseApiController #[OA\Patch(description: 'Update an existing customer, you can pass all or just a subset of all attributes', responses: [new OA\Response(response: 200, description: 'Returns the updated customer', content: new OA\JsonContent(ref: '#/components/schemas/CustomerEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/CustomerEditForm'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Customer ID to update', required: true)] - #[Rest\Patch(path: '/{id}', name: 'patch_customer', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}', name: 'patch_customer', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function patchAction(Request $request, Customer $customer): Response @@ -198,7 +198,7 @@ final class CustomerController extends BaseApiController #[IsGranted('edit', 'customer')] #[OA\Response(response: 200, description: 'Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.', content: new OA\JsonContent(ref: '#/components/schemas/CustomerEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Customer record ID to set the meta-field value for', required: true)] - #[Rest\Patch(path: '/{id}/meta', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/meta', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\RequestParam(name: 'name', strict: true, nullable: false, description: 'The meta-field name')] @@ -231,7 +231,7 @@ final class CustomerController extends BaseApiController #[IsGranted('edit', 'customer')] #[OA\Response(response: 200, description: 'Returns a collection of customer rate entities', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/CustomerRate')))] #[OA\Parameter(name: 'id', in: 'path', description: 'The customer whose rates will be returned', required: true)] - #[Rest\Get(path: '/{id}/rates', name: 'get_customer_rates', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}/rates', name: 'get_customer_rates', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getRatesAction(Customer $customer): Response @@ -253,7 +253,7 @@ final class CustomerController extends BaseApiController #[OA\Parameter(name: 'rateId', in: 'path', description: 'The rate to remove', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}/rates/{rateId}', name: 'delete_customer_rate', requirements: ['id' => '\d+', 'rateId' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}/rates/{rateId}', name: 'delete_customer_rate', requirements: ['id' => '\d+', 'rateId' => '\d+'])] public function deleteRateAction(Customer $customer, #[MapEntity(mapping: ['rateId' => 'id'])] CustomerRate $rate): Response { if ($rate->getCustomer() !== $customer) { @@ -274,7 +274,7 @@ final class CustomerController extends BaseApiController #[OA\Post(responses: [new OA\Response(response: 200, description: 'Returns the new created rate', content: new OA\JsonContent(ref: '#/components/schemas/CustomerRate'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'The customer to add the rate for', required: true)] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/CustomerRateForm'))] - #[Rest\Post(path: '/{id}/rates', name: 'post_customer_rate', requirements: ['id' => '\d+'])] + #[Route(methods: ['POST'], path: '/{id}/rates', name: 'post_customer_rate', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postRateAction(Customer $customer, Request $request): Response diff --git a/src/API/Model/CalendarEvent.php b/src/API/Model/CalendarEvent.php index d6d596127..d637570c4 100644 --- a/src/API/Model/CalendarEvent.php +++ b/src/API/Model/CalendarEvent.php @@ -48,15 +48,15 @@ final class CalendarEvent */ #[Serializer\Expose] #[Serializer\Groups(['Default'])] - #[Serializer\Type(name: 'DateTime')] - private \DateTimeInterface $start; // @phpstan-ignore-line + #[Serializer\Type(name: 'DateTimeImmutable')] + private \DateTimeImmutable $start; // @phpstan-ignore-line /** * Calendar entry end date */ #[Serializer\Expose] #[Serializer\Groups(['Default'])] - #[Serializer\Type(name: 'DateTime')] - private \DateTimeInterface $end; // @phpstan-ignore-line + #[Serializer\Type(name: 'DateTimeImmutable')] + private \DateTimeImmutable $end; // @phpstan-ignore-line public function setTitle(string $title): void { @@ -65,12 +65,12 @@ final class CalendarEvent public function setStart(\DateTimeInterface $start): void { - $this->start = $start; + $this->start = \DateTimeImmutable::createFromInterface($start); } public function setEnd(\DateTimeInterface $end): void { - $this->end = $end; + $this->end = \DateTimeImmutable::createFromInterface($end); } public function setColor(?string $color): void diff --git a/src/API/ProjectController.php b/src/API/ProjectController.php index 89e636cf5..ef57aa05a 100644 --- a/src/API/ProjectController.php +++ b/src/API/ProjectController.php @@ -31,7 +31,7 @@ use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Validator\Constraints; @@ -58,7 +58,7 @@ final class ProjectController extends BaseApiController * Returns a collection of projects (which are visible to the user) */ #[OA\Response(response: 200, description: 'Returns a collection of projects', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/ProjectCollection')))] - #[Rest\Get(path: '', name: 'get_projects')] + #[Route(methods: ['GET'], path: '', name: 'get_projects')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'customer', requirements: '\d+', strict: true, nullable: true, description: 'Customer ID to filter projects')] @@ -156,7 +156,7 @@ final class ProjectController extends BaseApiController * Returns one project */ #[OA\Response(response: 200, description: 'Returns one project entity', content: new OA\JsonContent(ref: '#/components/schemas/ProjectEntity'))] - #[Rest\Get(path: '/{id}', name: 'get_project', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}', name: 'get_project', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getAction(Project $project): Response @@ -172,7 +172,7 @@ final class ProjectController extends BaseApiController */ #[OA\Post(description: 'Creates a new project and returns it afterwards', responses: [new OA\Response(response: 200, description: 'Returns the new created project', content: new OA\JsonContent(ref: '#/components/schemas/ProjectEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/ProjectEditForm'))] - #[Rest\Post(path: '', name: 'post_project')] + #[Route(methods: ['POST'], path: '', name: 'post_project')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postAction(Request $request): Response @@ -214,7 +214,7 @@ final class ProjectController extends BaseApiController #[OA\Patch(description: 'Update an existing project, you can pass all or just a subset of all attributes', responses: [new OA\Response(response: 200, description: 'Returns the updated project', content: new OA\JsonContent(ref: '#/components/schemas/ProjectEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/ProjectEditForm'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Project ID to update', required: true)] - #[Rest\Patch(path: '/{id}', name: 'patch_project', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}', name: 'patch_project', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function patchAction(Request $request, Project $project): Response @@ -253,7 +253,7 @@ final class ProjectController extends BaseApiController #[IsGranted('edit', 'project')] #[OA\Response(response: 200, description: 'Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.', content: new OA\JsonContent(ref: '#/components/schemas/ProjectEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Project record ID to set the meta-field value for', required: true)] - #[Rest\Patch(path: '/{id}/meta', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/meta', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\RequestParam(name: 'name', strict: true, nullable: false, description: 'The meta-field name')] @@ -286,7 +286,7 @@ final class ProjectController extends BaseApiController #[IsGranted('edit', 'project')] #[OA\Response(response: 200, description: 'Returns a collection of project rate entities', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/ProjectRate')))] #[OA\Parameter(name: 'id', in: 'path', description: 'The project whose rates will be returned', required: true)] - #[Rest\Get(path: '/{id}/rates', name: 'get_project_rates', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}/rates', name: 'get_project_rates', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getRatesAction(Project $project): Response @@ -308,7 +308,7 @@ final class ProjectController extends BaseApiController #[OA\Parameter(name: 'rateId', in: 'path', description: 'The rate to remove', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}/rates/{rateId}', name: 'delete_project_rate', requirements: ['id' => '\d+', 'rateId' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}/rates/{rateId}', name: 'delete_project_rate', requirements: ['id' => '\d+', 'rateId' => '\d+'])] public function deleteRateAction(Project $project, #[MapEntity(mapping: ['rateId' => 'id'])] ProjectRate $rate): Response { if ($rate->getProject() !== $project) { @@ -329,7 +329,7 @@ final class ProjectController extends BaseApiController #[OA\Post(responses: [new OA\Response(response: 200, description: 'Returns the new created rate', content: new OA\JsonContent(ref: '#/components/schemas/ProjectRate'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'The project to add the rate for', required: true)] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/ProjectRateForm'))] - #[Rest\Post(path: '/{id}/rates', name: 'post_project_rate', requirements: ['id' => '\d+'])] + #[Route(methods: ['POST'], path: '/{id}/rates', name: 'post_project_rate', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postRateAction(Project $project, Request $request): Response diff --git a/src/API/StatusController.php b/src/API/StatusController.php index 65a403f07..0ae04f0e2 100644 --- a/src/API/StatusController.php +++ b/src/API/StatusController.php @@ -12,13 +12,13 @@ namespace App\API; use App\API\Model\Plugin; use App\API\Model\Version; use App\Plugin\PluginManager; -use FOS\RestBundle\Controller\Annotations as Rest; use FOS\RestBundle\View\View; use FOS\RestBundle\View\ViewHandlerInterface; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity; use OpenApi\Attributes as OA; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[IsGranted('IS_AUTHENTICATED_REMEMBERED')] @@ -33,7 +33,7 @@ final class StatusController extends BaseApiController * A testing route for the API */ #[OA\Response(response: 200, description: "A simple route that returns a 'pong', which you can use for testing the API", content: new OA\JsonContent(example: "{'message': 'pong'}"))] - #[Rest\Get(path: '/ping')] + #[Route(methods: ['GET'], path: '/ping')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function pingAction(): Response @@ -47,7 +47,7 @@ final class StatusController extends BaseApiController * Returns information about the Kimai release */ #[OA\Response(response: 200, description: 'Returns version information about the current release', content: new OA\JsonContent(ref: new Model(type: Version::class)))] - #[Rest\Get(path: '/version')] + #[Route(methods: ['GET'], path: '/version')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function versionAction(): Response @@ -59,7 +59,7 @@ final class StatusController extends BaseApiController * Returns information about installed Plugins */ #[OA\Response(response: 200, description: 'Returns a list of plugin names and versions', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: new Model(type: Plugin::class))))] - #[Rest\Get(path: '/plugins')] + #[Route(methods: ['GET'], path: '/plugins')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function pluginAction(PluginManager $pluginManager): Response diff --git a/src/API/TagController.php b/src/API/TagController.php index 4769941ed..70599e63f 100644 --- a/src/API/TagController.php +++ b/src/API/TagController.php @@ -20,7 +20,7 @@ use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity; use OpenApi\Attributes as OA; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[Route(path: '/tags')] @@ -40,7 +40,7 @@ final class TagController extends BaseApiController * Fetch all existing tags */ #[OA\Response(response: 200, description: 'Returns the collection of all existing tags as string array', content: new OA\JsonContent(type: 'array', items: new OA\Items(type: 'string')))] - #[Rest\Get(name: 'get_tags')] + #[Route(methods: ['GET'], name: 'get_tags')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'name', strict: true, nullable: true, description: 'Search term to filter tag list')] @@ -61,7 +61,7 @@ final class TagController extends BaseApiController */ #[OA\Post(description: 'Creates a new tag and returns it afterwards', responses: [new OA\Response(response: 200, description: 'Returns the new created tag', content: new OA\JsonContent(ref: '#/components/schemas/TagEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/TagEditForm'))] - #[Rest\Post(name: 'post_tag')] + #[Route(methods: ['POST'], name: 'post_tag')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postAction(Request $request): Response @@ -99,7 +99,7 @@ final class TagController extends BaseApiController #[OA\Parameter(name: 'id', in: 'path', description: 'Tag ID to delete', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}', name: 'delete_tag')] + #[Route(methods: ['DELETE'], path: '/{id}', name: 'delete_tag')] public function deleteAction(Tag $tag): Response { $this->repository->deleteTag($tag); diff --git a/src/API/TeamController.php b/src/API/TeamController.php index eed139025..515976482 100644 --- a/src/API/TeamController.php +++ b/src/API/TeamController.php @@ -19,7 +19,6 @@ use App\Repository\ActivityRepository; use App\Repository\CustomerRepository; use App\Repository\ProjectRepository; use App\Repository\TeamRepository; -use FOS\RestBundle\Controller\Annotations as Rest; use FOS\RestBundle\View\View; use FOS\RestBundle\View\ViewHandlerInterface; use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity; @@ -28,7 +27,7 @@ use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[Route(path: '/teams')] @@ -49,7 +48,7 @@ final class TeamController extends BaseApiController */ #[IsGranted('view_team')] #[OA\Response(response: 200, description: 'Returns the collection of teams', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/TeamCollection')))] - #[Rest\Get(path: '', name: 'get_teams')] + #[Route(methods: ['GET'], path: '', name: 'get_teams')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function cgetAction(): Response @@ -67,7 +66,7 @@ final class TeamController extends BaseApiController */ #[IsGranted('view_team')] #[OA\Response(response: 200, description: 'Returns one team entity', content: new OA\JsonContent(ref: '#/components/schemas/Team'))] - #[Rest\Get(path: '/{id}', name: 'get_team', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}', name: 'get_team', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getAction(Team $team): Response @@ -86,7 +85,7 @@ final class TeamController extends BaseApiController #[OA\Parameter(name: 'id', in: 'path', description: 'Team ID to delete', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}', name: 'delete_team', requirements: ['id' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}', name: 'delete_team', requirements: ['id' => '\d+'])] public function deleteAction(Team $team): Response { $this->repository->deleteTeam($team); @@ -102,7 +101,7 @@ final class TeamController extends BaseApiController #[IsGranted('create_team')] #[OA\Post(description: 'Creates a new team and returns it afterwards', responses: [new OA\Response(response: 200, description: 'Returns the new created team', content: new OA\JsonContent(ref: '#/components/schemas/Team'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/TeamEditForm'))] - #[Rest\Post(path: '', name: 'post_team')] + #[Route(methods: ['POST'], path: '', name: 'post_team')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postAction(Request $request): Response @@ -134,7 +133,7 @@ final class TeamController extends BaseApiController #[OA\Patch(description: 'Update an existing team, you can pass all or just a subset of all attributes (passing members will replace all existing ones)', responses: [new OA\Response(response: 200, description: 'Returns the updated team', content: new OA\JsonContent(ref: '#/components/schemas/Team'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/TeamEditForm'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Team ID to update', required: true)] - #[Rest\Patch(path: '/{id}', name: 'patch_team', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}', name: 'patch_team', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function patchAction(Request $request, Team $team): Response @@ -174,7 +173,7 @@ final class TeamController extends BaseApiController #[OA\Post(responses: [new OA\Response(response: 200, description: 'Adds a new user to a team.', content: new OA\JsonContent(ref: '#/components/schemas/Team'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'The team which will receive the new member', required: true)] #[OA\Parameter(name: 'userId', in: 'path', description: 'The team member to add (User ID)', required: true)] - #[Rest\Post(path: '/{id}/members/{userId}', name: 'post_team_member', requirements: ['id' => '\d+', 'userId' => '\d+'])] + #[Route(methods: ['POST'], path: '/{id}/members/{userId}', name: 'post_team_member', requirements: ['id' => '\d+', 'userId' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postMemberAction(Team $team, #[MapEntity(mapping: ['userId' => 'id'])] User $member): Response @@ -202,7 +201,7 @@ final class TeamController extends BaseApiController #[OA\Parameter(name: 'userId', in: 'path', description: 'The team member to remove (User ID)', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}/members/{userId}', name: 'delete_team_member', requirements: ['id' => '\d+', 'userId' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}/members/{userId}', name: 'delete_team_member', requirements: ['id' => '\d+', 'userId' => '\d+'])] public function deleteMemberAction(Team $team, #[MapEntity(mapping: ['userId' => 'id'])] User $member): Response { if (!$member->isInTeam($team)) { @@ -230,7 +229,7 @@ final class TeamController extends BaseApiController #[OA\Post(responses: [new OA\Response(response: 200, description: 'Adds a new customer to a team.', content: new OA\JsonContent(ref: '#/components/schemas/Team'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'The team that is granted access', required: true)] #[OA\Parameter(name: 'customerId', in: 'path', description: 'The customer to grant acecess to (Customer ID)', required: true)] - #[Rest\Post(path: '/{id}/customers/{customerId}', name: 'post_team_customer', requirements: ['id' => '\d+', 'customerId' => '\d+'])] + #[Route(methods: ['POST'], path: '/{id}/customers/{customerId}', name: 'post_team_customer', requirements: ['id' => '\d+', 'customerId' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postCustomerAction(Team $team, #[MapEntity(mapping: ['customerId' => 'id'])] Customer $customer, CustomerRepository $customerRepository): Response @@ -257,7 +256,7 @@ final class TeamController extends BaseApiController #[OA\Parameter(name: 'customerId', in: 'path', description: 'The customer to remove (Customer ID)', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}/customers/{customerId}', name: 'delete_team_customer', requirements: ['id' => '\d+', 'customerId' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}/customers/{customerId}', name: 'delete_team_customer', requirements: ['id' => '\d+', 'customerId' => '\d+'])] public function deleteCustomerAction(Team $team, #[MapEntity(mapping: ['customerId' => 'id'])] Customer $customer, CustomerRepository $customerRepository): Response { if (!$team->hasCustomer($customer)) { @@ -280,7 +279,7 @@ final class TeamController extends BaseApiController #[OA\Post(responses: [new OA\Response(response: 200, description: 'Adds a new project to a team.', content: new OA\JsonContent(ref: '#/components/schemas/Team'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'The team that is granted access', required: true)] #[OA\Parameter(name: 'projectId', in: 'path', description: 'The project to grant acecess to (Project ID)', required: true)] - #[Rest\Post(path: '/{id}/projects/{projectId}', name: 'post_team_project', requirements: ['id' => '\d+', 'projectId' => '\d+'])] + #[Route(methods: ['POST'], path: '/{id}/projects/{projectId}', name: 'post_team_project', requirements: ['id' => '\d+', 'projectId' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postProjectAction(Team $team, #[MapEntity(mapping: ['projectId' => 'id'])] Project $project, ProjectRepository $projectRepository): Response @@ -307,7 +306,7 @@ final class TeamController extends BaseApiController #[OA\Parameter(name: 'projectId', in: 'path', description: 'The project to remove (Project ID)', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}/projects/{projectId}', name: 'delete_team_project', requirements: ['id' => '\d+', 'projectId' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}/projects/{projectId}', name: 'delete_team_project', requirements: ['id' => '\d+', 'projectId' => '\d+'])] public function deleteProjectAction(Team $team, #[MapEntity(mapping: ['projectId' => 'id'])] Project $project, ProjectRepository $projectRepository): Response { if (!$team->hasProject($project)) { @@ -330,7 +329,7 @@ final class TeamController extends BaseApiController #[OA\Post(responses: [new OA\Response(response: 200, description: 'Adds a new activity to a team.', content: new OA\JsonContent(ref: '#/components/schemas/Team'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'The team that is granted access', required: true)] #[OA\Parameter(name: 'activityId', in: 'path', description: 'The activity to grant acecess to (Activity ID)', required: true)] - #[Rest\Post(path: '/{id}/activities/{activityId}', name: 'post_team_activity', requirements: ['id' => '\d+', 'activityId' => '\d+'])] + #[Route(methods: ['POST'], path: '/{id}/activities/{activityId}', name: 'post_team_activity', requirements: ['id' => '\d+', 'activityId' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postActivityAction(Team $team, #[MapEntity(mapping: ['activityId' => 'id'])] Activity $activity, ActivityRepository $activityRepository): Response @@ -357,7 +356,7 @@ final class TeamController extends BaseApiController #[OA\Parameter(name: 'activityId', in: 'path', description: 'The activity to remove (Activity ID)', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}/activities/{activityId}', name: 'delete_team_activity', requirements: ['id' => '\d+', 'activityId' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}/activities/{activityId}', name: 'delete_team_activity', requirements: ['id' => '\d+', 'activityId' => '\d+'])] public function deleteActivityAction(Team $team, #[MapEntity(mapping: ['activityId' => 'id'])] Activity $activity, ActivityRepository $activityRepository): Response { if (!$team->hasActivity($activity)) { diff --git a/src/API/TimesheetController.php b/src/API/TimesheetController.php index 8e2fa9e51..9952a64a8 100644 --- a/src/API/TimesheetController.php +++ b/src/API/TimesheetController.php @@ -38,7 +38,7 @@ use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\Form\FormError; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Validator\Constraints; @@ -72,7 +72,7 @@ final class TimesheetController extends BaseApiController */ #[IsGranted(new Expression("is_granted('view_own_timesheet') or is_granted('view_other_timesheet')"))] #[OA\Response(response: 200, description: 'Returns a collection of timesheet records. The datetime fields are given in the users local time including the timezone offset (ISO-8601).', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/TimesheetCollection')))] - #[Rest\Get(path: '', name: 'get_timesheets')] + #[Route(methods: ['GET'], path: '', name: 'get_timesheets')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'user', requirements: '\d+|all', strict: true, nullable: true, description: "User ID to filter timesheets. Needs permission 'view_other_timesheet', pass 'all' to fetch data for all user (default: current user)")] @@ -273,7 +273,7 @@ final class TimesheetController extends BaseApiController #[IsGranted('view', 'timesheet')] #[OA\Response(response: 200, description: 'Returns one timesheet record. Be aware that the datetime fields are given in the users local time including the timezone offset via ISO 8601.', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to fetch', required: true)] - #[Rest\Get(path: '/{id}', name: 'get_timesheet', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}', name: 'get_timesheet', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getAction(Timesheet $timesheet): Response @@ -290,7 +290,7 @@ final class TimesheetController extends BaseApiController #[IsGranted('create_own_timesheet')] #[OA\Post(description: 'Creates a new timesheet record for the current user and returns it afterwards.', responses: [new OA\Response(response: 200, description: 'Returns the new created timesheet', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEditForm'))] - #[Rest\Post(path: '', name: 'post_timesheet')] + #[Route(methods: ['POST'], path: '', name: 'post_timesheet')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'full', strict: true, nullable: true, description: 'Allows to fetch fully serialized objects including subresources (TimesheetExpanded). Allowed values: true (default: false)')] @@ -346,7 +346,7 @@ final class TimesheetController extends BaseApiController #[OA\Patch(description: 'Update an existing timesheet record, you can pass all or just a subset of the attributes.', responses: [new OA\Response(response: 200, description: 'Returns the updated timesheet', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))])] #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to update', required: true)] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEditForm'))] - #[Rest\Patch(path: '/{id}', name: 'patch_timesheet', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}', name: 'patch_timesheet', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function patchAction(Request $request, Timesheet $timesheet): Response @@ -392,7 +392,7 @@ final class TimesheetController extends BaseApiController #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to delete', required: true)] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] - #[Rest\Delete(path: '/{id}', name: 'delete_timesheet', requirements: ['id' => '\d+'])] + #[Route(methods: ['DELETE'], path: '/{id}', name: 'delete_timesheet', requirements: ['id' => '\d+'])] public function deleteAction(Timesheet $timesheet): Response { $this->service->deleteTimesheet($timesheet); @@ -407,7 +407,7 @@ final class TimesheetController extends BaseApiController */ #[IsGranted('view_own_timesheet')] #[OA\Response(response: 200, description: 'Returns the collection of recent user activities (always the latest entry of a unique working set grouped by customer, project and activity)', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/TimesheetCollectionExpanded')))] - #[Rest\Get(path: '/recent', name: 'recent_timesheet')] + #[Route(methods: ['GET'], path: '/recent', name: 'recent_timesheet')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'begin', requirements: [new Constraints\DateTime(format: 'Y-m-d\TH:i:s')], strict: true, nullable: true, description: 'Only records after this date will be included. Default: today - 1 year (format: HTML5)')] @@ -443,7 +443,7 @@ final class TimesheetController extends BaseApiController */ #[IsGranted('view_own_timesheet')] #[OA\Response(response: 200, description: 'Returns the collection of active timesheet records for the current user', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/TimesheetCollectionExpanded')))] - #[Rest\Get(path: '/active', name: 'active_timesheet')] + #[Route(methods: ['GET'], path: '/active', name: 'active_timesheet')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function activeAction(): Response @@ -468,8 +468,8 @@ final class TimesheetController extends BaseApiController #[IsGranted('stop', 'timesheet')] #[OA\Response(response: 200, description: 'Stops an active timesheet record and returns it afterwards.', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to stop', required: true)] - #[Rest\Get(path: '/{id}/stop', name: 'stop_timesheet_get', requirements: ['id' => '\d+'])] - #[Rest\Patch(path: '/{id}/stop', name: 'stop_timesheet', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}/stop', name: 'stop_timesheet_get', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/stop', name: 'stop_timesheet', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function stopAction(Timesheet $timesheet): Response @@ -488,8 +488,8 @@ final class TimesheetController extends BaseApiController #[IsGranted('start', 'timesheet')] #[OA\Response(response: 200, description: 'Restarts a timesheet record for the same customer, project, activity combination. The current user will be the owner of the new record. Kimai tries to stop running records, which is expected to fail depending on the configured rules. Data will be copied from the original record if requested.', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to restart', required: true)] - #[Rest\Get(path: '/{id}/restart', name: 'restart_timesheet_get', requirements: ['id' => '\d+'])] - #[Rest\Patch(path: '/{id}/restart', name: 'restart_timesheet', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}/restart', name: 'restart_timesheet_get', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/restart', name: 'restart_timesheet', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\RequestParam(name: 'copy', requirements: 'all', strict: true, nullable: true, description: 'Whether data should be copied to the new entry. Allowed values: all (default: nothing is copied)')] @@ -551,7 +551,7 @@ final class TimesheetController extends BaseApiController #[IsGranted('duplicate', 'timesheet')] #[OA\Response(response: 200, description: 'Duplicates a timesheet record, resetting the export state only.', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to duplicate', required: true)] - #[Rest\Patch(path: '/{id}/duplicate', name: 'duplicate_timesheet', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/duplicate', name: 'duplicate_timesheet', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function duplicateAction(Timesheet $timesheet): Response @@ -574,7 +574,7 @@ final class TimesheetController extends BaseApiController #[IsGranted('edit_export', 'timesheet')] #[OA\Response(response: 200, description: 'Switches the exported state on the record and therefor locks / unlocks it for further updates. Needs edit_export_*_timesheet permission.', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to switch export state', required: true)] - #[Rest\Patch(path: '/{id}/export', name: 'export_timesheet', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/export', name: 'export_timesheet', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function exportAction(Timesheet $timesheet): Response @@ -599,7 +599,7 @@ final class TimesheetController extends BaseApiController #[IsGranted('edit', 'timesheet')] #[OA\Response(response: 200, description: 'Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.', content: new OA\JsonContent(ref: '#/components/schemas/TimesheetEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'Timesheet record ID to set the meta-field value for', required: true)] - #[Rest\Patch(path: '/{id}/meta', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}/meta', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\RequestParam(name: 'name', strict: true, nullable: false, description: 'The meta-field name')] diff --git a/src/API/UserController.php b/src/API/UserController.php index 5f8ee6b19..a14743869 100644 --- a/src/API/UserController.php +++ b/src/API/UserController.php @@ -28,7 +28,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[Route(path: '/users')] @@ -54,7 +54,7 @@ final class UserController extends BaseApiController */ #[IsGranted('view_user')] #[OA\Response(response: 200, description: 'Returns the collection of users. Required permission: view_user', content: new OA\JsonContent(type: 'array', items: new OA\Items(ref: '#/components/schemas/UserCollection')))] - #[Rest\Get(path: '', name: 'get_users')] + #[Route(methods: ['GET'], path: '', name: 'get_users')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] #[Rest\QueryParam(name: 'visible', requirements: '1|2|3', default: 1, strict: true, nullable: true, description: 'Visibility status to filter users: 1=visible, 2=hidden, 3=all')] @@ -107,7 +107,7 @@ final class UserController extends BaseApiController #[IsGranted('view', 'profile')] #[OA\Response(response: 200, description: 'Return one user entity.', content: new OA\JsonContent(ref: '#/components/schemas/UserEntity'))] #[OA\Parameter(name: 'id', in: 'path', description: 'User ID to fetch', required: true)] - #[Rest\Get(path: '/{id}', name: 'get_user', requirements: ['id' => '\d+'])] + #[Route(methods: ['GET'], path: '/{id}', name: 'get_user', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function getAction(User $profile, EventDispatcherInterface $dispatcher): Response @@ -126,7 +126,7 @@ final class UserController extends BaseApiController * Return the current user entity */ #[OA\Response(response: 200, description: 'Return the current user entity.', content: new OA\JsonContent(ref: '#/components/schemas/UserEntity'))] - #[Rest\Get(path: '/me', name: 'me_user')] + #[Route(methods: ['GET'], path: '/me', name: 'me_user')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function meAction(): Response @@ -143,7 +143,7 @@ final class UserController extends BaseApiController #[IsGranted('create_user')] #[OA\Post(description: 'Creates a new user and returns it afterwards')] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/UserCreateForm'))] - #[Rest\Post(path: '', name: 'post_user')] + #[Route(methods: ['POST'], path: '', name: 'post_user')] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function postAction(Request $request): Response @@ -197,7 +197,7 @@ final class UserController extends BaseApiController #[OA\Patch(description: 'Update an existing user, you can pass all or just a subset of all attributes (passing roles will replace all existing ones)', responses: [new OA\Response(response: 200, description: 'Returns the updated user', content: new OA\JsonContent(ref: '#/components/schemas/UserEntity'))])] #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/UserEditForm'))] #[OA\Parameter(name: 'id', in: 'path', description: 'User ID to update', required: true)] - #[Rest\Patch(path: '/{id}', name: 'patch_user', requirements: ['id' => '\d+'])] + #[Route(methods: ['PATCH'], path: '/{id}', name: 'patch_user', requirements: ['id' => '\d+'])] #[ApiSecurity(name: 'apiUser')] #[ApiSecurity(name: 'apiToken')] public function patchAction(Request $request, User $profile): Response diff --git a/src/Constants.php b/src/Constants.php index 879187b67..a1394d2d3 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -17,11 +17,11 @@ class Constants /** * The current release version */ - public const VERSION = '2.7.0'; + public const VERSION = '2.8.0'; /** * The current release: major * 10000 + minor * 100 + patch */ - public const VERSION_ID = 20700; + public const VERSION_ID = 20800; /** * The software name */ diff --git a/src/Controller/AbstractController.php b/src/Controller/AbstractController.php index 8f6c0b44e..c88d79860 100644 --- a/src/Controller/AbstractController.php +++ b/src/Controller/AbstractController.php @@ -159,11 +159,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv /** * Adds a fully translated (both $message and all keys in $parameter) flash message to the stack. * - * @param string $type - * @param string $message * @param array $parameter - * @return void - * @throws \Exception */ private function addFlashTranslated(string $type, string $message, array $parameter = []): void { @@ -183,9 +179,6 @@ abstract class AbstractController extends BaseAbstractController implements Serv /** * Handles exception flash messages for failed update/create actions. - * @param \Exception $exception - * @param FormInterface $form - * @return void */ protected function handleFormUpdateException(\Exception $exception, FormInterface $form): void { @@ -262,10 +255,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv } /** - * @param FormInterface $form - * @param Request $request * @param array $filterParams parameter names, which should not be saved (neither session, nor database) - * @return bool * @throws \Exception */ protected function handleSearch(FormInterface $form, Request $request, array $filterParams = []): bool diff --git a/src/Controller/Reporting/CustomerMonthlyProjectsController.php b/src/Controller/Reporting/CustomerMonthlyProjectsController.php index f0a8ca840..0d1a8ba64 100644 --- a/src/Controller/Reporting/CustomerMonthlyProjectsController.php +++ b/src/Controller/Reporting/CustomerMonthlyProjectsController.php @@ -16,6 +16,7 @@ use App\Reporting\CustomerMonthlyProjects\CustomerMonthlyProjects; use App\Reporting\CustomerMonthlyProjects\CustomerMonthlyProjectsForm; use App\Reporting\CustomerMonthlyProjects\CustomerMonthlyProjectsRepository; use App\Repository\Query\UserQuery; +use App\Repository\Query\VisibilityInterface; use App\Repository\UserRepository; use PhpOffice\PhpSpreadsheet\Reader\Html; use Symfony\Component\HttpFoundation\Request; @@ -58,6 +59,7 @@ final class CustomerMonthlyProjectsController extends AbstractController $dateTimeFactory = $this->getDateTimeFactory(); $query = new UserQuery(); + $query->setVisibility(VisibilityInterface::SHOW_BOTH); $query->setSystemAccount(false); $query->setCurrentUser($currentUser); $allUsers = $userRepository->getUsersForQuery($query); diff --git a/src/Controller/Reporting/ReportUsersMonthController.php b/src/Controller/Reporting/ReportUsersMonthController.php index 087e4231b..56992faa9 100644 --- a/src/Controller/Reporting/ReportUsersMonthController.php +++ b/src/Controller/Reporting/ReportUsersMonthController.php @@ -16,6 +16,7 @@ use App\Model\DailyStatistic; use App\Reporting\MonthlyUserList\MonthlyUserList; use App\Reporting\MonthlyUserList\MonthlyUserListForm; use App\Repository\Query\UserQuery; +use App\Repository\Query\VisibilityInterface; use App\Repository\UserRepository; use App\Timesheet\TimesheetStatisticService; use PhpOffice\PhpSpreadsheet\Reader\Html; @@ -68,6 +69,7 @@ final class ReportUsersMonthController extends AbstractController $form->submit($request->query->all(), false); $query = new UserQuery(); + $query->setVisibility(VisibilityInterface::SHOW_BOTH); $query->setSystemAccount(false); $query->setCurrentUser($currentUser); diff --git a/src/Controller/Reporting/ReportUsersWeekController.php b/src/Controller/Reporting/ReportUsersWeekController.php index 4b20c7d9d..f0d812b41 100644 --- a/src/Controller/Reporting/ReportUsersWeekController.php +++ b/src/Controller/Reporting/ReportUsersWeekController.php @@ -16,6 +16,7 @@ use App\Model\DailyStatistic; use App\Reporting\WeeklyUserList\WeeklyUserList; use App\Reporting\WeeklyUserList\WeeklyUserListForm; use App\Repository\Query\UserQuery; +use App\Repository\Query\VisibilityInterface; use App\Repository\UserRepository; use App\Timesheet\TimesheetStatisticService; use PhpOffice\PhpSpreadsheet\Reader\Html; @@ -68,6 +69,7 @@ final class ReportUsersWeekController extends AbstractController $form->submit($request->query->all(), false); $query = new UserQuery(); + $query->setVisibility(VisibilityInterface::SHOW_BOTH); $query->setSystemAccount(false); $query->setCurrentUser($currentUser); diff --git a/src/Controller/Reporting/ReportUsersYearController.php b/src/Controller/Reporting/ReportUsersYearController.php index 88e308a23..32bb6e865 100644 --- a/src/Controller/Reporting/ReportUsersYearController.php +++ b/src/Controller/Reporting/ReportUsersYearController.php @@ -17,6 +17,7 @@ use App\Model\MonthlyStatistic; use App\Reporting\YearlyUserList\YearlyUserList; use App\Reporting\YearlyUserList\YearlyUserListForm; use App\Repository\Query\UserQuery; +use App\Repository\Query\VisibilityInterface; use App\Repository\UserRepository; use App\Timesheet\TimesheetStatisticService; use PhpOffice\PhpSpreadsheet\Reader\Html; @@ -75,6 +76,7 @@ final class ReportUsersYearController extends AbstractController $form->submit($request->query->all(), false); $query = new UserQuery(); + $query->setVisibility(VisibilityInterface::SHOW_BOTH); $query->setSystemAccount(false); $query->setCurrentUser($currentUser); diff --git a/symfony.lock b/symfony.lock index 6aebb4f66..4cc98547b 100644 --- a/symfony.lock +++ b/symfony.lock @@ -156,9 +156,6 @@ "kevinpapst/tabler-bundle": { "version": "dev-initial" }, - "laminas/laminas-escaper": { - "version": "2.7.0" - }, "league/csv": { "version": "9.4.1" }, diff --git a/templates/reporting/user_list_period_data.html.twig b/templates/reporting/user_list_period_data.html.twig index a095e79b9..15f6b82bb 100644 --- a/templates/reporting/user_list_period_data.html.twig +++ b/templates/reporting/user_list_period_data.html.twig @@ -38,6 +38,25 @@ {% set usersTotalDuration = 0 %} {% set usersTotalInternalRate = 0 %} {% set usersTotalRate = 0 %} + {% for period in attribute(userPeriod, period_attribute) %} + {% if period.totalDuration > 0 %} + {% set usersTotalDuration = usersTotalDuration + period.totalDuration %} + {% set absoluteDuration = absoluteDuration + period.totalDuration %} + {% endif %} + {% if period.totalInternalRate > 0 %} + {% set usersTotalInternalRate = usersTotalInternalRate + period.totalInternalRate %} + {% set absoluteInternalRate = absoluteInternalRate + period.totalInternalRate %} + {% endif %} + {% if period.totalRate > 0 %} + {% set usersTotalRate = usersTotalRate + period.totalRate %} + {% set absoluteRate = absoluteRate + period.totalRate %} + {% endif %} + {% set reportDateKey = period.date|report_date %} + {% set totalsDuration = totalsDuration|merge({(reportDateKey): (totalsDuration[reportDateKey] + period.totalDuration)}) %} + {% set totalsInternalRate = totalsInternalRate|merge({(reportDateKey): (totalsInternalRate[reportDateKey] + period.totalInternalRate)}) %} + {% set totalsRate = totalsRate|merge({(reportDateKey): (totalsRate[reportDateKey] + period.totalRate)}) %} + {% endfor %} + {% if userPeriod.user.enabled or usersTotalDuration > 0 %} {% if with_avatar %} @@ -51,24 +70,6 @@ {% if showAccountNumber %} {{ userPeriod.user.accountNumber }} {% endif %} - {% for period in attribute(userPeriod, period_attribute) %} - {% if period.totalDuration > 0 %} - {% set usersTotalDuration = usersTotalDuration + period.totalDuration %} - {% set absoluteDuration = absoluteDuration + period.totalDuration %} - {% endif %} - {% if period.totalInternalRate > 0 %} - {% set usersTotalInternalRate = usersTotalInternalRate + period.totalInternalRate %} - {% set absoluteInternalRate = absoluteInternalRate + period.totalInternalRate %} - {% endif %} - {% if period.totalRate > 0 %} - {% set usersTotalRate = usersTotalRate + period.totalRate %} - {% set absoluteRate = absoluteRate + period.totalRate %} - {% endif %} - {% set reportDateKey = period.date|report_date %} - {% set totalsDuration = totalsDuration|merge({(reportDateKey): (totalsDuration[reportDateKey] + period.totalDuration)}) %} - {% set totalsInternalRate = totalsInternalRate|merge({(reportDateKey): (totalsInternalRate[reportDateKey] + period.totalInternalRate)}) %} - {% set totalsRate = totalsRate|merge({(reportDateKey): (totalsRate[reportDateKey] + period.totalRate)}) %} - {% endfor %} {% if dataType == 'rate' %} {% block total_rate_user %}{% endblock %} @@ -92,6 +93,7 @@ {% endfor %} + {% endif %} {% endfor %} diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf index b40d6c9ec..9adf20892 100644 --- a/translations/messages.de.xlf +++ b/translations/messages.de.xlf @@ -1689,6 +1689,10 @@ days Tage + + unpaid_vacation + Unbezahlter Urlaub + diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index aed32124e..93a0aff0d 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -1689,6 +1689,10 @@ days Days + + unpaid_vacation + Unpaid holidays + diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf index 1a8c845b6..fb66883c6 100644 --- a/translations/validators.de.xlf +++ b/translations/validators.de.xlf @@ -148,7 +148,7 @@ You can book a maximum of {{ value }} days at once. - Sie können maximal {{ value }} Tage auf einmal buchen. + Sie können maximal {{ value }} Tage auf einmal buchen, aktuell sind {{ selected }} ausgewählt. The period of absence must not extend beyond the turn of the year. diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf index 4b4331d3f..d386e9005 100644 --- a/translations/validators.en.xlf +++ b/translations/validators.en.xlf @@ -148,7 +148,7 @@ You can book a maximum of {{ value }} days at once. - You can book a maximum of {{ value }} days at once. + You can book a maximum of {{ value }} days at once, you currently selected {{ selected }}. The period of absence must not extend beyond the turn of the year.