diff --git a/.env b/.env index bdd0937..3883c42 100644 --- a/.env +++ b/.env @@ -58,3 +58,10 @@ MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!" # postgresql+advisory://db_user:db_password@localhost/db_name LOCK_DSN=flock ###< symfony/lock ### + +###> tidy-feedback ### +# See https://github.com/itk-dev/tidy-feedback#all-configuration-options +TIDY_FEEDBACK_DATABASE_URL=pdo-sqlite://localhost//app/var/tidy-feedback.sqlite +TIDY_FEEDBACK_DISABLE=false +TIDY_FEEDBACK_DISABLE_PATTERN=@^/tidy-feedback/@ +###< tidy-feedback ### diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6bfe3..e8af3c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +* [PR-46](https://github.com/itk-dev/itk-projects/pull/46) + * Remove the "Summary" field. + * Ask "Er projektet godkendt" instead of "Er projektet vedtaget". + * Label the committee endorsement choice "Udvalg/Styregruppe". + * Rename "Emne" to "EU topic" and make it a single-line field. + * Show and accept thousands separators ("1.250.000") in the money fields, + added as you type. + * Mark the invalid fields and show their messages when a save fails, for + example a negative amount. + * Add [tidy-feedback](https://github.com/itk-dev/tidy-feedback) to the mix. * [PR-40](https://github.com/itk-dev/itk-projects/pull/40) Let a project belong to several areas, picked with a searchable multiselect. * [PR-43](https://github.com/itk-dev/itk-projects/pull/43) diff --git a/assets/controllers/autosave_controller.js b/assets/controllers/autosave_controller.js index 75622c4..05f7bb9 100644 --- a/assets/controllers/autosave_controller.js +++ b/assets/controllers/autosave_controller.js @@ -18,7 +18,7 @@ export default class extends Controller { unsavedText: { type: String, default: "Unsaved changes" }, errorText: { type: String, - default: "Couldn’t save — check the required fields", + default: "Couldn’t save — check the marked fields", }, offlineText: { type: String, @@ -73,9 +73,10 @@ export default class extends Controller { ); try { - const { status, location } = await this.request(); + const { status, location, body } = await this.request(); if (201 === status) { + this.clearErrors(); // The draft now exists — edit it in place from here on. if (location) { this.element.action = location; @@ -92,12 +93,21 @@ export default class extends Controller { "saved", ); } else if (204 === status) { + this.clearErrors(); this.setStatus( `${this.savedTextValue} · ${this.timestamp()}`, "saved", ); } else if (422 === status) { - this.setStatus(this.errorTextValue, "error"); + // Mark the invalid fields; messages that belong to no field (errors + // on the form itself) go in the status line instead. + const unplaced = this.markErrors(this.parseErrors(body)); + this.setStatus( + unplaced.length > 0 + ? unplaced.join(" ") + : this.errorTextValue, + "error", + ); } else { this.setStatus(this.offlineTextValue, "error"); } @@ -113,8 +123,8 @@ export default class extends Controller { } // POST the whole form via XHR so an in-flight save can be aborted when a - // newer one supersedes it. Resolves with the status and the - // X-Project-Location header (if any); rejects with an AbortError when + // newer one supersedes it. Resolves with the status, the response body and + // the X-Project-Location header (if any); rejects with an AbortError when // superseded. request() { return new Promise((resolve, reject) => { @@ -127,6 +137,7 @@ export default class extends Controller { xhr.addEventListener("load", () => resolve({ status: xhr.status, + body: xhr.responseText, location: xhr.getResponseHeader("X-Project-Location"), }), ); @@ -143,6 +154,57 @@ export default class extends Controller { }); } + // The 422 body is {errors: {"project[budget]": ["message", …], …}}. + parseErrors(body) { + try { + return JSON.parse(body)?.errors ?? {}; + } catch { + return {}; + } + } + + // Mark each invalid field the way a full render would: aria-invalid on the + // widget and a .form-errors list at the end of its row. Returns the + // messages that matched no field. + markErrors(errors) { + this.clearErrors(); + const unplaced = []; + + for (const [name, messages] of Object.entries(errors)) { + const escaped = CSS.escape(name); + const field = this.element.querySelector( + `[name="${escaped}"], [name="${escaped}[]"]`, + ); + const row = field?.closest(".form-row"); + if (!field || !row) { + unplaced.push(...messages); + continue; + } + + field.setAttribute("aria-invalid", "true"); + const list = document.createElement("ul"); + list.className = "form-errors"; + for (const message of messages) { + const item = document.createElement("li"); + item.textContent = message; + list.append(item); + } + row.append(list); + } + + return unplaced; + } + + // Drops both our marks and any rendered by the server on a full submit. + clearErrors() { + this.element + .querySelectorAll('[aria-invalid="true"]') + .forEach((field) => field.removeAttribute("aria-invalid")); + this.element + .querySelectorAll(".form-errors") + .forEach((list) => list.remove()); + } + hasEmptyRequiredField() { return Array.from( this.element.querySelectorAll("[data-autosave-required]"), diff --git a/assets/controllers/number_format_controller.js b/assets/controllers/number_format_controller.js new file mode 100644 index 0000000..d10e8c6 --- /dev/null +++ b/assets/controllers/number_format_controller.js @@ -0,0 +1,57 @@ +import { Controller } from "@hotwired/stimulus"; + +/* + * Groups the digits of a money field as they are typed ("1250000" becomes + * "1.250.000" in Danish, "1,250,000" in English), in the page locale so the + * value reads the way the server renders and parses it. Only digits and a + * leading minus survive: amounts are whole kroner, and the minus is kept so a + * negative amount still reaches the server and gets its validation error. + */ +export default class extends Controller { + connect() { + const locale = document.documentElement.lang || "en"; + this.formatter = new Intl.NumberFormat(locale, { + maximumFractionDigits: 0, + }); + this.format(); + } + + format() { + const input = this.element; + const before = input.value; + const caret = input.selectionStart ?? before.length; + // The caret is anchored to the digits typed before it; the separators + // around them come and go. + const digitsBeforeCaret = before + .slice(0, caret) + .replace(/\D/g, "").length; + + const after = this.group(before); + if (after === before) { + return; + } + input.value = after; + + let position = 0; + let seen = 0; + while (position < after.length && seen < digitsBeforeCaret) { + if (/\d/.test(after[position])) { + seen += 1; + } + position += 1; + } + input.setSelectionRange(position, position); + } + + // The sign is added by hand: some locales format a negative number with a + // typographic minus the server would not understand. + group(value) { + const negative = value.trimStart().startsWith("-"); + const digits = value.replace(/\D/g, "").replace(/^0+(?=\d)/, ""); + if ("" === digits) { + return negative ? "-" : ""; + } + + return (negative ? "-" : "") + this.formatter.format(BigInt(digits)); + } +} diff --git a/assets/styles/app.css b/assets/styles/app.css index 084b47f..00f037e 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -1281,6 +1281,12 @@ textarea { margin-top: var(--itk-space-1); } +input[aria-invalid="true"], +select[aria-invalid="true"], +textarea[aria-invalid="true"] { + border-color: var(--itk-danger); +} + .detail-grid { display: grid; grid-template-columns: 1.5fr 1fr; diff --git a/composer.json b/composer.json index 83f5e7c..befb20e 100644 --- a/composer.json +++ b/composer.json @@ -7,48 +7,49 @@ "php": ">=8.4", "ext-ctype": "*", "ext-iconv": "*", - "doctrine/doctrine-bundle": "^3.2", - "doctrine/doctrine-migrations-bundle": "^4.0", - "doctrine/orm": "^3.6", + "doctrine/doctrine-bundle": "^3.3.2", + "doctrine/doctrine-migrations-bundle": "^4.0.1", + "doctrine/orm": "^3.7.4", "itk-dev/entity-bundle": "^0.1", + "itk-dev/tidy-feedback": "^1.0", "league/csv": "^9.28", "symfony/asset": "~8.1.0", - "symfony/asset-mapper": "~8.1.0", - "symfony/console": "~8.1.0", - "symfony/dotenv": "~8.1.0", + "symfony/asset-mapper": "~8.1.8", + "symfony/console": "~8.1.8", + "symfony/dotenv": "~8.1.6", "symfony/flex": "^2", - "symfony/form": "~8.1.0", - "symfony/framework-bundle": "~8.1.0", - "symfony/mercure-bundle": "^0.4.2", - "symfony/rate-limiter": "~8.1.0", + "symfony/form": "~8.1.8", + "symfony/framework-bundle": "~8.1.8", + "symfony/mercure-bundle": "^0.4.3", + "symfony/rate-limiter": "~8.1.6", "symfony/runtime": "~8.1.0", - "symfony/security-bundle": "~8.1.0", - "symfony/translation": "~8.1.0", - "symfony/twig-bundle": "~8.1.0", - "symfony/ux-turbo": "^3.2", - "symfony/ux-twig-component": "^3.2", - "symfony/validator": "~8.1.0", - "symfony/yaml": "~8.1.0", - "twig/extra-bundle": "^2.12 || ^3.0", - "twig/twig": "^2.12 || ^3.0" + "symfony/security-bundle": "~8.1.8", + "symfony/translation": "~8.1.5", + "symfony/twig-bundle": "~8.1.7", + "symfony/ux-turbo": "^3.5.1", + "symfony/ux-twig-component": "^3.5.1", + "symfony/validator": "~8.1.8", + "symfony/yaml": "~8.1.8", + "twig/extra-bundle": "^2.12 || ^3.29", + "twig/twig": "^2.12 || ^3.30" }, "require-dev": { "doctrine/doctrine-fixtures-bundle": "^4.3", - "ergebnis/composer-normalize": "^2.52", - "friendsofphp/php-cs-fixer": "^3.95", + "ergebnis/composer-normalize": "^2.54", + "friendsofphp/php-cs-fixer": "^3.95.27", "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.2", - "phpstan/phpstan-doctrine": "^2.0", - "phpstan/phpstan-symfony": "^2.0", - "phpunit/phpunit": "^13.2", + "phpstan/phpstan": "^2.3", + "phpstan/phpstan-doctrine": "^2.0.28", + "phpstan/phpstan-symfony": "^2.1", + "phpunit/phpunit": "^13.4.1", "rregeer/phpunit-coverage-check": "^0.3.1", - "symfony/browser-kit": "~8.1.0", - "symfony/css-selector": "~8.1.0", + "symfony/browser-kit": "~8.1.5", + "symfony/css-selector": "~8.1.6", "symfony/debug-bundle": "~8.1.0", "symfony/maker-bundle": "^1.68", - "symfony/web-profiler-bundle": "~8.1.0", - "vincentlanglet/twig-cs-fixer": "^4.0", - "zenstruck/foundry": "^2.10" + "symfony/web-profiler-bundle": "~8.1.8", + "vincentlanglet/twig-cs-fixer": "^4.1.1", + "zenstruck/foundry": "^2.14" }, "replace": { "symfony/polyfill-ctype": "*", @@ -72,7 +73,7 @@ "url": "https://github.com/itk-dev/entity-bundle.git" } ], - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 8a5a5b5..925223d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ba09b5d9899b6ba95fc7141eefdffa11", + "content-hash": "61c852acc16ca02cc6b1da7d2bea137a", "packages": [ { "name": "composer/semver", - "version": "3.4.4", + "version": "3.5.1", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + "reference": "528948210cc46f967a4b98e83b19e76f2b504993" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", - "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "url": "https://api.github.com/repos/composer/semver/zipball/528948210cc46f967a4b98e83b19e76f2b504993", + "reference": "528948210cc46f967a4b98e83b19e76f2b504993", "shasum": "" }, "require": { @@ -59,7 +59,7 @@ "homepage": "http://robbast.nl" } ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", + "description": "Version comparison library that offers utilities, version constraint parsing and validation.", "keywords": [ "semantic", "semver", @@ -69,7 +69,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.4" + "source": "https://github.com/composer/semver/tree/3.5.1" }, "funding": [ { @@ -81,7 +81,7 @@ "type": "github" } ], - "time": "2025-08-20T19:15:30+00:00" + "time": "2026-10-05T13:12:12+00:00" }, { "name": "damienharper/auditor", @@ -233,29 +233,29 @@ }, { "name": "doctrine/collections", - "version": "2.6.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "7713da39d8e237f28411d6a616a3dce5e20d5de2" + "reference": "7c2f25ed928553a3de389ccb99aa46c0eedb2d4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/7713da39d8e237f28411d6a616a3dce5e20d5de2", - "reference": "7713da39d8e237f28411d6a616a3dce5e20d5de2", + "url": "https://api.github.com/repos/doctrine/collections/zipball/7c2f25ed928553a3de389ccb99aa46c0eedb2d4d", + "reference": "7c2f25ed928553a3de389ccb99aa46c0eedb2d4d", "shasum": "" }, "require": { "doctrine/deprecations": "^1", - "php": "^8.1", - "symfony/polyfill-php84": "^1.30" + "php": "^8.4", + "symfony/polyfill-php86": "^1.36" }, "require-dev": { "doctrine/coding-standard": "^14", "ext-json": "*", "phpstan/phpstan": "^2.1.30", "phpstan/phpstan-phpunit": "^2.0.7", - "phpunit/phpunit": "^10.5.58 || ^11.5.42 || ^12.4" + "phpunit/phpunit": "^12.4" }, "type": "library", "autoload": { @@ -299,7 +299,7 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/2.6.0" + "source": "https://github.com/doctrine/collections/tree/3.1.0" }, "funding": [ { @@ -315,20 +315,20 @@ "type": "tidelift" } ], - "time": "2026-01-15T10:01:58+00:00" + "time": "2026-04-29T20:41:02+00:00" }, { "name": "doctrine/dbal", - "version": "4.4.3", + "version": "4.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "61e730f1658814821a85f2402c945f3883407dec" + "reference": "c435cd7ea33e17d2a89288caf994cf3d4549b879" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/61e730f1658814821a85f2402c945f3883407dec", - "reference": "61e730f1658814821a85f2402c945f3883407dec", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/c435cd7ea33e17d2a89288caf994cf3d4549b879", + "reference": "c435cd7ea33e17d2a89288caf994cf3d4549b879", "shasum": "" }, "require": { @@ -344,9 +344,9 @@ "phpstan/phpstan": "2.1.30", "phpstan/phpstan-phpunit": "2.0.7", "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "11.5.50", - "slevomat/coding-standard": "8.27.1", - "squizlabs/php_codesniffer": "4.0.1", + "phpunit/phpunit": "11.5.56", + "slevomat/coding-standard": "8.31.1", + "squizlabs/php_codesniffer": "4.0.4", "symfony/cache": "^6.3.8|^7.0|^8.0", "symfony/console": "^5.4|^6.3|^7.0|^8.0" }, @@ -405,7 +405,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/4.4.3" + "source": "https://github.com/doctrine/dbal/tree/4.5.0" }, "funding": [ { @@ -421,7 +421,7 @@ "type": "tidelift" } ], - "time": "2026-03-20T08:52:12+00:00" + "time": "2026-09-24T16:11:26+00:00" }, { "name": "doctrine/deprecations", @@ -473,16 +473,16 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "3.2.4", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "75f1bf75d0ba099f23e7d43ebd804df5bec58c29" + "reference": "e6cd6aca912a5701fdc9bf4f0ad8f18f3f1448ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/75f1bf75d0ba099f23e7d43ebd804df5bec58c29", - "reference": "75f1bf75d0ba099f23e7d43ebd804df5bec58c29", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/e6cd6aca912a5701fdc9bf4f0ad8f18f3f1448ed", + "reference": "e6cd6aca912a5701fdc9bf4f0ad8f18f3f1448ed", "shasum": "" }, "require": { @@ -490,6 +490,7 @@ "doctrine/deprecations": "^1.0", "doctrine/persistence": "^4", "doctrine/sql-formatter": "^1.0.1", + "ext-mbstring": "*", "php": "^8.4", "symfony/cache": "^6.4 || ^7.0 || ^8.0", "symfony/config": "^6.4 || ^7.0 || ^8.0", @@ -501,7 +502,7 @@ }, "conflict": { "doctrine/orm": "<3.0 || >=4.0", - "twig/twig": "<3.0.4" + "twig/twig": "<3.0.4 || >=5" }, "require-dev": { "doctrine/coding-standard": "^14", @@ -517,6 +518,7 @@ "symfony/http-kernel": "^6.4 || ^7.0 || ^8.0", "symfony/messenger": "^6.4 || ^7.0 || ^8.0", "symfony/property-info": "^6.4 || ^7.0 || ^8.0", + "symfony/runtime": "^6.4 || ^7.0 || ^8.0", "symfony/security-bundle": "^6.4 || ^7.0 || ^8.0", "symfony/stopwatch": "^6.4 || ^7.0 || ^8.0", "symfony/string": "^6.4 || ^7.0 || ^8.0", @@ -524,7 +526,7 @@ "symfony/validator": "^6.4 || ^7.0 || ^8.0", "symfony/web-profiler-bundle": "^6.4 || ^7.0 || ^8.0", "symfony/yaml": "^6.4 || ^7.0 || ^8.0", - "twig/twig": "^3.21.1" + "twig/twig": "^3.21.1 || ^4" }, "suggest": { "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", @@ -569,7 +571,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/3.2.4" + "source": "https://github.com/doctrine/DoctrineBundle/tree/3.3.2" }, "funding": [ { @@ -585,20 +587,20 @@ "type": "tidelift" } ], - "time": "2026-06-09T19:11:55+00:00" + "time": "2026-09-09T11:58:04+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", - "reference": "20505da78735744fb4a42a3bb9a416b345ad6f7c" + "reference": "43e9212c7441178e3748580e53f88c08f4e70e5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/20505da78735744fb4a42a3bb9a416b345ad6f7c", - "reference": "20505da78735744fb4a42a3bb9a416b345ad6f7c", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/43e9212c7441178e3748580e53f88c08f4e70e5f", + "reference": "43e9212c7441178e3748580e53f88c08f4e70e5f", "shasum": "" }, "require": { @@ -661,7 +663,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues", - "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/4.0.0" + "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/4.0.1" }, "funding": [ { @@ -677,7 +679,7 @@ "type": "tidelift" } ], - "time": "2025-12-05T08:14:38+00:00" + "time": "2026-08-26T05:54:54+00:00" }, { "name": "doctrine/event-manager", @@ -931,27 +933,25 @@ }, { "name": "doctrine/lexer", - "version": "3.0.1", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + "reference": "71d305eaa6480d3d3460c7d053d1da7749fa9cca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/71d305eaa6480d3d3460c7d053d1da7749fa9cca", + "reference": "71d305eaa6480d3d3460c7d053d1da7749fa9cca", "shasum": "" }, "require": { "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^12", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^5.21" + "doctrine/coding-standard": "^14", + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^10.5.58 || ^12.5.4" }, "type": "library", "autoload": { @@ -988,7 +988,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/3.0.1" + "source": "https://github.com/doctrine/lexer/tree/3.0.3" }, "funding": [ { @@ -1004,20 +1004,20 @@ "type": "tidelift" } ], - "time": "2024-02-05T11:56:58+00:00" + "time": "2026-10-01T06:59:29+00:00" }, { "name": "doctrine/migrations", - "version": "3.9.7", + "version": "3.9.8", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "96cb2a89b56c9efb0bac38e606dc0b0f13e650ec" + "reference": "eb0b9ce3f999d720fa73037bbd06977ea34b76a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/96cb2a89b56c9efb0bac38e606dc0b0f13e650ec", - "reference": "96cb2a89b56c9efb0bac38e606dc0b0f13e650ec", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/eb0b9ce3f999d720fa73037bbd06977ea34b76a0", + "reference": "eb0b9ce3f999d720fa73037bbd06977ea34b76a0", "shasum": "" }, "require": { @@ -1091,7 +1091,7 @@ ], "support": { "issues": "https://github.com/doctrine/migrations/issues", - "source": "https://github.com/doctrine/migrations/tree/3.9.7" + "source": "https://github.com/doctrine/migrations/tree/3.9.8" }, "funding": [ { @@ -1107,28 +1107,28 @@ "type": "tidelift" } ], - "time": "2026-04-23T19:33:20+00:00" + "time": "2026-10-04T12:35:58+00:00" }, { "name": "doctrine/orm", - "version": "3.6.7", + "version": "3.7.4", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "bc217c0e19c3a9eadfa67697143b87c9ba01272c" + "reference": "84e21e325e3da22e46d7facbccdc9258f2332b1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/bc217c0e19c3a9eadfa67697143b87c9ba01272c", - "reference": "bc217c0e19c3a9eadfa67697143b87c9ba01272c", + "url": "https://api.github.com/repos/doctrine/orm/zipball/84e21e325e3da22e46d7facbccdc9258f2332b1e", + "reference": "84e21e325e3da22e46d7facbccdc9258f2332b1e", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/collections": "^2.2", + "doctrine/collections": "^2.2 || ^3.1", "doctrine/dbal": "^3.8.2 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", - "doctrine/event-manager": "^1.2 || ^2", + "doctrine/event-manager": "^2.1.1", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3 || ^2", "doctrine/lexer": "^3", @@ -1137,19 +1137,21 @@ "php": "^8.1", "psr/cache": "^1 || ^2 || ^3", "symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0", + "symfony/polyfill-php86": "^1.37", "symfony/var-exporter": "^6.3.9 || ^7.0 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^14.0", "phpbench/phpbench": "^1.0", "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "2.1.23", + "phpstan/phpstan": "2.2.14", "phpstan/phpstan-deprecation-rules": "^2", "phpunit/phpunit": "^10.5.0 || ^11.5", "psr/log": "^1 || ^2 || ^3", "symfony/cache": "^5.4 || ^6.2 || ^7.0 || ^8.0" }, "suggest": { + "ext-deepclone": "Improves performance when not using native lazy objects (Symfony 8.1+)", "ext-dom": "Provides support for XSD validation for XML mapping files", "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0" }, @@ -1193,9 +1195,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/3.6.7" + "source": "https://github.com/doctrine/orm/tree/3.7.4" }, - "time": "2026-05-25T16:45:47+00:00" + "time": "2026-10-05T18:31:26+00:00" }, { "name": "doctrine/persistence", @@ -1406,6 +1408,56 @@ }, "time": "2026-06-15T05:39:42+00:00" }, + { + "name": "itk-dev/tidy-feedback", + "version": "1.0.0-RC4", + "source": { + "type": "git", + "url": "https://github.com/itk-dev/tidy-feedback.git", + "reference": "254965e7b3b0f77071f6fc6beb41648d0cc4c686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/itk-dev/tidy-feedback/zipball/254965e7b3b0f77071f6fc6beb41648d0cc4c686", + "reference": "254965e7b3b0f77071f6fc6beb41648d0cc4c686", + "shasum": "" + }, + "require": { + "doctrine/dbal": "^3 || ^4", + "doctrine/orm": "^2.8 || ^3", + "symfony/cache": "^6 || ^7 || ^8", + "symfony/http-foundation": "^6 || ^7 || ^8", + "symfony/http-kernel": "^6 || ^7 || ^8", + "symfony/mime": "^6 || ^7 || ^8", + "symfony/routing": "^6 || ^7 || ^8", + "twig/twig": "^3" + }, + "require-dev": { + "drupal/coder": "^8.3", + "ergebnis/composer-normalize": "^2.47", + "friendsofphp/php-cs-fixer": "^3.75", + "phpunit/phpunit": "^11", + "rector/rector": "^2.0", + "vincentlanglet/twig-cs-fixer": "^3.8" + }, + "type": "drupal-module", + "autoload": { + "psr-4": { + "ItkDev\\TidyFeedback\\": "src/", + "ItkDev\\TidyFeedbackBundle\\": "symfony/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Tidy feedback", + "support": { + "issues": "https://github.com/itk-dev/tidy-feedback/issues", + "source": "https://github.com/itk-dev/tidy-feedback/tree/1.0.0-RC4" + }, + "time": "2026-10-07T14:49:25+00:00" + }, { "name": "lcobucci/jwt", "version": "5.6.0", @@ -1948,16 +2000,16 @@ }, { "name": "symfony/asset-mapper", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/asset-mapper.git", - "reference": "74b1b7b7019c728cb1f8672b502260e683b6374e" + "reference": "81047481894c6b074372b43c3e28ca9c882ef19e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/74b1b7b7019c728cb1f8672b502260e683b6374e", - "reference": "74b1b7b7019c728cb1f8672b502260e683b6374e", + "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/81047481894c6b074372b43c3e28ca9c882ef19e", + "reference": "81047481894c6b074372b43c3e28ca9c882ef19e", "shasum": "" }, "require": { @@ -2005,7 +2057,7 @@ "description": "Maps directories of assets & makes them available in a public directory with versioned filenames.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset-mapper/tree/v8.1.0" + "source": "https://github.com/symfony/asset-mapper/tree/v8.1.8" }, "funding": [ { @@ -2025,20 +2077,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-24T19:30:25+00:00" }, { "name": "symfony/cache", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "ba62e0ed9ea9bc26142844a891d4a3dfceb24aed" + "reference": "8888daf06a2fc8440346215d3b52f3c611cc486d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/ba62e0ed9ea9bc26142844a891d4a3dfceb24aed", - "reference": "ba62e0ed9ea9bc26142844a891d4a3dfceb24aed", + "url": "https://api.github.com/repos/symfony/cache/zipball/8888daf06a2fc8440346215d3b52f3c611cc486d", + "reference": "8888daf06a2fc8440346215d3b52f3c611cc486d", "shasum": "" }, "require": { @@ -2059,7 +2111,7 @@ "symfony/cache-implementation": "1.1|2.0|3.0" }, "require-dev": { - "cache/integration-tests": "dev-master", + "cache/integration-tests": "^1.0.3", "doctrine/dbal": "^4.3", "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", @@ -2104,7 +2156,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v8.1.0" + "source": "https://github.com/symfony/cache/tree/v8.1.8" }, "funding": [ { @@ -2124,20 +2176,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-29T12:38:40+00:00" }, { "name": "symfony/cache-contracts", - "version": "v3.7.0", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "225e8a254166bd3442e370c6f50145465db63831" + "reference": "9789738bc19af1106dc54d6afba9a0b467516cf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/225e8a254166bd3442e370c6f50145465db63831", - "reference": "225e8a254166bd3442e370c6f50145465db63831", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/9789738bc19af1106dc54d6afba9a0b467516cf2", + "reference": "9789738bc19af1106dc54d6afba9a0b467516cf2", "shasum": "" }, "require": { @@ -2184,7 +2236,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/cache-contracts/tree/v3.7.1" }, "funding": [ { @@ -2204,7 +2256,7 @@ "type": "tidelift" } ], - "time": "2026-05-05T15:33:14+00:00" + "time": "2026-06-05T06:23:12+00:00" }, { "name": "symfony/clock", @@ -2285,16 +2337,16 @@ }, { "name": "symfony/config", - "version": "v8.1.0", + "version": "v8.1.5", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "429783a0c649696f2058ea5ab5315f082dba6de9" + "reference": "ec711a6c14ae287d9618fbd2c9de4e223a1a4b02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/429783a0c649696f2058ea5ab5315f082dba6de9", - "reference": "429783a0c649696f2058ea5ab5315f082dba6de9", + "url": "https://api.github.com/repos/symfony/config/zipball/ec711a6c14ae287d9618fbd2c9de4e223a1a4b02", + "reference": "ec711a6c14ae287d9618fbd2c9de4e223a1a4b02", "shasum": "" }, "require": { @@ -2339,7 +2391,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v8.1.0" + "source": "https://github.com/symfony/config/tree/v8.1.5" }, "funding": [ { @@ -2359,20 +2411,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-20T09:59:12+00:00" }, { "name": "symfony/console", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f5a856c6ecb56b3c21ed94a5b7bf940d857d110a" + "reference": "4b81146e3ee248ea969186f85499b54fbc78db08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f5a856c6ecb56b3c21ed94a5b7bf940d857d110a", - "reference": "f5a856c6ecb56b3c21ed94a5b7bf940d857d110a", + "url": "https://api.github.com/repos/symfony/console/zipball/4b81146e3ee248ea969186f85499b54fbc78db08", + "reference": "4b81146e3ee248ea969186f85499b54fbc78db08", "shasum": "" }, "require": { @@ -2439,7 +2491,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v8.1.0" + "source": "https://github.com/symfony/console/tree/v8.1.8" }, "funding": [ { @@ -2459,20 +2511,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-18T16:00:27+00:00" }, { "name": "symfony/dependency-injection", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "b6ba1f45127106885de4b77558c5ecca8feb1e1b" + "reference": "e375617d3f132059bd096f41951b527c2eb60cd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b6ba1f45127106885de4b77558c5ecca8feb1e1b", - "reference": "b6ba1f45127106885de4b77558c5ecca8feb1e1b", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e375617d3f132059bd096f41951b527c2eb60cd0", + "reference": "e375617d3f132059bd096f41951b527c2eb60cd0", "shasum": "" }, "require": { @@ -2520,7 +2572,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/v8.1.0" + "source": "https://github.com/symfony/dependency-injection/tree/v8.1.8" }, "funding": [ { @@ -2540,20 +2592,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-29T12:38:40+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.7.0", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", - "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d", + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d", "shasum": "" }, "require": { @@ -2591,7 +2643,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.1" }, "funding": [ { @@ -2611,20 +2663,20 @@ "type": "tidelift" } ], - "time": "2026-04-13T15:52:40+00:00" + "time": "2026-06-05T06:23:12+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "80daf848dd39d9ff5a0f39aa6f2bf5448aa662c5" + "reference": "29ba9e0b21f3ac0f7f73d2d2b7b7755a4ff557e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/80daf848dd39d9ff5a0f39aa6f2bf5448aa662c5", - "reference": "80daf848dd39d9ff5a0f39aa6f2bf5448aa662c5", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/29ba9e0b21f3ac0f7f73d2d2b7b7755a4ff557e7", + "reference": "29ba9e0b21f3ac0f7f73d2d2b7b7755a4ff557e7", "shasum": "" }, "require": { @@ -2641,7 +2693,8 @@ "doctrine/dbal": "<4.3", "doctrine/lexer": "<1.1", "doctrine/orm": "<3.4", - "symfony/property-info": "<8.0" + "symfony/property-info": "<8.0", + "symfony/validator": "<7.4.17|>=8.0,<8.1.5" }, "require-dev": { "doctrine/collections": "^1.8|^2.0", @@ -2695,7 +2748,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v8.1.0" + "source": "https://github.com/symfony/doctrine-bridge/tree/v8.1.8" }, "funding": [ { @@ -2715,20 +2768,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:18:49+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/dotenv", - "version": "v8.1.0", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "7ed4e3a11e3c98235c70ded047d7ddf9e6ae854c" + "reference": "4ea87b35c75f7052309ec9735c0eb5c1fd7d2182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/7ed4e3a11e3c98235c70ded047d7ddf9e6ae854c", - "reference": "7ed4e3a11e3c98235c70ded047d7ddf9e6ae854c", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/4ea87b35c75f7052309ec9735c0eb5c1fd7d2182", + "reference": "4ea87b35c75f7052309ec9735c0eb5c1fd7d2182", "shasum": "" }, "require": { @@ -2769,7 +2822,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v8.1.0" + "source": "https://github.com/symfony/dotenv/tree/v8.1.6" }, "funding": [ { @@ -2789,20 +2842,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-07-26T10:31:34+00:00" }, { "name": "symfony/error-handler", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "d8aeb1abd3fef84795567850d3a567bdb5945ee5" + "reference": "c146daceccd5d4f864c051b233c276641cec527b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/d8aeb1abd3fef84795567850d3a567bdb5945ee5", - "reference": "d8aeb1abd3fef84795567850d3a567bdb5945ee5", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/c146daceccd5d4f864c051b233c276641cec527b", + "reference": "c146daceccd5d4f864c051b233c276641cec527b", "shasum": "" }, "require": { @@ -2850,7 +2903,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/v8.1.0" + "source": "https://github.com/symfony/error-handler/tree/v8.1.8" }, "funding": [ { @@ -2870,20 +2923,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-22T18:58:53+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v8.1.0", + "version": "v8.1.5", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102" + "reference": "7458da64220376b2e0dc2d8451bf43382c1ad297" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f249ae3f680958b6f1f9dd76e5747cf0695b4102", - "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7458da64220376b2e0dc2d8451bf43382c1ad297", + "reference": "7458da64220376b2e0dc2d8451bf43382c1ad297", "shasum": "" }, "require": { @@ -2936,7 +2989,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.5" }, "funding": [ { @@ -2956,20 +3009,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-21T17:47:34+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.7.0", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32" + "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32", - "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c7de7a00ffb67842132da02ea92988a39ccd9f4e", + "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e", "shasum": "" }, "require": { @@ -3016,7 +3069,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.1" }, "funding": [ { @@ -3036,20 +3089,20 @@ "type": "tidelift" } ], - "time": "2026-01-05T13:30:16+00:00" + "time": "2026-06-05T06:23:12+00:00" }, { "name": "symfony/filesystem", - "version": "v8.1.0", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2" + "reference": "7599ebb855fede59413ddb7f15198d67bfcae7ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/99aec13b82b4967ec5088222c4a3ecca955949c2", - "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7599ebb855fede59413ddb7f15198d67bfcae7ba", + "reference": "7599ebb855fede59413ddb7f15198d67bfcae7ba", "shasum": "" }, "require": { @@ -3087,7 +3140,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v8.1.0" + "source": "https://github.com/symfony/filesystem/tree/v8.1.6" }, "funding": [ { @@ -3107,20 +3160,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-23T10:06:25+00:00" }, { "name": "symfony/finder", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "58d2e767a66052c1487356f953445634a8194c64" + "reference": "bd4fed193a3132c91c5c93595cbfc78988915822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/58d2e767a66052c1487356f953445634a8194c64", - "reference": "58d2e767a66052c1487356f953445634a8194c64", + "url": "https://api.github.com/repos/symfony/finder/zipball/bd4fed193a3132c91c5c93595cbfc78988915822", + "reference": "bd4fed193a3132c91c5c93595cbfc78988915822", "shasum": "" }, "require": { @@ -3155,7 +3208,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.1.0" + "source": "https://github.com/symfony/finder/tree/v8.1.8" }, "funding": [ { @@ -3175,7 +3228,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-26T06:33:49+00:00" }, { "name": "symfony/flex", @@ -3252,16 +3305,16 @@ }, { "name": "symfony/form", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "82f3b7834a1fa05ea3ea5dc944a15cd350ce60a8" + "reference": "cd6635260d1f1b4dfc349f4a893fd0b2d1ea243b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/82f3b7834a1fa05ea3ea5dc944a15cd350ce60a8", - "reference": "82f3b7834a1fa05ea3ea5dc944a15cd350ce60a8", + "url": "https://api.github.com/repos/symfony/form/zipball/cd6635260d1f1b4dfc349f4a893fd0b2d1ea243b", + "reference": "cd6635260d1f1b4dfc349f4a893fd0b2d1ea243b", "shasum": "" }, "require": { @@ -3325,7 +3378,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v8.1.0" + "source": "https://github.com/symfony/form/tree/v8.1.8" }, "funding": [ { @@ -3345,20 +3398,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-29T12:38:40+00:00" }, { "name": "symfony/framework-bundle", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "6a0953f4fd8b51db6136c2628af99b7193e63256" + "reference": "78c28ec21e3ef4bd8a72de949d0ea2dead1e3f95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/6a0953f4fd8b51db6136c2628af99b7193e63256", - "reference": "6a0953f4fd8b51db6136c2628af99b7193e63256", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/78c28ec21e3ef4bd8a72de949d0ea2dead1e3f95", + "reference": "78c28ec21e3ef4bd8a72de949d0ea2dead1e3f95", "shasum": "" }, "require": { @@ -3367,7 +3420,7 @@ "php": ">=8.4.1", "symfony/cache": "^7.4|^8.0", "symfony/config": "^7.4.4|^8.0.4", - "symfony/dependency-injection": "^8.1", + "symfony/dependency-injection": "^8.1.8", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^7.4|^8.0", "symfony/event-dispatcher": "^8.1", @@ -3378,16 +3431,17 @@ "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-php85": "^1.33", "symfony/routing": "^7.4|^8.0", - "symfony/service-contracts": "^3.7", + "symfony/service-contracts": "^3.7.1", "symfony/var-exporter": "^8.1" }, "conflict": { "doctrine/persistence": "<1.3", "phpdocumentor/reflection-docblock": "<5.2|>=7", "phpdocumentor/type-resolver": "<1.5.1", - "symfony/console": "<8.1", + "symfony/console": "<8.1.2", "symfony/form": "<7.4", "symfony/json-streamer": "<7.4", + "symfony/mailer": "<7.4.17|>=8.0,<8.1.5", "symfony/messenger": "<7.4.10|>=8.0,<8.0.10", "symfony/mime": "<7.4.9|>=8.0,<8.0.9", "symfony/security-csrf": "<7.4", @@ -3397,7 +3451,6 @@ "symfony/workflow": "<7.4" }, "require-dev": { - "doctrine/persistence": "^1.3|^2|^3", "dragonmantank/cron-expression": "^3.1", "phpdocumentor/reflection-docblock": "^5.2|^6.0", "phpstan/phpdoc-parser": "^1.0|^2.0", @@ -3406,7 +3459,7 @@ "symfony/asset-mapper": "^7.4|^8.0", "symfony/browser-kit": "^7.4|^8.0", "symfony/clock": "^7.4|^8.0", - "symfony/console": "^8.1", + "symfony/console": "^8.1.2", "symfony/css-selector": "^7.4|^8.0", "symfony/dom-crawler": "^7.4|^8.0", "symfony/dotenv": "^7.4|^8.0", @@ -3468,7 +3521,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/v8.1.0" + "source": "https://github.com/symfony/framework-bundle/tree/v8.1.8" }, "funding": [ { @@ -3488,20 +3541,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/http-client", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "68a48e4c31f63fcd1bdff997a85a09e55efe8cdb" + "reference": "e20aca4ceaa888197de5c792ffc551d99e43d98a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/68a48e4c31f63fcd1bdff997a85a09e55efe8cdb", - "reference": "68a48e4c31f63fcd1bdff997a85a09e55efe8cdb", + "url": "https://api.github.com/repos/symfony/http-client/zipball/e20aca4ceaa888197de5c792ffc551d99e43d98a", + "reference": "e20aca4ceaa888197de5c792ffc551d99e43d98a", "shasum": "" }, "require": { @@ -3524,7 +3577,7 @@ "require-dev": { "amphp/http-client": "^5.3.2", "amphp/http-tunnel": "^2.0", - "guzzlehttp/guzzle": "^7.10", + "guzzlehttp/guzzle": "^7.10|^8.0", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", @@ -3565,7 +3618,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v8.1.0" + "source": "https://github.com/symfony/http-client/tree/v8.1.8" }, "funding": [ { @@ -3585,20 +3638,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-24T11:09:32+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.7.0", + "version": "v3.7.3", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d" + "reference": "35be0019e2c2c9fba80f9dc033290a5240f7b44f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", - "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/35be0019e2c2c9fba80f9dc033290a5240f7b44f", + "reference": "35be0019e2c2c9fba80f9dc033290a5240f7b44f", "shasum": "" }, "require": { @@ -3647,7 +3700,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.3" }, "funding": [ { @@ -3667,20 +3720,20 @@ "type": "tidelift" } ], - "time": "2026-03-06T13:17:50+00:00" + "time": "2026-08-04T08:41:16+00:00" }, { "name": "symfony/http-foundation", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "af11474600f06718086c2cda4fa6fa8d0a672e7e" + "reference": "662f5257658d4f60deff1bc790e9f2c68cb391bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/af11474600f06718086c2cda4fa6fa8d0a672e7e", - "reference": "af11474600f06718086c2cda4fa6fa8d0a672e7e", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/662f5257658d4f60deff1bc790e9f2c68cb391bf", + "reference": "662f5257658d4f60deff1bc790e9f2c68cb391bf", "shasum": "" }, "require": { @@ -3728,7 +3781,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v8.1.0" + "source": "https://github.com/symfony/http-foundation/tree/v8.1.8" }, "funding": [ { @@ -3748,20 +3801,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-24T07:13:53+00:00" }, { "name": "symfony/http-kernel", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "cefeb37c82eed3e0c42fa25ba64cd3a908d90f39" + "reference": "51c014e881d8b4ce61e56c0d4105f65b50df786a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cefeb37c82eed3e0c42fa25ba64cd3a908d90f39", - "reference": "cefeb37c82eed3e0c42fa25ba64cd3a908d90f39", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/51c014e881d8b4ce61e56c0d4105f65b50df786a", + "reference": "51c014e881d8b4ce61e56c0d4105f65b50df786a", "shasum": "" }, "require": { @@ -3777,6 +3830,7 @@ "symfony/dependency-injection": "<8.1", "symfony/flex": "<2.10", "symfony/http-client-contracts": "<2.5", + "symfony/serializer": "<7.4.15|>=8.0,<8.0.15|>=8.1,<8.1.2", "symfony/translation-contracts": "<2.5", "symfony/var-dumper": "<8.1", "symfony/web-profiler-bundle": "<8.1", @@ -3809,7 +3863,7 @@ "symfony/validator": "^7.4|^8.0", "symfony/var-dumper": "^8.1", "symfony/var-exporter": "^7.4|^8.0", - "twig/twig": "^3.21" + "twig/twig": "^3.21|^4.0" }, "type": "library", "autoload": { @@ -3837,7 +3891,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/v8.1.0" + "source": "https://github.com/symfony/http-kernel/tree/v8.1.8" }, "funding": [ { @@ -3857,20 +3911,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T08:46:08+00:00" + "time": "2026-09-29T14:08:01+00:00" }, { "name": "symfony/intl", - "version": "v8.1.0", + "version": "v8.1.5", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "7822dffb3e2128501a1ac781db5d8217fc9caac1" + "reference": "9a8ba3a0af4db32bf228ca841c319d5dc97f7d02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/7822dffb3e2128501a1ac781db5d8217fc9caac1", - "reference": "7822dffb3e2128501a1ac781db5d8217fc9caac1", + "url": "https://api.github.com/repos/symfony/intl/zipball/9a8ba3a0af4db32bf228ca841c319d5dc97f7d02", + "reference": "9a8ba3a0af4db32bf228ca841c319d5dc97f7d02", "shasum": "" }, "require": { @@ -3926,7 +3980,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v8.1.0" + "source": "https://github.com/symfony/intl/tree/v8.1.5" }, "funding": [ { @@ -3946,20 +4000,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-21T17:47:34+00:00" }, { "name": "symfony/lock", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "501dbc68f546a87b82d3a7430d15c6b63fc12b71" + "reference": "a57c18e351998f9964dff24713f7138a01d53703" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/501dbc68f546a87b82d3a7430d15c6b63fc12b71", - "reference": "501dbc68f546a87b82d3a7430d15c6b63fc12b71", + "url": "https://api.github.com/repos/symfony/lock/zipball/a57c18e351998f9964dff24713f7138a01d53703", + "reference": "a57c18e351998f9964dff24713f7138a01d53703", "shasum": "" }, "require": { @@ -4008,7 +4062,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v8.1.0" + "source": "https://github.com/symfony/lock/tree/v8.1.8" }, "funding": [ { @@ -4028,7 +4082,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-18T16:00:27+00:00" }, { "name": "symfony/mercure", @@ -4117,16 +4171,16 @@ }, { "name": "symfony/mercure-bundle", - "version": "v0.4.2", + "version": "v0.4.3", "source": { "type": "git", "url": "https://github.com/symfony/mercure-bundle.git", - "reference": "eae8bf5a75b4e1203bd9aa4181c7950a4df4b3e3" + "reference": "90e269c68fa10088e0affb02a3708ffce3e35f4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/eae8bf5a75b4e1203bd9aa4181c7950a4df4b3e3", - "reference": "eae8bf5a75b4e1203bd9aa4181c7950a4df4b3e3", + "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/90e269c68fa10088e0affb02a3708ffce3e35f4e", + "reference": "90e269c68fa10088e0affb02a3708ffce3e35f4e", "shasum": "" }, "require": { @@ -4135,7 +4189,7 @@ "symfony/config": "^6.4|^7.3|^8.0", "symfony/dependency-injection": "^6.4|^7.3|^8.0", "symfony/http-kernel": "^6.4|^7.3|^8.0", - "symfony/mercure": "*", + "symfony/mercure": "^0.6.1|^0.7", "symfony/web-link": "^6.4|^7.3|^8.0" }, "require-dev": { @@ -4150,7 +4204,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-main": "0.3.x-dev" + "dev-main": "0.4.x-dev" } }, "autoload": { @@ -4182,7 +4236,7 @@ ], "support": { "issues": "https://github.com/symfony/mercure-bundle/issues", - "source": "https://github.com/symfony/mercure-bundle/tree/v0.4.2" + "source": "https://github.com/symfony/mercure-bundle/tree/v0.4.3" }, "funding": [ { @@ -4194,7 +4248,93 @@ "type": "tidelift" } ], - "time": "2025-11-25T12:51:49+00:00" + "time": "2026-08-11T10:28:59+00:00" + }, + { + "name": "symfony/mime", + "version": "v8.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "773ac57f20e2795bdadb65b5b1b5f4850d498283" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/773ac57f20e2795bdadb65b5b1b5f4850d498283", + "reference": "773ac57f20e2795bdadb65b5b1b5f4850d498283", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/property-access": "^7.4|^8.0", + "symfony/property-info": "^7.4|^8.0", + "symfony/serializer": "^7.4.17|^8.1.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v8.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-09-04T11:02:17+00:00" }, { "name": "symfony/options-resolver", @@ -4342,16 +4482,16 @@ }, { "name": "symfony/polyfill-deepclone", - "version": "v1.40.0", + "version": "v1.43.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-deepclone.git", - "reference": "dca4ccba5f360070b574414dce4c1e7a559844fa" + "reference": "aaba44b6ee7299ae65717811c55b57ab9bc0fedd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/dca4ccba5f360070b574414dce4c1e7a559844fa", - "reference": "dca4ccba5f360070b574414dce4c1e7a559844fa", + "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/aaba44b6ee7299ae65717811c55b57ab9bc0fedd", + "reference": "aaba44b6ee7299ae65717811c55b57ab9bc0fedd", "shasum": "" }, "require": { @@ -4405,7 +4545,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.40.0" + "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.43.1" }, "funding": [ { @@ -4425,20 +4565,20 @@ "type": "tidelift" } ], - "time": "2026-06-12T07:27:17+00:00" + "time": "2026-10-06T19:46:18+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.38.1", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "e9247d281d694a5120554d9afaf54e070e88a603" + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", - "reference": "e9247d281d694a5120554d9afaf54e070e88a603", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5cac8f4db97208823aa353f59a01faad2da52c75", + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75", "shasum": "" }, "require": { @@ -4487,7 +4627,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.43.0" }, "funding": [ { @@ -4507,20 +4647,20 @@ "type": "tidelift" } ], - "time": "2026-05-26T05:58:03+00:00" + "time": "2026-09-25T15:46:47+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.38.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "445c90e341fccda10311019cf82ff73bb7343945" + "reference": "d13cf82f40af144e5e5a867dc54ec3c7b4544b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/445c90e341fccda10311019cf82ff73bb7343945", - "reference": "445c90e341fccda10311019cf82ff73bb7343945", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/d13cf82f40af144e5e5a867dc54ec3c7b4544b2e", + "reference": "d13cf82f40af144e5e5a867dc54ec3c7b4544b2e", "shasum": "" }, "require": { @@ -4575,7 +4715,94 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.43.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-09-25T15:46:47+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.43.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "533d68cf99c8f8ee2e8893c59ed59192e92cfd74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/533d68cf99c8f8ee2e8893c59ed59192e92cfd74", + "reference": "533d68cf99c8f8ee2e8893c59ed59192e92cfd74", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.43.0" }, "funding": [ { @@ -4595,20 +4822,20 @@ "type": "tidelift" } ], - "time": "2026-05-25T11:52:53+00:00" + "time": "2026-09-23T14:40:04+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.38.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b" + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b", - "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/ebd57ccc7edb93d632e184efbe7693d2517bab3b", + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b", "shasum": "" }, "require": { @@ -4660,7 +4887,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.43.0" }, "funding": [ { @@ -4680,20 +4907,20 @@ "type": "tidelift" } ], - "time": "2026-05-25T13:48:31+00:00" + "time": "2026-09-23T22:02:09+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.38.2", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", "shasum": "" }, "require": { @@ -4745,7 +4972,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.43.0" }, "funding": [ { @@ -4765,20 +4992,20 @@ "type": "tidelift" } ], - "time": "2026-05-27T06:59:30+00:00" + "time": "2026-09-24T15:19:04+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.38.1", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" + "reference": "86a42cbcc07adc331481a5ab310a4024bfc227f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", - "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/86a42cbcc07adc331481a5ab310a4024bfc227f6", + "reference": "86a42cbcc07adc331481a5ab310a4024bfc227f6", "shasum": "" }, "require": { @@ -4825,7 +5052,87 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.43.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-09-25T15:46:47+00:00" + }, + { + "name": "symfony/polyfill-php86", + "version": "v1.43.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php86.git", + "reference": "8840df45b24f33a49dc419fa18dc0057231ae1d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/8840df45b24f33a49dc419fa18dc0057231ae1d8", + "reference": "8840df45b24f33a49dc419fa18dc0057231ae1d8", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php86\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php86/tree/v1.43.0" }, "funding": [ { @@ -4845,20 +5152,20 @@ "type": "tidelift" } ], - "time": "2026-05-26T02:25:22+00:00" + "time": "2026-09-25T15:46:47+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.37.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" + "reference": "b23ff8245cc5c4479ea2be3d0132d2e6dd433993" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", - "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/b23ff8245cc5c4479ea2be3d0132d2e6dd433993", + "reference": "b23ff8245cc5c4479ea2be3d0132d2e6dd433993", "shasum": "" }, "require": { @@ -4908,7 +5215,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.43.0" }, "funding": [ { @@ -4928,20 +5235,20 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:19:22+00:00" + "time": "2026-09-24T05:20:52+00:00" }, { "name": "symfony/property-access", - "version": "v8.1.0", + "version": "v8.1.4", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9" + "reference": "1a41232c678972b93ce499a504e19ea09dfcd0b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/9261ef060f26cc7b728f67f141ba19b98a6209a9", - "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9", + "url": "https://api.github.com/repos/symfony/property-access/zipball/1a41232c678972b93ce499a504e19ea09dfcd0b2", + "reference": "1a41232c678972b93ce499a504e19ea09dfcd0b2", "shasum": "" }, "require": { @@ -4989,7 +5296,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v8.1.0" + "source": "https://github.com/symfony/property-access/tree/v8.1.4" }, "funding": [ { @@ -5009,20 +5316,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-07-30T12:40:56+00:00" }, { "name": "symfony/property-info", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7" + "reference": "fe727d4888a92ac9200a2c1b8e0a995b6022afa7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/4721e8c56d0cd2378e0ef9a9899f810008b859f7", - "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7", + "url": "https://api.github.com/repos/symfony/property-info/zipball/fe727d4888a92ac9200a2c1b8e0a995b6022afa7", + "reference": "fe727d4888a92ac9200a2c1b8e0a995b6022afa7", "shasum": "" }, "require": { @@ -5075,7 +5382,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v8.1.0" + "source": "https://github.com/symfony/property-info/tree/v8.1.8" }, "funding": [ { @@ -5095,20 +5402,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/rate-limiter", - "version": "v8.1.0", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "657d5b948e913b3989d9cf2f79a84e44e454345a" + "reference": "dee2fc983ca9944ac37af105a4940507ff5fc42c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/657d5b948e913b3989d9cf2f79a84e44e454345a", - "reference": "657d5b948e913b3989d9cf2f79a84e44e454345a", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/dee2fc983ca9944ac37af105a4940507ff5fc42c", + "reference": "dee2fc983ca9944ac37af105a4940507ff5fc42c", "shasum": "" }, "require": { @@ -5149,7 +5456,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v8.1.0" + "source": "https://github.com/symfony/rate-limiter/tree/v8.1.6" }, "funding": [ { @@ -5169,20 +5476,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-07T15:35:35+00:00" }, { "name": "symfony/routing", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3" + "reference": "e46d741c56485441f37104a3e7eace4e17ed91f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3", - "reference": "fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3", + "url": "https://api.github.com/repos/symfony/routing/zipball/e46d741c56485441f37104a3e7eace4e17ed91f9", + "reference": "e46d741c56485441f37104a3e7eace4e17ed91f9", "shasum": "" }, "require": { @@ -5229,7 +5536,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v8.1.0" + "source": "https://github.com/symfony/routing/tree/v8.1.8" }, "funding": [ { @@ -5249,7 +5556,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/runtime", @@ -5337,16 +5644,16 @@ }, { "name": "symfony/security-bundle", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "0489a6247f729652db9b9ff408f69ac3bee3589e" + "reference": "b18be9c45bb6e8dbc91787165516013ffefb72fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/0489a6247f729652db9b9ff408f69ac3bee3589e", - "reference": "0489a6247f729652db9b9ff408f69ac3bee3589e", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/b18be9c45bb6e8dbc91787165516013ffefb72fb", + "reference": "b18be9c45bb6e8dbc91787165516013ffefb72fb", "shasum": "" }, "require": { @@ -5376,6 +5683,7 @@ "symfony/framework-bundle": "^7.4|^8.0", "symfony/http-client": "^7.4|^8.0", "symfony/ldap": "^7.4|^8.0", + "symfony/lock": "^7.4|^8.0", "symfony/process": "^7.4|^8.0", "symfony/property-info": "^7.4|^8.0", "symfony/rate-limiter": "^7.4|^8.0", @@ -5414,7 +5722,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/v8.1.0" + "source": "https://github.com/symfony/security-bundle/tree/v8.1.8" }, "funding": [ { @@ -5434,20 +5742,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-24T11:09:32+00:00" }, { "name": "symfony/security-core", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "a8239abe61dafdd0c01c0b4019138b2855717f97" + "reference": "2dc0c95a47282476d90cf6c9e274767c50126b04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/a8239abe61dafdd0c01c0b4019138b2855717f97", - "reference": "a8239abe61dafdd0c01c0b4019138b2855717f97", + "url": "https://api.github.com/repos/symfony/security-core/zipball/2dc0c95a47282476d90cf6c9e274767c50126b04", + "reference": "2dc0c95a47282476d90cf6c9e274767c50126b04", "shasum": "" }, "require": { @@ -5497,7 +5805,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v8.1.0" + "source": "https://github.com/symfony/security-core/tree/v8.1.8" }, "funding": [ { @@ -5517,7 +5825,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/security-csrf", @@ -5593,16 +5901,16 @@ }, { "name": "symfony/security-http", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "e0e6c7b9e80eec37248b92359cbd6938c7086f4b" + "reference": "eac4db5a18d8c83a49d20ee46d6b42820103502f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/e0e6c7b9e80eec37248b92359cbd6938c7086f4b", - "reference": "e0e6c7b9e80eec37248b92359cbd6938c7086f4b", + "url": "https://api.github.com/repos/symfony/security-http/zipball/eac4db5a18d8c83a49d20ee46d6b42820103502f", + "reference": "eac4db5a18d8c83a49d20ee46d6b42820103502f", "shasum": "" }, "require": { @@ -5657,7 +5965,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v8.1.0" + "source": "https://github.com/symfony/security-http/tree/v8.1.8" }, "funding": [ { @@ -5677,20 +5985,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.7.0", + "version": "v3.7.3", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", - "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", "shasum": "" }, "require": { @@ -5744,7 +6052,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.3" }, "funding": [ { @@ -5764,20 +6072,20 @@ "type": "tidelift" } ], - "time": "2026-03-28T09:44:51+00:00" + "time": "2026-07-27T15:39:01+00:00" }, { "name": "symfony/stimulus-bundle", - "version": "v3.2.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/stimulus-bundle.git", - "reference": "3cf8cd35c400f287def6ccd4574c111c07661054" + "reference": "328b92cdf33a21267ee47904f8f5e330da356ce6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/3cf8cd35c400f287def6ccd4574c111c07661054", - "reference": "3cf8cd35c400f287def6ccd4574c111c07661054", + "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/328b92cdf33a21267ee47904f8f5e330da356ce6", + "reference": "328b92cdf33a21267ee47904f8f5e330da356ce6", "shasum": "" }, "require": { @@ -5787,7 +6095,7 @@ "symfony/deprecation-contracts": "^2.0|^3.0", "symfony/finder": "^7.4|^8.0", "symfony/http-kernel": "^7.4|^8.0", - "twig/twig": "^2.15.3|^3.8" + "twig/twig": "^2.15.3|^3.8|^4.0" }, "conflict": { "symfony/asset-mapper": "<6.4" @@ -5820,7 +6128,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/stimulus-bundle/tree/v3.2.0" + "source": "https://github.com/symfony/stimulus-bundle/tree/v3.5.1" }, "funding": [ { @@ -5840,7 +6148,7 @@ "type": "tidelift" } ], - "time": "2026-06-05T09:42:50+00:00" + "time": "2026-09-19T11:40:16+00:00" }, { "name": "symfony/stopwatch", @@ -5910,16 +6218,16 @@ }, { "name": "symfony/string", - "version": "v8.1.0", + "version": "v8.1.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9" + "reference": "d950140b5f56f31901e5b7a0c04ffc3a3deb943c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/afd5944f4005862d961efb85c8bbd5c523c4e3c9", - "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9", + "url": "https://api.github.com/repos/symfony/string/zipball/d950140b5f56f31901e5b7a0c04ffc3a3deb943c", + "reference": "d950140b5f56f31901e5b7a0c04ffc3a3deb943c", "shasum": "" }, "require": { @@ -5976,7 +6284,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.1.0" + "source": "https://github.com/symfony/string/tree/v8.1.7" }, "funding": [ { @@ -5996,20 +6304,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-11T14:51:16+00:00" }, { "name": "symfony/translation", - "version": "v8.1.0", + "version": "v8.1.5", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693" + "reference": "d9e1caba0d6b6f9a26710af8a2f88d37f001215a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b2bd012ca28c4acae830ee1206a5b6e35dd99693", - "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693", + "url": "https://api.github.com/repos/symfony/translation/zipball/d9e1caba0d6b6f9a26710af8a2f88d37f001215a", + "reference": "d9e1caba0d6b6f9a26710af8a2f88d37f001215a", "shasum": "" }, "require": { @@ -6069,7 +6377,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.1.0" + "source": "https://github.com/symfony/translation/tree/v8.1.5" }, "funding": [ { @@ -6089,20 +6397,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-21T17:47:34+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.7.0", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d" + "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/0ab302977a952b42fd51475c4ebac81f8da0a95d", - "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/ccb206b98faccc511ebae8e5fad50f2dc0b30621", + "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621", "shasum": "" }, "require": { @@ -6151,7 +6459,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.7.1" }, "funding": [ { @@ -6171,26 +6479,26 @@ "type": "tidelift" } ], - "time": "2026-01-05T13:30:16+00:00" + "time": "2026-06-05T06:23:12+00:00" }, { "name": "symfony/twig-bridge", - "version": "v8.1.0", + "version": "v8.1.7", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "25bb8c01edaab85e13142f6010df09b990388343" + "reference": "7d9f1e128b44e37170f424046d23a48a3e545ad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/25bb8c01edaab85e13142f6010df09b990388343", - "reference": "25bb8c01edaab85e13142f6010df09b990388343", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/7d9f1e128b44e37170f424046d23a48a3e545ad4", + "reference": "7d9f1e128b44e37170f424046d23a48a3e545ad4", "shasum": "" }, "require": { "php": ">=8.4.1", "symfony/translation-contracts": "^2.5|^3", - "twig/twig": "^3.25" + "twig/twig": "^3.25|^4.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2|>=7", @@ -6222,7 +6530,7 @@ "symfony/security-core": "^7.4|^8.0", "symfony/security-csrf": "^7.4|^8.0", "symfony/security-http": "^7.4|^8.0", - "symfony/serializer": "^7.4|^8.0", + "symfony/serializer": "^7.4.17|^8.1.5", "symfony/stopwatch": "^7.4|^8.0", "symfony/translation": "^7.4|^8.0", "symfony/validator": "^7.4|^8.0", @@ -6259,7 +6567,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v8.1.0" + "source": "https://github.com/symfony/twig-bridge/tree/v8.1.7" }, "funding": [ { @@ -6279,20 +6587,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-14T12:20:25+00:00" }, { "name": "symfony/twig-bundle", - "version": "v8.1.0", + "version": "v8.1.7", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "b7f4a471a07b8b52174d153e4db12f46954192ed" + "reference": "71648fac591a675b91ae408f03a3d95a3f98b436" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/b7f4a471a07b8b52174d153e4db12f46954192ed", - "reference": "b7f4a471a07b8b52174d153e4db12f46954192ed", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/71648fac591a675b91ae408f03a3d95a3f98b436", + "reference": "71648fac591a675b91ae408f03a3d95a3f98b436", "shasum": "" }, "require": { @@ -6343,7 +6651,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v8.1.0" + "source": "https://github.com/symfony/twig-bundle/tree/v8.1.7" }, "funding": [ { @@ -6363,20 +6671,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-11T14:51:16+00:00" }, { "name": "symfony/type-info", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7" + "reference": "18e1d891f0b8776141f281f7b6f5e67e4df9d9cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7", - "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7", + "url": "https://api.github.com/repos/symfony/type-info/zipball/18e1d891f0b8776141f281f7b6f5e67e4df9d9cd", + "reference": "18e1d891f0b8776141f281f7b6f5e67e4df9d9cd", "shasum": "" }, "require": { @@ -6425,7 +6733,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v8.1.0" + "source": "https://github.com/symfony/type-info/tree/v8.1.8" }, "funding": [ { @@ -6445,20 +6753,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/uid", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a" + "reference": "f412a0b5edd75eb3104a93bd0d11fd2ea3da34e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/7393f157a55f7e70a4de0334435c55a5a8fe749a", - "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a", + "url": "https://api.github.com/repos/symfony/uid/zipball/f412a0b5edd75eb3104a93bd0d11fd2ea3da34e4", + "reference": "f412a0b5edd75eb3104a93bd0d11fd2ea3da34e4", "shasum": "" }, "require": { @@ -6503,7 +6811,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v8.1.0" + "source": "https://github.com/symfony/uid/tree/v8.1.8" }, "funding": [ { @@ -6523,20 +6831,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-23T17:45:45+00:00" }, { "name": "symfony/ux-turbo", - "version": "v3.2.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/ux-turbo.git", - "reference": "923c6479da86ebdcbd4f723a80c24d47d50567fa" + "reference": "9a125fad60c75411b9b46478a927588d3e3bab2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-turbo/zipball/923c6479da86ebdcbd4f723a80c24d47d50567fa", - "reference": "923c6479da86ebdcbd4f723a80c24d47d50567fa", + "url": "https://api.github.com/repos/symfony/ux-turbo/zipball/9a125fad60c75411b9b46478a927588d3e3bab2d", + "reference": "9a125fad60c75411b9b46478a927588d3e3bab2d", "shasum": "" }, "require": { @@ -6604,7 +6912,7 @@ "turbo-stream" ], "support": { - "source": "https://github.com/symfony/ux-turbo/tree/v3.2.0" + "source": "https://github.com/symfony/ux-turbo/tree/v3.5.1" }, "funding": [ { @@ -6624,20 +6932,20 @@ "type": "tidelift" } ], - "time": "2026-06-19T07:14:15+00:00" + "time": "2026-09-19T11:40:16+00:00" }, { "name": "symfony/ux-twig-component", - "version": "v3.2.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/ux-twig-component.git", - "reference": "a9b93b10fe2056a6f93ebc1f9e3509f7fafb5bf2" + "reference": "e47eb29a7880da340210c6dc90b66e221b5ec549" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/a9b93b10fe2056a6f93ebc1f9e3509f7fafb5bf2", - "reference": "a9b93b10fe2056a6f93ebc1f9e3509f7fafb5bf2", + "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/e47eb29a7880da340210c6dc90b66e221b5ec549", + "reference": "e47eb29a7880da340210c6dc90b66e221b5ec549", "shasum": "" }, "require": { @@ -6646,7 +6954,8 @@ "symfony/deprecation-contracts": "^2.2|^3.0", "symfony/event-dispatcher": "^7.4|^8.0", "symfony/property-access": "^7.4|^8.0", - "twig/twig": "^3.10.3" + "twig/html-extra": "^3.29|^4.0", + "twig/twig": "^3.24|^4.0" }, "conflict": { "symfony/config": "<6.4" @@ -6660,8 +6969,7 @@ "symfony/framework-bundle": "^7.4|^8.0", "symfony/stimulus-bundle": "^2.9.1|^3.0", "symfony/twig-bundle": "^7.4|^8.0", - "twig/extra-bundle": "^3.10.3", - "twig/html-extra": "^3.10.3" + "twig/extra-bundle": "^3.24|^4.0" }, "type": "symfony-bundle", "extra": { @@ -6693,7 +7001,7 @@ "twig" ], "support": { - "source": "https://github.com/symfony/ux-twig-component/tree/v3.2.0" + "source": "https://github.com/symfony/ux-twig-component/tree/v3.5.1" }, "funding": [ { @@ -6713,20 +7021,20 @@ "type": "tidelift" } ], - "time": "2026-06-11T20:32:06+00:00" + "time": "2026-09-18T12:02:28+00:00" }, { "name": "symfony/validator", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "b122b2e384fa84166213ce98b887f01a3eea8d94" + "reference": "828f05cff662bb1661f195daa1b06961642ca9dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/b122b2e384fa84166213ce98b887f01a3eea8d94", - "reference": "b122b2e384fa84166213ce98b887f01a3eea8d94", + "url": "https://api.github.com/repos/symfony/validator/zipball/828f05cff662bb1661f195daa1b06961642ca9dd", + "reference": "828f05cff662bb1661f195daa1b06961642ca9dd", "shasum": "" }, "require": { @@ -6790,7 +7098,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v8.1.0" + "source": "https://github.com/symfony/validator/tree/v8.1.8" }, "funding": [ { @@ -6810,20 +7118,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-29T12:38:40+00:00" }, { "name": "symfony/var-dumper", - "version": "v8.1.0", + "version": "v8.1.7", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e" + "reference": "741a8c4c948b0bb9bd3653daacd3644c73c40ea5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e", - "reference": "c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/741a8c4c948b0bb9bd3653daacd3644c73c40ea5", + "reference": "741a8c4c948b0bb9bd3653daacd3644c73c40ea5", "shasum": "" }, "require": { @@ -6839,7 +7147,7 @@ "symfony/http-kernel": "^7.4|^8.0", "symfony/process": "^7.4|^8.0", "symfony/uid": "^7.4|^8.0", - "twig/twig": "^3.12" + "twig/twig": "^3.12|^4.0" }, "bin": [ "Resources/bin/var-dump-server" @@ -6877,7 +7185,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v8.1.0" + "source": "https://github.com/symfony/var-dumper/tree/v8.1.7" }, "funding": [ { @@ -6897,26 +7205,26 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-03T16:02:27+00:00" }, { "name": "symfony/var-exporter", - "version": "v8.1.0", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "2dd18582c5f6c024db9fc0ff9c76d873af726f34" + "reference": "802362f41128c430fd6685491e1fb72127fae78a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/2dd18582c5f6c024db9fc0ff9c76d873af726f34", - "reference": "2dd18582c5f6c024db9fc0ff9c76d873af726f34", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/802362f41128c430fd6685491e1fb72127fae78a", + "reference": "802362f41128c430fd6685491e1fb72127fae78a", "shasum": "" }, "require": { "php": ">=8.4.1", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-deepclone": "^1.37" + "symfony/polyfill-deepclone": "^1.40" }, "require-dev": { "symfony/property-access": "^7.4|^8.0", @@ -6960,7 +7268,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v8.1.0" + "source": "https://github.com/symfony/var-exporter/tree/v8.1.6" }, "funding": [ { @@ -6980,7 +7288,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-29T06:30:03+00:00" }, { "name": "symfony/web-link", @@ -7068,16 +7376,16 @@ }, { "name": "symfony/yaml", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0" + "reference": "030e96eed0303223bfca3af9109e9e64830b6ec3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/efb42bd2c6f4f3ccfd4683583449938b5fc146b0", - "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0", + "url": "https://api.github.com/repos/symfony/yaml/zipball/030e96eed0303223bfca3af9109e9e64830b6ec3", + "reference": "030e96eed0303223bfca3af9109e9e64830b6ec3", "shasum": "" }, "require": { @@ -7120,7 +7428,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v8.1.0" + "source": "https://github.com/symfony/yaml/tree/v8.1.8" }, "funding": [ { @@ -7140,20 +7448,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-26T06:33:49+00:00" }, { "name": "twig/extra-bundle", - "version": "v3.24.0", + "version": "v3.29.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "6a621fcb1f28aa9ea7b34a99047ae0cdf5b834c9" + "reference": "aaa2993e19293a99240c4c61aa461d743b0dd569" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/6a621fcb1f28aa9ea7b34a99047ae0cdf5b834c9", - "reference": "6a621fcb1f28aa9ea7b34a99047ae0cdf5b834c9", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/aaa2993e19293a99240c4c61aa461d743b0dd569", + "reference": "aaa2993e19293a99240c4c61aa461d743b0dd569", "shasum": "" }, "require": { @@ -7202,7 +7510,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.24.0" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.29.0" }, "funding": [ { @@ -7214,20 +7522,88 @@ "type": "tidelift" } ], - "time": "2026-02-07T08:07:38+00:00" + "time": "2026-09-11T08:59:50+00:00" + }, + { + "name": "twig/html-extra", + "version": "v3.29.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/html-extra.git", + "reference": "7147611979df81edb78baf7d003860b72e335c3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/html-extra/zipball/7147611979df81edb78baf7d003860b72e335c3f", + "reference": "7147611979df81edb78baf7d003860b72e335c3f", + "shasum": "" + }, + "require": { + "php": ">=8.1.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/mime": "^5.4|^6.4|^7.0|^8.0", + "twig/twig": "^3.13|^4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Twig\\Extra\\Html\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Twig extension for HTML", + "homepage": "https://twig.symfony.com", + "keywords": [ + "html", + "twig" + ], + "support": { + "source": "https://github.com/twigphp/html-extra/tree/v3.29.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2026-09-06T20:35:36+00:00" }, { "name": "twig/intl-extra", - "version": "v3.26.0", + "version": "v3.30.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "98f5ad5bff13230fcd2d834d9e79b50adf3ccda9" + "reference": "211c603b3f7d5a8f6c6543a02fe9f82c09b18025" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/98f5ad5bff13230fcd2d834d9e79b50adf3ccda9", - "reference": "98f5ad5bff13230fcd2d834d9e79b50adf3ccda9", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/211c603b3f7d5a8f6c6543a02fe9f82c09b18025", + "reference": "211c603b3f7d5a8f6c6543a02fe9f82c09b18025", "shasum": "" }, "require": { @@ -7266,7 +7642,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.26.0" + "source": "https://github.com/twigphp/intl-extra/tree/v3.30.0" }, "funding": [ { @@ -7278,20 +7654,20 @@ "type": "tidelift" } ], - "time": "2026-05-19T20:44:48+00:00" + "time": "2026-09-25T05:50:11+00:00" }, { "name": "twig/twig", - "version": "v3.27.1", + "version": "v3.30.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ae2071bffb38f04847fc0864d730c94b9cb8ab74" + "reference": "8c737079b726af72ff8ef3c595be9f6a810ea1ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ae2071bffb38f04847fc0864d730c94b9cb8ab74", - "reference": "ae2071bffb38f04847fc0864d730c94b9cb8ab74", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/8c737079b726af72ff8ef3c595be9f6a810ea1ef", + "reference": "8c737079b726af72ff8ef3c595be9f6a810ea1ef", "shasum": "" }, "require": { @@ -7346,7 +7722,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.27.1" + "source": "https://github.com/twigphp/Twig/tree/v3.30.0" }, "funding": [ { @@ -7358,7 +7734,7 @@ "type": "tidelift" } ], - "time": "2026-05-30T17:09:26+00:00" + "time": "2026-09-25T13:20:01+00:00" } ], "packages-dev": [ @@ -7810,50 +8186,51 @@ }, { "name": "ergebnis/composer-normalize", - "version": "2.52.0", + "version": "2.54.0", "source": { "type": "git", "url": "https://github.com/ergebnis/composer-normalize.git", - "reference": "988f83f5e51a42cdd2337e5fcd935432f8dfa33c" + "reference": "6a247926bc4e85b06bb12fa23d9593bc973be8d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/988f83f5e51a42cdd2337e5fcd935432f8dfa33c", - "reference": "988f83f5e51a42cdd2337e5fcd935432f8dfa33c", + "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/6a247926bc4e85b06bb12fa23d9593bc973be8d9", + "reference": "6a247926bc4e85b06bb12fa23d9593bc973be8d9", "shasum": "" }, "require": { "composer-plugin-api": "^2.0.0", + "composer-runtime-api": "^2.0.0", "ergebnis/json": "^1.4.0", "ergebnis/json-normalizer": "^4.9.0", "ergebnis/json-printer": "^3.7.0", "ext-json": "*", "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", "localheinz/diff": "^1.3.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" }, "require-dev": { - "composer/composer": "^2.9.8", + "composer/composer": "^2.10.3", "ergebnis/license": "^2.7.0", - "ergebnis/php-cs-fixer-config": "^6.62.1", + "ergebnis/php-cs-fixer-config": "^6.63.2", "ergebnis/phpstan-rules": "^2.13.1", - "ergebnis/phpunit-slow-test-detector": "^2.24.0", - "ergebnis/rector-rules": "^1.18.1", + "ergebnis/phpunit-slow-test-detector": "^2.25.0", + "ergebnis/rector-rules": "^1.18.3", "fakerphp/faker": "^1.24.1", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.54", - "phpstan/phpstan-deprecation-rules": "^2.0.4", - "phpstan/phpstan-phpunit": "^2.0.16", - "phpstan/phpstan-strict-rules": "^2.0.11", + "phpstan/phpstan": "^2.1.55", + "phpstan/phpstan-deprecation-rules": "^2.0.5", + "phpstan/phpstan-phpunit": "^2.0.18", + "phpstan/phpstan-strict-rules": "^2.0.12", "phpunit/phpunit": "^9.6.33", - "rector/rector": "^2.4.3", + "rector/rector": "^2.6.7", "symfony/filesystem": "^5.4.41" }, "type": "composer-plugin", "extra": { "class": "Ergebnis\\Composer\\Normalize\\NormalizePlugin", "branch-alias": { - "dev-main": "2.52-dev" + "dev-main": "2.54-dev" }, "plugin-optional": true, "composer-normalize": { @@ -7890,42 +8267,42 @@ "security": "https://github.com/ergebnis/composer-normalize/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/composer-normalize" }, - "time": "2026-05-15T15:39:24+00:00" + "time": "2026-09-24T19:41:19+00:00" }, { "name": "ergebnis/json", - "version": "1.6.0", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json.git", - "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1" + "reference": "829ce8b25c5e452249492c824f1d227777709403" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json/zipball/7b56d2b5d9e897e75b43e2e753075a0904c921b1", - "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1", + "url": "https://api.github.com/repos/ergebnis/json/zipball/829ce8b25c5e452249492c824f1d227777709403", + "reference": "829ce8b25c5e452249492c824f1d227777709403", "shasum": "" }, "require": { "ext-json": "*", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.44.0", - "ergebnis/data-provider": "^3.3.0", - "ergebnis/license": "^2.5.0", - "ergebnis/php-cs-fixer-config": "^6.37.0", - "ergebnis/phpstan-rules": "^2.11.0", - "ergebnis/phpunit-slow-test-detector": "^2.16.1", - "fakerphp/faker": "^1.24.0", + "ergebnis/data-provider": "^3.6.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.63.3", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.25.0", + "ergebnis/rector-rules": "^1.18.4", + "fakerphp/faker": "^1.24.1", "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.22", - "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.7", - "phpstan/phpstan-strict-rules": "^2.0.6", + "phpstan/phpstan": "^2.2.14", + "phpstan/phpstan-deprecation-rules": "^2.0.5", + "phpstan/phpstan-phpunit": "^2.0.18", + "phpstan/phpstan-strict-rules": "^2.0.12", "phpunit/phpunit": "^9.6.24", - "rector/rector": "^2.1.4" + "rector/rector": "^2.6.7" }, "type": "library", "extra": { @@ -7963,20 +8340,20 @@ "security": "https://github.com/ergebnis/json/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json" }, - "time": "2025-09-06T09:08:45+00:00" + "time": "2026-09-24T19:42:16+00:00" }, { "name": "ergebnis/json-normalizer", - "version": "4.10.1", + "version": "4.11.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-normalizer.git", - "reference": "77961faf2c651c3f05977b53c6c68e8434febf62" + "reference": "db539052df534709ca899620844bf046d0fa34f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/77961faf2c651c3f05977b53c6c68e8434febf62", - "reference": "77961faf2c651c3f05977b53c6c68e8434febf62", + "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/db539052df534709ca899620844bf046d0fa34f2", + "reference": "db539052df534709ca899620844bf046d0fa34f2", "shasum": "" }, "require": { @@ -7986,24 +8363,24 @@ "ergebnis/json-schema-validator": "^4.2.0", "ext-json": "*", "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" }, "require-dev": { - "composer/semver": "^3.4.3", - "ergebnis/composer-normalize": "^2.44.0", - "ergebnis/data-provider": "^3.3.0", - "ergebnis/license": "^2.5.0", - "ergebnis/php-cs-fixer-config": "^6.37.0", - "ergebnis/phpunit-slow-test-detector": "^2.16.1", - "fakerphp/faker": "^1.24.0", + "composer/semver": "^3.4.4", + "ergebnis/data-provider": "^3.6.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.63.3", + "ergebnis/phpunit-slow-test-detector": "^2.25.0", + "ergebnis/rector-rules": "^1.18.4", + "fakerphp/faker": "^1.24.1", "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.10", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpstan/phpstan-strict-rules": "^1.6.1", + "phpstan/phpstan": "^2.2.15", + "phpstan/phpstan-deprecation-rules": "^2.0.5", + "phpstan/phpstan-phpunit": "^2.0.18", + "phpstan/phpstan-strict-rules": "^2.0.12", "phpunit/phpunit": "^9.6.19", - "rector/rector": "^1.2.10" + "rector/rector": "^2.6.7" }, "suggest": { "composer/semver": "If you want to use ComposerJsonNormalizer or VersionConstraintNormalizer" @@ -8045,47 +8422,46 @@ "security": "https://github.com/ergebnis/json-normalizer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-normalizer" }, - "time": "2025-09-06T09:18:13+00:00" + "time": "2026-09-24T19:42:25+00:00" }, { "name": "ergebnis/json-pointer", - "version": "3.8.0", + "version": "3.9.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-pointer.git", - "reference": "b58c3c468a7ff109fdf9a255f17de29ecbe5276c" + "reference": "414a90039cdf458eeb71297315a2be6de195697a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-pointer/zipball/b58c3c468a7ff109fdf9a255f17de29ecbe5276c", - "reference": "b58c3c468a7ff109fdf9a255f17de29ecbe5276c", + "url": "https://api.github.com/repos/ergebnis/json-pointer/zipball/414a90039cdf458eeb71297315a2be6de195697a", + "reference": "414a90039cdf458eeb71297315a2be6de195697a", "shasum": "" }, "require": { - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.50.0", "ergebnis/data-provider": "^3.6.0", "ergebnis/license": "^2.7.0", - "ergebnis/php-cs-fixer-config": "^6.60.2", + "ergebnis/php-cs-fixer-config": "^6.63.3", "ergebnis/phpstan-rules": "^2.13.1", - "ergebnis/phpunit-slow-test-detector": "^2.24.0", - "ergebnis/rector-rules": "^1.16.0", + "ergebnis/phpunit-slow-test-detector": "^2.25.0", + "ergebnis/rector-rules": "^1.18.3", "fakerphp/faker": "^1.24.1", "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.46", - "phpstan/phpstan-deprecation-rules": "^2.0.4", - "phpstan/phpstan-phpunit": "^2.0.16", - "phpstan/phpstan-strict-rules": "^2.0.10", + "phpstan/phpstan": "^2.2.14", + "phpstan/phpstan-deprecation-rules": "^2.0.5", + "phpstan/phpstan-phpunit": "^2.0.18", + "phpstan/phpstan-strict-rules": "^2.0.12", "phpunit/phpunit": "^9.6.34", - "rector/rector": "^2.4.0" + "rector/rector": "^2.6.7" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.8-dev" + "dev-main": "3.9-dev" }, "composer-normalize": { "indent-size": 2, @@ -8120,42 +8496,42 @@ "security": "https://github.com/ergebnis/json-pointer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-pointer" }, - "time": "2026-04-07T14:52:13+00:00" + "time": "2026-09-24T19:42:34+00:00" }, { "name": "ergebnis/json-printer", - "version": "3.8.1", + "version": "3.9.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-printer.git", - "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e" + "reference": "7c8f49d86229947b4034e4637da95cb4390073e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/211d73fc7ec6daf98568ee6ed6e6d133dee8503e", - "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e", + "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/7c8f49d86229947b4034e4637da95cb4390073e6", + "reference": "7c8f49d86229947b4034e4637da95cb4390073e6", "shasum": "" }, "require": { "ext-json": "*", "ext-mbstring": "*", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.44.0", - "ergebnis/data-provider": "^3.3.0", - "ergebnis/license": "^2.5.0", - "ergebnis/php-cs-fixer-config": "^6.37.0", - "ergebnis/phpunit-slow-test-detector": "^2.16.1", + "ergebnis/data-provider": "^3.6.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.63.3", + "ergebnis/phpunit-slow-test-detector": "^2.25.0", + "ergebnis/rector-rules": "^1.18.4", "fakerphp/faker": "^1.24.0", "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.10", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.1", - "phpstan/phpstan-strict-rules": "^1.6.1", + "phpstan/phpstan": "^2.2.15", + "phpstan/phpstan-deprecation-rules": "^2.0.5", + "phpstan/phpstan-phpunit": "^2.0.18", + "phpstan/phpstan-strict-rules": "^2.0.12", "phpunit/phpunit": "^9.6.21", - "rector/rector": "^1.2.10" + "rector/rector": "^2.6.7" }, "type": "library", "extra": { @@ -8195,20 +8571,20 @@ "security": "https://github.com/ergebnis/json-printer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-printer" }, - "time": "2025-09-06T09:59:26+00:00" + "time": "2026-09-24T19:42:43+00:00" }, { "name": "ergebnis/json-schema-validator", - "version": "4.5.1", + "version": "4.6.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-schema-validator.git", - "reference": "b739527a480a9e3651360ad351ea77e7e9019df2" + "reference": "228bf86d963c06c863a3143c9d8531bb3ef72fbe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/b739527a480a9e3651360ad351ea77e7e9019df2", - "reference": "b739527a480a9e3651360ad351ea77e7e9019df2", + "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/228bf86d963c06c863a3143c9d8531bb3ef72fbe", + "reference": "228bf86d963c06c863a3143c9d8531bb3ef72fbe", "shasum": "" }, "require": { @@ -8216,23 +8592,23 @@ "ergebnis/json-pointer": "^3.4.0", "ext-json": "*", "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.44.0", - "ergebnis/data-provider": "^3.3.0", - "ergebnis/license": "^2.5.0", - "ergebnis/php-cs-fixer-config": "^6.37.0", - "ergebnis/phpunit-slow-test-detector": "^2.16.1", + "ergebnis/data-provider": "^3.6.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.63.3", + "ergebnis/phpunit-slow-test-detector": "^2.25.0", + "ergebnis/rector-rules": "^1.18.4", "fakerphp/faker": "^1.24.0", "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.10", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpstan/phpstan-strict-rules": "^1.6.1", + "phpstan/phpstan": "^2.2.15", + "phpstan/phpstan-deprecation-rules": "^2.0.5", + "phpstan/phpstan-phpunit": "^2.0.18", + "phpstan/phpstan-strict-rules": "^2.0.12", "phpunit/phpunit": "^9.6.20", - "rector/rector": "^1.2.10" + "rector/rector": "^2.6.7" }, "type": "library", "extra": { @@ -8272,7 +8648,7 @@ "security": "https://github.com/ergebnis/json-schema-validator/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-schema-validator" }, - "time": "2025-09-06T11:37:35+00:00" + "time": "2026-09-24T19:42:52+00:00" }, { "name": "evenement/evenement", @@ -8386,23 +8762,23 @@ }, { "name": "fidry/cpu-core-counter", - "version": "1.3.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "db9508f7b1474469d9d3c53b86f817e344732678" + "reference": "d384a7d0d6e67aa497327260ca95023e92dc2032" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", - "reference": "db9508f7b1474469d9d3c53b86f817e344732678", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/d384a7d0d6e67aa497327260ca95023e92dc2032", + "reference": "d384a7d0d6e67aa497327260ca95023e92dc2032", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "fidry/makefile": "^0.2.0", + "fidry/makefile": "^0.2.0 || ^1.1.2", "fidry/php-cs-fixer-config": "^1.1.2", "phpstan/extension-installer": "^1.2.0", "phpstan/phpstan": "^2.0", @@ -8410,6 +8786,7 @@ "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "symfony/polyfill-mbstring": "^1.33", "webmozarts/strict-phpunit": "^7.5" }, "type": "library", @@ -8435,7 +8812,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.4.1" }, "funding": [ { @@ -8443,20 +8820,20 @@ "type": "github" } ], - "time": "2025-08-14T07:29:31+00:00" + "time": "2026-09-29T22:11:39+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.95.8", + "version": "v3.95.27", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "4140023f552ff02346df9b1329742532166f677f" + "reference": "1d0c68ee5f37446d8ad5970b82384cd1bb0a3317" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4140023f552ff02346df9b1329742532166f677f", - "reference": "4140023f552ff02346df9b1329742532166f677f", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/1d0c68ee5f37446d8ad5970b82384cd1bb0a3317", + "reference": "1d0c68ee5f37446d8ad5970b82384cd1bb0a3317", "shasum": "" }, "require": { @@ -8490,16 +8867,15 @@ "require-dev": { "facile-it/paraunit": "^1.3.1 || ^2.11.0", "infection/infection": "^0.32.7", - "justinrainbow/json-schema": "^6.9.0", + "justinrainbow/json-schema": "^6.12.0", "keradus/cli-executor": "^2.3", - "mikey179/vfsstream": "^1.6.12", "php-coveralls/php-coveralls": "^2.9.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.8", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.8", - "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.55", - "symfony/polyfill-php85": "^1.38", - "symfony/var-dumper": "^5.4.48 || ^6.4.36 || ^7.4.8 || ^8.1.0", - "symfony/yaml": "^5.4.53 || ^6.4.41 || ^7.4.13 || ^8.1.0" + "phpunit/phpunit": "^9.6.36 || ^10.5.64 || ^11.5.56 || ^12.5.35 || ^13.3.3", + "symfony/polyfill-php85": "^1.41", + "symfony/var-dumper": "^5.4.48 || ^6.4.45 || ^7.4.18 || ^8.1.7", + "symfony/yaml": "^5.4.53 || ^6.4.45 || ^7.4.18 || ^8.1.6" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -8540,7 +8916,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.8" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.27" }, "funding": [ { @@ -8548,23 +8924,24 @@ "type": "github" } ], - "time": "2026-06-16T09:52:26+00:00" + "time": "2026-09-22T09:54:55+00:00" }, { "name": "justinrainbow/json-schema", - "version": "6.10.0", + "version": "6.13.1", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "8b1308a9d7bdbdb20ce87ef920f82b4564bb2d33" + "reference": "e54aacc4c0657b3a4af4f628428d2702146828c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/8b1308a9d7bdbdb20ce87ef920f82b4564bb2d33", - "reference": "8b1308a9d7bdbdb20ce87ef920f82b4564bb2d33", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/e54aacc4c0657b3a4af4f628428d2702146828c6", + "reference": "e54aacc4c0657b3a4af4f628428d2702146828c6", "shasum": "" }, "require": { + "ext-filter": "*", "ext-json": "*", "marc-mabe/php-enum": "^4.4", "php": "^7.2 || ^8.0" @@ -8597,20 +8974,9 @@ ], "authors": [ { - "name": "Bruno Prieto Reis", - "email": "bruno.p.reis@gmail.com" - }, - { - "name": "Justin Rainbow", - "email": "justin.rainbow@gmail.com" - }, - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - }, - { - "name": "Robert Schönthal", - "email": "seroscho@googlemail.com" + "name": "Danny van der Sluijs", + "email": "danny.vandersluijs@icloud.com", + "role": "Maintainer" } ], "description": "A library to validate a json schema.", @@ -8621,9 +8987,9 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/6.10.0" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.13.1" }, - "time": "2026-06-16T20:50:26+00:00" + "time": "2026-09-30T07:42:28+00:00" }, { "name": "localheinz/diff", @@ -8755,20 +9121,20 @@ }, { "name": "myclabs/deep-copy", - "version": "1.13.4", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae", + "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.0" }, "conflict": { "doctrine/collections": "<1.6.8", @@ -8803,32 +9169,31 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + "source": "https://github.com/myclabs/DeepCopy/tree/1.14.0" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" + "url": "https://github.com/mnapoli", + "type": "github" } ], - "time": "2025-08-01T08:46:24+00:00" + "time": "2026-08-11T10:17:44+00:00" }, { "name": "nikic/php-parser", - "version": "v5.7.0", + "version": "v5.9.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + "reference": "9e33da9553fe7786f0962b35f4e4ecf01be89def" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/9e33da9553fe7786f0962b35f4e4ecf01be89def", + "reference": "9e33da9553fe7786f0962b35f4e4ecf01be89def", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-json": "*", "ext-tokenizer": "*", "php": ">=7.4" @@ -8867,9 +9232,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.9.0" }, - "time": "2025-12-06T11:56:16+00:00" + "time": "2026-09-13T18:51:52+00:00" }, { "name": "phar-io/manifest", @@ -9039,11 +9404,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.2.2", + "version": "2.3.0", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e5cc34d491a90e79c216d824f60fe21fd4d93bd6", - "reference": "e5cc34d491a90e79c216d824f60fe21fd4d93bd6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b1f9890d9af53a25c58129e78f0aadd31f90d7f4", + "reference": "b1f9890d9af53a25c58129e78f0aadd31f90d7f4", "shasum": "" }, "require": { @@ -9099,20 +9464,20 @@ "type": "github" } ], - "time": "2026-06-05T09:00:01+00:00" + "time": "2026-10-06T06:15:36+00:00" }, { "name": "phpstan/phpstan-doctrine", - "version": "2.0.27", + "version": "2.0.28", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-doctrine.git", - "reference": "39b4ca45a07cdd6366eeefa2f7a993cddf3b9f9f" + "reference": "b4623954d5ffee6311e4ddbaef65c074ae0f781a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/39b4ca45a07cdd6366eeefa2f7a993cddf3b9f9f", - "reference": "39b4ca45a07cdd6366eeefa2f7a993cddf3b9f9f", + "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/b4623954d5ffee6311e4ddbaef65c074ae0f781a", + "reference": "b4623954d5ffee6311e4ddbaef65c074ae0f781a", "shasum": "" }, "require": { @@ -9174,35 +9539,35 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-doctrine/issues", - "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.27" + "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.28" }, - "time": "2026-06-10T10:39:35+00:00" + "time": "2026-07-13T08:43:43+00:00" }, { "name": "phpstan/phpstan-symfony", - "version": "2.0.20", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "53f1a6462dbe71fad36ce054caf5e1b725b740fd" + "reference": "1981b94f0dd3a5bb42268f6a7a0e8954ac76dc2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/53f1a6462dbe71fad36ce054caf5e1b725b740fd", - "reference": "53f1a6462dbe71fad36ce054caf5e1b725b740fd", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/1981b94f0dd3a5bb42268f6a7a0e8954ac76dc2e", + "reference": "1981b94f0dd3a5bb42268f6a7a0e8954ac76dc2e", "shasum": "" }, "require": { "ext-simplexml": "*", "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.1.13" + "phpstan/phpstan": "^2.3" }, "conflict": { "symfony/framework-bundle": "<3.0" }, "require-dev": { "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^2.0.8", + "phpstan/phpstan-phpunit": "^2.0.13", "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^9.6", "psr/container": "1.1.2", @@ -9248,22 +9613,22 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", - "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.20" + "source": "https://github.com/phpstan/phpstan-symfony/tree/2.1.0" }, - "time": "2026-06-16T09:17:35+00:00" + "time": "2026-10-03T15:54:38+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "14.2.2", + "version": "14.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "10d7da3628a99289cdf4c662dd7f0d73f1baec83" + "reference": "f1e54f06b6b4cea73cd6104ba3c0cfa0efa6d73f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/10d7da3628a99289cdf4c662dd7f0d73f1baec83", - "reference": "10d7da3628a99289cdf4c662dd7f0d73f1baec83", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1e54f06b6b4cea73cd6104ba3c0cfa0efa6d73f", + "reference": "f1e54f06b6b4cea73cd6104ba3c0cfa0efa6d73f", "shasum": "" }, "require": { @@ -9271,18 +9636,18 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.7.0", + "nikic/php-parser": "^5.9.0", "php": ">=8.4", - "phpunit/php-text-template": "^6.0", + "phpunit/php-text-template": "^6.0.1", "sebastian/complexity": "^6.0", - "sebastian/environment": "^9.3.2", + "sebastian/environment": "^9.3.3", "sebastian/git-state": "^1.0", - "sebastian/lines-of-code": "^5.0.1", + "sebastian/lines-of-code": "^5.0.2", "sebastian/version": "^7.0", "theseer/tokenizer": "^2.0.1" }, "require-dev": { - "phpunit/phpunit": "^13.2.0" + "phpunit/phpunit": "^13.3.6" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -9291,7 +9656,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "14.2.x-dev" + "dev-main": "14.4.x-dev" } }, "autoload": { @@ -9320,7 +9685,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.2.2" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.4.1" }, "funding": [ { @@ -9340,27 +9705,27 @@ "type": "tidelift" } ], - "time": "2026-06-08T11:50:38+00:00" + "time": "2026-10-03T14:05:38+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "7.0.0", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6e5aa1fb0a95b1703d83e721299ee18bb4e2de50" + "reference": "9bb4e6c58b62c1e043be995c66abec7c97307aae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6e5aa1fb0a95b1703d83e721299ee18bb4e2de50", - "reference": "6e5aa1fb0a95b1703d83e721299ee18bb4e2de50", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/9bb4e6c58b62c1e043be995c66abec7c97307aae", + "reference": "9bb4e6c58b62c1e043be995c66abec7c97307aae", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^13.3.1" }, "type": "library", "extra": { @@ -9393,7 +9758,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.2" }, "funding": [ { @@ -9413,7 +9778,7 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:33:26+00:00" + "time": "2026-08-25T14:47:43+00:00" }, { "name": "phpunit/php-invoker", @@ -9493,23 +9858,23 @@ }, { "name": "phpunit/php-text-template", - "version": "6.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4" + "reference": "97107691cb2b6c743b5e0c44be19e983cb337a02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/a47af19f93f76aa3368303d752aa5272ca3299f4", - "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/97107691cb2b6c743b5e0c44be19e983cb337a02", + "reference": "97107691cb2b6c743b5e0c44be19e983cb337a02", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^13.3.6" }, "type": "library", "extra": { @@ -9541,7 +9906,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/6.0.1" }, "funding": [ { @@ -9561,7 +9926,7 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:36:37+00:00" + "time": "2026-10-03T04:54:24+00:00" }, { "name": "phpunit/php-timer", @@ -9637,46 +10002,46 @@ }, { "name": "phpunit/phpunit", - "version": "13.2.1", + "version": "13.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba" + "reference": "ccde40327c501eebff192614b0dcf11806418901" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/60da0ff1e10a0f72ee18a24117ec3b613a346bba", - "reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ccde40327c501eebff192614b0dcf11806418901", + "reference": "ccde40327c501eebff192614b0dcf11806418901", "shasum": "" }, "require": { "ext-dom": "*", + "ext-filter": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", - "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.4", + "myclabs/deep-copy": "^1.14.0", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.4.1", - "phpunit/php-code-coverage": "^14.2.2", - "phpunit/php-file-iterator": "^7.0.0", + "phpunit/php-code-coverage": "^14.4.1", + "phpunit/php-file-iterator": "^7.0.2", "phpunit/php-invoker": "^7.0.0", - "phpunit/php-text-template": "^6.0.0", + "phpunit/php-text-template": "^6.0.1", "phpunit/php-timer": "^9.0.0", - "sebastian/cli-parser": "^5.0.0", - "sebastian/comparator": "^8.3.0", - "sebastian/diff": "^9.0", - "sebastian/environment": "^9.3.2", - "sebastian/exporter": "^8.1.0", + "sebastian/cli-parser": "^5.0.1", + "sebastian/comparator": "^8.4", + "sebastian/diff": "^9.0.1", + "sebastian/environment": "^9.3.3", + "sebastian/exporter": "^8.2.1", "sebastian/file-filter": "^1.0", "sebastian/git-state": "^1.0", "sebastian/global-state": "^9.0.1", - "sebastian/object-enumerator": "^8.0.0", - "sebastian/recursion-context": "^8.0.0", - "sebastian/type": "^7.0.1", - "sebastian/version": "^7.0.0", + "sebastian/object-enumerator": "^8.1.0", + "sebastian/recursion-context": "^8.0.1", + "sebastian/type": "^7.0.2", + "sebastian/version": "^7.0.1", "staabm/side-effects-detector": "^1.0.5" }, "bin": [ @@ -9685,7 +10050,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "13.2-dev" + "dev-main": "13.4-dev" } }, "autoload": { @@ -9717,7 +10082,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/13.2.1" + "source": "https://github.com/sebastianbergmann/phpunit/tree/13.4.1" }, "funding": [ { @@ -9725,7 +10090,7 @@ "type": "other" } ], - "time": "2026-06-15T13:14:22+00:00" + "time": "2026-10-05T05:51:21+00:00" }, { "name": "react/cache", @@ -10301,23 +10666,23 @@ }, { "name": "sebastian/cli-parser", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "48a4654fa5e48c1c81214e9930048a572d4b23ca" + "reference": "eeb759ad3146b7096fb59c3195d39e071cd409e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/48a4654fa5e48c1c81214e9930048a572d4b23ca", - "reference": "48a4654fa5e48c1c81214e9930048a572d4b23ca", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/eeb759ad3146b7096fb59c3195d39e071cd409e3", + "reference": "eeb759ad3146b7096fb59c3195d39e071cd409e3", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^13.2.6" }, "type": "library", "extra": { @@ -10346,7 +10711,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/5.0.1" }, "funding": [ { @@ -10366,20 +10731,20 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:39:44+00:00" + "time": "2026-08-01T04:27:14+00:00" }, { "name": "sebastian/comparator", - "version": "8.3.0", + "version": "8.4.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "c025fc7604afab3f195fab7cdaf72327331af241" + "reference": "3b070e608146cba00fd6fd1f0ffba89e5a8897fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c025fc7604afab3f195fab7cdaf72327331af241", - "reference": "c025fc7604afab3f195fab7cdaf72327331af241", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/3b070e608146cba00fd6fd1f0ffba89e5a8897fb", + "reference": "3b070e608146cba00fd6fd1f0ffba89e5a8897fb", "shasum": "" }, "require": { @@ -10387,10 +10752,10 @@ "ext-mbstring": "*", "php": ">=8.4", "sebastian/diff": "^9.0", - "sebastian/exporter": "^8.1.0" + "sebastian/exporter": "^8.2" }, "require-dev": { - "phpunit/phpunit": "^13.2" + "phpunit/phpunit": "^13.3" }, "suggest": { "ext-bcmath": "For comparing BcMath\\Number objects" @@ -10398,7 +10763,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "8.3-dev" + "dev-main": "8.4-dev" } }, "autoload": { @@ -10438,7 +10803,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/8.3.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/8.4.0" }, "funding": [ { @@ -10458,7 +10823,7 @@ "type": "tidelift" } ], - "time": "2026-06-05T03:06:45+00:00" + "time": "2026-08-07T07:23:13+00:00" }, { "name": "sebastian/complexity", @@ -10532,24 +10897,24 @@ }, { "name": "sebastian/diff", - "version": "9.0.0", + "version": "9.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226" + "reference": "a2df6626c1baf31d5a88674882a3072f151b5a26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a3fb6a298a265ff487a91bbea46e03cd01dbb226", - "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a2df6626c1baf31d5a88674882a3072f151b5a26", + "reference": "a2df6626c1baf31d5a88674882a3072f151b5a26", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.2", - "symfony/process": "^7.4.13" + "phpunit/phpunit": "^13.3.1", + "symfony/process": "^7.4.17" }, "type": "library", "extra": { @@ -10587,7 +10952,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/9.0.0" + "source": "https://github.com/sebastianbergmann/diff/tree/9.0.1" }, "funding": [ { @@ -10607,27 +10972,27 @@ "type": "tidelift" } ], - "time": "2026-06-05T03:04:51+00:00" + "time": "2026-08-25T15:38:55+00:00" }, { "name": "sebastian/environment", - "version": "9.3.2", + "version": "9.3.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e" + "reference": "d4dd10267a11055066a2a78ae04583d8ddd4f595" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e", - "reference": "6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d4dd10267a11055066a2a78ae04583d8ddd4f595", + "reference": "d4dd10267a11055066a2a78ae04583d8ddd4f595", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.1.11" + "phpunit/phpunit": "^13.3.6" }, "suggest": { "ext-posix": "*" @@ -10663,7 +11028,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/9.3.2" + "source": "https://github.com/sebastianbergmann/environment/tree/9.3.3" }, "funding": [ { @@ -10683,34 +11048,34 @@ "type": "tidelift" } ], - "time": "2026-05-25T13:41:38+00:00" + "time": "2026-10-01T12:37:56+00:00" }, { "name": "sebastian/exporter", - "version": "8.1.0", + "version": "8.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "c0d29a945f8cf82f300a05e69874508e307ca4c6" + "reference": "24a3b69bba4a12ab615fca9d34680c5598d9ab7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c0d29a945f8cf82f300a05e69874508e307ca4c6", - "reference": "c0d29a945f8cf82f300a05e69874508e307ca4c6", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/24a3b69bba4a12ab615fca9d34680c5598d9ab7a", + "reference": "24a3b69bba4a12ab615fca9d34680c5598d9ab7a", "shasum": "" }, "require": { "ext-mbstring": "*", "php": ">=8.4", - "sebastian/recursion-context": "^8.0" + "sebastian/recursion-context": "^8.0.1" }, "require-dev": { - "phpunit/phpunit": "^13.1.10" + "phpunit/phpunit": "^13.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.1-dev" + "dev-main": "8.2-dev" } }, "autoload": { @@ -10753,7 +11118,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/8.1.0" + "source": "https://github.com/sebastianbergmann/exporter/tree/8.2.1" }, "funding": [ { @@ -10773,7 +11138,7 @@ "type": "tidelift" } ], - "time": "2026-05-21T11:50:56+00:00" + "time": "2026-08-07T07:22:06+00:00" }, { "name": "sebastian/file-filter", @@ -10989,24 +11354,24 @@ }, { "name": "sebastian/lines-of-code", - "version": "5.0.1", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d2cff273a90c79b0eb590baa682d4b5c318bdbb7" + "reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d2cff273a90c79b0eb590baa682d4b5c318bdbb7", - "reference": "d2cff273a90c79b0eb590baa682d4b5c318bdbb7", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d1b6f8fce682505dbd048977f1abedf1b8ad3ff8", + "reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8", "shasum": "" }, "require": { - "nikic/php-parser": "^5.7.0", + "nikic/php-parser": "^5.8.0", "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.1.10" + "phpunit/phpunit": "^13.2.4" }, "type": "library", "extra": { @@ -11035,7 +11400,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/5.0.2" }, "funding": [ { @@ -11055,34 +11420,33 @@ "type": "tidelift" } ], - "time": "2026-05-19T16:23:37+00:00" + "time": "2026-07-09T08:42:34+00:00" }, { "name": "sebastian/object-enumerator", - "version": "8.0.0", + "version": "8.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "b39ab125fd9a7434b0ecbc4202eebce11a98cfc5" + "reference": "511064ecde82bd747e2ba2fab3dda8d977b59576" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/b39ab125fd9a7434b0ecbc4202eebce11a98cfc5", - "reference": "b39ab125fd9a7434b0ecbc4202eebce11a98cfc5", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/511064ecde82bd747e2ba2fab3dda8d977b59576", + "reference": "511064ecde82bd747e2ba2fab3dda8d977b59576", "shasum": "" }, "require": { "php": ">=8.4", - "sebastian/object-reflector": "^6.0", - "sebastian/recursion-context": "^8.0" + "sebastian/recursion-context": "^8.0.1" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^13.3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "8.1-dev" } }, "autoload": { @@ -11105,7 +11469,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/8.0.0" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/8.1.0" }, "funding": [ { @@ -11125,27 +11489,27 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:46:36+00:00" + "time": "2026-08-13T07:05:05+00:00" }, { "name": "sebastian/object-reflector", - "version": "6.0.0", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "3ca042c2c60b0eab094f8a1b6a7093f4d4c72200" + "reference": "f71bbcdc4f95456b4622810bec64eb06372e25b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/3ca042c2c60b0eab094f8a1b6a7093f4d4c72200", - "reference": "3ca042c2c60b0eab094f8a1b6a7093f4d4c72200", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/f71bbcdc4f95456b4622810bec64eb06372e25b2", + "reference": "f71bbcdc4f95456b4622810bec64eb06372e25b2", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^13.3.0" }, "type": "library", "extra": { @@ -11173,7 +11537,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/6.1.0" }, "funding": [ { @@ -11193,27 +11557,27 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:47:13+00:00" + "time": "2026-08-13T06:34:36+00:00" }, { "name": "sebastian/recursion-context", - "version": "8.0.0", + "version": "8.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "74c5af21f6a5833e91767ca068c4d3dfec15317e" + "reference": "32dba72f2b4642d6a93db22d6c0a9280ff2e3ca0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/74c5af21f6a5833e91767ca068c4d3dfec15317e", - "reference": "74c5af21f6a5833e91767ca068c4d3dfec15317e", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/32dba72f2b4642d6a93db22d6c0a9280ff2e3ca0", + "reference": "32dba72f2b4642d6a93db22d6c0a9280ff2e3ca0", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^13.2.6" }, "type": "library", "extra": { @@ -11249,7 +11613,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/8.0.0" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/8.0.1" }, "funding": [ { @@ -11269,27 +11633,27 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:51:28+00:00" + "time": "2026-08-03T05:58:12+00:00" }, { "name": "sebastian/type", - "version": "7.0.1", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fee0309275847fefd7636167085e379c1dbf6990" + "reference": "bd1df467864cb95140414059a535b2d906173fcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fee0309275847fefd7636167085e379c1dbf6990", - "reference": "fee0309275847fefd7636167085e379c1dbf6990", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/bd1df467864cb95140414059a535b2d906173fcf", + "reference": "bd1df467864cb95140414059a535b2d906173fcf", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.1.10" + "phpunit/phpunit": "^13.3.0" }, "type": "library", "extra": { @@ -11318,7 +11682,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/7.0.1" + "source": "https://github.com/sebastianbergmann/type/tree/7.0.2" }, "funding": [ { @@ -11338,20 +11702,20 @@ "type": "tidelift" } ], - "time": "2026-05-20T06:49:11+00:00" + "time": "2026-08-10T08:00:57+00:00" }, { "name": "sebastian/version", - "version": "7.0.0", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "ad37a5552c8e2b88572249fdc19b6da7792e021b" + "reference": "f1598cf1d8d1ca4c0f194a52f2fe72a559a7b0b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ad37a5552c8e2b88572249fdc19b6da7792e021b", - "reference": "ad37a5552c8e2b88572249fdc19b6da7792e021b", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/f1598cf1d8d1ca4c0f194a52f2fe72a559a7b0b1", + "reference": "f1598cf1d8d1ca4c0f194a52f2fe72a559a7b0b1", "shasum": "" }, "require": { @@ -11384,7 +11748,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/version/issues", "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/version/tree/7.0.1" }, "funding": [ { @@ -11404,7 +11768,7 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:52:52+00:00" + "time": "2026-10-04T05:51:14+00:00" }, { "name": "staabm/side-effects-detector", @@ -11460,16 +11824,16 @@ }, { "name": "symfony/browser-kit", - "version": "v8.1.0", + "version": "v8.1.5", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "74e18e582cdda0eca35f7c74e1e48e62f0ede853" + "reference": "f6766c9fb232e72897d6d55cf8f6aec38db2dbbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/74e18e582cdda0eca35f7c74e1e48e62f0ede853", - "reference": "74e18e582cdda0eca35f7c74e1e48e62f0ede853", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/f6766c9fb232e72897d6d55cf8f6aec38db2dbbf", + "reference": "f6766c9fb232e72897d6d55cf8f6aec38db2dbbf", "shasum": "" }, "require": { @@ -11508,7 +11872,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v8.1.0" + "source": "https://github.com/symfony/browser-kit/tree/v8.1.5" }, "funding": [ { @@ -11528,20 +11892,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-21T17:47:34+00:00" }, { "name": "symfony/css-selector", - "version": "v8.1.0", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd" + "reference": "08e2905152a39cf3fd1745d83f8c483e258887d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/dc0e2be45c9b5588c82414f02ac574b4b986abcd", - "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/08e2905152a39cf3fd1745d83f8c483e258887d9", + "reference": "08e2905152a39cf3fd1745d83f8c483e258887d9", "shasum": "" }, "require": { @@ -11577,7 +11941,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v8.1.0" + "source": "https://github.com/symfony/css-selector/tree/v8.1.6" }, "funding": [ { @@ -11597,7 +11961,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-23T10:06:25+00:00" }, { "name": "symfony/debug-bundle", @@ -11676,16 +12040,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v8.1.0", + "version": "v8.1.5", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "77ca351474ea018daba5f2e473cbf1b9b8e72ac6" + "reference": "94f70e1b2e5b7b8f8618871fd9eaad3e39e9f03d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/77ca351474ea018daba5f2e473cbf1b9b8e72ac6", - "reference": "77ca351474ea018daba5f2e473cbf1b9b8e72ac6", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/94f70e1b2e5b7b8f8618871fd9eaad3e39e9f03d", + "reference": "94f70e1b2e5b7b8f8618871fd9eaad3e39e9f03d", "shasum": "" }, "require": { @@ -11722,7 +12086,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v8.1.0" + "source": "https://github.com/symfony/dom-crawler/tree/v8.1.5" }, "funding": [ { @@ -11742,7 +12106,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-08-21T17:47:34+00:00" }, { "name": "symfony/maker-bundle", @@ -11846,16 +12210,16 @@ }, { "name": "symfony/process", - "version": "v8.1.0", + "version": "v8.1.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5" + "reference": "10823b09358e690df4ff943e24e8492bb1019fc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", - "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", + "url": "https://api.github.com/repos/symfony/process/zipball/10823b09358e690df4ff943e24e8492bb1019fc3", + "reference": "10823b09358e690df4ff943e24e8492bb1019fc3", "shasum": "" }, "require": { @@ -11887,7 +12251,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v8.1.0" + "source": "https://github.com/symfony/process/tree/v8.1.7" }, "funding": [ { @@ -11907,20 +12271,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-02T12:40:29+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v8.1.0", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "f8ccea08797a511b85a698b0da40e1b9e6461086" + "reference": "bd30b3f8e2cafe758d71c2237dc09544e144402e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/f8ccea08797a511b85a698b0da40e1b9e6461086", - "reference": "f8ccea08797a511b85a698b0da40e1b9e6461086", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/bd30b3f8e2cafe758d71c2237dc09544e144402e", + "reference": "bd30b3f8e2cafe758d71c2237dc09544e144402e", "shasum": "" }, "require": { @@ -11972,7 +12336,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v8.1.0" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v8.1.8" }, "funding": [ { @@ -11992,7 +12356,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "theseer/tokenizer", @@ -12046,16 +12410,16 @@ }, { "name": "vincentlanglet/twig-cs-fixer", - "version": "4.0.0", + "version": "4.1.1", "source": { "type": "git", "url": "https://github.com/VincentLanglet/Twig-CS-Fixer.git", - "reference": "10e0133faf33218ea3380432f3a757ba50e9e17d" + "reference": "53c1234b6e5d87ac2beaf686774bba013697f9c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/VincentLanglet/Twig-CS-Fixer/zipball/10e0133faf33218ea3380432f3a757ba50e9e17d", - "reference": "10e0133faf33218ea3380432f3a757ba50e9e17d", + "url": "https://api.github.com/repos/VincentLanglet/Twig-CS-Fixer/zipball/53c1234b6e5d87ac2beaf686774bba013697f9c5", + "reference": "53c1234b6e5d87ac2beaf686774bba013697f9c5", "shasum": "" }, "require": { @@ -12111,7 +12475,7 @@ "homepage": "https://github.com/VincentLanglet/Twig-CS-Fixer", "support": { "issues": "https://github.com/VincentLanglet/Twig-CS-Fixer/issues", - "source": "https://github.com/VincentLanglet/Twig-CS-Fixer/tree/4.0.0" + "source": "https://github.com/VincentLanglet/Twig-CS-Fixer/tree/4.1.1" }, "funding": [ { @@ -12119,20 +12483,20 @@ "type": "github" } ], - "time": "2026-06-15T14:41:51+00:00" + "time": "2026-09-08T21:26:25+00:00" }, { "name": "webmozart/assert", - "version": "2.4.1", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70" + "reference": "8a163706bbcac613733dba03f51e13b5eb1bb819" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/2ccb7c2e821038c03a3e6e1700c570c158c55f70", - "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/8a163706bbcac613733dba03f51e13b5eb1bb819", + "reference": "8a163706bbcac613733dba03f51e13b5eb1bb819", "shasum": "" }, "require": { @@ -12183,9 +12547,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.4.1" + "source": "https://github.com/webmozarts/assert/tree/2.5.0" }, - "time": "2026-06-15T15:31:57+00:00" + "time": "2026-10-05T23:14:19+00:00" }, { "name": "zenstruck/assert", @@ -12252,22 +12616,23 @@ }, { "name": "zenstruck/foundry", - "version": "v2.10.1", + "version": "v2.14.0", "source": { "type": "git", "url": "https://github.com/zenstruck/foundry.git", - "reference": "34cbd882df0fee5a5f9bd2f0c2f69286e283263d" + "reference": "6c140f441b7bc3a4bfd7b3b6efdda475493e580d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zenstruck/foundry/zipball/34cbd882df0fee5a5f9bd2f0c2f69286e283263d", - "reference": "34cbd882df0fee5a5f9bd2f0c2f69286e283263d", + "url": "https://api.github.com/repos/zenstruck/foundry/zipball/6c140f441b7bc3a4bfd7b3b6efdda475493e580d", + "reference": "6c140f441b7bc3a4bfd7b3b6efdda475493e580d", "shasum": "" }, "require": { "fakerphp/faker": "^1.24", "php": ">=8.1", "symfony/deprecation-contracts": "^2.2|^3.0", + "symfony/polyfill-deepclone": "^1.42", "symfony/polyfill-php84": "^1.32", "symfony/polyfill-php85": "^1.33", "symfony/property-access": "^6.4|^7.0|^8.0", @@ -12285,12 +12650,12 @@ "doctrine/collections": "^1.7|^2.0", "doctrine/common": "^3.2.2", "doctrine/doctrine-bundle": "^2.10|^3.0", - "doctrine/doctrine-migrations-bundle": "^2.2|^3.0", + "doctrine/doctrine-migrations-bundle": "^2.2|^3.0|^4.0", "doctrine/mongodb-odm": "^2.4", "doctrine/mongodb-odm-bundle": "^4.6|^5.0", "doctrine/orm": "^2.16|^3.0", "doctrine/persistence": "^2.0|^3.0|^4.0", - "phpunit/phpunit": "^9.5.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0", + "phpunit/phpunit": "^9.5.0 || ^10.0 || ^11.0 || ^12.0 || ~13.1.0", "symfony/browser-kit": "^6.4|^7.0|^8.0", "symfony/console": "^6.4|^7.0|^8.0", "symfony/dotenv": "^6.4|^7.0|^8.0", @@ -12331,7 +12696,10 @@ "Zenstruck\\Foundry\\": "src/", "Zenstruck\\Foundry\\Psalm\\": "utils/psalm", "Zenstruck\\Foundry\\Utils\\Rector\\": "utils/rector/src/" - } + }, + "exclude-from-classmap": [ + "src/Test/Behat/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -12360,7 +12728,7 @@ ], "support": { "issues": "https://github.com/zenstruck/foundry/issues", - "source": "https://github.com/zenstruck/foundry/tree/v2.10.1" + "source": "https://github.com/zenstruck/foundry/tree/v2.14.0" }, "funding": [ { @@ -12372,11 +12740,11 @@ "type": "github" } ], - "time": "2026-05-19T15:59:32+00:00" + "time": "2026-10-07T06:44:29+00:00" } ], "aliases": [], - "minimum-stability": "stable", + "minimum-stability": "dev", "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, diff --git a/config/bundles.php b/config/bundles.php index e69e836..ea79765 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -18,4 +18,5 @@ ITKDev\EntityBundle\ITKDevEntityBundle::class => ['all' => true], Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], + ItkDev\TidyFeedbackBundle\TidyFeedbackBundle::class => ['all' => true], ]; diff --git a/config/routes/tidy_feedback.yaml b/config/routes/tidy_feedback.yaml new file mode 100644 index 0000000..c02dc2a --- /dev/null +++ b/config/routes/tidy_feedback.yaml @@ -0,0 +1,4 @@ +#config/routes/tidy_feedback.yaml +tidy_feedback: + resource: '@TidyFeedbackBundle/config/routes.php' + prefix: /tidy-feedback diff --git a/migrations/Version20261007080000.php b/migrations/Version20261007080000.php new file mode 100644 index 0000000..478432b --- /dev/null +++ b/migrations/Version20261007080000.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE project DROP summary'); + } + + public function down(Schema $schema): void + { + // Recreates the empty column only; the dropped texts are not restored. + $this->addSql('ALTER TABLE project ADD summary LONGTEXT DEFAULT NULL'); + } +} diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index a10e38a..03c2bdd 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -15,6 +15,8 @@ use Doctrine\ORM\EntityManagerInterface; use League\Csv\Writer; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; @@ -161,7 +163,7 @@ public function new(Request $request, EntityManagerInterface $entityManager, Act if ($isAutosave) { // Not valid yet (e.g. no title): report it without creating anything. - return new Response(null, Response::HTTP_UNPROCESSABLE_ENTITY); + return $this->autosaveErrors($form); } return $this->render('project/new.html.twig', [ @@ -214,7 +216,7 @@ public function edit(Request $request, Project $project, EntityManagerInterface if ($isAutosave) { // Report the failed validation without redrawing the form the user is editing. - return new Response(null, Response::HTTP_UNPROCESSABLE_ENTITY); + return $this->autosaveErrors($form); } return $this->render('project/edit.html.twig', [ @@ -248,4 +250,34 @@ private function currentUser(): ?User return $user instanceof User ? $user : null; } + + /** + * The failed validation for the autosave client, which cannot redraw the + * form: the messages keyed by the fields' HTML names ("project[budget]") so + * it can mark the fields in place. Errors on the form itself sit under its + * own name ("project"). + * + * @param FormInterface $form + */ + private function autosaveErrors(FormInterface $form): JsonResponse + { + $errors = []; + foreach ($form->getErrors(true, true) as $error) { + $errors[$this->htmlName($error->getOrigin() ?? $form)][] = $error->getMessage(); + } + + return new JsonResponse(['errors' => $errors], Response::HTTP_UNPROCESSABLE_ENTITY); + } + + /** + * The name a field is posted under, built the way the form view does it. + * + * @param FormInterface $form + */ + private function htmlName(FormInterface $form): string + { + $parent = $form->getParent(); + + return null === $parent ? $form->getName() : sprintf('%s[%s]', $this->htmlName($parent), $form->getName()); + } } diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index 272f0a0..fd65c13 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -145,7 +145,6 @@ public function load(ObjectManager $manager): void $project = (new Project()) ->setTitle($title) ->setStatus($statuses[array_rand($statuses)]) - ->setSummary('Projektet arbejder med '.mb_strtolower($title).' gennem en tværgående indsats med fokus på borgernes hverdag og kommunens strategiske mål.') ->setDescription('Projektet er sat i gang, fordi kommunen har brug for at styrke indsatsen omkring '.mb_strtolower($title).".\n\nDet har ophæng i byrådets vedtagne strategier og i afdelingens handleplaner og gennemføres i samarbejde med relevante fagområder og eksterne partnere.") ->setEndorsement(0 === $index % 3 ? false : true) ->setAmountApplied((int) round($budget * 0.8)) diff --git a/src/Entity/Project.php b/src/Entity/Project.php index 8324d80..060184b 100644 --- a/src/Entity/Project.php +++ b/src/Entity/Project.php @@ -31,7 +31,7 @@ class Project extends AbstractEntity * @var list */ public const array COMPLETION_FIELDS = [ - 'title', 'areas', 'summary', 'description', 'types', 'status', + 'title', 'areas', 'description', 'types', 'status', 'organizationalAnchoring', 'amountApplied', 'budget', 'budgetItk', 'fundingRate', 'funding', 'timePeriodStart', 'timePeriodEnd', @@ -59,10 +59,6 @@ class Project extends AbstractEntity #[ORM\JoinTable(name: 'project_area')] private Collection $areas; - /** A few lines summing up the project's purpose, content, strategy and plans. */ - #[ORM\Column(type: Types::TEXT, nullable: true)] - private ?string $summary = null; - /** The fuller account: why the project is done and what it is anchored in. */ #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $description = null; @@ -235,18 +231,6 @@ public function setAreas(iterable $areas): static return $this; } - public function getSummary(): ?string - { - return $this->summary; - } - - public function setSummary(?string $summary): static - { - $this->summary = $summary; - - return $this; - } - public function getDescription(): ?string { return $this->description; @@ -604,7 +588,6 @@ public function getCompletionPercentage(): int $checks = [ null !== $this->title && '' !== $this->title, !$this->areas->isEmpty(), - null !== $this->summary && '' !== $this->summary, null !== $this->description && '' !== $this->description, !$this->types->isEmpty(), null !== $this->status, diff --git a/src/Form/ProjectType.php b/src/Form/ProjectType.php index d5cbf31..22fbb1e 100644 --- a/src/Form/ProjectType.php +++ b/src/Form/ProjectType.php @@ -34,15 +34,22 @@ class ProjectType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { + // Shared by the money fields: a numeric keypad on phones, and the + // number-format controller grouping the digits as they are typed. + $moneyAttr = [ + 'inputmode' => 'numeric', + 'data-controller' => 'number-format', + 'data-action' => 'input->number-format#format', + ]; + $builder ->add('title', TextType::class, [ 'label' => 'project.title', 'help' => 'project.title_help', ]) - ->add('topic', TextareaType::class, [ + ->add('topic', TextType::class, [ 'label' => 'project.topic', 'required' => false, - 'attr' => ['rows' => 4], 'help' => 'project.topic_help', ]) ->add('areas', EntityType::class, [ @@ -56,12 +63,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'attr' => ['data-area-select' => true, 'placeholder' => 'form.choose'], 'help' => 'project.area_help', ]) - ->add('summary', TextareaType::class, [ - 'label' => 'project.summary', - 'required' => false, - 'attr' => ['rows' => 4], - 'help' => 'project.summary_help', - ]) ->add('description', TextareaType::class, [ 'label' => 'project.description', 'required' => false, @@ -116,22 +117,29 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'choice_label' => static fn (EndorsementAuthor $value): string => $value->labelKey(), 'help' => 'project.endorsement_author_help', ]) + // The money fields are grouped ("1.250.000" in Danish), which makes + // Symfony render them as text inputs; the min attribute would be ignored + // there, so PositiveOrZero on the entity is the lower bound. The same + // grouping is applied live by the number-format controller. ->add('amountApplied', IntegerType::class, [ 'label' => 'project.amount_applied', 'required' => false, - 'attr' => ['min' => 0], + 'attr' => $moneyAttr, + 'grouping' => true, 'help' => 'project.amount_applied_help', ]) ->add('budget', IntegerType::class, [ 'label' => 'project.budget', 'required' => false, - 'attr' => ['min' => 0], + 'attr' => $moneyAttr, + 'grouping' => true, 'help' => 'project.budget_help', ]) ->add('budgetItk', IntegerType::class, [ 'label' => 'project.budget_itk', 'required' => false, - 'attr' => ['min' => 0], + 'attr' => $moneyAttr, + 'grouping' => true, 'help' => 'project.budget_itk_help', ]) ->add('fundingRate', EnumType::class, [ diff --git a/src/Repository/ProjectRepository.php b/src/Repository/ProjectRepository.php index 29a5679..3a1261d 100644 --- a/src/Repository/ProjectRepository.php +++ b/src/Repository/ProjectRepository.php @@ -43,7 +43,6 @@ public function search(ProjectFilter $filter): QueryBuilder $ors = [ 'LOWER(i.title) LIKE :q', 'LOWER(i.topic) LIKE :q', - 'LOWER(i.summary) LIKE :q', 'LOWER(i.description) LIKE :q', 'LOWER(i.statusAdditional) LIKE :q', 'LOWER(i.remainingFunding) LIKE :q', diff --git a/symfony.lock b/symfony.lock index 4719822..c47dfb1 100644 --- a/symfony.lock +++ b/symfony.lock @@ -75,6 +75,9 @@ "itk-dev/entity-bundle": { "version": "0.1.1" }, + "itk-dev/tidy-feedback": { + "version": "dev-feature/allow-symfony-8" + }, "phpstan/phpstan": { "version": "2.2", "recipe": { diff --git a/templates/form/fields.html.twig b/templates/form/fields.html.twig index 819ce0e..f703519 100644 --- a/templates/form/fields.html.twig +++ b/templates/form/fields.html.twig @@ -16,7 +16,9 @@
{{ help|trans(help_translation_parameters, translation_domain) }}
{%- endif -%} - {{ form_widget(form) }} + {#- aria-invalid lets the stylesheet outline the field, and is what the + autosave controller sets when it marks a field from a 422 response. -#} + {{ form_widget(form, errors|length > 0 ? {attr: attr|merge({'aria-invalid': 'true'})} : {}) }} {{ form_errors(form) }} {% endblock %} diff --git a/templates/project/_form.html.twig b/templates/project/_form.html.twig index 4fdecac..4d78f44 100644 --- a/templates/project/_form.html.twig +++ b/templates/project/_form.html.twig @@ -51,7 +51,6 @@ {{ form_row(form.areas) }} {{ form_row(form.types) }} - {{ form_row(form.summary) }} {{ form_row(form.description) }} diff --git a/templates/project/show.html.twig b/templates/project/show.html.twig index 2ded841..b46d7f3 100644 --- a/templates/project/show.html.twig +++ b/templates/project/show.html.twig @@ -28,11 +28,7 @@
- {% if project.summary %}

{{ project.summary }}

{% else %}

—

{% endif %} - {% if project.description %} -

{{ 'project.description'|trans }}

-

{{ project.description }}

- {% endif %} + {% if project.description %}

{{ project.description }}

{% else %}

—

{% endif %} {% if project.topic %}

{{ 'project.topic'|trans }}

{{ project.topic }}

diff --git a/tests/Controller/ProjectControllerTest.php b/tests/Controller/ProjectControllerTest.php index 1291917..f84d898 100644 --- a/tests/Controller/ProjectControllerTest.php +++ b/tests/Controller/ProjectControllerTest.php @@ -12,7 +12,6 @@ use App\Enum\FundingRate; use App\Enum\Status; use App\Tests\FunctionalTestCase; -use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Uid\Ulid; @@ -162,6 +161,8 @@ public function testTopicIsSavedShownSearchableAndExported(): void $topic = 'Digital Europe Blueprint '.uniqid(); $crawler = $this->client->request('GET', '/projects/new'); + // A single-line field like the title, not a textarea. + self::assertCount(1, $crawler->filter('input[type="text"][name="project[topic]"]')); $token = (string) $crawler->filter('input[name="project[_token]"]')->attr('value'); $this->client->request('POST', '/projects/new', [ 'project' => ['title' => 'Topic project', 'topic' => $topic, '_token' => $token], @@ -387,27 +388,20 @@ public function testTypesAreSavedShownFilteredAndExported(): void $em->flush(); } - public function testSummaryAndDescriptionAreSavedShownAndSearchable(): void + public function testDescriptionIsSavedShownAndSearchable(): void { $this->loginAsAdmin(); - $summary = 'Opsummering '.uniqid(); $description = 'Ophæng i klimaplanen '.uniqid(); $crawler = $this->client->request('GET', '/projects/new'); - self::assertStringContainsString('Opsummering', $crawler->filter('label[for="project_summary"]')->text()); self::assertStringContainsString('Beskrivelse', $crawler->filter('label[for="project_description"]')->text()); - - // The fuller description sits directly under the summary. - $names = $crawler->filter('form textarea')->each(static fn (Crawler $node): string => (string) $node->attr('name')); - $summaryAt = array_search('project[summary]', $names, true); - self::assertIsInt($summaryAt); - self::assertSame('project[description]', $names[$summaryAt + 1] ?? null); + // The summary field is gone; the description is the only free text in the basics section. + self::assertCount(0, $crawler->filter('[name="project[summary]"]')); $token = (string) $crawler->filter('input[name="project[_token]"]')->attr('value'); $this->client->request('POST', '/projects/new', [ 'project' => [ 'title' => 'Described project', - 'summary' => $summary, 'description' => $description, '_token' => $token, ], @@ -416,21 +410,58 @@ public function testSummaryAndDescriptionAreSavedShownAndSearchable(): void $project = $this->projects()->findOneBy(['title' => 'Described project']); self::assertInstanceOf(Project::class, $project); - self::assertSame($summary, $project->getSummary()); self::assertSame($description, $project->getDescription()); $id = (string) $project->getId(); + // The description leads the details card. $crawler = $this->client->request('GET', '/projects/'.$id); - $details = $crawler->filter('.card__body')->first()->text(); - self::assertStringContainsString($summary, $details); - self::assertStringContainsString($description, $details); + self::assertStringContainsString($description, $crawler->filter('.card__body')->first()->text()); - // Both texts are covered by the free-text filter. - foreach ([$summary, $description] as $needle) { - $crawler = $this->client->request('GET', '/projects?q='.urlencode($needle)); - self::assertStringContainsString('Described project', $crawler->filter('#project-results')->text()); + // And is covered by the free-text filter. + $crawler = $this->client->request('GET', '/projects?q='.urlencode($description)); + self::assertStringContainsString('Described project', $crawler->filter('#project-results')->text()); + + $this->removeProject($id); + } + + public function testMoneyFieldsUseThousandsSeparators(): void + { + $this->loginAsAdmin(); + $title = 'Grouped budget project '.uniqid(); + + // Grouping turns the number inputs into text inputs with a numeric keypad + // hint, and the number-format controller groups the digits as they are typed. + $crawler = $this->client->request('GET', '/projects/new'); + foreach (['amountApplied', 'budget', 'budgetItk'] as $field) { + self::assertCount(1, $crawler->filter(sprintf('input[type="text"][inputmode="numeric"][data-controller="number-format"][name="project[%s]"]', $field))); } + // Values typed with Danish separators are parsed to whole kroner. + $token = (string) $crawler->filter('input[name="project[_token]"]')->attr('value'); + $this->client->request('POST', '/projects/new', [ + 'project' => [ + 'title' => $title, + 'amountApplied' => '800.000', + 'budget' => '1.250.000', + 'budgetItk' => '250000', + '_token' => $token, + ], + ]); + $this->assertResponseRedirects(); + + $project = $this->projects()->findOneBy(['title' => $title]); + self::assertInstanceOf(Project::class, $project); + self::assertSame(800000, $project->getAmountApplied()); + self::assertSame(1250000, $project->getBudget()); + self::assertSame(250000, $project->getBudgetItk()); + $id = (string) $project->getId(); + + // And are rendered back with the separators. + $crawler = $this->client->request('GET', '/projects/'.$id.'/edit'); + self::assertSame('800.000', $crawler->filter('input[name="project[amountApplied]"]')->attr('value')); + self::assertSame('1.250.000', $crawler->filter('input[name="project[budget]"]')->attr('value')); + self::assertSame('250.000', $crawler->filter('input[name="project[budgetItk]"]')->attr('value')); + $this->removeProject($id); } @@ -592,6 +623,9 @@ public function testNewAutosaveReturnsUnprocessableWhenInvalid(): void $this->assertResponseStatusCodeSame(Response::HTTP_UNPROCESSABLE_ENTITY); self::assertNull($this->projects()->findOneBy(['title' => ''])); + + // The body names the field so the form can mark it in place. + self::assertSame(['project[title]'], array_keys($this->autosaveErrors())); } public function testEditAutosaveReturnsNoContent(): void @@ -616,14 +650,43 @@ public function testEditAutosaveReturnsUnprocessableWhenInvalid(): void $id = (string) $project->getId(); $this->client->request('POST', sprintf('/projects/%s/edit', $id), [ - 'project' => ['title' => ''], + 'project' => ['title' => '', 'budget' => '-500'], ], [], ['HTTP_X-Autosave' => '1']); $this->assertResponseStatusCodeSame(Response::HTTP_UNPROCESSABLE_ENTITY); + // Each invalid field is named with its message, so a negative amount + // points at the money field rather than at the form as a whole. + $errors = $this->autosaveErrors(); + self::assertSame(['project[title]', 'project[budget]'], array_keys($errors)); + foreach ($errors as $messages) { + self::assertCount(1, $messages); + self::assertNotSame('', $messages[0]); + } + $this->removeProject($id); } + public function testAnInvalidFieldIsMarkedOnTheRenderedForm(): void + { + $this->loginAsAdmin(); + $title = 'Negative budget project '.uniqid(); + + $crawler = $this->client->request('GET', '/projects/new'); + $token = (string) $crawler->filter('input[name="project[_token]"]')->attr('value'); + $crawler = $this->client->request('POST', '/projects/new', [ + 'project' => ['title' => $title, 'budget' => '-500', '_token' => $token], + ]); + + // A plain submit redraws the form: the invalid field is flagged and its + // message sits in the same row; valid fields are left alone. + $budget = $crawler->filter('input[name="project[budget]"]'); + self::assertSame('true', $budget->attr('aria-invalid')); + self::assertCount(1, $budget->closest('.form-row')->filter('.form-errors li')); + self::assertNull($crawler->filter('input[name="project[title]"]')->attr('aria-invalid')); + self::assertNull($this->projects()->findOneBy(['title' => $title])); + } + public function testTheProjectDefinitionIsShownOnCreateAndBehindALinkOnTheList(): void { $this->loginAsAdmin(); @@ -662,6 +725,24 @@ private function createProject(string $title, ?Status $status = null): Project return $project; } + /** + * The field errors in the last autosave response. + * + * @return array> + */ + private function autosaveErrors(): array + { + $this->assertResponseHeaderSame('Content-Type', 'application/json'); + $body = json_decode((string) $this->client->getResponse()->getContent(), true, 512, \JSON_THROW_ON_ERROR); + self::assertIsArray($body); + self::assertIsArray($body['errors']); + + /** @var array> $errors */ + $errors = $body['errors']; + + return $errors; + } + private function removeProject(string $id): void { $this->entityManager()->clear(); diff --git a/tests/Unit/Entity/ProjectTest.php b/tests/Unit/Entity/ProjectTest.php index 93c8f8d..3ec0bcf 100644 --- a/tests/Unit/Entity/ProjectTest.php +++ b/tests/Unit/Entity/ProjectTest.php @@ -53,7 +53,6 @@ public function testScalarAccessors(): void $project = (new Project()) ->setTitle('Grøn omstilling') ->setTopic('Digital Europe Blueprint for Data Space') - ->setSummary('Opsummering') ->setDescription('Beskrivelse') ->setStatus(Status::Granted) ->setStatusAdditional('Igangsat') @@ -70,7 +69,6 @@ public function testScalarAccessors(): void self::assertSame('Grøn omstilling', $project->getTitle()); self::assertSame('Digital Europe Blueprint for Data Space', $project->getTopic()); - self::assertSame('Opsummering', $project->getSummary()); self::assertSame('Beskrivelse', $project->getDescription()); self::assertSame(Status::Granted, $project->getStatus()); self::assertSame('Igangsat', $project->getStatusAdditional()); @@ -94,7 +92,6 @@ public function testCompletionPercentage(): void $full = (new Project()) ->setTitle('T') ->addArea((new Area())->setName('Klima og miljø')) - ->setSummary('S') ->setDescription('D') ->addType((new ProjectType())->setName('Projekt')) ->setStatus(Status::Granted) diff --git a/translations/messages.da.yaml b/translations/messages.da.yaml index 709013d..f057150 100644 --- a/translations/messages.da.yaml +++ b/translations/messages.da.yaml @@ -67,7 +67,7 @@ autosave: saved: Gemt unsaved: Ikke-gemte ændringer required: Tilføj en titel for at gemme. - error: Kunne ikke gemme — tjek de påkrævede felter + error: Kunne ikke gemme — tjek de markerede felter offline: Kunne ikke gemme — dine ændringer er bevaret her completion: Udfyldningsgrad @@ -167,12 +167,10 @@ dashboard: project: title: Titel title_help: Et kort, sigende navn på projektet. - topic: Emne + topic: EU topic topic_help: Det overordnede program, projektet er en del af. area: Område area_help: Vælg et eller flere tematiske områder. - summary: Opsummering - summary_help: Kort opsummering af formål, indhold, strategi og planer. description: Beskrivelse description_help: Hvorfor vi gør det, og hvad projektet har ophæng i. types: Type @@ -183,7 +181,7 @@ project: status_additional_help: Uddyb status, hvis der er behov. organizational_anchoring: Afdeling organizational_anchoring_help: Vælg en eller flere afdelinger. - endorsement: Er projektet vedtaget + endorsement: Er projektet godkendt endorsement_author: Hvor er det vedtaget endorsement_author_help: Hvor projektet er vedtaget. amount_applied: Ansøgt beløb (kr.) @@ -241,9 +239,9 @@ project: paid: vi får penge for at lave det examples_title: Eksempler på projekter examples: - first: Eksempel x - second: Eksempel y - third: Eksempel z + first: OS2ai storskala + second: EUROPAI + third: Aarhus ADM PC section: basics: Grundoplysninger classification: Klassificering @@ -420,7 +418,7 @@ enum: endorsement_author: city_council: Byrådet magistrate: Magistraten - committee: Udvalg + committee: Udvalg/Styregruppe department: Afdeling funding: municipal_budget: Kommunalt budget diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index c5e843e..5416005 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -67,7 +67,7 @@ autosave: saved: Saved unsaved: Unsaved changes required: Add a title to save. - error: Couldn’t save — check the required fields + error: Couldn’t save — check the marked fields offline: Save failed — your changes are kept here completion: Form completion @@ -167,12 +167,10 @@ dashboard: project: title: Title title_help: A short, descriptive name for the project. - topic: Topic + topic: EU topic topic_help: The wider programme this project is part of. area: Area area_help: Pick one or more thematic areas. - summary: Summary - summary_help: A brief summary of the purpose, content, strategy and plans. description: Description description_help: Why we are doing it, and what the project is anchored in. types: Type @@ -241,9 +239,9 @@ project: paid: we get paid to do it examples_title: Examples of projects examples: - first: Example x - second: Example y - third: Example z + first: OS2ai storskala + second: EUROPAI + third: Aarhus ADM PC section: basics: Basics classification: Classification