summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml10
-rw-r--r--.gitlab-ci/pipeline.yml3
-rw-r--r--composer.json5
-rw-r--r--composer.lock6
-rw-r--r--composer/Metapackage/DevDependencies/composer.json2
-rw-r--r--core/.cspell.json1
-rw-r--r--core/.deprecation-ignore.txt3
-rw-r--r--core/.phpstan-baseline.php32
-rw-r--r--core/assets/scaffold/files/default.settings.php24
-rw-r--r--core/assets/vendor/htmx/debug.js11
-rw-r--r--core/composer.json2
-rw-r--r--core/core.libraries.yml12
-rw-r--r--core/includes/theme.maintenance.inc6
-rw-r--r--core/lib/Drupal/Component/Diff/composer.json2
-rw-r--r--core/lib/Drupal/Component/Utility/Html.php4
-rw-r--r--core/lib/Drupal/Core/Composer/Composer.php4
-rw-r--r--core/lib/Drupal/Core/Hook/Attribute/FormAlter.php7
-rw-r--r--core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php36
-rw-r--r--core/lib/Drupal/Core/Test/PhpUnitTestRunner.php6
-rw-r--r--core/lib/Drupal/Core/Theme/ThemeCommonElements.php1
-rw-r--r--core/modules/ckeditor5/tests/src/Unit/HTMLRestrictionsTest.php8
-rw-r--r--core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php2
-rw-r--r--core/modules/field_ui/src/Hook/FieldUiHooks.php2
-rw-r--r--core/modules/media_library/tests/modules/media_library_test/src/Form/TestNodeFormOverride.php2
-rw-r--r--core/modules/menu_ui/src/Hook/MenuUiHooks.php4
-rw-r--r--core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php6
-rw-r--r--core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php4
-rw-r--r--core/modules/node/config/schema/node.schema.yml4
-rw-r--r--core/modules/node/node.services.yml13
-rw-r--r--core/modules/node/src/Entity/Node.php2
-rw-r--r--core/modules/node/src/Entity/NodeType.php2
-rw-r--r--core/modules/node/src/Form/NodeForm.php (renamed from core/modules/node/src/NodeForm.php)4
-rw-r--r--core/modules/node/src/Form/NodeTypeForm.php (renamed from core/modules/node/src/NodeTypeForm.php)2
-rw-r--r--core/modules/node/tests/modules/node_no_default_author/node_no_default_author.info.yml5
-rw-r--r--core/modules/node/tests/modules/node_no_default_author/src/Hook/NodeNoDefaultAuthorHooks.php31
-rw-r--r--core/modules/node/tests/src/Functional/NodeEditFormTest.php10
-rw-r--r--core/modules/system/templates/authorize-report.html.twig5
-rw-r--r--core/modules/update/src/Hook/UpdateHooks.php2
-rw-r--r--core/modules/update/src/UpdateRoot.php10
-rw-r--r--core/modules/update/tests/src/Functional/UpdateManagerTest.php37
-rw-r--r--core/modules/update/tests/src/Functional/UpdateMiscTest.php17
-rw-r--r--core/modules/update/tests/src/Kernel/UpdateDeleteFileIfStaleTest.php1
-rw-r--r--core/modules/update/update.authorize.inc1
-rw-r--r--core/modules/update/update.manager.inc3
-rw-r--r--core/modules/update/update.module35
-rw-r--r--core/modules/update/update.post_update.php23
-rw-r--r--core/modules/update/update.services.yml1
-rw-r--r--core/modules/views/src/Hook/ViewsViewsHooks.php23
-rw-r--r--core/phpunit.xml.dist23
-rw-r--r--core/scripts/js/vendor-update.js2
-rwxr-xr-xcore/scripts/run-tests.sh2
-rw-r--r--core/tests/Drupal/KernelTests/Core/Test/PhpUnitTestDiscoveryTest.php15
-rw-r--r--core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php5
-rw-r--r--core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit11/TestCompatibilityTrait.php13
-rw-r--r--core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php8
-rw-r--r--core/tests/Drupal/Tests/Component/Utility/HtmlTest.php3
-rw-r--r--core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php35
-rw-r--r--core/tests/Drupal/Tests/Core/Datetime/DrupalDateTimeTest.php8
-rw-r--r--core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php25
-rw-r--r--core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php5
-rw-r--r--core/tests/PHPStan/composer.json2
-rw-r--r--core/themes/claro/claro.theme2
-rw-r--r--core/themes/stable9/templates/admin/authorize-report.html.twig5
-rw-r--r--sites/default/default.settings.php24
64 files changed, 378 insertions, 235 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c2a64c8baa87..fbcfb8496a31 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -67,6 +67,7 @@ variables:
GIT_DEPTH: "50"
PARENT_PIPELINE_ID: $CI_PIPELINE_ID
_TARGET_PHP: "8.3-ubuntu"
+ PHPUNIT_FAIL_ON_PHPUNIT_DEPRECATION: false
#############
# Stages #
@@ -109,6 +110,7 @@ default:
before_script:
- composer validate
- composer install --optimize-autoloader
+ - composer run-script drupal-phpunit-upgrade-check
- mkdir -p ./sites/simpletest ./sites/default/files ./build/logs/junit /var/www/.composer
- chown -R www-data:www-data ./sites ./build/logs/junit ./vendor /var/www/
script:
@@ -128,9 +130,13 @@ default:
before_script:
- composer validate
- composer install --optimize-autoloader
+ - composer run-script drupal-phpunit-upgrade-check
- docker-php-ext-enable pcov
script:
- - vendor/bin/phpunit -c core/tests/Drupal/Tests/Component --testsuite unit-component --colors=always --testdox --coverage-text=component-coverage-report.txt --coverage-cobertura=component-coverage-cobertura.xml --log-junit junit.xml --fail-on-deprecation --fail-on-phpunit-deprecation
+ - |
+ [[ $PHPUNIT_FAIL_ON_PHPUNIT_DEPRECATION == false ]] && export _FAIL_ON_PHPUNIT_DEPRECATION=""
+ [[ $PHPUNIT_FAIL_ON_PHPUNIT_DEPRECATION != false ]] && export _FAIL_ON_PHPUNIT_DEPRECATION="--fail-on-phpunit-deprecation"
+ - vendor/bin/phpunit -c core/tests/Drupal/Tests/Component --testsuite unit-component --colors=always --testdox --coverage-text=component-coverage-report.txt --coverage-cobertura=component-coverage-cobertura.xml --log-junit junit.xml --fail-on-deprecation $_FAIL_ON_PHPUNIT_DEPRECATION
# Process the coverage text report to produce an OpenMetrics report.
- php .gitlab-ci/scripts/component-coverage-metrics.php
artifacts:
@@ -390,6 +396,7 @@ default:
- *phpstan-cache
- composer validate
- composer install --optimize-autoloader
+ - composer run-script drupal-phpunit-upgrade-check
- if [ -n "$COMPOSER_UPDATE" ]; then
composer update --optimize-autoloader;
composer outdated;
@@ -439,6 +446,7 @@ default:
script:
- composer validate
- composer install --optimize-autoloader
+ - composer run-script drupal-phpunit-upgrade-check
- if [ -n "$COMPOSER_UPDATE" ]; then
composer update --optimize-autoloader;
composer outdated;
diff --git a/.gitlab-ci/pipeline.yml b/.gitlab-ci/pipeline.yml
index d8324045c806..c311b1a03a63 100644
--- a/.gitlab-ci/pipeline.yml
+++ b/.gitlab-ci/pipeline.yml
@@ -72,6 +72,7 @@ variables:
MINK_DRIVER_ARGS_WEBDRIVER_CHROMEDRIVER_NON_W3C: '["chrome", {"browserName":"chrome","goog:chromeOptions":{"args":["--disable-dev-shm-usage","--disable-gpu","--headless","--dns-prefetch-disable"]}}, "http://localhost:9515"]'
CI_PARALLEL_NODE_INDEX: $CI_NODE_INDEX
CI_PARALLEL_NODE_TOTAL: $CI_NODE_TOTAL
+ PHPUNIT_FAIL_ON_PHPUNIT_DEPRECATION: false
.with-database: &with-database
name: $_CONFIG_DOCKERHUB_ROOT/$_TARGET_DB:production
@@ -101,6 +102,7 @@ variables:
.run-tests: &run-tests
script:
+ - sudo -u www-data -E -H composer run-script drupal-phpunit-upgrade-check
# Need to pass this along directly.
- sudo -u www-data -E -H php ./core/scripts/run-tests.sh --color --keep-results --types "$TESTSUITE" --concurrency "$CONCURRENCY" --repeat "1" --sqlite "./sites/default/files/tests.sqlite" --dburl $SIMPLETEST_DB --url $SIMPLETEST_BASE_URL --verbose --non-html --all --ci-parallel-node-index $CI_PARALLEL_NODE_INDEX --ci-parallel-node-total $CI_PARALLEL_NODE_TOTAL
@@ -230,6 +232,7 @@ variables:
- <<: *with-database
- <<: *with-chrome
script:
+ - sudo -u www-data -E -H composer run-script drupal-phpunit-upgrade-check
# Run a small subset of tests to prove non W3C testing still works.
- sudo -u www-data -E -H php ./core/scripts/run-tests.sh --color --keep-results --types "$TESTSUITE" --concurrency "$CONCURRENCY" --repeat "1" --sqlite "./sites/default/files/tests.sqlite" --dburl $SIMPLETEST_DB --url $SIMPLETEST_BASE_URL --verbose --non-html javascript
diff --git a/composer.json b/composer.json
index c999c6fbf271..3f1230c946e6 100644
--- a/composer.json
+++ b/composer.json
@@ -33,7 +33,7 @@
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^1.12.4 || ^2.1.11",
"phpstan/phpstan-phpunit": "^1.3.16 || ^2.0.6",
- "phpunit/phpunit": "^10.5.19",
+ "phpunit/phpunit": "^10.5.19 || ^11.5.3",
"symfony/browser-kit": "^7.2",
"symfony/css-selector": "^7.2",
"symfony/dom-crawler": "^7.2",
@@ -128,14 +128,17 @@
"repositories": [
{
"type": "path",
+ "canonical": false,
"url": "core"
},
{
"type": "path",
+ "canonical": false,
"url": "composer/Plugin/ProjectMessage"
},
{
"type": "path",
+ "canonical": false,
"url": "composer/Plugin/VendorHardening"
},
{
diff --git a/composer.lock b/composer.lock
index fa0d22b3c177..7bfd3eb9cff0 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": "7317ff2c0cfb5aed4d0df6e4b3e63c34",
+ "content-hash": "fbb4558bd4ae8ebb59dd3179e80083ac",
"packages": [
{
"name": "asm89/stack-cors",
@@ -496,7 +496,7 @@
"dist": {
"type": "path",
"url": "core",
- "reference": "7e8f42a2a16fa8db35c42d6ba0c7bcc9b3508588"
+ "reference": "b929d8770bd808cc3d4796cb57c0e6d186b5a010"
},
"require": {
"asm89/stack-cors": "^2.3",
@@ -528,7 +528,7 @@
"php-tuf/composer-stager": "^2.0",
"psr/log": "^3.0",
"revolt/event-loop": "^1.0",
- "sebastian/diff": "^4|^5",
+ "sebastian/diff": "^4 || ^5 || ^6 || ^7",
"symfony/console": "^7.2",
"symfony/dependency-injection": "^7.2",
"symfony/event-dispatcher": "^7.2",
diff --git a/composer/Metapackage/DevDependencies/composer.json b/composer/Metapackage/DevDependencies/composer.json
index db4c17097dab..9083180e3bc6 100644
--- a/composer/Metapackage/DevDependencies/composer.json
+++ b/composer/Metapackage/DevDependencies/composer.json
@@ -25,7 +25,7 @@
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^1.12.4 || ^2.1.11",
"phpstan/phpstan-phpunit": "^1.3.16 || ^2.0.6",
- "phpunit/phpunit": "^10.5.19",
+ "phpunit/phpunit": "^10.5.19 || ^11.5.3",
"symfony/browser-kit": "^7.2",
"symfony/css-selector": "^7.2",
"symfony/dom-crawler": "^7.2",
diff --git a/core/.cspell.json b/core/.cspell.json
index 0b65759aa4f4..8baf6e3d342e 100644
--- a/core/.cspell.json
+++ b/core/.cspell.json
@@ -7,6 +7,7 @@
"**/.*.json",
".*ignore",
"composer.lock",
+ "composer/Metapackage/PinnedDevDependencies/composer.json",
"assets/vendor/**",
"misc/jquery.form.js",
"lib/Drupal/Component/Diff/**",
diff --git a/core/.deprecation-ignore.txt b/core/.deprecation-ignore.txt
index 0e70057ddac8..2ed21d1dfad9 100644
--- a/core/.deprecation-ignore.txt
+++ b/core/.deprecation-ignore.txt
@@ -29,6 +29,9 @@
# PHPUnit 10.
%The "PHPUnit\\Framework\\TestCase::__construct\(\)" method is considered internal.*You should not extend it from "Drupal\\[^"]+"%
+# PHPUnit 11.
+%The "PHPUnit\\Framework\\TestCase::__construct\(\)" method is considered final\. It may change without further notice as of its next major version\. You should not extend it from "Drupal\\[^"]+"%
+
# Symfony 7.2
%Since symfony/http-foundation 7.2: NativeSessionStorage's "sid_length" option is deprecated and will be ignored in Symfony 8.0.%
%Since symfony/http-foundation 7.2: NativeSessionStorage's "sid_bits_per_character" option is deprecated and will be ignored in Symfony 8.0.%
diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php
index 588cde82f739..cbe268b00821 100644
--- a/core/.phpstan-baseline.php
+++ b/core/.phpstan-baseline.php
@@ -27166,28 +27166,28 @@ $ignoreErrors[] = [
'path' => __DIR__ . '/modules/node/src/NodeAccessControlHandlerInterface.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeForm\\:\\:create\\(\\) has no return type specified\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeForm\\:\\:create\\(\\) has no return type specified\\.$#',
'identifier' => 'missingType.return',
'count' => 1,
- 'path' => __DIR__ . '/modules/node/src/NodeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeForm.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeForm\\:\\:form\\(\\) has no return type specified\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeForm\\:\\:form\\(\\) has no return type specified\\.$#',
'identifier' => 'missingType.return',
'count' => 1,
- 'path' => __DIR__ . '/modules/node/src/NodeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeForm.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeForm\\:\\:preview\\(\\) has no return type specified\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeForm\\:\\:preview\\(\\) has no return type specified\\.$#',
'identifier' => 'missingType.return',
'count' => 1,
- 'path' => __DIR__ . '/modules/node/src/NodeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeForm.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeForm\\:\\:save\\(\\) should return int but return statement is missing\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeForm\\:\\:save\\(\\) should return int but return statement is missing\\.$#',
'identifier' => 'return.missing',
'count' => 2,
- 'path' => __DIR__ . '/modules/node/src/NodeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeForm.php',
];
$ignoreErrors[] = [
'message' => '#^Method Drupal\\\\node\\\\NodeGrantDatabaseStorage\\:\\:alterQuery\\(\\) should return int but return statement is missing\\.$#',
@@ -27274,28 +27274,28 @@ $ignoreErrors[] = [
'path' => __DIR__ . '/modules/node/src/NodeTranslationHandler.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeTypeForm\\:\\:create\\(\\) has no return type specified\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeTypeForm\\:\\:create\\(\\) has no return type specified\\.$#',
'identifier' => 'missingType.return',
'count' => 1,
- 'path' => __DIR__ . '/modules/node/src/NodeTypeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeTypeForm.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeTypeForm\\:\\:form\\(\\) has no return type specified\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeTypeForm\\:\\:form\\(\\) has no return type specified\\.$#',
'identifier' => 'missingType.return',
'count' => 1,
- 'path' => __DIR__ . '/modules/node/src/NodeTypeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeTypeForm.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeTypeForm\\:\\:save\\(\\) should return int but return statement is missing\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeTypeForm\\:\\:save\\(\\) should return int but return statement is missing\\.$#',
'identifier' => 'return.missing',
'count' => 1,
- 'path' => __DIR__ . '/modules/node/src/NodeTypeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeTypeForm.php',
];
$ignoreErrors[] = [
- 'message' => '#^Method Drupal\\\\node\\\\NodeTypeForm\\:\\:validateForm\\(\\) has no return type specified\\.$#',
+ 'message' => '#^Method Drupal\\\\node\\\\Form\\\\NodeTypeForm\\:\\:validateForm\\(\\) has no return type specified\\.$#',
'identifier' => 'missingType.return',
'count' => 1,
- 'path' => __DIR__ . '/modules/node/src/NodeTypeForm.php',
+ 'path' => __DIR__ . '/modules/node/src/Form/NodeTypeForm.php',
];
$ignoreErrors[] = [
'message' => '#^Method Drupal\\\\node\\\\NodeTypeInterface\\:\\:setDisplaySubmitted\\(\\) has no return type specified\\.$#',
diff --git a/core/assets/scaffold/files/default.settings.php b/core/assets/scaffold/files/default.settings.php
index 666a39643736..d4ba8a91829a 100644
--- a/core/assets/scaffold/files/default.settings.php
+++ b/core/assets/scaffold/files/default.settings.php
@@ -476,30 +476,6 @@ $settings['update_free_access'] = FALSE;
# $settings['class_loader_auto_detect'] = FALSE;
/**
- * Authorized file system operations:
- *
- * The Update Manager module included with Drupal provides a mechanism for
- * site administrators to securely install missing updates for the site
- * directly through the web user interface. On securely-configured servers,
- * the Update manager will require the administrator to provide SSH or FTP
- * credentials before allowing the installation to proceed; this allows the
- * site to update the new files as the user who owns all the Drupal files,
- * instead of as the user the webserver is running as. On servers where the
- * webserver user is itself the owner of the Drupal files, the administrator
- * will not be prompted for SSH or FTP credentials (note that these server
- * setups are common on shared hosting, but are inherently insecure).
- *
- * Some sites might wish to disable the above functionality, and only update
- * the code directly via SSH or FTP themselves. This setting completely
- * disables all functionality related to these authorized file operations.
- *
- * @see https://www.drupal.org/node/244924
- *
- * Remove the leading hash signs to disable.
- */
-# $settings['allow_authorize_operations'] = FALSE;
-
-/**
* Default mode for directories and files written by Drupal.
*
* Value should be in PHP Octal Notation, with leading zero.
diff --git a/core/assets/vendor/htmx/debug.js b/core/assets/vendor/htmx/debug.js
deleted file mode 100644
index 15378ccc0777..000000000000
--- a/core/assets/vendor/htmx/debug.js
+++ /dev/null
@@ -1,11 +0,0 @@
-htmx.defineExtension('debug', {
- onEvent: function(name, evt) {
- if (console.debug) {
- console.debug(name, evt)
- } else if (console) {
- console.log('DEBUG:', name, evt)
- } else {
- throw new Error('NO CONSOLE SUPPORTED')
- }
- }
-})
diff --git a/core/composer.json b/core/composer.json
index 2ce89dd0c0e9..8ece7d84bdd7 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -49,7 +49,7 @@
"pear/archive_tar": "^1.4.14",
"psr/log": "^3.0",
"mck89/peast": "^1.14",
- "sebastian/diff": "^4|^5",
+ "sebastian/diff": "^4 || ^5 || ^6 || ^7",
"php-tuf/composer-stager": "^2.0"
},
"conflict": {
diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 5ec851e898e7..76aaa3965f01 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -791,18 +791,6 @@ htmx:
js:
assets/vendor/htmx/htmx.min.js: { minified: true }
-htmx.debug:
- remote: https://github.com/bigskysoftware/htmx-extensions
- version: "2.0.1"
- license:
- name: Zero-Clause BSD
- url: https://raw.githubusercontent.com/bigskysoftware/htmx-extensions/refs/heads/main/src/debug/LICENSE
- gpl-compatible: true
- js:
- assets/vendor/htmx/debug.js: {}
- dependencies:
- - core/htmx
-
internal.floating-ui:
remote: https://github.com/floating-ui/floating-ui
version: "1.6.12"
diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc
index 2a37fbc9ffdc..4438d058499b 100644
--- a/core/includes/theme.maintenance.inc
+++ b/core/includes/theme.maintenance.inc
@@ -108,8 +108,14 @@ function _drupal_maintenance_theme(): void {
* @param array $variables
* An associative array containing:
* - messages: An array of result messages.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
function template_preprocess_authorize_report(&$variables): void {
+ @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
$messages = [];
if (!empty($variables['messages'])) {
foreach ($variables['messages'] as $heading => $logs) {
diff --git a/core/lib/Drupal/Component/Diff/composer.json b/core/lib/Drupal/Component/Diff/composer.json
index 3fd31e6c78fb..f4bc60d21bcb 100644
--- a/core/lib/Drupal/Component/Diff/composer.json
+++ b/core/lib/Drupal/Component/Diff/composer.json
@@ -8,7 +8,7 @@
"license": "GPL-2.0-or-later",
"require": {
"php": ">=8.3.0",
- "sebastian/diff": "^4|^5"
+ "sebastian/diff": "^4 || ^5 || ^6 || ^7"
},
"autoload": {
"psr-4": {
diff --git a/core/lib/Drupal/Component/Utility/Html.php b/core/lib/Drupal/Component/Utility/Html.php
index 38b328a4c61c..1a53a8de0e88 100644
--- a/core/lib/Drupal/Component/Utility/Html.php
+++ b/core/lib/Drupal/Component/Utility/Html.php
@@ -128,13 +128,13 @@ class Html {
// - 0-9 (U+0061 - U+007A)
// - ISO 10646 characters U+00A1 and higher
// We strip out any character not in the above list.
- $identifier = preg_replace('/[^\x{002D}\x{0030}-\x{0039}\x{0041}-\x{005A}\x{005F}\x{0061}-\x{007A}\x{00A1}-\x{FFFF}]/u', '', $identifier);
+ $identifier = preg_replace('/[^\x{002D}\x{0030}-\x{0039}\x{0041}-\x{005A}\x{005F}\x{0061}-\x{007A}\x{00A1}-\x{FFFF}]/u', '', (string) $identifier);
// Identifiers cannot start with a digit, two hyphens, or a hyphen followed
// by a digit.
$identifier = preg_replace([
'/^[0-9]/',
'/^(-[0-9])|^(--)/',
- ], ['_', '__'], $identifier);
+ ], ['_', '__'], (string) $identifier);
return $identifier;
}
diff --git a/core/lib/Drupal/Core/Composer/Composer.php b/core/lib/Drupal/Core/Composer/Composer.php
index 6f2391885499..87b494e98421 100644
--- a/core/lib/Drupal/Core/Composer/Composer.php
+++ b/core/lib/Drupal/Core/Composer/Composer.php
@@ -91,7 +91,7 @@ class Composer {
return;
}
- // If the PHP version is 7.4 or above and PHPUnit is less than version 9
+ // If the PHP version is 8.4 or above and PHPUnit is less than version 11
// call the drupal-phpunit-upgrade script to upgrade PHPUnit.
if (!static::upgradePHPUnitCheck($phpunit_package->getVersion())) {
$event->getComposer()
@@ -115,7 +115,7 @@ class Composer {
* @internal
*/
public static function upgradePHPUnitCheck($phpunit_version) {
- return !(version_compare(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, '7.4') >= 0 && version_compare($phpunit_version, '9.0') < 0);
+ return !(version_compare(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, '8.4') >= 0 && version_compare($phpunit_version, '11.0') < 0);
}
}
diff --git a/core/lib/Drupal/Core/Hook/Attribute/FormAlter.php b/core/lib/Drupal/Core/Hook/Attribute/FormAlter.php
index 95a8ed14768b..158010463d2a 100644
--- a/core/lib/Drupal/Core/Hook/Attribute/FormAlter.php
+++ b/core/lib/Drupal/Core/Hook/Attribute/FormAlter.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Drupal\Core\Hook\Attribute;
+use Drupal\Core\Hook\Order\OrderInterface;
+
/**
* Hook attribute for FormAlter.
*
@@ -37,13 +39,16 @@ class FormAlter extends Hook {
* (optional) The module this implementation is for. This allows one module
* to implement a hook on behalf of another module. Defaults to the module
* the implementation is in.
+ * @param \Drupal\Core\Hook\Order\OrderInterface|null $order
+ * (optional) Set the order of the implementation.
*/
public function __construct(
string $form_id = '',
public string $method = '',
public ?string $module = NULL,
+ public ?OrderInterface $order = NULL,
) {
- parent::__construct($form_id, $method, $module);
+ parent::__construct($form_id, $method, $module, $order);
}
}
diff --git a/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php b/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php
index 941c11ac27eb..757f647e5f0a 100644
--- a/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php
+++ b/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php
@@ -21,7 +21,41 @@ class CachedStrategy implements PlaceholderStrategyInterface {
* {@inheritdoc}
*/
public function processPlaceholders(array $placeholders) {
- return $this->renderCache->getMultiple($placeholders);
+ $return = $this->renderCache->getMultiple($placeholders);
+ if ($return) {
+ $return = $this->processNestedPlaceholders($return);
+ }
+
+ return $return;
+ }
+
+ /**
+ * Fetch any nested placeholders from cache.
+ *
+ * Placeholders returned from cache may have placeholders in #attached, which
+ * can themselves be fetched from the cache. By recursively processing the
+ * placeholders here, we're able to use multiple cache get to fetch the cache
+ * items at each level of recursion.
+ */
+ private function processNestedPlaceholders(array $placeholders): array {
+ $sets = [];
+ foreach ($placeholders as $key => $placeholder) {
+ if (!empty($placeholder['#attached']['placeholders'])) {
+ $sets[] = $placeholder['#attached']['placeholders'];
+ }
+ }
+ if ($sets) {
+ $cached = $this->renderCache->getMultiple(...array_merge($sets));
+ if ($cached) {
+ $cached = $this->processNestedPlaceholders($cached);
+ foreach ($placeholders as $key => $placeholder) {
+ if (!empty($placeholder['#attached']['placeholders'])) {
+ $placeholders[$key]['#attached']['placeholders'] = array_replace($placeholder['#attached']['placeholders'], $cached);
+ }
+ }
+ }
+ }
+ return $placeholders;
}
}
diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
index 3293b07b44bf..3f3a5ee9a96d 100644
--- a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
+++ b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
@@ -160,8 +160,12 @@ class PhpUnitTestRunner implements ContainerInjectionInterface {
// If the deprecation handler bridge is active, we need to fail when there
// are deprecations that get reported (i.e. not ignored or expected).
- if (DeprecationHandler::getConfiguration() !== FALSE) {
+ $deprecationConfiguration = DeprecationHandler::getConfiguration();
+ if ($deprecationConfiguration !== FALSE) {
$command[] = '--fail-on-deprecation';
+ if ($deprecationConfiguration['failOnPhpunitDeprecation']) {
+ $command[] = '--fail-on-phpunit-deprecation';
+ }
}
// Add to the command the file containing the test class to be run.
diff --git a/core/lib/Drupal/Core/Theme/ThemeCommonElements.php b/core/lib/Drupal/Core/Theme/ThemeCommonElements.php
index 03e143662558..5ddf58fd6f22 100644
--- a/core/lib/Drupal/Core/Theme/ThemeCommonElements.php
+++ b/core/lib/Drupal/Core/Theme/ThemeCommonElements.php
@@ -176,6 +176,7 @@ class ThemeCommonElements {
],
'includes' => ['core/includes/theme.maintenance.inc'],
'template' => 'authorize-report',
+ 'deprecated' => 'The "authorize-report" template is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119',
],
'pager' => [
'render element' => 'pager',
diff --git a/core/modules/ckeditor5/tests/src/Unit/HTMLRestrictionsTest.php b/core/modules/ckeditor5/tests/src/Unit/HTMLRestrictionsTest.php
index f512c008ceeb..dfd6c1db1da8 100644
--- a/core/modules/ckeditor5/tests/src/Unit/HTMLRestrictionsTest.php
+++ b/core/modules/ckeditor5/tests/src/Unit/HTMLRestrictionsTest.php
@@ -1131,8 +1131,8 @@ class HTMLRestrictionsTest extends UnitTestCase {
'expected_union' => 'a',
];
yield 'attribute restrictions are different: <ol type=*> vs <ol type="A"> — vice versa' => [
- 'b' => new HTMLRestrictions(['ol' => ['type' => ['A' => TRUE]]]),
- 'a' => new HTMLRestrictions(['ol' => ['type' => TRUE]]),
+ 'a' => new HTMLRestrictions(['ol' => ['type' => ['A' => TRUE]]]),
+ 'b' => new HTMLRestrictions(['ol' => ['type' => TRUE]]),
'expected_diff' => HTMLRestrictions::emptySet(),
'expected_intersection' => 'a',
'expected_union' => 'b',
@@ -1145,8 +1145,8 @@ class HTMLRestrictionsTest extends UnitTestCase {
'expected_union' => 'a',
];
yield 'attribute restrictions are different: <ol type=*> vs <ol type="1"> — vice versa' => [
- 'b' => new HTMLRestrictions(['ol' => ['type' => ['1' => TRUE]]]),
- 'a' => new HTMLRestrictions(['ol' => ['type' => TRUE]]),
+ 'a' => new HTMLRestrictions(['ol' => ['type' => ['1' => TRUE]]]),
+ 'b' => new HTMLRestrictions(['ol' => ['type' => TRUE]]),
'expected_diff' => HTMLRestrictions::emptySet(),
'expected_intersection' => 'a',
'expected_union' => 'b',
diff --git a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
index 41174b60490b..eadb49642080 100644
--- a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
+++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
@@ -56,7 +56,7 @@ class ModerationStateFieldItemList extends FieldItemList {
// It is possible that the bundle does not exist at this point. For example,
// the node type form creates a fake Node entity to get default values.
- // @see \Drupal\node\NodeTypeForm::form()
+ // @see \Drupal\node\Form\NodeTypeForm::form()
$workflow = $moderation_info->getWorkFlowForEntity($entity);
return $workflow ? $workflow->getTypePlugin()->getInitialState($entity)->id() : NULL;
}
diff --git a/core/modules/field_ui/src/Hook/FieldUiHooks.php b/core/modules/field_ui/src/Hook/FieldUiHooks.php
index 06434e2ec4df..3210e2f7c5b4 100644
--- a/core/modules/field_ui/src/Hook/FieldUiHooks.php
+++ b/core/modules/field_ui/src/Hook/FieldUiHooks.php
@@ -249,7 +249,7 @@ class FieldUiHooks {
*
* Adds a button 'Save and manage fields' to forms.
*
- * @see \Drupal\node\NodeTypeForm
+ * @see \Drupal\node\Form\NodeTypeForm
* @see \Drupal\comment\CommentTypeForm
* @see \Drupal\media\MediaTypeForm
* @see \Drupal\block_content\BlockContentTypeForm
diff --git a/core/modules/media_library/tests/modules/media_library_test/src/Form/TestNodeFormOverride.php b/core/modules/media_library/tests/modules/media_library_test/src/Form/TestNodeFormOverride.php
index 4dda6ff75444..50305332a25d 100644
--- a/core/modules/media_library/tests/modules/media_library_test/src/Form/TestNodeFormOverride.php
+++ b/core/modules/media_library/tests/modules/media_library_test/src/Form/TestNodeFormOverride.php
@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Drupal\media_library_test\Form;
use Drupal\Core\Form\FormStateInterface;
-use Drupal\node\NodeForm;
+use Drupal\node\Form\NodeForm;
/**
* Override NodeForm to test media library form submission semantics.
diff --git a/core/modules/menu_ui/src/Hook/MenuUiHooks.php b/core/modules/menu_ui/src/Hook/MenuUiHooks.php
index 9b32ffa18247..46f2c85d1d76 100644
--- a/core/modules/menu_ui/src/Hook/MenuUiHooks.php
+++ b/core/modules/menu_ui/src/Hook/MenuUiHooks.php
@@ -121,7 +121,7 @@ class MenuUiHooks {
}
/**
- * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
+ * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\Form\NodeForm.
*
* Adds menu item fields to the node form.
*
@@ -231,7 +231,7 @@ class MenuUiHooks {
}
/**
- * Implements hook_form_FORM_ID_alter() for \Drupal\node\NodeTypeForm.
+ * Implements hook_form_FORM_ID_alter() for \Drupal\node\Form\NodeTypeForm.
*
* Adds menu options to the node type form.
*
diff --git a/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php b/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php
index 1999e3ad86f4..9e508da9b225 100644
--- a/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php
+++ b/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php
@@ -85,9 +85,9 @@ abstract class MigrateSourceTestBase extends KernelTestBase {
* The fully qualified class name of the plugin to be tested.
*/
protected function getPluginClass() {
- $covers = $this->getTestClassCovers();
- if (!empty($covers)) {
- return $covers[0];
+ $covers = $this->valueObjectForEvents()->metadata()->isCovers()->isClassLevel()->asArray();
+ if (isset($covers[0])) {
+ return $covers[0]->target();
}
else {
$this->fail('No plugin class was specified');
diff --git a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
index 3264d769c195..f1ca3242a2a8 100644
--- a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
+++ b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
@@ -73,14 +73,14 @@ class PerformanceTest extends PerformanceTestBase {
$expected = [
'QueryCount' => 4,
- 'CacheGetCount' => 49,
+ 'CacheGetCount' => 48,
'CacheGetCountByBin' => [
'config' => 11,
'data' => 4,
'discovery' => 10,
'bootstrap' => 6,
'dynamic_page_cache' => 1,
- 'render' => 16,
+ 'render' => 15,
'menu' => 1,
],
'CacheSetCount' => 2,
diff --git a/core/modules/node/config/schema/node.schema.yml b/core/modules/node/config/schema/node.schema.yml
index 08fe92cc401e..8c81f68ae604 100644
--- a/core/modules/node/config/schema/node.schema.yml
+++ b/core/modules/node/config/schema/node.schema.yml
@@ -24,7 +24,7 @@ node.type.*:
label: 'Machine-readable name'
constraints:
# Node type machine names are specifically limited to 32 characters.
- # @see \Drupal\node\NodeTypeForm::form()
+ # @see \Drupal\node\Form\NodeTypeForm::form()
Length:
max: 32
description:
@@ -50,7 +50,7 @@ node.type.*:
constraints:
# These are the values of the DRUPAL_DISABLED, DRUPAL_OPTIONAL, and
# DRUPAL_REQUIRED constants.
- # @see \Drupal\node\NodeTypeForm::form()
+ # @see \Drupal\node\Form\NodeTypeForm::form()
Choice: [0, 1, 2]
display_submitted:
type: boolean
diff --git a/core/modules/node/node.services.yml b/core/modules/node/node.services.yml
index a70ae7faa576..83eb19f7355d 100644
--- a/core/modules/node/node.services.yml
+++ b/core/modules/node/node.services.yml
@@ -1,3 +1,16 @@
+parameters:
+ node.moved_classes:
+ 'Drupal\node\NodeForm':
+ class: 'Drupal\node\Form\NodeForm'
+ deprecation_version: drupal:11.2.0
+ removed_version: drupal:12.0.0
+ change_record: https://www.drupal.org/node/3517871
+ 'Drupal\node\NodeTypeForm':
+ class: 'Drupal\node\Form\NodeTypeForm'
+ deprecation_version: drupal:11.2.0
+ removed_version: drupal:12.0.0
+ change_record: https://www.drupal.org/node/3517871
+
services:
_defaults:
autoconfigure: true
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index f4c519a43c8a..0f61a74f1c01 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -11,8 +11,8 @@ use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\node\Form\DeleteMultiple;
use Drupal\node\Form\NodeDeleteForm;
+use Drupal\node\Form\NodeForm;
use Drupal\node\NodeAccessControlHandler;
-use Drupal\node\NodeForm;
use Drupal\node\NodeInterface;
use Drupal\node\NodeListBuilder;
use Drupal\node\NodeStorage;
diff --git a/core/modules/node/src/Entity/NodeType.php b/core/modules/node/src/Entity/NodeType.php
index 35b911d7ffb7..48d295635f3d 100644
--- a/core/modules/node/src/Entity/NodeType.php
+++ b/core/modules/node/src/Entity/NodeType.php
@@ -9,7 +9,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\node\Form\NodeTypeDeleteConfirm;
use Drupal\node\NodeTypeAccessControlHandler;
-use Drupal\node\NodeTypeForm;
+use Drupal\node\Form\NodeTypeForm;
use Drupal\node\NodeTypeInterface;
use Drupal\node\NodeTypeListBuilder;
use Drupal\user\Entity\EntityPermissionsRouteProvider;
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/Form/NodeForm.php
index ab81a4e3f928..d5afa396568c 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/Form/NodeForm.php
@@ -1,6 +1,6 @@
<?php
-namespace Drupal\node;
+namespace Drupal\node\Form;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
@@ -163,7 +163,7 @@ class NodeForm extends ContentEntityForm {
$form['meta']['author'] = [
'#type' => 'item',
'#title' => $this->t('Author'),
- '#markup' => $node->getOwner()->getAccountName(),
+ '#markup' => $node->getOwner()?->getAccountName(),
'#wrapper_attributes' => ['class' => ['entity-meta__author']],
];
diff --git a/core/modules/node/src/NodeTypeForm.php b/core/modules/node/src/Form/NodeTypeForm.php
index 3328ade970da..93d510d4387e 100644
--- a/core/modules/node/src/NodeTypeForm.php
+++ b/core/modules/node/src/Form/NodeTypeForm.php
@@ -1,6 +1,6 @@
<?php
-namespace Drupal\node;
+namespace Drupal\node\Form;
use Drupal\Core\Entity\BundleEntityFormBase;
use Drupal\Core\Entity\EntityFieldManagerInterface;
diff --git a/core/modules/node/tests/modules/node_no_default_author/node_no_default_author.info.yml b/core/modules/node/tests/modules/node_no_default_author/node_no_default_author.info.yml
new file mode 100644
index 000000000000..c4f56344370f
--- /dev/null
+++ b/core/modules/node/tests/modules/node_no_default_author/node_no_default_author.info.yml
@@ -0,0 +1,5 @@
+name: 'Node no default author'
+type: module
+description: 'Disables the default value callback for the uid field on node.'
+package: Testing
+version: VERSION
diff --git a/core/modules/node/tests/modules/node_no_default_author/src/Hook/NodeNoDefaultAuthorHooks.php b/core/modules/node/tests/modules/node_no_default_author/src/Hook/NodeNoDefaultAuthorHooks.php
new file mode 100644
index 000000000000..700e82236adc
--- /dev/null
+++ b/core/modules/node/tests/modules/node_no_default_author/src/Hook/NodeNoDefaultAuthorHooks.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\node_no_default_author\Hook;
+
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for node_no_default_author.
+ */
+class NodeNoDefaultAuthorHooks {
+
+ /**
+ * Implements hook_entity_base_field_info_alter().
+ */
+ #[Hook('entity_base_field_info_alter')]
+ public function entityBaseFieldInfoAlter(&$fields, EntityTypeInterface $entity_type): void {
+ if ($entity_type->id() === 'node') {
+ $fields['uid']->setDefaultValueCallback(static::class . '::noDefaultAuthor');
+ }
+ }
+
+ /**
+ * An empty callback to set for the default value callback of uid.
+ */
+ public static function noDefaultAuthor(): void {
+ }
+
+}
diff --git a/core/modules/node/tests/src/Functional/NodeEditFormTest.php b/core/modules/node/tests/src/Functional/NodeEditFormTest.php
index bc8cfa927e43..dc47998c9093 100644
--- a/core/modules/node/tests/src/Functional/NodeEditFormTest.php
+++ b/core/modules/node/tests/src/Functional/NodeEditFormTest.php
@@ -258,6 +258,16 @@ class NodeEditFormTest extends NodeTestBase {
}
/**
+ * Tests the node form when the author is NULL.
+ */
+ public function testNodeFormNullAuthor(): void {
+ \Drupal::service('module_installer')->install(['node_no_default_author']);
+ $this->drupalLogin($this->adminUser);
+ $this->drupalGet('node/add/page');
+ $this->assertSession()->statusCodeEquals(200);
+ }
+
+ /**
* Checks that the "authored by" works correctly with various values.
*
* @param \Drupal\node\NodeInterface $node
diff --git a/core/modules/system/templates/authorize-report.html.twig b/core/modules/system/templates/authorize-report.html.twig
index 914458684775..f6f443c58075 100644
--- a/core/modules/system/templates/authorize-report.html.twig
+++ b/core/modules/system/templates/authorize-report.html.twig
@@ -12,6 +12,11 @@
* @see template_preprocess_authorize_report()
*
* @ingroup themeable
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
#}
{% if messages %}
diff --git a/core/modules/update/src/Hook/UpdateHooks.php b/core/modules/update/src/Hook/UpdateHooks.php
index 293882f01246..49cb455a8430 100644
--- a/core/modules/update/src/Hook/UpdateHooks.php
+++ b/core/modules/update/src/Hook/UpdateHooks.php
@@ -178,8 +178,6 @@ class UpdateHooks {
\Drupal::moduleHandler()->loadInclude('update', 'inc', 'update.fetch');
_update_cron_notify();
}
- // Clear garbage from disk.
- update_clear_update_disk_cache();
}
/**
diff --git a/core/modules/update/src/UpdateRoot.php b/core/modules/update/src/UpdateRoot.php
index a2f1619d6ea6..abcf499d5b4b 100644
--- a/core/modules/update/src/UpdateRoot.php
+++ b/core/modules/update/src/UpdateRoot.php
@@ -6,7 +6,12 @@ use Drupal\Core\DrupalKernelInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
- * Gets the root path used by the Update Manager to install or update projects.
+ * Gets the root path used by the legacy Update Manager to install or update projects.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
class UpdateRoot {
@@ -32,7 +37,7 @@ class UpdateRoot {
protected $updateRoot;
/**
- * Constructs an UpdateRootFactory instance.
+ * Constructs an UpdateRoot instance.
*
* @param \Drupal\Core\DrupalKernelInterface $drupal_kernel
* The Drupal kernel.
@@ -40,6 +45,7 @@ class UpdateRoot {
* The request stack.
*/
public function __construct(DrupalKernelInterface $drupal_kernel, RequestStack $request_stack) {
+ @trigger_error(__CLASS__ . ' is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
$this->drupalKernel = $drupal_kernel;
$this->requestStack = $request_stack;
}
diff --git a/core/modules/update/tests/src/Functional/UpdateManagerTest.php b/core/modules/update/tests/src/Functional/UpdateManagerTest.php
new file mode 100644
index 000000000000..a69e06a72fdd
--- /dev/null
+++ b/core/modules/update/tests/src/Functional/UpdateManagerTest.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\update\Functional;
+
+/**
+ * Tests legacy Update Manager functionality of the Update Status module.
+ *
+ * @group legacy
+ * @group update
+ */
+class UpdateManagerTest extends UpdateTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected $defaultTheme = 'stark';
+
+ /**
+ * Checks that clearing the disk cache works.
+ */
+ public function testClearDiskCache(): void {
+ $directories = [
+ _update_manager_cache_directory(FALSE),
+ _update_manager_extract_directory(FALSE),
+ ];
+ // Check that update directories does not exists.
+ foreach ($directories as $directory) {
+ $this->assertDirectoryDoesNotExist($directory);
+ }
+
+ // Method must not fail if update directories do not exists.
+ update_clear_update_disk_cache();
+ }
+
+}
diff --git a/core/modules/update/tests/src/Functional/UpdateMiscTest.php b/core/modules/update/tests/src/Functional/UpdateMiscTest.php
index 5b544ea36b0e..3a06d965ee5e 100644
--- a/core/modules/update/tests/src/Functional/UpdateMiscTest.php
+++ b/core/modules/update/tests/src/Functional/UpdateMiscTest.php
@@ -41,23 +41,6 @@ class UpdateMiscTest extends UpdateTestBase {
}
/**
- * Checks that clearing the disk cache works.
- */
- public function testClearDiskCache(): void {
- $directories = [
- _update_manager_cache_directory(FALSE),
- _update_manager_extract_directory(FALSE),
- ];
- // Check that update directories does not exists.
- foreach ($directories as $directory) {
- $this->assertDirectoryDoesNotExist($directory);
- }
-
- // Method must not fail if update directories do not exists.
- update_clear_update_disk_cache();
- }
-
- /**
* Tests the Update Status module when the update server returns 503 errors.
*/
public function testServiceUnavailable(): void {
diff --git a/core/modules/update/tests/src/Kernel/UpdateDeleteFileIfStaleTest.php b/core/modules/update/tests/src/Kernel/UpdateDeleteFileIfStaleTest.php
index ff5a8b02d457..1e33d81d6141 100644
--- a/core/modules/update/tests/src/Kernel/UpdateDeleteFileIfStaleTest.php
+++ b/core/modules/update/tests/src/Kernel/UpdateDeleteFileIfStaleTest.php
@@ -10,6 +10,7 @@ use Drupal\KernelTests\KernelTestBase;
* Tests the update_delete_file_if_stale() function.
*
* @group update
+ * @group legacy
*/
class UpdateDeleteFileIfStaleTest extends KernelTestBase {
diff --git a/core/modules/update/update.authorize.inc b/core/modules/update/update.authorize.inc
index 64f8fe7b014a..59bcd97f2325 100644
--- a/core/modules/update/update.authorize.inc
+++ b/core/modules/update/update.authorize.inc
@@ -107,6 +107,7 @@ function update_authorize_batch_copy_project($project, $updater_name, $local_url
return;
}
+ // @phpstan-ignore getDeprecatedService.deprecated
$updater = new $updater_name($local_url, \Drupal::getContainer()->get('update.root'));
try {
diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc
index f4b18321002b..e76854ae8de9 100644
--- a/core/modules/update/update.manager.inc
+++ b/core/modules/update/update.manager.inc
@@ -172,9 +172,11 @@ function update_manager_file_get($url) {
}
// Check the cache and download the file if needed.
+ // @phpstan-ignore function.deprecated
$cache_directory = _update_manager_cache_directory();
$local = $cache_directory . '/' . \Drupal::service('file_system')->basename($parsed_url['path']);
+ // @phpstan-ignore function.deprecated
if (!file_exists($local) || update_delete_file_if_stale($local)) {
try {
$data = (string) \Drupal::httpClient()->get($url)->getBody();
@@ -229,6 +231,7 @@ function update_manager_batch_project_get($project, $url, &$context): void {
}
// Extract it.
+ // @phpstan-ignore function.deprecated
$extract_directory = _update_manager_extract_directory();
try {
update_manager_archive_extract($local_cache, $extract_directory);
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index e06ac21ea317..89e94fe7b1d7 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -276,8 +276,15 @@ function update_storage_clear(): void {
*
* @return string
* An eight character string uniquely identifying this Drupal installation.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
function _update_manager_unique_identifier() {
+ @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
+
static $id;
if (!isset($id)) {
$id = substr(hash('sha256', Settings::getHashSalt()), 0, 8);
@@ -295,8 +302,15 @@ function _update_manager_unique_identifier() {
* @return string
* The full path to the temporary directory where update file archives should
* be extracted.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
function _update_manager_extract_directory($create = TRUE) {
+ @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
+
static $directory;
if (!isset($directory)) {
$directory = 'temporary://update-extraction-' . _update_manager_unique_identifier();
@@ -317,8 +331,15 @@ function _update_manager_extract_directory($create = TRUE) {
* @return string
* The full path to the temporary directory where update file archives should
* be cached.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
function _update_manager_cache_directory($create = TRUE) {
+ @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
+
static $directory;
if (!isset($directory)) {
$directory = 'temporary://update-cache-' . _update_manager_unique_identifier();
@@ -331,8 +352,15 @@ function _update_manager_cache_directory($create = TRUE) {
/**
* Clears the temporary files and directories based on file age from disk.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
function update_clear_update_disk_cache(): void {
+ @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
+
// List of update module cache directories. Do not create the directories if
// they do not exist.
$directories = [
@@ -368,8 +396,15 @@ function update_clear_update_disk_cache(): void {
*
* @return bool
* TRUE if the file is stale and deleted successfully, FALSE otherwise.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
function update_delete_file_if_stale($path) {
+ @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
+
if (file_exists($path)) {
$filectime = filectime($path);
$max_age = \Drupal::config('system.file')->get('temporary_maximum_age');
diff --git a/core/modules/update/update.post_update.php b/core/modules/update/update.post_update.php
index 3462899d989b..34ddba396858 100644
--- a/core/modules/update/update.post_update.php
+++ b/core/modules/update/update.post_update.php
@@ -5,6 +5,8 @@
* Post update functions for Update Status.
*/
+use Drupal\Core\Site\Settings;
+
/**
* Implements hook_removed_post_updates().
*/
@@ -14,3 +16,24 @@ function update_remove_post_updates() {
'update_post_update_set_blank_fetch_url_to_null' => '11.0.0',
];
}
+
+/**
+ * Removes the legacy 'Update Manager' disk cache.
+ */
+function update_post_update_clear_disk_cache(): void {
+ // @see _update_manager_unique_id()
+ $id = substr(hash('sha256', Settings::getHashSalt()), 0, 8);
+ // List of legacy 'Update Manager' cache directories.
+ $directories = [
+ // @see _update_manager_cache_directory()
+ "temporary://update-cache-$id",
+ // @see _update_manager_extract_directory()
+ "temporary://update-extraction-$id",
+ ];
+ foreach ($directories as $directory) {
+ if (is_dir($directory)) {
+ \Drupal::service('file_system')->deleteRecursive($directory);
+ }
+ }
+
+}
diff --git a/core/modules/update/update.services.yml b/core/modules/update/update.services.yml
index 465df135529a..bebf0398151c 100644
--- a/core/modules/update/update.services.yml
+++ b/core/modules/update/update.services.yml
@@ -21,6 +21,7 @@ services:
update.root:
class: Drupal\update\UpdateRoot
arguments: ['@kernel', '@request_stack']
+ deprecated: The "%service_id%" service is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119
logger.channel.update:
parent: logger.channel_base
arguments: [ 'update' ]
diff --git a/core/modules/views/src/Hook/ViewsViewsHooks.php b/core/modules/views/src/Hook/ViewsViewsHooks.php
index 531f6c754fa2..a54decce9e62 100644
--- a/core/modules/views/src/Hook/ViewsViewsHooks.php
+++ b/core/modules/views/src/Hook/ViewsViewsHooks.php
@@ -183,6 +183,7 @@ class ViewsViewsHooks {
if (is_array($result)) {
$data = NestedArray::mergeDeep($result, $data);
}
+ \Drupal::moduleHandler()->invoke($field_storage->getTypeProvider(), 'field_views_data_views_data_alter', [&$data, $field_storage]);
}
}
}
@@ -190,28 +191,6 @@ class ViewsViewsHooks {
}
/**
- * Implements hook_views_data_alter().
- *
- * Field modules can implement hook_field_views_data_views_data_alter() to
- * alter the views data on a per field basis. This is weirdly named so as not
- * to conflict with the \Drupal::moduleHandler()->alter('field_views_data') in
- * views_views_data().
- */
- #[Hook('views_data_alter')]
- public function viewsDataAlter(&$data): void {
- $entity_type_manager = \Drupal::entityTypeManager();
- if (!$entity_type_manager->hasDefinition('field_storage_config')) {
- return;
- }
- /** @var \Drupal\field\FieldStorageConfigInterface $field_storage */
- foreach ($entity_type_manager->getStorage('field_storage_config')->loadMultiple() as $field_storage) {
- if (\Drupal::service('views.field_data_provider')->getSqlStorageForField($field_storage)) {
- \Drupal::moduleHandler()->invoke($field_storage->getTypeProvider(), 'field_views_data_views_data_alter', [&$data, $field_storage]);
- }
- }
- }
-
- /**
* Implements hook_field_views_data().
*
* The function implements the hook on behalf of 'core' because it adds a
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index 8915265e148e..c858081cad26 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -100,25 +100,35 @@
<directory>modules/**/tests/src/Kernel</directory>
<directory>recipes/*/tests/src/Kernel</directory>
<directory>profiles/**/tests/src/Kernel</directory>
- <directory>profiles/tests/testing/modules/*/tests/src/Kernel</directory>
<directory>themes/**/tests/src/Kernel</directory>
<directory>../modules/**/tests/src/Kernel</directory>
<directory>../profiles/**/tests/src/Kernel</directory>
<directory>../themes/**/tests/src/Kernel</directory>
+ <!-- @todo remove line(s) below once PHPUnit 10 is no longer used; they
+ are redundant in PHPUnit 11+ that fully implements globstar (**)
+ pattern.
+ @see https://www.drupal.org/project/drupal/issues/3497116
+ -->
+ <directory>profiles/tests/testing/modules/*/tests/src/Kernel</directory>
</testsuite>
<testsuite name="functional">
<directory>tests/Drupal/FunctionalTests</directory>
<directory>modules/**/tests/src/Functional</directory>
- <directory>modules/config/tests/config_test/tests/src/Functional</directory>
- <directory>modules/system/tests/modules/entity_test/tests/src/Functional</directory>
- <directory>modules/layout_builder/modules/layout_builder_expose_all_field_blocks/tests/src/Functional</directory>
<directory>profiles/**/tests/src/Functional</directory>
- <directory>profiles/demo_umami/modules/demo_umami_content/tests/src/Functional</directory>
<directory>recipes/*/tests/src/Functional</directory>
<directory>themes/**/tests/src/Functional</directory>
<directory>../modules/**/tests/src/Functional</directory>
<directory>../profiles/**/tests/src/Functional</directory>
<directory>../themes/**/tests/src/Functional</directory>
+ <!-- @todo remove line(s) below once PHPUnit 10 is no longer used; they
+ are redundant in PHPUnit 11+ that fully implements globstar (**)
+ pattern.
+ @see https://www.drupal.org/project/drupal/issues/3497116
+ -->
+ <directory>modules/config/tests/config_test/tests/src/Functional</directory>
+ <directory>modules/system/tests/modules/entity_test/tests/src/Functional</directory>
+ <directory>modules/layout_builder/modules/layout_builder_expose_all_field_blocks/tests/src/Functional</directory>
+ <directory>profiles/demo_umami/modules/demo_umami_content/tests/src/Functional</directory>
</testsuite>
<testsuite name="functional-javascript">
<directory>tests/Drupal/FunctionalJavascriptTests</directory>
@@ -152,9 +162,6 @@
<directory>../modules/*/tests</directory>
<directory>../modules/*/*/src/Tests</directory>
<directory>../modules/*/*/tests</directory>
- <directory suffix=".api.php">./lib/**</directory>
- <directory suffix=".api.php">./modules/**</directory>
- <directory suffix=".api.php">../modules/**</directory>
</exclude>
</source>
</phpunit>
diff --git a/core/scripts/js/vendor-update.js b/core/scripts/js/vendor-update.js
index 1b5de61fa36d..4a6f2ef91c69 100644
--- a/core/scripts/js/vendor-update.js
+++ b/core/scripts/js/vendor-update.js
@@ -81,11 +81,11 @@ const assetsFolder = `${coreFolder}/assets/vendor`;
},
{
pack: 'htmx.org',
+ folder: 'htmx',
library: 'htmx',
files: [
{ from: 'dist/htmx.min.js', to: 'htmx.min.js' },
{ from: 'dist/htmx.js', to: 'htmx.js' },
- { from: 'dist/ext/debug.js', to: 'debug.js' },
],
},
{
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index c1ca97703df8..4545a00cc3ac 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -173,7 +173,7 @@ if ($args['clean']) {
}
if (!Composer::upgradePHPUnitCheck(Version::id())) {
- simpletest_script_print_error("PHPUnit testing framework version 9 or greater is required when running on PHP 7.4 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.");
+ simpletest_script_print_error("PHPUnit testing framework version 11 or greater is required when running on PHP 8.4 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.");
exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
}
diff --git a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitTestDiscoveryTest.php b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitTestDiscoveryTest.php
index 6d7fcaeed9ae..705981f75079 100644
--- a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitTestDiscoveryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitTestDiscoveryTest.php
@@ -6,6 +6,7 @@ namespace Drupal\KernelTests\Core\Test;
use Drupal\Core\Test\TestDiscovery;
use Drupal\KernelTests\KernelTestBase;
+use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion;
use PHPUnit\TextUI\Configuration\Builder;
use PHPUnit\TextUI\Configuration\TestSuiteBuilder;
use Symfony\Component\Process\Process;
@@ -96,14 +97,28 @@ class PhpUnitTestDiscoveryTest extends KernelTestBase {
$phpUnitXmlList = new \DOMDocument();
$phpUnitXmlList->loadXML(file_get_contents($this->xmlOutputFile));
$phpUnitClientList = [];
+ // Try PHPUnit 10 format first.
+ // @todo remove once PHPUnit 10 is no longer used.
foreach ($phpUnitXmlList->getElementsByTagName('testCaseClass') as $node) {
$phpUnitClientList[] = $node->getAttribute('name');
}
+ // If empty, try PHPUnit 11+ format.
+ if (empty($phpUnitClientList)) {
+ foreach ($phpUnitXmlList->getElementsByTagName('testClass') as $node) {
+ $phpUnitClientList[] = $node->getAttribute('name');
+ }
+ }
asort($phpUnitClientList);
// Check against Drupal's discovery.
$this->assertEquals(implode("\n", $phpUnitClientList), implode("\n", $internalList), self::TEST_LIST_MISMATCH_MESSAGE);
+ // @todo once PHPUnit 10 is no longer used re-enable the rest of the test.
+ // @see https://www.drupal.org/project/drupal/issues/3497116
+ if (RunnerVersion::getMajor() >= 11) {
+ $this->markTestIncomplete('On PHPUnit 11+ the test triggers warnings due to phpunit.xml setup. Re-enable in https://www.drupal.org/project/drupal/issues/3497116.');
+ }
+
// PHPUnit's test discovery - via API.
$phpUnitConfiguration = (new Builder())->build(['--configuration', 'core']);
$phpUnitTestSuite = (new TestSuiteBuilder())->build($phpUnitConfiguration);
diff --git a/core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php b/core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php
index c176980bae27..f66ef7c8c947 100644
--- a/core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php
+++ b/core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php
@@ -76,6 +76,11 @@ final class DeprecationHandler {
$environmentVariable = "ignoreFile=$deprecationIgnoreFilename";
}
parse_str($environmentVariable, $configuration);
+
+ $environmentVariable = getenv('PHPUNIT_FAIL_ON_PHPUNIT_DEPRECATION');
+ $phpUnitDeprecationVariable = $environmentVariable !== FALSE ? $environmentVariable : TRUE;
+ $configuration['failOnPhpunitDeprecation'] = filter_var($phpUnitDeprecationVariable, \FILTER_VALIDATE_BOOLEAN);
+
return $configuration;
}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit11/TestCompatibilityTrait.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit11/TestCompatibilityTrait.php
new file mode 100644
index 000000000000..84638f9f0f57
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit11/TestCompatibilityTrait.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit11;
+
+/**
+ * Drupal's forward compatibility layer with multiple versions of PHPUnit.
+ *
+ * @internal
+ */
+trait TestCompatibilityTrait {
+}
diff --git a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
index 8dd4d8fb5948..ae46c3cc5a56 100644
--- a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
+++ b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
@@ -671,16 +671,16 @@ class DateTimePlusTest extends TestCase {
// There should be a 19 hour time interval between
// new years in Sydney and new years in LA in year 2000.
[
- 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')),
- 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')),
+ 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')),
+ 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')),
'absolute' => FALSE,
'expected' => $positive_19_hours,
],
// In 1970 Sydney did not observe daylight savings time
// So there is only an 18 hour time interval.
[
- 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')),
- 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')),
+ 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')),
+ 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')),
'absolute' => FALSE,
'expected' => $positive_18_hours,
],
diff --git a/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php b/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
index b2c459e06a78..800483fab501 100644
--- a/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
@@ -65,6 +65,7 @@ class HtmlTest extends TestCase {
$id1 = 'abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789';
$id2 = '¡¢£¤¥';
$id3 = 'css__identifier__with__double__underscores';
+ $id4 = "\x80\x81";
return [
// Verify that no valid ASCII characters are stripped from the identifier.
[$id1, $id1, []],
@@ -73,6 +74,8 @@ class HtmlTest extends TestCase {
[$id2, $id2, []],
// Verify that double underscores are not stripped from the identifier.
[$id3, $id3],
+ // Confirm that NULL identifier does not trigger PHP 8.1 deprecation message.
+ ['', $id4],
// Verify that invalid characters (including non-breaking space) are
// stripped from the identifier.
['invalid_identifier', 'invalid_ !"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ identifier', []],
diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
index 2b4d2990d52e..76f5cc118ae6 100644
--- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
@@ -172,25 +172,17 @@ class ConfigEntityStorageTest extends UnitTestCase {
*/
public function testCreateWithPredefinedUuid(): void {
$this->cacheTagsInvalidator->invalidateTags(Argument::cetera())->shouldNotBeCalled();
-
- $entity = $this->getMockEntity();
- $entity->set('id', 'foo');
- $entity->set('langcode', 'hu');
- $entity->set('uuid', 'baz');
- $entity->setOriginalId('foo');
- $entity->enforceIsNew();
-
- $this->moduleHandler->invokeAll('test_entity_type_create', [$entity])
- ->shouldBeCalled();
- $this->moduleHandler->invokeAll('entity_create', [$entity, 'test_entity_type'])
- ->shouldBeCalled();
-
$this->uuidService->generate()->shouldNotBeCalled();
$entity = $this->entityStorage->create(['id' => 'foo', 'uuid' => 'baz']);
$this->assertInstanceOf(EntityInterface::class, $entity);
$this->assertSame('foo', $entity->id());
$this->assertSame('baz', $entity->uuid());
+
+ $this->moduleHandler->invokeAll('test_entity_type_create', [$entity])
+ ->shouldBeCalled();
+ $this->moduleHandler->invokeAll('entity_create', [$entity, 'test_entity_type'])
+ ->shouldBeCalled();
}
/**
@@ -202,25 +194,18 @@ class ConfigEntityStorageTest extends UnitTestCase {
*/
public function testCreate() {
$this->cacheTagsInvalidator->invalidateTags(Argument::cetera())->shouldNotBeCalled();
+ $this->uuidService->generate()->willReturn('bar');
- $entity = $this->getMockEntity();
- $entity->set('id', 'foo');
- $entity->set('langcode', 'hu');
- $entity->set('uuid', 'bar');
- $entity->setOriginalId('foo');
- $entity->enforceIsNew();
+ $entity = $this->entityStorage->create(['id' => 'foo']);
+ $this->assertInstanceOf(EntityInterface::class, $entity);
+ $this->assertSame('foo', $entity->id());
+ $this->assertSame('bar', $entity->uuid());
$this->moduleHandler->invokeAll('test_entity_type_create', [$entity])
->shouldBeCalled();
$this->moduleHandler->invokeAll('entity_create', [$entity, 'test_entity_type'])
->shouldBeCalled();
- $this->uuidService->generate()->willReturn('bar');
-
- $entity = $this->entityStorage->create(['id' => 'foo']);
- $this->assertInstanceOf(EntityInterface::class, $entity);
- $this->assertSame('foo', $entity->id());
- $this->assertSame('bar', $entity->uuid());
return $entity;
}
diff --git a/core/tests/Drupal/Tests/Core/Datetime/DrupalDateTimeTest.php b/core/tests/Drupal/Tests/Core/Datetime/DrupalDateTimeTest.php
index e1ec84395f9d..40b94bd046bf 100644
--- a/core/tests/Drupal/Tests/Core/Datetime/DrupalDateTimeTest.php
+++ b/core/tests/Drupal/Tests/Core/Datetime/DrupalDateTimeTest.php
@@ -84,16 +84,16 @@ class DrupalDateTimeTest extends UnitTestCase {
// There should be a 19 hour time interval between
// new years in Sydney and new years in LA in year 2000.
[
- 'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
- 'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
+ 'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
+ 'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
'absolute' => FALSE,
'expected' => $positive_19_hours,
],
// In 1970 Sydney did not observe daylight savings time
// So there is only an 18 hour time interval.
[
- 'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
- 'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
+ 'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
+ 'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
'absolute' => FALSE,
'expected' => $positive_18_hours,
],
diff --git a/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php
index f57a80d1393c..2381b64b83a5 100644
--- a/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php
@@ -206,11 +206,8 @@ class KeyValueEntityStorageTest extends UnitTestCase {
/**
* @covers ::create
* @covers ::doCreate
- *
- * @return \Drupal\Core\Entity\EntityInterface
- * The newly created entity instance with the specified ID and generated UUID.
*/
- public function testCreate() {
+ public function testCreate(): void {
$entity = $this->getMockEntity(EntityBaseTest::class, [], ['toArray']);
$this->entityType->expects($this->once())
->method('getClass')
@@ -231,24 +228,18 @@ class KeyValueEntityStorageTest extends UnitTestCase {
$this->assertInstanceOf('Drupal\Core\Entity\EntityInterface', $entity);
$this->assertSame('foo', $entity->id());
$this->assertSame('bar', $entity->uuid());
- return $entity;
}
/**
* @covers ::save
* @covers ::doSave
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity.
- *
- * @return \Drupal\Core\Entity\EntityInterface
- * The saved entity instance after insertion.
- *
- * @depends testCreate
*/
- public function testSaveInsert(EntityInterface $entity) {
+ public function testSaveInsert(): EntityInterface&MockObject {
$this->setUpKeyValueEntityStorage();
+ $entity = $this->getMockEntity(EntityBaseTest::class, [['id' => 'foo']], ['toArray']);
+ $entity->enforceIsNew();
+
$expected = ['id' => 'foo'];
$this->keyValueStore->expects($this->exactly(2))
->method('has')
@@ -285,12 +276,9 @@ class KeyValueEntityStorageTest extends UnitTestCase {
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity.
*
- * @return \Drupal\Core\Entity\EntityInterface
- * The updated entity instance after saving.
- *
* @depends testSaveInsert
*/
- public function testSaveUpdate(EntityInterface $entity) {
+ public function testSaveUpdate(EntityInterface $entity): void {
$this->entityType->expects($this->once())
->method('getClass')
->willReturn(get_class($entity));
@@ -320,7 +308,6 @@ class KeyValueEntityStorageTest extends UnitTestCase {
->with('foo', $expected);
$return = $this->entityStorage->save($entity);
$this->assertSame(SAVED_UPDATED, $return);
- return $entity;
}
/**
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
index 37cede409b88..5653e8a356b0 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
@@ -1105,12 +1105,7 @@ class SqlContentEntityStorageTest extends UnitTestCase {
$this->setUpEntityStorage();
$entity = $this->entityStorage->create();
- $entity->expects($this->atLeastOnce())
- ->method('id')
- ->willReturn('foo');
-
$this->assertInstanceOf(EntityInterface::class, $entity);
- $this->assertSame('foo', $entity->id());
$this->assertTrue($entity->isNew());
}
diff --git a/core/tests/PHPStan/composer.json b/core/tests/PHPStan/composer.json
index ab10409fcbff..f6fb20053884 100644
--- a/core/tests/PHPStan/composer.json
+++ b/core/tests/PHPStan/composer.json
@@ -2,7 +2,7 @@
"name": "drupal/phpstan-testing",
"description": "Tests Drupal core's PHPStan rules",
"require-dev": {
- "phpunit/phpunit": "^10",
+ "phpunit/phpunit": "^11",
"phpstan/phpstan": "2.1.12"
},
"license": "GPL-2.0-or-later",
diff --git a/core/themes/claro/claro.theme b/core/themes/claro/claro.theme
index c406fed47c22..a031dc860c35 100644
--- a/core/themes/claro/claro.theme
+++ b/core/themes/claro/claro.theme
@@ -665,7 +665,7 @@ function _claro_convert_link_to_action_link(array $link, $icon_name = NULL, $siz
}
/**
- * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
+ * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\Form\NodeForm.
*
* Changes vertical tabs to container.
*/
diff --git a/core/themes/stable9/templates/admin/authorize-report.html.twig b/core/themes/stable9/templates/admin/authorize-report.html.twig
index 2e5a59c0c03b..8784ca30cd89 100644
--- a/core/themes/stable9/templates/admin/authorize-report.html.twig
+++ b/core/themes/stable9/templates/admin/authorize-report.html.twig
@@ -10,6 +10,11 @@
* - attributes: HTML attributes for the element.
*
* @see template_preprocess_authorize_report()
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
#}
{% if messages %}
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 666a39643736..d4ba8a91829a 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -476,30 +476,6 @@ $settings['update_free_access'] = FALSE;
# $settings['class_loader_auto_detect'] = FALSE;
/**
- * Authorized file system operations:
- *
- * The Update Manager module included with Drupal provides a mechanism for
- * site administrators to securely install missing updates for the site
- * directly through the web user interface. On securely-configured servers,
- * the Update manager will require the administrator to provide SSH or FTP
- * credentials before allowing the installation to proceed; this allows the
- * site to update the new files as the user who owns all the Drupal files,
- * instead of as the user the webserver is running as. On servers where the
- * webserver user is itself the owner of the Drupal files, the administrator
- * will not be prompted for SSH or FTP credentials (note that these server
- * setups are common on shared hosting, but are inherently insecure).
- *
- * Some sites might wish to disable the above functionality, and only update
- * the code directly via SSH or FTP themselves. This setting completely
- * disables all functionality related to these authorized file operations.
- *
- * @see https://www.drupal.org/node/244924
- *
- * Remove the leading hash signs to disable.
- */
-# $settings['allow_authorize_operations'] = FALSE;
-
-/**
* Default mode for directories and files written by Drupal.
*
* Value should be in PHP Octal Notation, with leading zero.