From 79835a2abd48ce8f7057e81b5e20af7d37d1eb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4se?= Date: Tue, 24 Dec 2024 01:00:43 +0100 Subject: [PATCH 1/5] Bump core version requirements for custom module and tidy info files --- composer-manifest.yaml | 17 +- composer.json | 6 +- composer.lock | 794 ++++++++---------- config/sync/navigation.settings.yml | 2 +- .../custom/academy/academy/academy.info.yml | 8 +- .../academy/dummy/academy_dummy.info.yml | 5 +- .../academy/academy_log/academy_log.info.yml | 4 +- .../custom/academy/courses/courses.info.yml | 4 +- .../custom/academy/lectures/lectures.info.yml | 10 +- .../academy/paragraphs/paragraphs.info.yml | 12 +- .../custom/academy/progress/progress.info.yml | 7 +- .../questionnaire/questionnaire.info.yml | 6 +- .../child_entities/child_entities.info.yml | 6 +- .../blocker_mode/blocker_mode.info.yml | 13 +- .../consumer_permissions.info.yml | 6 +- .../jsonapi_obscurity.info.yml | 6 +- .../oauth_grant/oauth_grant.info.yml | 15 +- .../oauth_grant_remote.info.yml | 15 +- .../postman_interface.info.yml | 10 +- web/modules/custom/mailer/mailer.info.yml | 5 +- .../monitoring/logbook/logbook.info.yml | 4 +- .../custom/monitoring/stats/stats.info.yml | 6 +- .../projects/feedback/feedback.info.yml | 11 +- .../projects/lifecycle/lifecycle.info.yml | 5 +- .../lifecycle_test_workflows.info.yml | 2 +- .../projects/dummy/projects_dummy.info.yml | 12 +- .../projects/projects/projects.info.yml | 2 +- .../user_types/creatives/creatives.info.yml | 6 +- .../creatives/dummy/creatives_dummy.info.yml | 16 +- .../dummy/organizations_dummy.info.yml | 16 +- .../organizations/organizations.info.yml | 8 +- .../custom/user_types/user_types.info.yml | 11 +- .../custom/youvo/dummy/youvo_dummy.info.yml | 14 +- web/modules/custom/youvo/youvo.info.yml | 11 +- .../youvo_development.info.yml | 4 +- .../youvo_platform/youvo_platform.info.yml | 6 +- web/sites/default/install.settings.php | 2 +- 37 files changed, 514 insertions(+), 573 deletions(-) diff --git a/composer-manifest.yaml b/composer-manifest.yaml index 44fc3e09..a95a2bdf 100644 --- a/composer-manifest.yaml +++ b/composer-manifest.yaml @@ -29,12 +29,9 @@ packages: dekor/php-array-table: '2.0' dflydev/dot-access-data: v3.0.3 doctrine/annotations: 1.14.4 - doctrine/common: 3.4.5 doctrine/deprecations: 1.1.4 - doctrine/event-manager: 2.0.1 doctrine/instantiator: 2.0.0 doctrine/lexer: 2.1.1 - doctrine/persistence: 3.4.0 dompdf/php-font-lib: 1.0.1 drupal/admin_toolbar: 3.5.1 drupal/coder: 8.3.26 @@ -47,8 +44,6 @@ packages: drupal/core-project-message: 10.4.0 drupal/core-recommended: 10.4.0 drupal/core-vendor-hardening: 10.4.0 - drupal/devel: 5.3.1 - drupal/devel_mail_logger: 2.0.0 drupal/entity: 1.5.0 drupal/file_mdm: 3.1.0 drupal/filefield_paths: 1.0.0-beta8 @@ -77,7 +72,7 @@ packages: drupal/upgrade_status: 4.3.6 drupal/user_bundle: 1.4.0 drupal/warmer: 2.0.14 - drush/drush: 12.5.3 + drush/drush: 13.3.3 e0ipso/shaper: 1.2.5 egulias/email-validator: 4.0.2 fakerphp/faker: v1.24.1 @@ -90,10 +85,15 @@ packages: guzzlehttp/guzzle: 7.9.2 guzzlehttp/promises: 2.0.4 guzzlehttp/psr7: 2.7.0 + illuminate/collections: v11.36.1 + illuminate/conditionable: v11.36.1 + illuminate/contracts: v11.36.1 + illuminate/macroable: v11.36.1 jangregor/phpstan-prophecy: 1.0.2 joachim-n/composer-manifest: 1.1.7 justinrainbow/json-schema: 5.3.0 - lcobucci/clock: 3.0.0 + laravel/prompts: v0.1.25 + lcobucci/clock: 3.3.1 lcobucci/jwt: 4.3.0 league/container: 4.2.4 league/event: 2.2.0 @@ -155,12 +155,13 @@ packages: psr/http-factory: 1.1.0 psr/http-message: '2.0' psr/log: 3.0.2 + psr/simple-cache: 3.0.0 psy/psysh: v0.12.7 ralouphie/getallheaders: 3.0.3 ramsey/collection: 2.0.0 ramsey/uuid: 4.7.6 react/promise: v3.2.0 - roave/security-advisories: 'dev-latest:abbccc97f36a9c78f033525c019d310433f22b57' + roave/security-advisories: 'dev-latest:5a88337185d08d54ac102bc6eb137fc432ea70fb' sebastian/cli-parser: 1.0.2 sebastian/code-unit: 1.0.8 sebastian/code-unit-reverse-lookup: 2.0.3 diff --git a/composer.json b/composer.json index d6496606..308205ac 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "drupal/subrequests": "^3.0", "drupal/upgrade_status": "^4.0", "drupal/user_bundle": "^1.2", - "drush/drush": "^12", + "drush/drush": "^13.3", "joachim-n/composer-manifest": "^1.1" }, "conflict": { @@ -63,7 +63,7 @@ "tbachert/spi": true }, "platform": { - "php": "8.1" + "php": "8.3" } }, "extra": { @@ -136,8 +136,6 @@ "drupal/admin_toolbar": "^3.3", "drupal/coder": "^8.3", "drupal/core-dev": "^10.4", - "drupal/devel": "^5.1", - "drupal/devel_mail_logger": "^2.0", "drupal/mailsystem": "^4.4", "drupal/openapi": "^2.1", "drupal/openapi_jsonapi": "^3.0", diff --git a/composer.lock b/composer.lock index db1d5356..ce652784 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cf3b78f3be287d9b5f4bde61fa429daa", + "content-hash": "6d3bd225c52dc5f300bab98f0ce0a5a0", "packages": [ { "name": "asm89/stack-cors", @@ -3085,58 +3085,62 @@ }, { "name": "drush/drush", - "version": "12.5.3", + "version": "13.3.3", "source": { "type": "git", "url": "https://github.com/drush-ops/drush.git", - "reference": "7fe0a492d5126c457c5fb184c4668a132b0aaac6" + "reference": "d124723dacb4208ccb875b7114722e420fccf06d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drush-ops/drush/zipball/7fe0a492d5126c457c5fb184c4668a132b0aaac6", - "reference": "7fe0a492d5126c457c5fb184c4668a132b0aaac6", + "url": "https://api.github.com/repos/drush-ops/drush/zipball/d124723dacb4208ccb875b7114722e420fccf06d", + "reference": "d124723dacb4208ccb875b7114722e420fccf06d", "shasum": "" }, "require": { - "chi-teck/drupal-code-generator": "^3.0", + "chi-teck/drupal-code-generator": "^3.6 || ^4@alpha", "composer-runtime-api": "^2.2", "composer/semver": "^1.4 || ^3", "consolidation/annotated-command": "^4.9.2", - "consolidation/config": "^2.1.2", + "consolidation/config": "^2.1.2 || ^3", "consolidation/filter-via-dot-access-data": "^2.0.2", "consolidation/output-formatters": "^4.3.2", - "consolidation/robo": "^4.0.6", + "consolidation/robo": "^4.0.6 || ^5", "consolidation/site-alias": "^4", "consolidation/site-process": "^5.2.0", + "dflydev/dot-access-data": "^3.0.2", "ext-dom": "*", "grasmash/yaml-cli": "^3.1", "guzzlehttp/guzzle": "^7.0", - "league/container": "^4", - "php": ">=8.1", - "psy/psysh": "~0.11", - "symfony/event-dispatcher": "^6", - "symfony/filesystem": "^6.1", - "symfony/finder": "^6", - "symfony/var-dumper": "^6.0", - "symfony/yaml": "^6.0", - "webflo/drupal-finder": "^1.2" + "laravel/prompts": "^0.1.21", + "league/container": "^4.2", + "php": ">=8.2", + "psy/psysh": "~0.12", + "symfony/event-dispatcher": "^6 || ^7", + "symfony/filesystem": "^6.1 || ^7", + "symfony/finder": "^6 || ^7", + "symfony/var-dumper": "^6.0 || ^7", + "symfony/yaml": "^6.0 || ^7" }, "conflict": { - "drupal/core": "< 10.0", + "drupal/core": "< 10.2", "drupal/migrate_run": "*", "drupal/migrate_tools": "<= 5" }, "require-dev": { "composer/installers": "^2", - "cweagans/composer-patches": "~1.0", - "drupal/core-recommended": "^10", + "cweagans/composer-patches": "~1.7.3", + "drupal/core-recommended": "^10.2.5 || 11.0.x-dev", "drupal/semver_example": "2.3.0", - "phpunit/phpunit": "^9", - "rector/rector": "^0.12", + "jetbrains/phpstorm-attributes": "^1.0", + "mglaman/phpstan-drupal": "^1.2", + "phpunit/phpunit": "^9 || ^10", + "rector/rector": "^1", "squizlabs/php_codesniffer": "^3.7" }, "bin": [ - "drush" + "drush", + "drush.php" ], "type": "library", "extra": { @@ -3217,7 +3221,7 @@ "issues": "https://github.com/drush-ops/drush/issues", "security": "https://github.com/drush-ops/drush/security/advisories", "slack": "https://drupal.slack.com/messages/C62H9CWQM", - "source": "https://github.com/drush-ops/drush/tree/12.5.3" + "source": "https://github.com/drush-ops/drush/tree/13.3.3" }, "funding": [ { @@ -3225,7 +3229,7 @@ "type": "github" } ], - "time": "2024-08-02T11:57:29+00:00" + "time": "2024-11-10T20:02:03+00:00" }, { "name": "e0ipso/shaper", @@ -3946,6 +3950,202 @@ ], "time": "2024-07-18T11:15:46+00:00" }, + { + "name": "illuminate/collections", + "version": "v11.36.1", + "source": { + "type": "git", + "url": "https://github.com/illuminate/collections.git", + "reference": "21868f9ac221a42d4346dc56495d11ab7e0d339a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/collections/zipball/21868f9ac221a42d4346dc56495d11ab7e0d339a", + "reference": "21868f9ac221a42d4346dc56495d11ab7e0d339a", + "shasum": "" + }, + "require": { + "illuminate/conditionable": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "php": "^8.2" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "files": [ + "functions.php", + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Collections package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-12-13T13:58:10+00:00" + }, + { + "name": "illuminate/conditionable", + "version": "v11.36.1", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "911df1bda950a3b799cf80671764e34eede131c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/911df1bda950a3b799cf80671764e34eede131c6", + "reference": "911df1bda950a3b799cf80671764e34eede131c6", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-11-21T16:28:56+00:00" + }, + { + "name": "illuminate/contracts", + "version": "v11.36.1", + "source": { + "type": "git", + "url": "https://github.com/illuminate/contracts.git", + "reference": "184317f701ba20ca265e36808ed54b75b115972d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/184317f701ba20ca265e36808ed54b75b115972d", + "reference": "184317f701ba20ca265e36808ed54b75b115972d", + "shasum": "" + }, + "require": { + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Contracts\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Contracts package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-11-25T15:33:38+00:00" + }, + { + "name": "illuminate/macroable", + "version": "v11.36.1", + "source": { + "type": "git", + "url": "https://github.com/illuminate/macroable.git", + "reference": "e1cb9e51b9ed5d3c9bc1ab431d0a52fe42a990ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/e1cb9e51b9ed5d3c9bc1ab431d0a52fe42a990ed", + "reference": "e1cb9e51b9ed5d3c9bc1ab431d0a52fe42a990ed", + "shasum": "" + }, + "require": { + "php": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Macroable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-06-28T20:10:30+00:00" + }, { "name": "joachim-n/composer-manifest", "version": "1.1.7", @@ -4055,36 +4255,94 @@ }, "time": "2024-07-06T21:00:26+00:00" }, + { + "name": "laravel/prompts", + "version": "v0.1.25", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/7b4029a84c37cb2725fc7f011586e2997040bc95", + "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/collections": "^10.0|^11.0", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.1.25" + }, + "time": "2024-08-12T22:06:33+00:00" + }, { "name": "lcobucci/clock", - "version": "3.0.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/lcobucci/clock.git", - "reference": "039ef98c6b57b101d10bd11d8fdfda12cbd996dc" + "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/clock/zipball/039ef98c6b57b101d10bd11d8fdfda12cbd996dc", - "reference": "039ef98c6b57b101d10bd11d8fdfda12cbd996dc", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/db3713a61addfffd615b79bf0bc22f0ccc61b86b", + "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", "psr/clock": "^1.0" }, "provide": { "psr/clock-implementation": "1.0" }, "require-dev": { - "infection/infection": "^0.26", - "lcobucci/coding-standard": "^9.0", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-deprecation-rules": "^1.1.1", - "phpstan/phpstan-phpunit": "^1.3.2", - "phpstan/phpstan-strict-rules": "^1.4.4", - "phpunit/phpunit": "^9.5.27" + "infection/infection": "^0.29", + "lcobucci/coding-standard": "^11.1.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.10.25", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.13", + "phpstan/phpstan-strict-rules": "^1.5.1", + "phpunit/phpunit": "^11.3.6" }, "type": "library", "autoload": { @@ -4105,7 +4363,7 @@ "description": "Yet another clock abstraction", "support": { "issues": "https://github.com/lcobucci/clock/issues", - "source": "https://github.com/lcobucci/clock/tree/3.0.0" + "source": "https://github.com/lcobucci/clock/tree/3.3.1" }, "funding": [ { @@ -4117,7 +4375,7 @@ "type": "patreon" } ], - "time": "2022-12-19T15:00:24+00:00" + "time": "2024-09-24T20:45:14+00:00" }, { "name": "lcobucci/jwt", @@ -5819,6 +6077,57 @@ }, "time": "2024-09-11T13:17:53+00:00" }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, { "name": "psy/psysh", "version": "v0.12.7", @@ -9648,188 +9957,6 @@ }, "time": "2022-02-04T12:51:07+00:00" }, - { - "name": "doctrine/common", - "version": "3.4.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "6c8fef961f67b8bc802ce3e32e3ebd1022907286" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/6c8fef961f67b8bc802ce3e32e3ebd1022907286", - "reference": "6c8fef961f67b8bc802ce3e32e3ebd1022907286", - "shasum": "" - }, - "require": { - "doctrine/persistence": "^2.0 || ^3.0", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9.0 || ^10.0", - "doctrine/collections": "^1", - "phpstan/phpstan": "^1.4.1", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", - "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^6.1", - "vimeo/psalm": "^4.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", - "homepage": "https://www.doctrine-project.org/projects/common.html", - "keywords": [ - "common", - "doctrine", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.5" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", - "type": "tidelift" - } - ], - "time": "2024-10-08T15:53:43+00:00" - }, - { - "name": "doctrine/event-manager", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/event-manager.git", - "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", - "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "conflict": { - "doctrine/common": "<2.9" - }, - "require-dev": { - "doctrine/coding-standard": "^12", - "phpstan/phpstan": "^1.8.8", - "phpunit/phpunit": "^10.5", - "vimeo/psalm": "^5.24" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", - "homepage": "https://www.doctrine-project.org/projects/event-manager.html", - "keywords": [ - "event", - "event dispatcher", - "event manager", - "event system", - "events" - ], - "support": { - "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/2.0.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", - "type": "tidelift" - } - ], - "time": "2024-05-22T20:47:39+00:00" - }, { "name": "doctrine/instantiator", "version": "2.0.0", @@ -9900,102 +10027,6 @@ ], "time": "2022-12-30T00:23:10+00:00" }, - { - "name": "doctrine/persistence", - "version": "3.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/persistence.git", - "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/0ea965320cec355dba75031c1b23d4c78362e3ff", - "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff", - "shasum": "" - }, - "require": { - "doctrine/event-manager": "^1 || ^2", - "php": "^7.2 || ^8.0", - "psr/cache": "^1.0 || ^2.0 || ^3.0" - }, - "conflict": { - "doctrine/common": "<2.10" - }, - "require-dev": { - "doctrine/coding-standard": "^12", - "doctrine/common": "^3.0", - "phpstan/phpstan": "1.12.7", - "phpstan/phpstan-phpunit": "^1", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5.38 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Persistence\\": "src/Persistence" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", - "homepage": "https://www.doctrine-project.org/projects/persistence.html", - "keywords": [ - "mapper", - "object", - "odm", - "orm", - "persistence" - ], - "support": { - "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.4.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence", - "type": "tidelift" - } - ], - "time": "2024-10-30T19:48:12+00:00" - }, { "name": "drupal/admin_toolbar", "version": "3.5.1", @@ -10188,121 +10219,6 @@ }, "time": "2024-11-21T12:39:32+00:00" }, - { - "name": "drupal/devel", - "version": "5.3.1", - "source": { - "type": "git", - "url": "https://git.drupalcode.org/project/devel.git", - "reference": "5.3.1" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/devel-5.3.1.zip", - "reference": "5.3.1", - "shasum": "6a5f13bdf93dc5f7f194b6af847589ae15e37b63" - }, - "require": { - "doctrine/common": "^2.7 || ^3.4", - "drupal/core": "^10.3 || ^11 || ^12", - "php": ">=8.1", - "symfony/var-dumper": "^4 || ^5 || ^6 || ^7" - }, - "conflict": { - "drupal/core": "<10.3", - "drush/drush": "<12.5.1", - "kint-php/kint": "<3" - }, - "require-dev": { - "drush/drush": "^13", - "firephp/firephp-core": "^0.5.3", - "kint-php/kint": "^5.1" - }, - "suggest": { - "kint-php/kint": "Kint provides an informative display of arrays/objects. Useful for debugging and developing." - }, - "type": "drupal-module", - "extra": { - "drupal": { - "version": "5.3.1", - "datestamp": "1723258446", - "security-coverage": { - "status": "covered", - "message": "Covered by Drupal's security advisory policy" - } - } - }, - "notification-url": "https://packages.drupal.org/8/downloads", - "license": [ - "GPL-2.0-or-later" - ], - "authors": [ - { - "name": "moshe weitzman", - "homepage": "https://www.drupal.org/user/23" - } - ], - "description": "Various blocks, pages, and functions for developers.", - "homepage": "https://www.drupal.org/project/devel", - "support": { - "source": "https://gitlab.com/drupalspoons/devel", - "issues": "https://gitlab.com/drupalspoons/devel/-/issues", - "slack": "https://drupal.slack.com/archives/C012WAW1MH6" - } - }, - { - "name": "drupal/devel_mail_logger", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://git.drupalcode.org/project/devel_mail_logger.git", - "reference": "2.0.0" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/devel_mail_logger-2.0.0.zip", - "reference": "2.0.0", - "shasum": "05b2879597b0b72e141f82c0836dd599ff6fef6c" - }, - "require": { - "drupal/core": "^8 || ^9 || ^10", - "php": ">=7.4" - }, - "type": "drupal-module", - "extra": { - "drupal": { - "version": "2.0.0", - "datestamp": "1685568166", - "security-coverage": { - "status": "not-covered", - "message": "Project has not opted into security advisory coverage!" - } - } - }, - "notification-url": "https://packages.drupal.org/8/downloads", - "license": [ - "GPL-2.0+" - ], - "authors": [ - { - "name": "sadashiv", - "homepage": "https://www.drupal.org/user/1773304" - }, - { - "name": "uniquename", - "homepage": "https://www.drupal.org/user/532810" - } - ], - "description": "A Custom Mail Interface that logs mail to DB", - "homepage": "https://www.drupal.org/project/devel_mail_logger", - "keywords": [ - "Drupal" - ], - "support": { - "source": "http://cgit.drupalcode.org/devel_mail_logger", - "issues": "https://www.drupal.org/project/issues/devel_mail_logger" - } - }, { "name": "drupal/mailsystem", "version": "4.5.0", @@ -13324,12 +13240,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "abbccc97f36a9c78f033525c019d310433f22b57" + "reference": "5a88337185d08d54ac102bc6eb137fc432ea70fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/abbccc97f36a9c78f033525c019d310433f22b57", - "reference": "abbccc97f36a9c78f033525c019d310433f22b57", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/5a88337185d08d54ac102bc6eb137fc432ea70fb", + "reference": "5a88337185d08d54ac102bc6eb137fc432ea70fb", "shasum": "" }, "conflict": { @@ -13879,7 +13795,7 @@ "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", "shopxo/shopxo": "<=6.1", "showdoc/showdoc": "<2.10.4", - "shuchkin/simplexlsx": ">=1.0.12,<1.1.12", + "shuchkin/simplexlsx": ">=1.0.12,<1.1.13", "silverstripe-australia/advancedreports": ">=1,<=2", "silverstripe/admin": "<1.13.19|>=2,<2.1.8", "silverstripe/assets": ">=1,<1.11.1", @@ -14169,7 +14085,7 @@ "type": "tidelift" } ], - "time": "2024-12-20T16:05:39+00:00" + "time": "2024-12-23T19:04:22+00:00" }, { "name": "sebastian/cli-parser", @@ -16277,7 +16193,7 @@ "platform": [], "platform-dev": [], "platform-overrides": { - "php": "8.1" + "php": "8.3" }, "plugin-api-version": "2.2.0" } diff --git a/config/sync/navigation.settings.yml b/config/sync/navigation.settings.yml index 3ef933aa..23eb95c0 100644 --- a/config/sync/navigation.settings.yml +++ b/config/sync/navigation.settings.yml @@ -1,6 +1,6 @@ logo: provider: custom - path: 'public://navigation-logo/logo_y.png' + path: 'assets://logo_y.png' max: filesize: 1048576 height: 40 diff --git a/web/modules/custom/academy/academy/academy.info.yml b/web/modules/custom/academy/academy/academy.info.yml index ce8e83b4..92420be7 100644 --- a/web/modules/custom/academy/academy/academy.info.yml +++ b/web/modules/custom/academy/academy/academy.info.yml @@ -1,10 +1,10 @@ name: Academy type: module description: Academy base module. -core_version_requirement: '^9.3 || ^10' -package: 'Academy' +core_version_requirement: ^10.3 || ^11 +package: Academy dependencies: - - youvo:youvo - - jsonapi_include:jsonapi_include - drupal:content_translation + - jsonapi_include:jsonapi_include + - youvo:youvo diff --git a/web/modules/custom/academy/academy/dummy/academy_dummy.info.yml b/web/modules/custom/academy/academy/dummy/academy_dummy.info.yml index a7fe5287..b8862441 100644 --- a/web/modules/custom/academy/academy/dummy/academy_dummy.info.yml +++ b/web/modules/custom/academy/academy/dummy/academy_dummy.info.yml @@ -1,9 +1,10 @@ name: Academy Dummy type: module -description: 'Generates dummy content for academy entities.' -core_version_requirement: '^9.3 || ^10' +description: Generates dummy content for academy entities. package: Academy +core_version_requirement: ^10.3 || ^11 + dependencies: - academy:academy - lectures:lectures diff --git a/web/modules/custom/academy/academy_log/academy_log.info.yml b/web/modules/custom/academy/academy_log/academy_log.info.yml index ac934d30..0d6efae9 100644 --- a/web/modules/custom/academy/academy_log/academy_log.info.yml +++ b/web/modules/custom/academy/academy_log/academy_log.info.yml @@ -1,8 +1,8 @@ name: Academy Log type: module description: Academy log module. -core_version_requirement: '^9.3 || ^10' -package: 'Academy' +core_version_requirement: ^10.3 || ^11 +package: Academy dependencies: - academy:academy diff --git a/web/modules/custom/academy/courses/courses.info.yml b/web/modules/custom/academy/courses/courses.info.yml index d05eec4a..237e43d9 100644 --- a/web/modules/custom/academy/courses/courses.info.yml +++ b/web/modules/custom/academy/courses/courses.info.yml @@ -1,7 +1,7 @@ name: Courses type: module -description: 'Provides a course entity.' -core_version_requirement: '^9.3 || ^10' +description: Provides a course entity. +core_version_requirement: ^10.3 || ^11 package: Academy dependencies: diff --git a/web/modules/custom/academy/lectures/lectures.info.yml b/web/modules/custom/academy/lectures/lectures.info.yml index ce0ae8b1..046746dc 100644 --- a/web/modules/custom/academy/lectures/lectures.info.yml +++ b/web/modules/custom/academy/lectures/lectures.info.yml @@ -1,12 +1,12 @@ name: Lectures type: module -description: 'Provides a Lecture entity.' +description: Provides a Lecture entity. package: Academy -core_version_requirement: '^10.3 || ^11' +core_version_requirement: ^10.3 || ^11 dependencies: - academy:academy - - courses:courses - child_entities:child_entities - - drupal:field (>= 8.8.0) - - drupal:text (>= 8.8.0) + - courses:courses + - drupal:field + - drupal:text diff --git a/web/modules/custom/academy/paragraphs/paragraphs.info.yml b/web/modules/custom/academy/paragraphs/paragraphs.info.yml index 4de7708d..8528ca9f 100644 --- a/web/modules/custom/academy/paragraphs/paragraphs.info.yml +++ b/web/modules/custom/academy/paragraphs/paragraphs.info.yml @@ -1,12 +1,14 @@ name: Paragraphs type: module -description: 'Provides a bundled Paragraph entity as child of Lecture entity.' -core_version_requirement: '^9.3 || ^10' +description: Provides a bundled Paragraph entity as child of Lecture entity. +core_version_requirement: ^10.3 || ^11 package: Academy + dependencies: - academy:academy - - lectures:lectures - child_entities:child_entities - - drupal:field (>= 9.3.0) - - drupal:text (>= 9.3.0) + - drupal:field + - drupal:text + - lectures:lectures + configure: entity.paragraph_type.collection diff --git a/web/modules/custom/academy/progress/progress.info.yml b/web/modules/custom/academy/progress/progress.info.yml index a02bb065..970864ba 100644 --- a/web/modules/custom/academy/progress/progress.info.yml +++ b/web/modules/custom/academy/progress/progress.info.yml @@ -1,11 +1,12 @@ name: Progress type: module -description: 'Documents the user progress in academy.' -core_version_requirement: '^9.3 || ^10' +description: Documents the user progress in academy. +core_version_requirement: ^10.3 || ^11 package: Academy + dependencies: - academy:academy - courses:courses - lectures:lectures - - questionnaire:questionnaire - paragraphs:paragraphs + - questionnaire:questionnaire diff --git a/web/modules/custom/academy/questionnaire/questionnaire.info.yml b/web/modules/custom/academy/questionnaire/questionnaire.info.yml index 62f07704..b2785ff5 100644 --- a/web/modules/custom/academy/questionnaire/questionnaire.info.yml +++ b/web/modules/custom/academy/questionnaire/questionnaire.info.yml @@ -1,10 +1,12 @@ name: Questionnaire type: module -description: 'Provides a questionnaire paragraph type and a question entity.' -core_version_requirement: '^9.3 || ^10' +description: Provides a questionnaire paragraph type and a question entity. +core_version_requirement: ^10.3 || ^11 package: Academy + dependencies: - academy:academy - paragraphs:paragraphs - drupal:text + configure: entity.question_type.collection diff --git a/web/modules/custom/child_entities/child_entities.info.yml b/web/modules/custom/child_entities/child_entities.info.yml index 2b89228d..7d8251c8 100644 --- a/web/modules/custom/child_entities/child_entities.info.yml +++ b/web/modules/custom/child_entities/child_entities.info.yml @@ -1,7 +1,7 @@ -name: 'Child Entities' +name: Child Entities type: module -description: 'Introduces Entity Trait to create child entities.' -core_version_requirement: '^9.3 || ^10' +description: Introduces Entity Trait to create child entities. +core_version_requirement: ^10.3 || ^11 package: Academy dependencies: diff --git a/web/modules/custom/interfaces/blocker_mode/blocker_mode.info.yml b/web/modules/custom/interfaces/blocker_mode/blocker_mode.info.yml index adb97112..43b09cb4 100644 --- a/web/modules/custom/interfaces/blocker_mode/blocker_mode.info.yml +++ b/web/modules/custom/interfaces/blocker_mode/blocker_mode.info.yml @@ -1,12 +1,13 @@ -name: 'Blocker Mode' -description: 'Block all incoming traffic with exceptions.' +name: Blocker Mode +type: module +description: Block all incoming traffic with exceptions. package: youvo -configure: blocker_mode.settings -type: module -core_version_requirement: '^9.3 || ^10' +core_version_requirement: ^10.3 || ^11 dependencies: - - youvo:youvo - creatives:creatives - organizations:organizations + - youvo:youvo + +configure: blocker_mode.settings diff --git a/web/modules/custom/interfaces/consumer_permissions/consumer_permissions.info.yml b/web/modules/custom/interfaces/consumer_permissions/consumer_permissions.info.yml index 61e85da7..c379a0df 100644 --- a/web/modules/custom/interfaces/consumer_permissions/consumer_permissions.info.yml +++ b/web/modules/custom/interfaces/consumer_permissions/consumer_permissions.info.yml @@ -1,8 +1,10 @@ name: Consumer Permissions +type: module description: Provides user permissions to authenticate with certain consumers. package: Authentication -type: module -core_version_requirement: ^9 || ^10 + +core_version_requirement: ^10.3 || ^11 + dependencies: - consumers:consumers - simple_oauth:simple_oauth diff --git a/web/modules/custom/interfaces/jsonapi_obscurity/jsonapi_obscurity.info.yml b/web/modules/custom/interfaces/jsonapi_obscurity/jsonapi_obscurity.info.yml index f70c39e9..63556888 100644 --- a/web/modules/custom/interfaces/jsonapi_obscurity/jsonapi_obscurity.info.yml +++ b/web/modules/custom/interfaces/jsonapi_obscurity/jsonapi_obscurity.info.yml @@ -1,7 +1,9 @@ name: JSON:API Obscurity +type: module description: Obscures JSON:API path as recommended in security considerations. package: Web services -type: module -core_version_requirement: ^9 || ^10 + +core_version_requirement: ^10.3 || ^11 + dependencies: - drupal:jsonapi diff --git a/web/modules/custom/interfaces/oauth_grant/oauth_grant.info.yml b/web/modules/custom/interfaces/oauth_grant/oauth_grant.info.yml index f6f3d42e..92c6ef24 100644 --- a/web/modules/custom/interfaces/oauth_grant/oauth_grant.info.yml +++ b/web/modules/custom/interfaces/oauth_grant/oauth_grant.info.yml @@ -1,13 +1,14 @@ -name: 'OAuth Grant' -description: 'Governs behavior for OAuth2 Authorization Code Grant.' +name: OAuth Grant +type: module +description: Governs behavior for OAuth2 Authorization Code Grant. package: Interfaces -configure: oauth_grant.settings -type: module -core_version_requirement: '^9.3 || ^10' +core_version_requirement: ^10.3 || ^11 dependencies: - - youvo:youvo - - consumers:consumers - consumer_image_styles:consumer_image_styles + - consumers:consumers - simple_oauth:simple_oauth + - youvo:youvo + +configure: oauth_grant.settings diff --git a/web/modules/custom/interfaces/oauth_grant_remote/oauth_grant_remote.info.yml b/web/modules/custom/interfaces/oauth_grant_remote/oauth_grant_remote.info.yml index 1c19ab39..0ba70509 100644 --- a/web/modules/custom/interfaces/oauth_grant_remote/oauth_grant_remote.info.yml +++ b/web/modules/custom/interfaces/oauth_grant_remote/oauth_grant_remote.info.yml @@ -1,13 +1,14 @@ -name: 'OAuth Grant Remote' -description: 'Pings the OAuth Relay for authentication.' +name: OAuth Grant Remote +type: module +description: Pings the OAuth Relay for authentication. package: Interfaces -configure: oauth_grant_remote.settings -type: module -core_version_requirement: '^9.3 || ^10' +core_version_requirement: ^10.3 || ^11 dependencies: - - youvo:youvo - consumers:consumers - - simple_oauth:simple_oauth - drupal:rest + - simple_oauth:simple_oauth + - youvo:youvo + +configure: oauth_grant_remote.settings diff --git a/web/modules/custom/interfaces/postman_interface/postman_interface.info.yml b/web/modules/custom/interfaces/postman_interface/postman_interface.info.yml index 471e88e1..a7f9fb31 100644 --- a/web/modules/custom/interfaces/postman_interface/postman_interface.info.yml +++ b/web/modules/custom/interfaces/postman_interface/postman_interface.info.yml @@ -1,16 +1,16 @@ name: Postman Interface +type: module description: Provides REST resources to exchange data with Postman. package: Interfaces -type: module -core_version_requirement: '^9.3 || ^10' +core_version_requirement: '^10.3 || ^11' dependencies: - - youvo:youvo - - projects:projects - - lifecycle:lifecycle - academy:academy - courses:courses - lectures:lectures + - lifecycle:lifecycle - paragraphs:paragraphs + - projects:projects - questionnaire:questionnaire + - youvo:youvo diff --git a/web/modules/custom/mailer/mailer.info.yml b/web/modules/custom/mailer/mailer.info.yml index 05e73a41..db03727f 100644 --- a/web/modules/custom/mailer/mailer.info.yml +++ b/web/modules/custom/mailer/mailer.info.yml @@ -2,7 +2,10 @@ name: Mailer type: module description: Administration and handling of transactional emails. package: youvo -core_version_requirement: ^9 || ^10 + +core_version_requirement: ^10.3 || ^11 + dependencies: - youvo:youvo + configure: entity.transactional_email.collection diff --git a/web/modules/custom/monitoring/logbook/logbook.info.yml b/web/modules/custom/monitoring/logbook/logbook.info.yml index c38ab809..7bf7850d 100644 --- a/web/modules/custom/monitoring/logbook/logbook.info.yml +++ b/web/modules/custom/monitoring/logbook/logbook.info.yml @@ -2,6 +2,8 @@ name: Logbook type: module description: Logbook that tracks site-wide events. package: youvo -core_version_requirement: ^9.3 || ^10 + +core_version_requirement: ^10.3 || ^11 + dependencies: - youvo:youvo diff --git a/web/modules/custom/monitoring/stats/stats.info.yml b/web/modules/custom/monitoring/stats/stats.info.yml index 9de54fac..c0d51ce9 100644 --- a/web/modules/custom/monitoring/stats/stats.info.yml +++ b/web/modules/custom/monitoring/stats/stats.info.yml @@ -2,7 +2,9 @@ name: Stats type: module description: Provides some site-wide stats. package: youvo -core_version_requirement: ^9.3 || ^10 + +core_version_requirement: ^10.3 || ^11 + dependencies: - - youvo:youvo - logbook:logbook + - youvo:youvo diff --git a/web/modules/custom/projects/feedback/feedback.info.yml b/web/modules/custom/projects/feedback/feedback.info.yml index bbc3eb33..d9b40df5 100644 --- a/web/modules/custom/projects/feedback/feedback.info.yml +++ b/web/modules/custom/projects/feedback/feedback.info.yml @@ -1,11 +1,14 @@ name: Feedback type: module -description: 'Provides a feedback entity.' +description: Provides a feedback entity. package: youvo -core_version_requirement: ^9.3 || ^10 + +core_version_requirement: ^10.3 || ^11 + dependencies: - - youvo:youvo - - projects:projects - creatives:creatives - organizations:organizations + - projects:projects + - youvo:youvo + configure: entity.feedback_type.collection diff --git a/web/modules/custom/projects/lifecycle/lifecycle.info.yml b/web/modules/custom/projects/lifecycle/lifecycle.info.yml index 6b9638d6..30ee49f4 100644 --- a/web/modules/custom/projects/lifecycle/lifecycle.info.yml +++ b/web/modules/custom/projects/lifecycle/lifecycle.info.yml @@ -1,11 +1,12 @@ name: Lifecycle type: module description: Adds a field type which can be used for storing and transitioning states according to workflows. -core_version_requirement: '^9.3 || ^10' package: Projects +core_version_requirement: ^10.3 || ^11 + dependencies: - - drupal:system (>=8.4) - drupal:options + - drupal:system - drupal:workflows - youvo:youvo diff --git a/web/modules/custom/projects/lifecycle/tests/modules/lifecycle_test_workflows/lifecycle_test_workflows.info.yml b/web/modules/custom/projects/lifecycle/tests/modules/lifecycle_test_workflows/lifecycle_test_workflows.info.yml index a6fe6a85..5faacf56 100644 --- a/web/modules/custom/projects/lifecycle/tests/modules/lifecycle_test_workflows/lifecycle_test_workflows.info.yml +++ b/web/modules/custom/projects/lifecycle/tests/modules/lifecycle_test_workflows/lifecycle_test_workflows.info.yml @@ -2,7 +2,7 @@ name: Lifecycle Test Workflows type: module description: Adds test workflows. -core_version_requirement: ^9.3 || ^10 +core_version_requirement: ^10.3 || ^11 dependencies: - lifecycle:lifecycle diff --git a/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml b/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml index 1cf1461d..7338d01d 100644 --- a/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml +++ b/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml @@ -1,14 +1,14 @@ name: 'Projects Dummy' +type: module description: 'Provides dummy project content.' package: Projects -type: module -core_version_requirement: '^9.3 || ^10' +core_version_requirement: '^10.3 || ^11' dependencies: - - drupal:file (>= 9.3.0) - - drupal:user (>= 9.3.0) - - youvo:youvo - - youvo_dummy:youvo_dummy + - drupal:file + - drupal:user - organizations_dummy:organizations_dummy - projects:projects + - youvo:youvo + - youvo_dummy:youvo_dummy diff --git a/web/modules/custom/projects/projects/projects.info.yml b/web/modules/custom/projects/projects/projects.info.yml index 6c4da9d8..72747dea 100644 --- a/web/modules/custom/projects/projects/projects.info.yml +++ b/web/modules/custom/projects/projects/projects.info.yml @@ -1,8 +1,8 @@ name: Projects +type: module description: 'Defines Project entities and handles business logic.' package: Projects -type: module core_version_requirement: '^10.3 || ^11' dependencies: diff --git a/web/modules/custom/user_types/creatives/creatives.info.yml b/web/modules/custom/user_types/creatives/creatives.info.yml index f91bdb85..7cfc3161 100644 --- a/web/modules/custom/user_types/creatives/creatives.info.yml +++ b/web/modules/custom/user_types/creatives/creatives.info.yml @@ -1,10 +1,10 @@ name: 'Creatives' +type: module description: 'Custom module which provides base framework for creatives.' package: 'youvo' -type: module -core_version_requirement: '^9.3 || ^10' +core_version_requirement: '^10.3 || ^11' dependencies: - - youvo:youvo - user_types:user_types + - youvo:youvo diff --git a/web/modules/custom/user_types/creatives/dummy/creatives_dummy.info.yml b/web/modules/custom/user_types/creatives/dummy/creatives_dummy.info.yml index 8d064c78..1d4bdcd9 100644 --- a/web/modules/custom/user_types/creatives/dummy/creatives_dummy.info.yml +++ b/web/modules/custom/user_types/creatives/dummy/creatives_dummy.info.yml @@ -1,13 +1,13 @@ -name: 'Creatives Dummy' -description: 'Custom module which provides creatives dummy content.' -package: 'youvo' - +name: Creatives Dummy type: module -core_version_requirement: '^9.3 || ^10' +description: Custom module which provides creatives dummy content. +package: youvo + +core_version_requirement: ^10.3 || ^11 dependencies: - - drupal:file (>= 9.3.0) - - drupal:user (>= 9.3.0) + - creatives:creatives + - drupal:file + - drupal:user - youvo:youvo - youvo_dummy:youvo_dummy - - creatives:creatives diff --git a/web/modules/custom/user_types/organizations/dummy/organizations_dummy.info.yml b/web/modules/custom/user_types/organizations/dummy/organizations_dummy.info.yml index 3e42a9b7..79ed733b 100644 --- a/web/modules/custom/user_types/organizations/dummy/organizations_dummy.info.yml +++ b/web/modules/custom/user_types/organizations/dummy/organizations_dummy.info.yml @@ -1,13 +1,13 @@ -name: 'Organizations Dummy' -description: 'Custom module which provides organizations dummy content.' -package: 'youvo' - +name: Organizations Dummy type: module -core_version_requirement: '^9.3 || ^10' +description: Custom module which provides organizations dummy content. +package: youvo + +core_version_requirement: ^10.3 || ^11 dependencies: - - drupal:file (>= 9.3.0) - - drupal:user (>= 9.3.0) + - drupal:file + - drupal:user + - organizations:organizations - youvo:youvo - youvo_dummy:youvo_dummy - - organizations:organizations diff --git a/web/modules/custom/user_types/organizations/organizations.info.yml b/web/modules/custom/user_types/organizations/organizations.info.yml index b09b54bb..f28e5662 100644 --- a/web/modules/custom/user_types/organizations/organizations.info.yml +++ b/web/modules/custom/user_types/organizations/organizations.info.yml @@ -1,11 +1,11 @@ name: 'Organizations' +type: module description: 'Custom module which provides base framework for organizations.' package: 'youvo' -type: module -core_version_requirement: '^9.3 || ^10' +core_version_requirement: '^10.3 || ^11' dependencies: - - youvo:youvo - - user_types:user_types - projects:projects + - user_types:user_types + - youvo:youvo diff --git a/web/modules/custom/user_types/user_types.info.yml b/web/modules/custom/user_types/user_types.info.yml index daf19bc2..f7cd18ef 100644 --- a/web/modules/custom/user_types/user_types.info.yml +++ b/web/modules/custom/user_types/user_types.info.yml @@ -1,9 +1,10 @@ -name: 'User Types' -description: 'Custom module which provides storage definitions for different user types.' -package: 'youvo' +name: User Types type: module -core_version_requirement: '^10.3 || ^11' +description: Custom module which provides storage definitions for different user types. +package: youvo + +core_version_requirement: ^10.3 || ^11 dependencies: - - youvo:youvo - simple_oauth:simple_oauth + - youvo:youvo diff --git a/web/modules/custom/youvo/dummy/youvo_dummy.info.yml b/web/modules/custom/youvo/dummy/youvo_dummy.info.yml index 681ce7b6..72740341 100644 --- a/web/modules/custom/youvo/dummy/youvo_dummy.info.yml +++ b/web/modules/custom/youvo/dummy/youvo_dummy.info.yml @@ -1,11 +1,11 @@ -name: 'Youvo Dummy' -description: 'Custom module which provides dummy content.' -package: 'youvo' - +name: Youvo Dummy type: module -core_version_requirement: '^9.3 || ^10' +description: Custom module which provides dummy content. +package: youvo + +core_version_requirement: ^10.3 || ^11 dependencies: - - drupal:file (>= 9.3.0) - - drupal:user (>= 9.3.0) + - drupal:file + - drupal:user - youvo:youvo diff --git a/web/modules/custom/youvo/youvo.info.yml b/web/modules/custom/youvo/youvo.info.yml index 8c2a6cbf..5c6e91f9 100644 --- a/web/modules/custom/youvo/youvo.info.yml +++ b/web/modules/custom/youvo/youvo.info.yml @@ -1,13 +1,14 @@ -name: 'Youvo Base' -description: 'Custom module which provides base framework for platform.' -package: 'youvo' +name: Youvo Base type: module -core_version_requirement: '^10.3 || ^11' +description: Custom module which provides base framework for platform. +package: youvo + +core_version_requirement: ^10.3 || ^11 dependencies: - - drupal:taxonomy - drupal:field - drupal:user + - drupal:taxonomy - filefield_paths:filefield_paths - jsonapi_extras:jsonapi_extras - jsonapi_include:jsonapi_include diff --git a/web/profiles/youvo_development/youvo_development.info.yml b/web/profiles/youvo_development/youvo_development.info.yml index 7d575671..f3f7c8e4 100644 --- a/web/profiles/youvo_development/youvo_development.info.yml +++ b/web/profiles/youvo_development/youvo_development.info.yml @@ -1,8 +1,8 @@ name: Youvo Development type: profile -description: 'Configuration profile for initial install of youvo adding development modules.' +description: Configuration profile for initial install of youvo adding development modules. -core_version_requirement: '^9.3 || ^10' +core_version_requirement: ^10.3 || ^11 base profile: youvo_platform diff --git a/web/profiles/youvo_platform/youvo_platform.info.yml b/web/profiles/youvo_platform/youvo_platform.info.yml index 9895025e..c5857841 100644 --- a/web/profiles/youvo_platform/youvo_platform.info.yml +++ b/web/profiles/youvo_platform/youvo_platform.info.yml @@ -1,9 +1,9 @@ name: Youvo Platform type: profile -description: 'Configuration profile for initial install of youvo.' +description: Configuration profile for initial install of youvo. +package: youvo -core_version_requirement: '^9.3 || ^10' -package: 'youvo' +core_version_requirement: ^10.3 || ^11 install: # Core diff --git a/web/sites/default/install.settings.php b/web/sites/default/install.settings.php index a18c7dfc..b41f9a1c 100644 --- a/web/sites/default/install.settings.php +++ b/web/sites/default/install.settings.php @@ -514,7 +514,7 @@ * must exist and be writable by Drupal. This directory must be relative to * the Drupal installation directory and be accessible over the web. */ -$settings['file_assets_path'] = 'files'; +$settings['file_assets_path'] = 'assets'; /** * Public file base URL: From 2138ce0052f74eb909c50665d5748a04e9b7824d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4se?= Date: Tue, 24 Dec 2024 02:03:41 +0100 Subject: [PATCH 2/5] Update to Drupal 11 with all dependencies --- .ddev/config.yaml | 2 +- .github/workflows/phpanalysis.yml | 4 +- composer-manifest.yaml | 118 +- composer.json | 28 +- composer.lock | 1919 +++++++++-------- composer.patches.json | 13 +- config/sync/core.extension.yml | 1 - config/sync/simple_oauth.settings.yml | 9 +- patches/core/3266057-110.patch | 1490 ------------- ...dify-upload-user-avatar-access-check.patch | 6 +- .../drupal-11-compatibility.patch | 13 + .../drupal-11-compatibility.patch | 24 + .../drupal-11-compatibility.patch | 23 + .../drupal-11-compatibility.patch | 114 + patches/simple_oauth/2946882-c33fa214.patch | 728 +++++++ patches/simple_oauth/3082984-d2c39a92.patch | 279 +++ patches/simple_oauth/SO52-3082984-12.patch | 420 ---- .../custom-token-revoke-profile-update.patch | 484 ----- recipes/.gitignore | 1 + .../youvo_development.info.yml | 2 - 20 files changed, 2245 insertions(+), 3433 deletions(-) delete mode 100644 patches/core/3266057-110.patch create mode 100644 patches/jsonapi_boost/drupal-11-compatibility.patch create mode 100644 patches/jsonapi_cross_bundles/drupal-11-compatibility.patch create mode 100644 patches/multivalue_form_element/drupal-11-compatibility.patch create mode 100644 patches/responsive_favicons/drupal-11-compatibility.patch create mode 100644 patches/simple_oauth/2946882-c33fa214.patch create mode 100644 patches/simple_oauth/3082984-d2c39a92.patch delete mode 100644 patches/simple_oauth/SO52-3082984-12.patch delete mode 100644 patches/simple_oauth/custom-token-revoke-profile-update.patch create mode 100644 recipes/.gitignore diff --git a/.ddev/config.yaml b/.ddev/config.yaml index 50858d85..2a64ef33 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -1,5 +1,5 @@ name: youvo -type: drupal10 +type: drupal11 docroot: web php_version: "8.3" webserver_type: nginx-fpm diff --git a/.github/workflows/phpanalysis.yml b/.github/workflows/phpanalysis.yml index 0f2a299e..47c8f6fd 100644 --- a/.github/workflows/phpanalysis.yml +++ b/.github/workflows/phpanalysis.yml @@ -51,7 +51,7 @@ jobs: id: extcache uses: shivammathur/cache-extensions@v1 with: - php-version: 8.1 + php-version: 8.3 extensions: ${{ env.extensions }} key: ${{ env.key }} @@ -65,7 +65,7 @@ jobs: - name: Set up PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.3 extensions: ${{ env.extensions }} coverage: none diff --git a/composer-manifest.yaml b/composer-manifest.yaml index a95a2bdf..f1b0e59c 100644 --- a/composer-manifest.yaml +++ b/composer-manifest.yaml @@ -3,7 +3,7 @@ packages: behat/mink: v1.12.0 behat/mink-browserkit-driver: v2.2.0 brick/math: 0.12.1 - chi-teck/drupal-code-generator: 3.6.1 + chi-teck/drupal-code-generator: 4.1.0 colinodell/psr-testlogger: v1.3.0 composer/ca-bundle: 1.5.4 composer/class-map-generator: 1.5.0 @@ -15,12 +15,11 @@ packages: composer/spdx-licenses: 1.5.8 composer/xdebug-handler: 3.0.5 consolidation/annotated-command: 4.10.1 - consolidation/config: 2.1.2 + consolidation/config: 3.1.0 consolidation/filter-via-dot-access-data: 2.0.2 consolidation/log: 3.1.0 consolidation/output-formatters: 4.6.0 - consolidation/robo: 4.0.6 - consolidation/self-update: 2.2.0 + consolidation/robo: 5.1.0 consolidation/site-alias: 4.1.1 consolidation/site-process: 5.4.2 cweagans/composer-patches: 1.7.3 @@ -28,7 +27,7 @@ packages: defuse/php-encryption: v2.4.0 dekor/php-array-table: '2.0' dflydev/dot-access-data: v3.0.3 - doctrine/annotations: 1.14.4 + doctrine/annotations: 2.0.2 doctrine/deprecations: 1.1.4 doctrine/instantiator: 2.0.0 doctrine/lexer: 2.1.1 @@ -38,12 +37,12 @@ packages: drupal/config_ignore: 3.3.0 drupal/consumer_image_styles: 4.0.10 drupal/consumers: 1.19.0 - drupal/core: 10.4.0 - drupal/core-composer-scaffold: 10.4.0 - drupal/core-dev: 10.4.0 - drupal/core-project-message: 10.4.0 - drupal/core-recommended: 10.4.0 - drupal/core-vendor-hardening: 10.4.0 + drupal/core: 11.1.0 + drupal/core-composer-scaffold: 11.1.0 + drupal/core-dev: 11.1.0 + drupal/core-project-message: 11.1.0 + drupal/core-recommended: 11.1.0 + drupal/core-vendor-hardening: 11.1.0 drupal/entity: 1.5.0 drupal/file_mdm: 3.1.0 drupal/filefield_paths: 1.0.0-beta8 @@ -66,7 +65,7 @@ packages: drupal/restui: 1.22.0 drupal/schemata: 1.0.0 drupal/schemata_json_schema: 1.0.0 - drupal/simple_oauth: 5.2.5 + drupal/simple_oauth: 6.0.0-beta8 drupal/sophron: 2.2.0 drupal/subrequests: 3.0.12 drupal/upgrade_status: 4.3.6 @@ -94,7 +93,7 @@ packages: justinrainbow/json-schema: 5.3.0 laravel/prompts: v0.1.25 lcobucci/clock: 3.3.1 - lcobucci/jwt: 4.3.0 + lcobucci/jwt: 5.4.2 league/container: 4.2.4 league/event: 2.2.0 league/oauth2-server: 8.5.5 @@ -104,6 +103,7 @@ packages: lullabot/php-webdriver: v2.0.6 masterminds/html5: 2.9.0 mck89/peast: v1.16.3 + mglaman/composer-drupal-lenient: 1.0.7 mglaman/phpstan-drupal: 1.3.2 micheh/phpcs-gitlab: 1.1.0 mikey179/vfsstream: v1.6.12 @@ -129,6 +129,7 @@ packages: php-http/guzzle7-adapter: 1.1.0 php-http/httplug: 2.4.1 php-http/promise: 1.3.1 + php-tuf/composer-stager: v2.0.0 phpcompatibility/php-compatibility: 9.3.5 phpdocumentor/reflection-common: 2.2.0 phpdocumentor/reflection-docblock: 5.6.1 @@ -141,12 +142,12 @@ packages: phpstan/phpstan: 1.12.13 phpstan/phpstan-deprecation-rules: 1.2.1 phpstan/phpstan-phpunit: 1.4.2 - phpunit/php-code-coverage: 9.2.32 - phpunit/php-file-iterator: 3.0.6 - phpunit/php-invoker: 3.1.1 - phpunit/php-text-template: 2.0.4 - phpunit/php-timer: 5.0.3 - phpunit/phpunit: 9.6.22 + phpunit/php-code-coverage: 10.1.16 + phpunit/php-file-iterator: 4.1.0 + phpunit/php-invoker: 4.0.0 + phpunit/php-text-template: 3.0.1 + phpunit/php-timer: 6.0.0 + phpunit/phpunit: 10.5.40 psr/cache: 3.0.0 psr/clock: 1.0.0 psr/container: 2.0.2 @@ -161,23 +162,23 @@ packages: ramsey/collection: 2.0.0 ramsey/uuid: 4.7.6 react/promise: v3.2.0 + revolt/event-loop: v1.0.6 roave/security-advisories: 'dev-latest:5a88337185d08d54ac102bc6eb137fc432ea70fb' - sebastian/cli-parser: 1.0.2 - sebastian/code-unit: 1.0.8 - sebastian/code-unit-reverse-lookup: 2.0.3 - sebastian/comparator: 4.0.8 - sebastian/complexity: 2.0.3 - sebastian/diff: 4.0.6 - sebastian/environment: 5.1.5 - sebastian/exporter: 4.0.6 - sebastian/global-state: 5.0.7 - sebastian/lines-of-code: 1.0.4 - sebastian/object-enumerator: 4.0.4 - sebastian/object-reflector: 2.0.4 - sebastian/recursion-context: 4.0.5 - sebastian/resource-operations: 3.0.4 - sebastian/type: 3.2.1 - sebastian/version: 3.0.2 + sebastian/cli-parser: 2.0.1 + sebastian/code-unit: 2.0.0 + sebastian/code-unit-reverse-lookup: 3.0.0 + sebastian/comparator: 5.0.3 + sebastian/complexity: 3.2.0 + sebastian/diff: 5.1.1 + sebastian/environment: 6.1.0 + sebastian/exporter: 5.1.2 + sebastian/global-state: 6.0.2 + sebastian/lines-of-code: 2.0.2 + sebastian/object-enumerator: 5.0.0 + sebastian/object-reflector: 3.0.0 + sebastian/recursion-context: 5.0.0 + sebastian/type: 4.0.0 + sebastian/version: 4.0.1 seld/jsonlint: 1.11.0 seld/phar-utils: 1.2.1 seld/signal-handler: 2.0.2 @@ -185,23 +186,22 @@ packages: slevomat/coding-standard: 8.15.0 squizlabs/php_codesniffer: 3.11.2 steverhoades/oauth2-openid-connect-server: v2.6.1 - symfony/browser-kit: v6.4.13 - symfony/console: v6.4.15 - symfony/css-selector: v6.4.13 - symfony/dependency-injection: v6.4.16 + symfony/browser-kit: v7.2.0 + symfony/console: v7.2.1 + symfony/css-selector: v7.2.0 + symfony/dependency-injection: v7.2.0 symfony/deprecation-contracts: v3.5.1 - symfony/dom-crawler: v6.4.16 - symfony/error-handler: v6.4.14 - symfony/event-dispatcher: v6.4.13 + symfony/dom-crawler: v7.2.0 + symfony/error-handler: v7.2.1 + symfony/event-dispatcher: v7.2.0 symfony/event-dispatcher-contracts: v3.5.1 - symfony/filesystem: v6.4.13 - symfony/finder: v6.4.13 - symfony/http-foundation: v6.4.16 - symfony/http-kernel: v6.4.16 - symfony/lock: v6.4.13 - symfony/mailer: v6.4.13 - symfony/mime: v6.4.13 - symfony/phpunit-bridge: v6.4.16 + symfony/filesystem: v7.2.0 + symfony/finder: v7.2.0 + symfony/http-foundation: v7.2.0 + symfony/http-kernel: v7.2.1 + symfony/lock: v7.2.0 + symfony/mailer: v7.2.0 + symfony/mime: v7.2.1 symfony/polyfill-ctype: v1.31.0 symfony/polyfill-iconv: v1.31.0 symfony/polyfill-intl-grapheme: v1.31.0 @@ -213,17 +213,17 @@ packages: symfony/polyfill-php81: v1.31.0 symfony/polyfill-php82: v1.31.0 symfony/polyfill-php83: v1.31.0 - symfony/process: v6.4.15 - symfony/psr-http-message-bridge: v6.4.13 - symfony/routing: v6.4.16 - symfony/serializer: v6.4.15 + symfony/process: v7.2.0 + symfony/psr-http-message-bridge: v7.2.0 + symfony/routing: v7.2.0 + symfony/serializer: v7.2.0 symfony/service-contracts: v3.5.1 - symfony/string: v6.4.15 + symfony/string: v7.2.0 symfony/translation-contracts: v3.5.1 - symfony/validator: v6.4.16 - symfony/var-dumper: v6.4.15 - symfony/var-exporter: v6.4.13 - symfony/yaml: v6.4.13 + symfony/validator: v7.2.0 + symfony/var-dumper: v7.2.0 + symfony/var-exporter: v7.2.0 + symfony/yaml: v7.2.0 tbachert/spi: v1.0.2 theseer/tokenizer: 1.2.3 twig/twig: v3.16.0 diff --git a/composer.json b/composer.json index 308205ac..50ba004b 100644 --- a/composer.json +++ b/composer.json @@ -19,11 +19,11 @@ "cweagans/composer-patches": "^1.7", "drupal/config_ignore": "^3.3", "drupal/consumer_image_styles": "^4.0", - "drupal/core": "^10.4", - "drupal/core-composer-scaffold": "^10.4", - "drupal/core-project-message": "^10.4", - "drupal/core-recommended": "^10.4", - "drupal/core-vendor-hardening": "^10.4", + "drupal/core": "^11.1", + "drupal/core-composer-scaffold": "^11.1", + "drupal/core-project-message": "^11.1", + "drupal/core-recommended": "^11.1", + "drupal/core-vendor-hardening": "^11.1", "drupal/entity": "^1.4", "drupal/filefield_paths": "^1.0@beta", "drupal/gin": "^4.0", @@ -36,12 +36,13 @@ "drupal/mail_login": "^4.0", "drupal/multivalue_form_element": "^1.0@beta", "drupal/responsive_favicons": "^2.0", - "drupal/simple_oauth": "^5.2", + "drupal/simple_oauth": "^6.0@beta", "drupal/subrequests": "^3.0", "drupal/upgrade_status": "^4.0", "drupal/user_bundle": "^1.2", "drush/drush": "^13.3", - "joachim-n/composer-manifest": "^1.1" + "joachim-n/composer-manifest": "^1.1", + "mglaman/composer-drupal-lenient": "^1.0" }, "conflict": { "drupal/drupal": "*" @@ -60,7 +61,8 @@ "joachim-n/composer-manifest": true, "php-http/discovery": true, "phpstan/extension-installer": true, - "tbachert/spi": true + "tbachert/spi": true, + "mglaman/composer-drupal-lenient": true }, "platform": { "php": "8.3" @@ -129,13 +131,21 @@ "enable-patching": true, "patchLevel": { "drupal/core": "-p2" + }, + "drupal-lenient": { + "allowed-list": [ + "drupal/jsonapi_boost", + "drupal/jsonapi_cross_bundles", + "drupal/multivalue_form_element", + "drupal/responsive_favicons" + ] } }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7", "drupal/admin_toolbar": "^3.3", "drupal/coder": "^8.3", - "drupal/core-dev": "^10.4", + "drupal/core-dev": "^11.1", "drupal/mailsystem": "^4.4", "drupal/openapi": "^2.1", "drupal/openapi_jsonapi": "^3.0", diff --git a/composer.lock b/composer.lock index ce652784..36fba5d9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6d3bd225c52dc5f300bab98f0ce0a5a0", + "content-hash": "e9ce34aa9689c16f177bab2cd6fe8b0d", "packages": [ { "name": "asm89/stack-cors", @@ -64,43 +64,44 @@ }, { "name": "chi-teck/drupal-code-generator", - "version": "3.6.1", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/Chi-teck/drupal-code-generator.git", - "reference": "2dbd8d231945681a398862a3282ade3cf0ea23ab" + "reference": "9a5501beb1a7aa2400afa5e5679bf21c526c497c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/2dbd8d231945681a398862a3282ade3cf0ea23ab", - "reference": "2dbd8d231945681a398862a3282ade3cf0ea23ab", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/9a5501beb1a7aa2400afa5e5679bf21c526c497c", + "reference": "9a5501beb1a7aa2400afa5e5679bf21c526c497c", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=8.1.0", + "php": ">=8.3.0", "psr/event-dispatcher": "^1.0", "psr/log": "^3.0", - "symfony/console": "^6.3", - "symfony/dependency-injection": "^6.3.2", - "symfony/filesystem": "^6.3", - "symfony/string": "^6.3", + "symfony/console": "^7.1", + "symfony/dependency-injection": "^7.1", + "symfony/filesystem": "^7.1", + "symfony/string": "^7.0", "twig/twig": "^3.4" }, "conflict": { + "nikic/php-parser": "<4.17", "squizlabs/php_codesniffer": "<3.6" }, "require-dev": { "chi-teck/drupal-coder-extension": "^2.0.0-beta3", - "drupal/coder": "8.3.23", - "drupal/core": "10.3.x-dev", + "drupal/coder": "8.3.24", + "drupal/core": "11.x-dev", "ext-simplexml": "*", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^9.6", + "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.9", - "symfony/var-dumper": "^6.4", - "symfony/yaml": "^6.3", - "vimeo/psalm": "^5.22.2" + "symfony/var-dumper": "^7.1", + "symfony/yaml": "^7.1", + "vimeo/psalm": "^5.24.0" }, "bin": [ "bin/dcg" @@ -118,9 +119,9 @@ "description": "Drupal code generator", "support": { "issues": "https://github.com/Chi-teck/drupal-code-generator/issues", - "source": "https://github.com/Chi-teck/drupal-code-generator/tree/3.6.1" + "source": "https://github.com/Chi-teck/drupal-code-generator/tree/4.1.0" }, - "time": "2024-06-06T17:36:37+00:00" + "time": "2024-10-30T18:25:43+00:00" }, { "name": "composer/installers", @@ -412,30 +413,30 @@ }, { "name": "consolidation/config", - "version": "2.1.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/consolidation/config.git", - "reference": "597f8d7fbeef801736250ec10c3e190569b1b0ae" + "reference": "0615499781449ab773ffc609b97b934b3357b3f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/config/zipball/597f8d7fbeef801736250ec10c3e190569b1b0ae", - "reference": "597f8d7fbeef801736250ec10c3e190569b1b0ae", + "url": "https://api.github.com/repos/consolidation/config/zipball/0615499781449ab773ffc609b97b934b3357b3f9", + "reference": "0615499781449ab773ffc609b97b934b3357b3f9", "shasum": "" }, "require": { - "dflydev/dot-access-data": "^1.1.0 || ^2 || ^3", - "grasmash/expander": "^2.0.1 || ^3", - "php": ">=7.1.3", - "symfony/event-dispatcher": "^4 || ^5 || ^6" + "dflydev/dot-access-data": "^3", + "grasmash/expander": "^3", + "php": ">=8.2.0", + "symfony/event-dispatcher": "^7" }, "require-dev": { "ext-json": "*", - "phpunit/phpunit": ">=7.5.20", + "phpunit/phpunit": "^9", "squizlabs/php_codesniffer": "^3", - "symfony/console": "^4 || ^5 || ^6", - "symfony/yaml": "^4 || ^5 || ^6", + "symfony/console": "^7", + "symfony/yaml": "^7", "yoast/phpunit-polyfills": "^1" }, "suggest": { @@ -466,9 +467,9 @@ "description": "Provide configuration services for a commandline tool.", "support": { "issues": "https://github.com/consolidation/config/issues", - "source": "https://github.com/consolidation/config/tree/2.1.2" + "source": "https://github.com/consolidation/config/tree/3.1.0" }, - "time": "2022-10-06T17:48:03+00:00" + "time": "2024-11-28T14:37:27+00:00" }, { "name": "consolidation/filter-via-dot-access-data", @@ -628,33 +629,32 @@ }, { "name": "consolidation/robo", - "version": "4.0.6", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/consolidation/robo.git", - "reference": "55a272370940607649e5c46eb173c5c54f7c166d" + "reference": "dde6bd88de5e1e8a7f6ed8906f80353817647ad9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/robo/zipball/55a272370940607649e5c46eb173c5c54f7c166d", - "reference": "55a272370940607649e5c46eb173c5c54f7c166d", + "url": "https://api.github.com/repos/consolidation/robo/zipball/dde6bd88de5e1e8a7f6ed8906f80353817647ad9", + "reference": "dde6bd88de5e1e8a7f6ed8906f80353817647ad9", "shasum": "" }, "require": { "consolidation/annotated-command": "^4.8.1", - "consolidation/config": "^2.0.1", - "consolidation/log": "^2.0.2 || ^3", + "consolidation/config": "^3", + "consolidation/log": "^3", "consolidation/output-formatters": "^4.1.2", - "consolidation/self-update": "^2.0", "league/container": "^3.3.1 || ^4.0", - "php": ">=8.0", + "php": ">=8.2", "phpowermove/docblock": "^4.0", - "symfony/console": "^6", - "symfony/event-dispatcher": "^6", - "symfony/filesystem": "^6", - "symfony/finder": "^6", - "symfony/process": "^6", - "symfony/yaml": "^6" + "symfony/console": "^6 || ^7", + "symfony/event-dispatcher": "^6 || ^7", + "symfony/filesystem": "^6 || ^7", + "symfony/finder": "^6 || ^7", + "symfony/process": "^6 || ^7", + "symfony/yaml": "^6 || ^7" }, "conflict": { "codegyre/robo": "*" @@ -663,11 +663,12 @@ "natxet/cssmin": "3.0.4", "patchwork/jsqueeze": "^2", "pear/archive_tar": "^1.4.4", - "phpunit/phpunit": "^7.5.20 || ^8", + "phpunit/phpunit": "^7.5.20 || ^8 || ^9", "squizlabs/php_codesniffer": "^3.6", "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { + "consolidation/self-update": "For self-updating a phar-based app built with Robo", "natxet/cssmin": "For minifying CSS files in taskMinify", "patchwork/jsqueeze": "For minifying JS files in taskMinify", "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.", @@ -695,64 +696,9 @@ "description": "Modern task runner", "support": { "issues": "https://github.com/consolidation/robo/issues", - "source": "https://github.com/consolidation/robo/tree/4.0.6" - }, - "time": "2023-04-30T21:49:04+00:00" - }, - { - "name": "consolidation/self-update", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/consolidation/self-update.git", - "reference": "972a1016761c9b63314e040836a12795dff6953a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/consolidation/self-update/zipball/972a1016761c9b63314e040836a12795dff6953a", - "reference": "972a1016761c9b63314e040836a12795dff6953a", - "shasum": "" - }, - "require": { - "composer/semver": "^3.2", - "php": ">=5.5.0", - "symfony/console": "^2.8 || ^3 || ^4 || ^5 || ^6", - "symfony/filesystem": "^2.5 || ^3 || ^4 || ^5 || ^6" - }, - "bin": [ - "scripts/release" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.x-dev" - } + "source": "https://github.com/consolidation/robo/tree/5.1.0" }, - "autoload": { - "psr-4": { - "SelfUpdate\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alexander Menk", - "email": "menk@mestrona.net" - }, - { - "name": "Greg Anderson", - "email": "greg.1.anderson@greenknowe.org" - } - ], - "description": "Provides a self:update command for Symfony Console applications.", - "support": { - "issues": "https://github.com/consolidation/self-update/issues", - "source": "https://github.com/consolidation/self-update/tree/2.2.0" - }, - "time": "2023-03-18T01:37:41+00:00" + "time": "2024-10-22T13:18:54+00:00" }, { "name": "consolidation/site-alias", @@ -1111,30 +1057,30 @@ }, { "name": "doctrine/annotations", - "version": "1.14.4", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "253dca476f70808a5aeed3a47cc2cc88c5cab915" + "reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/253dca476f70808a5aeed3a47cc2cc88c5cab915", - "reference": "253dca476f70808a5aeed3a47cc2cc88c5cab915", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/901c2ee5d26eb64ff43c47976e114bf00843acf7", + "reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7", "shasum": "" }, "require": { - "doctrine/lexer": "^1 || ^2", + "doctrine/lexer": "^2 || ^3", "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", + "php": "^7.2 || ^8.0", "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^12", - "phpstan/phpstan": "~1.4.10 || ^1.10.28", + "doctrine/cache": "^2.0", + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.10.28", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7", + "symfony/cache": "^5.4 || ^6.4 || ^7", "vimeo/psalm": "^4.30 || ^5.14" }, "suggest": { @@ -1181,9 +1127,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.14.4" + "source": "https://github.com/doctrine/annotations/tree/2.0.2" }, - "time": "2024-09-05T10:15:52+00:00" + "time": "2024-09-05T10:17:24+00:00" }, { "name": "doctrine/deprecations", @@ -1521,23 +1467,24 @@ }, { "name": "drupal/core", - "version": "10.4.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "2ac1930116a840b4fbd0ad5cdd3a6d58939a0b1d" + "reference": "0f9b2c320c20d0cbafef18764fac8e957a84071f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/2ac1930116a840b4fbd0ad5cdd3a6d58939a0b1d", - "reference": "2ac1930116a840b4fbd0ad5cdd3a6d58939a0b1d", + "url": "https://api.github.com/repos/drupal/core/zipball/0f9b2c320c20d0cbafef18764fac8e957a84071f", + "reference": "0f9b2c320c20d0cbafef18764fac8e957a84071f", "shasum": "" }, "require": { "asm89/stack-cors": "^2.1", "composer-runtime-api": "^2.1", "composer/semver": "^3.3", - "doctrine/annotations": "^1.14", + "doctrine/annotations": "^2.0", + "doctrine/lexer": "^2.0", "egulias/email-validator": "^3.2.1|^4.0", "ext-date": "*", "ext-dom": "*", @@ -1552,30 +1499,33 @@ "ext-spl": "*", "ext-tokenizer": "*", "ext-xml": "*", + "ext-zlib": "*", "guzzlehttp/guzzle": "^7.5", "guzzlehttp/psr7": "^2.4.5", "masterminds/html5": "^2.7", "mck89/peast": "^1.14", "pear/archive_tar": "^1.4.14", - "php": ">=8.1.0", + "php": ">=8.3.0", + "php-tuf/composer-stager": "^2-rc5", "psr/log": "^3.0", - "sebastian/diff": "^4", - "symfony/console": "^6.4", - "symfony/dependency-injection": "^6.4", - "symfony/event-dispatcher": "^6.4", - "symfony/filesystem": "^6.4", - "symfony/finder": "^6.4", - "symfony/http-foundation": "^6.4", - "symfony/http-kernel": "^6.4", - "symfony/mailer": "^6.4", - "symfony/mime": "^6.4", + "revolt/event-loop": "^1.0", + "sebastian/diff": "^4|^5", + "symfony/console": "^7.2", + "symfony/dependency-injection": "^7.2", + "symfony/event-dispatcher": "^7.2", + "symfony/filesystem": "^7.2", + "symfony/finder": "^7.2", + "symfony/http-foundation": "^7.2", + "symfony/http-kernel": "^7.2", + "symfony/mailer": "^7.2", + "symfony/mime": "^7.2", "symfony/polyfill-iconv": "^1.26", - "symfony/process": "^6.4", - "symfony/psr-http-message-bridge": "^2.1|^6.4", - "symfony/routing": "^6.4", - "symfony/serializer": "^6.4", - "symfony/validator": "^6.4", - "symfony/yaml": "^6.4", + "symfony/process": "^7.2", + "symfony/psr-http-message-bridge": "^7.2", + "symfony/routing": "^7.2", + "symfony/serializer": "^7.2", + "symfony/validator": "^7.2", + "symfony/yaml": "^7.2", "twig/twig": "^3.15.0" }, "conflict": { @@ -1620,7 +1570,6 @@ "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc", "[web-root]/robots.txt": "assets/scaffold/files/robots.txt", "[web-root]/update.php": "assets/scaffold/files/update.php", - "[web-root]/web.config": "assets/scaffold/files/web.config", "[web-root]/INSTALL.txt": "assets/scaffold/files/drupal.INSTALL.txt", "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore", "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json", @@ -1632,6 +1581,7 @@ "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes", "[web-root]/modules/README.txt": "assets/scaffold/files/modules.README.txt", "[web-root]/profiles/README.txt": "assets/scaffold/files/profiles.README.txt", + "[project-root]/recipes/README.txt": "assets/scaffold/files/recipes.README.txt", "[web-root]/sites/example.sites.php": "assets/scaffold/files/example.sites.php", "[web-root]/sites/development.services.yml": "assets/scaffold/files/development.services.yml", "[web-root]/sites/example.settings.local.php": "assets/scaffold/files/example.settings.local.php", @@ -1679,22 +1629,22 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/10.4.0" + "source": "https://github.com/drupal/core/tree/11.1.0" }, - "time": "2024-12-17T22:18:01+00:00" + "time": "2024-12-13T22:30:22+00:00" }, { "name": "drupal/core-composer-scaffold", - "version": "10.4.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/drupal/core-composer-scaffold.git", - "reference": "db17b59620ce1c142a34dc017d9e696ce4771e55" + "reference": "30e2dce1d08858236ae2703c0a72d120d8075bc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/db17b59620ce1c142a34dc017d9e696ce4771e55", - "reference": "db17b59620ce1c142a34dc017d9e696ce4771e55", + "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/30e2dce1d08858236ae2703c0a72d120d8075bc5", + "reference": "30e2dce1d08858236ae2703c0a72d120d8075bc5", "shasum": "" }, "require": { @@ -1729,13 +1679,13 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-composer-scaffold/tree/10.4.0" + "source": "https://github.com/drupal/core-composer-scaffold/tree/11.1.0" }, - "time": "2024-08-22T14:31:30+00:00" + "time": "2024-11-02T22:49:15+00:00" }, { "name": "drupal/core-project-message", - "version": "10.4.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/drupal/core-project-message.git", @@ -1776,25 +1726,25 @@ }, { "name": "drupal/core-recommended", - "version": "10.4.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "4c2f51834d9b74e2db66f61868ac174ee9d672a8" + "reference": "b4ee05b115b4c74ff1417e3ed0a49b78158db444" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/4c2f51834d9b74e2db66f61868ac174ee9d672a8", - "reference": "4c2f51834d9b74e2db66f61868ac174ee9d672a8", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/b4ee05b115b4c74ff1417e3ed0a49b78158db444", + "reference": "b4ee05b115b4c74ff1417e3ed0a49b78158db444", "shasum": "" }, "require": { "asm89/stack-cors": "~v2.2.0", "composer/semver": "~3.4.3", - "doctrine/annotations": "~1.14.4", + "doctrine/annotations": "~2.0.2", "doctrine/deprecations": "~1.1.3", "doctrine/lexer": "~2.1.1", - "drupal/core": "10.4.0", + "drupal/core": "11.1.0", "egulias/email-validator": "~4.0.2", "guzzlehttp/guzzle": "~7.9.2", "guzzlehttp/promises": "~2.0.4", @@ -1805,6 +1755,7 @@ "pear/console_getopt": "~v1.4.3", "pear/pear-core-minimal": "~v1.10.16", "pear/pear_exception": "~v1.0.2", + "php-tuf/composer-stager": "~v2.0.0-rc6", "psr/cache": "~3.0.0", "psr/container": "~2.0.2", "psr/event-dispatcher": "~1.0.0", @@ -1812,37 +1763,37 @@ "psr/http-factory": "~1.1.0", "psr/log": "~3.0.2", "ralouphie/getallheaders": "~3.0.3", - "sebastian/diff": "~4.0.6", - "symfony/console": "~v6.4.15", - "symfony/dependency-injection": "~v6.4.16", + "revolt/event-loop": "~v1.0.6", + "sebastian/diff": "~5.1.1", + "symfony/console": "~v7.2.0", + "symfony/dependency-injection": "~v7.2.0", "symfony/deprecation-contracts": "~v3.5.1", - "symfony/error-handler": "~v6.4.14", - "symfony/event-dispatcher": "~v6.4.13", + "symfony/error-handler": "~v7.2.0", + "symfony/event-dispatcher": "~v7.2.0", "symfony/event-dispatcher-contracts": "~v3.5.1", - "symfony/filesystem": "~v6.4.13", - "symfony/finder": "~v6.4.13", - "symfony/http-foundation": "~v6.4.16", - "symfony/http-kernel": "~v6.4.16", - "symfony/mailer": "~v6.4.13", - "symfony/mime": "~v6.4.13", + "symfony/filesystem": "~v7.2.0", + "symfony/finder": "~v7.2.0", + "symfony/http-foundation": "~v7.2.0", + "symfony/http-kernel": "~v7.2.0", + "symfony/mailer": "~v7.2.0", + "symfony/mime": "~v7.2.0", "symfony/polyfill-ctype": "~v1.31.0", "symfony/polyfill-iconv": "~v1.31.0", "symfony/polyfill-intl-grapheme": "~v1.31.0", "symfony/polyfill-intl-idn": "~v1.31.0", "symfony/polyfill-intl-normalizer": "~v1.31.0", "symfony/polyfill-mbstring": "~v1.31.0", - "symfony/polyfill-php83": "~v1.31.0", - "symfony/process": "~v6.4.15", - "symfony/psr-http-message-bridge": "~v6.4.13", - "symfony/routing": "~v6.4.16", - "symfony/serializer": "~v6.4.15", + "symfony/process": "~v7.2.0", + "symfony/psr-http-message-bridge": "~v7.2.0", + "symfony/routing": "~v7.2.0", + "symfony/serializer": "~v7.2.0", "symfony/service-contracts": "~v3.5.1", - "symfony/string": "~v6.4.15", + "symfony/string": "~v7.2.0", "symfony/translation-contracts": "~v3.5.1", - "symfony/validator": "~v6.4.16", - "symfony/var-dumper": "~v6.4.15", - "symfony/var-exporter": "~v6.4.13", - "symfony/yaml": "~v6.4.13", + "symfony/validator": "~v7.2.0", + "symfony/var-dumper": "~v7.2.0", + "symfony/var-exporter": "~v7.2.0", + "symfony/yaml": "~v7.2.0", "twig/twig": "~v3.16.0" }, "conflict": { @@ -1855,22 +1806,22 @@ ], "description": "Core and its dependencies with known-compatible minor versions. Require this project INSTEAD OF drupal/core.", "support": { - "source": "https://github.com/drupal/core-recommended/tree/10.4.0" + "source": "https://github.com/drupal/core-recommended/tree/11.1.0" }, - "time": "2024-12-17T22:18:01+00:00" + "time": "2024-12-13T22:30:22+00:00" }, { "name": "drupal/core-vendor-hardening", - "version": "10.4.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/drupal/core-vendor-hardening.git", - "reference": "82bb33f8da23130afa412e239c72ce70a8dba690" + "reference": "8fe818ea278f5ff612ad079bf134a6a02790f7a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-vendor-hardening/zipball/82bb33f8da23130afa412e239c72ce70a8dba690", - "reference": "82bb33f8da23130afa412e239c72ce70a8dba690", + "url": "https://api.github.com/repos/drupal/core-vendor-hardening/zipball/8fe818ea278f5ff612ad079bf134a6a02790f7a3", + "reference": "8fe818ea278f5ff612ad079bf134a6a02790f7a3", "shasum": "" }, "require": { @@ -1896,9 +1847,9 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-vendor-hardening/tree/10.4.0" + "source": "https://github.com/drupal/core-vendor-hardening/tree/11.1.0" }, - "time": "2024-11-11T20:22:36+00:00" + "time": "2024-11-11T18:39:05+00:00" }, { "name": "drupal/entity", @@ -2368,7 +2319,7 @@ "shasum": "7a884a31cc71d3dd60f6222e7427be34847a1456" }, "require": { - "drupal/core": "^9 || ^10", + "drupal/core": "^8 || ^9 || ^10 || ^11 || ^12", "drupal/jsonapi_extras": "*", "drupal/warmer": "*" }, @@ -2414,7 +2365,7 @@ "shasum": "25728babff93f1a44fbee832f4c69d23f7a06685" }, "require": { - "drupal/core": "^8.7.7 || ^9 || ^10" + "drupal/core": "^8 || ^9 || ^10 || ^11 || ^12" }, "require-dev": { "drupal/jsonapi_extras": "^3" @@ -2652,7 +2603,7 @@ "shasum": "653214124be45f11bb76c76871355a30651dd6fe" }, "require": { - "drupal/core": "^9.3 || ^10", + "drupal/core": "^8 || ^9 || ^10 || ^11 || ^12", "php": ">=7.4" }, "type": "drupal-module", @@ -2706,7 +2657,7 @@ "shasum": "d42db3b36422cdd915f03089900b4a2408535a80" }, "require": { - "drupal/core": "^9.3 || ^10" + "drupal/core": "^8 || ^9 || ^10 || ^11 || ^12" }, "type": "drupal-module", "extra": { @@ -2747,42 +2698,37 @@ }, { "name": "drupal/simple_oauth", - "version": "5.2.5", + "version": "6.0.0-beta8", "source": { "type": "git", "url": "https://git.drupalcode.org/project/simple_oauth.git", - "reference": "5.2.5" + "reference": "6.0.0-beta8" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/simple_oauth-5.2.5.zip", - "reference": "5.2.5", - "shasum": "3517d07e4896a32eddda7446b85a2afa945321a2" + "url": "https://ftp.drupal.org/files/projects/simple_oauth-6.0.0-beta8.zip", + "reference": "6.0.0-beta8", + "shasum": "5629128e55b4834c169f3c4a18b30aa9b48b49fc" }, "require": { - "drupal/consumers": "^1.14", - "drupal/core": "^9 || ^10", - "lcobucci/jwt": "^4", - "league/oauth2-server": "^8.3", - "php": ">=7.4", - "steverhoades/oauth2-openid-connect-server": "^2.4" + "drupal/consumers": "^1.17", + "drupal/core": "^10.2 || ^11", + "league/oauth2-server": "^8.5 || ^9.0", + "php": ">=8.1", + "steverhoades/oauth2-openid-connect-server": "^2.6" }, "require-dev": { + "drupal/simple_oauth_static_scope": "*", "phpspec/prophecy-phpunit": "^2" }, "type": "drupal-module", "extra": { "drupal": { - "version": "5.2.5", - "datestamp": "1700206902", + "version": "6.0.0-beta8", + "datestamp": "1734959037", "security-coverage": { - "status": "covered", - "message": "Covered by Drupal's security advisory policy" - } - }, - "drush": { - "services": { - "drush.services.yml": "^9 || ^10 || ^11" + "status": "not-covered", + "message": "Beta releases are not covered by Drupal security advisories." } } }, @@ -2792,8 +2738,9 @@ ], "authors": [ { - "name": "bojan_dev", - "homepage": "https://www.drupal.org/user/2801849" + "name": "Mateu Aguiló Bosch", + "homepage": "https://www.drupal.org/user/2801849", + "email": "mateu.aguilo.bosch@gmail.com" }, { "name": "bradjones1", @@ -4379,39 +4326,38 @@ }, { "name": "lcobucci/jwt", - "version": "4.3.0", + "version": "5.4.2", "source": { "type": "git", "url": "https://github.com/lcobucci/jwt.git", - "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4" + "reference": "ea1ce71cbf9741e445a5914e2f67cdbb484ff712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/4d7de2fe0d51a96418c0d04004986e410e87f6b4", - "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/ea1ce71cbf9741e445a5914e2f67cdbb484ff712", + "reference": "ea1ce71cbf9741e445a5914e2f67cdbb484ff712", "shasum": "" }, "require": { - "ext-hash": "*", - "ext-json": "*", - "ext-mbstring": "*", "ext-openssl": "*", "ext-sodium": "*", - "lcobucci/clock": "^2.0 || ^3.0", - "php": "^7.4 || ^8.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "psr/clock": "^1.0" }, "require-dev": { - "infection/infection": "^0.21", - "lcobucci/coding-standard": "^6.0", - "mikey179/vfsstream": "^1.6.7", + "infection/infection": "^0.29", + "lcobucci/clock": "^3.2", + "lcobucci/coding-standard": "^11.0", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/php-invoker": "^3.1", - "phpunit/phpunit": "^9.5" + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.7", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^11.1" + }, + "suggest": { + "lcobucci/clock": ">= 3.2" }, "type": "library", "autoload": { @@ -4437,7 +4383,7 @@ ], "support": { "issues": "https://github.com/lcobucci/jwt/issues", - "source": "https://github.com/lcobucci/jwt/tree/4.3.0" + "source": "https://github.com/lcobucci/jwt/tree/5.4.2" }, "funding": [ { @@ -4449,7 +4395,7 @@ "type": "patreon" } ], - "time": "2023-01-02T13:28:00+00:00" + "time": "2024-11-07T12:54:35+00:00" }, { "name": "league/container", @@ -4965,6 +4911,64 @@ }, "time": "2024-07-23T14:00:32+00:00" }, + { + "name": "mglaman/composer-drupal-lenient", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/mglaman/composer-drupal-lenient.git", + "reference": "bcb9be7f2d3160be43cd1d13a44580734a5afee0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mglaman/composer-drupal-lenient/zipball/bcb9be7f2d3160be43cd1d13a44580734a5afee0", + "reference": "bcb9be7f2d3160be43cd1d13a44580734a5afee0", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": ">=8.1" + }, + "require-dev": { + "composer/composer": "^2.3", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.2", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "composer-plugin", + "extra": { + "class": "ComposerDrupalLenient\\Plugin" + }, + "autoload": { + "psr-4": { + "ComposerDrupalLenient\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Matt Glaman", + "email": "nmd.matt@gmail.com" + } + ], + "support": { + "issues": "https://github.com/mglaman/composer-drupal-lenient/issues", + "source": "https://github.com/mglaman/composer-drupal-lenient/tree/1.0.7" + }, + "funding": [ + { + "url": "https://github.com/mglaman", + "type": "github" + } + ], + "time": "2024-11-21T15:59:26+00:00" + }, { "name": "mglaman/phpstan-drupal", "version": "1.3.2", @@ -5510,6 +5514,79 @@ }, "time": "2024-10-03T13:43:19+00:00" }, + { + "name": "php-tuf/composer-stager", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-tuf/composer-stager.git", + "reference": "abaf3e26110199d999e5bf8f6086ddeeef011c22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-tuf/composer-stager/zipball/abaf3e26110199d999e5bf8f6086ddeeef011c22", + "reference": "abaf3e26110199d999e5bf8f6086ddeeef011c22", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=8.1.0", + "symfony/filesystem": "^6.2 || ^7.0", + "symfony/process": "^6.4.14 || ^7.1.7", + "symfony/translation-contracts": "^3.1" + }, + "conflict": { + "symfony/process": ">=6 <6.4.14 || >=7 <7.1.7", + "symfony/symfony": ">=6 <6.4.14 || >=7 <7.1.7" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ext-simplexml": "*", + "phpspec/prophecy": "^1.17", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5.19", + "slevomat/coding-standard": "^8.13", + "squizlabs/php_codesniffer": "^3.7", + "symfony/config": "^6.3", + "symfony/dependency-injection": "^6.3", + "symfony/yaml": "^6.3", + "thecodingmachine/phpstan-strict-rules": "^1.0" + }, + "suggest": { + "symfony/dependency-injection": "For dependency injection", + "symfony/translation": "For internationalization tools" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpTuf\\ComposerStager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Travis Carden", + "email": "travis.carden@gmail.com", + "role": "Developer" + } + ], + "description": "Stages Composer commands so they can be safely run on a production codebase.", + "homepage": "https://github.com/php-tuf/composer-stager", + "support": { + "issues": "https://github.com/php-tuf/composer-stager/issues", + "source": "https://github.com/php-tuf/composer-stager" + }, + "time": "2024-12-16T11:15:45+00:00" + }, { "name": "phpowermove/docblock", "version": "v4.0", @@ -6251,31 +6328,103 @@ }, "time": "2019-03-08T08:55:37+00:00" }, + { + "name": "revolt/event-loop", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/revoltphp/event-loop.git", + "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/25de49af7223ba039f64da4ae9a28ec2d10d0254", + "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Revolt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Rock-solid event loop for concurrent PHP applications.", + "keywords": [ + "async", + "asynchronous", + "concurrency", + "event", + "event-loop", + "non-blocking", + "scheduler" + ], + "support": { + "issues": "https://github.com/revoltphp/event-loop/issues", + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.6" + }, + "time": "2023-11-30T05:34:44+00:00" + }, { "name": "sebastian/diff", - "version": "4.0.6", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -6307,7 +6456,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -6315,7 +6465,7 @@ "type": "github" } ], - "time": "2024-03-02T06:30:58+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "steverhoades/oauth2-openid-connect-server", @@ -6364,47 +6514,46 @@ }, { "name": "symfony/console", - "version": "v6.4.15", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd" + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", - "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" + "symfony/string": "^6.4|^7.0" }, "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6438,7 +6587,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.15" + "source": "https://github.com/symfony/console/tree/v7.2.1" }, "funding": [ { @@ -6454,44 +6603,43 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:19:14+00:00" + "time": "2024-12-11T03:49:26+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.16", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "7a379d8871f6a36f01559c14e11141cc02eb8dc8" + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7a379d8871f6a36f01559c14e11141cc02eb8dc8", - "reference": "7a379d8871f6a36f01559c14e11141cc02eb8dc8", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a475747af1a1c98272a5471abc35f3da81197c5d", + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/container": "^1.1|^2.0", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/service-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.2.10|^7.0" + "symfony/service-contracts": "^3.5", + "symfony/var-exporter": "^6.4|^7.0" }, "conflict": { "ext-psr": "<1.1|>=2", - "symfony/config": "<6.1", - "symfony/finder": "<5.4", - "symfony/proxy-manager-bridge": "<6.3", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { "psr/container-implementation": "1.1|2.0", "symfony/service-implementation": "1.1|2.0|3.0" }, "require-dev": { - "symfony/config": "^6.1|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/config": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6519,7 +6667,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.16" + "source": "https://github.com/symfony/dependency-injection/tree/v7.2.0" }, "funding": [ { @@ -6535,7 +6683,7 @@ "type": "tidelift" } ], - "time": "2024-11-25T14:52:46+00:00" + "time": "2024-11-25T15:45:00+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6606,22 +6754,22 @@ }, { "name": "symfony/error-handler", - "version": "v6.4.14", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "9e024324511eeb00983ee76b9aedc3e6ecd993d9" + "reference": "6150b89186573046167796fa5f3f76601d5145f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/9e024324511eeb00983ee76b9aedc3e6ecd993d9", - "reference": "9e024324511eeb00983ee76b9aedc3e6ecd993d9", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/6150b89186573046167796fa5f3f76601d5145f8", + "reference": "6150b89186573046167796fa5f3f76601d5145f8", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/var-dumper": "^6.4|^7.0" }, "conflict": { "symfony/deprecation-contracts": "<2.5", @@ -6630,7 +6778,7 @@ "require-dev": { "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^5.4|^6.0|^7.0" + "symfony/serializer": "^6.4|^7.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -6661,7 +6809,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.14" + "source": "https://github.com/symfony/error-handler/tree/v7.2.1" }, "funding": [ { @@ -6677,28 +6825,28 @@ "type": "tidelift" } ], - "time": "2024-11-05T15:34:40+00:00" + "time": "2024-12-07T08:50:44+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e" + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", - "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4", + "symfony/dependency-injection": "<6.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -6707,13 +6855,13 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0|^7.0" + "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6741,7 +6889,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.13" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" }, "funding": [ { @@ -6757,7 +6905,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -6837,25 +6985,25 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3" + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/4856c9cf585d5a0313d8d35afd681a526f038dd3", - "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^5.4|^6.4|^7.0" + "symfony/process": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6883,7 +7031,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.13" + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" }, "funding": [ { @@ -6899,27 +7047,27 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/finder", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "daea9eca0b08d0ed1dc9ab702a46128fd1be4958" + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/daea9eca0b08d0ed1dc9ab702a46128fd1be4958", - "reference": "daea9eca0b08d0ed1dc9ab702a46128fd1be4958", + "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.0|^7.0" + "symfony/filesystem": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6947,7 +7095,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.13" + "source": "https://github.com/symfony/finder/tree/v7.2.0" }, "funding": [ { @@ -6963,40 +7111,41 @@ "type": "tidelift" } ], - "time": "2024-10-01T08:30:56+00:00" + "time": "2024-10-23T06:56:12+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.4.16", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57" + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/431771b7a6f662f1575b3cfc8fd7617aa9864d57", - "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e88a66c3997859532bc2ddd6dd8f35aba2711744", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php83": "^1.27" }, "conflict": { + "doctrine/dbal": "<3.6", "symfony/cache": "<6.4.12|>=7.0,<7.1.5" }, "require-dev": { - "doctrine/dbal": "^2.13.1|^3|^4", + "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", "symfony/cache": "^6.4.12|^7.1.5", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/rate-limiter": "^5.4|^6.0|^7.0" + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7024,7 +7173,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.16" + "source": "https://github.com/symfony/http-foundation/tree/v7.2.0" }, "funding": [ { @@ -7040,77 +7189,77 @@ "type": "tidelift" } ], - "time": "2024-11-13T18:58:10+00:00" + "time": "2024-11-13T18:58:46+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.16", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0" + "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", - "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d8ae58eecae44c8e66833e76cc50a4ad3c002d97", + "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/browser-kit": "<5.4", - "symfony/cache": "<5.4", - "symfony/config": "<6.1", - "symfony/console": "<5.4", + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", "symfony/dependency-injection": "<6.4", - "symfony/doctrine-bridge": "<5.4", - "symfony/form": "<5.4", - "symfony/http-client": "<5.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<5.4", - "symfony/messenger": "<5.4", - "symfony/translation": "<5.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<5.4", + "symfony/twig-bridge": "<6.4", "symfony/validator": "<6.4", - "symfony/var-dumper": "<6.3", - "twig/twig": "<2.13" + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0|^7.0", - "symfony/clock": "^6.2|^7.0", - "symfony/config": "^6.1|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", - "symfony/dom-crawler": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/property-access": "^5.4.5|^6.0.5|^7.0", - "symfony/routing": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.4.4|^7.0.4", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^7.1", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", - "symfony/var-dumper": "^5.4|^6.4|^7.0", - "symfony/var-exporter": "^6.2|^7.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.12" }, "type": "library", "autoload": { @@ -7138,7 +7287,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.16" + "source": "https://github.com/symfony/http-kernel/tree/v7.2.1" }, "funding": [ { @@ -7154,43 +7303,43 @@ "type": "tidelift" } ], - "time": "2024-11-27T12:49:36+00:00" + "time": "2024-12-11T12:09:10+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "c2f7e0d8d7ac8fe25faccf5d8cac462805db2663" + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/c2f7e0d8d7ac8fe25faccf5d8cac462805db2663", - "reference": "c2f7e0d8d7ac8fe25faccf5d8cac462805db2663", + "url": "https://api.github.com/repos/symfony/mailer/zipball/e4d358702fb66e4c8a2af08e90e7271a62de39cc", + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc", "shasum": "" }, "require": { "egulias/email-validator": "^2.1.10|^3|^4", - "php": ">=8.1", + "php": ">=8.2", "psr/event-dispatcher": "^1", "psr/log": "^1|^2|^3", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/mime": "^6.2|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^7.2", "symfony/service-contracts": "^2.5|^3" }, "conflict": { "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<5.4", - "symfony/messenger": "<6.2", - "symfony/mime": "<6.2", - "symfony/twig-bridge": "<6.2.1" + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/messenger": "^6.2|^7.0", - "symfony/twig-bridge": "^6.2|^7.0" + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7218,7 +7367,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.13" + "source": "https://github.com/symfony/mailer/tree/v7.2.0" }, "funding": [ { @@ -7234,25 +7383,24 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-11-25T15:21:05+00:00" }, { "name": "symfony/mime", - "version": "v6.4.13", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "1de1cf14d99b12c7ebbb850491ec6ae3ed468855" + "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/1de1cf14d99b12c7ebbb850491ec6ae3ed468855", - "reference": "1de1cf14d99b12c7ebbb850491ec6ae3ed468855", + "url": "https://api.github.com/repos/symfony/mime/zipball/7f9617fcf15cb61be30f8b252695ed5e2bfac283", + "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, @@ -7260,17 +7408,17 @@ "egulias/email-validator": "~3.0.0", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<5.4", + "symfony/mailer": "<6.4", "symfony/serializer": "<6.4.3|>7.0,<7.0.3" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.4|^7.0", - "symfony/property-access": "^5.4|^6.0|^7.0", - "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", "symfony/serializer": "^6.4.3|^7.0.3" }, "type": "library", @@ -7303,7 +7451,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.13" + "source": "https://github.com/symfony/mime/tree/v7.2.1" }, "funding": [ { @@ -7319,7 +7467,7 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-12-07T08:50:44+00:00" }, { "name": "symfony/polyfill-ctype", @@ -7956,20 +8104,20 @@ }, { "name": "symfony/process", - "version": "v6.4.15", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "3cb242f059c14ae08591c5c4087d1fe443564392" + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/3cb242f059c14ae08591c5c4087d1fe443564392", - "reference": "3cb242f059c14ae08591c5c4087d1fe443564392", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -7997,7 +8145,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.15" + "source": "https://github.com/symfony/process/tree/v7.2.0" }, "funding": [ { @@ -8013,40 +8161,40 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:19:14+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "c9cf83326a1074f83a738fc5320945abf7fb7fec" + "reference": "03f2f72319e7acaf2a9f6fcbe30ef17eec51594f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/c9cf83326a1074f83a738fc5320945abf7fb7fec", - "reference": "c9cf83326a1074f83a738fc5320945abf7fb7fec", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/03f2f72319e7acaf2a9f6fcbe30ef17eec51594f", + "reference": "03f2f72319e7acaf2a9f6fcbe30ef17eec51594f", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/http-message": "^1.0|^2.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0" + "symfony/http-foundation": "^6.4|^7.0" }, "conflict": { "php-http/discovery": "<1.15", - "symfony/http-kernel": "<6.2" + "symfony/http-kernel": "<6.4" }, "require-dev": { "nyholm/psr7": "^1.1", "php-http/discovery": "^1.15", "psr/log": "^1.1.4|^2|^3", - "symfony/browser-kit": "^5.4|^6.0|^7.0", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/framework-bundle": "^6.2|^7.0", - "symfony/http-kernel": "^6.2|^7.0" + "symfony/browser-kit": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" }, "type": "symfony-bridge", "autoload": { @@ -8080,7 +8228,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v6.4.13" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.2.0" }, "funding": [ { @@ -8096,40 +8244,38 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-09-26T08:57:56+00:00" }, { "name": "symfony/routing", - "version": "v6.4.16", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220" + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/91e02e606b4b705c2f4fb42f7e7708b7923a3220", - "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220", + "url": "https://api.github.com/repos/symfony/routing/zipball/e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { - "doctrine/annotations": "<1.12", - "symfony/config": "<6.2", - "symfony/dependency-injection": "<5.4", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.12|^2", "psr/log": "^1|^2|^3", - "symfony/config": "^6.2|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8163,7 +8309,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.16" + "source": "https://github.com/symfony/routing/tree/v7.2.0" }, "funding": [ { @@ -8179,61 +8325,61 @@ "type": "tidelift" } ], - "time": "2024-11-13T15:31:34+00:00" + "time": "2024-11-25T11:08:51+00:00" }, { "name": "symfony/serializer", - "version": "v6.4.15", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "9d862d66198f3c2e30404228629ef4c18d5d608e" + "reference": "3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/9d862d66198f3c2e30404228629ef4c18d5d608e", - "reference": "9d862d66198f3c2e30404228629ef4c18d5d608e", + "url": "https://api.github.com/repos/symfony/serializer/zipball/3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0", + "reference": "3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/dependency-injection": "<5.4", - "symfony/property-access": "<5.4", - "symfony/property-info": "<5.4.24|>=6,<6.2.11", - "symfony/uid": "<5.4", + "symfony/dependency-injection": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/uid": "<6.4", "symfony/validator": "<6.4", - "symfony/yaml": "<5.4" + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.12|^2", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", "seld/jsonlint": "^1.10", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/filesystem": "^5.4|^6.0|^7.0", - "symfony/form": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/property-access": "^5.4.26|^6.3|^7.0", - "symfony/property-info": "^5.4.24|^6.2.11|^7.0", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^7.2", + "symfony/error-handler": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0", - "symfony/var-exporter": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8261,7 +8407,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.4.15" + "source": "https://github.com/symfony/serializer/tree/v7.2.0" }, "funding": [ { @@ -8277,7 +8423,7 @@ "type": "tidelift" } ], - "time": "2024-10-23T13:25:59+00:00" + "time": "2024-11-25T15:21:05+00:00" }, { "name": "symfony/service-contracts", @@ -8364,20 +8510,20 @@ }, { "name": "symfony/string", - "version": "v6.4.15", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -8387,11 +8533,12 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0|^7.0" + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8430,7 +8577,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.15" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -8446,7 +8593,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:12+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/translation-contracts", @@ -8528,20 +8675,20 @@ }, { "name": "symfony/validator", - "version": "v6.4.16", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "9b0d1988b56511706bc91d96ead39acd77aaf34d" + "reference": "ddad20aa8cf7a45a9d6300e5776b8d252dc3524b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/9b0d1988b56511706bc91d96ead39acd77aaf34d", - "reference": "9b0d1988b56511706bc91d96ead39acd77aaf34d", + "url": "https://api.github.com/repos/symfony/validator/zipball/ddad20aa8cf7a45a9d6300e5776b8d252dc3524b", + "reference": "ddad20aa8cf7a45a9d6300e5776b8d252dc3524b", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", @@ -8549,34 +8696,34 @@ "symfony/translation-contracts": "^2.5|^3" }, "conflict": { - "doctrine/annotations": "<1.13", "doctrine/lexer": "<1.1", - "symfony/dependency-injection": "<5.4", - "symfony/expression-language": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/intl": "<5.4", - "symfony/property-info": "<5.4", - "symfony/translation": "<5.4.35|>=6.0,<6.3.12|>=6.4,<6.4.3|>=7.0,<7.0.3", - "symfony/yaml": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<7.0", + "symfony/expression-language": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/intl": "<6.4", + "symfony/property-info": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.13|^2", "egulias/email-validator": "^2.1.10|^3|^4", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/intl": "^5.4|^6.0|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/property-access": "^5.4|^6.0|^7.0", - "symfony/property-info": "^5.4|^6.0|^7.0", - "symfony/translation": "^5.4.35|~6.3.12|^6.4.3|^7.0.3", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/type-info": "^7.1", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8605,7 +8752,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.4.16" + "source": "https://github.com/symfony/validator/tree/v7.2.0" }, "funding": [ { @@ -8621,38 +8768,36 @@ "type": "tidelift" } ], - "time": "2024-11-27T09:48:51+00:00" + "time": "2024-11-27T09:50:52+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.15", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80" + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", - "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^6.3|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/uid": "^5.4|^6.0|^7.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.12" }, "bin": [ "Resources/bin/var-dump-server" @@ -8690,7 +8835,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.15" + "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" }, "funding": [ { @@ -8706,30 +8851,29 @@ "type": "tidelift" } ], - "time": "2024-11-08T15:28:48+00:00" + "time": "2024-11-08T15:48:14+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "0f605f72a363f8743001038a176eeb2a11223b51" + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0f605f72a363f8743001038a176eeb2a11223b51", - "reference": "0f605f72a363f8743001038a176eeb2a11223b51", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=8.2" }, "require-dev": { "symfony/property-access": "^6.4|^7.0", "symfony/serializer": "^6.4|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8767,7 +8911,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.13" + "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" }, "funding": [ { @@ -8783,32 +8927,32 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-10-18T07:58:17+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9" + "reference": "099581e99f557e9f16b43c5916c26380b54abb22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", - "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^6.4|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -8839,7 +8983,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.13" + "source": "https://github.com/symfony/yaml/tree/v7.2.0" }, "funding": [ { @@ -8855,7 +8999,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-10-23T06:56:12+00:00" }, { "name": "twig/twig", @@ -10165,16 +10309,16 @@ }, { "name": "drupal/core-dev", - "version": "10.4.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/drupal/core-dev.git", - "reference": "9c6c089f73671083d9588affa287a59a80e6edc8" + "reference": "87b1646fe04f10112cb836e83f8b5594fb02e273" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-dev/zipball/9c6c089f73671083d9588affa287a59a80e6edc8", - "reference": "9c6c089f73671083d9588affa287a59a80e6edc8", + "url": "https://api.github.com/repos/drupal/core-dev/zipball/87b1646fe04f10112cb836e83f8b5594fb02e273", + "reference": "87b1646fe04f10112cb836e83f8b5594fb02e273", "shasum": "" }, "require": { @@ -10184,9 +10328,9 @@ "composer/composer": "^2.8.1", "drupal/coder": "^8.3.10", "justinrainbow/json-schema": "^5.2", - "lullabot/mink-selenium2-driver": "^1.7", - "lullabot/php-webdriver": "^2.0.4", - "mglaman/phpstan-drupal": "^1.2.12", + "lullabot/mink-selenium2-driver": "^1.7.3", + "lullabot/php-webdriver": "^2.0.5", + "mglaman/phpstan-drupal": "^1.2.11", "micheh/phpcs-gitlab": "^1.1", "mikey179/vfsstream": "^1.6.11", "open-telemetry/exporter-otlp": "^1", @@ -10196,14 +10340,13 @@ "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.12.4", "phpstan/phpstan-phpunit": "^1.3.16", - "phpunit/phpunit": "^9.6.13", - "symfony/browser-kit": "^6.4", - "symfony/css-selector": "^6.4", - "symfony/dom-crawler": "^6.4", - "symfony/error-handler": "^6.4", - "symfony/lock": "^6.4", - "symfony/phpunit-bridge": "^6.4", - "symfony/var-dumper": "^6.4" + "phpunit/phpunit": "^10.5.19", + "symfony/browser-kit": "^7.2", + "symfony/css-selector": "^7.2", + "symfony/dom-crawler": "^7.2", + "symfony/error-handler": "^7.2", + "symfony/lock": "^7.2", + "symfony/var-dumper": "^7.2" }, "conflict": { "webflo/drupal-core-require-dev": "*" @@ -10215,9 +10358,9 @@ ], "description": "require-dev dependencies from drupal/drupal; use in addition to drupal/core-recommended to run tests from drupal/core.", "support": { - "source": "https://github.com/drupal/core-dev/tree/10.4.0" + "source": "https://github.com/drupal/core-dev/tree/11.1.0" }, - "time": "2024-11-21T12:39:32+00:00" + "time": "2024-12-09T12:29:59+00:00" }, { "name": "drupal/mailsystem", @@ -12560,16 +12703,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.32", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { @@ -12577,18 +12720,18 @@ "ext-libxml": "*", "ext-xmlwriter": "*", "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-text-template": "^2.0.4", - "sebastian/code-unit-reverse-lookup": "^2.0.3", - "sebastian/complexity": "^2.0.3", - "sebastian/environment": "^5.1.5", - "sebastian/lines-of-code": "^1.0.4", - "sebastian/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.6" + "phpunit/phpunit": "^10.1" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -12597,7 +12740,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "9.2.x-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -12626,7 +12769,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -12634,32 +12777,32 @@ "type": "github" } ], - "time": "2024-08-22T04:23:01+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -12686,7 +12829,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -12694,28 +12838,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -12723,7 +12867,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -12749,7 +12893,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -12757,32 +12901,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -12808,7 +12952,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -12816,32 +12961,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -12867,7 +13012,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -12875,24 +13020,23 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "9.6.22", + "version": "10.5.40", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c" + "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f80235cb4d3caa59ae09be3adf1ded27521d1a9c", - "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6ddda95af52f69c1e0c7b4f977cccb58048798c", + "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -12902,27 +13046,26 @@ "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.32", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.4", - "phpunit/php-timer": "^5.0.3", - "sebastian/cli-parser": "^1.0.2", - "sebastian/code-unit": "^1.0.8", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.6", - "sebastian/environment": "^5.1.5", - "sebastian/exporter": "^4.0.6", - "sebastian/global-state": "^5.0.7", - "sebastian/object-enumerator": "^4.0.4", - "sebastian/resource-operations": "^3.0.4", - "sebastian/type": "^3.2.1", - "sebastian/version": "^3.0.2" + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.3", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.2", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.0", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -12930,7 +13073,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.6-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -12962,7 +13105,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.22" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.40" }, "funding": [ { @@ -12978,7 +13121,7 @@ "type": "tidelift" } ], - "time": "2024-12-05T13:48:26+00:00" + "time": "2024-12-21T05:49:06+00:00" }, { "name": "ramsey/collection", @@ -14089,28 +14232,28 @@ }, { "name": "sebastian/cli-parser", - "version": "1.0.2", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -14133,7 +14276,8 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" }, "funding": [ { @@ -14141,32 +14285,32 @@ "type": "github" } ], - "time": "2024-03-02T06:27:43+00:00" + "time": "2024-03-02T07:12:49+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -14189,7 +14333,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" }, "funding": [ { @@ -14197,32 +14341,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2023-02-03T06:58:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -14244,7 +14388,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -14252,34 +14396,36 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -14318,7 +14464,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -14326,33 +14473,33 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.3", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -14375,7 +14522,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -14383,27 +14531,27 @@ "type": "github" } ], - "time": "2023-12-22T06:19:30+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/environment", - "version": "5.1.5", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -14411,7 +14559,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -14430,7 +14578,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -14438,7 +14586,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -14446,34 +14595,34 @@ "type": "github" } ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.6", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -14515,7 +14664,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" }, "funding": [ { @@ -14523,38 +14673,35 @@ "type": "github" } ], - "time": "2024-03-02T06:33:00+00:00" + "time": "2024-03-02T07:17:12+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.7", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -14573,13 +14720,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" }, "funding": [ { @@ -14587,33 +14735,33 @@ "type": "github" } ], - "time": "2024-03-02T06:35:11+00:00" + "time": "2024-03-02T07:19:19+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.4", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -14636,7 +14784,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -14644,34 +14793,34 @@ "type": "github" } ], - "time": "2023-12-22T06:20:34+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -14693,7 +14842,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -14701,32 +14850,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -14748,7 +14897,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -14756,32 +14905,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.5", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -14811,61 +14960,7 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:07:39+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -14873,32 +14968,32 @@ "type": "github" } ], - "time": "2024-03-14T16:00:52+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "3.2.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -14921,7 +15016,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -14929,29 +15024,29 @@ "type": "github" } ], - "time": "2023-02-03T06:13:03+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -14974,7 +15069,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -14982,7 +15077,7 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "seld/jsonlint", @@ -15362,27 +15457,27 @@ }, { "name": "symfony/browser-kit", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "65d4b3fd9556e4b5b41287bef93c671f8f9f86ab" + "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/65d4b3fd9556e4b5b41287bef93c671f8f9f86ab", - "reference": "65d4b3fd9556e4b5b41287bef93c671f8f9f86ab", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/8d64d17e198082f8f198d023a6b634e7b5fdda94", + "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/dom-crawler": "^5.4|^6.0|^7.0" + "php": ">=8.2", + "symfony/dom-crawler": "^6.4|^7.0" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0" + "symfony/css-selector": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -15410,7 +15505,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/v6.4.13" + "source": "https://github.com/symfony/browser-kit/tree/v7.2.0" }, "funding": [ { @@ -15426,24 +15521,24 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/css-selector", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "cb23e97813c5837a041b73a6d63a9ddff0778f5e" + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/cb23e97813c5837a041b73a6d63a9ddff0778f5e", - "reference": "cb23e97813c5837a041b73a6d63a9ddff0778f5e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -15475,7 +15570,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.4.13" + "source": "https://github.com/symfony/css-selector/tree/v7.2.0" }, "funding": [ { @@ -15491,30 +15586,30 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.4.16", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "4304e6ad5c894a9c72831ad459f627bfd35d766d" + "reference": "b176e1f1f550ef44c94eb971bf92488de08f7c6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4304e6ad5c894a9c72831ad459f627bfd35d766d", - "reference": "4304e6ad5c894a9c72831ad459f627bfd35d766d", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b176e1f1f550ef44c94eb971bf92488de08f7c6b", + "reference": "b176e1f1f550ef44c94eb971bf92488de08f7c6b", "shasum": "" }, "require": { "masterminds/html5": "^2.6", - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0|^7.0" + "symfony/css-selector": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -15542,7 +15637,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.4.16" + "source": "https://github.com/symfony/dom-crawler/tree/v7.2.0" }, "funding": [ { @@ -15558,33 +15653,32 @@ "type": "tidelift" } ], - "time": "2024-11-13T15:06:22+00:00" + "time": "2024-11-13T16:15:23+00:00" }, { "name": "symfony/lock", - "version": "v6.4.13", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "a69c3dd151ab7e14925f119164cfdf65d55392a4" + "reference": "07212a5994a30e3667e95e5b16b2dda0685aff84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/a69c3dd151ab7e14925f119164cfdf65d55392a4", - "reference": "a69c3dd151ab7e14925f119164cfdf65d55392a4", + "url": "https://api.github.com/repos/symfony/lock/zipball/07212a5994a30e3667e95e5b16b2dda0685aff84", + "reference": "07212a5994a30e3667e95e5b16b2dda0685aff84", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=8.2", + "psr/log": "^1|^2|^3" }, "conflict": { - "doctrine/dbal": "<2.13", - "symfony/cache": "<6.2" + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4" }, "require-dev": { - "doctrine/dbal": "^2.13|^3|^4", + "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0" }, "type": "library", @@ -15621,89 +15715,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v6.4.13" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-10-25T15:19:46+00:00" - }, - { - "name": "symfony/phpunit-bridge", - "version": "v6.4.16", - "source": { - "type": "git", - "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "cebafe2f1ad2d1e745c1015b7c2519592341e4e6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/cebafe2f1ad2d1e745c1015b7c2519592341e4e6", - "reference": "cebafe2f1ad2d1e745c1015b7c2519592341e4e6", - "shasum": "" - }, - "require": { - "php": ">=7.1.3" - }, - "conflict": { - "phpunit/phpunit": "<7.5|9.1.2" - }, - "require-dev": { - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/polyfill-php81": "^1.27" - }, - "bin": [ - "bin/simple-phpunit" - ], - "type": "symfony-bridge", - "extra": { - "thanks": { - "url": "https://github.com/sebastianbergmann/phpunit", - "name": "phpunit/phpunit" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Bridge\\PhpUnit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/", - "/bin/" - ] - }, - "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": "Provides utilities for PHPUnit, especially user deprecation notices management", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.16" + "source": "https://github.com/symfony/lock/tree/v7.2.0" }, "funding": [ { @@ -15719,7 +15731,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T15:06:22+00:00" + "time": "2024-10-25T15:34:29+00:00" }, { "name": "symfony/polyfill-php73", @@ -16184,6 +16196,7 @@ "stability-flags": { "drupal/filefield_paths": 10, "drupal/multivalue_form_element": 10, + "drupal/simple_oauth": 10, "drupal/openapi_ui": 5, "drupal/openapi_ui_redoc": 5, "roave/security-advisories": 20 diff --git a/composer.patches.json b/composer.patches.json index 68741d01..0e42e42a 100644 --- a/composer.patches.json +++ b/composer.patches.json @@ -1,10 +1,9 @@ { "patches": { "drupal/core": { - "Issue #3266057: Introduce base profiles": "patches/core/3266057-110.patch", "Issue #2924549: Invoke hook after a site install is complete": "patches/core/2924549-65.patch", - "Issue #3181946: ReplicaKillSwitch unnecessarily starts a session on each request": "patches/core/3181946-29.patch", "Issue #3098935: JSON:API can't handle exceptions thrown during authentication": "patches/core/3098935-16.patch", + "Issue #3181946: ReplicaKillSwitch unnecessarily starts a session on each request": "patches/core/3181946-29.patch", "Custom: Change file upload route for jsonapi extras": "patches/core/custom-change-file-upload-route-for-jsonapi-extras.patch", "Custom: Modify upload user avatar access check": "patches/core/custom-modify-upload-user-avatar-access-check.patch", "Custom: Jsonapi Upload route is recognized as jsonapi request": "patches/core/custom-file-upload-route-is-jsonapi-request.patch", @@ -15,10 +14,12 @@ "Custom: Exclude consumer entity type from filefield_paths handling": "patches/filefield_paths/custom-exclude-consumer-entity-type.patch" }, "drupal/jsonapi_boost": { + "Issue #3431472: Drupal 11 Compatibility": "patches/jsonapi_boost/drupal-11-compatibility.patch", "Custom: Add account switcher to JSON:API warming": "patches/jsonapi_boost/custom-add-account-switcher-to-jsonapi-boost-warming.patch" }, "drupal/jsonapi_cross_bundles": { "Issue #3070430: Incompatible with JSON:API Extras": "patches/jsonapi_cross_bundles/3070430-incompatible-with-jsonapi-extras.patch", + "Issue #3451983: Drupal 11 Compatibility": "patches/jsonapi_cross_bundles/drupal-11-compatibility.patch", "Custom: Exclude users from cross bundles resources": "patches/jsonapi_cross_bundles/custom-exclude-users-from-cross-bundle-resources.patch", "Custom: Plural resource paths": "patches/jsonapi_cross_bundles/custom-plural-resource-paths.patch" }, @@ -30,15 +31,17 @@ "Custom: Improve typing": "patches/jsonapi_include/custom-improve-typing.patch" }, "drupal/multivalue_form_element": { + "Issue #3433537: Drupal 11 Compatibility": "patches/multivalue_form_element/drupal-11-compatibility.patch", "Custom: Limit validation error for type form element in AJAX callback": "patches/multivalue_form_element/custom-limit-validation-error-for-type.patch", "Custom: Modify input for checkbox in multivalue form element to correctly retain values after reordering": "patches/multivalue_form_element/custom-populate-checkbox-input.patch" }, "drupal/responsive_favicons": { - "Issue #3382829: Split Icon links in their own meta tag definition": "patches/responsive_favicons/3382839-9.patch" + "Issue #3382829: Split Icon links in their own meta tag definition": "patches/responsive_favicons/3382839-9.patch", + "Issue #3434213: Drupal 11 Compatibility": "patches/responsive_favicons/drupal-11-compatibility.patch" }, "drupal/simple_oauth": { - "Custom: Token revoke on profile update": "patches/simple_oauth/custom-token-revoke-profile-update.patch", - "Issue #3082984: Reduce logging severity/don't log expired tokens/401s": "patches/simple_oauth/SO52-3082984-12.patch" + "Issue #3082984: Reduce logging severity/don't log expired tokens/401s": "patches/simple_oauth/3082984-d2c39a92.patch", + "Issue #2946882: Auth revoke on profile update": "patches/simple_oauth/2946882-c33fa214.patch" }, "drupal/warmer": { "Custom: Add items list to queue command": "patches/warmer/custom-add-items-limit-to-queue-command.patch" diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 00872150..72959b81 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -87,7 +87,6 @@ module: warmer: 0 workflows: 0 youvo: 0 - youvo_platform: 0 youvo_dummy: 1 creatives_dummy: 2 academy_dummy: 3 diff --git a/config/sync/simple_oauth.settings.yml b/config/sync/simple_oauth.settings.yml index cef6642c..f10d6438 100644 --- a/config/sync/simple_oauth.settings.yml +++ b/config/sync/simple_oauth.settings.yml @@ -1,11 +1,12 @@ _core: default_config_hash: KsPFWSp6mgXIQgjBJEShfKUGn6VLRlbpIJ2EysXvXWM -access_token_expiration: 3600 -authorization_code_expiration: 120 -refresh_token_expiration: 1209600 +scope_provider: dynamic token_cron_batch_size: 0 public_key: '' private_key: '' +disable_openid_connect: true +access_token_expiration: 3600 +authorization_code_expiration: 120 +refresh_token_expiration: 1209600 remember_clients: true use_implicit: false -disable_openid_connect: true diff --git a/patches/core/3266057-110.patch b/patches/core/3266057-110.patch deleted file mode 100644 index de332d58..00000000 --- a/patches/core/3266057-110.patch +++ /dev/null @@ -1,1490 +0,0 @@ -diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc -index 00eadeb5..4b0ac355 100644 ---- a/core/includes/install.core.inc -+++ b/core/includes/install.core.inc -@@ -468,6 +468,12 @@ function install_begin_request($class_loader, &$install_state) { - if (isset($install_state['profile_info']['distribution']['install']['theme'])) { - $install_state['theme'] = $install_state['profile_info']['distribution']['install']['theme']; - } -+ // Ensure all profile directories are registered. -+ $profiles = \Drupal::service('extension.list.profile')->getAncestors($profile); -+ $profile_directories = array_map(function ($extension) { -+ return $extension->getPath(); -+ }, $profiles); -+ $listing->setProfileDirectories($profile_directories); - } - - // Before having installed the system module and being able to do a module -@@ -864,15 +870,17 @@ function install_tasks($install_state) { - - // Now add any tasks defined by the installation profile. - if (!empty($install_state['parameters']['profile'])) { -- // Load the profile install file, because it is not always loaded when -- // hook_install_tasks() is invoked (e.g. batch processing). -- $profile = $install_state['parameters']['profile']; -- if ($profile !== FALSE) { -- $profile_install_file = $install_state['profiles'][$profile]->getPath() . '/' . $profile . '.install'; -+ $profiles = \Drupal::service('extension.list.profile')->getAncestors($install_state['parameters']['profile']); -+ foreach (array_keys($profiles) as $profile_name) { -+ $profile = $install_state['profiles'][$profile_name]; -+ // Load the profile install file, because it is not always loaded when -+ // hook_install_tasks() is invoked (e.g. batch processing). -+ $profile_install_file = $profile->getPath() . '/' . $profile_name . '.install'; - if (file_exists($profile_install_file)) { - include_once \Drupal::root() . '/' . $profile_install_file; - } -- $function = $install_state['parameters']['profile'] . '_install_tasks'; -+ // If this is a base profile then the profile isn't loaded -+ $function = $profile_name . '_install_tasks'; - if (function_exists($function)) { - $result = $function($install_state); - if (is_array($result)) { -@@ -895,11 +903,13 @@ function install_tasks($install_state) { - - // Allow the installation profile to modify the full list of tasks. - if (!empty($install_state['parameters']['profile'])) { -- $profile = $install_state['parameters']['profile']; -- if ($install_state['profiles'][$profile]->load()) { -- $function = $install_state['parameters']['profile'] . '_install_tasks_alter'; -- if (function_exists($function)) { -- $function($tasks, $install_state); -+ $profiles = \Drupal::service('extension.list.profile')->getAncestors($install_state['parameters']['profile']); -+ foreach (array_keys($profiles) as $profile_name) { -+ if ($install_state['profiles'][$profile_name]->load()) { -+ $function = $profile_name . '_install_tasks_alter'; -+ if (function_exists($function)) { -+ $function($tasks, $install_state); -+ } - } - } - } -@@ -1281,7 +1291,9 @@ function install_select_profile(&$install_state) { - * - For interactive installations via request query parameters. - * - For non-interactive installations via install_drupal() settings. - * - One of the available profiles is a distribution. If multiple profiles are -- * distributions, then the first discovered profile will be selected. -+ * distributions, then the first discovered profile will be selected. If an -+ * inherited profile is detected that is a distribution, it will be chosen -+ * over its base profile. - * - Only one visible profile is available. - * - * @param array $install_state -@@ -1306,12 +1318,9 @@ function _install_select_profile(&$install_state) { - return $profile; - } - } -- // If any of the profiles are distribution profiles, return the first one. -- foreach ($install_state['profiles'] as $profile) { -- $profile_info = install_profile_info($profile->getName()); -- if (!empty($profile_info['distribution'])) { -- return $profile->getName(); -- } -+ // Check for a distribution profile. -+ if ($distribution = \Drupal::service('extension.list.profile')->selectDistribution(array_keys($install_state['profiles']))) { -+ return $distribution; - } - // Get all visible (not hidden) profiles. - $visible_profiles = array_filter($install_state['profiles'], function ($profile) { -@@ -1541,7 +1550,9 @@ function _install_get_version_info($version) { - function install_load_profile(&$install_state) { - $profile = $install_state['parameters']['profile']; - if ($profile !== FALSE) { -- $install_state['profiles'][$profile]->load(); -+ foreach (array_keys(\Drupal::service('extension.list.profile')->getAncestors($profile)) as $profile_id) { -+ $install_state['profiles'][$profile_id]->load(); -+ } - $install_state['profile_info'] = install_profile_info($profile, $install_state['parameters']['langcode'] ?? 'en'); - } - -@@ -1674,7 +1685,10 @@ function install_install_profile(&$install_state) { - // any disparities that this creates. - \Drupal::service('config.installer')->installOptionalConfig(); - -- \Drupal::service('module_installer')->install([$install_state['parameters']['profile']], FALSE); -+ // Install all the profiles. -+ $profiles = \Drupal::service('extension.list.profile') -+ ->getAncestors($install_state['parameters']['profile']); -+ \Drupal::service('module_installer')->install(array_keys($profiles), FALSE); - - // Ensure that the install profile's theme is used. - // @see _drupal_maintenance_theme() -diff --git a/core/includes/install.inc b/core/includes/install.inc -index 3391fb99..791ddc7f 100644 ---- a/core/includes/install.inc -+++ b/core/includes/install.inc -@@ -450,10 +450,6 @@ function _drupal_rewrite_settings_dump_one(\stdClass $variable, $prefix = '', $s - * about profiles. - */ - function drupal_verify_profile($install_state) { -- $profile = $install_state['parameters']['profile']; -- if ($profile === FALSE) { -- return []; -- } - $info = $install_state['profile_info']; - - // Get the list of available modules for the selected installation profile. -@@ -462,10 +458,11 @@ function drupal_verify_profile($install_state) { - foreach ($listing->scan('module') as $present_module) { - $present_modules[] = $present_module->getName(); - } -- -- // The installation profile is also a module, which needs to be installed -- // after all the other dependencies have been installed. -- $present_modules[] = $profile; -+ // Get the list of available profiles, which may be used as base profiles or -+ // ancestors of the selected installation profile. -+ foreach ($listing->scan('profile') as $present_profile) { -+ $present_modules[] = $present_profile->getName(); -+ } - - // Verify that all of the profile's required modules are present. - $missing_modules = array_diff($info['install'], $present_modules); -@@ -1012,6 +1009,9 @@ function drupal_check_module($module) { - * Drupal's default installer theme. - * - finish_url: A destination to visit after the installation of the - * distribution is finished -+ * - base profile: The shortname of the base installation profile. Existence of -+ * this key denotes that the installation profile depends on a parent -+ * installation profile. - * - * Note that this function does an expensive file system scan to get info file - * information for dependencies. If you only need information from the info -@@ -1039,22 +1039,9 @@ function install_profile_info($profile, $langcode = 'en') { - static $cache = []; - - if (!isset($cache[$profile][$langcode])) { -- // Set defaults for module info. -- $defaults = [ -- 'dependencies' => [], -- 'install' => [], -- 'themes' => ['stark'], -- 'description' => '', -- 'version' => NULL, -- 'hidden' => FALSE, -- 'php' => \Drupal::MINIMUM_PHP, -- 'config_install_path' => NULL, -- ]; - $profile_path = \Drupal::service('extension.list.profile')->getPath($profile); -- /** @var \Drupal\Core\Extension\InfoParserInterface $parser */ -- $parser = \Drupal::service('info_parser'); -- $info = $parser->parse("$profile_path/$profile.info.yml"); -- $info += $defaults; -+ $info = \Drupal::service('extension.list.profile')->getExtensionInfo($profile); -+ $ancestors = \Drupal::service('extension.list.profile')->getAncestors($profile); - - $dependency_name_function = function ($dependency) { - return Dependency::createFromString($dependency)->getName(); -@@ -1065,6 +1052,8 @@ function install_profile_info($profile, $langcode = 'en') { - // Convert install key in [project:module] format. - $info['install'] = array_map($dependency_name_function, $info['install']); - -+ /** @var \Drupal\Core\Extension\InfoParserInterface $parser */ -+ $parser = \Drupal::service('info_parser'); - // Get a list of core's required modules. - $required = []; - $listing = new ExtensionDiscovery(\Drupal::root()); -@@ -1082,6 +1071,9 @@ function install_profile_info($profile, $langcode = 'en') { - // remove any duplicates. - $info['install'] = array_unique(array_merge($info['install'], $required, $info['dependencies'], $locale)); - -+ // Remove the base profiles from the install list. -+ $info['install'] = array_diff($info['install'], array_keys($ancestors)); -+ - // If the profile has a config/sync directory use that to install drupal. - if (is_dir($profile_path . '/config/sync')) { - $info['config_install_path'] = $profile_path . '/config/sync'; -diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php -index 9b985573..e26351ac 100644 ---- a/core/lib/Drupal/Core/Config/ConfigInstaller.php -+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php -@@ -5,6 +5,7 @@ - use Drupal\Component\Utility\Crypt; - use Drupal\Component\Utility\NestedArray; - use Drupal\Core\Config\Entity\ConfigDependencyManager; -+use Drupal\Core\Extension\ProfileExtensionList; - use Drupal\Core\Extension\ExtensionPathResolver; - use Drupal\Core\Installer\InstallerKernel; - use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; -@@ -53,6 +54,13 @@ class ConfigInstaller implements ConfigInstallerInterface { - */ - protected $sourceStorage; - -+ /** -+ * The profile list. -+ * -+ * @var \Drupal\Core\Extension\ProfileExtensionList -+ */ -+ protected $profileList; -+ - /** - * Is configuration being created as part of a configuration sync. - * -@@ -91,8 +99,10 @@ class ConfigInstaller implements ConfigInstallerInterface { - * The name of the currently active installation profile. - * @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver - * The extension path resolver. -+ * @param \Drupal\Core\Extension\ProfileExtensionList|null $profile_list -+ * (optional) The profile list. - */ -- public function __construct(ConfigFactoryInterface $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, ConfigManagerInterface $config_manager, EventDispatcherInterface $event_dispatcher, $install_profile, ExtensionPathResolver $extension_path_resolver) { -+ public function __construct(ConfigFactoryInterface $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, ConfigManagerInterface $config_manager, EventDispatcherInterface $event_dispatcher, $install_profile, ExtensionPathResolver $extension_path_resolver, ProfileExtensionList $profile_list = NULL) { - $this->configFactory = $config_factory; - $this->activeStorages[$active_storage->getCollectionName()] = $active_storage; - $this->typedConfig = $typed_config; -@@ -100,6 +110,7 @@ public function __construct(ConfigFactoryInterface $config_factory, StorageInter - $this->eventDispatcher = $event_dispatcher; - $this->installProfile = $install_profile; - $this->extensionPathResolver = $extension_path_resolver; -+ $this->profileList = $profile_list ?: \Drupal::service('extension.list.profile'); - } - - /** -@@ -529,7 +540,8 @@ public function checkConfigurationToInstall($type, $name) { - - // Install profiles can not have config clashes. Configuration that - // has the same name as a module's configuration will be used instead. -- if ($name != $this->drupalGetProfile()) { -+ $profiles = $this->profileList->getAncestors($this->installProfile); -+ if (!isset($profiles[$name])) { - // Throw an exception if the module being installed contains configuration - // that already exists. Additionally, can not continue installing more - // modules because those may depend on the current module being installed. -diff --git a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php -index e48b255e..8517d122 100644 ---- a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php -+++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php -@@ -3,6 +3,7 @@ - namespace Drupal\Core\Config; - - use Drupal\Core\Extension\ExtensionDiscovery; -+use Drupal\Core\Extension\ProfileExtensionList; - - /** - * Storage to access configuration and schema in enabled extensions. -@@ -50,9 +51,11 @@ class ExtensionInstallStorage extends InstallStorage { - * search and to get overrides from. - * @param string $profile - * The current installation profile. -+ * @param \Drupal\Core\Extension\ProfileExtensionList $profile_list -+ * The list of install profiles. - */ -- public function __construct(StorageInterface $config_storage, $directory, $collection, $include_profile, $profile) { -- parent::__construct($directory, $collection); -+ public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, $include_profile = TRUE, $profile = NULL, ProfileExtensionList $profile_list = NULL) { -+ parent::__construct($directory, $collection, $profile_list); - $this->configStorage = $config_storage; - $this->includeProfile = $include_profile; - $this->installProfile = $profile; -@@ -86,26 +89,13 @@ public function createCollection($collection) { - protected function getAllFolders() { - if (!isset($this->folders)) { - $this->folders = []; -- $this->folders += $this->getCoreNames(); -+ $this->folders = $this->getCoreNames() + $this->folders; - - $extensions = $this->configStorage->read('core.extension'); - // @todo Remove this scan as part of https://www.drupal.org/node/2186491 -- $listing = new ExtensionDiscovery(\Drupal::root()); -+ $listing = new ExtensionDiscovery(\Drupal::root(), TRUE, NULL, NULL, $this->profileList); - if (!empty($extensions['module'])) { - $modules = $extensions['module']; -- // Remove the install profile as this is handled later. -- unset($modules[$this->installProfile]); -- $profile_list = $listing->scan('profile'); -- if ($this->installProfile && isset($profile_list[$this->installProfile])) { -- // Prime the \Drupal\Core\Extension\ExtensionList::getPathname() -- // static cache with the profile info file location so we can use -- // ExtensionList::getPath() on the active profile during the module -- // scan. -- // @todo Remove as part of https://www.drupal.org/node/2186491 -- /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list */ -- $profile_extension_list = \Drupal::service('extension.list.profile'); -- $profile_extension_list->setPathname($this->installProfile, $profile_list[$this->installProfile]->getPathname()); -- } - $module_list_scan = $listing->scan('module'); - $module_list = []; - foreach (array_keys($modules) as $module) { -@@ -113,7 +103,7 @@ protected function getAllFolders() { - $module_list[$module] = $module_list_scan[$module]; - } - } -- $this->folders += $this->getComponentNames($module_list); -+ $this->folders = $this->getComponentNames($module_list) + $this->folders; - } - if (!empty($extensions['theme'])) { - $theme_list_scan = $listing->scan('theme'); -@@ -122,22 +112,16 @@ protected function getAllFolders() { - $theme_list[$theme] = $theme_list_scan[$theme]; - } - } -- $this->folders += $this->getComponentNames($theme_list); -+ $this->folders = $this->getComponentNames($theme_list) + $this->folders; - } - - if ($this->includeProfile) { -- // The install profile can override module default configuration. We do -- // this by replacing the config file path from the module/theme with the -- // install profile version if there are any duplicates. -- if ($this->installProfile) { -- if (!isset($profile_list)) { -- $profile_list = $listing->scan('profile'); -- } -- if (isset($profile_list[$this->installProfile])) { -- $profile_folders = $this->getComponentNames([$profile_list[$this->installProfile]]); -- $this->folders = $profile_folders + $this->folders; -- } -- } -+ // The install profile (and any parent profiles) can override module -+ // default configuration. We do this by replacing the config file path -+ // from the module/theme with the install profile version if there are -+ // any duplicates. -+ // @todo Remove as part of https://www.drupal.org/node/2186491 -+ $this->folders = $this->getComponentNames($this->profileList->getAncestors($this->installProfile)) + $this->folders; - } - } - return $this->folders; -diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php -index 136be5d6..181c62c2 100644 ---- a/core/lib/Drupal/Core/Config/InstallStorage.php -+++ b/core/lib/Drupal/Core/Config/InstallStorage.php -@@ -4,6 +4,7 @@ - - use Drupal\Core\Extension\ExtensionDiscovery; - use Drupal\Core\Extension\Extension; -+use Drupal\Core\Extension\ProfileExtensionList; - - /** - * Storage used by the Drupal installer. -@@ -47,6 +48,13 @@ class InstallStorage extends FileStorage { - */ - protected $directory; - -+ /** -+ * The profile list, used to find additional folders to scan for config. -+ * -+ * @var \Drupal\Core\Extension\ProfileExtensionList -+ */ -+ protected $profileList; -+ - /** - * Constructs an InstallStorage object. - * -@@ -56,9 +64,14 @@ class InstallStorage extends FileStorage { - * @param string $collection - * (optional) The collection to store configuration in. Defaults to the - * default collection. -+ * @param \Drupal\Core\Extension\ProfileExtensionList $profile_list -+ * (optional) The profile list. - */ -- public function __construct($directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION) { -+ public function __construct($directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, ProfileExtensionList $profile_list = NULL) { - parent::__construct($directory, $collection); -+ if (\Drupal::hasService('extension.list.profile')) { -+ $this->profileList = $profile_list ?: \Drupal::service('extension.list.profile'); -+ } - } - - /** -@@ -150,7 +163,9 @@ public function listAll($prefix = '') { - protected function getAllFolders() { - if (!isset($this->folders)) { - $this->folders = []; -- $this->folders += $this->getCoreNames(); -+ $this->folders = $this->getCoreNames() + $this->folders; -+ // Get dependent profiles and add the extension components. -+ $this->folders = $this->getComponentNames($this->profileList->getAncestors()) + $this->folders; - // Perform an ExtensionDiscovery scan as we cannot use - // \Drupal\Core\Extension\ExtensionList::getPath() yet because the system - // module may not yet be enabled during install. -@@ -167,12 +182,12 @@ protected function getAllFolders() { - /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list */ - $profile_extension_list = \Drupal::service('extension.list.profile'); - $profile_extension_list->setPathname($profile, $profile_list[$profile]->getPathname()); -- $this->folders += $this->getComponentNames([$profile_list[$profile]]); -+ $this->folders = $this->getComponentNames([$profile_list[$profile]]) + $this->folders; - } - } - // @todo Remove as part of https://www.drupal.org/node/2186491 -- $this->folders += $this->getComponentNames($listing->scan('module')); -- $this->folders += $this->getComponentNames($listing->scan('theme')); -+ $this->folders = $this->getComponentNames($listing->scan('module')) + $this->folders; -+ $this->folders = $this->getComponentNames($listing->scan('theme')) + $this->folders; - } - return $this->folders; - } -diff --git a/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php -index d2259643..2962bffa 100644 ---- a/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php -+++ b/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php -@@ -7,6 +7,7 @@ - use Drupal\Core\Config\ConfigImporterEvent; - use Drupal\Core\Config\ConfigImportValidateEventSubscriberBase; - use Drupal\Core\Config\ConfigNameException; -+use Drupal\Core\Extension\Extension; - use Drupal\Core\Extension\ConfigImportModuleUninstallValidatorInterface; - use Drupal\Core\Extension\ModuleExtensionList; - use Drupal\Core\Extension\ModuleUninstallValidatorInterface; -@@ -144,12 +145,18 @@ protected function validateModules(ConfigImporter $config_importer) { - $config_importer->logError($this->t('Unable to install the %module module since it does not exist.', ['%module' => $module])); - } - -+ // Get a list of parent profiles and the main profile. -+ /** @var \Drupal\Core\Extension\Extension[] $profiles */ -+ $profiles = \Drupal::service('extension.list.profile')->getAncestors(); -+ /** @var \Drupal\Core\Extension\Extension $main_profile */ -+ $main_profile = end($profiles); -+ - // Ensure that all modules being installed have their dependencies met. - $installs = $config_importer->getExtensionChangelist('module', 'install'); - foreach ($installs as $module) { - $missing_dependencies = []; - foreach (array_keys($module_data[$module]->requires) as $required_module) { -- if (!isset($core_extension['module'][$required_module])) { -+ if (!isset($core_extension['module'][$required_module]) && !array_key_exists($module, $profiles)) { - $missing_dependencies[] = $module_data[$required_module]->info['name']; - } - } -@@ -169,10 +176,15 @@ protected function validateModules(ConfigImporter $config_importer) { - $uninstalls = $config_importer->getExtensionChangelist('module', 'uninstall'); - foreach ($uninstalls as $module) { - foreach (array_keys($module_data[$module]->required_by) as $dependent_module) { -- if ($module_data[$dependent_module]->status && !in_array($dependent_module, $uninstalls, TRUE) && $dependent_module !== $install_profile) { -- $module_name = $module_data[$module]->info['name']; -- $dependent_module_name = $module_data[$dependent_module]->info['name']; -- $config_importer->logError($this->t('Unable to uninstall the %module module since the %dependent_module module is installed.', ['%module' => $module_name, '%dependent_module' => $dependent_module_name])); -+ if ($module_data[$dependent_module]->status && !in_array($dependent_module, $uninstalls, TRUE)) { -+ if (!array_key_exists($dependent_module, $profiles)) { -+ $module_name = $module_data[$module]->info['name']; -+ $dependent_module_name = $module_data[$dependent_module]->info['name']; -+ $config_importer->logError($this->t('Unable to uninstall the %module module since the %dependent_module module is installed.', [ -+ '%module' => $module_name, -+ '%dependent_module' => $dependent_module_name, -+ ])); -+ } - } - } - // Ensure that modules can be uninstalled. -diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php -index ebd3553c..bc6bb39b 100644 ---- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php -+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php -@@ -91,6 +91,15 @@ class ExtensionDiscovery { - */ - protected $sitePath; - -+ /** -+ * The profile list. -+ * -+ * Used to determine the directories in which we want to scan for modules. -+ * -+ * @var \Drupal\Core\Extension\ProfileExtensionList -+ */ -+ protected $profileList; -+ - /** - * Constructs a new ExtensionDiscovery object. - * -@@ -102,12 +111,24 @@ class ExtensionDiscovery { - * The available profile directories - * @param string $site_path - * The path to the site. -+ * @param \Drupal\Core\Extension\ProfileExtensionList|null $profile_list -+ * (optional) The profile list. - */ -- public function __construct(string $root, $use_file_cache = TRUE, ?array $profile_directories = NULL, ?string $site_path = NULL) { -+ public function __construct(string $root, bool $use_file_cache = TRUE, array $profile_directories = NULL, string $site_path = NULL, ProfileExtensionList $profile_list = NULL) { - $this->root = $root; - $this->fileCache = $use_file_cache ? FileCacheFactory::get('extension_discovery') : NULL; - $this->profileDirectories = $profile_directories; - $this->sitePath = $site_path; -+ -+ // ExtensionDiscovery can be used without a service container -+ // (@drupalKernel::moduleData), so only use the profile list service if it -+ // is available to us. -+ if ($profile_list) { -+ $this->profileList = $profile_list; -+ } -+ elseif (\Drupal::hasService('extension.list.profile')) { -+ $this->profileList = \Drupal::service('extension.list.profile'); -+ } - } - - /** -@@ -246,7 +267,19 @@ public function setProfileDirectoriesFromSettings() { - $this->profileDirectories[] = '_does_not_exist_profile_CNKDSIUSYFUISEFCB'; - } - elseif ($profile) { -- $this->profileDirectories[] = \Drupal::service('extension.list.profile')->getPath($profile); -+ if ($this->profileList) { -+ $profiles = $this->profileList->getAncestors($profile); -+ } -+ else { -+ $profiles = [ -+ $profile => new Extension($this->root, 'profile', \Drupal::service('extension.list.profile')->getPath($profile)), -+ ]; -+ } -+ -+ $profile_directories = array_map(function (Extension $extension) { -+ return $extension->getPath(); -+ }, $profiles); -+ $this->profileDirectories = array_unique(array_merge($profile_directories, $this->profileDirectories)); - } - return $this; - } -diff --git a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php -index 1176b566..2a580986 100644 ---- a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php -+++ b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php -@@ -42,7 +42,7 @@ class ModuleExtensionList extends ExtensionList { - /** - * The profile list needed by this module list. - * -- * @var \Drupal\Core\Extension\ExtensionList -+ * @var \Drupal\Core\Extension\ProfileExtensionList - */ - protected $profileList; - -@@ -63,14 +63,14 @@ class ModuleExtensionList extends ExtensionList { - * The state. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The config factory. -- * @param \Drupal\Core\Extension\ExtensionList $profile_list -+ * @param \Drupal\Core\Extension\ProfileExtensionList $profile_list - * The site profile listing. - * @param string $install_profile - * The install profile used by the site. - * @param array[] $container_modules_info - * (optional) The module locations coming from the compiled container. - */ -- public function __construct($root, $type, CacheBackendInterface $cache, InfoParserInterface $info_parser, ModuleHandlerInterface $module_handler, StateInterface $state, ConfigFactoryInterface $config_factory, ExtensionList $profile_list, $install_profile, array $container_modules_info = []) { -+ public function __construct($root, $type, CacheBackendInterface $cache, InfoParserInterface $info_parser, ModuleHandlerInterface $module_handler, StateInterface $state, ConfigFactoryInterface $config_factory, ProfileExtensionList $profile_list, $install_profile, array $container_modules_info = []) { - parent::__construct($root, $type, $cache, $info_parser, $module_handler, $state, $install_profile); - - $this->configFactory = $config_factory; -@@ -106,9 +106,7 @@ protected function getExtensionDiscovery() { - */ - protected function getProfileDirectories(ExtensionDiscovery $discovery) { - $discovery->setProfileDirectories([]); -- $all_profiles = $discovery->scan('profile'); -- $active_profile = $all_profiles[$this->installProfile]; -- $profiles = array_intersect_key($all_profiles, $this->configFactory->get('core.extension')->get('module') ?: [$active_profile->getName() => 0]); -+ $profiles = $this->profileList->getAncestors($this->installProfile); - - $profile_directories = array_map(function (Extension $profile) { - return $profile->getPath(); -@@ -136,13 +134,9 @@ protected function getActiveProfile() { - */ - protected function doScanExtensions() { - $extensions = parent::doScanExtensions(); -- -- $profiles = $this->profileList->getList(); -- // Modify the active profile object that was previously added to the module -- // list. -- if ($this->installProfile && isset($profiles[$this->installProfile])) { -- $extensions[$this->installProfile] = $profiles[$this->installProfile]; -- } -+ // Merge in the install profile and any profile ancestors. -+ $profiles = $this->profileList->getAncestors($this->installProfile); -+ $extensions = array_merge($extensions, $profiles); - - return $extensions; - } -diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php -index 5820e71e..5d31533e 100644 ---- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php -+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php -@@ -420,7 +420,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) { - return FALSE; - } - -- // Skip already uninstalled modules. -+ // Skip already uninstalled modules and dependencies of profiles. - if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent])) { - $module_list[$dependent] = $dependent; - } -diff --git a/core/lib/Drupal/Core/Extension/ProfileExtensionList.php b/core/lib/Drupal/Core/Extension/ProfileExtensionList.php -index 5ef9c451..cbaae106 100644 ---- a/core/lib/Drupal/Core/Extension/ProfileExtensionList.php -+++ b/core/lib/Drupal/Core/Extension/ProfileExtensionList.php -@@ -23,13 +23,171 @@ class ProfileExtensionList extends ExtensionList { - 'package' => 'Other', - 'version' => NULL, - 'php' => \Drupal::MINIMUM_PHP, -+ 'themes' => ['stark'], -+ 'hidden' => FALSE, -+ 'base profile' => '', - ]; - -+ /** -+ * {@inheritdoc} -+ */ -+ public function getExtensionInfo($extension_name) { -+ $all_info = $this->getAllAvailableInfo(); -+ if (isset($all_info[$extension_name])) { -+ return $all_info[$extension_name]; -+ } -+ throw new \InvalidArgumentException("The {$this->type} $extension_name does not exist."); -+ } -+ -+ /** -+ * Returns the profile, its parent profile, if it has one, and any ancestors. -+ * -+ * @param string $profile -+ * (optional) The name of profile. Defaults to the current install profile. -+ * -+ * @return \Drupal\Core\Extension\Extension[] -+ * An associative array of Extension objects, keyed by profile name in -+ * descending order of their dependencies (ancestors first). If the profile -+ * is not given and cannot be determined, returns an empty array. -+ */ -+ public function getAncestors($profile = NULL) { -+ $ancestors = []; -+ -+ if (empty($profile)) { -+ $profile = $this->installProfile ?: \Drupal::installProfile(); -+ } -+ if (empty($profile)) { -+ return $ancestors; -+ } -+ -+ $extension = $this->get($profile); -+ -+ foreach ($extension->ancestors as $ancestor) { -+ $ancestors[$ancestor] = $this->get($ancestor); -+ } -+ $ancestors[$profile] = $extension; -+ -+ return $ancestors; -+ } -+ -+ /** -+ * Returns all available profiles which are distributions. -+ * -+ * @return \Drupal\Core\Extension\Extension[] -+ * Processed extension objects, keyed by machine name. -+ */ -+ public function listDistributions() { -+ return array_filter($this->getList(), function (Extension $profile) { -+ return !empty($profile->info['distribution']); -+ }); -+ } -+ -+ /** -+ * Select the install distribution from the list of profiles. -+ * -+ * If there are multiple profiles marked as distributions, select the first. -+ * If there is an inherited profile marked as a distribution, select it over -+ * its base profile. -+ * -+ * @param string[] $profiles -+ * List of profile names to search. -+ * -+ * @return string|null -+ * The selected distribution profile name, or NULL if none is found. -+ */ -+ public function selectDistribution(array $profiles = NULL) { -+ $distributions = $this->listDistributions(); -+ -+ if ($profiles) { -+ $distributions = array_intersect_key($distributions, array_flip($profiles)); -+ } -+ -+ // Remove any distributions which are extended by another one. -+ foreach ($distributions as $profile) { -+ if (!empty($profile->info['base profile'])) { -+ $base_profile = $profile->info['base profile']; -+ unset($distributions[$base_profile]); -+ } -+ } -+ -+ return key($distributions) ?: NULL; -+ } -+ -+ /** -+ * {@inheritdoc} -+ */ -+ protected function doList() { -+ $profiles = parent::doList(); -+ -+ // Compute the ancestry of each profile before any further processing. -+ foreach ($profiles as $profile) { -+ // Maintain a list of profiles which depend on this one. -+ $profile->children = []; -+ -+ // Maintain a list of profiles that this one depends on, in reverse -+ // ancestral order (immediate parent first). -+ $profile->ancestors = $this->computeAncestry($profiles, $profile); -+ -+ // Give the profile a heavy weight to ensure that its hooks run last. -+ $profile->weight = count($profile->ancestors) + 1000; -+ } -+ -+ // For each profile, merge in ancestors' module and theme lists. -+ foreach ($profiles as $profile_name => $profile) { -+ if (empty($profile->ancestors)) { -+ continue; -+ } -+ // Reference the extension info here for readability. -+ $info = &$profile->info; -+ -+ // Add the parent profile as a hard dependency. -+ $info['dependencies'][] = reset($profile->ancestors); -+ -+ // Add all themes and extensions listed by ancestors. -+ foreach ($profile->ancestors as $ancestor) { -+ $ancestor = $profiles[$ancestor]; -+ -+ // Add the current profile as a child of the ancestor. -+ $ancestor->children[] = $profile_name; -+ $info['install'] = array_merge($info['install'], $ancestor->info['install']); -+ $info['themes'] = array_merge($info['themes'], $ancestor->info['themes']); -+ // Add ancestor dependencies as our dependencies. -+ $info['dependencies'] = array_merge($info['dependencies'], $ancestor->info['dependencies']); -+ } -+ $info['dependencies'] = array_unique($info['dependencies']); -+ $info['install'] = array_unique($info['install']); -+ $info['themes'] = array_unique($info['themes']); -+ } -+ return $profiles; -+ } -+ -+ /** -+ * Computes and returns the ancestral lineage of a profile. -+ * -+ * @param \Drupal\Core\Extension\Extension[] $profiles -+ * All discovered profiles. -+ * @param \Drupal\Core\Extension\Extension $profile -+ * The profile for which to compute the ancestry. -+ * -+ * @return string[] -+ * The names of the ancestors of the given profile, in order. -+ */ -+ protected function computeAncestry(array $profiles, Extension $profile) { -+ $ancestors = []; -+ -+ while (!empty($profile->info['base profile'])) { -+ array_unshift($ancestors, $profile->info['base profile']); -+ $profile = $profile->info['base profile']; -+ $profile = $profiles[$profile]; -+ } -+ return $ancestors; -+ } -+ - /** - * {@inheritdoc} - */ - protected function getInstalledExtensionNames() { -- return [$this->installProfile]; -+ return array_keys($this->getAncestors()); - } - - } -diff --git a/core/lib/Drupal/Core/Installer/InstallerProfileExtensionList.php b/core/lib/Drupal/Core/Installer/InstallerProfileExtensionList.php -index e69de29b..d5c42ade 100644 ---- a/core/lib/Drupal/Core/Installer/InstallerProfileExtensionList.php -+++ b/core/lib/Drupal/Core/Installer/InstallerProfileExtensionList.php -@@ -0,0 +1,58 @@ -+addedPathNames[$extension_name])) { -+ return $this->addedPathNames[$extension_name]; -+ } -+ elseif (isset($this->pathNames[$extension_name])) { -+ return $this->pathNames[$extension_name]; -+ } -+ elseif (isset(static::$staticAddedPathNames[$extension_name])) { -+ return static::$staticAddedPathNames[$extension_name]; -+ } -+ elseif (($path_names = $this->getPathnames()) && isset($path_names[$extension_name])) { -+ // Ensure we don't have to do path scanning more than really needed. -+ foreach ($path_names as $extension => $path_name) { -+ static::$staticAddedPathNames[$extension] = $path_name; -+ } -+ return $path_names[$extension_name]; -+ } -+ throw new \InvalidArgumentException("The {$this->type} $extension_name does not exist."); -+ } -+ -+} -diff --git a/core/lib/Drupal/Core/Installer/NormalInstallerServiceProvider.php b/core/lib/Drupal/Core/Installer/NormalInstallerServiceProvider.php -index 7c8d8129..8f267134 100644 ---- a/core/lib/Drupal/Core/Installer/NormalInstallerServiceProvider.php -+++ b/core/lib/Drupal/Core/Installer/NormalInstallerServiceProvider.php -@@ -58,6 +58,7 @@ public function register(ContainerBuilder $container) { - - // Use performance-optimized extension lists. - $container->getDefinition('extension.list.module')->setClass(InstallerModuleExtensionList::class); -+ $container->getDefinition('extension.list.profile')->setClass(InstallerProfileExtensionList::class); - $container->getDefinition('extension.list.theme')->setClass(InstallerThemeExtensionList::class); - $container->getDefinition('extension.list.theme_engine')->setClass(InstallerThemeEngineExtensionList::class); - -diff --git a/core/modules/config/tests/config_test/src/TestInstallStorage.php b/core/modules/config/tests/config_test/src/TestInstallStorage.php -index e3c4918d..6d140815 100644 ---- a/core/modules/config/tests/config_test/src/TestInstallStorage.php -+++ b/core/modules/config/tests/config_test/src/TestInstallStorage.php -@@ -21,9 +21,10 @@ protected function getAllFolders() { - $this->folders = $this->getCoreNames(); - $listing = new ExtensionDiscovery(\Drupal::root()); - $listing->setProfileDirectories([]); -- $this->folders += $this->getComponentNames($listing->scan('profile')); -- $this->folders += $this->getComponentNames($listing->scan('module')); -- $this->folders += $this->getComponentNames($listing->scan('theme')); -+ // @todo Remove as part of https://www.drupal.org/node/2186491 -+ $this->folders = $this->getComponentNames($listing->scan('profile')) + $this->folders; -+ $this->folders = $this->getComponentNames($listing->scan('module')) + $this->folders; -+ $this->folders = $this->getComponentNames($listing->scan('theme')) + $this->folders; - } - return $this->folders; - } -diff --git a/core/modules/config/tests/src/Functional/ConfigImportBaseInstallProfileTest.php b/core/modules/config/tests/src/Functional/ConfigImportBaseInstallProfileTest.php -index e69de29b..9173bb34 100644 ---- a/core/modules/config/tests/src/Functional/ConfigImportBaseInstallProfileTest.php -+++ b/core/modules/config/tests/src/Functional/ConfigImportBaseInstallProfileTest.php -@@ -0,0 +1,109 @@ -+webUser = $this->drupalCreateUser(['synchronize configuration']); -+ $this->drupalLogin($this->webUser); -+ $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync')); -+ } -+ -+ /** -+ * Tests config importer cannot uninstall parent install profile/s. -+ * -+ * Also, tests that dependencies of parent profile/s can be uninstalled. -+ * -+ * @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber -+ */ -+ public function testInstallParentProfileValidation() { -+ $sync = $this->container->get('config.storage.sync'); -+ $this->copyConfig($this->container->get('config.storage'), $sync); -+ $core = $sync->read('core.extension'); -+ -+ // Ensure that parent profile can not be uninstalled. -+ unset($core['module']['testing']); -+ $sync->write('core.extension', $core); -+ -+ $this->drupalGet('admin/config/development/configuration'); -+ $this->submitForm([], 'Import all'); -+ $this->assertSession()->pageTextContains('The configuration cannot be imported because it failed validation for the following reasons:'); -+ $this->assertSession()->pageTextContains('Unable to uninstall the Testing profile since it is a parent of another installed profile.'); -+ -+ // Uninstall dependencies of parent profile. -+ $core['module']['testing'] = 0; -+ if (isset($core['module']['dynamic_page_cache'])) { -+ unset($core['module']['dynamic_page_cache']); -+ } -+ $sync->write('core.extension', $core); -+ $sync->deleteAll('dynamic_page_cache.'); -+ $this->drupalGet('admin/config/development/configuration'); -+ $this->submitForm([], 'Import all'); -+ $this->assertSession()->pageTextContains('The configuration was imported successfully.'); -+ $this->rebuildContainer(); -+ $this->assertFalse(\Drupal::moduleHandler()->moduleExists('dynamic_page_cache'), 'The dynamic_page_cache module has been uninstalled.'); -+ } -+ -+ /** -+ * Tests config importer cannot uninstall sub-profile/s. -+ * -+ * Also, tests dependencies of sub-profile/s can be uninstalled. -+ * -+ * @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber -+ */ -+ public function testInstallSubProfileValidation() { -+ $sync = $this->container->get('config.storage.sync'); -+ $this->copyConfig($this->container->get('config.storage'), $sync); -+ $core = $sync->read('core.extension'); -+ -+ // Ensure install sub-profiles can not be uninstalled. -+ unset($core['module']['testing_inherited']); -+ $sync->write('core.extension', $core); -+ -+ $this->drupalGet('admin/config/development/configuration'); -+ $this->submitForm([], 'Import all'); -+ $this->assertSession()->pageTextContains('The configuration cannot be imported because it failed validation for the following reasons:'); -+ $this->assertSession()->pageTextContains('Unable to uninstall the Testing Inherited profile since it is the main install profile.'); -+ -+ // Uninstall dependencies of main profile. -+ $core['module']['testing_inherited'] = 0; -+ if (isset($core['module']['syslog'])) { -+ unset($core['module']['syslog']); -+ } -+ $sync->write('core.extension', $core); -+ $sync->deleteAll('syslog.'); -+ $this->drupalGet('admin/config/development/configuration'); -+ $this->submitForm([], 'Import all'); -+ $this->assertSession()->pageTextContains('The configuration was imported successfully.'); -+ $this->rebuildContainer(); -+ $this->assertFalse(\Drupal::moduleHandler()->moduleExists('syslog'), 'The syslog module has been uninstalled.'); -+ } -+ -+} -diff --git a/core/modules/config/tests/src/Functional/ConfigImportInstallProfileTest.php b/core/modules/config/tests/src/Functional/ConfigImportInstallProfileTest.php -index 12d58a6a..9ad93c8c 100644 ---- a/core/modules/config/tests/src/Functional/ConfigImportInstallProfileTest.php -+++ b/core/modules/config/tests/src/Functional/ConfigImportInstallProfileTest.php -@@ -68,7 +68,7 @@ public function testInstallProfileValidation(): void { - $this->drupalGet('admin/config/development/configuration'); - $this->submitForm([], 'Import all'); - $this->assertSession()->pageTextContains('The configuration cannot be imported because it failed validation for the following reasons:'); -- $this->assertSession()->pageTextContains("The install profile 'Testing config import' is providing the following module(s): testing_config_import_module"); -+ $this->assertSession()->pageTextContains('Unable to uninstall the Testing config import profile since it is the main install profile.'); - - // Uninstall dependencies of testing_config_import. - unset($core['module']['syslog']); -diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php -index d09f2c63..41f9563b 100644 ---- a/core/modules/system/src/Form/ModulesUninstallForm.php -+++ b/core/modules/system/src/Form/ModulesUninstallForm.php -@@ -142,6 +142,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { - return $form; - } - -+ $profiles = \Drupal::service('extension.list.profile')->getAncestors(); -+ // Remove any profiles from the list. -+ $uninstallable = array_diff_key($uninstallable, $profiles); -+ - // Deprecated and obsolete modules should appear at the top of the - // uninstallation list. - $unstable_lifecycle = array_flip([ -@@ -195,7 +199,8 @@ public function buildForm(array $form, FormStateInterface $form_state) { - $form['uninstall'][$module->getName()]['#disabled'] = TRUE; - } - // All modules which depend on this one must be uninstalled first, before -- // we can allow this module to be uninstalled. -+ // we can allow this module to be uninstalled. (Installation profiles are -+ // excluded from this list.) - foreach (array_keys($module->required_by) as $dependent) { - if ($this->updateRegistry->getInstalledVersion($dependent) !== $this->updateRegistry::SCHEMA_UNINSTALLED) { - $form['modules'][$module->getName()]['#required_by'][] = $dependent; -diff --git a/core/profiles/testing_inherited/config/install/block.block.stable_login.yml b/core/profiles/testing_inherited/config/install/block.block.stable_login.yml -index e69de29b..9338951f 100644 ---- a/core/profiles/testing_inherited/config/install/block.block.stable_login.yml -+++ b/core/profiles/testing_inherited/config/install/block.block.stable_login.yml -@@ -0,0 +1,19 @@ -+langcode: en -+status: true -+dependencies: -+ module: -+ - user -+ theme: -+ - stable9 -+id: stable_login -+theme: stable9 -+region: sidebar_first -+weight: 0 -+provider: null -+plugin: user_login_block -+settings: -+ id: user_login_block -+ label: 'User login' -+ provider: user -+ label_display: visible -+visibility: { } -diff --git a/core/profiles/testing_inherited/config/install/system.theme.yml b/core/profiles/testing_inherited/config/install/system.theme.yml -index e69de29b..25377e44 100644 ---- a/core/profiles/testing_inherited/config/install/system.theme.yml -+++ b/core/profiles/testing_inherited/config/install/system.theme.yml -@@ -0,0 +1,2 @@ -+# @todo: Remove this file in https://www.drupal.org/node/2352949 -+default: stable9 -diff --git a/core/profiles/testing_inherited/modules/child_profile_module/child_profile_module.info.yml b/core/profiles/testing_inherited/modules/child_profile_module/child_profile_module.info.yml -index e69de29b..132b1149 100644 ---- a/core/profiles/testing_inherited/modules/child_profile_module/child_profile_module.info.yml -+++ b/core/profiles/testing_inherited/modules/child_profile_module/child_profile_module.info.yml -@@ -0,0 +1,5 @@ -+name: 'Child profile module' -+type: module -+description: 'A module contained in a child profile, for testing.' -+package: Testing -+version: VERSION -diff --git a/core/profiles/testing_inherited/modules/contrib/contrib_child_profile_module/contrib_child_profile_module.info.yml b/core/profiles/testing_inherited/modules/contrib/contrib_child_profile_module/contrib_child_profile_module.info.yml -index e69de29b..822c5720 100644 ---- a/core/profiles/testing_inherited/modules/contrib/contrib_child_profile_module/contrib_child_profile_module.info.yml -+++ b/core/profiles/testing_inherited/modules/contrib/contrib_child_profile_module/contrib_child_profile_module.info.yml -@@ -0,0 +1,5 @@ -+name: 'Contrib child profile module' -+type: module -+description: 'A contrib module contained in a child profile, for testing.' -+package: Testing -+version: VERSION -diff --git a/core/profiles/testing_inherited/modules/custom/custom_child_profile_module/custom_child_profile_module.info.yml b/core/profiles/testing_inherited/modules/custom/custom_child_profile_module/custom_child_profile_module.info.yml -index e69de29b..ef81a8a5 100644 ---- a/core/profiles/testing_inherited/modules/custom/custom_child_profile_module/custom_child_profile_module.info.yml -+++ b/core/profiles/testing_inherited/modules/custom/custom_child_profile_module/custom_child_profile_module.info.yml -@@ -0,0 +1,5 @@ -+name: 'Custom child profile module' -+type: module -+description: 'A custom module contained in a child profile, for testing.' -+package: Testing -+version: VERSION -diff --git a/core/profiles/testing_inherited/testing_inherited.info.yml b/core/profiles/testing_inherited/testing_inherited.info.yml -index e69de29b..635c9353 100644 ---- a/core/profiles/testing_inherited/testing_inherited.info.yml -+++ b/core/profiles/testing_inherited/testing_inherited.info.yml -@@ -0,0 +1,17 @@ -+name: Testing Inherited -+type: profile -+description: 'Profile for testing base profile inheritance.' -+version: VERSION -+hidden: true -+ -+base profile: testing -+ -+install: -+ - block -+ - config -+ - child_profile_module -+ - contrib_child_profile_module -+ - custom_child_profile_module -+ -+themes: -+ - stable9 -diff --git a/core/profiles/testing_inherited/tests/src/Functional/InheritedProfileTest.php b/core/profiles/testing_inherited/tests/src/Functional/InheritedProfileTest.php -index e69de29b..ca08e3e3 100644 ---- a/core/profiles/testing_inherited/tests/src/Functional/InheritedProfileTest.php -+++ b/core/profiles/testing_inherited/tests/src/Functional/InheritedProfileTest.php -@@ -0,0 +1,46 @@ -+assertInstanceOf(BlockInterface::class, Block::load('stable_login')); -+ -+ // Check that stable is the default theme. -+ $this->assertSame('stable9', $this->config('system.theme')->get('default')); -+ -+ /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ -+ $module_handler = $this->container->get('module_handler'); -+ // Check that parent dependencies are installed. -+ $this->assertTrue($module_handler->moduleExists('page_cache')); -+ // Check that child profile dependencies are installed. -+ $this->assertTrue($module_handler->moduleExists('config')); -+ // Check that modules contained in the child profile are installed. -+ $this->assertTrue($module_handler->moduleExists('child_profile_module')); -+ $this->assertTrue($module_handler->moduleExists('contrib_child_profile_module')); -+ $this->assertTrue($module_handler->moduleExists('custom_child_profile_module')); -+ -+ // Check that all themes were installed. -+ $this->assertTrue(\Drupal::service('theme_handler')->themeExists('stable9')); -+ } -+ -+} -diff --git a/core/profiles/testing_inherited_standard/config/install/core.entity_view_display.node.page.teaser.yml b/core/profiles/testing_inherited_standard/config/install/core.entity_view_display.node.page.teaser.yml -index e69de29b..91194c2f 100644 ---- a/core/profiles/testing_inherited_standard/config/install/core.entity_view_display.node.page.teaser.yml -+++ b/core/profiles/testing_inherited_standard/config/install/core.entity_view_display.node.page.teaser.yml -@@ -0,0 +1,27 @@ -+langcode: en -+status: true -+dependencies: -+ config: -+ - core.entity_view_mode.node.teaser -+ - field.field.node.page.body -+ - node.type.page -+ module: -+ - text -+ - user -+id: node.page.teaser -+targetEntityType: node -+bundle: page -+mode: teaser -+content: -+ body: -+ label: hidden -+ type: text_summary_or_trimmed -+ weight: 100 -+ region: content -+ settings: -+ trim_length: 300 -+ third_party_settings: { } -+ links: -+ weight: 101 -+ region: content -+hidden: { } -diff --git a/core/profiles/testing_inherited_standard/testing_inherited_standard.info.yml b/core/profiles/testing_inherited_standard/testing_inherited_standard.info.yml -index e69de29b..04d24749 100644 ---- a/core/profiles/testing_inherited_standard/testing_inherited_standard.info.yml -+++ b/core/profiles/testing_inherited_standard/testing_inherited_standard.info.yml -@@ -0,0 +1,12 @@ -+name: Testing Inherited Standard -+type: profile -+description: 'Profile for testing base profile inheritance.' -+version: VERSION -+hidden: true -+ -+base profile: standard -+ -+install: [] -+ -+themes: -+ - olivero -diff --git a/core/profiles/testing_inherited_standard/tests/src/Functional/InheritedProfileTest.php b/core/profiles/testing_inherited_standard/tests/src/Functional/InheritedProfileTest.php -index e69de29b..c83ccae4 100644 ---- a/core/profiles/testing_inherited_standard/tests/src/Functional/InheritedProfileTest.php -+++ b/core/profiles/testing_inherited_standard/tests/src/Functional/InheritedProfileTest.php -@@ -0,0 +1,38 @@ -+config('core.entity_view_display.node.page.teaser')->get('content.body.settings.trim_length'); -+ $this->assertEquals(300, $trim_length, 'Sub-profile configuration successfully overrides base profile configuration.'); -+ } -+ -+} -diff --git a/core/profiles/testing_sub_sub_profile/config/install/system.theme.yml b/core/profiles/testing_sub_sub_profile/config/install/system.theme.yml -index e69de29b..911d5890 100644 ---- a/core/profiles/testing_sub_sub_profile/config/install/system.theme.yml -+++ b/core/profiles/testing_sub_sub_profile/config/install/system.theme.yml -@@ -0,0 +1,2 @@ -+# @todo: Remove this file once https://www.drupal.org/node/2854576 is resolved. -+default: stable9 -diff --git a/core/profiles/testing_sub_sub_profile/modules/grandchild_profile_module/grandchild_profile_module.info.yml b/core/profiles/testing_sub_sub_profile/modules/grandchild_profile_module/grandchild_profile_module.info.yml -index e69de29b..06e0e52d 100644 ---- a/core/profiles/testing_sub_sub_profile/modules/grandchild_profile_module/grandchild_profile_module.info.yml -+++ b/core/profiles/testing_sub_sub_profile/modules/grandchild_profile_module/grandchild_profile_module.info.yml -@@ -0,0 +1,5 @@ -+name: 'Grandchild profile module' -+type: module -+description: 'A module contained in a grandchild profile, for testing.' -+package: Testing -+version: VERSION -diff --git a/core/profiles/testing_sub_sub_profile/testing_sub_sub_profile.info.yml b/core/profiles/testing_sub_sub_profile/testing_sub_sub_profile.info.yml -index e69de29b..25d7ca67 100644 ---- a/core/profiles/testing_sub_sub_profile/testing_sub_sub_profile.info.yml -+++ b/core/profiles/testing_sub_sub_profile/testing_sub_sub_profile.info.yml -@@ -0,0 +1,11 @@ -+name: Testing Sub_Sub_Profile -+type: profile -+description: 'Profile for testing deep profile inheritance.' -+version: VERSION -+hidden: true -+ -+base profile: testing_inherited -+ -+install: -+ - syslog -+ - grandchild_profile_module -diff --git a/core/profiles/testing_sub_sub_profile/tests/src/Functional/DeepInheritedProfileTest.php b/core/profiles/testing_sub_sub_profile/tests/src/Functional/DeepInheritedProfileTest.php -index e69de29b..39c8f1d2 100644 ---- a/core/profiles/testing_sub_sub_profile/tests/src/Functional/DeepInheritedProfileTest.php -+++ b/core/profiles/testing_sub_sub_profile/tests/src/Functional/DeepInheritedProfileTest.php -@@ -0,0 +1,38 @@ -+assertSame('stable9', $this->config('system.theme')->get('default')); -+ -+ /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ -+ $module_handler = $this->container->get('module_handler'); -+ // page_cache was enabled in main profile. -+ $this->assertTrue($module_handler->moduleExists('page_cache')); -+ // block was enabled in parent profile. -+ $this->assertTrue($module_handler->moduleExists('block')); -+ // syslog was enabled in this profile. -+ $this->assertTrue($module_handler->moduleExists('syslog')); -+ // A module contained in this profile was installed too. -+ $this->assertTrue($module_handler->moduleExists('grandchild_profile_module')); -+ } -+ -+} -diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ProfileExtensionListTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ProfileExtensionListTest.php -index e69de29b..1d767453 100644 ---- a/core/tests/Drupal/KernelTests/Core/Extension/ProfileExtensionListTest.php -+++ b/core/tests/Drupal/KernelTests/Core/Extension/ProfileExtensionListTest.php -@@ -0,0 +1,145 @@ -+container->get('extension.list.profile'); -+ -+ $info = $profile_list->getExtensionInfo('testing_inherited'); -+ $this->assertNotEmpty($info); -+ $this->assertSame($info['name'], 'Testing Inherited'); -+ $this->assertSame($info['base profile'], 'testing'); -+ $this->assertContains('config', $info['install']); -+ $this->assertContains('drupal:page_cache', $info['install']); -+ $this->assertTrue($info['hidden'], 'Profiles should be hidden'); -+ -+ // Test that profiles without any base return normalized info. -+ $info = $profile_list->getExtensionInfo('minimal'); -+ $this->assertSame('', $info['base profile']); -+ -+ // Tests three levels profile inheritance. -+ $info = $profile_list->getExtensionInfo('testing_sub_sub_profile'); -+ $this->assertSame($info['base profile'], 'testing_inherited'); -+ } -+ -+ /** -+ * Tests getting profile dependency list. -+ * -+ * @covers ::getAncestors -+ */ -+ public function testGetAncestors() { -+ /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_list */ -+ $profile_list = $this->container->get('extension.list.profile'); -+ -+ $profiles = $profile_list->getAncestors('testing'); -+ $this->assertCount(1, $profiles); -+ -+ $profiles = $profile_list->getAncestors('testing_inherited'); -+ $this->assertCount(2, $profiles); -+ -+ $profiles = $profile_list->getAncestors('testing_sub_sub_profile'); -+ $this->assertCount(3, $profiles); -+ -+ $first_profile = current($profiles); -+ $this->assertInstanceOf(Extension::class, $first_profile); -+ $this->assertSame($first_profile->getName(), 'testing'); -+ $this->assertSame(1000, $first_profile->weight); -+ $this->assertObjectHasAttribute('origin', $first_profile); -+ -+ $second_profile = next($profiles); -+ $this->assertInstanceOf(Extension::class, $second_profile); -+ $this->assertSame($second_profile->getName(), 'testing_inherited'); -+ $this->assertSame(1001, $second_profile->weight); -+ $this->assertObjectHasAttribute('origin', $second_profile); -+ -+ $third_profile = next($profiles); -+ $this->assertInstanceOf(Extension::class, $third_profile); -+ $this->assertSame($third_profile->getName(), 'testing_sub_sub_profile'); -+ $this->assertSame(1002, $third_profile->weight); -+ $this->assertObjectHasAttribute('origin', $third_profile); -+ } -+ -+ /** -+ * @covers ::selectDistribution -+ * -+ * @depends testGetExtensionInfo -+ */ -+ public function testSelectDistribution() { -+ $profile_list = new TestProfileExtensionList( -+ $this->container->getParameter('app.root'), -+ 'profile', -+ $this->container->get('cache.default'), -+ $this->container->get('info_parser'), -+ $this->container->get('module_handler'), -+ $this->container->get('state'), -+ $this->container->getParameter('install_profile') -+ ); -+ -+ $profiles = ['testing', 'testing_inherited']; -+ $base_info = $profile_list->getExtensionInfo('minimal'); -+ $profile_info = $profile_list->getExtensionInfo('testing_inherited'); -+ -+ // Neither profile has distribution set. -+ $distribution = $profile_list->selectDistribution($profiles); -+ $this->assertEmpty($distribution, 'No distribution should be selected'); -+ -+ // Set base profile distribution. -+ $base_info['distribution']['name'] = 'Minimal'; -+ $profile_list->profileInfo['minimal'] = $base_info; -+ // Base profile distribution should not be selected. -+ $distribution = $profile_list->selectDistribution($profiles); -+ $this->assertEmpty($distribution, 'Base profile distribution should not be selected'); -+ -+ // Set main profile distribution. -+ $profile_info['distribution']['name'] = 'Testing Inherited'; -+ $profile_list->profileInfo['testing_inherited'] = $profile_info; -+ // Main profile distribution should be selected. -+ $distribution = $profile_list->selectDistribution($profiles); -+ $this->assertEquals($distribution, 'testing_inherited'); -+ } -+ -+} -+ -+final class TestProfileExtensionList extends ProfileExtensionList { -+ -+ /** -+ * Overridden profile info, keyed by extension name. -+ * -+ * @var array -+ */ -+ public $profileInfo = []; -+ -+ /** -+ * {@inheritdoc} -+ */ -+ public function getList() { -+ $extensions = parent::getList(); -+ -+ foreach ($extensions as $name => $extension) { -+ if (isset($this->profileInfo[$name])) { -+ $extension->info = $this->profileInfo[$name]; -+ } -+ } -+ return $extensions; -+ } -+ -+} -diff --git a/core/tests/Drupal/Tests/Core/Database/DatabaseTest.php b/core/tests/Drupal/Tests/Core/Database/DatabaseTest.php -index 0119c7ae..f7cd343b 100644 ---- a/core/tests/Drupal/Tests/Core/Database/DatabaseTest.php -+++ b/core/tests/Drupal/Tests/Core/Database/DatabaseTest.php -@@ -54,6 +54,7 @@ protected function setUp(): void { - ->willReturnMap([ - ['kernel', TRUE], - ['extension.list.database_driver', TRUE], -+ ['extension.list.profile', TRUE], - ]); - $container->expects($this->any()) - ->method('get') diff --git a/patches/core/custom-modify-upload-user-avatar-access-check.patch b/patches/core/custom-modify-upload-user-avatar-access-check.patch index 464facf2..fc60b05c 100644 --- a/patches/core/custom-modify-upload-user-avatar-access-check.patch +++ b/patches/core/custom-modify-upload-user-avatar-access-check.patch @@ -1,7 +1,7 @@ -diff --git a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php +diff --git a/core/modules/jsonapi/src/Controller/FileUpload.php b/core/modules/jsonapi/src/Controller/FileUpload.php index 945c77f..d9674fc 100644 ---- a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php -+++ b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php +--- a/core/modules/jsonapi/src/Controller/FileUpload.php ++++ b/core/modules/jsonapi/src/Controller/FileUpload.php @@ -328,6 +328,9 @@ public static function checkFileUploadAccess(AccountInterface $account, FieldDef ? $entity_access_control_handler->access($entity, 'update', $account, TRUE) : $entity_access_control_handler->createAccess($bundle, $account, [], TRUE); diff --git a/patches/jsonapi_boost/drupal-11-compatibility.patch b/patches/jsonapi_boost/drupal-11-compatibility.patch new file mode 100644 index 00000000..5b1bd062 --- /dev/null +++ b/patches/jsonapi_boost/drupal-11-compatibility.patch @@ -0,0 +1,13 @@ +diff --git a/jsonapi_boost.info.yml b/jsonapi_boost.info.yml +index 542d670bd9f30a80c3588631252cc8c520dec374..1fa8e2e990561b9c1ce30de1fef2ba10b1e78b66 100644 +--- a/jsonapi_boost.info.yml ++++ b/jsonapi_boost.info.yml +@@ -1,7 +1,7 @@ + name: 'JSON:API Boost' + description: Improve the performance of the JSON:API module with a cache-warming strategy. + type: module +-core_version_requirement: ^9 || ^10 ++core_version_requirement: ^9 || ^10 || ^11 + dependencies: + - drupal:jsonapi + - jsonapi_extras:jsonapi_extras diff --git a/patches/jsonapi_cross_bundles/drupal-11-compatibility.patch b/patches/jsonapi_cross_bundles/drupal-11-compatibility.patch new file mode 100644 index 00000000..7e0337c1 --- /dev/null +++ b/patches/jsonapi_cross_bundles/drupal-11-compatibility.patch @@ -0,0 +1,24 @@ +diff --git a/jsonapi_cross_bundles.info.yml b/jsonapi_cross_bundles.info.yml +index 57e596dc6fbb5860c38db5e5878dfce519bdd5a9..563c7b3918189e98392889144729525c5cf9665f 100644 +--- a/jsonapi_cross_bundles.info.yml ++++ b/jsonapi_cross_bundles.info.yml +@@ -1,6 +1,6 @@ + name: "JSON:API Cross Bundles" + description: "Add cross-bundle resource collections for Drupal's JSON API module" +-core_version_requirement: ^8.7.7 || ^9 || ^10 ++core_version_requirement: ^8.7.7 || ^9 || ^10 || ^11 + type: module + dependencies: + - drupal:jsonapi +diff --git a/tests/modules/jsonapi_cross_bundles_test/jsonapi_cross_bundles_test.info.yml b/tests/modules/jsonapi_cross_bundles_test/jsonapi_cross_bundles_test.info.yml +index b66b165b2dc41599ce5819a3cdecbb650368d9e8..d71946689649df5dbd96269275e5d93d7577a5fd 100644 +--- a/tests/modules/jsonapi_cross_bundles_test/jsonapi_cross_bundles_test.info.yml ++++ b/tests/modules/jsonapi_cross_bundles_test/jsonapi_cross_bundles_test.info.yml +@@ -1,6 +1,6 @@ + name: 'JSON:API Cross Bundles Test' + description: Hooks for testing +-core_version_requirement: ^8.7.7 || ^9 || ^10 ++core_version_requirement: ^8.7.7 || ^9 || ^10 || ^11 + type: module + dependencies: + - jsonapi_cross_bundles:jsonapi_cross_bundles_test diff --git a/patches/multivalue_form_element/drupal-11-compatibility.patch b/patches/multivalue_form_element/drupal-11-compatibility.patch new file mode 100644 index 00000000..9b543e13 --- /dev/null +++ b/patches/multivalue_form_element/drupal-11-compatibility.patch @@ -0,0 +1,23 @@ +diff --git a/multivalue_form_element.info.yml b/multivalue_form_element.info.yml +--- a/multivalue_form_element.info.yml ++++ b/multivalue_form_element.info.yml (date 1678886199000) +@@ -1,5 +1,5 @@ + name: Multi-value form element + description: Provides a multi-value form element that wraps any number of form elements. + type: module +-core_version_requirement: ^9.3 || ^10 ++core_version_requirement: ^10.1 || ^11 + +diff --git a/tests/modules/multivalue_form_element_test/multivalue_form_element_test.info.yml b/tests/modules/multivalue_form_element_test/multivalue_form_element_test.info.yml +--- a/tests/modules/multivalue_form_element_test/multivalue_form_element_test.info.yml ++++ b/tests/modules/multivalue_form_element_test/multivalue_form_element_test.info.yml (date 1735000242756) +@@ -2,7 +2,7 @@ + description: Test module for Multi-value form element. + type: module + package: Testing +-core_version_requirement: ^9.3 || ^10 ++core_version_requirement: ^10.1 || ^11 + + dependencies: + - drupal:multivalue_form_element + diff --git a/patches/responsive_favicons/drupal-11-compatibility.patch b/patches/responsive_favicons/drupal-11-compatibility.patch new file mode 100644 index 00000000..8fbf0551 --- /dev/null +++ b/patches/responsive_favicons/drupal-11-compatibility.patch @@ -0,0 +1,114 @@ +diff --git a/responsive_favicons.info.yml b/responsive_favicons.info.yml +index d9fa082f4bbefc230bda210954a08a4f9f8674ad..d2c32e4add0d141ca60acfda9e25e72253c8351a 100644 +--- a/responsive_favicons.info.yml ++++ b/responsive_favicons.info.yml +@@ -1,7 +1,7 @@ + name: 'Responsive Favicons' + type: module + description: 'Add responsive favicons to your site based on the code from https://realfavicongenerator.net/' +-core_version_requirement: ^9.3 || ^10 ++core_version_requirement: ^10.3 || ^11 + package: User interface + configure: responsive_favicons.admin + dependencies: +diff --git a/src/Form/ResponsiveFaviconsAdmin.php b/src/Form/ResponsiveFaviconsAdmin.php +index ef0636fc786e05a76446bc81c8e442ee903619e2..7ce3c9833c9f49e1181aeff2a3d363fc8934253f 100644 +--- a/src/Form/ResponsiveFaviconsAdmin.php ++++ b/src/Form/ResponsiveFaviconsAdmin.php +@@ -2,13 +2,16 @@ + + namespace Drupal\responsive_favicons\Form; + ++use Drupal\Core\Config\ConfigFactoryInterface; ++use Drupal\Core\Config\TypedConfigManagerInterface; + use Drupal\Core\File\Exception\FileException; + use Drupal\Core\File\Exception\FileWriteException; ++use Drupal\Core\File\FileExists; ++use Drupal\Core\File\FileSystemInterface; + use Drupal\Core\Form\ConfigFormBase; + use Drupal\Core\Form\FormStateInterface; + use Drupal\Core\Messenger\MessengerTrait; + use Drupal\Core\Site\Settings; +-use Drupal\Core\File\FileSystemInterface; + use Drupal\Core\StringTranslation\StringTranslationTrait; + use Symfony\Component\DependencyInjection\ContainerInterface; + +@@ -29,13 +32,30 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + */ + protected $fileSystem; + ++ /** ++ * Constructs a ResponsiveFaviconsAdmin object. ++ * ++ * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory ++ * The factory for configuration objects. ++ * @param \Drupal\Core\File\FileSystemInterface $fileSystem ++ * The file system service. ++ * @param \Drupal\Core\Config\TypedConfigManagerInterface|null $typedConfigManager ++ * The typed config manager. ++ */ ++ public function __construct(ConfigFactoryInterface $config_factory, FileSystemInterface $fileSystem, $typedConfigManager = NULL) { ++ parent::__construct($config_factory, $typedConfigManager); ++ $this->fileSystem = $fileSystem; ++ } ++ + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { +- $instance = parent::create($container); +- $instance->fileSystem = $container->get('file_system'); +- return $instance; ++ return new static( ++ $container->get('config.factory'), ++ $container->get('file_system'), ++ $container->get('config.typed') ?? NULL, ++ ); + } + + /** +@@ -170,7 +190,7 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + $local_cache = NULL; + if (!empty($_FILES['files']['name']['upload'])) { + $validators = ['file_validate_extensions' => ['zip']]; +- if (!($finfo = file_save_upload('upload', $validators, NULL, 0, FileSystemInterface::EXISTS_REPLACE))) { ++ if (!($finfo = file_save_upload('upload', $validators, NULL, 0, FileExists::Rename))) { + // Failed to upload the file. file_save_upload() calls + // \Drupal\Core\Messenger\MessengerInterface::addError() on failure. + return; +@@ -203,7 +223,7 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + foreach ($files as $file) { + // Handle exceptions when copy does not happen correctly. + try { +- $success = $this->fileSystem->copy($directory . '/' . $file, $destination, FileSystemInterface::EXISTS_REPLACE); ++ $success = $this->fileSystem->copy($directory . '/' . $file, $destination, FileExists::Rename); + } + catch (FileException $e) { + $success = FALSE; +@@ -220,7 +240,7 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + $find = preg_quote('"\/android-chrome', '/'); + $replace = '"' . str_replace('/', '\/', _responsive_favicons_normalise_path('/android-chrome')); + $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); +- $this->fileSystem->saveData($file_contents, $uri, FileSystemInterface::EXISTS_REPLACE); ++ $this->fileSystem->saveData($file_contents, $uri, FileExists::Rename); + } + // Rewrite the paths of the XML files. + elseif (preg_match('/\.xml$/', $file)) { +@@ -228,7 +248,7 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + $find = preg_quote('"/mstile', '/'); + $replace = '"' . _responsive_favicons_normalise_path('/mstile'); + $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); +- $this->fileSystem->saveData($file_contents, $uri, FileSystemInterface::EXISTS_REPLACE); ++ $this->fileSystem->saveData($file_contents, $uri, FileExists::Rename); + } + // Rewrite the paths of the WEBMANIFEST files. + elseif (preg_match('/\.webmanifest$/', $file)) { +@@ -236,7 +256,7 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + $find = preg_quote('"/android-chrome', '/'); + $replace = '"' . _responsive_favicons_normalise_path('/android-chrome'); + $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); +- $this->fileSystem->saveData($file_contents, $uri, FileSystemInterface::EXISTS_REPLACE); ++ $this->fileSystem->saveData($file_contents, $uri, FileExists::Rename); + } + } + catch (FileWriteException $e) { diff --git a/patches/simple_oauth/2946882-c33fa214.patch b/patches/simple_oauth/2946882-c33fa214.patch new file mode 100644 index 00000000..100a402f --- /dev/null +++ b/patches/simple_oauth/2946882-c33fa214.patch @@ -0,0 +1,728 @@ +diff --git a/simple_oauth.module b/simple_oauth.module +index 70c65b0bd409ceddee0238d312341e3ece4d0945..6bc782d1b7b93039ac2697db7008ad439fdffe91 100644 +--- a/simple_oauth.module ++++ b/simple_oauth.module +@@ -11,17 +11,18 @@ use Drupal\Core\Entity\EntityTypeInterface; + use Drupal\Core\Field\BaseFieldDefinition; + use Drupal\Core\Field\FieldStorageDefinitionInterface; + use Drupal\Core\Form\FormStateInterface; +-use Drupal\Core\Session\AccountInterface; + use Drupal\Core\StringTranslation\TranslatableMarkup; + use Drupal\Core\Url; ++use Drupal\simple_oauth\EntityUpdateHookHandler; + use Drupal\consumers\Entity\ConsumerInterface; ++use Drupal\user\UserInterface; + use Symfony\Component\HttpFoundation\RedirectResponse; + + /** + * Implements hook_cron(). + */ + function simple_oauth_cron() { +- /** @var \Drupal\simple_oauth\ExpiredCollector $collector */ ++ /** @var \Drupal\simple_oauth\ExpiredCollectorInterface $collector */ + $collector = \Drupal::service('simple_oauth.expired_collector'); + $config = \Drupal::config('simple_oauth.settings'); + $logger = \Drupal::logger('simple_oauth'); +@@ -39,15 +40,14 @@ function simple_oauth_cron() { + * Implements hook_entity_update(). + */ + function simple_oauth_entity_update(EntityInterface $entity) { +- /** @var \Drupal\simple_oauth\ExpiredCollector $collector */ +- $collector = \Drupal::service('simple_oauth.expired_collector'); +- // Collect the affected tokens and expire them. +- if ($entity instanceof AccountInterface) { +- $collector->deleteMultipleTokens($collector->collectForAccount($entity)); +- } +- if ($entity instanceof ConsumerInterface) { +- $collector->deleteMultipleTokens($collector->collectForClient($entity)); +- } ++ \Drupal::service(EntityUpdateHookHandler::class)->handleEntityUpdate($entity); ++} ++ ++/** ++ * Implements hook_ENTITY_TYPE_predelete() for user entities. ++ */ ++function simple_oauth_user_predelete(UserInterface $entity) { ++ \Drupal::service(EntityUpdateHookHandler::class)->handleUserDelete($entity); + } + + /** +diff --git a/simple_oauth.services.yml b/simple_oauth.services.yml +index 2fbc8a929bab56f4c507be3c2dee6a829fc28c51..f2e38a9bf5400fcdc76b88d41e3591121d996f07 100644 +--- a/simple_oauth.services.yml ++++ b/simple_oauth.services.yml +@@ -108,6 +108,10 @@ services: + simple_oauth.known_clients: + class: \Drupal\simple_oauth\KnownClientsRepository + arguments: [ '@user.data' ] ++ Drupal\simple_oauth\EntityUpdateHookHandler: ++ arguments: ++ - '@simple_oauth.expired_collector' ++ - '@event_dispatcher' + + # Services for OpenID Connect. + Drupal\simple_oauth\OpenIdConnect\UserIdentityProvider: +diff --git a/src/EntityUpdateHookHandler.php b/src/EntityUpdateHookHandler.php +new file mode 100644 +index 0000000000000000000000000000000000000000..d827a516eb6429e90122ee6d57a2c8c83ca7f749 +--- /dev/null ++++ b/src/EntityUpdateHookHandler.php +@@ -0,0 +1,100 @@ ++expiredCollector = $expired_collector; ++ $this->eventDispatcher = $event_dispatcher; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function handleEntityUpdate(EntityInterface $entity): void { ++ // Collect the affected tokens and expire them. ++ if ($entity instanceof UserInterface) { ++ // Following the Drupal core pattern, revoke access to the system when ++ // password has been changed. ++ $password_changed = $entity->pass->value !== $entity->original->pass->value; ++ ++ // When the account got blocked, we should revoke user's access to ++ // the site. ++ $account_blocked = !$entity->isActive() && $entity->original->isActive(); ++ ++ // When roles have changed, we should revoke the token to prevent ++ // potential access to the content where the user has no access ++ // to anymore. ++ $roles_new = $entity->getRoles(); ++ $roles_old = $entity->original->getRoles(); ++ $roles_changed = !empty(array_merge( ++ array_diff($roles_new, $roles_old), ++ array_diff($roles_old, $roles_new) ++ )); ++ ++ $event = new UserUpdateTokenInvalidationEvent( ++ $password_changed || $account_blocked || $roles_changed, ++ $entity ++ ); ++ $this->eventDispatcher->dispatch($event); ++ if ($event->willInvalidateAccessTokens()) { ++ $this->expiredCollector ++ ->deleteMultipleTokens($this->expiredCollector->collectForAccount( ++ $entity, ++ $event->willInvalidateRefreshTokens() ++ )); ++ } ++ } ++ if ($entity instanceof ConsumerInterface) { ++ $this->expiredCollector ++ ->deleteMultipleTokens($this->expiredCollector->collectForClient($entity)); ++ } ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function handleUserDelete(UserInterface $user): void { ++ $this->expiredCollector ++ ->deleteMultipleTokens($this->expiredCollector->collectForAccount( ++ $user, ++ TRUE ++ )); ++ } ++ ++} +diff --git a/src/EntityUpdateHookHandlerInterface.php b/src/EntityUpdateHookHandlerInterface.php +new file mode 100644 +index 0000000000000000000000000000000000000000..6fd91a49c1a7c65dea03fb49efbb387e9095feb4 +--- /dev/null ++++ b/src/EntityUpdateHookHandlerInterface.php +@@ -0,0 +1,33 @@ ++user; ++ } ++ ++ /** ++ * Get the unchanged user entity. ++ * ++ * @return \Drupal\user\UserInterface|null ++ * The unchanged user entity. ++ */ ++ public function getOriginalUser(): ?UserInterface { ++ return $this->user->original ?? NULL; ++ } ++ ++ /** ++ * Setter for access token invalidation. ++ * ++ * @param bool $flag ++ * Whether to invalidate access tokens. ++ */ ++ public function setInvalidateAccessTokens(bool $flag): void { ++ $this->invalidateAccessTokens = $flag; ++ } ++ ++ /** ++ * Getter for access token invalidation behavior. ++ * ++ * @return bool ++ * Determination. ++ */ ++ public function willInvalidateAccessTokens(): bool { ++ return $this->invalidateAccessTokens; ++ } ++ ++ /** ++ * Getter for refresh token invalidation behavior. ++ * ++ * @return bool ++ * Determination. ++ */ ++ public function willInvalidateRefreshTokens(): bool { ++ return $this->invalidateRefreshTokens; ++ } ++ ++ /** ++ * Setter for refresh token invalidation. ++ * ++ * @param bool $flag ++ * Whether to invalidate refresh tokens. ++ */ ++ public function setInvalidateRefreshTokens(bool $flag): void { ++ $this->invalidateRefreshTokens = $flag; ++ if ($flag === TRUE) { ++ $this->invalidateAccessTokens = TRUE; ++ } ++ } ++ ++ /** ++ * Getter for Simple OAuth's determination of access characteristic change. ++ * ++ * @return bool ++ * TRUE if the user's roles, password or status has changed. ++ */ ++ public function haveUserAccessCharacteristicsChanged(): bool { ++ return $this->haveAccessCharacteristicsChanged; ++ } ++ ++ /** ++ * Constructor. ++ * ++ * @param bool $access_characteristics_have_changed ++ * Flag for whether user access characteristics have changed. ++ * @param \Drupal\user\UserInterface $user ++ * The user entity. ++ */ ++ public function __construct(bool $access_characteristics_have_changed, UserInterface $user) { ++ $this->haveAccessCharacteristicsChanged = $access_characteristics_have_changed; ++ $this->user = $user; ++ } ++ ++} +diff --git a/src/ExpiredCollector.php b/src/ExpiredCollector.php +index c8e498626d58d3fc58193a4ac5ac5e7de9e6798b..9cb4504a9b847169828766025ef97f6bfe11c643 100644 +--- a/src/ExpiredCollector.php ++++ b/src/ExpiredCollector.php +@@ -12,7 +12,7 @@ use Drupal\consumers\Entity\Consumer; + /** + * Service in charge of deleting or expiring tokens that cannot be used anymore. + */ +-class ExpiredCollector { ++class ExpiredCollector implements ExpiredCollectorInterface { + + /** + * The token storage. +@@ -52,13 +52,7 @@ class ExpiredCollector { + } + + /** +- * Collect all expired token ids. +- * +- * @param int $limit +- * Number of tokens to fetch. +- * +- * @return \Drupal\simple_oauth\Entity\Oauth2TokenInterface[] +- * The expired tokens. ++ * {@inheritdoc} + */ + public function collect(int $limit = 0): array { + $query = $this->tokenStorage->getQuery(); +@@ -75,21 +69,17 @@ class ExpiredCollector { + } + + /** +- * Collect all the tokens associated with the provided account. +- * +- * @param \Drupal\Core\Session\AccountInterface $account +- * The account. +- * +- * @return \Drupal\simple_oauth\Entity\Oauth2TokenInterface[] +- * The tokens. ++ * {@inheritdoc} + */ +- public function collectForAccount(AccountInterface $account): array { ++ public function collectForAccount(AccountInterface $account, bool $include_refresh_tokens = FALSE): array { + $clients = []; + $output = []; + $query = $this->tokenStorage->getQuery(); + $query->accessCheck(); + $query->condition('auth_user_id', $account->id()); +- $query->condition('bundle', 'refresh_token', '!='); ++ if (!$include_refresh_tokens) { ++ $query->condition('bundle', 'refresh_token', '!='); ++ } + $entity_ids = $query->execute(); + $output = $entity_ids + ? array_values($this->tokenStorage->loadMultiple(array_values($entity_ids))) +@@ -118,13 +108,7 @@ class ExpiredCollector { + } + + /** +- * Collect all the tokens associated a particular client. +- * +- * @param \Drupal\consumers\Entity\Consumer $client +- * The account. +- * +- * @return \Drupal\simple_oauth\Entity\Oauth2TokenInterface[] +- * The tokens. ++ * {@inheritdoc} + */ + public function collectForClient(Consumer $client): array { + $query = $this->tokenStorage->getQuery(); +@@ -139,14 +123,9 @@ class ExpiredCollector { + } + + /** +- * Deletes multiple tokens based on ID. +- * +- * @param \Drupal\simple_oauth\Entity\Oauth2TokenInterface[] $tokens +- * The token entity IDs. +- * +- * @throws \Drupal\Core\Entity\EntityStorageException ++ * {@inheritdoc} + */ +- public function deleteMultipleTokens(array $tokens = []) { ++ public function deleteMultipleTokens(array $tokens = []): void { + $this->tokenStorage->delete($tokens); + } + +diff --git a/src/ExpiredCollectorInterface.php b/src/ExpiredCollectorInterface.php +new file mode 100644 +index 0000000000000000000000000000000000000000..bc318d5e975442c16b389d9977ba472d953604dc +--- /dev/null ++++ b/src/ExpiredCollectorInterface.php +@@ -0,0 +1,58 @@ ++fileSystemChecker = $file_system_checker; +@@ -78,11 +78,11 @@ class Oauth2TokenSettingsForm extends ConfigFormBase { + public static function create(ContainerInterface $container): self { + return new static( + $container->get('config.factory'), +- $container->get('config.typed'), + $container->get('simple_oauth.filesystem_checker'), + $container->get('messenger'), + $container->get('entity_type.manager'), +- $container->get('plugin.manager.scope_provider') ++ $container->get('plugin.manager.scope_provider'), ++ $container->get('config.typed'), + ); + } + +diff --git a/src/Form/OpenIdConnectSettingsForm.php b/src/Form/OpenIdConnectSettingsForm.php +index 49a7eb11b4409005c1aaf4162f2edfcf6f3eb7b9..131b32e341a24b13d5ab4d37609d5d39d4ddb9d3 100644 +--- a/src/Form/OpenIdConnectSettingsForm.php ++++ b/src/Form/OpenIdConnectSettingsForm.php +@@ -21,7 +21,7 @@ class OpenIdConnectSettingsForm extends ConfigFormBase { + * + * @var string[] + */ +- private $claimNames; ++ private array $claimNames; + + /** + * Oauth2TokenSettingsForm constructor. +@@ -32,8 +32,14 @@ class OpenIdConnectSettingsForm extends ConfigFormBase { + * The typed config manager. + * @param string[] $claim_names + * The names of the claims. ++ * @param \Drupal\Core\Config\TypedConfigManagerInterface|null $typedConfigManager ++ * The typed config object. + */ +- public function __construct(ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typedConfigManager, array $claim_names) { ++ public function __construct( ++ ConfigFactoryInterface $config_factory, ++ array $claim_names, ++ TypedConfigManager $typedConfigManager = NULL, ++ ) { + parent::__construct($config_factory, $typedConfigManager); + $this->claimNames = $claim_names; + } +@@ -50,8 +56,8 @@ class OpenIdConnectSettingsForm extends ConfigFormBase { + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory'), +- $container->get('config.typed'), +- $container->getParameter('simple_oauth.openid.claims') ++ $container->getParameter('simple_oauth.openid.claims'), ++ $container->get('config.typed') + ); + } + +diff --git a/tests/src/Unit/EntityUpdateHandlerTest.php b/tests/src/Unit/EntityUpdateHandlerTest.php +new file mode 100644 +index 0000000000000000000000000000000000000000..899e9aad2f3cc03f2082e98460e8d08109d4322e +--- /dev/null ++++ b/tests/src/Unit/EntityUpdateHandlerTest.php +@@ -0,0 +1,140 @@ ++expiredCollector = $this->prophesize(ExpiredCollectorInterface::class); ++ $this->expiredCollector ++ ->collectForAccount(Argument::type(UserInterface::class), Argument::type('bool')) ++ ->willReturn([]); ++ ++ $event_dispatcher = $this->prophesize(EventDispatcherInterface::class); ++ $event_dispatcher ++ ->dispatch(Argument::type(UserUpdateTokenInvalidationEvent::class)) ++ ->willReturn(new Event()); ++ ++ $this->updateHandler = new EntityUpdateHookHandler( ++ $this->expiredCollector->reveal(), ++ $event_dispatcher->reveal() ++ ); ++ } ++ ++ /** ++ * Tokens should be invalidated when user roles change. ++ * ++ * @covers ::entityUpdateHandler ++ */ ++ public function testEntityUpdateHandlerRoleChange() { ++ $user = $this->prophesize(UserInterface::class); ++ $user->getRoles()->willReturn(['role1']); ++ $user->pass = (object) ['value' => 'password']; ++ $user->isActive()->willReturn(TRUE); ++ ++ $user_original = $this->prophesize(UserInterface::class); ++ $user_original->getRoles()->willReturn(['role1', 'role2']); ++ $user_original->pass = (object) ['value' => 'password']; ++ $user_original->isActive()->willReturn(TRUE); ++ $user->original = $user_original->reveal(); ++ ++ $this->updateHandler->handleEntityUpdate($user->reveal()); ++ $this->expiredCollector->deleteMultipleTokens([])->shouldBeCalled(); ++ } ++ ++ /** ++ * Tokens should be invalidated when user password changes. ++ * ++ * @covers ::entityUpdateHandler ++ */ ++ public function testEntityUpdateHandlerPasswordChange() { ++ $user = $this->prophesize(UserInterface::class); ++ $user->getRoles()->willReturn(['role1']); ++ $user->pass = (object) ['value' => 'new_password']; ++ $user->isActive()->willReturn(TRUE); ++ ++ $user_original = $this->prophesize(UserInterface::class); ++ $user_original->getRoles()->willReturn(['role1']); ++ $user_original->pass = (object) ['value' => 'password']; ++ $user_original->isActive()->willReturn(TRUE); ++ $user->original = $user_original->reveal(); ++ ++ $this->updateHandler->handleEntityUpdate($user->reveal()); ++ $this->expiredCollector->deleteMultipleTokens([])->shouldBeCalled(); ++ } ++ ++ /** ++ * Tokens should be invalidated when user status changes. ++ * ++ * @covers ::entityUpdateHandler ++ */ ++ public function testEntityUpdateHandlerStatusChange() { ++ $user = $this->prophesize(UserInterface::class); ++ $user->getRoles()->willReturn(['role1']); ++ $user->pass = (object) ['value' => 'password']; ++ $user->isActive()->willReturn(FALSE); ++ ++ $user_original = $this->prophesize(UserInterface::class); ++ $user_original->getRoles()->willReturn(['role1']); ++ $user_original->pass = (object) ['value' => 'password']; ++ $user_original->isActive()->willReturn(TRUE); ++ $user->original = $user_original->reveal(); ++ ++ $this->updateHandler->handleEntityUpdate($user->reveal()); ++ $this->expiredCollector->deleteMultipleTokens([])->shouldBeCalled(); ++ } ++ ++ /** ++ * Tokens should be invalidated when user roles, status and pass are same. ++ * ++ * @covers ::entityUpdateHandler ++ */ ++ public function testEntityUpdateHandlerNoChange() { ++ $user = $this->prophesize(UserInterface::class); ++ $user->getRoles()->willReturn(['role1']); ++ $user->pass = (object) ['value' => 'password']; ++ $user->isActive()->willReturn(TRUE); ++ ++ $user_original = $this->prophesize(UserInterface::class); ++ $user_original->getRoles()->willReturn(['role1']); ++ $user_original->pass = (object) ['value' => 'password']; ++ $user_original->isActive()->willReturn(TRUE); ++ $user->original = $user_original->reveal(); ++ ++ $this->updateHandler->handleEntityUpdate($user->reveal()); ++ $this->expiredCollector->deleteMultipleTokens([])->shouldBeCalled(); ++ } ++ ++} diff --git a/patches/simple_oauth/3082984-d2c39a92.patch b/patches/simple_oauth/3082984-d2c39a92.patch new file mode 100644 index 00000000..7ee23eab --- /dev/null +++ b/patches/simple_oauth/3082984-d2c39a92.patch @@ -0,0 +1,279 @@ +diff --git a/simple_oauth.services.yml b/simple_oauth.services.yml +index 2fbc8a929bab56f4c507be3c2dee6a829fc28c51..7eb33261421be870fae5f8eaf786ca9961f7e683 100644 +--- a/simple_oauth.services.yml ++++ b/simple_oauth.services.yml +@@ -24,7 +24,6 @@ services: + - '@simple_oauth.page_cache_request_policy.disallow_oauth2_token_requests' + - '@psr7.http_message_factory' + - '@psr7.http_foundation_factory' +- - '@logger.channel.simple_oauth' + tags: + - { name: authentication_provider, provider_id: oauth2, global: TRUE, priority: 35 } + simple_oauth.page_cache_request_policy.disallow_oauth2_token_requests: +@@ -32,6 +31,11 @@ services: + public: false + tags: + - { name: page_cache_request_policy } ++ Drupal\simple_oauth\EventSubscriber\ExceptionLoggingSubscriber: ++ decorates: 'exception.logger' ++ arguments: ++ - '@Drupal\simple_oauth\EventSubscriber\ExceptionLoggingSubscriber.inner' ++ - '@logger.channel.simple_oauth' + + simple_oauth.normalizer.oauth2_token: + class: Drupal\simple_oauth\Normalizer\TokenEntityNormalizer +diff --git a/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php b/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php +index 47d0e73f07282de8c178b3dbace964d56f44a50e..e702c3abb8b15b36f3811d14eb5e3448e3cfa034 100644 +--- a/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php ++++ b/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php +@@ -5,16 +5,14 @@ namespace Drupal\simple_oauth\Authentication\Provider; + use Drupal\Core\Authentication\AuthenticationProviderInterface; + use Drupal\Core\Entity\EntityTypeManagerInterface; + use Drupal\Core\StringTranslation\StringTranslationTrait; +-use Drupal\Core\Utility\Error; + use Drupal\simple_oauth\Authentication\TokenAuthUser; ++use Drupal\simple_oauth\Exception\OAuthUnauthorizedHttpException; + use Drupal\simple_oauth\PageCache\SimpleOauthRequestPolicyInterface; + use Drupal\simple_oauth\Server\ResourceServerFactoryInterface; + use League\OAuth2\Server\Exception\OAuthServerException; +-use Psr\Log\LoggerInterface; + use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; + use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; + use Symfony\Component\HttpFoundation\Request; +-use Symfony\Component\HttpKernel\Exception\HttpException; + + /** + * OAuth2 authentication provider. +@@ -60,13 +58,6 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa + */ + protected HttpFoundationFactoryInterface $httpFoundationFactory; + +- /** +- * The simple_oauth logger channel. +- * +- * @var \Psr\Log\LoggerInterface +- */ +- protected LoggerInterface $logger; +- + /** + * Constructs an HTTP basic authentication provider object. + * +@@ -80,8 +71,6 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa + * The HTTP message factory. + * @param \Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface $http_foundation_factory + * The HTTP foundation factory. +- * @param \Psr\Log\LoggerInterface $logger +- * The simple_oauth logger channel. + */ + public function __construct( + ResourceServerFactoryInterface $resource_server_factory, +@@ -89,14 +78,12 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa + SimpleOauthRequestPolicyInterface $page_cache_request_policy, + HttpMessageFactoryInterface $http_message_factory, + HttpFoundationFactoryInterface $http_foundation_factory, +- LoggerInterface $logger, + ) { + $this->resourceServerFactory = $resource_server_factory; + $this->entityTypeManager = $entity_type_manager; + $this->oauthPageCacheRequestPolicy = $page_cache_request_policy; + $this->httpMessageFactory = $http_message_factory; + $this->httpFoundationFactory = $http_foundation_factory; +- $this->logger = $logger; + } + + /** +@@ -130,11 +117,10 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa + $auth_request = $this->httpFoundationFactory->createRequest($output_psr7_request); + } + catch (OAuthServerException $exception) { +- Error::logException($this->logger, $exception); +- +- throw new HttpException( +- $exception->getHttpStatusCode(), +- $exception->getHint(), ++ // Forward authentication challenge to be interpreted by the requester. ++ throw new OAuthUnauthorizedHttpException( ++ $this->getUnauthorizedExceptionChallenge($request, $exception), ++ $exception->getMessage(), + $exception + ); + } +@@ -156,10 +142,9 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa + ['%name' => $account->getAccountName()] + ) + ); +- Error::logException($this->logger, $exception); +- throw new HttpException( +- $exception->getHttpStatusCode(), +- $exception->getHint(), ++ throw new OAuthUnauthorizedHttpException( ++ $this->getUnauthorizedExceptionChallenge($request, $exception), ++ $exception->getMessage(), + $exception + ); + } +@@ -174,4 +159,25 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa + return $account; + } + ++ ++ /** ++ * Formats challenge for unauthorized exception. ++ * ++ * @param \Symfony\Component\HttpFoundation\Request $request ++ * Request. ++ * @param \League\OAuth2\Server\Exception\OAuthServerException $exception ++ * Exception. ++ * ++ * @return string ++ * Formatted challenge for result. ++ */ ++ protected function getUnauthorizedExceptionChallenge(Request $request, OAuthServerException $exception) { ++ return sprintf( ++ '%s realm="OAuth", error="%s", error_description="%s"', ++ strpos($request->headers->get('Authorization'), 'Bearer') === 0 ? 'Bearer' : 'Basic', ++ $exception->getErrorType(), ++ $exception->getHint() ++ ); ++ } ++ + } +diff --git a/src/Controller/Oauth2AuthorizeController.php b/src/Controller/Oauth2AuthorizeController.php +index a69e0ea0df53489f27cce24532385259339d3227..6c39bb265276a322e7c81f385a0f4134eb9b2db4 100644 +--- a/src/Controller/Oauth2AuthorizeController.php ++++ b/src/Controller/Oauth2AuthorizeController.php +@@ -166,7 +166,7 @@ class Oauth2AuthorizeController extends ControllerBase { + } + } + catch (OAuthServerException $exception) { +- Error::logException($this->logger, $exception); ++ $this->logger->error($exception->getMessage() . ' Hint: ' . $exception->getHint() . '.'); + $response = $exception->generateHttpResponse($server_response); + } + +diff --git a/src/Controller/Oauth2Token.php b/src/Controller/Oauth2Token.php +index 51e4d80449f79dd80653e7afe51f459b68789c9b..84ee091f4362cd3d79ce434266f1ba826f0b0fe3 100644 +--- a/src/Controller/Oauth2Token.php ++++ b/src/Controller/Oauth2Token.php +@@ -10,6 +10,7 @@ use League\OAuth2\Server\Exception\OAuthServerException; + use League\OAuth2\Server\Repositories\ClientRepositoryInterface; + use Psr\Http\Message\ResponseInterface; + use Psr\Log\LoggerInterface; ++use Psr\Log\LogLevel; + use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; + use Symfony\Component\DependencyInjection\ContainerInterface; + use Symfony\Component\HttpFoundation\Request; +@@ -114,7 +115,10 @@ class Oauth2Token extends ControllerBase { + $response = $server->respondToAccessTokenRequest($server_request, $server_response); + } + catch (OAuthServerException $exception) { +- Error::logException($this->logger, $exception); ++ $this->logger->log( ++ $exception->getCode() < 500 ? LogLevel::NOTICE : LogLevel::ERROR, ++ $exception->getMessage() . ' Hint: ' . $exception->getHint() . '.' ++ ); + $response = $exception->generateHttpResponse($server_response); + } + +diff --git a/src/EventSubscriber/ExceptionLoggingSubscriber.php b/src/EventSubscriber/ExceptionLoggingSubscriber.php +new file mode 100644 +index 0000000000000000000000000000000000000000..cf351d3fcf89cdfb43944642721355d20d322c3e +--- /dev/null ++++ b/src/EventSubscriber/ExceptionLoggingSubscriber.php +@@ -0,0 +1,65 @@ ++inner = $inner; ++ $this->logger = $logger; ++ } ++ ++ /** ++ * Log exceptions. ++ * ++ * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event ++ * The event to process. ++ */ ++ public function onException(ExceptionEvent $event): void { ++ if ($event->getThrowable() instanceof OAuthUnauthorizedHttpException) { ++ $throwable = $event->getThrowable(); ++ $this->logger->notice($throwable->getMessage() . ++ ' Hint: ' . $throwable->getPrevious()->getHint() . '.'); ++ return; ++ } ++ $this->inner->onException($event); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public static function getSubscribedEvents() { ++ return CoreExceptionLoggingSubscriber::getSubscribedEvents(); ++ } ++ ++} +diff --git a/src/Exception/OAuthUnauthorizedHttpException.php b/src/Exception/OAuthUnauthorizedHttpException.php +new file mode 100644 +index 0000000000000000000000000000000000000000..75baa81aef6b1f8517f95cb8889d723b74975c0f +--- /dev/null ++++ b/src/Exception/OAuthUnauthorizedHttpException.php +@@ -0,0 +1,7 @@ ++oauthPageCacheRequestPolicy = new DisallowSimpleOauthRequests(); + $http_message_factory = $this->prophesize(HttpMessageFactoryInterface::class); + $http_foundation_factory = $this->prophesize(HttpFoundationFactoryInterface::class); +- $logger = $this->prophesize(LoggerChannelInterface::class); + $this->provider = new SimpleOauthAuthenticationProvider( + $resource_server_factory->reveal(), + $entity_type_manager->reveal(), + $this->oauthPageCacheRequestPolicy, + $http_message_factory->reveal(), + $http_foundation_factory->reveal(), +- $logger->reveal() + ); + } diff --git a/patches/simple_oauth/SO52-3082984-12.patch b/patches/simple_oauth/SO52-3082984-12.patch deleted file mode 100644 index f64be556..00000000 --- a/patches/simple_oauth/SO52-3082984-12.patch +++ /dev/null @@ -1,420 +0,0 @@ -diff --git a/simple_oauth.services.yml b/simple_oauth.services.yml -index 0455a1a..0058616 100644 ---- a/simple_oauth.services.yml -+++ b/simple_oauth.services.yml -@@ -17,6 +17,7 @@ services: - - '@simple_oauth.server.resource_server' - - '@entity_type.manager' - - '@simple_oauth.page_cache_request_policy.disallow_oauth2_token_requests' -+ - '@logger.channel.simple_oauth' - tags: - - { name: authentication_provider, provider_id: oauth2, global: TRUE, priority: 35 } - simple_oauth.page_cache_request_policy.disallow_oauth2_token_requests: -@@ -24,7 +25,14 @@ services: - public: false - tags: - - { name: page_cache_request_policy } -- -+ logger.channel.simple_oauth: -+ parent: logger.channel_base -+ arguments: ['simple_oauth'] -+ Drupal\simple_oauth\EventSubscriber\ExceptionLoggingSubscriber: -+ decorates: 'exception.logger' -+ arguments: -+ - '@Drupal\simple_oauth\EventSubscriber\ExceptionLoggingSubscriber.inner' -+ - '@logger.channel.simple_oauth' - simple_oauth.normalizer.oauth2_token: - class: Drupal\simple_oauth\Normalizer\TokenEntityNormalizer - arguments: [ '@entity_type.manager' ] -diff --git a/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php b/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php -index cf93cb9..c8978ae 100644 ---- a/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php -+++ b/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php -@@ -6,11 +6,11 @@ use Drupal\Core\Authentication\AuthenticationProviderInterface; - use Drupal\Core\Entity\EntityTypeManagerInterface; - use Drupal\Core\StringTranslation\StringTranslationTrait; - use Drupal\simple_oauth\Authentication\TokenAuthUser; -+use Drupal\simple_oauth\Exception\OAuthUnauthorizedHttpException; - use Drupal\simple_oauth\PageCache\SimpleOauthRequestPolicyInterface; - use Drupal\simple_oauth\Server\ResourceServerInterface; - use League\OAuth2\Server\Exception\OAuthServerException; - use Symfony\Component\HttpFoundation\Request; --use Symfony\Component\HttpKernel\Exception\HttpException; - - /** - * @internal -@@ -78,12 +78,10 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa - $auth_request = $this->resourceServer->validateAuthenticatedRequest($request); - } - catch (OAuthServerException $exception) { -- // Procedural code here is hard to avoid. -- watchdog_exception('simple_oauth', $exception); -- -- throw new HttpException( -- $exception->getHttpStatusCode(), -- $exception->getHint(), -+ // Forward authentication challenge to be interpreted by the requester. -+ throw new OAuthUnauthorizedHttpException( -+ $this->getUnauthorizedExceptionChallenge($request, $exception), -+ $exception->getMessage(), - $exception - ); - } -@@ -106,10 +104,9 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa - ['%name' => $account->getAccountName()] - ) - ); -- watchdog_exception('simple_oauth', $exception); -- throw new HttpException( -- $exception->getHttpStatusCode(), -- $exception->getHint(), -+ throw new OAuthUnauthorizedHttpException( -+ $this->getUnauthorizedExceptionChallenge($request, $exception), -+ $exception->getMessage(), - $exception - ); - } -@@ -124,4 +121,25 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa - return $account; - } - -+ -+ /** -+ * Formats challenge for unauthorized exception. -+ * -+ * @param \Symfony\Component\HttpFoundation\Request $request -+ * Request. -+ * @param \League\OAuth2\Server\Exception\OAuthServerException $exception -+ * Exception. -+ * -+ * @return string -+ * Formatted challenge for result. -+ */ -+ protected function getUnauthorizedExceptionChallenge(Request $request, OAuthServerException $exception) { -+ return sprintf( -+ '%s realm="OAuth", error="%s", error_description="%s"', -+ strpos($request->headers->get('Authorization'), 'Bearer') === 0 ? 'Bearer' : 'Basic', -+ $exception->getErrorType(), -+ $exception->getHint() -+ ); -+ } -+ - } -diff --git a/src/Controller/Oauth2AuthorizeController.php b/src/Controller/Oauth2AuthorizeController.php -index 13dde1d..0bbb6e3 100644 ---- a/src/Controller/Oauth2AuthorizeController.php -+++ b/src/Controller/Oauth2AuthorizeController.php -@@ -17,13 +17,14 @@ use League\OAuth2\Server\Entities\ScopeEntityInterface; - use League\OAuth2\Server\Exception\OAuthServerException; - use League\OAuth2\Server\Repositories\ClientRepositoryInterface; - use League\OAuth2\Server\RequestTypes\AuthorizationRequest; -+use Psr\Log\LoggerInterface; - use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; - use Symfony\Component\DependencyInjection\ContainerInterface; - use Symfony\Component\HttpFoundation\RedirectResponse; - use Symfony\Component\HttpFoundation\Request; - - /** -- * Oauth2AuthorizeController. -+ * Controller for authorization code grant. - */ - class Oauth2AuthorizeController extends ControllerBase { - -@@ -55,13 +56,20 @@ class Oauth2AuthorizeController extends ControllerBase { - */ - protected $knownClientRepository; - -+ /** -+ * The logger channel. -+ * -+ * @var \Psr\Log\LoggerInterface -+ */ -+ protected $logger; -+ - /** - * @var \League\OAuth2\Server\Repositories\ClientRepositoryInterface - */ - protected $clientRepository; - - /** -- * Oauth2AuthorizeController construct. -+ * Oauth2AuthorizeController constructor. - * - * @param \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface $message_factory - * The PSR-7 converter. -@@ -73,19 +81,23 @@ class Oauth2AuthorizeController extends ControllerBase { - * The known client repository service. - * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $client_repository - * The client repository service. -+ * @param \Psr\Log\LoggerInterface $logger -+ * Logger channel. - */ - public function __construct( - HttpMessageFactoryInterface $message_factory, - Oauth2GrantManagerInterface $grant_manager, - ConfigFactoryInterface $config_factory, - KnownClientsRepositoryInterface $known_clients_repository, -- ClientRepositoryInterface $client_repository -+ ClientRepositoryInterface $client_repository, -+ LoggerInterface $logger - ) { - $this->messageFactory = $message_factory; - $this->grantManager = $grant_manager; - $this->configFactory = $config_factory; - $this->knownClientRepository = $known_clients_repository; - $this->clientRepository = $client_repository; -+ $this->logger = $logger; - } - - /** -@@ -97,7 +109,8 @@ class Oauth2AuthorizeController extends ControllerBase { - $container->get('plugin.manager.oauth2_grant.processor'), - $container->get('config.factory'), - $container->get('simple_oauth.known_clients'), -- $container->get('simple_oauth.repositories.client') -+ $container->get('simple_oauth.repositories.client'), -+ $container->get('logger.channel.simple_oauth') - ); - } - -@@ -166,8 +179,9 @@ class Oauth2AuthorizeController extends ControllerBase { - } - catch (OAuthServerException $exception) { - $this->messenger()->addError($this->t('Fatal error. Unable to get the authorization server.')); -- watchdog_exception('simple_oauth', $exception); -- return new RedirectResponse(Url::fromRoute('')->toString()); -+ $this->logger->error($exception->getMessage() . -+ ' Hint: ' . $exception->getHint() . '.'); -+ return RedirectResponse::create(Url::fromRoute('')->toString()); - } - if ($auth_request) { - $can_grant_codes = $this->currentUser() -diff --git a/src/Controller/Oauth2Token.php b/src/Controller/Oauth2Token.php -index 286d073..93822b5 100644 ---- a/src/Controller/Oauth2Token.php -+++ b/src/Controller/Oauth2Token.php -@@ -9,6 +9,8 @@ use League\OAuth2\Server\AuthorizationServer; - use League\OAuth2\Server\Exception\OAuthServerException; - use League\OAuth2\Server\Repositories\ClientRepositoryInterface; - use Psr\Http\Message\ServerRequestInterface; -+use Psr\Log\LoggerInterface; -+use Psr\Log\LogLevel; - use Symfony\Component\DependencyInjection\ContainerInterface; - - class Oauth2Token extends ControllerBase { -@@ -23,6 +25,11 @@ class Oauth2Token extends ControllerBase { - */ - protected $clientRepository; - -+ /** -+ * Logger channel. -+ */ -+ protected LoggerInterface $logger; -+ - /** - * Oauth2Token constructor. - * -@@ -31,9 +38,14 @@ class Oauth2Token extends ControllerBase { - * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $client_repository - * The client repository service. - */ -- public function __construct(Oauth2GrantManagerInterface $grant_manager, ClientRepositoryInterface $client_repository) { -+ public function __construct( -+ Oauth2GrantManagerInterface $grant_manager, -+ ClientRepositoryInterface $client_repository, -+ LoggerInterface $logger -+ ) { - $this->grantManager = $grant_manager; - $this->clientRepository = $client_repository; -+ $this->logger = $logger; - } - - /** -@@ -42,7 +54,8 @@ class Oauth2Token extends ControllerBase { - public static function create(ContainerInterface $container) { - return new static( - $container->get('plugin.manager.oauth2_grant.processor'), -- $container->get('simple_oauth.repositories.client') -+ $container->get('simple_oauth.repositories.client'), -+ $container->get('logger.channel.simple_oauth') - ); - } - -@@ -69,7 +82,10 @@ class Oauth2Token extends ControllerBase { - $response = $this->handleToken($request, $auth_server); - } - catch (OAuthServerException $exception) { -- watchdog_exception('simple_oauth', $exception); -+ $this->logger->log( -+ $exception->getCode() < 500 ? LogLevel::NOTICE : LogLevel::ERROR, -+ $exception->getMessage() . ' Hint: ' . $exception->getHint() . '.' -+ ); - $response = $exception->generateHttpResponse(new Response()); - } - return $response; -diff --git a/src/Entity/Form/Oauth2GenerateKeyForm.php b/src/Entity/Form/Oauth2GenerateKeyForm.php -index a51b22a..b55deea 100755 ---- a/src/Entity/Form/Oauth2GenerateKeyForm.php -+++ b/src/Entity/Form/Oauth2GenerateKeyForm.php -@@ -8,7 +8,9 @@ use Drupal\Core\Ajax\HtmlCommand; - use Drupal\Core\Ajax\InvokeCommand; - use Drupal\Core\Form\FormBase; - use Drupal\Core\Form\FormStateInterface; -+use Drupal\Core\Utility\Error; - use Drupal\simple_oauth\Service\KeyGeneratorService; -+use Psr\Log\LoggerInterface; - use Symfony\Component\DependencyInjection\ContainerInterface; - - /** -@@ -21,13 +23,20 @@ class Oauth2GenerateKeyForm extends FormBase { - */ - private $keyGen; - -+ /** -+ * @var \Psr\Log\LoggerInterface -+ */ -+ protected $logger; -+ - /** - * Oauth2GenerateKeyForm constructor. - * - * @param \Drupal\simple_oauth\Service\KeyGeneratorService $key_generator_service -+ * @param \Psr\Log\LoggerInterface $logger - */ -- public function __construct(KeyGeneratorService $key_generator_service) { -+ public function __construct(KeyGeneratorService $key_generator_service, LoggerInterface $logger) { - $this->keyGen = $key_generator_service; -+ $this->logger = $logger; - } - - /** -@@ -35,7 +44,8 @@ class Oauth2GenerateKeyForm extends FormBase { - */ - public static function create(ContainerInterface $container) { - return new static( -- $container->get('simple_oauth.key.generator') -+ $container->get('simple_oauth.key.generator'), -+ $container->get('logger.channel.simple_oauth') - ); - } - -@@ -126,7 +136,8 @@ class Oauth2GenerateKeyForm extends FormBase { - } - catch (\Exception $exception) { - // If exception log it and return an error message. -- watchdog_exception('simple_oauth', $exception); -+ $variables = Error::decodeException($exception); -+ $this->logger->error('%type: @message in %function (line %line of %file).', $variables); - $response->addCommand(new InvokeCommand('#key-error-message', 'show')); - return $response->addCommand(new HtmlCommand('#key-error-message', $exception->getMessage())); - } -diff --git a/src/EventSubscriber/ExceptionLoggingSubscriber.php b/src/EventSubscriber/ExceptionLoggingSubscriber.php -new file mode 100644 -index 0000000..cf351d3 ---- /dev/null -+++ b/src/EventSubscriber/ExceptionLoggingSubscriber.php -@@ -0,0 +1,65 @@ -+inner = $inner; -+ $this->logger = $logger; -+ } -+ -+ /** -+ * Log exceptions. -+ * -+ * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event -+ * The event to process. -+ */ -+ public function onException(ExceptionEvent $event): void { -+ if ($event->getThrowable() instanceof OAuthUnauthorizedHttpException) { -+ $throwable = $event->getThrowable(); -+ $this->logger->notice($throwable->getMessage() . -+ ' Hint: ' . $throwable->getPrevious()->getHint() . '.'); -+ return; -+ } -+ $this->inner->onException($event); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public static function getSubscribedEvents() { -+ return CoreExceptionLoggingSubscriber::getSubscribedEvents(); -+ } -+ -+} -diff --git a/src/Exception/OAuthUnauthorizedHttpException.php b/src/Exception/OAuthUnauthorizedHttpException.php -new file mode 100644 -index 0000000..75baa81 ---- /dev/null -+++ b/src/Exception/OAuthUnauthorizedHttpException.php -@@ -0,0 +1,7 @@ -+prophesize(ResourceServerInterface::class); - $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class); -+ $logger = $this->prophesize(LoggerInterface::class); - $this->oauthPageCacheRequestPolicy = new DisallowSimpleOauthRequests(); - $this->provider = new SimpleOauthAuthenticationProvider( - $resource_server->reveal(), - $entity_type_manager->reveal(), -- $this->oauthPageCacheRequestPolicy -+ $this->oauthPageCacheRequestPolicy, -+ $logger->reveal(), - ); - } diff --git a/patches/simple_oauth/custom-token-revoke-profile-update.patch b/patches/simple_oauth/custom-token-revoke-profile-update.patch deleted file mode 100644 index d18f43a1..00000000 --- a/patches/simple_oauth/custom-token-revoke-profile-update.patch +++ /dev/null @@ -1,484 +0,0 @@ -diff --git a/.gitignore b/.gitignore -new file mode 100644 -index 0000000..de4a392 ---- /dev/null -+++ b/.gitignore -@@ -0,0 +1,2 @@ -+/vendor -+/composer.lock -diff --git a/composer.json b/composer.json -index 7dc400f..9819eec 100644 ---- a/composer.json -+++ b/composer.json -@@ -2,6 +2,12 @@ - "name": "drupal/simple_oauth", - "description": "The Simple OAuth module for Drupal", - "type": "drupal-module", -+ "repositories": [ -+ { -+ "type": "composer", -+ "url": "https://packages.drupal.org/8" -+ } -+ ], - "require": { - "lcobucci/jwt": "^4", - "league/oauth2-server": "^8.3", -@@ -10,7 +16,9 @@ - "php": ">=7.4" - }, - "require-dev": { -- "phpspec/prophecy-phpunit": "^2" -+ "phpspec/prophecy-phpunit": "^2", -+ "drupal/core-recommended": "^9", -+ "drupal/core-dev": "^9" - }, - "license": "GPL-2.0-or-later", - "extra": { -@@ -19,5 +27,10 @@ - "drush.services.yml": "^9" - } - } -+ }, -+ "config": { -+ "allow-plugins": { -+ "dealerdirect/phpcodesniffer-composer-installer": true -+ } - } - } -diff --git a/simple_oauth.module b/simple_oauth.module -index 7a98bc6..a27055d 100644 ---- a/simple_oauth.module -+++ b/simple_oauth.module -@@ -14,6 +14,7 @@ use Drupal\Core\Session\AccountInterface; - use Drupal\consumers\Entity\ConsumerInterface; - use Drupal\Core\StringTranslation\TranslatableMarkup; - use Drupal\Core\Url; -+use Drupal\simple_oauth\EntityUpdateHookHandler; - use Drupal\user\RoleInterface; - use Drupal\Core\Link; - -@@ -39,15 +40,7 @@ function simple_oauth_cron() { - * Implements hook_entity_update(). - */ - function simple_oauth_entity_update(EntityInterface $entity) { -- /** @var \Drupal\simple_oauth\ExpiredCollector $collector */ -- $collector = \Drupal::service('simple_oauth.expired_collector'); -- // Collect the affected tokens and expire them. -- if ($entity instanceof AccountInterface) { -- $collector->deleteMultipleTokens($collector->collectForAccount($entity)); -- } -- if ($entity instanceof ConsumerInterface) { -- $collector->deleteMultipleTokens($collector->collectForClient($entity)); -- } -+ \Drupal::service(EntityUpdateHookHandler::class)->handleEntityUpdate($entity); - } - - /** -diff --git a/simple_oauth.services.yml b/simple_oauth.services.yml -index 0455a1a..e869dab 100644 ---- a/simple_oauth.services.yml -+++ b/simple_oauth.services.yml -@@ -109,3 +109,7 @@ services: - arguments: [ '@entity_type.manager', '%simple_oauth.openid.claims%', '@module_handler' ] - tags: - - { name: normalizer, priority: 21 } -+ Drupal\simple_oauth\EntityUpdateHookHandler: -+ arguments: -+ - '@simple_oauth.expired_collector' -+ - '@event_dispatcher' -\ No newline at end of file -diff --git a/src/EntityUpdateHookHandler.php b/src/EntityUpdateHookHandler.php -new file mode 100644 -index 0000000..3df0448 ---- /dev/null -+++ b/src/EntityUpdateHookHandler.php -@@ -0,0 +1,78 @@ -+collector = $expired_collector; -+ $this->eventDispatcher = $event_dispatcher; -+ } -+ -+ /** -+ * Handle invalidation of tokens secondary to entity update. -+ * -+ * @param \Drupal\Core\Entity\EntityInterface $entity -+ * Updated entity. -+ */ -+ public function handleEntityUpdate(EntityInterface $entity): void { -+ // Collect the affected tokens and expire them. -+ if ($entity instanceof UserInterface) { -+ // Following the Drupal core pattern, revoke access to the system when -+ // password has been changed. -+ $password_changed = $entity->pass->value !== $entity->original->pass->value; -+ -+ // When the account got blocked, we should revoke user's access to the site. -+ $account_blocked = !$entity->isActive() && $entity->original->isActive(); -+ -+ // When roles have changed, we should revoke the token to prevent potential -+ // access to the content where the user has no access to anymore. -+ $roles_new = $entity->getRoles(); -+ $roles_old = $entity->original->getRoles(); -+ $roles_changed = array_merge( -+ array_diff($roles_new, $roles_old), -+ array_diff($roles_old, $roles_new) -+ ); -+ -+ $event = new UserUpdateTokenInvalidationEvent( -+ $password_changed || $account_blocked || $roles_changed -+ ); -+ $this->eventDispatcher->dispatch($event); -+ if ($event->willInvalidateAccessTokens()) { -+ $this->collector -+ ->deleteMultipleTokens($this->collector->collectForAccount( -+ $entity, -+ $event->willInvalidateRefreshTokens() -+ )); -+ } -+ } -+ if ($entity instanceof Consumer) { -+ $this->collector -+ ->deleteMultipleTokens($this->collector->collectForClient($entity)); -+ } -+ } -+ -+} -diff --git a/src/Event/UserUpdateTokenInvalidationEvent.php b/src/Event/UserUpdateTokenInvalidationEvent.php -new file mode 100644 -index 0000000..1716ff4 ---- /dev/null -+++ b/src/Event/UserUpdateTokenInvalidationEvent.php -@@ -0,0 +1,100 @@ -+invalidateAccessTokens = $flag; -+ } -+ -+ /** -+ * Getter for access token invalidation behavior. -+ * -+ * @return bool -+ * Determination. -+ */ -+ public function willInvalidateAccessTokens(): bool { -+ return $this->invalidateRefreshTokens; -+ } -+ -+ /** -+ * Getter for refresh token invalidation behavior. -+ * -+ * @return bool -+ * Determination. -+ */ -+ public function willInvalidateRefreshTokens(): bool { -+ return $this->invalidateRefreshTokens; -+ } -+ -+ /** -+ * Setter for refresh token invalidation. -+ * -+ * @param bool $flag -+ * Whether to invalidate refresh tokens. -+ */ -+ public function setInvalidateRefreshTokens(bool $flag): void { -+ $this->invalidateRefreshTokens = $flag; -+ if ($flag === TRUE) { -+ $this->invalidateAccessTokens = TRUE; -+ } -+ } -+ -+ /** -+ * Getter for Simple OAuth's determination of access characteristic change. -+ * -+ * @return bool -+ * TRUE if the user's roles, password or status has changed. -+ */ -+ public function haveUserAccessCharacteristicsChanged(): bool { -+ return $this->haveAccessCharacteristicsChanged; -+ } -+ -+ /** -+ * Constructor. -+ * -+ * @param bool $access_characteristics_have_changed -+ * Flag for whether user access characteristics have changed. -+ */ -+ public function __construct(bool $access_characteristics_have_changed) { -+ $this->haveAccessCharacteristicsChanged = $access_characteristics_have_changed; -+ } -+ -+} -diff --git a/src/ExpiredCollector.php b/src/ExpiredCollector.php -index 0eb6795..4566483 100644 ---- a/src/ExpiredCollector.php -+++ b/src/ExpiredCollector.php -@@ -78,15 +78,19 @@ class ExpiredCollector { - * - * @param \Drupal\Core\Session\AccountInterface $account - * The account. -+ * @param bool $include_refresh_tokens -+ * Include refresh tokens. FALSE by default for BC reasons. - * - * @return \Drupal\simple_oauth\Entity\Oauth2TokenInterface[] - * The tokens. - */ -- public function collectForAccount(AccountInterface $account) { -+ public function collectForAccount(AccountInterface $account, bool $include_refresh_tokens = FALSE) { - $query = $this->tokenStorage->getQuery(); - $query->accessCheck(); - $query->condition('auth_user_id', $account->id()); -- $query->condition('bundle', 'refresh_token', '!='); -+ if (!$include_refresh_tokens) { -+ $query->condition('bundle', 'refresh_token', '!='); -+ } - $entity_ids = $query->execute(); - $output = $entity_ids - ? array_values($this->tokenStorage->loadMultiple(array_values($entity_ids))) --- -GitLab - - -From 5ff0c27b5e125ccab69e6fe4eab4abb06e82024b Mon Sep 17 00:00:00 2001 -From: Brad Jones -Date: Fri, 19 Aug 2022 23:22:58 -0600 -Subject: [PATCH 2/5] CS update - ---- - simple_oauth.services.yml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/simple_oauth.services.yml b/simple_oauth.services.yml -index e869dab..4b9425a 100644 ---- a/simple_oauth.services.yml -+++ b/simple_oauth.services.yml -@@ -112,4 +112,4 @@ services: - Drupal\simple_oauth\EntityUpdateHookHandler: - arguments: - - '@simple_oauth.expired_collector' -- - '@event_dispatcher' -\ No newline at end of file -+ - '@event_dispatcher' --- -GitLab - - -From 5626f6ae559f2f51eda619cebab4429c3b554e62 Mon Sep 17 00:00:00 2001 -From: Brad Jones -Date: Sat, 20 Aug 2022 00:15:55 -0600 -Subject: [PATCH 3/5] Fix property names - ---- - src/Event/UserUpdateTokenInvalidationEvent.php | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/Event/UserUpdateTokenInvalidationEvent.php b/src/Event/UserUpdateTokenInvalidationEvent.php -index 1716ff4..f49a308 100644 ---- a/src/Event/UserUpdateTokenInvalidationEvent.php -+++ b/src/Event/UserUpdateTokenInvalidationEvent.php -@@ -51,7 +51,7 @@ final class UserUpdateTokenInvalidationEvent extends Event { - * Determination. - */ - public function willInvalidateAccessTokens(): bool { -- return $this->invalidateRefreshTokens; -+ return $this->invalidateAccessTokens; - } - - /** --- -GitLab - - -From 421586422f23219ed24b976fed450b76599de791 Mon Sep 17 00:00:00 2001 -From: Brad Jones -Date: Thu, 17 Nov 2022 16:03:35 -0700 -Subject: [PATCH 4/5] Use ConsumerInterface - ---- - src/EntityUpdateHookHandler.php | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/EntityUpdateHookHandler.php b/src/EntityUpdateHookHandler.php -index 3df0448..78a0988 100644 ---- a/src/EntityUpdateHookHandler.php -+++ b/src/EntityUpdateHookHandler.php -@@ -2,7 +2,7 @@ - - namespace Drupal\simple_oauth; - --use Drupal\consumers\Entity\Consumer; -+use Drupal\consumers\Entity\ConsumerInterface; - use Drupal\Core\Entity\EntityInterface; - use Drupal\simple_oauth\Event\UserUpdateTokenInvalidationEvent; - use Drupal\user\UserInterface; -@@ -69,7 +69,7 @@ final class EntityUpdateHookHandler { - )); - } - } -- if ($entity instanceof Consumer) { -+ if ($entity instanceof ConsumerInterface) { - $this->collector - ->deleteMultipleTokens($this->collector->collectForClient($entity)); - } --- -GitLab - - -From ca33f209399e1d9c34fa52a98cdc9dfe314196c3 Mon Sep 17 00:00:00 2001 -From: Dieter Holvoet -Date: Thu, 5 Jan 2023 14:14:38 +0100 -Subject: [PATCH 5/5] Add the user entity to the event object - ---- - src/EntityUpdateHookHandler.php | 3 +- - .../UserUpdateTokenInvalidationEvent.php | 33 ++++++++++++++++++- - 2 files changed, 34 insertions(+), 2 deletions(-) - -diff --git a/src/EntityUpdateHookHandler.php b/src/EntityUpdateHookHandler.php -index 78a0988..d7dd5ee 100644 ---- a/src/EntityUpdateHookHandler.php -+++ b/src/EntityUpdateHookHandler.php -@@ -58,7 +58,8 @@ final class EntityUpdateHookHandler { - ); - - $event = new UserUpdateTokenInvalidationEvent( -- $password_changed || $account_blocked || $roles_changed -+ $password_changed || $account_blocked || $roles_changed, -+ $entity - ); - $this->eventDispatcher->dispatch($event); - if ($event->willInvalidateAccessTokens()) { -diff --git a/src/Event/UserUpdateTokenInvalidationEvent.php b/src/Event/UserUpdateTokenInvalidationEvent.php -index f49a308..f3095f1 100644 ---- a/src/Event/UserUpdateTokenInvalidationEvent.php -+++ b/src/Event/UserUpdateTokenInvalidationEvent.php -@@ -3,12 +3,20 @@ - namespace Drupal\simple_oauth\Event; - - use Drupal\Component\EventDispatcher\Event; -+use Drupal\user\UserInterface; - - /** - * Event for determining whether to invalidate user tokens on update. - */ - final class UserUpdateTokenInvalidationEvent extends Event { - -+ /** -+ * The user entity. -+ * -+ * @var \Drupal\user\UserInterface -+ */ -+ protected UserInterface $user; -+ - /** - * Whether Simple OAuth has determined that the user's access has changed. - * -@@ -34,6 +42,26 @@ final class UserUpdateTokenInvalidationEvent extends Event { - */ - protected ?bool $invalidateRefreshTokens = FALSE; - -+ /** -+ * Get the changed user entity. -+ * -+ * @return \Drupal\user\UserInterface -+ * The user entity. -+ */ -+ public function getUser(): UserInterface { -+ return $this->user; -+ } -+ -+ /** -+ * Get the unchanged user entity. -+ * -+ * @return \Drupal\user\UserInterface|null -+ * The unchanged user entity. -+ */ -+ public function getOriginalUser(): ?UserInterface { -+ return $this->user->original ?? NULL; -+ } -+ - /** - * Setter for access token invalidation. - * -@@ -92,9 +120,12 @@ final class UserUpdateTokenInvalidationEvent extends Event { - * - * @param bool $access_characteristics_have_changed - * Flag for whether user access characteristics have changed. -+ * @param \Drupal\user\UserInterface $user -+ * The user entity. - */ -- public function __construct(bool $access_characteristics_have_changed) { -+ public function __construct(bool $access_characteristics_have_changed, UserInterface $user) { - $this->haveAccessCharacteristicsChanged = $access_characteristics_have_changed; -+ $this->user = $user; - } - - } diff --git a/recipes/.gitignore b/recipes/.gitignore new file mode 100644 index 00000000..739a3394 --- /dev/null +++ b/recipes/.gitignore @@ -0,0 +1 @@ +/README.txt \ No newline at end of file diff --git a/web/profiles/youvo_development/youvo_development.info.yml b/web/profiles/youvo_development/youvo_development.info.yml index f3f7c8e4..06333fd5 100644 --- a/web/profiles/youvo_development/youvo_development.info.yml +++ b/web/profiles/youvo_development/youvo_development.info.yml @@ -4,8 +4,6 @@ description: Configuration profile for initial install of youvo adding developme core_version_requirement: ^10.3 || ^11 -base profile: youvo_platform - install: # Development - admin_toolbar From 58cbbf4115af97db1d6e0c1d95cd3b3d11dbc695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4se?= Date: Tue, 24 Dec 2024 02:24:17 +0100 Subject: [PATCH 3/5] Fix tests after Drupal 11 upgrade --- .../custom/projects/projects/src/Entity/Project.php | 1 + .../projects/projects/src/Form/ProjectForm.php | 1 + .../Resource/ProjectApplyResourceTest.php | 10 +++++----- .../Resource/ProjectCompleteResourceTest.php | 12 ++++++------ .../Resource/ProjectMediateResourceTest.php | 10 +++++----- .../Resource/ProjectNotifyResourceTest.php | 8 ++++---- .../Resource/ProjectPublishResourceTest.php | 8 ++++---- .../Resource/ProjectResetResourceTest.php | 2 +- .../Resource/ProjectSubmitResourceTest.php | 8 ++++---- .../user_types/tests/src/Unit/ProfileUtilityTest.php | 4 ++-- 10 files changed, 33 insertions(+), 31 deletions(-) diff --git a/web/modules/custom/projects/projects/src/Entity/Project.php b/web/modules/custom/projects/projects/src/Entity/Project.php index 88c77dd8..109f6e0c 100644 --- a/web/modules/custom/projects/projects/src/Entity/Project.php +++ b/web/modules/custom/projects/projects/src/Entity/Project.php @@ -237,6 +237,7 @@ public function getParticipants(): array { $tasks = $this->get('field_participants_tasks')->getValue(); /** @var \Drupal\user\UserInterface $participant */ foreach ($participants_field->referencedEntities() as $delta => $participant) { + // @phpstan-ignore-next-line $participant->task = $tasks[$delta]['value']; $participants[(int) $participant->id()] = $participant; } diff --git a/web/modules/custom/projects/projects/src/Form/ProjectForm.php b/web/modules/custom/projects/projects/src/Form/ProjectForm.php index 0a6a2f1d..2d0d74ab 100644 --- a/web/modules/custom/projects/projects/src/Form/ProjectForm.php +++ b/web/modules/custom/projects/projects/src/Form/ProjectForm.php @@ -29,6 +29,7 @@ public function form(array $form, FormStateInterface $form_state): array { $participants_default = []; foreach ($project->getParticipants() as $participant) { /** @var string $task */ + // @phpstan-ignore-next-line $task = $participant->task; $task_id = match ($task) { 'Manager' => 7, diff --git a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectApplyResourceTest.php b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectApplyResourceTest.php index 3baad08e..25d04170 100644 --- a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectApplyResourceTest.php +++ b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectApplyResourceTest.php @@ -75,7 +75,7 @@ public function testProjectApplyAlreadyApplied(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The applicant conditions for this application are not met. The creative may already applied."}', $response->getContent()); + $this->assertEquals('The applicant conditions for this application are not met. The creative may already applied.', $response->getContent()); } /** @@ -95,7 +95,7 @@ public function testProjectApplyManager(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The applicant conditions for this application are not met. The creative may already applied."}', $response->getContent()); + $this->assertEquals('The applicant conditions for this application are not met. The creative may already applied.', $response->getContent()); } /** @@ -115,7 +115,7 @@ public function testProjectApplyNotOpen(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this application are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this application are not met.', $response->getContent()); } /** @@ -137,7 +137,7 @@ public function testProjectApplyNotPublished(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this application are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this application are not met.', $response->getContent()); } /** @@ -157,7 +157,7 @@ public function testProjectApplyNoPermission(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The \u0027restful post project:apply\u0027 permission is required."}', $response->getContent()); + $this->assertEquals('The \'restful post project:apply\' permission is required.', $response->getContent()); } } diff --git a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectCompleteResourceTest.php b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectCompleteResourceTest.php index f6ce77ab..a124d818 100644 --- a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectCompleteResourceTest.php +++ b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectCompleteResourceTest.php @@ -151,7 +151,7 @@ public function testProjectCompleteNotOngoing(): void { $response = $this->doRequest($request); $this->assertEquals(409, $response->getStatusCode()); - $this->assertEquals('{"message":"Project can not be completed."}', $response->getContent()); + $this->assertEquals('Project can not be completed.', $response->getContent()); } /** @@ -171,7 +171,7 @@ public function testProjectCompleteNotOwner(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -191,7 +191,7 @@ public function testProjectCompleteNotManager(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -211,7 +211,7 @@ public function testProjectCompleteNotParticipant(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -233,7 +233,7 @@ public function testProjectCompleteNotPublished(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -253,7 +253,7 @@ public function testProjectCompleteNoPermission(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The \u0027restful post project:complete\u0027 permission is required."}', $response->getContent()); + $this->assertEquals('The \'restful post project:complete\' permission is required.', $response->getContent()); } } diff --git a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectMediateResourceTest.php b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectMediateResourceTest.php index dacbd012..e3426ff6 100644 --- a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectMediateResourceTest.php +++ b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectMediateResourceTest.php @@ -129,7 +129,7 @@ public function testProjectMediateNotOpen(): void { $response = $this->doRequest($request); $this->assertEquals(409, $response->getStatusCode()); - $this->assertEquals('{"message":"Project can not be mediated."}', $response->getContent()); + $this->assertEquals('Project can not be mediated.', $response->getContent()); } /** @@ -149,7 +149,7 @@ public function testProjectMediateNotOwner(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -169,7 +169,7 @@ public function testProjectMediateNotManager(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -191,7 +191,7 @@ public function testProjectMediateNotPublished(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -211,7 +211,7 @@ public function testProjectMediateNoPermission(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The \u0027restful post project:mediate\u0027 permission is required."}', $response->getContent()); + $this->assertEquals('The \'restful post project:mediate\' permission is required.', $response->getContent()); } } diff --git a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectNotifyResourceTest.php b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectNotifyResourceTest.php index ba03adb0..c9b5628d 100644 --- a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectNotifyResourceTest.php +++ b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectNotifyResourceTest.php @@ -93,7 +93,7 @@ public function testProjectNotifyNotDraft(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this action are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this action are not met.', $response->getContent()); } /** @@ -113,7 +113,7 @@ public function testProjectNotifyNotManager(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this action are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this action are not met.', $response->getContent()); } /** @@ -135,7 +135,7 @@ public function testProjectNotifyNotPublished(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this action are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this action are not met.', $response->getContent()); } /** @@ -155,7 +155,7 @@ public function testProjectNotifyNoPermission(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The \u0027restful post project:notify\u0027 permission is required."}', $response->getContent()); + $this->assertEquals('The \'restful post project:notify\' permission is required.', $response->getContent()); } } diff --git a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectPublishResourceTest.php b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectPublishResourceTest.php index 05f6ba5b..ac16d18e 100644 --- a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectPublishResourceTest.php +++ b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectPublishResourceTest.php @@ -73,7 +73,7 @@ public function testProjectPublishNotPending(): void { $response = $this->doRequest($request); $this->assertEquals(409, $response->getStatusCode()); - $this->assertEquals('{"message":"Project can not be published."}', $response->getContent()); + $this->assertEquals('Project can not be published.', $response->getContent()); } /** @@ -93,7 +93,7 @@ public function testProjectPublishNotManager(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -115,7 +115,7 @@ public function testProjectPublishNotPublished(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -135,7 +135,7 @@ public function testProjectPublishNoPermission(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The \u0027restful post project:publish\u0027 permission is required."}', $response->getContent()); + $this->assertEquals('The \'restful post project:publish\' permission is required.', $response->getContent()); } } diff --git a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectResetResourceTest.php b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectResetResourceTest.php index 288f5816..64466ddc 100644 --- a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectResetResourceTest.php +++ b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectResetResourceTest.php @@ -53,7 +53,7 @@ public function testProjectResetNoPermission(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The \u0027restful post project:reset\u0027 permission is required."}', $response->getContent()); + $this->assertEquals('The \'restful post project:reset\' permission is required.', $response->getContent()); } } diff --git a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectSubmitResourceTest.php b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectSubmitResourceTest.php index c34b1a0c..9ba8cf42 100644 --- a/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectSubmitResourceTest.php +++ b/web/modules/custom/projects/projects/tests/src/ExistingSite/Resource/ProjectSubmitResourceTest.php @@ -73,7 +73,7 @@ public function testProjectSubmitNotDraft(): void { $response = $this->doRequest($request); $this->assertEquals(409, $response->getStatusCode()); - $this->assertEquals('{"message":"Project can not be submitted."}', $response->getContent()); + $this->assertEquals('Project can not be submitted.', $response->getContent()); } /** @@ -93,7 +93,7 @@ public function testProjectSubmitNotOwner(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -115,7 +115,7 @@ public function testProjectSubmitNotPublished(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The project conditions for this transition are not met."}', $response->getContent()); + $this->assertEquals('The project conditions for this transition are not met.', $response->getContent()); } /** @@ -135,7 +135,7 @@ public function testProjectSubmitNoPermission(): void { $response = $this->doRequest($request); $this->assertEquals(403, $response->getStatusCode()); - $this->assertEquals('{"message":"The \u0027restful post project:submit\u0027 permission is required."}', $response->getContent()); + $this->assertEquals('The \'restful post project:submit\' permission is required.', $response->getContent()); } } diff --git a/web/modules/custom/user_types/tests/src/Unit/ProfileUtilityTest.php b/web/modules/custom/user_types/tests/src/Unit/ProfileUtilityTest.php index 205d53e1..0ea513b9 100644 --- a/web/modules/custom/user_types/tests/src/Unit/ProfileUtilityTest.php +++ b/web/modules/custom/user_types/tests/src/Unit/ProfileUtilityTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\user_types\Unit; -use Drupal\consumers\Entity\ConsumerInterface; +use Drupal\consumers\Entity\Consumer; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountProxyInterface; @@ -91,7 +91,7 @@ protected function setUp(): void { ->method('bundle') ->willReturn('organization'); - $consumer = $this->createMock(ConsumerInterface::class); + $consumer = $this->createMock(Consumer::class); $consumer_field = $this->createMock(EntityReferenceFieldItemListInterface::class); $consumer_field->expects($this->any()) ->method('__get') From 7564f1f59dba4cbec6c0c618725a2f03a13ca8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4se?= Date: Tue, 24 Dec 2024 13:19:15 +0100 Subject: [PATCH 4/5] Update patch --- composer.patches.json | 4 +- ...-d2c39a92.patch => 3082984-2a5cb2a8.patch} | 59 +++++++++++++------ 2 files changed, 44 insertions(+), 19 deletions(-) rename patches/simple_oauth/{3082984-d2c39a92.patch => 3082984-2a5cb2a8.patch} (84%) diff --git a/composer.patches.json b/composer.patches.json index 0e42e42a..41096f80 100644 --- a/composer.patches.json +++ b/composer.patches.json @@ -40,8 +40,8 @@ "Issue #3434213: Drupal 11 Compatibility": "patches/responsive_favicons/drupal-11-compatibility.patch" }, "drupal/simple_oauth": { - "Issue #3082984: Reduce logging severity/don't log expired tokens/401s": "patches/simple_oauth/3082984-d2c39a92.patch", - "Issue #2946882: Auth revoke on profile update": "patches/simple_oauth/2946882-c33fa214.patch" + "Issue #2946882: Auth revoke on profile update": "patches/simple_oauth/2946882-c33fa214.patch", + "Issue #3082984: Reduce logging severity/don't log expired tokens/401s": "patches/simple_oauth/3082984-2a5cb2a8.patch" }, "drupal/warmer": { "Custom: Add items list to queue command": "patches/warmer/custom-add-items-limit-to-queue-command.patch" diff --git a/patches/simple_oauth/3082984-d2c39a92.patch b/patches/simple_oauth/3082984-2a5cb2a8.patch similarity index 84% rename from patches/simple_oauth/3082984-d2c39a92.patch rename to patches/simple_oauth/3082984-2a5cb2a8.patch index 7ee23eab..ad82a828 100644 --- a/patches/simple_oauth/3082984-d2c39a92.patch +++ b/patches/simple_oauth/3082984-2a5cb2a8.patch @@ -23,7 +23,7 @@ index 2fbc8a929bab56f4c507be3c2dee6a829fc28c51..7eb33261421be870fae5f8eaf786ca99 simple_oauth.normalizer.oauth2_token: class: Drupal\simple_oauth\Normalizer\TokenEntityNormalizer diff --git a/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php b/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php -index 47d0e73f07282de8c178b3dbace964d56f44a50e..e702c3abb8b15b36f3811d14eb5e3448e3cfa034 100644 +index 47d0e73f07282de8c178b3dbace964d56f44a50e..fb03015acb32c706a935c61c7d442516bda3ee87 100644 --- a/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php +++ b/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php @@ -5,16 +5,14 @@ namespace Drupal\simple_oauth\Authentication\Provider; @@ -112,11 +112,10 @@ index 47d0e73f07282de8c178b3dbace964d56f44a50e..e702c3abb8b15b36f3811d14eb5e3448 $exception ); } -@@ -174,4 +159,25 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa +@@ -174,4 +159,24 @@ class SimpleOauthAuthenticationProvider implements AuthenticationProviderInterfa return $account; } -+ + /** + * Formats challenge for unauthorized exception. + * @@ -139,10 +138,18 @@ index 47d0e73f07282de8c178b3dbace964d56f44a50e..e702c3abb8b15b36f3811d14eb5e3448 + } diff --git a/src/Controller/Oauth2AuthorizeController.php b/src/Controller/Oauth2AuthorizeController.php -index a69e0ea0df53489f27cce24532385259339d3227..6c39bb265276a322e7c81f385a0f4134eb9b2db4 100644 +index a69e0ea0df53489f27cce24532385259339d3227..7a22230487ebb0a3c4c790560b70cbc8c53d8e13 100644 --- a/src/Controller/Oauth2AuthorizeController.php +++ b/src/Controller/Oauth2AuthorizeController.php -@@ -166,7 +166,7 @@ class Oauth2AuthorizeController extends ControllerBase { +@@ -5,7 +5,6 @@ namespace Drupal\simple_oauth\Controller; + use Drupal\Component\Utility\UrlHelper; + use Drupal\Core\Controller\ControllerBase; + use Drupal\Core\Url; +-use Drupal\Core\Utility\Error; + use Drupal\simple_oauth\Entities\ScopeEntity; + use Drupal\simple_oauth\Entities\UserEntity; + use Drupal\simple_oauth\Form\Oauth2AuthorizeForm; +@@ -166,7 +165,7 @@ class Oauth2AuthorizeController extends ControllerBase { } } catch (OAuthServerException $exception) { @@ -152,18 +159,24 @@ index a69e0ea0df53489f27cce24532385259339d3227..6c39bb265276a322e7c81f385a0f4134 } diff --git a/src/Controller/Oauth2Token.php b/src/Controller/Oauth2Token.php -index 51e4d80449f79dd80653e7afe51f459b68789c9b..84ee091f4362cd3d79ce434266f1ba826f0b0fe3 100644 +index 51e4d80449f79dd80653e7afe51f459b68789c9b..954cab875b938243cbb074c5d2d1b1c3c354e9d9 100644 --- a/src/Controller/Oauth2Token.php +++ b/src/Controller/Oauth2Token.php -@@ -10,6 +10,7 @@ use League\OAuth2\Server\Exception\OAuthServerException; +@@ -3,12 +3,12 @@ + namespace Drupal\simple_oauth\Controller; + + use Drupal\Core\Controller\ControllerBase; +-use Drupal\Core\Utility\Error; + use Drupal\simple_oauth\Server\AuthorizationServerFactoryInterface; + use GuzzleHttp\Psr7\Response; + use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use Psr\Http\Message\ResponseInterface; - use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; + use Psr\Log\LoggerInterface; use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; use Symfony\Component\DependencyInjection\ContainerInterface; - use Symfony\Component\HttpFoundation\Request; -@@ -114,7 +115,10 @@ class Oauth2Token extends ControllerBase { +@@ -114,7 +114,10 @@ class Oauth2Token extends ControllerBase { $response = $server->respondToAccessTokenRequest($server_request, $server_response); } catch (OAuthServerException $exception) { @@ -177,7 +190,7 @@ index 51e4d80449f79dd80653e7afe51f459b68789c9b..84ee091f4362cd3d79ce434266f1ba82 diff --git a/src/EventSubscriber/ExceptionLoggingSubscriber.php b/src/EventSubscriber/ExceptionLoggingSubscriber.php new file mode 100644 -index 0000000000000000000000000000000000000000..cf351d3fcf89cdfb43944642721355d20d322c3e +index 0000000000000000000000000000000000000000..b91d129cd245a02212db1b9ae4990f25d21a34af --- /dev/null +++ b/src/EventSubscriber/ExceptionLoggingSubscriber.php @@ -0,0 +1,65 @@ @@ -185,10 +198,10 @@ index 0000000000000000000000000000000000000000..cf351d3fcf89cdfb43944642721355d2 + +namespace Drupal\simple_oauth\EventSubscriber; + -+use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber as CoreExceptionLoggingSubscriber; +use Drupal\simple_oauth\Exception\OAuthUnauthorizedHttpException; +use Psr\Log\LoggerInterface; ++use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\ExceptionEvent; + +/** @@ -216,7 +229,7 @@ index 0000000000000000000000000000000000000000..cf351d3fcf89cdfb43944642721355d2 + */ + public function __construct( + EventSubscriberInterface $inner, -+ LoggerInterface $logger ++ LoggerInterface $logger, + ) { + $this->inner = $inner; + $this->logger = $logger; @@ -248,22 +261,33 @@ index 0000000000000000000000000000000000000000..cf351d3fcf89cdfb43944642721355d2 +} diff --git a/src/Exception/OAuthUnauthorizedHttpException.php b/src/Exception/OAuthUnauthorizedHttpException.php new file mode 100644 -index 0000000000000000000000000000000000000000..75baa81aef6b1f8517f95cb8889d723b74975c0f +index 0000000000000000000000000000000000000000..b0c00bae6a7f0286b389b6013f7fe6da3e8a831b --- /dev/null +++ b/src/Exception/OAuthUnauthorizedHttpException.php -@@ -0,0 +1,7 @@ +@@ -0,0 +1,10 @@ +oauthPageCacheRequestPolicy = new DisallowSimpleOauthRequests(); $http_message_factory = $this->prophesize(HttpMessageFactoryInterface::class); $http_foundation_factory = $this->prophesize(HttpFoundationFactoryInterface::class); @@ -277,3 +301,4 @@ index f1dff6637ece6bff99b7cc06f458ee6552a1c1fa..d18fdec4e4e6ae44fd148420be1b4c1a - $logger->reveal() ); } + From 538785b82124b58bbe20634e4c7f2dae623f1d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4se?= Date: Tue, 24 Dec 2024 14:49:04 +0100 Subject: [PATCH 5/5] Update GitHub workflow and fix site install --- .github/workflows/ci.yml | 54 +++ .github/workflows/phpanalysis.yml | 80 ---- composer-manifest.yaml | 5 + composer.json | 3 + composer.lock | 395 +++++++++++++++++- composer.patches.json | 3 + config/.env.ci | 14 + .../drupal-11-compatibility.patch | 12 + phpunit.xml | 42 +- scripts/install-ci.sh | 39 ++ .../questionnaire/questionnaire.install | 19 - .../projects/dummy/projects_dummy.info.yml | 1 + web/sites/default/install.services.yml | 192 +++++++++ 13 files changed, 744 insertions(+), 115 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/phpanalysis.yml create mode 100644 config/.env.ci create mode 100644 patches/devel_mail_logger/drupal-11-compatibility.patch create mode 100644 scripts/install-ci.sh create mode 100755 web/sites/default/install.services.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..de2ed638 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,54 @@ +name: Tests + +on: + pull_request: + push: + branches: + - main + +jobs: + lint: + name: Linting + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + coverage: none + php-version: 8.3 + - name: Validate Dependencies + run: composer validate + - name: Install Dependencies + uses: ramsey/composer-install@v3 + - name: Check Coding Standards + run: vendor/bin/phpcs --report=summary + - name: Static Code Analysis + run: vendor/bin/phpstan analyze web/modules/custom + + test: + name: Testing + runs-on: ubuntu-latest + needs: lint + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + coverage: no + php-version: 8.3 + - name: Install Dependencies + uses: ramsey/composer-install@v3 + - name: Setup Environment + run: | + sudo systemctl start mysql.service + mysql -uroot -h127.0.0.1 -proot -e 'CREATE DATABASE IF NOT EXISTS db;' + sudo systemctl start apache2.service + - name: Unit & Kernel Tests + run: vendor/bin/phpunit --testsuite unit,kernel --testdox --stop-on-failure + - name: Install Drupal + run: bash scripts/install-ci.sh + - name: Existing Site Tests + run: vendor/bin/phpunit --testsuite existing-site --testdox --stop-on-failure diff --git a/.github/workflows/phpanalysis.yml b/.github/workflows/phpanalysis.yml deleted file mode 100644 index 47c8f6fd..00000000 --- a/.github/workflows/phpanalysis.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: PHP Code Analysis & Tests - -on: - pull_request: - push: - branches: - - main - -jobs: - phpanalysis: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install PHP_CodeSniffer and PHPStan - run: | - composer require --dev dealerdirect/phpcodesniffer-composer-installer - composer require --dev drupal/coder - - - name: Check coding standards - run: | - vendor/bin/phpcs --report=summary - - - name: Static code analysis - run: | - vendor/bin/phpstan analyze web/modules/custom - - phptests: - needs: phpanalysis - runs-on: ubuntu-latest - env: - extensions: gd - key: cache - services: - db: - image: mysql:5.7 - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_USER: db - MYSQL_PASSWORD: db - MYSQL_DATABASE: db - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - steps: - - name: Check out - uses: actions/checkout@v2 - - - name: Set up cache environment - id: extcache - uses: shivammathur/cache-extensions@v1 - with: - php-version: 8.3 - extensions: ${{ env.extensions }} - key: ${{ env.key }} - - - name: Cache dependencies - uses: actions/cache@v3 - with: - path: ${{ steps.extcache.outputs.dir }} - key: ${{ steps.extcache.outputs.key }} - restore-keys: ${{ steps.extcache.outputs.key }} - - - name: Set up PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.3 - extensions: ${{ env.extensions }} - coverage: none - - - name: Install dependencies - run: | - sudo apt-get install patch - composer validate - composer install --no-interaction --no-progress - - - name: Run PHPUnit tests - run: | - vendor/bin/phpunit --testsuite unit,kernel diff --git a/composer-manifest.yaml b/composer-manifest.yaml index f1b0e59c..c513ed40 100644 --- a/composer-manifest.yaml +++ b/composer-manifest.yaml @@ -28,9 +28,12 @@ packages: dekor/php-array-table: '2.0' dflydev/dot-access-data: v3.0.3 doctrine/annotations: 2.0.2 + doctrine/common: 3.4.5 doctrine/deprecations: 1.1.4 + doctrine/event-manager: 2.0.1 doctrine/instantiator: 2.0.0 doctrine/lexer: 2.1.1 + doctrine/persistence: 3.4.0 dompdf/php-font-lib: 1.0.1 drupal/admin_toolbar: 3.5.1 drupal/coder: 8.3.26 @@ -43,6 +46,8 @@ packages: drupal/core-project-message: 11.1.0 drupal/core-recommended: 11.1.0 drupal/core-vendor-hardening: 11.1.0 + drupal/devel: 5.3.1 + drupal/devel_mail_logger: 2.0.0 drupal/entity: 1.5.0 drupal/file_mdm: 3.1.0 drupal/filefield_paths: 1.0.0-beta8 diff --git a/composer.json b/composer.json index 50ba004b..59aa4ec0 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,8 @@ "drupal/core-project-message": "^11.1", "drupal/core-recommended": "^11.1", "drupal/core-vendor-hardening": "^11.1", + "drupal/devel": "^5.3", + "drupal/devel_mail_logger": "^2.0", "drupal/entity": "^1.4", "drupal/filefield_paths": "^1.0@beta", "drupal/gin": "^4.0", @@ -134,6 +136,7 @@ }, "drupal-lenient": { "allowed-list": [ + "drupal/devel_mail_logger", "drupal/jsonapi_boost", "drupal/jsonapi_cross_bundles", "drupal/multivalue_form_element", diff --git a/composer.lock b/composer.lock index 36fba5d9..8817e82e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e9ce34aa9689c16f177bab2cd6fe8b0d", + "content-hash": "e80c9d30b9778508e69dfc53824d950f", "packages": [ { "name": "asm89/stack-cors", @@ -1131,6 +1131,97 @@ }, "time": "2024-09-05T10:17:24+00:00" }, + { + "name": "doctrine/common", + "version": "3.4.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "6c8fef961f67b8bc802ce3e32e3ebd1022907286" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/6c8fef961f67b8bc802ce3e32e3ebd1022907286", + "reference": "6c8fef961f67b8bc802ce3e32e3ebd1022907286", + "shasum": "" + }, + "require": { + "doctrine/persistence": "^2.0 || ^3.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0 || ^10.0", + "doctrine/collections": "^1", + "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.0", + "symfony/phpunit-bridge": "^6.1", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", + "homepage": "https://www.doctrine-project.org/projects/common.html", + "keywords": [ + "common", + "doctrine", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/common/issues", + "source": "https://github.com/doctrine/common/tree/3.4.5" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", + "type": "tidelift" + } + ], + "time": "2024-10-08T15:53:43+00:00" + }, { "name": "doctrine/deprecations", "version": "1.1.4", @@ -1176,6 +1267,97 @@ }, "time": "2024-12-07T21:18:45+00:00" }, + { + "name": "doctrine/event-manager", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "time": "2024-05-22T20:47:39+00:00" + }, { "name": "doctrine/lexer", "version": "2.1.1", @@ -1254,6 +1436,102 @@ ], "time": "2024-02-05T11:35:39+00:00" }, + { + "name": "doctrine/persistence", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/persistence.git", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/0ea965320cec355dba75031c1b23d4c78362e3ff", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^1 || ^2", + "php": "^7.2 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "doctrine/common": "<2.10" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "doctrine/common": "^3.0", + "phpstan/phpstan": "1.12.7", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5.38 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Persistence\\": "src/Persistence" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", + "homepage": "https://www.doctrine-project.org/projects/persistence.html", + "keywords": [ + "mapper", + "object", + "odm", + "orm", + "persistence" + ], + "support": { + "issues": "https://github.com/doctrine/persistence/issues", + "source": "https://github.com/doctrine/persistence/tree/3.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence", + "type": "tidelift" + } + ], + "time": "2024-10-30T19:48:12+00:00" + }, { "name": "dompdf/php-font-lib", "version": "1.0.1", @@ -1851,6 +2129,121 @@ }, "time": "2024-11-11T18:39:05+00:00" }, + { + "name": "drupal/devel", + "version": "5.3.1", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/devel.git", + "reference": "5.3.1" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/devel-5.3.1.zip", + "reference": "5.3.1", + "shasum": "6a5f13bdf93dc5f7f194b6af847589ae15e37b63" + }, + "require": { + "doctrine/common": "^2.7 || ^3.4", + "drupal/core": "^10.3 || ^11 || ^12", + "php": ">=8.1", + "symfony/var-dumper": "^4 || ^5 || ^6 || ^7" + }, + "conflict": { + "drupal/core": "<10.3", + "drush/drush": "<12.5.1", + "kint-php/kint": "<3" + }, + "require-dev": { + "drush/drush": "^13", + "firephp/firephp-core": "^0.5.3", + "kint-php/kint": "^5.1" + }, + "suggest": { + "kint-php/kint": "Kint provides an informative display of arrays/objects. Useful for debugging and developing." + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "5.3.1", + "datestamp": "1723258446", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "moshe weitzman", + "homepage": "https://www.drupal.org/user/23" + } + ], + "description": "Various blocks, pages, and functions for developers.", + "homepage": "https://www.drupal.org/project/devel", + "support": { + "source": "https://gitlab.com/drupalspoons/devel", + "issues": "https://gitlab.com/drupalspoons/devel/-/issues", + "slack": "https://drupal.slack.com/archives/C012WAW1MH6" + } + }, + { + "name": "drupal/devel_mail_logger", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/devel_mail_logger.git", + "reference": "2.0.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/devel_mail_logger-2.0.0.zip", + "reference": "2.0.0", + "shasum": "05b2879597b0b72e141f82c0836dd599ff6fef6c" + }, + "require": { + "drupal/core": "^8 || ^9 || ^10 || ^11 || ^12", + "php": ">=7.4" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "2.0.0", + "datestamp": "1685568166", + "security-coverage": { + "status": "not-covered", + "message": "Project has not opted into security advisory coverage!" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "sadashiv", + "homepage": "https://www.drupal.org/user/1773304" + }, + { + "name": "uniquename", + "homepage": "https://www.drupal.org/user/532810" + } + ], + "description": "A Custom Mail Interface that logs mail to DB", + "homepage": "https://www.drupal.org/project/devel_mail_logger", + "keywords": [ + "Drupal" + ], + "support": { + "source": "http://cgit.drupalcode.org/devel_mail_logger", + "issues": "https://www.drupal.org/project/issues/devel_mail_logger" + } + }, { "name": "drupal/entity", "version": "1.5.0", diff --git a/composer.patches.json b/composer.patches.json index 41096f80..6d4498c5 100644 --- a/composer.patches.json +++ b/composer.patches.json @@ -10,6 +10,9 @@ "Custom: Hide meta drupal IDs in JSON:API response": "patches/core/custom-hide-meta-drupal-ids-jsonapi.patch", "Custom Issue #3050383: PageCache getCacheId doesnt compare cid of the following subrequests in subrequest queue calls": "patches/core/custom-page-cache-id-doesnt-compare-cid-subrequests.patch" }, + "drupal/devel_mail_logger": { + "Issue #3438288: Drupal 11 Compatibility": "patches/devel_mail_logger/drupal-11-compatibility.patch" + }, "drupal/filefield_paths": { "Custom: Exclude consumer entity type from filefield_paths handling": "patches/filefield_paths/custom-exclude-consumer-entity-type.patch" }, diff --git a/config/.env.ci b/config/.env.ci new file mode 100644 index 00000000..39e64c0a --- /dev/null +++ b/config/.env.ci @@ -0,0 +1,14 @@ +PROJECT_NAME=youvo + +SITE_NAME=youvo.org +SITE_MAIL=hello@youvo.org +ACCOUNT_NAME=admin@youvo.org +ACCOUNT_MAIL=admin@youvo.org +ACCOUNT_PASS=admin + +DB_NAME=db +DB_USER=root +DB_PASSWORD=root +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DRIVER=mysql diff --git a/patches/devel_mail_logger/drupal-11-compatibility.patch b/patches/devel_mail_logger/drupal-11-compatibility.patch new file mode 100644 index 00000000..516e2a8a --- /dev/null +++ b/patches/devel_mail_logger/drupal-11-compatibility.patch @@ -0,0 +1,12 @@ +diff --git a/devel_mail_logger.info.yml b/devel_mail_logger.info.yml +index e224aa18aca6f3d521e584e0b287878468c37f20..2ebc0020ec263a356757a478e0445ce66a6549a1 100644 +--- a/devel_mail_logger.info.yml ++++ b/devel_mail_logger.info.yml +@@ -2,6 +2,6 @@ name: 'Devel Mail Logger' + type: module + description: 'A Custom Mail Interface that logs mail to DB' + package: Development +-core_version_requirement: ^8 || ^9 || ^10 ++core_version_requirement: ^8 || ^9 || ^10 || ^11 + tags: + - developer diff --git a/phpunit.xml b/phpunit.xml index 95478555..c4851b5f 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,37 +1,49 @@ + cacheResult="false"> + + - - - + + + - + + - - web/modules/custom + + ./web/modules/custom/*/tests/src/Unit + ./web/modules/custom/*/*/tests/src/Unit + + + ./web/modules/custom/*/tests/src/ExistingSite + ./web/modules/custom/*/*/tests/src/ExistingSite + + + ./web/modules/custom/*/tests/src/Kernel + ./web/modules/custom/*/*/tests/src/Kernel + + + ./web/modules/custom/*/tests/src/Functional + ./web/modules/custom/*/*/tests/src/Functional + - - - web/modules/custom - - + diff --git a/scripts/install-ci.sh b/scripts/install-ci.sh new file mode 100644 index 00000000..aeee91be --- /dev/null +++ b/scripts/install-ci.sh @@ -0,0 +1,39 @@ +#!/bin/bash + + # Exit on error. + set -e + + # Get variables. + set -a; source config/.env.ci; set +a + echo "Variables loaded ..." + + # Reset settings. + cd web/sites || exit + chmod -R 0755 default + cd default || exit + if test -f "settings.php"; then + sudo chmod 0777 settings.php + rm settings.php + fi + if test -f "services.yml"; then + sudo chmod 0777 services.yml + rm services.yml + fi + cp install.settings.php settings.php + cp install.services.yml services.yml + echo "Settings reset ..." + + # Install Drupal. + cd ../../.. + vendor/bin/drush si --yes --existing-config \ + --locale=en \ + --db-url="${DB_DRIVER}"://"${DB_USER}":"${DB_PASSWORD}"@"${DB_HOST}":"${DB_PORT}"/"${DB_NAME}" \ + --site-name="${SITE_NAME}" \ + --site-mail="${SITE_MAIL}" \ + --account-name="${ACCOUNT_NAME}" \ + --account-mail="${ACCOUNT_MAIL}" \ + --account-pass="${ACCOUNT_PASS}" + + # Rebuild Cache. + echo "Rebuild cache ..." + vendor/bin/drush cr > /dev/null 2>&1 diff --git a/web/modules/custom/academy/questionnaire/questionnaire.install b/web/modules/custom/academy/questionnaire/questionnaire.install index 55e2d927..bb3aa5a1 100644 --- a/web/modules/custom/academy/questionnaire/questionnaire.install +++ b/web/modules/custom/academy/questionnaire/questionnaire.install @@ -11,29 +11,10 @@ use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Utility\Error; use Drupal\paragraphs\Entity\ParagraphType; -/** - * Implements hook_install(). - */ -function questionnaire_install(): void { - // Add questionnaire target bundle to paragraph reference in lecture entity. - $config = \Drupal::configFactory()->getEditable('field.field.lecture.lecture.paragraphs'); - $current_types = $config->get('settings.handler_settings.target_bundles'); - $current_types['questionnaire'] = 'questionnaire'; - $config->set('settings.handler_settings.target_bundles', $current_types); - $config->save(TRUE); -} - /** * Implements hook_uninstall(). */ function questionnaire_uninstall(): void { - // Remove questionnaire target bundle to paragraph reference in lecture - // entity. - $config = \Drupal::configFactory()->getEditable('field.field.lecture.lecture.paragraphs'); - $current_types = $config->get('settings.handler_settings.target_bundles'); - unset($current_types['questionnaire']); - $config->set('settings.handler_settings.target_bundles', $current_types); - $config->save(TRUE); // Remove config entity for questionnaire paragraph type. try { diff --git a/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml b/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml index 7338d01d..abe074c0 100644 --- a/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml +++ b/web/modules/custom/projects/projects/dummy/projects_dummy.info.yml @@ -6,6 +6,7 @@ package: Projects core_version_requirement: '^10.3 || ^11' dependencies: + - creatives_dummy:creatives_dummy - drupal:file - drupal:user - organizations_dummy:organizations_dummy diff --git a/web/sites/default/install.services.yml b/web/sites/default/install.services.yml new file mode 100755 index 00000000..2fa45ba3 --- /dev/null +++ b/web/sites/default/install.services.yml @@ -0,0 +1,192 @@ +parameters: + jsonapi_obscurity.prefix: '' + session.storage.options: + # Default ini options for sessions. + # + # Some distributions of Linux (most notably Debian) ship their PHP + # installations with garbage collection (gc) disabled. Since Drupal depends + # on PHP's garbage collection for clearing sessions, ensure that garbage + # collection occurs by using the most common settings. + # @default 1 + gc_probability: 1 + # @default 100 + gc_divisor: 100 + # + # Set session lifetime (in seconds), i.e. the grace period for session + # data. Sessions are deleted by the session garbage collector after one + # session lifetime has elapsed since the user's last visit. When a session + # is deleted, authenticated users are logged out, and the contents of the + # user's session is discarded. + # @default 200000 + gc_maxlifetime: 200000 + # + # Set session cookie lifetime (in seconds), i.e. the time from the session + # is created to the cookie expires, i.e. when the browser is expected to + # discard the cookie. The value 0 means "until the browser is closed". + # @default 2000000 + cookie_lifetime: 2000000 + # + # Drupal automatically generates a unique session cookie name based on the + # full domain name used to access the site. This mechanism is sufficient + # for most use-cases, including multi-site deployments. However, if it is + # desired that a session can be reused across different subdomains, the + # cookie domain needs to be set to the shared base domain. Doing so assures + # that users remain logged in as they cross between various subdomains. + # To maximize compatibility and normalize the behavior across user agents, + # the cookie domain should start with a dot. + # + # @default none + # cookie_domain: '.example.com' + # + # Set the session ID string length. The length can be between 22 to 256. The + # PHP recommended value is 48. See + # https://www.php.net/manual/session.security.ini.php for more information. + # This value should be kept in sync with + # \Drupal\Core\Session\SessionConfiguration::__construct() + # @default 48 + sid_length: 48 + # + # Set the number of bits in encoded session ID character. The possible + # values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", + # ","). The PHP recommended value is 6. See + # https://www.php.net/manual/session.security.ini.php for more information. + # This value should be kept in sync with + # \Drupal\Core\Session\SessionConfiguration::__construct() + # @default 6 + sid_bits_per_character: 6 + twig.config: + # Twig debugging: + # + # When debugging is enabled: + # - The markup of each Twig template is surrounded by HTML comments that + # contain theming information, such as template file name suggestions. + # - Note that this debugging markup will cause automated tests that directly + # check rendered HTML to fail. When running automated tests, 'debug' + # should be set to FALSE. + # - The dump() function can be used in Twig templates to output information + # about template variables. + # - Twig templates are automatically recompiled whenever the source code + # changes (see auto_reload below). + # + # For more information about debugging Twig templates, see + # https://www.drupal.org/node/1906392. + # + # Enabling Twig debugging is not recommended in production environments. + # @default false + debug: false + # Twig auto-reload: + # + # Automatically recompile Twig templates whenever the source code changes. + # If you don't provide a value for auto_reload, it will be determined + # based on the value of debug. + # + # Enabling auto-reload is not recommended in production environments. + # @default null + auto_reload: null + # Twig cache: + # + # By default, Twig templates will be compiled and stored in the filesystem + # to increase performance. Disabling the Twig cache will recompile the + # templates from source each time they are used. In most cases the + # auto_reload setting above should be enabled rather than disabling the + # Twig cache. + # + # Disabling the Twig cache is not recommended in production environments. + # @default true + cache: true + renderer.config: + # Renderer required cache contexts: + # + # The Renderer will automatically associate these cache contexts with every + # render array, hence varying every render array by these cache contexts. + # + # @default ['languages:language_interface', 'theme', 'user.permissions'] + required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions'] + # Renderer automatic placeholdering conditions: + # + # Drupal allows portions of the page to be automatically deferred when + # rendering to improve cache performance. That is especially helpful for + # cache contexts that vary widely, such as the active user. On some sites + # those may be different, however, such as sites with only a handful of + # users. If you know what the high-cardinality cache contexts are for your + # site, specify those here. If you're not sure, the defaults are fairly safe + # in general. + # + # For more information about rendering optimizations see + # https://www.drupal.org/developing/api/8/render/arrays/cacheability#optimizing + auto_placeholder_conditions: + # Max-age at or below which caching is not considered worthwhile. + # + # Disable by setting to -1. + # + # @default 0 + max-age: 0 + # Cache contexts with a high cardinality. + # + # Disable by setting to []. + # + # @default ['session', 'user'] + contexts: ['session', 'user'] + # Tags with a high invalidation frequency. + # + # Disable by setting to []. + # + # @default [] + tags: [] + # Cacheability debugging: + # + # Responses with cacheability metadata (CacheableResponseInterface instances) + # get X-Drupal-Cache-Tags, X-Drupal-Cache-Contexts and X-Drupal-Cache-Max-Age + # headers. + # + # For more information about debugging cacheable responses, see + # https://www.drupal.org/developing/api/8/response/cacheable-response-interface + # + # Enabling cacheability debugging is not recommended in production + # environments. + # @default false + http.response.debug_cacheability_headers: false + factory.keyvalue: {} + # Default key/value storage service to use. + # @default keyvalue.database + # default: keyvalue.database + # Collection-specific overrides. + # state: keyvalue.database + factory.keyvalue.expirable: {} + # Default key/value expirable storage service to use. + # @default keyvalue.database.expirable + # default: keyvalue.database.expirable + # Allowed protocols for URL generation. + filter_protocols: + - http + - https + - ftp + - news + - nntp + - tel + - telnet + - mailto + - irc + - ssh + - sftp + - webcal + - rtsp + + # Configure Cross-Site HTTP requests (CORS). + # Read https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS + # for more information about the topic in general. + # Note: By default the configuration is disabled. + cors.config: + enabled: false + # Specify allowed headers, like 'x-allowed-header'. + allowedHeaders: [] + # Specify allowed request methods, specify ['*'] to allow all possible ones. + allowedMethods: [] + # Configure requests allowed from specific origins. + allowedOrigins: ['*'] + # Sets the Access-Control-Expose-Headers header. + exposedHeaders: false + # Sets the Access-Control-Max-Age header. + maxAge: false + # Sets the Access-Control-Allow-Credentials header. + supportsCredentials: false