Release 2.49 (#5820)

* bump packages
* add column summarization per customer (#5808)
* clarify database requirements
* added helper methods to fetch original expected time

Co-authored-by: GregorB54321 <34287148+GregorB54321@users.noreply.github.com>
This commit is contained in:
Kevin Papst
2026-02-15 21:31:06 +01:00
committed by GitHub
parent f376b5c8a1
commit ff6918fcab
10 changed files with 221 additions and 117 deletions

View File

@@ -28,7 +28,7 @@ and so much more.
### Requirements ### Requirements
- PHP 8.1.3 minimum with support for 8.2, 8.3, 8.4, 8.5 - PHP 8.1.3 minimum with support for 8.2, 8.3, 8.4, 8.5
- MariaDB or MySQL - MariaDB / MySQL in their oldest maintained LTS release, currently MariaDB >= [10.6](https://endoflife.date/mariadb) or MySQL >= [8.4](https://endoflife.date/mysql)
- A webserver and subdomain (subdirectory is not supported) - A webserver and subdomain (subdirectory is not supported)
- PHP extensions: `gd`, `intl`, `json`, `mbstring`, `pdo`, `tokenizer`, `xml`, `xsl`, `zip` - PHP extensions: `gd`, `intl`, `json`, `mbstring`, `pdo`, `tokenizer`, `xml`, `xsl`, `zip`

241
composer.lock generated
View File

@@ -726,29 +726,29 @@
}, },
{ {
"name": "doctrine/deprecations", "name": "doctrine/deprecations",
"version": "1.1.5", "version": "1.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/deprecations.git", "url": "https://github.com/doctrine/deprecations.git",
"reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca",
"reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.1 || ^8.0" "php": "^7.1 || ^8.0"
}, },
"conflict": { "conflict": {
"phpunit/phpunit": "<=7.5 || >=13" "phpunit/phpunit": "<=7.5 || >=14"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^9 || ^12 || ^13", "doctrine/coding-standard": "^9 || ^12 || ^14",
"phpstan/phpstan": "1.4.10 || 2.1.11", "phpstan/phpstan": "1.4.10 || 2.1.30",
"phpstan/phpstan-phpunit": "^1.0 || ^2", "phpstan/phpstan-phpunit": "^1.0 || ^2",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0",
"psr/log": "^1 || ^2 || ^3" "psr/log": "^1 || ^2 || ^3"
}, },
"suggest": { "suggest": {
@@ -768,9 +768,9 @@
"homepage": "https://www.doctrine-project.org/", "homepage": "https://www.doctrine-project.org/",
"support": { "support": {
"issues": "https://github.com/doctrine/deprecations/issues", "issues": "https://github.com/doctrine/deprecations/issues",
"source": "https://github.com/doctrine/deprecations/tree/1.1.5" "source": "https://github.com/doctrine/deprecations/tree/1.1.6"
}, },
"time": "2025-04-07T20:06:18+00:00" "time": "2026-02-07T07:09:04+00:00"
}, },
{ {
"name": "doctrine/doctrine-bundle", "name": "doctrine/doctrine-bundle",
@@ -1308,16 +1308,16 @@
}, },
{ {
"name": "doctrine/migrations", "name": "doctrine/migrations",
"version": "3.9.5", "version": "3.9.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/migrations.git", "url": "https://github.com/doctrine/migrations.git",
"reference": "1b823afbc40f932dae8272574faee53f2755eac5" "reference": "ffd8355cdd8505fc650d9604f058bf62aedd80a1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/migrations/zipball/1b823afbc40f932dae8272574faee53f2755eac5", "url": "https://api.github.com/repos/doctrine/migrations/zipball/ffd8355cdd8505fc650d9604f058bf62aedd80a1",
"reference": "1b823afbc40f932dae8272574faee53f2755eac5", "reference": "ffd8355cdd8505fc650d9604f058bf62aedd80a1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1391,7 +1391,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/migrations/issues", "issues": "https://github.com/doctrine/migrations/issues",
"source": "https://github.com/doctrine/migrations/tree/3.9.5" "source": "https://github.com/doctrine/migrations/tree/3.9.6"
}, },
"funding": [ "funding": [
{ {
@@ -1407,7 +1407,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-11-20T11:15:36+00:00" "time": "2026-02-11T06:46:11+00:00"
}, },
{ {
"name": "doctrine/orm", "name": "doctrine/orm",
@@ -1608,16 +1608,16 @@
}, },
{ {
"name": "doctrine/sql-formatter", "name": "doctrine/sql-formatter",
"version": "1.5.3", "version": "1.5.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/sql-formatter.git", "url": "https://github.com/doctrine/sql-formatter.git",
"reference": "a8af23a8e9d622505baa2997465782cbe8bb7fc7" "reference": "9563949f5cd3bd12a17d12fb980528bc141c5806"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/a8af23a8e9d622505baa2997465782cbe8bb7fc7", "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/9563949f5cd3bd12a17d12fb980528bc141c5806",
"reference": "a8af23a8e9d622505baa2997465782cbe8bb7fc7", "reference": "9563949f5cd3bd12a17d12fb980528bc141c5806",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1657,9 +1657,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/sql-formatter/issues", "issues": "https://github.com/doctrine/sql-formatter/issues",
"source": "https://github.com/doctrine/sql-formatter/tree/1.5.3" "source": "https://github.com/doctrine/sql-formatter/tree/1.5.4"
}, },
"time": "2025-10-26T09:35:14+00:00" "time": "2026-02-08T16:21:46+00:00"
}, },
{ {
"name": "easybill/zugferd-php", "name": "easybill/zugferd-php",
@@ -1919,29 +1919,29 @@
}, },
{ {
"name": "friendsofsymfony/rest-bundle", "name": "friendsofsymfony/rest-bundle",
"version": "3.8.0", "version": "3.9.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git", "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git",
"reference": "d24736896518bae817bf0de8a6b682cb6535044b" "reference": "0a0d597a79734a8bd3a90cf6fa58de82940fc873"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/d24736896518bae817bf0de8a6b682cb6535044b", "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/0a0d597a79734a8bd3a90cf6fa58de82940fc873",
"reference": "d24736896518bae817bf0de8a6b682cb6535044b", "reference": "0a0d597a79734a8bd3a90cf6fa58de82940fc873",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.4|^8.0", "php": "^7.4|^8.0",
"symfony/config": "^5.4|^6.4|^7.0", "symfony/config": "^5.4|^6.4|^7.0|^8.0",
"symfony/dependency-injection": "^5.4|^6.4|^7.0", "symfony/dependency-injection": "^5.4|^6.4|^7.0|^8.0",
"symfony/deprecation-contracts": "^2.1|^3.0", "symfony/deprecation-contracts": "^2.1|^3.0",
"symfony/event-dispatcher": "^5.4|^6.4|^7.0", "symfony/event-dispatcher": "^5.4|^6.4|^7.0|^8.0",
"symfony/framework-bundle": "^5.4|^6.4|^7.0", "symfony/framework-bundle": "^5.4|^6.4|^7.0|^8.0",
"symfony/http-foundation": "^5.4|^6.4|^7.0", "symfony/http-foundation": "^5.4|^6.4|^7.0|^8.0",
"symfony/http-kernel": "^5.4|^6.4|^7.0", "symfony/http-kernel": "^5.4|^6.4|^7.0|^8.0",
"symfony/routing": "^5.4|^6.4|^7.0", "symfony/routing": "^5.4|^6.4|^7.0|^8.0",
"symfony/security-core": "^5.4|^6.4|^7.0", "symfony/security-core": "^5.4|^6.4|^7.0|^8.0",
"willdurand/jsonp-callback-validator": "^1.0|^2.0", "willdurand/jsonp-callback-validator": "^1.0|^2.0",
"willdurand/negotiation": "^2.0|^3.0" "willdurand/negotiation": "^2.0|^3.0"
}, },
@@ -1959,19 +1959,19 @@
"psr/http-message": "^1.0", "psr/http-message": "^1.0",
"psr/log": "^1.0|^2.0|^3.0", "psr/log": "^1.0|^2.0|^3.0",
"sensio/framework-extra-bundle": "^6.1", "sensio/framework-extra-bundle": "^6.1",
"symfony/asset": "^5.4|^6.4|^7.0", "symfony/asset": "^5.4|^6.4|^7.0|^8.0",
"symfony/browser-kit": "^5.4|^6.4|^7.0", "symfony/browser-kit": "^5.4|^6.4|^7.0|^8.0",
"symfony/css-selector": "^5.4|^6.4|^7.0", "symfony/css-selector": "^5.4|^6.4|^7.0|^8.0",
"symfony/expression-language": "^5.4|^6.4|^7.0", "symfony/expression-language": "^5.4|^6.4|^7.0|^8.0",
"symfony/form": "^5.4|^6.4|^7.0", "symfony/form": "^5.4|^6.4|^7.0|^8.0",
"symfony/mime": "^5.4|^6.4|^7.0", "symfony/mime": "^5.4|^6.4|^7.0|^8.0",
"symfony/phpunit-bridge": "^7.0.1", "symfony/phpunit-bridge": "^7.0.1|^8.0",
"symfony/security-bundle": "^5.4|^6.4|^7.0", "symfony/security-bundle": "^5.4|^6.4|^7.0|^8.0",
"symfony/serializer": "^5.4|^6.4|^7.0", "symfony/serializer": "^5.4|^6.4|^7.0|^8.0",
"symfony/twig-bundle": "^5.4|^6.4|^7.0", "symfony/twig-bundle": "^5.4|^6.4|^7.0|^8.0",
"symfony/validator": "^5.4|^6.4|^7.0", "symfony/validator": "^5.4|^6.4|^7.0|^8.0",
"symfony/web-profiler-bundle": "^5.4|^6.4|^7.0", "symfony/web-profiler-bundle": "^5.4|^6.4|^7.0|^8.0",
"symfony/yaml": "^5.4|^6.4|^7.0" "symfony/yaml": "^5.4|^6.4|^7.0|^8.0"
}, },
"suggest": { "suggest": {
"jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended", "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended",
@@ -2019,9 +2019,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/FriendsOfSymfony/FOSRestBundle/issues", "issues": "https://github.com/FriendsOfSymfony/FOSRestBundle/issues",
"source": "https://github.com/FriendsOfSymfony/FOSRestBundle/tree/3.8.0" "source": "https://github.com/FriendsOfSymfony/FOSRestBundle/tree/3.9.0"
}, },
"time": "2024-11-04T08:41:36+00:00" "time": "2026-02-10T02:36:12+00:00"
}, },
{ {
"name": "gedmo/doctrine-extensions", "name": "gedmo/doctrine-extensions",
@@ -2722,16 +2722,16 @@
}, },
{ {
"name": "kevinpapst/tabler-bundle", "name": "kevinpapst/tabler-bundle",
"version": "2.1.0", "version": "2.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/kevinpapst/TablerBundle.git", "url": "https://github.com/kevinpapst/TablerBundle.git",
"reference": "b608ff05a7ba77b8fc32540bca086f6d18c2761e" "reference": "d0f4130d7cba33015bbd798bfe529eeb4f19ac3f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/kevinpapst/TablerBundle/zipball/b608ff05a7ba77b8fc32540bca086f6d18c2761e", "url": "https://api.github.com/repos/kevinpapst/TablerBundle/zipball/d0f4130d7cba33015bbd798bfe529eeb4f19ac3f",
"reference": "b608ff05a7ba77b8fc32540bca086f6d18c2761e", "reference": "d0f4130d7cba33015bbd798bfe529eeb4f19ac3f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2781,7 +2781,7 @@
"description": "Admin/Backend theme bundle for Symfony based on Tabler.io", "description": "Admin/Backend theme bundle for Symfony based on Tabler.io",
"support": { "support": {
"issues": "https://github.com/kevinpapst/TablerBundle/issues", "issues": "https://github.com/kevinpapst/TablerBundle/issues",
"source": "https://github.com/kevinpapst/TablerBundle/tree/2.1.0" "source": "https://github.com/kevinpapst/TablerBundle/tree/2.2.0"
}, },
"funding": [ "funding": [
{ {
@@ -2793,7 +2793,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2026-01-19T09:05:10+00:00" "time": "2026-02-15T08:43:44+00:00"
}, },
{ {
"name": "league/csv", "name": "league/csv",
@@ -10801,16 +10801,16 @@
}, },
{ {
"name": "zircote/swagger-php", "name": "zircote/swagger-php",
"version": "5.8.0", "version": "5.8.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zircote/swagger-php.git", "url": "https://github.com/zircote/swagger-php.git",
"reference": "9cf5d1a0c159894026708c9e837e69140c2d3922" "reference": "18ee6592518238a5a6c9905aae4926d5bbc65754"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/9cf5d1a0c159894026708c9e837e69140c2d3922", "url": "https://api.github.com/repos/zircote/swagger-php/zipball/18ee6592518238a5a6c9905aae4926d5bbc65754",
"reference": "9cf5d1a0c159894026708c9e837e69140c2d3922", "reference": "18ee6592518238a5a6c9905aae4926d5bbc65754",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10883,7 +10883,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/zircote/swagger-php/issues", "issues": "https://github.com/zircote/swagger-php/issues",
"source": "https://github.com/zircote/swagger-php/tree/5.8.0" "source": "https://github.com/zircote/swagger-php/tree/5.8.2"
}, },
"funding": [ "funding": [
{ {
@@ -10891,7 +10891,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2026-01-28T01:27:48+00:00" "time": "2026-02-10T20:10:15+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@@ -11437,16 +11437,16 @@
}, },
{ {
"name": "friendsofphp/php-cs-fixer", "name": "friendsofphp/php-cs-fixer",
"version": "v3.93.1", "version": "v3.94.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "b3546ab487c0762c39f308dc1ec0ea2c461fc21a" "reference": "883b20fb38c7866de9844ab6d0a205c423bde2d4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/b3546ab487c0762c39f308dc1ec0ea2c461fc21a", "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/883b20fb38c7866de9844ab6d0a205c423bde2d4",
"reference": "b3546ab487c0762c39f308dc1ec0ea2c461fc21a", "reference": "883b20fb38c7866de9844ab6d0a205c423bde2d4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11463,7 +11463,7 @@
"react/event-loop": "^1.5", "react/event-loop": "^1.5",
"react/socket": "^1.16", "react/socket": "^1.16",
"react/stream": "^1.4", "react/stream": "^1.4",
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0 || ^8.0",
"symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0", "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
@@ -11477,18 +11477,18 @@
"symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0" "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0"
}, },
"require-dev": { "require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.7", "facile-it/paraunit": "^1.3.1 || ^2.7.1",
"infection/infection": "^0.32", "infection/infection": "^0.32.3",
"justinrainbow/json-schema": "^6.6", "justinrainbow/json-schema": "^6.6.4",
"keradus/cli-executor": "^2.3", "keradus/cli-executor": "^2.3",
"mikey179/vfsstream": "^1.6.12", "mikey179/vfsstream": "^1.6.12",
"php-coveralls/php-coveralls": "^2.9", "php-coveralls/php-coveralls": "^2.9.1",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.7",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.7",
"phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.48", "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.51",
"symfony/polyfill-php85": "^1.33", "symfony/polyfill-php85": "^1.33",
"symfony/var-dumper": "^5.4.48 || ^6.4.26 || ^7.4.0 || ^8.0", "symfony/var-dumper": "^5.4.48 || ^6.4.32 || ^7.4.4 || ^8.0.4",
"symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0" "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0.1"
}, },
"suggest": { "suggest": {
"ext-dom": "For handling output formats in XML", "ext-dom": "For handling output formats in XML",
@@ -11529,7 +11529,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.93.1" "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.94.0"
}, },
"funding": [ "funding": [
{ {
@@ -11537,7 +11537,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2026-01-28T23:50:50+00:00" "time": "2026-02-11T16:44:33+00:00"
}, },
{ {
"name": "masterminds/html5", "name": "masterminds/html5",
@@ -11726,11 +11726,11 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "2.1.37", "version": "2.1.39",
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/28cd424c5ea984128c95cfa7ea658808e8954e49", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c6f73a2af4cbcd99c931d0fb8f08548cc0fa8224",
"reference": "28cd424c5ea984128c95cfa7ea658808e8954e49", "reference": "c6f73a2af4cbcd99c931d0fb8f08548cc0fa8224",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11775,25 +11775,25 @@
"type": "github" "type": "github"
} }
], ],
"time": "2026-01-24T08:21:55+00:00" "time": "2026-02-11T14:48:56+00:00"
}, },
{ {
"name": "phpstan/phpstan-deprecation-rules", "name": "phpstan/phpstan-deprecation-rules",
"version": "2.0.3", "version": "2.0.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-deprecation-rules.git", "url": "https://github.com/phpstan/phpstan-deprecation-rules.git",
"reference": "468e02c9176891cc901143da118f09dc9505fc2f" "reference": "6b5571001a7f04fa0422254c30a0017ec2f2cacc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/468e02c9176891cc901143da118f09dc9505fc2f", "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/6b5571001a7f04fa0422254c30a0017ec2f2cacc",
"reference": "468e02c9176891cc901143da118f09dc9505fc2f", "reference": "6b5571001a7f04fa0422254c30a0017ec2f2cacc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.4 || ^8.0", "php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.1.15" "phpstan/phpstan": "^2.1.39"
}, },
"require-dev": { "require-dev": {
"php-parallel-lint/php-parallel-lint": "^1.2", "php-parallel-lint/php-parallel-lint": "^1.2",
@@ -11818,24 +11818,27 @@
"MIT" "MIT"
], ],
"description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.",
"keywords": [
"static analysis"
],
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues",
"source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/2.0.3" "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/2.0.4"
}, },
"time": "2025-05-14T10:56:57+00:00" "time": "2026-02-09T13:21:14+00:00"
}, },
{ {
"name": "phpstan/phpstan-doctrine", "name": "phpstan/phpstan-doctrine",
"version": "2.0.14", "version": "2.0.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-doctrine.git", "url": "https://github.com/phpstan/phpstan-doctrine.git",
"reference": "70cd3e82fef49171163ff682a89cfe793d88581c" "reference": "f4ff6084a26d91174b3f0b047589af293a893104"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/70cd3e82fef49171163ff682a89cfe793d88581c", "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/f4ff6084a26d91174b3f0b047589af293a893104",
"reference": "70cd3e82fef49171163ff682a89cfe793d88581c", "reference": "f4ff6084a26d91174b3f0b047589af293a893104",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11891,24 +11894,27 @@
"MIT" "MIT"
], ],
"description": "Doctrine extensions for PHPStan", "description": "Doctrine extensions for PHPStan",
"keywords": [
"static analysis"
],
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-doctrine/issues", "issues": "https://github.com/phpstan/phpstan-doctrine/issues",
"source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.14" "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.16"
}, },
"time": "2026-01-25T14:56:09+00:00" "time": "2026-02-11T08:54:45+00:00"
}, },
{ {
"name": "phpstan/phpstan-phpunit", "name": "phpstan/phpstan-phpunit",
"version": "2.0.12", "version": "2.0.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git", "url": "https://github.com/phpstan/phpstan-phpunit.git",
"reference": "e4c5a22bf43d3d2bd5a780ad261a622ff62c49a4" "reference": "6ab598e1bc106e6827fd346ae4a12b4a5d634c32"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/e4c5a22bf43d3d2bd5a780ad261a622ff62c49a4", "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/6ab598e1bc106e6827fd346ae4a12b4a5d634c32",
"reference": "e4c5a22bf43d3d2bd5a780ad261a622ff62c49a4", "reference": "6ab598e1bc106e6827fd346ae4a12b4a5d634c32",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11944,29 +11950,32 @@
"MIT" "MIT"
], ],
"description": "PHPUnit extensions and rules for PHPStan", "description": "PHPUnit extensions and rules for PHPStan",
"keywords": [
"static analysis"
],
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-phpunit/issues", "issues": "https://github.com/phpstan/phpstan-phpunit/issues",
"source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.12" "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.16"
}, },
"time": "2026-01-22T13:40:00+00:00" "time": "2026-02-14T09:05:21+00:00"
}, },
{ {
"name": "phpstan/phpstan-strict-rules", "name": "phpstan/phpstan-strict-rules",
"version": "2.0.8", "version": "2.0.10",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git", "url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "1ed9e626a37f7067b594422411539aa807190573" "reference": "1aba28b697c1e3b6bbec8a1725f8b11b6d3e5a5f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/1ed9e626a37f7067b594422411539aa807190573", "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/1aba28b697c1e3b6bbec8a1725f8b11b6d3e5a5f",
"reference": "1ed9e626a37f7067b594422411539aa807190573", "reference": "1aba28b697c1e3b6bbec8a1725f8b11b6d3e5a5f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.4 || ^8.0", "php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.1.29" "phpstan/phpstan": "^2.1.39"
}, },
"require-dev": { "require-dev": {
"php-parallel-lint/php-parallel-lint": "^1.2", "php-parallel-lint/php-parallel-lint": "^1.2",
@@ -11992,24 +12001,27 @@
"MIT" "MIT"
], ],
"description": "Extra strict and opinionated rules for PHPStan", "description": "Extra strict and opinionated rules for PHPStan",
"keywords": [
"static analysis"
],
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues", "issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.8" "source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.10"
}, },
"time": "2026-01-27T08:10:25+00:00" "time": "2026-02-11T14:17:32+00:00"
}, },
{ {
"name": "phpstan/phpstan-symfony", "name": "phpstan/phpstan-symfony",
"version": "2.0.12", "version": "2.0.14",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-symfony.git", "url": "https://github.com/phpstan/phpstan-symfony.git",
"reference": "a46dd92eaf15146cd932d897a272e59cd4108ce2" "reference": "678136545a552a33b07f1a59a013f76df286cc34"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/a46dd92eaf15146cd932d897a272e59cd4108ce2", "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/678136545a552a33b07f1a59a013f76df286cc34",
"reference": "a46dd92eaf15146cd932d897a272e59cd4108ce2", "reference": "678136545a552a33b07f1a59a013f76df286cc34",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12063,11 +12075,14 @@
} }
], ],
"description": "Symfony Framework extensions and rules for PHPStan", "description": "Symfony Framework extensions and rules for PHPStan",
"keywords": [
"static analysis"
],
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-symfony/issues", "issues": "https://github.com/phpstan/phpstan-symfony/issues",
"source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.12" "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.14"
}, },
"time": "2026-01-23T09:04:33+00:00" "time": "2026-02-11T12:27:30+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",

View File

@@ -27,6 +27,7 @@ parameters:
numericOperandsInArithmeticOperators: true numericOperandsInArithmeticOperators: true
switchConditionsMatchingType: true switchConditionsMatchingType: true
noVariableVariables: false noVariableVariables: false
reportNonIntStringArrayKey: false
paths: paths:
- src - src
tmpDir: %rootDir%/../../../var/cache/phpstan tmpDir: %rootDir%/../../../var/cache/phpstan

View File

@@ -17,11 +17,11 @@ final class Constants
/** /**
* The current release version * The current release version
*/ */
public const VERSION = '2.48.0'; public const VERSION = '2.49.0';
/** /**
* The current release: major * 10000 + minor * 100 + patch * The current release: major * 10000 + minor * 100 + patch
*/ */
public const VERSION_ID = 24800; public const VERSION_ID = 24900;
/** /**
* The software name * The software name
*/ */

View File

@@ -36,6 +36,7 @@ class WorkingTime
#[ORM\Column(name: 'expected', type: Types::INTEGER, nullable: false)] #[ORM\Column(name: 'expected', type: Types::INTEGER, nullable: false)]
#[Assert\NotNull] #[Assert\NotNull]
private int $expectedTime = 0; private int $expectedTime = 0;
private ?int $originalExpectedTime = null;
#[ORM\Column(name: 'actual', type: Types::INTEGER, nullable: false)] #[ORM\Column(name: 'actual', type: Types::INTEGER, nullable: false)]
#[Assert\NotNull] #[Assert\NotNull]
private int $actualTime = 0; private int $actualTime = 0;
@@ -75,6 +76,39 @@ class WorkingTime
public function setExpectedTime(int $expectedTime): void public function setExpectedTime(int $expectedTime): void
{ {
$this->expectedTime = $expectedTime; $this->expectedTime = $expectedTime;
$this->storeOriginalExpectedTime();
}
public function storeOriginalExpectedTime(): void
{
if ($this->originalExpectedTime === null) {
$this->originalExpectedTime = $this->expectedTime;
}
}
public function getOriginalExpectedTime(): int
{
$this->storeOriginalExpectedTime();
return $this->originalExpectedTime ?? 0;
}
public function halveExpectedTime(): int
{
$this->storeOriginalExpectedTime();
$reduceBy = ($this->getOriginalExpectedTime() / 2);
$this->expectedTime = $this->expectedTime - $reduceBy;
return $reduceBy;
}
public function emptyExpectedTime(): void
{
$this->storeOriginalExpectedTime();
$this->expectedTime = 0;
} }
public function getActualTime(): int public function getActualTime(): int

View File

@@ -17,5 +17,8 @@
{% block column_classes_total -%} {% block column_classes_total -%}
{% if column is weekend %} weekend{% endif %} {% if column is weekend %} weekend{% endif %}
{%- endblock %} {%- endblock %}
{% block column_classes_customer_total -%}
{% if column is weekend %} weekend{% endif %}
{%- endblock %}
{% endembed %} {% endembed %}
{% endblock %} {% endblock %}

View File

@@ -46,6 +46,23 @@
{% elseif data.customer != totalCurrency %} {% elseif data.customer != totalCurrency %}
{% set totalCurrency = null %} {% set totalCurrency = null %}
{% endif %} {% endif %}
{% set customerTotalsDuration = {} %}
{% set customerTotalsInternalRate = {} %}
{% set customerTotalsRate = {} %}
{% for column in period.dateTimes %}
{% set dateKey = column|report_date %}
{% set customerTotalsDuration = customerTotalsDuration|merge({(dateKey): 0}) %}
{% set customerTotalsInternalRate = customerTotalsInternalRate|merge({(dateKey): 0}) %}
{% set customerTotalsRate = customerTotalsRate|merge({(dateKey): 0}) %}
{% endfor %}
{% for project in data.projects %}
{% for column in project.data.data %}
{% set dateKey = column.date|report_date %}
{% set customerTotalsDuration = customerTotalsDuration|merge({(dateKey): (customerTotalsDuration[dateKey] + column.duration)}) %}
{% set customerTotalsInternalRate = customerTotalsInternalRate|merge({(dateKey): (customerTotalsInternalRate[dateKey] + column.internalRate)}) %}
{% set customerTotalsRate = customerTotalsRate|merge({(dateKey): (customerTotalsRate[dateKey] + column.rate)}) %}
{% endfor %}
{% endfor %}
<tr class="summary"> <tr class="summary">
<td>{{ widgets.label_customer(data.customer) }}</td> <td>{{ widgets.label_customer(data.customer) }}</td>
<td class="text-center total"> <td class="text-center total">
@@ -59,7 +76,20 @@
{% endif %} {% endif %}
{% if with_links %}</a>{% endif %} {% if with_links %}</a>{% endif %}
</td> </td>
<td colspan="{{ columns }}"></td> {% for column in period.dateTimes %}
{% set dateKey = column|report_date %}
<td class="text-nowrap text-center day-total {% block column_classes_customer_total %}{% endblock %}">
{% if customerTotalsRate[dateKey] > 0 or customerTotalsInternalRate[dateKey] > 0 or customerTotalsDuration[dateKey] > 0 %}
{% if dataType == 'rate' %}
<strong>{{ customerTotalsRate[dateKey]|money(currency) }}</strong>
{% elseif dataType == 'internalRate' %}
<strong>{{ customerTotalsInternalRate[dateKey]|money(currency) }}</strong>
{% else %}
<strong>{{ customerTotalsDuration[dateKey]|duration(decimal) }}</strong>
{% endif %}
{% endif %}
</td>
{% endfor %}
</tr> </tr>
{% for project in data.projects %} {% for project in data.projects %}
{% set absoluteDuration = absoluteDuration + project.duration %} {% set absoluteDuration = absoluteDuration + project.duration %}

View File

@@ -14,5 +14,6 @@
{% block column_classes_project %}{% endblock %} {% block column_classes_project %}{% endblock %}
{% block column_classes_activity %}{% endblock %} {% block column_classes_activity %}{% endblock %}
{% block column_classes_total %}{% endblock %} {% block column_classes_total %}{% endblock %}
{% block column_classes_customer_total %}{% endblock %}
{% endembed %} {% endembed %}
{% endblock %} {% endblock %}

View File

@@ -5,4 +5,5 @@
{% block column_classes_project %}{% endblock %} {% block column_classes_project %}{% endblock %}
{% block column_classes_activity %}{% endblock %} {% block column_classes_activity %}{% endblock %}
{% block column_classes_total %}{% endblock %} {% block column_classes_total %}{% endblock %}
{% block column_classes_customer_total %}{% endblock %}
{% endembed %} {% endembed %}

View File

@@ -50,4 +50,23 @@ class WorkingTimeTest extends TestCase
self::assertSame($approvedBy, $sut->getApprovedBy()); self::assertSame($approvedBy, $sut->getApprovedBy());
self::assertTrue($sut->isApproved()); self::assertTrue($sut->isApproved());
} }
public function testExpectedTime(): void
{
$user = new User();
$user->setUsername('bar');
$date = new \DateTimeImmutable();
$sut = new WorkingTime($user, $date);
$sut->setExpectedTime(222222);
self::assertEquals(222222, $sut->getExpectedTime());
self::assertEquals(222222, $sut->getOriginalExpectedTime());
$reducedBy = $sut->halveExpectedTime();
self::assertEquals(111111, $reducedBy);
self::assertEquals(111111, $sut->getExpectedTime());
self::assertEquals(222222, $sut->getOriginalExpectedTime());
$sut->emptyExpectedTime();
self::assertEquals(0, $sut->getExpectedTime());
self::assertEquals(222222, $sut->getOriginalExpectedTime());
}
} }