diff --git a/composer.json b/composer.json index 07c9666b..2b2a585f 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "friendsofsymfony/rest-bundle": "^3.0", "gedmo/doctrine-extensions": "^3.6", "jms/serializer-bundle": "^5.0", - "kevinpapst/tabler-bundle": "^0.14", + "kevinpapst/tabler-bundle": "^0.15", "league/csv": "^9.4", "mpdf/mpdf": "^8.0", "nelmio/api-doc-bundle": "^4.0", diff --git a/composer.lock b/composer.lock index db9e45ae..ff76e4a1 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": "1bdbdd73cd12f5111c5e34db51d7ad10", + "content-hash": "276b8b25218c04ae6527eccfec7f1464", "packages": [ { "name": "bacon/bacon-qr-code", @@ -661,16 +661,16 @@ }, { "name": "doctrine/dbal", - "version": "3.6.1", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e" + "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/57815c7bbcda3cd18871d253c1dd8cbe56f8526e", - "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/b4bd1cfbd2b916951696d82e57d054394d84864c", + "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c", "shasum": "" }, "require": { @@ -686,9 +686,9 @@ "doctrine/coding-standard": "11.1.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2022.3", - "phpstan/phpstan": "1.10.3", + "phpstan/phpstan": "1.10.9", "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.4", + "phpunit/phpunit": "9.6.6", "psalm/plugin-phpunit": "0.18.4", "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^5.4|^6.0", @@ -753,7 +753,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.6.1" + "source": "https://github.com/doctrine/dbal/tree/3.6.2" }, "funding": [ { @@ -769,7 +769,7 @@ "type": "tidelift" } ], - "time": "2023-03-02T19:26:24+00:00" + "time": "2023-04-14T07:25:38+00:00" }, { "name": "doctrine/deprecations", @@ -816,16 +816,16 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "2.9.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "9819c00c2eea750b99902f244309b824911b72b2" + "reference": "7539b3c8bd620f7df6c2c6d510204bd2ce0064e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/9819c00c2eea750b99902f244309b824911b72b2", - "reference": "9819c00c2eea750b99902f244309b824911b72b2", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/7539b3c8bd620f7df6c2c6d510204bd2ce0064e3", + "reference": "7539b3c8bd620f7df6c2c6d510204bd2ce0064e3", "shasum": "" }, "require": { @@ -912,7 +912,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/2.9.0" + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.9.1" }, "funding": [ { @@ -928,7 +928,7 @@ "type": "tidelift" } ], - "time": "2023-03-23T20:02:57+00:00" + "time": "2023-04-14T05:39:34+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", @@ -1449,29 +1449,29 @@ }, { "name": "doctrine/orm", - "version": "2.14.2", + "version": "2.15.0", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "e5fb1a4a8f5aa4e37612f66a22aac10291bcbb52" + "reference": "7b5fafffbeb560e75adc349e71bf1e90463796d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/e5fb1a4a8f5aa4e37612f66a22aac10291bcbb52", - "reference": "e5fb1a4a8f5aa4e37612f66a22aac10291bcbb52", + "url": "https://api.github.com/repos/doctrine/orm/zipball/7b5fafffbeb560e75adc349e71bf1e90463796d2", + "reference": "7b5fafffbeb560e75adc349e71bf1e90463796d2", "shasum": "" }, "require": { "composer-runtime-api": "^2", "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5 || ^2.0", + "doctrine/collections": "^1.5 || ^2.1", "doctrine/common": "^3.0.3", "doctrine/dbal": "^2.13.1 || ^3.2", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", - "doctrine/instantiator": "^1.3", - "doctrine/lexer": "^1.2.3 || ^2", + "doctrine/instantiator": "^1.3 || ^2", + "doctrine/lexer": "^2", "doctrine/persistence": "^2.4 || ^3", "ext-ctype": "*", "php": "^7.1 || ^8.0", @@ -1485,9 +1485,9 @@ }, "require-dev": { "doctrine/annotations": "^1.13 || ^2", - "doctrine/coding-standard": "^9.0.2 || ^11.0", + "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.10.6", + "phpstan/phpstan": "~1.4.10 || 1.10.14", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", @@ -1544,9 +1544,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.14.2" + "source": "https://github.com/doctrine/orm/tree/2.15.0" }, - "time": "2023-03-30T15:18:54+00:00" + "time": "2023-04-26T18:52:02+00:00" }, { "name": "doctrine/persistence", @@ -2416,16 +2416,16 @@ }, { "name": "kevinpapst/tabler-bundle", - "version": "0.14", + "version": "0.15", "source": { "type": "git", "url": "https://github.com/kevinpapst/TablerBundle.git", - "reference": "49db98ed5923cdd45aeb4316f08c914979722731" + "reference": "570cdda287a49127217f0f2aa4425d3174073bdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kevinpapst/TablerBundle/zipball/49db98ed5923cdd45aeb4316f08c914979722731", - "reference": "49db98ed5923cdd45aeb4316f08c914979722731", + "url": "https://api.github.com/repos/kevinpapst/TablerBundle/zipball/570cdda287a49127217f0f2aa4425d3174073bdb", + "reference": "570cdda287a49127217f0f2aa4425d3174073bdb", "shasum": "" }, "require": { @@ -2474,7 +2474,7 @@ "description": "Admin/Backend theme bundle for Symfony based on Tabler.io", "support": { "issues": "https://github.com/kevinpapst/TablerBundle/issues", - "source": "https://github.com/kevinpapst/TablerBundle/tree/0.14" + "source": "https://github.com/kevinpapst/TablerBundle/tree/0.15" }, "funding": [ { @@ -2486,7 +2486,7 @@ "type": "github" } ], - "time": "2023-03-29T10:36:05+00:00" + "time": "2023-04-06T16:30:28+00:00" }, { "name": "laminas/laminas-escaper", @@ -2978,27 +2978,27 @@ }, { "name": "mpdf/mpdf", - "version": "v8.1.5", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/mpdf/mpdf.git", - "reference": "c264ce27af0d794ecd04e201b7e37a06b8a9d720" + "reference": "146c7c1dfd21c826b9d5bbfe3c15e52fd933c90f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mpdf/mpdf/zipball/c264ce27af0d794ecd04e201b7e37a06b8a9d720", - "reference": "c264ce27af0d794ecd04e201b7e37a06b8a9d720", + "url": "https://api.github.com/repos/mpdf/mpdf/zipball/146c7c1dfd21c826b9d5bbfe3c15e52fd933c90f", + "reference": "146c7c1dfd21c826b9d5bbfe3c15e52fd933c90f", "shasum": "" }, "require": { "ext-gd": "*", "ext-mbstring": "*", + "mpdf/psr-log-aware-trait": "^2.0 || ^3.0", "myclabs/deep-copy": "^1.7", "paragonie/random_compat": "^1.4|^2.0|^9.99.99", "php": "^5.6 || ^7.0 || ~8.0.0 || ~8.1.0 || ~8.2.0", - "php-http/message-factory": "^1.0", "psr/http-message": "^1.0", - "psr/log": "^1.0 || ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", "setasign/fpdi": "^2.1" }, "require-dev": { @@ -3051,7 +3051,51 @@ "type": "custom" } ], - "time": "2023-04-04T15:06:48+00:00" + "time": "2023-05-03T19:36:43+00:00" + }, + { + "name": "mpdf/psr-log-aware-trait", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/mpdf/psr-log-aware-trait.git", + "reference": "a633da6065e946cc491e1c962850344bb0bf3e78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpdf/psr-log-aware-trait/zipball/a633da6065e946cc491e1c962850344bb0bf3e78", + "reference": "a633da6065e946cc491e1c962850344bb0bf3e78", + "shasum": "" + }, + "require": { + "psr/log": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Mpdf\\PsrLogAwareTrait\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Dorison", + "email": "mark@chromatichq.com" + }, + { + "name": "Kristofer Widholm", + "email": "kristofer@chromatichq.com" + } + ], + "description": "Trait to allow support of different psr/log versions.", + "support": { + "issues": "https://github.com/mpdf/psr-log-aware-trait/issues", + "source": "https://github.com/mpdf/psr-log-aware-trait/tree/v3.0.0" + }, + "time": "2023-05-03T06:19:36+00:00" }, { "name": "myclabs/deep-copy", @@ -3407,16 +3451,16 @@ }, { "name": "pagerfanta/pagerfanta", - "version": "v3.7.0", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/BabDev/Pagerfanta.git", - "reference": "d0230abaf94c2625b77a8e05d0c79fea9d80fda5" + "reference": "a07c84296e491add39d103b812129de77610c33b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/BabDev/Pagerfanta/zipball/d0230abaf94c2625b77a8e05d0c79fea9d80fda5", - "reference": "d0230abaf94c2625b77a8e05d0c79fea9d80fda5", + "url": "https://api.github.com/repos/BabDev/Pagerfanta/zipball/a07c84296e491add39d103b812129de77610c33b", + "reference": "a07c84296e491add39d103b812129de77610c33b", "shasum": "" }, "require": { @@ -3433,7 +3477,7 @@ "doctrine/phpcr-odm": "<1.5", "ruflin/elastica": "<6.0", "solarium/solarium": "<5.0", - "twig/twig": "<1.35 || >=2.0,<2.5" + "twig/twig": "<2.13" }, "replace": { "pagerfanta/core": "self.version", @@ -3454,17 +3498,16 @@ "doctrine/mongodb-odm": "^2.2.2", "doctrine/orm": "^2.8", "doctrine/phpcr-odm": "^1.5", - "friendsofphp/php-cs-fixer": "^3.13", - "jackalope/jackalope-doctrine-dbal": "^1.6", + "jackalope/jackalope-doctrine-dbal": "^1.7.4", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "1.9.2", - "phpstan/phpstan-phpunit": "1.2.2", - "phpunit/phpunit": "9.5.26", + "phpstan/phpstan": "1.9.14", + "phpstan/phpstan-phpunit": "1.3.3", + "phpunit/phpunit": "9.6.7 || 10.1.0", + "rector/rector": "0.15.12", "ruflin/elastica": "^6.0 || ^7.0", "solarium/solarium": "^5.0 || ^6.0", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "symfony/phpunit-bridge": "^5.4 || ^6.0", - "twig/twig": "^1.35 || ^2.5 || ^3.0" + "symfony/cache": "^5.4 || ^6.0", + "twig/twig": "^2.13 || ^3.0" }, "suggest": { "twig/twig": "To integrate Pagerfanta with Twig" @@ -3499,7 +3542,7 @@ ], "support": { "issues": "https://github.com/BabDev/Pagerfanta/issues", - "source": "https://github.com/BabDev/Pagerfanta/tree/v3.7.0" + "source": "https://github.com/BabDev/Pagerfanta/tree/v3.8.0" }, "funding": [ { @@ -3507,7 +3550,7 @@ "type": "github" } ], - "time": "2022-12-02T16:35:42+00:00" + "time": "2023-04-15T16:39:36+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -3626,60 +3669,6 @@ }, "time": "2020-10-15T08:29:30+00:00" }, - { - "name": "php-http/message-factory", - "version": "v1.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-http/message-factory.git", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "psr/http-message": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Factory interfaces for PSR-7 HTTP Message", - "homepage": "http://php-http.org", - "keywords": [ - "factory", - "http", - "message", - "stream", - "uri" - ], - "support": { - "issues": "https://github.com/php-http/message-factory/issues", - "source": "https://github.com/php-http/message-factory/tree/master" - }, - "time": "2015-12-19T14:08:53+00:00" - }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -4068,16 +4057,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.18.1", + "version": "1.20.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f" + "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/22dcdfd725ddf99583bfe398fc624ad6c5004a0f", - "reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", + "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", "shasum": "" }, "require": { @@ -4107,9 +4096,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.18.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.4" }, - "time": "2023-04-07T11:51:11+00:00" + "time": "2023-05-02T09:19:37+00:00" }, { "name": "psr/cache", @@ -4425,16 +4414,16 @@ }, { "name": "psr/log", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", - "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { @@ -4443,7 +4432,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { @@ -4469,9 +4458,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/2.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2021-07-14T16:41:46+00:00" + "time": "2021-07-14T16:46:02+00:00" }, { "name": "psr/simple-cache", @@ -4959,16 +4948,16 @@ }, { "name": "symfony/cache", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "76babfd82f6bfd8f6cbe851a153b95dd074ffc53" + "reference": "1ce7ed8e7ca6948892b6a3a52bb60cf2b04f7c94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/76babfd82f6bfd8f6cbe851a153b95dd074ffc53", - "reference": "76babfd82f6bfd8f6cbe851a153b95dd074ffc53", + "url": "https://api.github.com/repos/symfony/cache/zipball/1ce7ed8e7ca6948892b6a3a52bb60cf2b04f7c94", + "reference": "1ce7ed8e7ca6948892b6a3a52bb60cf2b04f7c94", "shasum": "" }, "require": { @@ -4977,7 +4966,7 @@ "psr/log": "^1.1|^2|^3", "symfony/cache-contracts": "^1.1.7|^2|^3", "symfony/service-contracts": "^1.1|^2|^3", - "symfony/var-exporter": "^6.2.7" + "symfony/var-exporter": "^6.2.10" }, "conflict": { "doctrine/dbal": "<2.13.1", @@ -5035,7 +5024,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.2.8" + "source": "https://github.com/symfony/cache/tree/v6.2.10" }, "funding": [ { @@ -5051,7 +5040,7 @@ "type": "tidelift" } ], - "time": "2023-03-30T07:37:32+00:00" + "time": "2023-04-21T15:42:15+00:00" }, { "name": "symfony/cache-contracts", @@ -5211,16 +5200,16 @@ }, { "name": "symfony/console", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b" + "reference": "12288d9f4500f84a4d02254d4aa968b15488476f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3582d68a64a86ec25240aaa521ec8bc2342b369b", - "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b", + "url": "https://api.github.com/repos/symfony/console/zipball/12288d9f4500f84a4d02254d4aa968b15488476f", + "reference": "12288d9f4500f84a4d02254d4aa968b15488476f", "shasum": "" }, "require": { @@ -5287,7 +5276,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.2.8" + "source": "https://github.com/symfony/console/tree/v6.2.10" }, "funding": [ { @@ -5303,7 +5292,7 @@ "type": "tidelift" } ], - "time": "2023-03-29T21:42:15+00:00" + "time": "2023-04-28T13:37:43+00:00" }, { "name": "symfony/css-selector", @@ -5372,16 +5361,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "b6195feacceb88fc58a02b69522b569e4c6188ac" + "reference": "d732a66a2672669232c0b4536c8c96724a679780" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b6195feacceb88fc58a02b69522b569e4c6188ac", - "reference": "b6195feacceb88fc58a02b69522b569e4c6188ac", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d732a66a2672669232c0b4536c8c96724a679780", + "reference": "d732a66a2672669232c0b4536c8c96724a679780", "shasum": "" }, "require": { @@ -5439,7 +5428,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.2.8" + "source": "https://github.com/symfony/dependency-injection/tree/v6.2.10" }, "funding": [ { @@ -5455,7 +5444,7 @@ "type": "tidelift" } ], - "time": "2023-03-30T13:35:57+00:00" + "time": "2023-04-21T15:42:15+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5526,16 +5515,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.2.8", + "version": "v6.2.9", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "70e9e36a590699c26c1a0a0c46b0eaa7a6bb019d" + "reference": "4b3aeaa90d41c5527d7ba211d12102cedf06936e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/70e9e36a590699c26c1a0a0c46b0eaa7a6bb019d", - "reference": "70e9e36a590699c26c1a0a0c46b0eaa7a6bb019d", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/4b3aeaa90d41c5527d7ba211d12102cedf06936e", + "reference": "4b3aeaa90d41c5527d7ba211d12102cedf06936e", "shasum": "" }, "require": { @@ -5621,7 +5610,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.8" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.9" }, "funding": [ { @@ -5637,7 +5626,7 @@ "type": "tidelift" } ], - "time": "2023-03-09T16:20:02+00:00" + "time": "2023-04-11T16:08:35+00:00" }, { "name": "symfony/dotenv", @@ -5715,16 +5704,16 @@ }, { "name": "symfony/error-handler", - "version": "v6.2.7", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "61e90f94eb014054000bc902257d2763fac09166" + "reference": "8b7e9f124640cb0611624a9383176c3e5f7d8cfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/61e90f94eb014054000bc902257d2763fac09166", - "reference": "61e90f94eb014054000bc902257d2763fac09166", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/8b7e9f124640cb0611624a9383176c3e5f7d8cfb", + "reference": "8b7e9f124640cb0611624a9383176c3e5f7d8cfb", "shasum": "" }, "require": { @@ -5766,7 +5755,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.2.7" + "source": "https://github.com/symfony/error-handler/tree/v6.2.10" }, "funding": [ { @@ -5782,7 +5771,7 @@ "type": "tidelift" } ], - "time": "2023-02-14T08:44:56+00:00" + "time": "2023-04-18T13:46:08+00:00" }, { "name": "symfony/event-dispatcher", @@ -6011,16 +6000,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.2.7", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "82b6c62b959f642d000456f08c6d219d749215b3" + "reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3", - "reference": "82b6c62b959f642d000456f08c6d219d749215b3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd588debf7d1bc16a2c84b4b3b71145d9946b894", + "reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894", "shasum": "" }, "require": { @@ -6054,7 +6043,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.2.7" + "source": "https://github.com/symfony/filesystem/tree/v6.2.10" }, "funding": [ { @@ -6070,7 +6059,7 @@ "type": "tidelift" } ], - "time": "2023-02-14T08:44:56+00:00" + "time": "2023-04-18T13:46:08+00:00" }, { "name": "symfony/finder", @@ -6203,16 +6192,16 @@ }, { "name": "symfony/form", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "751efa84f868337c63e29560c02cff7ae27d874b" + "reference": "a123512b46caea497ab8d96d9dbdbdaaf416a606" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/751efa84f868337c63e29560c02cff7ae27d874b", - "reference": "751efa84f868337c63e29560c02cff7ae27d874b", + "url": "https://api.github.com/repos/symfony/form/zipball/a123512b46caea497ab8d96d9dbdbdaaf416a606", + "reference": "a123512b46caea497ab8d96d9dbdbdaaf416a606", "shasum": "" }, "require": { @@ -6287,7 +6276,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v6.2.8" + "source": "https://github.com/symfony/form/tree/v6.2.10" }, "funding": [ { @@ -6303,20 +6292,20 @@ "type": "tidelift" } ], - "time": "2023-03-31T11:20:06+00:00" + "time": "2023-04-19T08:03:37+00:00" }, { "name": "symfony/framework-bundle", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "92bf9008afea94408d10148dcff89b259b8fc328" + "reference": "823f285befde4e97bb70d97cae57997c38e4d6fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/92bf9008afea94408d10148dcff89b259b8fc328", - "reference": "92bf9008afea94408d10148dcff89b259b8fc328", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/823f285befde4e97bb70d97cae57997c38e4d6fd", + "reference": "823f285befde4e97bb70d97cae57997c38e4d6fd", "shasum": "" }, "require": { @@ -6438,7 +6427,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.2.8" + "source": "https://github.com/symfony/framework-bundle/tree/v6.2.10" }, "funding": [ { @@ -6454,20 +6443,20 @@ "type": "tidelift" } ], - "time": "2023-03-31T09:55:36+00:00" + "time": "2023-04-23T08:23:35+00:00" }, { "name": "symfony/http-client", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "66391ba3a8862c560e1d9134c96d9bd2a619b477" + "reference": "3f5545a91c8e79dedd1a06c4b04e1682c80c42f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/66391ba3a8862c560e1d9134c96d9bd2a619b477", - "reference": "66391ba3a8862c560e1d9134c96d9bd2a619b477", + "url": "https://api.github.com/repos/symfony/http-client/zipball/3f5545a91c8e79dedd1a06c4b04e1682c80c42f9", + "reference": "3f5545a91c8e79dedd1a06c4b04e1682c80c42f9", "shasum": "" }, "require": { @@ -6526,7 +6515,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.2.8" + "source": "https://github.com/symfony/http-client/tree/v6.2.10" }, "funding": [ { @@ -6542,7 +6531,7 @@ "type": "tidelift" } ], - "time": "2023-03-31T09:14:44+00:00" + "time": "2023-04-20T13:12:48+00:00" }, { "name": "symfony/http-client-contracts", @@ -6627,16 +6616,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "511a524affeefc191939348823ac75e9921c2112" + "reference": "49adbb92bcb4e3c2943719d2756271e8b9602acc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/511a524affeefc191939348823ac75e9921c2112", - "reference": "511a524affeefc191939348823ac75e9921c2112", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/49adbb92bcb4e3c2943719d2756271e8b9602acc", + "reference": "49adbb92bcb4e3c2943719d2756271e8b9602acc", "shasum": "" }, "require": { @@ -6685,7 +6674,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.2.8" + "source": "https://github.com/symfony/http-foundation/tree/v6.2.10" }, "funding": [ { @@ -6701,20 +6690,20 @@ "type": "tidelift" } ], - "time": "2023-03-29T21:42:15+00:00" + "time": "2023-04-18T13:46:08+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "9563229e56076070d92ca30c089e801e8a4629a3" + "reference": "81064a65a5496f17d2b6984f6519406f98864215" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9563229e56076070d92ca30c089e801e8a4629a3", - "reference": "9563229e56076070d92ca30c089e801e8a4629a3", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/81064a65a5496f17d2b6984f6519406f98864215", + "reference": "81064a65a5496f17d2b6984f6519406f98864215", "shasum": "" }, "require": { @@ -6796,7 +6785,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.2.8" + "source": "https://github.com/symfony/http-kernel/tree/v6.2.10" }, "funding": [ { @@ -6812,20 +6801,20 @@ "type": "tidelift" } ], - "time": "2023-03-31T12:00:10+00:00" + "time": "2023-04-28T13:50:28+00:00" }, { "name": "symfony/intl", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "724bab553a3865d390a893f0881e855324e032e1" + "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/724bab553a3865d390a893f0881e855324e032e1", - "reference": "724bab553a3865d390a893f0881e855324e032e1", + "url": "https://api.github.com/repos/symfony/intl/zipball/860c99e53149d22df1900d3aefdaeb17adb7669d", + "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d", "shasum": "" }, "require": { @@ -6866,7 +6855,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a PHP replacement layer for the C intl extension that includes additional data from the ICU library", + "description": "Provides access to the localization data of the ICU library", "homepage": "https://symfony.com", "keywords": [ "i18n", @@ -6877,7 +6866,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v6.2.8" + "source": "https://github.com/symfony/intl/tree/v6.2.10" }, "funding": [ { @@ -6893,7 +6882,7 @@ "type": "tidelift" } ], - "time": "2023-03-10T10:06:03+00:00" + "time": "2023-04-14T16:23:31+00:00" }, { "name": "symfony/mailer", @@ -6976,16 +6965,16 @@ }, { "name": "symfony/mime", - "version": "v6.2.7", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "62e341f80699badb0ad70b31149c8df89a2d778e" + "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/62e341f80699badb0ad70b31149c8df89a2d778e", - "reference": "62e341f80699badb0ad70b31149c8df89a2d778e", + "url": "https://api.github.com/repos/symfony/mime/zipball/b6c137fc53a9f7c4c951cd3f362b3734c7a97723", + "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723", "shasum": "" }, "require": { @@ -7039,7 +7028,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.2.7" + "source": "https://github.com/symfony/mime/tree/v6.2.10" }, "funding": [ { @@ -7055,7 +7044,7 @@ "type": "tidelift" } ], - "time": "2023-02-24T10:42:00+00:00" + "time": "2023-04-19T09:54:16+00:00" }, { "name": "symfony/monolog-bridge", @@ -7863,16 +7852,16 @@ }, { "name": "symfony/property-info", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "400a019b7c05030599fd15f02b3d4ce287631732" + "reference": "617177c24e1a92e011851948ba973758429a68b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/400a019b7c05030599fd15f02b3d4ce287631732", - "reference": "400a019b7c05030599fd15f02b3d4ce287631732", + "url": "https://api.github.com/repos/symfony/property-info/zipball/617177c24e1a92e011851948ba973758429a68b2", + "reference": "617177c24e1a92e011851948ba973758429a68b2", "shasum": "" }, "require": { @@ -7932,7 +7921,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.2.8" + "source": "https://github.com/symfony/property-info/tree/v6.2.10" }, "funding": [ { @@ -7948,7 +7937,7 @@ "type": "tidelift" } ], - "time": "2023-03-14T15:00:05+00:00" + "time": "2023-04-18T13:46:08+00:00" }, { "name": "symfony/rate-limiter", @@ -8192,16 +8181,16 @@ }, { "name": "symfony/security-bundle", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "c781ba5ab5f71a5c8bd5fce5b4c8b6ad9eb7f3d5" + "reference": "b12dcedbcf423ae6d34d79cfaa6791a21c90bd14" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/c781ba5ab5f71a5c8bd5fce5b4c8b6ad9eb7f3d5", - "reference": "c781ba5ab5f71a5c8bd5fce5b4c8b6ad9eb7f3d5", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/b12dcedbcf423ae6d34d79cfaa6791a21c90bd14", + "reference": "b12dcedbcf423ae6d34d79cfaa6791a21c90bd14", "shasum": "" }, "require": { @@ -8216,7 +8205,7 @@ "symfony/password-hasher": "^5.4|^6.0", "symfony/security-core": "^6.2", "symfony/security-csrf": "^5.4|^6.0", - "symfony/security-http": "^6.2.6" + "symfony/security-http": "^6.2.10" }, "conflict": { "symfony/browser-kit": "<5.4", @@ -8272,7 +8261,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.2.8" + "source": "https://github.com/symfony/security-bundle/tree/v6.2.10" }, "funding": [ { @@ -8288,7 +8277,7 @@ "type": "tidelift" } ], - "time": "2023-03-10T10:06:03+00:00" + "time": "2023-04-21T15:49:06+00:00" }, { "name": "symfony/security-core", @@ -8454,16 +8443,16 @@ }, { "name": "symfony/security-http", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "6d47056ee9f394aeace1799e73ead5a2107f581d" + "reference": "c468f059fac27680acf7e84cea07ba5ffff8942a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/6d47056ee9f394aeace1799e73ead5a2107f581d", - "reference": "6d47056ee9f394aeace1799e73ead5a2107f581d", + "url": "https://api.github.com/repos/symfony/security-http/zipball/c468f059fac27680acf7e84cea07ba5ffff8942a", + "reference": "c468f059fac27680acf7e84cea07ba5ffff8942a", "shasum": "" }, "require": { @@ -8519,7 +8508,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v6.2.8" + "source": "https://github.com/symfony/security-http/tree/v6.2.10" }, "funding": [ { @@ -8535,20 +8524,20 @@ "type": "tidelift" } ], - "time": "2023-03-10T10:06:03+00:00" + "time": "2023-04-21T11:56:14+00:00" }, { "name": "symfony/serializer", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "db9d36470bf0990990fda9320b8b001bb582f075" + "reference": "0732edf0ad28dd3faacde4f1200ab9d7a4d5f40d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/db9d36470bf0990990fda9320b8b001bb582f075", - "reference": "db9d36470bf0990990fda9320b8b001bb582f075", + "url": "https://api.github.com/repos/symfony/serializer/zipball/0732edf0ad28dd3faacde4f1200ab9d7a4d5f40d", + "reference": "0732edf0ad28dd3faacde4f1200ab9d7a4d5f40d", "shasum": "" }, "require": { @@ -8620,7 +8609,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.2.8" + "source": "https://github.com/symfony/serializer/tree/v6.2.10" }, "funding": [ { @@ -8636,7 +8625,7 @@ "type": "tidelift" } ], - "time": "2023-03-31T09:14:44+00:00" + "time": "2023-04-18T13:57:49+00:00" }, { "name": "symfony/service-contracts", @@ -9261,16 +9250,16 @@ }, { "name": "symfony/validator", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "c63584f84edbdba9d2519f888350dd90615abe35" + "reference": "c02ea86844926f04247bc1f5db5f85bb53330823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/c63584f84edbdba9d2519f888350dd90615abe35", - "reference": "c63584f84edbdba9d2519f888350dd90615abe35", + "url": "https://api.github.com/repos/symfony/validator/zipball/c02ea86844926f04247bc1f5db5f85bb53330823", + "reference": "c02ea86844926f04247bc1f5db5f85bb53330823", "shasum": "" }, "require": { @@ -9349,7 +9338,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.2.8" + "source": "https://github.com/symfony/validator/tree/v6.2.10" }, "funding": [ { @@ -9365,20 +9354,20 @@ "type": "tidelift" } ], - "time": "2023-03-20T16:06:02+00:00" + "time": "2023-04-19T09:54:16+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "d37ab6787be2db993747b6218fcc96e8e3bb4bd0" + "reference": "41a750a23412ca76fdbbf5096943b4134272c1ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d37ab6787be2db993747b6218fcc96e8e3bb4bd0", - "reference": "d37ab6787be2db993747b6218fcc96e8e3bb4bd0", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/41a750a23412ca76fdbbf5096943b4134272c1ab", + "reference": "41a750a23412ca76fdbbf5096943b4134272c1ab", "shasum": "" }, "require": { @@ -9437,7 +9426,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.2.8" + "source": "https://github.com/symfony/var-dumper/tree/v6.2.10" }, "funding": [ { @@ -9453,20 +9442,20 @@ "type": "tidelift" } ], - "time": "2023-03-29T21:42:15+00:00" + "time": "2023-04-18T13:46:08+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "8302bb670204500d492c6b8c595ee9a27da62cd6" + "reference": "9a07920c2058bafee921ce4d90aeef2193837d63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8302bb670204500d492c6b8c595ee9a27da62cd6", - "reference": "8302bb670204500d492c6b8c595ee9a27da62cd6", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/9a07920c2058bafee921ce4d90aeef2193837d63", + "reference": "9a07920c2058bafee921ce4d90aeef2193837d63", "shasum": "" }, "require": { @@ -9511,7 +9500,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.2.8" + "source": "https://github.com/symfony/var-exporter/tree/v6.2.10" }, "funding": [ { @@ -9527,7 +9516,7 @@ "type": "tidelift" } ], - "time": "2023-03-14T15:48:45+00:00" + "time": "2023-04-21T08:33:05+00:00" }, { "name": "symfony/webpack-encore-bundle", @@ -9604,16 +9593,16 @@ }, { "name": "symfony/yaml", - "version": "v6.2.7", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57" + "reference": "61916f3861b1e9705b18cfde723921a71dd1559d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e8e6a1d59e050525f27a1f530aa9703423cb7f57", - "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57", + "url": "https://api.github.com/repos/symfony/yaml/zipball/61916f3861b1e9705b18cfde723921a71dd1559d", + "reference": "61916f3861b1e9705b18cfde723921a71dd1559d", "shasum": "" }, "require": { @@ -9658,7 +9647,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.2.7" + "source": "https://github.com/symfony/yaml/tree/v6.2.10" }, "funding": [ { @@ -9674,7 +9663,7 @@ "type": "tidelift" } ], - "time": "2023-02-16T09:57:23+00:00" + "time": "2023-04-28T13:25:36+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -9731,16 +9720,16 @@ }, { "name": "twig/cssinliner-extra", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/twigphp/cssinliner-extra.git", - "reference": "381877765d17b0178322d68b818e0c67f9c93187" + "reference": "85c8f3d7712bab57f6162f9637613df0511f207b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/381877765d17b0178322d68b818e0c67f9c93187", - "reference": "381877765d17b0178322d68b818e0c67f9c93187", + "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/85c8f3d7712bab57f6162f9637613df0511f207b", + "reference": "85c8f3d7712bab57f6162f9637613df0511f207b", "shasum": "" }, "require": { @@ -9752,11 +9741,6 @@ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, "autoload": { "psr-4": { "Twig\\Extra\\CssInliner\\": "" @@ -9785,7 +9769,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.5.1" + "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.6.0" }, "funding": [ { @@ -9797,20 +9781,20 @@ "type": "tidelift" } ], - "time": "2023-02-08T07:44:55+00:00" + "time": "2023-02-09T06:45:16+00:00" }, { "name": "twig/extra-bundle", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "a961e553a624eebdbd423ad5ab931497ca6d87cd" + "reference": "4a9674e775f49a9df5e26da66546e8f3364afe67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/a961e553a624eebdbd423ad5ab931497ca6d87cd", - "reference": "a961e553a624eebdbd423ad5ab931497ca6d87cd", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/4a9674e775f49a9df5e26da66546e8f3364afe67", + "reference": "4a9674e775f49a9df5e26da66546e8f3364afe67", "shasum": "" }, "require": { @@ -9831,11 +9815,6 @@ "twig/string-extra": "^2.12|^3.0" }, "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, "autoload": { "psr-4": { "Twig\\Extra\\TwigExtraBundle\\": "" @@ -9864,7 +9843,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.5.1" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.6.0" }, "funding": [ { @@ -9876,20 +9855,20 @@ "type": "tidelift" } ], - "time": "2023-02-08T07:44:55+00:00" + "time": "2023-04-14T11:03:02+00:00" }, { "name": "twig/inky-extra", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/twigphp/inky-extra.git", - "reference": "4efde499b99942a27e206898e55208a8692c16ca" + "reference": "907abf7046082cc151a3ee01f268dbf5f5f28eab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/inky-extra/zipball/4efde499b99942a27e206898e55208a8692c16ca", - "reference": "4efde499b99942a27e206898e55208a8692c16ca", + "url": "https://api.github.com/repos/twigphp/inky-extra/zipball/907abf7046082cc151a3ee01f268dbf5f5f28eab", + "reference": "907abf7046082cc151a3ee01f268dbf5f5f28eab", "shasum": "" }, "require": { @@ -9901,11 +9880,6 @@ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, "autoload": { "psr-4": { "Twig\\Extra\\Inky\\": "" @@ -9935,7 +9909,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/inky-extra/tree/v3.5.1" + "source": "https://github.com/twigphp/inky-extra/tree/v3.6.0" }, "funding": [ { @@ -9947,20 +9921,20 @@ "type": "tidelift" } ], - "time": "2023-02-08T07:44:55+00:00" + "time": "2023-02-09T06:45:16+00:00" }, { "name": "twig/intl-extra", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "c3ebfac1624228c0556de57a34af6b7d83a1a408" + "reference": "a97c323bebfca009d02994a5a8568c0b412a49ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/c3ebfac1624228c0556de57a34af6b7d83a1a408", - "reference": "c3ebfac1624228c0556de57a34af6b7d83a1a408", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/a97c323bebfca009d02994a5a8568c0b412a49ab", + "reference": "a97c323bebfca009d02994a5a8568c0b412a49ab", "shasum": "" }, "require": { @@ -9972,11 +9946,6 @@ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, "autoload": { "psr-4": { "Twig\\Extra\\Intl\\": "" @@ -10004,7 +9973,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.5.1" + "source": "https://github.com/twigphp/intl-extra/tree/v3.6.0" }, "funding": [ { @@ -10016,20 +9985,20 @@ "type": "tidelift" } ], - "time": "2023-02-08T07:44:55+00:00" + "time": "2023-02-09T06:45:16+00:00" }, { "name": "twig/string-extra", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/twigphp/string-extra.git", - "reference": "e8403cf7140319917577604be406dfb371246437" + "reference": "fab682645b3f8730fbdb7bf9ec8fe668d6f76638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/string-extra/zipball/e8403cf7140319917577604be406dfb371246437", - "reference": "e8403cf7140319917577604be406dfb371246437", + "url": "https://api.github.com/repos/twigphp/string-extra/zipball/fab682645b3f8730fbdb7bf9ec8fe668d6f76638", + "reference": "fab682645b3f8730fbdb7bf9ec8fe668d6f76638", "shasum": "" }, "require": { @@ -10042,11 +10011,6 @@ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, "autoload": { "psr-4": { "Twig\\Extra\\String\\": "" @@ -10076,7 +10040,7 @@ "unicode" ], "support": { - "source": "https://github.com/twigphp/string-extra/tree/v3.5.1" + "source": "https://github.com/twigphp/string-extra/tree/v3.6.0" }, "funding": [ { @@ -10088,20 +10052,20 @@ "type": "tidelift" } ], - "time": "2023-02-08T07:44:55+00:00" + "time": "2023-02-09T06:45:16+00:00" }, { "name": "twig/twig", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15" + "reference": "106c170d08e8415d78be2d16c3d057d0d108262b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15", - "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/106c170d08e8415d78be2d16c3d057d0d108262b", + "reference": "106c170d08e8415d78be2d16c3d057d0d108262b", "shasum": "" }, "require": { @@ -10110,15 +10074,10 @@ "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { - "psr/container": "^1.0", + "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, "autoload": { "psr-4": { "Twig\\": "src/" @@ -10152,7 +10111,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.5.1" + "source": "https://github.com/twigphp/Twig/tree/v3.6.0" }, "funding": [ { @@ -10164,7 +10123,7 @@ "type": "tidelift" } ], - "time": "2023-02-08T07:49:20+00:00" + "time": "2023-05-03T19:06:57+00:00" }, { "name": "webmozart/assert", @@ -10325,16 +10284,16 @@ }, { "name": "zircote/swagger-php", - "version": "4.7.8", + "version": "4.7.10", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "4a1d1272c2dd3afd8d96e92f02dc3565d5cc3c18" + "reference": "6d2f0fcc46bf9043877de8656a9ea95331155522" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/4a1d1272c2dd3afd8d96e92f02dc3565d5cc3c18", - "reference": "4a1d1272c2dd3afd8d96e92f02dc3565d5cc3c18", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/6d2f0fcc46bf9043877de8656a9ea95331155522", + "reference": "6d2f0fcc46bf9043877de8656a9ea95331155522", "shasum": "" }, "require": { @@ -10397,9 +10356,9 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/4.7.8" + "source": "https://github.com/zircote/swagger-php/tree/4.7.10" }, - "time": "2023-03-19T21:25:02+00:00" + "time": "2023-04-28T00:56:39+00:00" } ], "packages-dev": [ @@ -10609,16 +10568,16 @@ }, { "name": "doctrine/data-fixtures", - "version": "1.6.5", + "version": "1.6.6", "source": { "type": "git", "url": "https://github.com/doctrine/data-fixtures.git", - "reference": "e6b97f557942ea17564bbc30ae3ebc9bd2209363" + "reference": "4af35dadbfcf4b00abb2a217c4c8c8800cf5fcf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/e6b97f557942ea17564bbc30ae3ebc9bd2209363", - "reference": "e6b97f557942ea17564bbc30ae3ebc9bd2209363", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/4af35dadbfcf4b00abb2a217c4c8c8800cf5fcf4", + "reference": "4af35dadbfcf4b00abb2a217c4c8c8800cf5fcf4", "shasum": "" }, "require": { @@ -10671,7 +10630,7 @@ ], "support": { "issues": "https://github.com/doctrine/data-fixtures/issues", - "source": "https://github.com/doctrine/data-fixtures/tree/1.6.5" + "source": "https://github.com/doctrine/data-fixtures/tree/1.6.6" }, "funding": [ { @@ -10687,20 +10646,20 @@ "type": "tidelift" } ], - "time": "2023-04-03T14:58:58+00:00" + "time": "2023-04-20T13:08:54+00:00" }, { "name": "doctrine/doctrine-fixtures-bundle", - "version": "3.4.3", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", - "reference": "fd39829fed8f090ef6e185d33449d47c2fb59c9c" + "reference": "9ec3139c52a42e94c9fd1e95f8d2bca94326edfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/fd39829fed8f090ef6e185d33449d47c2fb59c9c", - "reference": "fd39829fed8f090ef6e185d33449d47c2fb59c9c", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/9ec3139c52a42e94c9fd1e95f8d2bca94326edfb", + "reference": "9ec3139c52a42e94c9fd1e95f8d2bca94326edfb", "shasum": "" }, "require": { @@ -10754,7 +10713,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineFixturesBundle/issues", - "source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/3.4.3" + "source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/3.4.4" }, "funding": [ { @@ -10770,7 +10729,7 @@ "type": "tidelift" } ], - "time": "2023-04-11T12:37:36+00:00" + "time": "2023-05-02T15:12:16+00:00" }, { "name": "fakerphp/faker", @@ -10938,26 +10897,24 @@ }, { "name": "masterminds/html5", - "version": "2.7.6", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947" + "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3", + "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-dom": "*", - "ext-libxml": "*", "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" }, "type": "library", "extra": { @@ -11001,9 +10958,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.6" + "source": "https://github.com/Masterminds/html5-php/tree/2.8.0" }, - "time": "2022-08-18T16:18:26+00:00" + "time": "2023-04-26T07:27:39+00:00" }, { "name": "nikic/php-parser", @@ -11174,16 +11131,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.12", + "version": "1.10.14", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "7b2aaf999e522e2b10011a594cf06dc37de7fbd8" + "reference": "d232901b09e67538e5c86a724be841bea5768a7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7b2aaf999e522e2b10011a594cf06dc37de7fbd8", - "reference": "7b2aaf999e522e2b10011a594cf06dc37de7fbd8", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d232901b09e67538e5c86a724be841bea5768a7c", + "reference": "d232901b09e67538e5c86a724be841bea5768a7c", "shasum": "" }, "require": { @@ -11232,25 +11189,25 @@ "type": "tidelift" } ], - "time": "2023-04-12T10:33:29+00:00" + "time": "2023-04-19T13:47:27+00:00" }, { "name": "phpstan/phpstan-doctrine", - "version": "1.3.37", + "version": "1.3.38", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-doctrine.git", - "reference": "62bd362b432fe29e175168689510ddd927b698f8" + "reference": "f1499e54358052fef17d349881ee87a7c4cc4c67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/62bd362b432fe29e175168689510ddd927b698f8", - "reference": "62bd362b432fe29e175168689510ddd927b698f8", + "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/f1499e54358052fef17d349881ee87a7c4cc4c67", + "reference": "f1499e54358052fef17d349881ee87a7c4cc4c67", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^1.10.12" }, "conflict": { "doctrine/collections": "<1.0", @@ -11300,9 +11257,9 @@ "description": "Doctrine extensions for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-doctrine/issues", - "source": "https://github.com/phpstan/phpstan-doctrine/tree/1.3.37" + "source": "https://github.com/phpstan/phpstan-doctrine/tree/1.3.38" }, - "time": "2023-03-17T14:57:03+00:00" + "time": "2023-05-04T10:53:10+00:00" }, { "name": "phpstan/phpstan-phpunit", @@ -11407,16 +11364,16 @@ }, { "name": "phpstan/phpstan-symfony", - "version": "1.2.25", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "1da7bf450c6b351fec08ca0aa97298473d4f6ab3" + "reference": "7e78605a699d183f5a6936cf91904f4c16ca79b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/1da7bf450c6b351fec08ca0aa97298473d4f6ab3", - "reference": "1da7bf450c6b351fec08ca0aa97298473d4f6ab3", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/7e78605a699d183f5a6936cf91904f4c16ca79b2", + "reference": "7e78605a699d183f5a6936cf91904f4c16ca79b2", "shasum": "" }, "require": { @@ -11472,9 +11429,9 @@ "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.2.25" + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.3.1" }, - "time": "2023-04-05T12:16:20+00:00" + "time": "2023-04-14T16:59:18+00:00" }, { "name": "phpunit/php-code-coverage", @@ -13011,16 +12968,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v6.2.8", + "version": "v6.2.9", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "0e0d0f709997ad1224ef22bb0a28287c44b7840f" + "reference": "328bc3795059651d2d4e462e8febdf7ec2d7a626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/0e0d0f709997ad1224ef22bb0a28287c44b7840f", - "reference": "0e0d0f709997ad1224ef22bb0a28287c44b7840f", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/328bc3795059651d2d4e462e8febdf7ec2d7a626", + "reference": "328bc3795059651d2d4e462e8febdf7ec2d7a626", "shasum": "" }, "require": { @@ -13061,7 +13018,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.2.8" + "source": "https://github.com/symfony/dom-crawler/tree/v6.2.9" }, "funding": [ { @@ -13077,20 +13034,20 @@ "type": "tidelift" } ], - "time": "2023-03-09T16:20:02+00:00" + "time": "2023-04-11T16:03:19+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.2.7", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "56965fae0b6b8d271015990eff5240ffff02e185" + "reference": "552950db2919421ad917e29e76d1999a2a31a8e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/56965fae0b6b8d271015990eff5240ffff02e185", - "reference": "56965fae0b6b8d271015990eff5240ffff02e185", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/552950db2919421ad917e29e76d1999a2a31a8e3", + "reference": "552950db2919421ad917e29e76d1999a2a31a8e3", "shasum": "" }, "require": { @@ -13144,7 +13101,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.2.7" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.10" }, "funding": [ { @@ -13160,20 +13117,20 @@ "type": "tidelift" } ], - "time": "2023-02-16T09:57:23+00:00" + "time": "2023-04-18T13:46:08+00:00" }, { "name": "symfony/process", - "version": "v6.2.8", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "75ed64103df4f6615e15a7fe38b8111099f47416" + "reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/75ed64103df4f6615e15a7fe38b8111099f47416", - "reference": "75ed64103df4f6615e15a7fe38b8111099f47416", + "url": "https://api.github.com/repos/symfony/process/zipball/b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e", + "reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e", "shasum": "" }, "require": { @@ -13205,7 +13162,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.2.8" + "source": "https://github.com/symfony/process/tree/v6.2.10" }, "funding": [ { @@ -13221,20 +13178,20 @@ "type": "tidelift" } ], - "time": "2023-03-09T16:20:02+00:00" + "time": "2023-04-18T13:56:57+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v6.2.7", + "version": "v6.2.10", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "0d183e0a69652e348007e97ffff8d3ded9cc6d2d" + "reference": "24b6f4370f1cd59aacfc5e799c8614b40776e9c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/0d183e0a69652e348007e97ffff8d3ded9cc6d2d", - "reference": "0d183e0a69652e348007e97ffff8d3ded9cc6d2d", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/24b6f4370f1cd59aacfc5e799c8614b40776e9c8", + "reference": "24b6f4370f1cd59aacfc5e799c8614b40776e9c8", "shasum": "" }, "require": { @@ -13283,7 +13240,7 @@ "description": "Provides a development tool that gives detailed information about the execution of any request", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.2.7" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.2.10" }, "funding": [ { @@ -13299,7 +13256,7 @@ "type": "tidelift" } ], - "time": "2023-02-21T16:32:03+00:00" + "time": "2023-04-24T13:41:17+00:00" }, { "name": "theseer/tokenizer", diff --git a/config/packages/kimai.yaml b/config/packages/kimai.yaml index 415611a6..cafe4af8 100644 --- a/config/packages/kimai.yaml +++ b/config/packages/kimai.yaml @@ -105,28 +105,21 @@ kimai: TEAMS: ['view_team','create_team','edit_team','delete_team'] LOCKDOWN: ['lockdown_grace_timesheet','lockdown_override_timesheet'] REPORTING: ['view_reporting','view_other_reporting','project_reporting','customer_reporting'] - # some single default definitions for roles - SINGLE_USER: ['view_team_member','time_team_project','create_tag','view_reporting'] - SINGLE_TEAMLEAD: ['view_rate_own_timesheet','view_rate_other_timesheet','hourly-rate_own_profile','view_team_member'] - SINGLE_ADMIN: ['hourly-rate_own_profile','edit_exported_timesheet','teams_own_profile','view_team_member','view_all_data'] - SINGLE_SUPER_ADMIN: ['hourly-rate_own_profile','hourly-rate_other_profile','roles_own_profile','system_information','system_configuration','plugins','edit_exported_timesheet','teams_own_profile','view_team_member','upload_invoice_template','view_all_data'] - # link above sets to one complete set for each user role - ROLE_USER: ['@TIMESHEET','@PROFILE','@SINGLE_USER'] - ROLE_TEAMLEAD: ['@ACTIVITIES_TEAMLEAD','@PROJECTS_TEAMLEAD','@CUSTOMERS_TEAMLEAD','@TIMESHEET_OTHER','@INVOICE','@TIMESHEET','@PROFILE','@EXPORT','@BILLABLE','@TAGS','@REPORTING','@SINGLE_TEAMLEAD'] - ROLE_ADMIN: ['@ACTIVITIES','@PROJECTS','@CUSTOMERS','@INVOICE','@INVOICE_ADMIN','@TIMESHEET','@TIMESHEET_OTHER','@PROFILE','@TEAMS','@RATE','@RATE_OTHER','@EXPORT','@BILLABLE','@TAGS','@LOCKDOWN','@REPORTING','@SINGLE_ADMIN'] - ROLE_SUPER_ADMIN: ['@ACTIVITIES','@PROJECTS','@CUSTOMERS','@INVOICE','@INVOICE_ADMIN','@TIMESHEET','@TIMESHEET_OTHER','@PROFILE','@PROFILE_OTHER','@USER','@TEAMS','@RATE','@RATE_OTHER','@EXPORT','@BILLABLE','@TAGS','@LOCKDOWN','@REPORTING','@SINGLE_SUPER_ADMIN'] - # mapping "sets" or permissions to user roles ("role name" = [array of "set names"]) + # permissions which are deactivated, as these features are hidden for now + # brave users can try to activate them and be surprised what happens + REGISTER_BETA: [] + # mapping a "role name" to an array of "set names" maps: - ROLE_USER: ['ROLE_USER'] - ROLE_TEAMLEAD: ['ROLE_TEAMLEAD'] - ROLE_ADMIN: ['ROLE_ADMIN'] - ROLE_SUPER_ADMIN: ['ROLE_SUPER_ADMIN'] - # add or remove single permissions + ROLE_USER: ['TIMESHEET','PROFILE'] + ROLE_TEAMLEAD: ['ACTIVITIES_TEAMLEAD','PROJECTS_TEAMLEAD','CUSTOMERS_TEAMLEAD','TIMESHEET_OTHER','INVOICE','TIMESHEET','PROFILE','EXPORT','BILLABLE','TAGS','REPORTING'] + ROLE_ADMIN: ['ACTIVITIES','PROJECTS','CUSTOMERS','INVOICE','INVOICE_ADMIN','TIMESHEET','TIMESHEET_OTHER','PROFILE','TEAMS','RATE','RATE_OTHER','EXPORT','BILLABLE','TAGS','LOCKDOWN','REPORTING'] + ROLE_SUPER_ADMIN: ['ACTIVITIES','PROJECTS','CUSTOMERS','INVOICE','INVOICE_ADMIN','TIMESHEET','TIMESHEET_OTHER','PROFILE','PROFILE_OTHER','USER','TEAMS','RATE','RATE_OTHER','EXPORT','BILLABLE','TAGS','LOCKDOWN','REPORTING'] + # mapping a "role name" to an array of "permission names" roles: - ROLE_USER: [] - ROLE_TEAMLEAD: [] - ROLE_ADMIN: [] - ROLE_SUPER_ADMIN: [] + ROLE_USER: ['view_team_member','time_team_project','create_tag','view_reporting'] + ROLE_TEAMLEAD: ['view_rate_own_timesheet','view_rate_other_timesheet','hourly-rate_own_profile','view_team_member'] + ROLE_ADMIN: ['hourly-rate_own_profile','edit_exported_timesheet','teams_own_profile','view_team_member','view_all_data'] + ROLE_SUPER_ADMIN: ['hourly-rate_own_profile','hourly-rate_other_profile','roles_own_profile','system_information','system_configuration','plugins','edit_exported_timesheet','teams_own_profile','view_team_member','upload_invoice_template','view_all_data'] # -------------------------------------------------------------------------------- diff --git a/phpstan.neon b/phpstan.neon index 04092980..18e7617c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -7,6 +7,12 @@ includes: - %rootDir%/../phpstan/conf/bleedingEdge.neon parameters: + featureToggles: + skipCheckGenericClasses: + - Symfony\Component\Form\AbstractType + - Symfony\Component\Form\FormInterface + - Symfony\Component\Form\FormTypeExtensionInterface + - Symfony\Component\Form\FormTypeInterface level: 9 strictRules: allRules: false @@ -55,16 +61,6 @@ parameters: count: 1 path: src/API/Authentication/TokenAuthenticator.php - - - message: "#^Method App\\\\API\\\\BaseApiController\\:\\:createSearchForm\\(\\) has parameter \\$data with no type specified\\.$#" - count: 1 - path: src/API/BaseApiController.php - - - - message: "#^Method App\\\\API\\\\BaseApiController\\:\\:createSearchForm\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" - count: 1 - path: src/API/BaseApiController.php - - message: "#^Parameter \\#1 \\$user of static method App\\\\Timesheet\\\\DateTimeFactory\\:\\:createByUser\\(\\) expects App\\\\Entity\\\\User, App\\\\Entity\\\\User\\|null given\\.$#" count: 1 @@ -910,31 +906,6 @@ parameters: count: 1 path: src/Configuration/SystemConfiguration.php - - - message: "#^Method App\\\\Controller\\\\AbstractController\\:\\:createFormForGetRequest\\(\\) has parameter \\$data with no type specified\\.$#" - count: 1 - path: src/Controller/AbstractController.php - - - - message: "#^Method App\\\\Controller\\\\AbstractController\\:\\:createFormForGetRequest\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Controller/AbstractController.php - - - - message: "#^Method App\\\\Controller\\\\AbstractController\\:\\:createFormWithName\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Controller/AbstractController.php - - - - message: "#^Method App\\\\Controller\\\\AbstractController\\:\\:createSearchForm\\(\\) has parameter \\$data with no type specified\\.$#" - count: 1 - path: src/Controller/AbstractController.php - - - - message: "#^Method App\\\\Controller\\\\AbstractController\\:\\:createSearchForm\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Controller/AbstractController.php - - message: "#^Method App\\\\Controller\\\\AbstractController\\:\\:getLastSearch\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -1335,21 +1306,6 @@ parameters: count: 1 path: src/Controller/Reporting/ReportUsersYearController.php - - - message: "#^Parameter \\#1 \\$begin of class App\\\\Model\\\\MonthlyStatistic constructor expects DateTime, DateTime\\|null given\\.$#" - count: 1 - path: src/Controller/Reporting/ReportUsersYearController.php - - - - message: "#^Parameter \\#1 \\$begin of method App\\\\Timesheet\\\\TimesheetStatisticService\\:\\:getMonthlyStats\\(\\) expects DateTime, DateTime\\|null given\\.$#" - count: 1 - path: src/Controller/Reporting/ReportUsersYearController.php - - - - message: "#^Parameter \\#1 \\$financialYear of method App\\\\Timesheet\\\\DateTimeFactory\\:\\:createEndOfFinancialYear\\(\\) expects DateTimeInterface, DateTime\\|null given\\.$#" - count: 1 - path: src/Controller/Reporting/ReportUsersYearController.php - - message: "#^Parameter \\#3 \\$users of method App\\\\Timesheet\\\\TimesheetStatisticService\\:\\:getMonthlyStats\\(\\) expects array\\, iterable\\ given\\.$#" count: 1 @@ -1375,16 +1331,6 @@ parameters: count: 1 path: src/Controller/Reporting/UserWeekController.php - - - message: "#^Cannot call method modify\\(\\) on DateTime\\|null\\.$#" - count: 2 - path: src/Controller/Reporting/UserYearController.php - - - - message: "#^Cannot clone non\\-object variable \\$start of type DateTime\\|null\\.$#" - count: 2 - path: src/Controller/Reporting/UserYearController.php - - message: "#^Method App\\\\Controller\\\\Reporting\\\\UserYearController\\:\\:getData\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -1395,21 +1341,6 @@ parameters: count: 1 path: src/Controller/Reporting/UserYearController.php - - - message: "#^Parameter \\#1 \\$begin of class App\\\\Model\\\\MonthlyStatistic constructor expects DateTime, DateTime\\|null given\\.$#" - count: 1 - path: src/Controller/Reporting/UserYearController.php - - - - message: "#^Parameter \\#1 \\$begin of method App\\\\Controller\\\\Reporting\\\\AbstractUserReportController\\:\\:prepareReport\\(\\) expects DateTime, DateTime\\|null given\\.$#" - count: 1 - path: src/Controller/Reporting/UserYearController.php - - - - message: "#^Parameter \\#1 \\$financialYear of method App\\\\Timesheet\\\\DateTimeFactory\\:\\:createEndOfFinancialYear\\(\\) expects DateTimeInterface, DateTime\\|null given\\.$#" - count: 1 - path: src/Controller/Reporting/UserYearController.php - - message: "#^Parameter \\#3 \\$user of class App\\\\Model\\\\MonthlyStatistic constructor expects App\\\\Entity\\\\User, App\\\\Entity\\\\User\\|null given\\.$#" count: 1 @@ -1675,16 +1606,6 @@ parameters: count: 1 path: src/DependencyInjection/AppExtension.php - - - message: "#^Method App\\\\DependencyInjection\\\\AppExtension\\:\\:getFilteredPermissions\\(\\) has parameter \\$permissions with no value type specified in iterable type array\\.$#" - count: 1 - path: src/DependencyInjection/AppExtension.php - - - - message: "#^Method App\\\\DependencyInjection\\\\AppExtension\\:\\:getFilteredPermissions\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DependencyInjection/AppExtension.php - - message: "#^Method App\\\\DependencyInjection\\\\Configuration\\:\\:getProjectNode\\(\\) has no return type specified\\.$#" count: 1 @@ -4240,26 +4161,6 @@ parameters: count: 1 path: src/Form/Type/UserPreferencesCollectionType.php - - - message: "#^Cannot call method modify\\(\\) on mixed\\.$#" - count: 2 - path: src/Form/Type/WeekPickerType.php - - - - message: "#^Cannot clone non\\-object variable \\$date of type mixed\\.$#" - count: 2 - path: src/Form/Type/WeekPickerType.php - - - - message: "#^Cannot call method modify\\(\\) on mixed\\.$#" - count: 2 - path: src/Form/Type/YearPickerType.php - - - - message: "#^Cannot clone non\\-object variable \\$date of type mixed\\.$#" - count: 2 - path: src/Form/Type/YearPickerType.php - - message: "#^Cannot access offset mixed on mixed\\.$#" count: 1 @@ -5155,21 +5056,6 @@ parameters: count: 1 path: src/Project/ProjectStatisticService.php - - - message: "#^Property App\\\\Reporting\\\\AbstractUserList\\:\\:\\$date has no type specified\\.$#" - count: 1 - path: src/Reporting/AbstractUserList.php - - - - message: "#^Property App\\\\Reporting\\\\AbstractUserList\\:\\:\\$decimal has no type specified\\.$#" - count: 1 - path: src/Reporting/AbstractUserList.php - - - - message: "#^Property App\\\\Reporting\\\\AbstractUserList\\:\\:\\$sumType has no type specified\\.$#" - count: 1 - path: src/Reporting/AbstractUserList.php - - message: "#^Method App\\\\Reporting\\\\CustomerMonthlyProjects\\\\CustomerMonthlyProjectsRepository\\:\\:getGroupedByCustomerProjectActivityUser\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -6590,11 +6476,6 @@ parameters: count: 1 path: src/Utils/Pagination.php - - - message: "#^Method App\\\\Utils\\\\PaginationTemplate\\:\\:getDefaultOptions\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Utils/PaginationTemplate.php - - message: "#^Parameter \\#1 \\$class of method App\\\\Utils\\\\PaginationTemplate\\:\\:linkLi\\(\\) expects string, mixed given\\.$#" count: 1 diff --git a/src/API/BaseApiController.php b/src/API/BaseApiController.php index 39574a8c..6cdfdee7 100644 --- a/src/API/BaseApiController.php +++ b/src/API/BaseApiController.php @@ -17,6 +17,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormTypeInterface; /** * @method null|User getUser() @@ -27,7 +28,15 @@ abstract class BaseApiController extends AbstractController public const DATE_FORMAT = DateTimeType::HTML5_FORMAT; public const DATE_FORMAT_PHP = 'Y-m-d\TH:i:s'; - protected function createSearchForm(string $type = FormType::class, $data = null, array $options = []): FormInterface + /** + * @template TFormType of FormTypeInterface + * @template TData of mixed + * @param class-string $type + * @param TData|null $data + * @param array $options + * @return FormInterface + */ + protected function createSearchForm(string $type = FormType::class, mixed $data = null, array $options = []): FormInterface { return $this->container ->get('form.factory') diff --git a/src/Constants.php b/src/Constants.php index e2d92e03..ea739ecd 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -17,11 +17,11 @@ class Constants /** * The current release version */ - public const VERSION = '2.0.17'; + public const VERSION = '2.0.18'; /** * The current release: major * 10000 + minor * 100 + patch */ - public const VERSION_ID = 20017; + public const VERSION_ID = 20018; /** * The software name */ diff --git a/src/Controller/AbstractController.php b/src/Controller/AbstractController.php index d747380a..e7f2fbf9 100644 --- a/src/Controller/AbstractController.php +++ b/src/Controller/AbstractController.php @@ -20,6 +20,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseAbstract use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormTypeInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\SessionInterface; @@ -47,19 +48,41 @@ abstract class AbstractController extends BaseAbstractController implements Serv return $this->container->get('translator'); } - protected function createSearchForm(string $type = FormType::class, $data = null, array $options = []): FormInterface + /** + * @template TFormType of FormTypeInterface + * @template TData of mixed + * @param class-string $type + * @param TData $data + * @param array $options + * @return FormInterface + */ + protected function createSearchForm(string $type, mixed $data, array $options = []): FormInterface { return $this->createFormForGetRequest($type, $data, $options); } - protected function createFormForGetRequest(string $type = FormType::class, $data = null, array $options = []): FormInterface + /** + * @template TFormType of FormTypeInterface + * @template TData of mixed + * @param class-string $type + * @param TData $data + * @param array $options + * @return FormInterface + */ + protected function createFormForGetRequest(string $type, mixed $data, array $options = []): FormInterface { - return $this->container - ->get('form.factory') - ->createNamed('', $type, $data, array_merge(['method' => 'GET'], $options)); + return $this->container->get('form.factory')->createNamed('', $type, $data, array_merge(['method' => 'GET'], $options)); // @phpstan-ignore-line } - protected function createFormWithName(string $name, string $type, mixed $data = null, array $options = []): FormInterface + /** + * @template TFormType of FormTypeInterface + * @template TData of mixed + * @param class-string $type + * @param TData|null $data + * @param array $options + * @return FormInterface + */ + protected function createFormWithName(string $name, string $type = FormType::class, mixed $data = null, array $options = []): FormInterface { return $this->container->get('form.factory')->createNamed($name, $type, $data, $options); } @@ -166,6 +189,9 @@ 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 { diff --git a/src/Controller/ActivityController.php b/src/Controller/ActivityController.php index f91cd030..706ca7eb 100644 --- a/src/Controller/ActivityController.php +++ b/src/Controller/ActivityController.php @@ -414,6 +414,10 @@ final class ActivityController extends AbstractController return $writer->getFileResponse($spreadsheet); } + /** + * @param ActivityQuery $query + * @return FormInterface + */ private function getToolbarForm(ActivityQuery $query): FormInterface { return $this->createSearchForm(ActivityToolbarForm::class, $query, [ @@ -423,6 +427,10 @@ final class ActivityController extends AbstractController ]); } + /** + * @param Activity $activity + * @return FormInterface + */ private function createEditForm(Activity $activity): FormInterface { $currency = $this->configuration->getCustomerDefaultCurrency(); diff --git a/src/Controller/CustomerController.php b/src/Controller/CustomerController.php index 570ec4d6..9bfb47b1 100644 --- a/src/Controller/CustomerController.php +++ b/src/Controller/CustomerController.php @@ -505,6 +505,10 @@ final class CustomerController extends AbstractController ]); } + /** + * @param CustomerQuery $query + * @return FormInterface + */ private function getToolbarForm(CustomerQuery $query): FormInterface { return $this->createSearchForm(CustomerToolbarForm::class, $query, [ @@ -514,6 +518,10 @@ final class CustomerController extends AbstractController ]); } + /** + * @param CustomerComment $comment + * @return FormInterface + */ private function getCommentForm(CustomerComment $comment): FormInterface { if (null === $comment->getId()) { @@ -526,6 +534,10 @@ final class CustomerController extends AbstractController ]); } + /** + * @param Customer $customer + * @return FormInterface + */ private function createEditForm(Customer $customer): FormInterface { $event = new CustomerMetaDefinitionEvent($customer); diff --git a/src/Controller/ExportController.php b/src/Controller/ExportController.php index 81fb284e..2a73a612 100644 --- a/src/Controller/ExportController.php +++ b/src/Controller/ExportController.php @@ -157,6 +157,11 @@ final class ExportController extends AbstractController return $this->export->getExportItems($query); } + /** + * @param ExportQuery $query + * @param string $method + * @return FormInterface + */ private function getToolbarForm(ExportQuery $query, string $method): FormInterface { return $this->createSearchForm(ExportToolbarForm::class, $query, [ diff --git a/src/Controller/Reporting/AbstractUserReportController.php b/src/Controller/Reporting/AbstractUserReportController.php index 95a49a59..59f92008 100644 --- a/src/Controller/Reporting/AbstractUserReportController.php +++ b/src/Controller/Reporting/AbstractUserReportController.php @@ -17,7 +17,7 @@ use App\Model\Statistic\StatisticDate; use App\Repository\ActivityRepository; use App\Repository\ProjectRepository; use App\Timesheet\TimesheetStatisticService; -use DateTime; +use DateTimeInterface; abstract class AbstractUserReportController extends AbstractController { @@ -35,17 +35,17 @@ abstract class AbstractUserReportController extends AbstractController return true; } - protected function getStatisticDataRaw(DateTime $begin, DateTime $end, User $user): array + protected function getStatisticDataRaw(DateTimeInterface $begin, DateTimeInterface $end, User $user): array { return $this->statisticService->getDailyStatisticsGrouped($begin, $end, [$user]); } - protected function createStatisticModel(DateTime $begin, DateTime $end, User $user): DateStatisticInterface + protected function createStatisticModel(DateTimeInterface $begin, DateTimeInterface $end, User $user): DateStatisticInterface { return new DailyStatistic($begin, $end, $user); } - protected function prepareReport(DateTime $begin, DateTime $end, User $user): array + protected function prepareReport(DateTimeInterface $begin, DateTimeInterface $end, User $user): array { $data = $this->getStatisticDataRaw($begin, $end, $user); diff --git a/src/Controller/Reporting/ReportUsersYearController.php b/src/Controller/Reporting/ReportUsersYearController.php index 20806468..38671691 100644 --- a/src/Controller/Reporting/ReportUsersYearController.php +++ b/src/Controller/Reporting/ReportUsersYearController.php @@ -105,7 +105,9 @@ final class ReportUsersYearController extends AbstractController $values->setDate(clone $defaultDate); } + /** @var \DateTime $start */ $start = $values->getDate(); + // there is a potential edge case bug for financial years: // the last month will be skipped, if the financial year started on a different day than the first $end = $dateTimeFactory->createEndOfFinancialYear($start); diff --git a/src/Controller/Reporting/UserYearController.php b/src/Controller/Reporting/UserYearController.php index 1e0a6058..cecee575 100644 --- a/src/Controller/Reporting/UserYearController.php +++ b/src/Controller/Reporting/UserYearController.php @@ -16,6 +16,7 @@ use App\Model\MonthlyStatistic; use App\Reporting\YearByUser\YearByUser; use App\Reporting\YearByUser\YearByUserForm; use DateTime; +use DateTimeInterface; use Exception; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -75,6 +76,7 @@ final class UserYearController extends AbstractUserReportController $values->setDate(clone $defaultDate); } + /** @var \DateTimeInterface $start */ $start = $values->getDate(); // there is a potential edge case bug for financial years: // the last month will be skipped, if the financial year started on a different day than the first @@ -82,10 +84,10 @@ final class UserYearController extends AbstractUserReportController $selectedUser = $values->getUser(); - $previous = clone $start; + $previous = DateTime::createFromInterface($start); $previous->modify('-1 year'); - $next = clone $start; + $next = DateTime::createFromInterface($start); $next->modify('+1 year'); $data = $this->prepareReport($start, $end, $selectedUser); @@ -105,12 +107,12 @@ final class UserYearController extends AbstractUserReportController ]; } - protected function getStatisticDataRaw(DateTime $begin, DateTime $end, User $user): array + protected function getStatisticDataRaw(DateTimeInterface $begin, DateTimeInterface $end, User $user): array { return $this->statisticService->getMonthlyStatisticsGrouped($begin, $end, [$user]); } - protected function createStatisticModel(DateTime $begin, DateTime $end, User $user): DateStatisticInterface + protected function createStatisticModel(DateTimeInterface $begin, DateTimeInterface $end, User $user): DateStatisticInterface { return new MonthlyStatistic($begin, $end, $user); } diff --git a/src/DependencyInjection/AppExtension.php b/src/DependencyInjection/AppExtension.php index 9898cd60..eadcb8c4 100644 --- a/src/DependencyInjection/AppExtension.php +++ b/src/DependencyInjection/AppExtension.php @@ -152,9 +152,6 @@ final class AppExtension extends Extension // permissions as well, which are off by default for all roles foreach ($config['sets'] as $set => $permNames) { foreach ($permNames as $name) { - if (str_starts_with($name, '@') || str_starts_with($name, '!')) { - continue; - } $names[$name] = true; } } @@ -169,9 +166,7 @@ final class AppExtension extends Extension $exception->setPath('kimai.permissions.maps.' . $role); throw $exception; } - $roles[$role] = array_merge($roles[$role] ?? [], $this->getFilteredPermissions( - $this->extractSinglePermissionsFromSet($config, $set) - )); + $roles[$role] = array_merge($roles[$role] ?? [], $this->extractSinglePermissionsFromSet($config, $set)); } } @@ -182,7 +177,7 @@ final class AppExtension extends Extension $roles[$name][$name2] = true; } } - $config['roles'][$name] = $this->getFilteredPermissions($roles[$name]); + $config['roles'][$name] = $roles[$name]; } // make sure to apply all other permissions that might have been registered through plugins @@ -205,21 +200,6 @@ final class AppExtension extends Extension $container->setParameter('kimai.permission_roles', array_map('strtoupper', array_values(array_unique($roles)))); } - private function getFilteredPermissions(array $permissions): array - { - $deleteFromArray = array_filter($permissions, function ($permission): bool { - return $permission[0] === '!'; - }, ARRAY_FILTER_USE_KEY); - - return array_filter($permissions, function ($permission) use ($deleteFromArray): bool { - if ($permission[0] === '!') { - return false; - } - - return !\array_key_exists('!' . $permission, $deleteFromArray); - }, ARRAY_FILTER_USE_KEY); - } - private function extractSinglePermissionsFromSet(array $permissions, string $name): array { if (!isset($permissions['sets'][$name])) { @@ -229,14 +209,7 @@ final class AppExtension extends Extension $result = []; foreach ($permissions['sets'][$name] as $permissionName) { - if ($permissionName[0] === '@') { - $result = array_merge( - $result, - $this->extractSinglePermissionsFromSet($permissions, substr($permissionName, 1)) - ); - } else { - $result[$permissionName] = true; - } + $result[$permissionName] = true; } return $result; diff --git a/src/Entity/UserPreference.php b/src/Entity/UserPreference.php index 7e0f8efd..05b9a3ee 100644 --- a/src/Entity/UserPreference.php +++ b/src/Entity/UserPreference.php @@ -47,6 +47,7 @@ class UserPreference #[Serializer\Groups(['Default'])] private string $name; #[ORM\Column(name: 'value', type: 'string', length: 255, nullable: true)] + #[Assert\Length(max: 250)] #[Serializer\Expose] #[Serializer\Groups(['Default'])] private ?string $value; diff --git a/src/Form/CustomerEditForm.php b/src/Form/CustomerEditForm.php index 9bafcc0b..e846e25a 100644 --- a/src/Form/CustomerEditForm.php +++ b/src/Form/CustomerEditForm.php @@ -24,6 +24,9 @@ use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ class CustomerEditForm extends AbstractType { use EntityFormTrait; diff --git a/src/Form/Toolbar/ActivityToolbarForm.php b/src/Form/Toolbar/ActivityToolbarForm.php index a8dd25d9..e3a33194 100644 --- a/src/Form/Toolbar/ActivityToolbarForm.php +++ b/src/Form/Toolbar/ActivityToolbarForm.php @@ -17,6 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering the activities. + * @extends AbstractType */ final class ActivityToolbarForm extends AbstractType { diff --git a/src/Form/Toolbar/CustomerToolbarForm.php b/src/Form/Toolbar/CustomerToolbarForm.php index f67b806f..597e9e39 100644 --- a/src/Form/Toolbar/CustomerToolbarForm.php +++ b/src/Form/Toolbar/CustomerToolbarForm.php @@ -16,6 +16,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering the customer. + * @extends AbstractType */ final class CustomerToolbarForm extends AbstractType { diff --git a/src/Form/Toolbar/ExportToolbarForm.php b/src/Form/Toolbar/ExportToolbarForm.php index 9e14ba81..1b882b32 100644 --- a/src/Form/Toolbar/ExportToolbarForm.php +++ b/src/Form/Toolbar/ExportToolbarForm.php @@ -17,6 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering timesheet entries for exports. + * @extends AbstractType */ final class ExportToolbarForm extends AbstractType { diff --git a/src/Form/Toolbar/InvoiceArchiveForm.php b/src/Form/Toolbar/InvoiceArchiveForm.php index baa0e58c..76da8f9a 100644 --- a/src/Form/Toolbar/InvoiceArchiveForm.php +++ b/src/Form/Toolbar/InvoiceArchiveForm.php @@ -17,6 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering timesheet entries for invoices. + * @extends AbstractType */ final class InvoiceArchiveForm extends AbstractType { diff --git a/src/Form/Toolbar/InvoiceToolbarForm.php b/src/Form/Toolbar/InvoiceToolbarForm.php index dccac8a1..558bb535 100644 --- a/src/Form/Toolbar/InvoiceToolbarForm.php +++ b/src/Form/Toolbar/InvoiceToolbarForm.php @@ -18,6 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering timesheet entries for invoices. + * @extends AbstractType */ final class InvoiceToolbarForm extends AbstractType { diff --git a/src/Form/Toolbar/ProjectToolbarForm.php b/src/Form/Toolbar/ProjectToolbarForm.php index ba474937..e90aed38 100644 --- a/src/Form/Toolbar/ProjectToolbarForm.php +++ b/src/Form/Toolbar/ProjectToolbarForm.php @@ -16,6 +16,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering the projects. + * @extends AbstractType */ final class ProjectToolbarForm extends AbstractType { diff --git a/src/Form/Toolbar/TagToolbarForm.php b/src/Form/Toolbar/TagToolbarForm.php index c97980c2..02c22fe3 100644 --- a/src/Form/Toolbar/TagToolbarForm.php +++ b/src/Form/Toolbar/TagToolbarForm.php @@ -14,6 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class TagToolbarForm extends AbstractType { use ToolbarFormTrait; diff --git a/src/Form/Toolbar/TeamToolbarForm.php b/src/Form/Toolbar/TeamToolbarForm.php index 9c0f82d4..158988f2 100644 --- a/src/Form/Toolbar/TeamToolbarForm.php +++ b/src/Form/Toolbar/TeamToolbarForm.php @@ -14,6 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class TeamToolbarForm extends AbstractType { use ToolbarFormTrait; diff --git a/src/Form/Toolbar/TimesheetExportToolbarForm.php b/src/Form/Toolbar/TimesheetExportToolbarForm.php index 8f7451c5..6c9ad363 100644 --- a/src/Form/Toolbar/TimesheetExportToolbarForm.php +++ b/src/Form/Toolbar/TimesheetExportToolbarForm.php @@ -16,6 +16,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering the timesheet. + * @extends AbstractType */ final class TimesheetExportToolbarForm extends AbstractType { diff --git a/src/Form/Toolbar/TimesheetToolbarForm.php b/src/Form/Toolbar/TimesheetToolbarForm.php index 6eb3d2aa..2f397d77 100644 --- a/src/Form/Toolbar/TimesheetToolbarForm.php +++ b/src/Form/Toolbar/TimesheetToolbarForm.php @@ -16,6 +16,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering the timesheet. + * @extends AbstractType */ final class TimesheetToolbarForm extends AbstractType { diff --git a/src/Form/Toolbar/UserToolbarForm.php b/src/Form/Toolbar/UserToolbarForm.php index 9107d697..0abd746d 100644 --- a/src/Form/Toolbar/UserToolbarForm.php +++ b/src/Form/Toolbar/UserToolbarForm.php @@ -16,6 +16,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used for filtering the user. + * @extends AbstractType */ final class UserToolbarForm extends AbstractType { diff --git a/src/Form/Type/TeamMemberType.php b/src/Form/Type/TeamMemberType.php index 636dd538..82122cf5 100644 --- a/src/Form/Type/TeamMemberType.php +++ b/src/Form/Type/TeamMemberType.php @@ -14,6 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class TeamMemberType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/Type/TeamType.php b/src/Form/Type/TeamType.php index e2e2157a..ada8c977 100644 --- a/src/Form/Type/TeamType.php +++ b/src/Form/Type/TeamType.php @@ -18,6 +18,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class TeamType extends AbstractType { public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Form/Type/TimesheetBillableType.php b/src/Form/Type/TimesheetBillableType.php index 092fbccc..c277d4d1 100644 --- a/src/Form/Type/TimesheetBillableType.php +++ b/src/Form/Type/TimesheetBillableType.php @@ -16,6 +16,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select if a timesheet is billable. + * @extends AbstractType */ final class TimesheetBillableType extends AbstractType { diff --git a/src/Form/Type/TimezoneType.php b/src/Form/Type/TimezoneType.php index 86bb607b..c89d62a9 100644 --- a/src/Form/Type/TimezoneType.php +++ b/src/Form/Type/TimezoneType.php @@ -13,6 +13,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TimezoneType as BaseTimezoneType; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class TimezoneType extends AbstractType { public function getBlockPrefix(): string diff --git a/src/Form/Type/UserLanguageType.php b/src/Form/Type/UserLanguageType.php index 5c74d354..b808c9f0 100644 --- a/src/Form/Type/UserLanguageType.php +++ b/src/Form/Type/UserLanguageType.php @@ -16,6 +16,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; /** * Custom form field type to select the user language. + * @extends AbstractType */ final class UserLanguageType extends AbstractType { diff --git a/src/Form/Type/UserPreferenceType.php b/src/Form/Type/UserPreferenceType.php index d1f04b64..5df131e5 100644 --- a/src/Form/Type/UserPreferenceType.php +++ b/src/Form/Type/UserPreferenceType.php @@ -13,15 +13,19 @@ use App\Entity\UserPreference; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; +use Symfony\Component\Form\Extension\Core\Type\TextareaType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Contracts\Translation\TranslatorInterface; /** * Custom form field type to edit a user preference. + * @extends AbstractType */ final class UserPreferenceType extends AbstractType { @@ -46,6 +50,10 @@ final class UserPreferenceType extends AbstractType unset($options['required']); } + if (\in_array($preference->getType(), [TextType::class, TextareaType::class])) { + $constraints[] = new Length(['max' => 255]); + } + if (\in_array($preference->getType(), [CheckboxType::class, YesNoType::class])) { $required = false; } diff --git a/src/Form/Type/UserPreferencesCollectionType.php b/src/Form/Type/UserPreferencesCollectionType.php index 964bbd21..b28662d0 100644 --- a/src/Form/Type/UserPreferencesCollectionType.php +++ b/src/Form/Type/UserPreferencesCollectionType.php @@ -9,6 +9,7 @@ namespace App\Form\Type; +use App\Entity\User; use App\Entity\UserPreference; use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Form\AbstractType; @@ -20,6 +21,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to edit user preferences. + * @extends AbstractType */ final class UserPreferencesCollectionType extends AbstractType { diff --git a/src/Form/Type/UserRoleType.php b/src/Form/Type/UserRoleType.php index 644a3177..e24ec4be 100644 --- a/src/Form/Type/UserRoleType.php +++ b/src/Form/Type/UserRoleType.php @@ -18,6 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select a user role. + * @extends AbstractType */ final class UserRoleType extends AbstractType { diff --git a/src/Form/Type/UserType.php b/src/Form/Type/UserType.php index cd2516ea..a836c091 100644 --- a/src/Form/Type/UserType.php +++ b/src/Form/Type/UserType.php @@ -21,6 +21,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select a user. + * @extends AbstractType */ final class UserType extends AbstractType { diff --git a/src/Form/Type/VisibilityType.php b/src/Form/Type/VisibilityType.php index 855ebcc3..a475c30e 100644 --- a/src/Form/Type/VisibilityType.php +++ b/src/Form/Type/VisibilityType.php @@ -16,6 +16,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select a visibility. + * @extends AbstractType */ final class VisibilityType extends AbstractType { diff --git a/src/Form/Type/WeekDaysType.php b/src/Form/Type/WeekDaysType.php index 3b425ea6..d834010f 100644 --- a/src/Form/Type/WeekDaysType.php +++ b/src/Form/Type/WeekDaysType.php @@ -17,6 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select weekdays. + * @extends AbstractType */ final class WeekDaysType extends AbstractType { diff --git a/src/Form/Type/WeekPickerType.php b/src/Form/Type/WeekPickerType.php index 68de077b..2e5cf111 100644 --- a/src/Form/Type/WeekPickerType.php +++ b/src/Form/Type/WeekPickerType.php @@ -17,8 +17,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select a week via picker and select previous and next week. - * * Always falls back to the current week if none or an invalid date is given. + * @extends AbstractType<\DateTimeInterface|null> */ final class WeekPickerType extends AbstractType { @@ -28,19 +28,22 @@ final class WeekPickerType extends AbstractType 'widget' => 'single_text', 'html5' => false, 'format' => DateType::HTML5_FORMAT, - 'start_date' => new \DateTime(), + 'start_date' => new \DateTimeImmutable(), ]); } public function buildView(FormView $view, FormInterface $form, array $options): void { - /** @var \DateTime|null $date */ + /** @var \DateTimeInterface|null $date */ $date = $form->getData(); if (null === $date) { + /** @var \DateTimeImmutable $date */ $date = $options['start_date']; } + $date = \DateTime::createFromInterface($date); + $view->vars['week'] = $date; $view->vars['previousWeek'] = (clone $date)->modify('-1 week'); $view->vars['nextWeek'] = (clone $date)->modify('+1 week'); diff --git a/src/Form/Type/YearPickerType.php b/src/Form/Type/YearPickerType.php index 29f72053..9a1c57bd 100644 --- a/src/Form/Type/YearPickerType.php +++ b/src/Form/Type/YearPickerType.php @@ -17,8 +17,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select a year via picker and select previous and next year. - * * Always falls back to the current year if none or an invalid date is given. + * @extends AbstractType<\DateTimeInterface|null> */ final class YearPickerType extends AbstractType { @@ -28,20 +28,23 @@ final class YearPickerType extends AbstractType 'widget' => 'single_text', 'html5' => false, 'format' => DateType::HTML5_FORMAT, - 'start_date' => new \DateTime(), + 'start_date' => new \DateTimeImmutable(), 'show_range' => false, ]); } public function buildView(FormView $view, FormInterface $form, array $options): void { - /** @var \DateTime|null $date */ + /** @var \DateTimeInterface|null $date */ $date = $form->getData(); - if (null === $date) { + if ($date === null) { + /** @var \DateTimeImmutable $date */ $date = $options['start_date']; } + $date = \DateTime::createFromInterface($date); + $view->vars['year'] = $date; $view->vars['show_range'] = $options['show_range']; $view->vars['previousYear'] = (clone $date)->modify('-1 year'); diff --git a/src/Form/Type/YesNoType.php b/src/Form/Type/YesNoType.php index 4dcaeec7..1db5955f 100644 --- a/src/Form/Type/YesNoType.php +++ b/src/Form/Type/YesNoType.php @@ -15,6 +15,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Custom form field type to select between Yes and No. + * @extends AbstractType */ final class YesNoType extends AbstractType { diff --git a/src/Form/UserApiTokenType.php b/src/Form/UserApiTokenType.php index c938b75e..a800e75c 100644 --- a/src/Form/UserApiTokenType.php +++ b/src/Form/UserApiTokenType.php @@ -18,6 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used to set the users API token. + * @extends AbstractType */ final class UserApiTokenType extends AbstractType { diff --git a/src/Form/UserEditType.php b/src/Form/UserEditType.php index e0f589c1..be6d0a95 100644 --- a/src/Form/UserEditType.php +++ b/src/Form/UserEditType.php @@ -23,6 +23,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used to edit the profile of a User. + * @extends AbstractType */ class UserEditType extends AbstractType { diff --git a/src/Form/UserPasswordType.php b/src/Form/UserPasswordType.php index a4edf518..be5b0e66 100644 --- a/src/Form/UserPasswordType.php +++ b/src/Form/UserPasswordType.php @@ -17,7 +17,8 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; /** - * Defines the form used to set the users password. + * Defines the form used to set the user password. + * @extends AbstractType */ final class UserPasswordType extends AbstractType { diff --git a/src/Form/UserPreferencesForm.php b/src/Form/UserPreferencesForm.php index 4b5823e1..3abad12f 100644 --- a/src/Form/UserPreferencesForm.php +++ b/src/Form/UserPreferencesForm.php @@ -17,6 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used to edit the user preferences. + * @extends AbstractType */ final class UserPreferencesForm extends AbstractType { diff --git a/src/Form/UserRolesType.php b/src/Form/UserRolesType.php index 241c4527..5f5cdae2 100644 --- a/src/Form/UserRolesType.php +++ b/src/Form/UserRolesType.php @@ -17,6 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used to set roles for a User. + * @extends AbstractType */ final class UserRolesType extends AbstractType { diff --git a/src/Form/UserTeamsType.php b/src/Form/UserTeamsType.php index 56bbce2d..41b2c41f 100644 --- a/src/Form/UserTeamsType.php +++ b/src/Form/UserTeamsType.php @@ -17,6 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * Defines the form used to assign a User to teams. + * @extends AbstractType */ final class UserTeamsType extends AbstractType { diff --git a/src/Form/UserTwoFactorType.php b/src/Form/UserTwoFactorType.php index a0def9bf..32353237 100644 --- a/src/Form/UserTwoFactorType.php +++ b/src/Form/UserTwoFactorType.php @@ -20,6 +20,9 @@ use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Context\ExecutionContextInterface; +/** + * @extends AbstractType + */ final class UserTwoFactorType extends AbstractType { public function __construct(private TotpAuthenticatorInterface $totpAuthenticator) diff --git a/src/Invoice/Hydrator/InvoiceItemDefaultHydrator.php b/src/Invoice/Hydrator/InvoiceItemDefaultHydrator.php index 66c6c80c..347eae8e 100644 --- a/src/Invoice/Hydrator/InvoiceItemDefaultHydrator.php +++ b/src/Invoice/Hydrator/InvoiceItemDefaultHydrator.php @@ -93,6 +93,10 @@ final class InvoiceItemDefaultHydrator implements InvoiceItemHydrator 'entry.user_alias' => $user->getAlias() ?? '', 'entry.user_display' => $user->getDisplayName() ?? '', ]); + + foreach ($user->getVisiblePreferences() as $pref) { + $values['entry.user_preference.' . $pref->getName()] = $pref->getValue(); + } } if (null !== $activity) { diff --git a/src/Model/MonthlyStatistic.php b/src/Model/MonthlyStatistic.php index 2bbcfb24..d7777c62 100644 --- a/src/Model/MonthlyStatistic.php +++ b/src/Model/MonthlyStatistic.php @@ -19,12 +19,12 @@ final class MonthlyStatistic implements DateStatisticInterface /** * @var array, StatisticDate>> */ - private $years = []; - private $begin; - private $end; - private $user; + private array $years = []; + private DateTimeInterface $begin; + private DateTimeInterface $end; + private User $user; - public function __construct(DateTime $begin, DateTime $end, User $user) + public function __construct(DateTimeInterface $begin, DateTimeInterface $end, User $user) { $this->begin = clone $begin; $this->end = clone $end; @@ -43,7 +43,7 @@ final class MonthlyStatistic implements DateStatisticInterface } $years = []; - $begin = clone $this->begin; + $begin = DateTime::createFromInterface($this->begin); $begin->setTime(0, 0, 0); $tmp = clone $begin; diff --git a/src/Reporting/AbstractUserList.php b/src/Reporting/AbstractUserList.php index 12e65c66..8e32b8de 100644 --- a/src/Reporting/AbstractUserList.php +++ b/src/Reporting/AbstractUserList.php @@ -13,20 +13,17 @@ use App\Entity\Team; abstract class AbstractUserList { - private $date; - private $decimal = false; - private $sumType = 'duration'; - /** - * @var Team|null - */ - private $team = null; + private ?\DateTimeInterface $date = null; + private bool $decimal = false; + private string $sumType = 'duration'; + private ?Team $team = null; - public function getDate(): ?\DateTime + public function getDate(): ?\DateTimeInterface { return $this->date; } - public function setDate(\DateTime $date): void + public function setDate(\DateTimeInterface $date): void { $this->date = $date; } diff --git a/src/Reporting/CustomerMonthlyProjects/CustomerMonthlyProjectsForm.php b/src/Reporting/CustomerMonthlyProjects/CustomerMonthlyProjectsForm.php index 42318be7..4748608e 100644 --- a/src/Reporting/CustomerMonthlyProjects/CustomerMonthlyProjectsForm.php +++ b/src/Reporting/CustomerMonthlyProjects/CustomerMonthlyProjectsForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class CustomerMonthlyProjectsForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/MonthByUser/MonthByUserForm.php b/src/Reporting/MonthByUser/MonthByUserForm.php index 7a10a514..ff7648fd 100644 --- a/src/Reporting/MonthByUser/MonthByUserForm.php +++ b/src/Reporting/MonthByUser/MonthByUserForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class MonthByUserForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/MonthlyUserList/MonthlyUserListForm.php b/src/Reporting/MonthlyUserList/MonthlyUserListForm.php index 340b0437..684378d5 100644 --- a/src/Reporting/MonthlyUserList/MonthlyUserListForm.php +++ b/src/Reporting/MonthlyUserList/MonthlyUserListForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class MonthlyUserListForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/ProjectDateRange/ProjectDateRangeForm.php b/src/Reporting/ProjectDateRange/ProjectDateRangeForm.php index 98ac3285..71b0aba4 100644 --- a/src/Reporting/ProjectDateRange/ProjectDateRangeForm.php +++ b/src/Reporting/ProjectDateRange/ProjectDateRangeForm.php @@ -17,6 +17,9 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class ProjectDateRangeForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/ProjectDetails/ProjectDetailsForm.php b/src/Reporting/ProjectDetails/ProjectDetailsForm.php index 02d1e343..2c7027fd 100644 --- a/src/Reporting/ProjectDetails/ProjectDetailsForm.php +++ b/src/Reporting/ProjectDetails/ProjectDetailsForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class ProjectDetailsForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/ProjectInactive/ProjectInactiveForm.php b/src/Reporting/ProjectInactive/ProjectInactiveForm.php index 0c20dcb9..d0dab8d5 100644 --- a/src/Reporting/ProjectInactive/ProjectInactiveForm.php +++ b/src/Reporting/ProjectInactive/ProjectInactiveForm.php @@ -14,6 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class ProjectInactiveForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/ProjectView/ProjectViewForm.php b/src/Reporting/ProjectView/ProjectViewForm.php index 5442d8a4..5446f4ce 100644 --- a/src/Reporting/ProjectView/ProjectViewForm.php +++ b/src/Reporting/ProjectView/ProjectViewForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class ProjectViewForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/WeekByUser/WeekByUserForm.php b/src/Reporting/WeekByUser/WeekByUserForm.php index 32805483..838fbe49 100644 --- a/src/Reporting/WeekByUser/WeekByUserForm.php +++ b/src/Reporting/WeekByUser/WeekByUserForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class WeekByUserForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/WeeklyUserList/WeeklyUserListForm.php b/src/Reporting/WeeklyUserList/WeeklyUserListForm.php index 916793a6..62ae6acf 100644 --- a/src/Reporting/WeeklyUserList/WeeklyUserListForm.php +++ b/src/Reporting/WeeklyUserList/WeeklyUserListForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class WeeklyUserListForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/YearByUser/YearByUserForm.php b/src/Reporting/YearByUser/YearByUserForm.php index e45a0883..f4526166 100644 --- a/src/Reporting/YearByUser/YearByUserForm.php +++ b/src/Reporting/YearByUser/YearByUserForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class YearByUserForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Reporting/YearlyUserList/YearlyUserListForm.php b/src/Reporting/YearlyUserList/YearlyUserListForm.php index 1b108167..3be0710c 100644 --- a/src/Reporting/YearlyUserList/YearlyUserListForm.php +++ b/src/Reporting/YearlyUserList/YearlyUserListForm.php @@ -16,6 +16,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType + */ final class YearlyUserListForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Repository/Query/BaseQuery.php b/src/Repository/Query/BaseQuery.php index 081ebcd7..e4356f00 100644 --- a/src/Repository/Query/BaseQuery.php +++ b/src/Repository/Query/BaseQuery.php @@ -77,6 +77,11 @@ class BaseQuery return $this; } + public function hasTeams(): bool + { + return \count($this->teams) > 0; + } + /** * @return Team[] */ diff --git a/src/Repository/TimesheetRepository.php b/src/Repository/TimesheetRepository.php index 32a109aa..ad700375 100644 --- a/src/Repository/TimesheetRepository.php +++ b/src/Repository/TimesheetRepository.php @@ -515,9 +515,11 @@ class TimesheetRepository extends EntityRepository // if teams are used and the user is not a teamlead, the list of users would be empty and then leading to NOT limit the select by user IDs $user[] = $currentUser; - foreach ($currentUser->getTeams() as $team) { - if ($currentUser->isTeamleadOf($team)) { - $query->addTeam($team); + if (!$query->hasTeams()) { + foreach ($currentUser->getTeams() as $team) { + if ($currentUser->isTeamleadOf($team)) { + $query->addTeam($team); + } } } } diff --git a/src/Timesheet/TimesheetStatisticService.php b/src/Timesheet/TimesheetStatisticService.php index 6683cf29..fccb1bcf 100644 --- a/src/Timesheet/TimesheetStatisticService.php +++ b/src/Timesheet/TimesheetStatisticService.php @@ -14,6 +14,7 @@ use App\Model\DailyStatistic; use App\Model\MonthlyStatistic; use App\Repository\TimesheetRepository; use DateTime; +use DateTimeInterface; final class TimesheetStatisticService { @@ -22,12 +23,12 @@ final class TimesheetStatisticService } /** - * @param DateTime $begin - * @param DateTime $end + * @param DateTimeInterface $begin + * @param DateTimeInterface $end * @param User[] $users * @return DailyStatistic[] */ - public function getDailyStatistics(DateTime $begin, DateTime $end, array $users): array + public function getDailyStatistics(DateTimeInterface $begin, DateTimeInterface $end, array $users): array { /** @var DailyStatistic[] $stats */ $stats = []; @@ -86,12 +87,12 @@ final class TimesheetStatisticService /** * @internal only for core development - * @param DateTime $begin - * @param DateTime $end + * @param DateTimeInterface $begin + * @param DateTimeInterface $end * @param User[] $users * @return array */ - public function getDailyStatisticsGrouped(DateTime $begin, DateTime $end, array $users): array + public function getDailyStatisticsGrouped(DateTimeInterface $begin, DateTimeInterface $end, array $users): array { $stats = []; $usersById = []; @@ -163,12 +164,12 @@ final class TimesheetStatisticService /** * @internal only for core development - * @param DateTime $begin - * @param DateTime $end + * @param DateTimeInterface $begin + * @param DateTimeInterface $end * @param User[] $users * @return array */ - public function getMonthlyStatisticsGrouped(DateTime $begin, DateTime $end, array $users): array + public function getMonthlyStatisticsGrouped(DateTimeInterface $begin, DateTimeInterface $end, array $users): array { $stats = []; $usersById = []; diff --git a/src/Twig/Extensions.php b/src/Twig/Extensions.php index e36504c0..b3f75f6a 100644 --- a/src/Twig/Extensions.php +++ b/src/Twig/Extensions.php @@ -19,6 +19,8 @@ use Twig\TwigTest; final class Extensions extends AbstractExtension { + public const REPORT_DATE = 'Y-m-d'; + /** * {@inheritdoc} */ @@ -56,9 +58,9 @@ final class Extensions extends AbstractExtension ]; } - public function formatReportDate(\DateTime $dateTime): string + public function formatReportDate(\DateTimeInterface $dateTime): string { - return $dateTime->format('Y-m-d'); + return $dateTime->format(self::REPORT_DATE); } public function getIsoDayByName(string $weekDay): int diff --git a/src/Utils/DataTable.php b/src/Utils/DataTable.php index 308f8b16..e726109f 100644 --- a/src/Utils/DataTable.php +++ b/src/Utils/DataTable.php @@ -9,6 +9,7 @@ namespace App\Utils; +use App\Form\MultiUpdate\MultiUpdateTable; use App\Repository\Query\BaseQuery; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; @@ -18,6 +19,9 @@ final class DataTable implements \Countable, \IteratorAggregate { private ?Pagination $pagination = null; private ?FormInterface $searchForm = null; + /** + * @var FormInterface|null + */ private ?FormInterface $batchForm = null; private array $columns = []; private array $reloadEvents = []; @@ -79,6 +83,10 @@ final class DataTable implements \Countable, \IteratorAggregate return $this->batchForm?->createView(); } + /** + * @param FormInterface|null $batchForm + * @return void + */ public function setBatchForm(?FormInterface $batchForm): void { $this->batchForm = $batchForm; diff --git a/src/Utils/PaginationTemplate.php b/src/Utils/PaginationTemplate.php index 61dea183..61a537f6 100644 --- a/src/Utils/PaginationTemplate.php +++ b/src/Utils/PaginationTemplate.php @@ -13,6 +13,9 @@ use Pagerfanta\View\Template\TwitterBootstrap5Template; final class PaginationTemplate extends TwitterBootstrap5Template { + /** + * @return array + */ protected function getDefaultOptions(): array { return array_merge( diff --git a/symfony.lock b/symfony.lock index 58e4cd21..4d5412c7 100644 --- a/symfony.lock +++ b/symfony.lock @@ -225,9 +225,6 @@ "phar-io/version": { "version": "1.0.1" }, - "php-http/message-factory": { - "version": "v1.0.2" - }, "phpdocumentor/reflection-common": { "version": "1.0.1" }, diff --git a/templates/project/charts.html.twig b/templates/project/charts.html.twig index ec45ccf4..69a53347 100644 --- a/templates/project/charts.html.twig +++ b/templates/project/charts.html.twig @@ -77,6 +77,14 @@ {% endif %} {% endfor %} {% endfor %} + {% set last = chartData|last %} + {% if last is not empty and last.value > 0 %} + {% set chartValueZero = { + 'label': (showMoneyBudget ? 0|money(currency) : 0|duration), + 'value': (showMoneyBudget ? 0|chart_money : 0|chart_duration), + } %} + {% set chartData = chartData|merge([chartValueZero]) %} + {% endif %} {{ bar_chart(chartPrefix, chartLabels, [chartData], {'height': '300px', 'renderEvent': 'render.' ~ chartPrefix, 'type': 'line'}) }} {% endif %} {% endif %} diff --git a/tests/Invoice/Hydrator/InvoiceItemDefaultHydratorTest.php b/tests/Invoice/Hydrator/InvoiceItemDefaultHydratorTest.php index eb8d79ca..f3124461 100644 --- a/tests/Invoice/Hydrator/InvoiceItemDefaultHydratorTest.php +++ b/tests/Invoice/Hydrator/InvoiceItemDefaultHydratorTest.php @@ -69,6 +69,8 @@ class InvoiceItemDefaultHydratorTest extends TestCase 'entry.user_alias', 'entry.user_display', 'entry.user_title', + 'entry.user_preference.foo', + 'entry.user_preference.mad', 'entry.activity', 'entry.activity_id', 'entry.activity.meta.foo-activity', diff --git a/tests/Invoice/Renderer/DebugRendererTest.php b/tests/Invoice/Renderer/DebugRendererTest.php index 26e4981d..0f9452f3 100644 --- a/tests/Invoice/Renderer/DebugRendererTest.php +++ b/tests/Invoice/Renderer/DebugRendererTest.php @@ -276,6 +276,8 @@ class DebugRendererTest extends TestCase 'entry.user_display', 'entry.user_alias', 'entry.user_title', + 'entry.user_preference.foo', + 'entry.user_preference.mad', 'entry.activity', 'entry.activity_id', 'entry.activity.meta.foo-activity', diff --git a/tests/Invoice/Renderer/RendererTestTrait.php b/tests/Invoice/Renderer/RendererTestTrait.php index 5b4383be..54e3204d 100644 --- a/tests/Invoice/Renderer/RendererTestTrait.php +++ b/tests/Invoice/Renderer/RendererTestTrait.php @@ -133,17 +133,21 @@ trait RendererTestTrait $activity2->method('getMetaFields')->willReturn(new ArrayCollection([$aMeta2])); $activity2->method('getVisibleMetaFields')->willReturn([$aMeta2]); - $userMethods = ['getId', 'getPreferenceValue', 'getUsername', 'getUserIdentifier']; + $pref1 = new UserPreference('foo', 'bar'); + $pref2 = new UserPreference('mad', 123.45); + $userMethods = ['getId', 'getPreferenceValue', 'getVisiblePreferences', 'getUsername', 'getUserIdentifier']; $user1 = $this->getMockBuilder(User::class)->onlyMethods($userMethods)->disableOriginalConstructor()->getMock(); $user1->method('getId')->willReturn(1); $user1->method('getPreferenceValue')->willReturn('50'); $user1->method('getUsername')->willReturn('foo-bar'); $user1->method('getUserIdentifier')->willReturn('foo-bar'); + $user1->method('getVisiblePreferences')->willReturn([$pref1, $pref2]); - $user2 = $this->getMockBuilder(User::class)->onlyMethods($userMethods)->disableOriginalConstructor()->getMock(); + $user2 = $this->createMock(User::class); $user2->method('getId')->willReturn(2); $user2->method('getUsername')->willReturn('hello-world'); $user2->method('getUserIdentifier')->willReturn('hello-world'); + $user2->method('getVisiblePreferences')->willReturn([$pref1, $pref2]); $timesheet = new Timesheet(); $timesheet @@ -204,6 +208,8 @@ trait RendererTestTrait $userKevin = new User(); $userKevin->setUserIdentifier('kevin'); + $userKevin->addPreference($pref1); + $userKevin->addPreference($pref2); $timesheet5 = new Timesheet(); $timesheet5 @@ -292,11 +298,14 @@ trait RendererTestTrait $activity->setProject($project); $activity->setMetaField((new ActivityMeta())->setName('foo-activity')->setValue('bar-activity')->setIsVisible(true)); + $pref1 = new UserPreference('foo', 'bar'); + $pref2 = new UserPreference('mad', 123.45); $user1 = $this->createMock(User::class); $user1->method('getId')->willReturn(1); $user1->method('getPreferenceValue')->willReturn('50'); $user1->method('getUsername')->willReturn('foo-bar'); $user1->method('getUserIdentifier')->willReturn('foo-bar'); + $user1->method('getVisiblePreferences')->willReturn([$pref1, $pref2]); $timesheet = new Timesheet(); $timesheet diff --git a/tests/Saml/Security/SamlAuthenticationSuccessHandlerTest.php b/tests/Saml/Security/SamlAuthenticationSuccessHandlerTest.php index 7b3cfa04..979453a7 100644 --- a/tests/Saml/Security/SamlAuthenticationSuccessHandlerTest.php +++ b/tests/Saml/Security/SamlAuthenticationSuccessHandlerTest.php @@ -13,6 +13,7 @@ use App\Entity\User; use App\Saml\SamlToken; use App\Saml\Security\SamlAuthenticationSuccessHandler; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Http\HttpUtils; @@ -27,6 +28,7 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase $handler = new SamlAuthenticationSuccessHandler($httpUtils, ['always_use_default_target_path' => true]); $defaultTargetPath = $httpUtils->generateUri($this->getRequest('/sso/login'), $this->getOption($handler, 'default_target_path', '/')); $response = $handler->onAuthenticationSuccess($this->getRequest('/login', 'http://localhost/relayed'), $this->getSamlToken()); + $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertTrue($response->isRedirect($defaultTargetPath)); } @@ -34,6 +36,7 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase { $handler = new SamlAuthenticationSuccessHandler(new HttpUtils($this->getUrlGenerator()), ['always_use_default_target_path' => false]); $response = $handler->onAuthenticationSuccess($this->getRequest('/sso/login', 'http://localhost/relayed'), $this->getSamlToken()); + $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertTrue($response->isRedirect('http://localhost/relayed')); } @@ -43,6 +46,7 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase $handler = new SamlAuthenticationSuccessHandler($httpUtils, ['always_use_default_target_path' => false]); $defaultTargetPath = $httpUtils->generateUri($this->getRequest('/sso/login'), $this->getOption($handler, 'default_target_path', '/')); $response = $handler->onAuthenticationSuccess($this->getRequest(), $this->getSamlToken()); + $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertTrue($response->isRedirect($defaultTargetPath)); } @@ -52,6 +56,7 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase $handler = new SamlAuthenticationSuccessHandler($httpUtils, ['always_use_default_target_path' => false]); $loginPath = $httpUtils->generateUri($this->getRequest('/sso/login'), $this->getOption($handler, 'login_path', '/login')); $response = $handler->onAuthenticationSuccess($this->getRequest($loginPath), $this->getSamlToken()); + $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertTrue(!$response->isRedirect($loginPath)); }