diff --git a/composer.lock b/composer.lock index 987d30de..1b93c22e 100644 --- a/composer.lock +++ b/composer.lock @@ -60,16 +60,16 @@ }, { "name": "chi-teck/drupal-code-generator", - "version": "1.32.0", + "version": "1.33.0", "source": { "type": "git", "url": "https://github.com/Chi-teck/drupal-code-generator.git", - "reference": "0e045f7a7e747af3d8f603156bf4d73be5768246" + "reference": "49f4ce174ed83764e3389ddb75c4758772435243" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/0e045f7a7e747af3d8f603156bf4d73be5768246", - "reference": "0e045f7a7e747af3d8f603156bf4d73be5768246", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/49f4ce174ed83764e3389ddb75c4758772435243", + "reference": "49f4ce174ed83764e3389ddb75c4758772435243", "shasum": "" }, "require": { @@ -79,6 +79,9 @@ "symfony/filesystem": "^2.7 || ^3.4 || ^4.0", "twig/twig": "^1.41 || ^2.12" }, + "conflict": { + "drush/drush": "< 10.3.2" + }, "bin": [ "bin/dcg" ], @@ -101,27 +104,27 @@ "GPL-2.0-or-later" ], "description": "Drupal code generator", - "time": "2020-04-16T06:45:06+00:00" + "time": "2020-10-11T16:56:42+00:00" }, { "name": "clue/stream-filter", - "version": "v1.4.1", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/clue/php-stream-filter.git", - "reference": "5a58cc30a8bd6a4eb8f856adf61dd3e013f53f71" + "reference": "aeb7d8ea49c7963d3b581378955dbf5bc49aa320" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/clue/php-stream-filter/zipball/5a58cc30a8bd6a4eb8f856adf61dd3e013f53f71", - "reference": "5a58cc30a8bd6a4eb8f856adf61dd3e013f53f71", + "url": "https://api.github.com/repos/clue/php-stream-filter/zipball/aeb7d8ea49c7963d3b581378955dbf5bc49aa320", + "reference": "aeb7d8ea49c7963d3b581378955dbf5bc49aa320", "shasum": "" }, "require": { "php": ">=5.3" }, "require-dev": { - "phpunit/phpunit": "^5.0 || ^4.8" + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" }, "type": "library", "autoload": { @@ -139,7 +142,7 @@ "authors": [ { "name": "Christian Lück", - "email": "christian@lueck.tv" + "email": "christian@clue.engineering" } ], "description": "A simple and modern approach to stream filtering in PHP", @@ -153,20 +156,30 @@ "stream_filter_append", "stream_filter_register" ], - "time": "2019-04-09T12:31:48+00:00" + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-10-02T12:38:20+00:00" }, { "name": "commerceguys/addressing", - "version": "v1.0.8", + "version": "v1.0.9", "source": { "type": "git", "url": "https://github.com/commerceguys/addressing.git", - "reference": "cf202c913c10d85085ab5ed9ec88607e312839ce" + "reference": "7f6b8780ae20862529a0ceaaf102a3f7ff740b91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/commerceguys/addressing/zipball/cf202c913c10d85085ab5ed9ec88607e312839ce", - "reference": "cf202c913c10d85085ab5ed9ec88607e312839ce", + "url": "https://api.github.com/repos/commerceguys/addressing/zipball/7f6b8780ae20862529a0ceaaf102a3f7ff740b91", + "reference": "7f6b8780ae20862529a0ceaaf102a3f7ff740b91", "shasum": "" }, "require": { @@ -212,7 +225,7 @@ "localization", "postal" ], - "time": "2020-05-26T11:04:04+00:00" + "time": "2020-09-12T12:15:49+00:00" }, { "name": "composer/installers", @@ -414,25 +427,25 @@ }, { "name": "consolidation/annotated-command", - "version": "2.12.0", + "version": "2.12.1", "source": { "type": "git", "url": "https://github.com/consolidation/annotated-command.git", - "reference": "512a2e54c98f3af377589de76c43b24652bcb789" + "reference": "0ee361762df2274f360c085e3239784a53f850b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/512a2e54c98f3af377589de76c43b24652bcb789", - "reference": "512a2e54c98f3af377589de76c43b24652bcb789", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/0ee361762df2274f360c085e3239784a53f850b5", + "reference": "0ee361762df2274f360c085e3239784a53f850b5", "shasum": "" }, "require": { - "consolidation/output-formatters": "^3.4", + "consolidation/output-formatters": "^3.5.1", "php": ">=5.4.5", "psr/log": "^1", "symfony/console": "^2.8|^3|^4", "symfony/event-dispatcher": "^2.5|^3|^4", - "symfony/finder": "^2.5|^3|^4" + "symfony/finder": "^2.5|^3|^4|^5" }, "require-dev": { "g1a/composer-test-scenarios": "^3", @@ -443,6 +456,16 @@ "type": "library", "extra": { "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, "symfony4": { "require": { "symfony/console": "^4.0" @@ -506,7 +529,7 @@ } ], "description": "Initialize Symfony Console commands from annotated command class methods.", - "time": "2019-03-08T16:55:03+00:00" + "time": "2020-10-11T04:30:03+00:00" }, { "name": "consolidation/config", @@ -748,23 +771,23 @@ }, { "name": "consolidation/output-formatters", - "version": "3.5.0", + "version": "3.5.1", "source": { "type": "git", "url": "https://github.com/consolidation/output-formatters.git", - "reference": "99ec998ffb697e0eada5aacf81feebfb13023605" + "reference": "0d38f13051ef05c223a2bb8e962d668e24785196" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/99ec998ffb697e0eada5aacf81feebfb13023605", - "reference": "99ec998ffb697e0eada5aacf81feebfb13023605", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/0d38f13051ef05c223a2bb8e962d668e24785196", + "reference": "0d38f13051ef05c223a2bb8e962d668e24785196", "shasum": "" }, "require": { "dflydev/dot-access-data": "^1.1.0", "php": ">=5.4.0", "symfony/console": "^2.8|^3|^4", - "symfony/finder": "^2.5|^3|^4" + "symfony/finder": "^2.5|^3|^4|^5" }, "require-dev": { "g1a/composer-test-scenarios": "^3", @@ -780,6 +803,16 @@ "type": "library", "extra": { "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, "symfony4": { "require": { "symfony/console": "^4.0" @@ -845,27 +878,27 @@ } ], "description": "Format text by applying transformations provided by plug-in formatters.", - "time": "2019-05-30T23:16:01+00:00" + "time": "2020-10-11T04:15:32+00:00" }, { "name": "consolidation/robo", - "version": "1.4.12", + "version": "1.4.13", "source": { "type": "git", "url": "https://github.com/consolidation/Robo.git", - "reference": "eb45606f498b3426b9a98b7c85e300666a968e51" + "reference": "fd28dcca1b935950ece26e63541fbdeeb09f7343" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/Robo/zipball/eb45606f498b3426b9a98b7c85e300666a968e51", - "reference": "eb45606f498b3426b9a98b7c85e300666a968e51", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/fd28dcca1b935950ece26e63541fbdeeb09f7343", + "reference": "fd28dcca1b935950ece26e63541fbdeeb09f7343", "shasum": "" }, "require": { - "consolidation/annotated-command": "^2.11.0|^4.1", + "consolidation/annotated-command": "^2.12.1|^4.1", "consolidation/config": "^1.2.1", "consolidation/log": "^1.1.1|^2", - "consolidation/output-formatters": "^3.1.13|^4.1", + "consolidation/output-formatters": "^3.5.1|^4.1", "consolidation/self-update": "^1.1.5", "grasmash/yaml-expander": "^1.4", "league/container": "^2.4.1", @@ -873,7 +906,7 @@ "symfony/console": "^2.8|^3|^4", "symfony/event-dispatcher": "^2.5|^3|^4", "symfony/filesystem": "^2.5|^3|^4", - "symfony/finder": "^2.5|^3|^4", + "symfony/finder": "^2.5|^3|^4|^5", "symfony/process": "^2.5|^3|^4" }, "replace": { @@ -900,6 +933,16 @@ "type": "library", "extra": { "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, "symfony4": { "require": { "symfony/console": "^4" @@ -950,7 +993,7 @@ } ], "description": "Modern task runner", - "time": "2020-02-18T17:31:26+00:00" + "time": "2020-10-11T04:51:34+00:00" }, { "name": "consolidation/self-update", @@ -1179,24 +1222,24 @@ }, { "name": "cweagans/composer-patches", - "version": "1.6.7", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/cweagans/composer-patches.git", - "reference": "2e6f72a2ad8d59cd7e2b729f218bf42adb14f590" + "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/2e6f72a2ad8d59cd7e2b729f218bf42adb14f590", - "reference": "2e6f72a2ad8d59cd7e2b729f218bf42adb14f590", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/ae02121445ad75f4eaff800cc532b5e6233e2ddf", + "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0", + "composer-plugin-api": "^1.0 || ^2.0", "php": ">=5.3.0" }, "require-dev": { - "composer/composer": "~1.0", + "composer/composer": "~1.0 || ~2.0", "phpunit/phpunit": "~4.6" }, "type": "composer-plugin", @@ -1219,7 +1262,7 @@ } ], "description": "Provides a way to patch Composer packages.", - "time": "2019-08-29T20:11:49+00:00" + "time": "2020-09-30T17:56:20+00:00" }, { "name": "davedevelopment/stiphle", @@ -2078,16 +2121,16 @@ }, { "name": "drupal/core", - "version": "8.9.2", + "version": "8.9.7", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "8f0e24555c093669ce41edbb30637fe19df16802" + "reference": "ded1be08c23f19211f9a2514a72e7defb1204efc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/8f0e24555c093669ce41edbb30637fe19df16802", - "reference": "8f0e24555c093669ce41edbb30637fe19df16802", + "url": "https://api.github.com/repos/drupal/core/zipball/ded1be08c23f19211f9a2514a72e7defb1204efc", + "reference": "ded1be08c23f19211f9a2514a72e7defb1204efc", "shasum": "" }, "require": { @@ -2305,20 +2348,20 @@ "GPL-2.0-or-later" ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", - "time": "2020-07-08T18:53:45+00:00" + "time": "2020-10-07T19:37:20+00:00" }, { "name": "drupal/core-composer-scaffold", - "version": "8.9.2", + "version": "8.9.7", "source": { "type": "git", "url": "https://github.com/drupal/core-composer-scaffold.git", - "reference": "07cdfe2799789fc0c2d0e3e1ba64cb5e2a973ece" + "reference": "c902d07cb49ef73777e2b33a39e54c2861a8c81d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/07cdfe2799789fc0c2d0e3e1ba64cb5e2a973ece", - "reference": "07cdfe2799789fc0c2d0e3e1ba64cb5e2a973ece", + "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/c902d07cb49ef73777e2b33a39e54c2861a8c81d", + "reference": "c902d07cb49ef73777e2b33a39e54c2861a8c81d", "shasum": "" }, "require": { @@ -2352,20 +2395,20 @@ "keywords": [ "drupal" ], - "time": "2020-05-29T11:36:27+00:00" + "time": "2020-08-07T22:30:30+00:00" }, { "name": "drupal/core-recommended", - "version": "8.9.2", + "version": "8.9.7", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "8301ff766f17ce8a9eb36d3ffd183cbfff01dad6" + "reference": "7895ddd703101bdec91fb6ae58381036a9768e1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/8301ff766f17ce8a9eb36d3ffd183cbfff01dad6", - "reference": "8301ff766f17ce8a9eb36d3ffd183cbfff01dad6", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/7895ddd703101bdec91fb6ae58381036a9768e1f", + "reference": "7895ddd703101bdec91fb6ae58381036a9768e1f", "shasum": "" }, "require": { @@ -2377,7 +2420,7 @@ "doctrine/common": "v2.7.3", "doctrine/inflector": "v1.2.0", "doctrine/lexer": "1.0.2", - "drupal/core": "8.9.2", + "drupal/core": "8.9.7", "easyrdf/easyrdf": "0.9.1", "egulias/email-validator": "2.1.17", "guzzlehttp/guzzle": "6.5.4", @@ -2406,7 +2449,7 @@ "symfony/dependency-injection": "v3.4.41", "symfony/event-dispatcher": "v3.4.41", "symfony/http-foundation": "v3.4.41", - "symfony/http-kernel": "v3.4.41", + "symfony/http-kernel": "v3.4.44", "symfony/polyfill-ctype": "v1.17.0", "symfony/polyfill-iconv": "v1.17.0", "symfony/polyfill-intl-idn": "v1.17.0", @@ -2434,7 +2477,7 @@ "GPL-2.0-or-later" ], "description": "Locked core dependencies; require this project INSTEAD OF drupal/core.", - "time": "2020-07-08T18:53:45+00:00" + "time": "2020-10-07T19:37:20+00:00" }, { "name": "drupal/ctools", @@ -2881,17 +2924,17 @@ }, { "name": "drupal/geocoder", - "version": "3.9.0", + "version": "3.12.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/geocoder.git", - "reference": "8.x-3.9" + "reference": "8.x-3.12" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/geocoder-8.x-3.9.zip", - "reference": "8.x-3.9", - "shasum": "f1ab729b01fa2a3cb140bee7a20353581963ab7c" + "url": "https://ftp.drupal.org/files/projects/geocoder-8.x-3.12.zip", + "reference": "8.x-3.12", + "shasum": "41b01ec71c44103f11447f952b3bcedc8c59c925" }, "require": { "davedevelopment/stiphle": "^0.9.2", @@ -2913,6 +2956,7 @@ "geocoder-php/geoips-provider": "^4.1", "geocoder-php/geonames-provider": "^4.1", "geocoder-php/google-maps-provider": "^4.2", + "geocoder-php/graphhopper-provider": "^0.1.0", "geocoder-php/host-ip-provider": "^4.0", "geocoder-php/ip-info-db-provider": "^4.0", "geocoder-php/mapbox-provider": "^0.1", @@ -2933,8 +2977,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-3.9", - "datestamp": "1595974934", + "version": "8.x-3.12", + "datestamp": "1601316542", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3003,17 +3047,17 @@ }, { "name": "drupal/geofield", - "version": "1.15.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/geofield.git", - "reference": "8.x-1.15" + "reference": "8.x-1.16" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/geofield-8.x-1.15.zip", - "reference": "8.x-1.15", - "shasum": "b2726d7d6cd46a8b4615c828f7944bcba1193875" + "url": "https://ftp.drupal.org/files/projects/geofield-8.x-1.16.zip", + "reference": "8.x-1.16", + "shasum": "b759dbf3e0c7225bce8bcead6954115e255dc349" }, "require": { "drupal/core": "^8.8 || ^9", @@ -3022,8 +3066,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.15", - "datestamp": "1591556172", + "version": "8.x-1.16", + "datestamp": "1601938843", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3032,7 +3076,7 @@ }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -3081,17 +3125,17 @@ }, { "name": "drupal/geofield_map", - "version": "2.66.0", + "version": "2.67.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/geofield_map.git", - "reference": "8.x-2.66" + "reference": "8.x-2.67" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/geofield_map-8.x-2.66.zip", - "reference": "8.x-2.66", - "shasum": "6de69eb448fe636264fe74410239a477e76dc173" + "url": "https://ftp.drupal.org/files/projects/geofield_map-8.x-2.67.zip", + "reference": "8.x-2.67", + "shasum": "6b98bbcaf1de0c38da8683b39aa9c43ccf226d82" }, "require": { "drupal/core": "^8.8 || ^9", @@ -3100,8 +3144,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-2.66", - "datestamp": "1593119796", + "version": "8.x-2.67", + "datestamp": "1597844476", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3110,7 +3154,7 @@ }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -3194,17 +3238,17 @@ }, { "name": "drupal/google_analytics_reports", - "version": "3.0.0-rc2", + "version": "3.0.0-rc3", "source": { "type": "git", "url": "https://git.drupalcode.org/project/google_analytics_reports.git", - "reference": "8.x-3.0-rc2" + "reference": "8.x-3.0-rc3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/google_analytics_reports-8.x-3.0-rc2.zip", - "reference": "8.x-3.0-rc2", - "shasum": "fbe050883db8f1264973e420e42e555f6539f436" + "url": "https://ftp.drupal.org/files/projects/google_analytics_reports-8.x-3.0-rc3.zip", + "reference": "8.x-3.0-rc3", + "shasum": "051c1e8aa031a0d16f0087943a9b73456de7b15e" }, "require": { "drupal/core": "^8 || ^9", @@ -3213,8 +3257,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-3.0-rc2", - "datestamp": "1591782424", + "version": "8.x-3.0-rc3", + "datestamp": "1594893535", "security-coverage": { "status": "not-covered", "message": "RC releases are not covered by Drupal security advisories." @@ -3267,7 +3311,7 @@ }, { "name": "drupal/google_analytics_reports_api", - "version": "3.0.0-rc2", + "version": "3.0.0-rc3", "require": { "drupal/core": "^8 || ^9", "drupal/google_analytics_reports": "self.version" @@ -3275,8 +3319,8 @@ "type": "metapackage", "extra": { "drupal": { - "version": "8.x-3.0-rc2", - "datestamp": "1591782424", + "version": "8.x-3.0-rc3", + "datestamp": "1594893535", "security-coverage": { "status": "not-covered", "message": "RC releases are not covered by Drupal security advisories." @@ -3635,17 +3679,17 @@ }, { "name": "drupal/masonry", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/masonry.git", - "reference": "8.x-1.1" + "reference": "8.x-1.2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/masonry-8.x-1.1.zip", - "reference": "8.x-1.1", - "shasum": "c45e4b21e08b5fa3998bb1852282131ec8761c74" + "url": "https://ftp.drupal.org/files/projects/masonry-8.x-1.2.zip", + "reference": "8.x-1.2", + "shasum": "28b780a93c1692f4b746093c9e52b734cf179ff8" }, "require": { "drupal/core": "^8 || ^9" @@ -3653,8 +3697,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.1", - "datestamp": "1594537870", + "version": "8.x-1.2", + "datestamp": "1602247057", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3685,17 +3729,17 @@ }, { "name": "drupal/mediteran", - "version": "1.11.0", + "version": "1.13.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/mediteran.git", - "reference": "8.x-1.11" + "reference": "8.x-1.13" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/mediteran-8.x-1.11.zip", - "reference": "8.x-1.11", - "shasum": "93a72f234b862f73ec0fa43dc3a9d5fd5857f163" + "url": "https://ftp.drupal.org/files/projects/mediteran-8.x-1.13.zip", + "reference": "8.x-1.13", + "shasum": "1566effdd7ce7cef122b771506f8a644d4a1ccd6" }, "require": { "drupal/core": "^8 || ^9" @@ -3703,8 +3747,8 @@ "type": "drupal-theme", "extra": { "drupal": { - "version": "8.x-1.11", - "datestamp": "1594537822", + "version": "8.x-1.13", + "datestamp": "1601900608", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3737,33 +3781,34 @@ }, { "name": "drupal/metatag", - "version": "1.13.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/metatag.git", - "reference": "8.x-1.13" + "reference": "8.x-1.14" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/metatag-8.x-1.13.zip", - "reference": "8.x-1.13", - "shasum": "c471d9982a6540fd7baccc94572947923634fb6b" + "url": "https://ftp.drupal.org/files/projects/metatag-8.x-1.14.zip", + "reference": "8.x-1.14", + "shasum": "9bf9f1517ad015d0c93ca1460e284c557624aa90" }, "require": { - "drupal/core": "^8 || ^9", + "drupal/core": "^8.7.7 || ^9", "drupal/token": "^1.0" }, "require-dev": { "drupal/metatag_dc": "*", "drupal/metatag_open_graph": "*", - "drupal/page_manager": "4.x-dev", + "drupal/page_manager": "*", + "drupal/panelizer": "4.x-dev", "drupal/redirect": "1.x-dev" }, "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.13", - "datestamp": "1587478404", + "version": "8.x-1.14", + "datestamp": "1597183852", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3772,7 +3817,7 @@ }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -4271,17 +4316,17 @@ }, { "name": "drupal/schema_metatag", - "version": "1.7.0", + "version": "1.8.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/schema_metatag.git", - "reference": "8.x-1.7" + "reference": "8.x-1.8" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/schema_metatag-8.x-1.7.zip", - "reference": "8.x-1.7", - "shasum": "880ce69c9c1510e90747ebfab64070dbf704f653" + "url": "https://ftp.drupal.org/files/projects/schema_metatag-8.x-1.8.zip", + "reference": "8.x-1.8", + "shasum": "dac50842bcac35607b0be8e28518e08fa3f6b66f" }, "require": { "drupal/core": "^8 || ^9", @@ -4295,8 +4340,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.7", - "datestamp": "1595441023", + "version": "8.x-1.8", + "datestamp": "1599905688", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4425,26 +4470,26 @@ }, { "name": "drupal/tacjs", - "version": "3.9.0", + "version": "3.10.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/tacjs.git", - "reference": "8.x-3.9" + "reference": "8.x-3.10" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/tacjs-8.x-3.9.zip", - "reference": "8.x-3.9", - "shasum": "fea6efc4eaa8f36c3081daeb89ae8edcec6ebe3f" + "url": "https://ftp.drupal.org/files/projects/tacjs-8.x-3.10.zip", + "reference": "8.x-3.10", + "shasum": "7b26dea8c20dc7925cc38c1fe3bcd75de65df6ec" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8 || ^9" }, "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-3.9", - "datestamp": "1584092255", + "version": "8.x-3.10", + "datestamp": "1597403474", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4737,17 +4782,17 @@ }, { "name": "drupal/varbase_total_control", - "version": "6.11.0", + "version": "6.12.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/varbase_total_control.git", - "reference": "8.x-6.11" + "reference": "8.x-6.12" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/varbase_total_control-8.x-6.11.zip", - "reference": "8.x-6.11", - "shasum": "ce01ed87c8733433f3b129ae040d03e14bcdd3db" + "url": "https://ftp.drupal.org/files/projects/varbase_total_control-8.x-6.12.zip", + "reference": "8.x-6.12", + "shasum": "20acd0cf46e71d11f47ef641ec58ef3ed579e2f8" }, "require": { "composer/installers": "~1.0", @@ -4770,8 +4815,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-6.11", - "datestamp": "1591080576", + "version": "8.x-6.12", + "datestamp": "1602078570", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4943,20 +4988,20 @@ }, { "name": "drush/drush", - "version": "10.3.1", + "version": "10.3.5", "source": { "type": "git", "url": "https://github.com/drush-ops/drush.git", - "reference": "aad2b17ad34801d9b55cff903e3e7db65d754b80" + "reference": "ce1352c816d8852e64226142eeddc68f823646f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drush-ops/drush/zipball/aad2b17ad34801d9b55cff903e3e7db65d754b80", - "reference": "aad2b17ad34801d9b55cff903e3e7db65d754b80", + "url": "https://api.github.com/repos/drush-ops/drush/zipball/ce1352c816d8852e64226142eeddc68f823646f1", + "reference": "ce1352c816d8852e64226142eeddc68f823646f1", "shasum": "" }, "require": { - "chi-teck/drupal-code-generator": "^1.30.5", + "chi-teck/drupal-code-generator": "^1.32.1", "composer/semver": "^1.4", "consolidation/config": "^1.2", "consolidation/filter-via-dot-access-data": "^1", @@ -4965,6 +5010,7 @@ "consolidation/site-process": "^2.1 || ^4", "ext-dom": "*", "grasmash/yaml-expander": "^1.1.1", + "guzzlehttp/guzzle": "^6.3 || ^7.0", "league/container": "~2", "php": ">=7.1.3", "psr/log": "~1.0", @@ -5018,9 +5064,6 @@ "sut/drush/contrib/{$name}": [ "type:drupal-drush" ] - }, - "branch-alias": { - "dev-master": "10.x-dev" } }, "autoload": { @@ -5075,7 +5118,7 @@ "type": "github" } ], - "time": "2020-06-30T19:43:45+00:00" + "time": "2020-10-05T11:50:13+00:00" }, { "name": "easyrdf/easyrdf", @@ -5199,16 +5242,16 @@ }, { "name": "gasparesganga/php-shapefile", - "version": "v3.3.0", + "version": "v3.3.3", "source": { "type": "git", "url": "https://github.com/gasparesganga/php-shapefile.git", - "reference": "af9b7221ddaf36a85a37e6a23281bd53ed750c4d" + "reference": "839475272ef8c7585f5afa31939c95d6d02371a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/gasparesganga/php-shapefile/zipball/af9b7221ddaf36a85a37e6a23281bd53ed750c4d", - "reference": "af9b7221ddaf36a85a37e6a23281bd53ed750c4d", + "url": "https://api.github.com/repos/gasparesganga/php-shapefile/zipball/839475272ef8c7585f5afa31939c95d6d02371a6", + "reference": "839475272ef8c7585f5afa31939c95d6d02371a6", "shasum": "" }, "require": { @@ -5243,7 +5286,7 @@ "shp", "wkt" ], - "time": "2020-05-23T09:10:21+00:00" + "time": "2020-09-17T08:22:36+00:00" }, { "name": "geocoder-php/chain-provider", @@ -6223,16 +6266,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.6.0", + "version": "v4.10.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "c346bbfafe2ff60680258b631afb730d186ed864" + "reference": "658f1be311a230e0907f5dfe0213742aff0596de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c346bbfafe2ff60680258b631afb730d186ed864", - "reference": "c346bbfafe2ff60680258b631afb730d186ed864", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de", "shasum": "" }, "require": { @@ -6240,8 +6283,8 @@ "php": ">=7.0" }, "require-dev": { - "ircmaxell/php-yacc": "0.0.5", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -6249,7 +6292,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.9-dev" } }, "autoload": { @@ -6271,7 +6314,7 @@ "parser", "php" ], - "time": "2020-07-02T17:12:47+00:00" + "time": "2020-09-26T10:30:38+00:00" }, { "name": "oomphinc/composer-installers-extender", @@ -6610,16 +6653,16 @@ }, { "name": "php-http/discovery", - "version": "1.9.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/php-http/discovery.git", - "reference": "64a18cc891957e05d91910b3c717d6bd11fbede9" + "reference": "4366bf1bc39b663aa87459bd725501d2f1988b6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/64a18cc891957e05d91910b3c717d6bd11fbede9", - "reference": "64a18cc891957e05d91910b3c717d6bd11fbede9", + "url": "https://api.github.com/repos/php-http/discovery/zipball/4366bf1bc39b663aa87459bd725501d2f1988b6c", + "reference": "4366bf1bc39b663aa87459bd725501d2f1988b6c", "shasum": "" }, "require": { @@ -6671,7 +6714,7 @@ "message", "psr7" ], - "time": "2020-07-13T15:44:45+00:00" + "time": "2020-09-22T13:31:04+00:00" }, { "name": "php-http/guzzle6-adapter", @@ -6796,20 +6839,20 @@ }, { "name": "php-http/message", - "version": "1.8.0", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/php-http/message.git", - "reference": "ce8f43ac1e294b54aabf5808515c3554a19c1e1c" + "reference": "09f3f13af3a1a4273ecbf8e6b27248c002a3db29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/message/zipball/ce8f43ac1e294b54aabf5808515c3554a19c1e1c", - "reference": "ce8f43ac1e294b54aabf5808515c3554a19c1e1c", + "url": "https://api.github.com/repos/php-http/message/zipball/09f3f13af3a1a4273ecbf8e6b27248c002a3db29", + "reference": "09f3f13af3a1a4273ecbf8e6b27248c002a3db29", "shasum": "" }, "require": { - "clue/stream-filter": "^1.4", + "clue/stream-filter": "^1.4.1", "php": "^7.1", "php-http/message-factory": "^1.0.2", "psr/http-message": "^1.0" @@ -6820,6 +6863,7 @@ "require-dev": { "akeneo/phpspec-skip-example-extension": "^1.0", "coduo/phpspec-data-provider-extension": "^1.0", + "ergebnis/composer-normalize": "^2.1", "ext-zlib": "*", "guzzlehttp/psr7": "^1.0", "henrikbjorn/phpspec-code-coverage": "^1.0", @@ -6864,7 +6908,7 @@ "message", "psr-7" ], - "time": "2019-08-05T06:55:08+00:00" + "time": "2020-10-13T06:21:08+00:00" }, { "name": "php-http/message-factory", @@ -7863,16 +7907,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.4.10", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b27f491309db5757816db672b256ea2e03677d30" + "reference": "ebc51494739d3b081ea543ed7c462fa73a4f74db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b27f491309db5757816db672b256ea2e03677d30", - "reference": "b27f491309db5757816db672b256ea2e03677d30", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ebc51494739d3b081ea543ed7c462fa73a4f74db", + "reference": "ebc51494739d3b081ea543ed7c462fa73a4f74db", "shasum": "" }, "require": { @@ -7923,24 +7967,24 @@ "type": "tidelift" } ], - "time": "2020-05-30T18:50:54+00:00" + "time": "2020-09-27T13:54:16+00:00" }, { "name": "symfony/finder", - "version": "v4.4.10", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "5729f943f9854c5781984ed4907bbb817735776b" + "reference": "60d08560f9aa72997c44077c40d47aa28a963230" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/5729f943f9854c5781984ed4907bbb817735776b", - "reference": "5729f943f9854c5781984ed4907bbb817735776b", + "url": "https://api.github.com/repos/symfony/finder/zipball/60d08560f9aa72997c44077c40d47aa28a963230", + "reference": "60d08560f9aa72997c44077c40d47aa28a963230", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.1.3" }, "type": "library", "extra": { @@ -7986,7 +8030,7 @@ "type": "tidelift" } ], - "time": "2020-03-27T16:54:36+00:00" + "time": "2020-10-02T07:34:48+00:00" }, { "name": "symfony/http-foundation", @@ -8058,16 +8102,16 @@ }, { "name": "symfony/http-kernel", - "version": "v3.4.41", + "version": "v3.4.44", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "e4e4ed6c008c983645b4eee6b67d8f258cde54df" + "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e4e4ed6c008c983645b4eee6b67d8f258cde54df", - "reference": "e4e4ed6c008c983645b4eee6b67d8f258cde54df", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/27dcaa8c6b18c75df9f37badeb4d3564ffaa1326", + "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326", "shasum": "" }, "require": { @@ -8158,7 +8202,7 @@ "type": "tidelift" } ], - "time": "2020-05-31T05:14:17+00:00" + "time": "2020-08-31T05:53:42+00:00" }, { "name": "symfony/polyfill-ctype", @@ -8668,16 +8712,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.17.1", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4a5b6bba3259902e386eb80dd1956181ee90b5b2" + "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4a5b6bba3259902e386eb80dd1956181ee90b5b2", - "reference": "4a5b6bba3259902e386eb80dd1956181ee90b5b2", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/d87d5766cbf48d72388a9f6b85f280c8ad51f981", + "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981", "shasum": "" }, "require": { @@ -8686,7 +8730,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.17-dev" + "dev-master": "1.18-dev" }, "thanks": { "name": "symfony/polyfill", @@ -8744,7 +8788,7 @@ "type": "tidelift" } ], - "time": "2020-06-06T08:46:27+00:00" + "time": "2020-07-14T12:35:20+00:00" }, { "name": "symfony/polyfill-util", @@ -9307,16 +9351,16 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.10", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "56b3aa5eab0ac6720dcd559fd1d590ce301594ac" + "reference": "0dc22bdf9d1197467bb04d505355180b6f20bcca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/56b3aa5eab0ac6720dcd559fd1d590ce301594ac", - "reference": "56b3aa5eab0ac6720dcd559fd1d590ce301594ac", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0dc22bdf9d1197467bb04d505355180b6f20bcca", + "reference": "0dc22bdf9d1197467bb04d505355180b6f20bcca", "shasum": "" }, "require": { @@ -9394,7 +9438,7 @@ "type": "tidelift" } ], - "time": "2020-05-30T20:06:45+00:00" + "time": "2020-09-18T08:35:10+00:00" }, { "name": "symfony/yaml", diff --git a/web/core/assets/scaffold/files/default.settings.php b/web/core/assets/scaffold/files/default.settings.php index 62f73e1b..c5e2b4ab 100644 --- a/web/core/assets/scaffold/files/default.settings.php +++ b/web/core/assets/scaffold/files/default.settings.php @@ -781,10 +781,13 @@ $settings['migrate_node_migrate_type_classic'] = FALSE; /** * Load local development override configuration, if available. * - * Use settings.local.php to override variables on secondary (staging, - * development, etc) installations of this site. Typically used to disable - * caching, JavaScript/CSS compression, re-routing of outgoing emails, and - * other things that should not happen on development and testing sites. + * Create a settings.local.php file to override variables on secondary (staging, + * development, etc.) installations of this site. + * + * Typical uses of settings.local.php include: + * - Disabling caching. + * - Disabling JavaScript/CSS compression. + * - Rerouting outgoing emails. * * Keep this code block at the end of this file to take full effect. */ diff --git a/web/core/core.libraries.yml b/web/core/core.libraries.yml index b0367417..a17ce7c0 100644 --- a/web/core/core.libraries.yml +++ b/web/core/core.libraries.yml @@ -25,10 +25,10 @@ classList: ckeditor: remote: https://github.com/ckeditor/ckeditor-dev - version: "4.14.0" + version: "4.14.1" license: name: GNU-GPL-2.0-or-later - url: https://github.com/ckeditor/ckeditor4/blob/4.14.0/LICENSE.md + url: https://github.com/ckeditor/ckeditor4/blob/4.14.1/LICENSE.md gpl-compatible: true js: assets/vendor/ckeditor/ckeditor.js: { preprocess: false, minified: true } diff --git a/web/core/drupalci.yml b/web/core/drupalci.yml index 8cc5f1d4..1cec41ce 100644 --- a/web/core/drupalci.yml +++ b/web/core/drupalci.yml @@ -5,8 +5,6 @@ build: assessment: validate_codebase: phplint: - csslint: - halt-on-fail: false eslint: # A test must pass eslinting standards check in order to continue processing. halt-on-fail: false diff --git a/web/core/includes/entity.inc b/web/core/includes/entity.inc index 34c048b3..3515b6dd 100644 --- a/web/core/includes/entity.inc +++ b/web/core/includes/entity.inc @@ -233,7 +233,8 @@ function entity_load_unchanged($entity_type, $id) { * An array of entity IDs of the entities to delete. * * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use - * the entity storage's delete() method to delete multiple entities: + * the entity storage's \Drupal\Core\Entity\EntityStorageInterface::delete() + * method to delete multiple entities: * @code * $storage_handler = \Drupal::entityTypeManager()->getStorage($entity_type); * $entities = $storage_handler->loadMultiple($ids); diff --git a/web/core/includes/pager.inc b/web/core/includes/pager.inc index cb06d804..0864b782 100644 --- a/web/core/includes/pager.inc +++ b/web/core/includes/pager.inc @@ -26,13 +26,13 @@ use Drupal\Component\Utility\Html; * displays the third page of search results at that URL. * * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use - * \Drupal\Core\Pager\RequestPagerInterface->findPage() instead. + * \Drupal\Core\Pager\PagerParametersInterface->findPage() instead. * * @see https://www.drupal.org/node/2779457 * @see \Drupal\Core\Pager\PagerParametersInterface::findPage() */ function pager_find_page($element = 0) { - @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\RequestPagerInterface->findPage() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED); + @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\PagerParametersInterface->findPage() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED); /* @var $pager_parameters \Drupal\Core\Pager\PagerParametersInterface */ $pager_parameters = \Drupal::service('pager.parameters'); return $pager_parameters->findPage($element); @@ -150,13 +150,13 @@ function pager_default_initialize($total, $limit, $element = 0) { * page request except for those pertaining to paging. * * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use - * \Drupal\Core\Pager\RequestPagerInterface->getQueryParameters() instead. + * \Drupal\Core\Pager\PagerParametersInterface->getQueryParameters() instead. * * @see https://www.drupal.org/node/2779457 * @see \Drupal\Core\Pager\PagerParametersInterface::getQueryParameters() */ function pager_get_query_parameters() { - @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\RequestPagerInterface->getQueryParameters() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED); + @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\PagerParametersInterface->getQueryParameters() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED); /* @var $pager_params \Drupal\Core\Pager\PagerParametersInterface */ $pager_params = \Drupal::service('pager.parameters'); return $pager_params->getQueryParameters(); diff --git a/web/core/lib/Drupal.php b/web/core/lib/Drupal.php index b51f2401..0e9d50fc 100644 --- a/web/core/lib/Drupal.php +++ b/web/core/lib/Drupal.php @@ -82,7 +82,7 @@ class Drupal { /** * The current system version. */ - const VERSION = '8.9.2'; + const VERSION = '8.9.7'; /** * Core API compatibility. @@ -606,8 +606,8 @@ class Drupal { * This method is a convenience wrapper for the link generator service's * generate() method. * - * @param string $text - * The link text for the anchor tag. + * @param string|array|\Drupal\Component\Render\MarkupInterface $text + * The link text for the anchor tag as a translated string or render array. * @param \Drupal\Core\Url $url * The URL object used for the link. * diff --git a/web/core/lib/Drupal/Component/Datetime/DateTimePlus.php b/web/core/lib/Drupal/Component/Datetime/DateTimePlus.php index ef200d19..01c46470 100644 --- a/web/core/lib/Drupal/Component/Datetime/DateTimePlus.php +++ b/web/core/lib/Drupal/Component/Datetime/DateTimePlus.php @@ -624,11 +624,10 @@ class DateTimePlus { $valid_date = FALSE; $valid_time = TRUE; // Check for a valid date using checkdate(). Only values that - // meet that test are valid. - if (array_key_exists('year', $array) && array_key_exists('month', $array) && array_key_exists('day', $array)) { - if (@checkdate($array['month'], $array['day'], $array['year'])) { - $valid_date = TRUE; - } + // meet that test are valid. An empty value, either a string or a 0, is not + // a valid value. + if (!empty($array['year']) && !empty($array['month']) && !empty($array['day'])) { + $valid_date = checkdate($array['month'], $array['day'], $array['year']); } // Testing for valid time is reversed. Missing time is OK, // but incorrect values are not. diff --git a/web/core/lib/Drupal/Component/Transliteration/PhpTransliteration.php b/web/core/lib/Drupal/Component/Transliteration/PhpTransliteration.php index 2f639740..8d62175e 100644 --- a/web/core/lib/Drupal/Component/Transliteration/PhpTransliteration.php +++ b/web/core/lib/Drupal/Component/Transliteration/PhpTransliteration.php @@ -58,6 +58,21 @@ class PhpTransliteration implements TransliterationInterface { */ protected $genericMap = []; + /** + * Special characters for ::removeDiacritics(). + * + * Characters which have accented variants but their base character + * transliterates to more than one ASCII character require special + * treatment: we want to remove their accent and use the un- + * transliterated base character. + */ + protected $fixTransliterateForRemoveDiacritics = [ + 'AE' => 'Æ', + 'ae' => 'æ', + 'ZH' => 'Ʒ', + 'zh' => 'ʒ', + ]; + /** * Constructs a transliteration object. * @@ -93,6 +108,9 @@ class PhpTransliteration implements TransliterationInterface { if (strlen($to_add) === 1) { $replacement = $to_add; } + elseif (isset($this->fixTransliterateForRemoveDiacritics[$to_add])) { + $replacement = $this->fixTransliterateForRemoveDiacritics[$to_add]; + } } $result .= $replacement; diff --git a/web/core/lib/Drupal/Component/Utility/Bytes.php b/web/core/lib/Drupal/Component/Utility/Bytes.php index d625b123..477e6e48 100644 --- a/web/core/lib/Drupal/Component/Utility/Bytes.php +++ b/web/core/lib/Drupal/Component/Utility/Bytes.php @@ -35,7 +35,8 @@ class Bytes { return round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0]))); } else { - return round($size); + // Ensure size is a proper number type. + return round((float) $size); } } diff --git a/web/core/lib/Drupal/Component/Utility/Image.php b/web/core/lib/Drupal/Component/Utility/Image.php index fcfedb1a..f1368c1b 100644 --- a/web/core/lib/Drupal/Component/Utility/Image.php +++ b/web/core/lib/Drupal/Component/Utility/Image.php @@ -30,8 +30,6 @@ class Image { * * @return bool * TRUE if $dimensions was modified, FALSE otherwise. - * - * @see image_scale() */ public static function scaleDimensions(array &$dimensions, $width = NULL, $height = NULL, $upscale = FALSE) { $aspect = $dimensions['height'] / $dimensions['width']; diff --git a/web/core/lib/Drupal/Component/Utility/Unicode.php b/web/core/lib/Drupal/Component/Utility/Unicode.php index 64e066d7..a44b50d0 100644 --- a/web/core/lib/Drupal/Component/Utility/Unicode.php +++ b/web/core/lib/Drupal/Component/Utility/Unicode.php @@ -537,16 +537,16 @@ EOD; */ public static function mimeHeaderDecode($header) { $callback = function ($matches) { - $data = ($matches[2] == 'B') ? base64_decode($matches[3]) : str_replace('_', ' ', quoted_printable_decode($matches[3])); + $data = (strtolower($matches[2]) == 'b') ? base64_decode($matches[3]) : str_replace('_', ' ', quoted_printable_decode($matches[3])); if (strtolower($matches[1]) != 'utf-8') { $data = static::convertToUtf8($data, $matches[1]); } return $data; }; // First step: encoded chunks followed by other encoded chunks (need to collapse whitespace) - $header = preg_replace_callback('/=\?([^?]+)\?(Q|B)\?([^?]+|\?(?!=))\?=\s+(?==\?)/', $callback, $header); + $header = preg_replace_callback('/=\?([^?]+)\?([Qq]|[Bb])\?([^?]+|\?(?!=))\?=\s+(?==\?)/', $callback, $header); // Second step: remaining chunks (do not collapse whitespace) - return preg_replace_callback('/=\?([^?]+)\?(Q|B)\?([^?]+|\?(?!=))\?=/', $callback, $header); + return preg_replace_callback('/=\?([^?]+)\?([Qq]|[Bb])\?([^?]+|\?(?!=))\?=/', $callback, $header); } /** diff --git a/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php index 99328413..d2cf20a2 100644 --- a/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php +++ b/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php @@ -345,7 +345,7 @@ class LibraryDiscoveryParser { $library_file = $path . '/' . $extension . '.libraries.yml'; if (file_exists($this->root . '/' . $library_file)) { try { - $libraries = Yaml::decode(file_get_contents($this->root . '/' . $library_file)); + $libraries = Yaml::decode(file_get_contents($this->root . '/' . $library_file)) ?? []; } catch (InvalidDataTypeException $e) { // Rethrow a more helpful exception to provide context. diff --git a/web/core/lib/Drupal/Core/Block/BlockBase.php b/web/core/lib/Drupal/Core/Block/BlockBase.php index f5324bfb..7076da42 100644 --- a/web/core/lib/Drupal/Core/Block/BlockBase.php +++ b/web/core/lib/Drupal/Core/Block/BlockBase.php @@ -2,18 +2,10 @@ namespace Drupal\Core\Block; -use Drupal\Core\Access\AccessResult; -use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Messenger\MessengerTrait; use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait; use Drupal\Core\Plugin\ContextAwarePluginBase; -use Drupal\Component\Utility\NestedArray; -use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Plugin\PluginWithFormsInterface; -use Drupal\Core\Plugin\PluginWithFormsTrait; use Drupal\Core\Render\PreviewFallbackInterface; -use Drupal\Core\Session\AccountInterface; -use Drupal\Component\Transliteration\TransliterationInterface; /** * Defines a base block implementation that most blocks plugins will extend. @@ -26,260 +18,7 @@ use Drupal\Component\Transliteration\TransliterationInterface; */ abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginInterface, PluginWithFormsInterface, PreviewFallbackInterface { + use BlockPluginTrait; use ContextAwarePluginAssignmentTrait; - use MessengerTrait; - use PluginWithFormsTrait; - - /** - * The transliteration service. - * - * @var \Drupal\Component\Transliteration\TransliterationInterface - */ - protected $transliteration; - - /** - * {@inheritdoc} - */ - public function label() { - if (!empty($this->configuration['label'])) { - return $this->configuration['label']; - } - - $definition = $this->getPluginDefinition(); - // Cast the admin label to a string since it is an object. - // @see \Drupal\Core\StringTranslation\TranslatableMarkup - return (string) $definition['admin_label']; - } - - /** - * {@inheritdoc} - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = NestedArray::mergeDeep( - $this->baseConfigurationDefaults(), - $this->defaultConfiguration(), - $configuration - ); - } - - /** - * Returns generic default configuration for block plugins. - * - * @return array - * An associative array with the default configuration. - */ - protected function baseConfigurationDefaults() { - return [ - 'id' => $this->getPluginId(), - 'label' => '', - 'provider' => $this->pluginDefinition['provider'], - 'label_display' => static::BLOCK_LABEL_VISIBLE, - ]; - } - - /** - * {@inheritdoc} - */ - public function defaultConfiguration() { - return []; - } - - /** - * {@inheritdoc} - */ - public function setConfigurationValue($key, $value) { - $this->configuration[$key] = $value; - } - - /** - * {@inheritdoc} - */ - public function calculateDependencies() { - return []; - } - - /** - * {@inheritdoc} - */ - public function access(AccountInterface $account, $return_as_object = FALSE) { - $access = $this->blockAccess($account); - return $return_as_object ? $access : $access->isAllowed(); - } - - /** - * Indicates whether the block should be shown. - * - * Blocks with specific access checking should override this method rather - * than access(), in order to avoid repeating the handling of the - * $return_as_object argument. - * - * @param \Drupal\Core\Session\AccountInterface $account - * The user session for which to check access. - * - * @return \Drupal\Core\Access\AccessResult - * The access result. - * - * @see self::access() - */ - protected function blockAccess(AccountInterface $account) { - // By default, the block is visible. - return AccessResult::allowed(); - } - - /** - * {@inheritdoc} - * - * Creates a generic configuration form for all block types. Individual - * block plugins can add elements to this form by overriding - * BlockBase::blockForm(). Most block plugins should not override this - * method unless they need to alter the generic form elements. - * - * @see \Drupal\Core\Block\BlockBase::blockForm() - */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $definition = $this->getPluginDefinition(); - $form['provider'] = [ - '#type' => 'value', - '#value' => $definition['provider'], - ]; - - $form['admin_label'] = [ - '#type' => 'item', - '#title' => $this->t('Block description'), - '#plain_text' => $definition['admin_label'], - ]; - $form['label'] = [ - '#type' => 'textfield', - '#title' => $this->t('Title'), - '#maxlength' => 255, - '#default_value' => $this->label(), - '#required' => TRUE, - ]; - $form['label_display'] = [ - '#type' => 'checkbox', - '#title' => $this->t('Display title'), - '#default_value' => ($this->configuration['label_display'] === static::BLOCK_LABEL_VISIBLE), - '#return_value' => static::BLOCK_LABEL_VISIBLE, - ]; - - // Add context mapping UI form elements. - $contexts = $form_state->getTemporaryValue('gathered_contexts') ?: []; - $form['context_mapping'] = $this->addContextAssignmentElement($this, $contexts); - // Add plugin-specific settings for this block type. - $form += $this->blockForm($form, $form_state); - return $form; - } - - /** - * {@inheritdoc} - */ - public function blockForm($form, FormStateInterface $form_state) { - return []; - } - - /** - * {@inheritdoc} - * - * Most block plugins should not override this method. To add validation - * for a specific block type, override BlockBase::blockValidate(). - * - * @see \Drupal\Core\Block\BlockBase::blockValidate() - */ - public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { - // Remove the admin_label form item element value so it will not persist. - $form_state->unsetValue('admin_label'); - - $this->blockValidate($form, $form_state); - } - - /** - * {@inheritdoc} - */ - public function blockValidate($form, FormStateInterface $form_state) {} - - /** - * {@inheritdoc} - * - * Most block plugins should not override this method. To add submission - * handling for a specific block type, override BlockBase::blockSubmit(). - * - * @see \Drupal\Core\Block\BlockBase::blockSubmit() - */ - public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { - // Process the block's submission handling if no errors occurred only. - if (!$form_state->getErrors()) { - $this->configuration['label'] = $form_state->getValue('label'); - $this->configuration['label_display'] = $form_state->getValue('label_display'); - $this->configuration['provider'] = $form_state->getValue('provider'); - $this->blockSubmit($form, $form_state); - } - } - - /** - * {@inheritdoc} - */ - public function blockSubmit($form, FormStateInterface $form_state) {} - - /** - * {@inheritdoc} - */ - public function getMachineNameSuggestion() { - $definition = $this->getPluginDefinition(); - $admin_label = $definition['admin_label']; - - // @todo This is basically the same as what is done in - // \Drupal\system\MachineNameController::transliterate(), so it might make - // sense to provide a common service for the two. - $transliterated = $this->transliteration()->transliterate($admin_label, LanguageInterface::LANGCODE_DEFAULT, '_'); - $transliterated = mb_strtolower($transliterated); - - $transliterated = preg_replace('@[^a-z0-9_.]+@', '', $transliterated); - - return $transliterated; - } - - /** - * {@inheritdoc} - */ - public function getPreviewFallbackString() { - return $this->t('"@block" block', ['@block' => $this->label()]); - } - - /** - * Wraps the transliteration service. - * - * @return \Drupal\Component\Transliteration\TransliterationInterface - */ - protected function transliteration() { - if (!$this->transliteration) { - $this->transliteration = \Drupal::transliteration(); - } - return $this->transliteration; - } - - /** - * Sets the transliteration service. - * - * @param \Drupal\Component\Transliteration\TransliterationInterface $transliteration - * The transliteration service. - */ - public function setTransliteration(TransliterationInterface $transliteration) { - $this->transliteration = $transliteration; - } } diff --git a/web/core/lib/Drupal/Core/Block/BlockPluginTrait.php b/web/core/lib/Drupal/Core/Block/BlockPluginTrait.php new file mode 100644 index 00000000..c7c47660 --- /dev/null +++ b/web/core/lib/Drupal/Core/Block/BlockPluginTrait.php @@ -0,0 +1,287 @@ +configuration['label'])) { + return $this->configuration['label']; + } + + $definition = $this->getPluginDefinition(); + // Cast the admin label to a string since it is an object. + // @see \Drupal\Core\StringTranslation\TranslatableMarkup + return (string) $definition['admin_label']; + } + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->setConfiguration($configuration); + } + + /** + * {@inheritdoc} + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * {@inheritdoc} + */ + public function setConfiguration(array $configuration) { + $this->configuration = NestedArray::mergeDeep( + $this->baseConfigurationDefaults(), + $this->defaultConfiguration(), + $configuration + ); + } + + /** + * Returns generic default configuration for block plugins. + * + * @return array + * An associative array with the default configuration. + */ + protected function baseConfigurationDefaults() { + return [ + 'id' => $this->getPluginId(), + 'label' => '', + 'provider' => $this->pluginDefinition['provider'], + 'label_display' => BlockPluginInterface::BLOCK_LABEL_VISIBLE, + ]; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return []; + } + + /** + * {@inheritdoc} + */ + public function setConfigurationValue($key, $value) { + $this->configuration[$key] = $value; + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + return []; + } + + /** + * {@inheritdoc} + */ + public function access(AccountInterface $account, $return_as_object = FALSE) { + $access = $this->blockAccess($account); + return $return_as_object ? $access : $access->isAllowed(); + } + + /** + * Indicates whether the block should be shown. + * + * Blocks with specific access checking should override this method rather + * than access(), in order to avoid repeating the handling of the + * $return_as_object argument. + * + * @param \Drupal\Core\Session\AccountInterface $account + * The user session for which to check access. + * + * @return \Drupal\Core\Access\AccessResult + * The access result. + * + * @see self::access() + */ + protected function blockAccess(AccountInterface $account) { + // By default, the block is visible. + return AccessResult::allowed(); + } + + /** + * {@inheritdoc} + * + * Creates a generic configuration form for all block types. Individual + * block plugins can add elements to this form by overriding + * BlockBase::blockForm(). Most block plugins should not override this + * method unless they need to alter the generic form elements. + * + * @see \Drupal\Core\Block\BlockBase::blockForm() + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $definition = $this->getPluginDefinition(); + $form['provider'] = [ + '#type' => 'value', + '#value' => $definition['provider'], + ]; + + $form['admin_label'] = [ + '#type' => 'item', + '#title' => $this->t('Block description'), + '#plain_text' => $definition['admin_label'], + ]; + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Title'), + '#maxlength' => 255, + '#default_value' => $this->label(), + '#required' => TRUE, + ]; + $form['label_display'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Display title'), + '#default_value' => ($this->configuration['label_display'] === BlockPluginInterface::BLOCK_LABEL_VISIBLE), + '#return_value' => BlockPluginInterface::BLOCK_LABEL_VISIBLE, + ]; + + // Add context mapping UI form elements. + $contexts = $form_state->getTemporaryValue('gathered_contexts') ?: []; + $form['context_mapping'] = $this->addContextAssignmentElement($this, $contexts); + // Add plugin-specific settings for this block type. + $form += $this->blockForm($form, $form_state); + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + return []; + } + + /** + * {@inheritdoc} + * + * Most block plugins should not override this method. To add validation + * for a specific block type, override BlockBase::blockValidate(). + * + * @see \Drupal\Core\Block\BlockBase::blockValidate() + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + // Remove the admin_label form item element value so it will not persist. + $form_state->unsetValue('admin_label'); + + $this->blockValidate($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function blockValidate($form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + * + * Most block plugins should not override this method. To add submission + * handling for a specific block type, override BlockBase::blockSubmit(). + * + * @see \Drupal\Core\Block\BlockBase::blockSubmit() + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + // Process the block's submission handling if no errors occurred only. + if (!$form_state->getErrors()) { + $this->configuration['label'] = $form_state->getValue('label'); + $this->configuration['label_display'] = $form_state->getValue('label_display'); + $this->configuration['provider'] = $form_state->getValue('provider'); + $this->blockSubmit($form, $form_state); + } + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function getMachineNameSuggestion() { + $definition = $this->getPluginDefinition(); + $admin_label = $definition['admin_label']; + + // @todo This is basically the same as what is done in + // \Drupal\system\MachineNameController::transliterate(), so it might make + // sense to provide a common service for the two. + $transliterated = $this->transliteration()->transliterate($admin_label, LanguageInterface::LANGCODE_DEFAULT, '_'); + $transliterated = mb_strtolower($transliterated); + + $transliterated = preg_replace('@[^a-z0-9_.]+@', '', $transliterated); + + return $transliterated; + } + + /** + * {@inheritdoc} + */ + public function getPreviewFallbackString() { + return $this->t('"@block" block', ['@block' => $this->label()]); + } + + /** + * Wraps the transliteration service. + * + * @return \Drupal\Component\Transliteration\TransliterationInterface + */ + protected function transliteration() { + if (!$this->transliteration) { + $this->transliteration = \Drupal::transliteration(); + } + return $this->transliteration; + } + + /** + * Sets the transliteration service. + * + * @param \Drupal\Component\Transliteration\TransliterationInterface $transliteration + * The transliteration service. + */ + public function setTransliteration(TransliterationInterface $transliteration) { + $this->transliteration = $transliteration; + } + +} diff --git a/web/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php b/web/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php index b7f3a19f..79900c5f 100644 --- a/web/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php +++ b/web/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php @@ -2,8 +2,11 @@ namespace Drupal\Core\Block\Plugin\Block; -use Drupal\Core\Block\BlockBase; +use Drupal\Core\Block\BlockPluginInterface; +use Drupal\Core\Block\BlockPluginTrait; +use Drupal\Core\Cache\CacheableDependencyTrait; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\PluginBase; /** * Defines a fallback plugin for missing block plugins. @@ -14,7 +17,10 @@ use Drupal\Core\Form\FormStateInterface; * category = @Translation("Block"), * ) */ -class Broken extends BlockBase { +class Broken extends PluginBase implements BlockPluginInterface { + + use BlockPluginTrait; + use CacheableDependencyTrait; /** * {@inheritdoc} diff --git a/web/core/lib/Drupal/Core/Config/ConfigEvents.php b/web/core/lib/Drupal/Core/Config/ConfigEvents.php index 349d9582..8aa2d8d6 100644 --- a/web/core/lib/Drupal/Core/Config/ConfigEvents.php +++ b/web/core/lib/Drupal/Core/Config/ConfigEvents.php @@ -121,7 +121,7 @@ final class ConfigEvents { * fire the event again to continue processing missing content dependencies. * * @see \Drupal\Core\Config\ConfigImporter::processMissingContent() - * @see \Drupal\Core\Config\MissingContentEvent + * @see \Drupal\Core\Config\Importer\MissingContentEvent */ const IMPORT_MISSING_CONTENT = 'config.importer.missing_content'; diff --git a/web/core/lib/Drupal/Core/Config/Entity/Query/Condition.php b/web/core/lib/Drupal/Core/Config/Entity/Query/Condition.php index 2adfd80d..420bc0d3 100644 --- a/web/core/lib/Drupal/Core/Config/Entity/Query/Condition.php +++ b/web/core/lib/Drupal/Core/Config/Entity/Query/Condition.php @@ -130,6 +130,11 @@ class Condition extends ConditionBase { return TRUE; } } + // If the parent does not exist, it's safe to say the actual property + // we're checking for is also NULL. + elseif ($condition['operator'] === 'IS NULL') { + return TRUE; + } } // Only try to match a scalar if there are no remaining keys in // $needs_matching as this indicates that we are looking for a specific diff --git a/web/core/lib/Drupal/Core/Config/Entity/Query/Query.php b/web/core/lib/Drupal/Core/Config/Entity/Query/Query.php index 5c14c9ac..66470dce 100644 --- a/web/core/lib/Drupal/Core/Config/Entity/Query/Query.php +++ b/web/core/lib/Drupal/Core/Config/Entity/Query/Query.php @@ -89,7 +89,14 @@ class Query extends QueryBase implements QueryInterface { $direction = $sort['direction'] == 'ASC' ? -1 : 1; $field = $sort['field']; uasort($result, function ($a, $b) use ($field, $direction) { - return ($a[$field] <= $b[$field]) ? $direction : -$direction; + $properties = explode('.', $field); + foreach ($properties as $property) { + if (isset($a[$property]) || isset($b[$property])) { + $a = isset($a[$property]) ? $a[$property] : NULL; + $b = isset($b[$property]) ? $b[$property] : NULL; + } + } + return ($a <= $b) ? $direction : -$direction; }); } diff --git a/web/core/lib/Drupal/Core/Config/Importer/MissingContentEvent.php b/web/core/lib/Drupal/Core/Config/Importer/MissingContentEvent.php index 9b7baf76..e2302970 100644 --- a/web/core/lib/Drupal/Core/Config/Importer/MissingContentEvent.php +++ b/web/core/lib/Drupal/Core/Config/Importer/MissingContentEvent.php @@ -7,7 +7,7 @@ use Symfony\Component\EventDispatcher\Event; /** * Wraps a configuration event for event listeners. * - * @see \Drupal\Core\Config\Config\ConfigEvents::IMPORT_MISSING_CONTENT + * @see \Drupal\Core\Config\ConfigEvents::IMPORT_MISSING_CONTENT */ class MissingContentEvent extends Event { diff --git a/web/core/lib/Drupal/Core/Database/Connection.php b/web/core/lib/Drupal/Core/Database/Connection.php index 00e6d6c9..70e0dea8 100644 --- a/web/core/lib/Drupal/Core/Database/Connection.php +++ b/web/core/lib/Drupal/Core/Database/Connection.php @@ -1501,8 +1501,8 @@ abstract class Connection { /** * Prepares a statement for execution and returns a statement object * - * Emulated prepared statements does not communicate with the database server - * so this method does not check the statement. + * Emulated prepared statements do not communicate with the database server so + * this method does not check the statement. * * @param string $statement * This must be a valid SQL statement for the target database server. diff --git a/web/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/web/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php index 5ef4d70e..7c221fd9 100644 --- a/web/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php +++ b/web/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php @@ -686,11 +686,11 @@ class Schema extends DatabaseSchema { $condition->condition('column_name', $column); $condition->compile($this->connection, $this); // Don't use {} around information_schema.columns table. - return $this->connection->query("SELECT column_comment as column_comment FROM information_schema.columns WHERE " . (string) $condition, $condition->arguments())->fetchField(); + return $this->connection->query("SELECT column_comment AS column_comment FROM information_schema.columns WHERE " . (string) $condition, $condition->arguments())->fetchField(); } $condition->compile($this->connection, $this); // Don't use {} around information_schema.tables table. - $comment = $this->connection->query("SELECT table_comment as table_comment FROM information_schema.tables WHERE " . (string) $condition, $condition->arguments())->fetchField(); + $comment = $this->connection->query("SELECT table_comment AS table_comment FROM information_schema.tables WHERE " . (string) $condition, $condition->arguments())->fetchField(); // Work-around for MySQL 5.0 bug http://bugs.mysql.com/bug.php?id=11379 return preg_replace('/; InnoDB free:.*$/', '', $comment); } diff --git a/web/core/lib/Drupal/Core/Database/Query/Select.php b/web/core/lib/Drupal/Core/Database/Query/Select.php index 45d0fce2..bcfad552 100644 --- a/web/core/lib/Drupal/Core/Database/Query/Select.php +++ b/web/core/lib/Drupal/Core/Database/Query/Select.php @@ -814,13 +814,16 @@ class Select extends Query implements SelectInterface { $fields = []; foreach ($this->tables as $alias => $table) { if (!empty($table['all_fields'])) { - $fields[] = $this->connection->escapeTable($alias) . '.*'; + $fields[] = $this->connection->escapeAlias($alias) . '.*'; } } foreach ($this->fields as $field) { + // Note that $field['table'] holds the table alias. + // @see \Drupal\Core\Database\Query\Select::addField + $table = isset($field['table']) ? $this->connection->escapeAlias($field['table']) . '.' : ''; // Always use the AS keyword for field aliases, as some // databases require it (e.g., PostgreSQL). - $fields[] = (isset($field['table']) ? $this->connection->escapeTable($field['table']) . '.' : '') . $this->connection->escapeField($field['field']) . ' AS ' . $this->connection->escapeAlias($field['alias']); + $fields[] = $table . $this->connection->escapeField($field['field']) . ' AS ' . $this->connection->escapeAlias($field['alias']); } foreach ($this->expressions as $expression) { $fields[] = $expression['expression'] . ' AS ' . $this->connection->escapeAlias($expression['alias']); @@ -852,7 +855,7 @@ class Select extends Query implements SelectInterface { // Don't use the AS keyword for table aliases, as some // databases don't support it (e.g., Oracle). - $query .= $table_string . ' ' . $this->connection->escapeTable($table['alias']); + $query .= $table_string . ' ' . $this->connection->escapeAlias($table['alias']); if (!empty($table['condition'])) { $query .= ' ON ' . (string) $table['condition']; diff --git a/web/core/lib/Drupal/Core/Database/Schema.php b/web/core/lib/Drupal/Core/Database/Schema.php index 62097208..935c90d7 100644 --- a/web/core/lib/Drupal/Core/Database/Schema.php +++ b/web/core/lib/Drupal/Core/Database/Schema.php @@ -200,7 +200,7 @@ abstract class Schema implements PlaceholderInterface { // couldn't use \Drupal::database()->select() here because it would prefix // information_schema.tables and the query would fail. // Don't use {} around information_schema.tables table. - $results = $this->connection->query("SELECT table_name as table_name FROM information_schema.tables WHERE " . (string) $condition, $condition->arguments()); + $results = $this->connection->query("SELECT table_name AS table_name FROM information_schema.tables WHERE " . (string) $condition, $condition->arguments()); foreach ($results as $table) { // Take into account tables that have an individual prefix. if (isset($individually_prefixed_tables[$table->table_name])) { diff --git a/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php b/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php index b0681ec0..55c6bd63 100644 --- a/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php +++ b/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php @@ -8,7 +8,7 @@ namespace Drupal\Core\DependencyInjection; trait DeprecatedServicePropertyTrait { /** - * Alows to access deprecated/removed properties. + * Allows to access deprecated/removed properties. * * This method must be public. */ diff --git a/web/core/lib/Drupal/Core/Entity/ContentEntityFormInterface.php b/web/core/lib/Drupal/Core/Entity/ContentEntityFormInterface.php index 9688b1f1..853c3786 100644 --- a/web/core/lib/Drupal/Core/Entity/ContentEntityFormInterface.php +++ b/web/core/lib/Drupal/Core/Entity/ContentEntityFormInterface.php @@ -70,7 +70,7 @@ interface ContentEntityFormInterface extends EntityFormInterface { * For more information about entity validation, see * https://www.drupal.org/node/2015613. * - * @return \Drupal\Core\Entity\ContentEntityTypeInterface + * @return \Drupal\Core\Entity\ContentEntityInterface * The built entity. */ public function validateForm(array &$form, FormStateInterface $form_state); diff --git a/web/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/web/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php index 10421aba..241ce456 100644 --- a/web/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php +++ b/web/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php @@ -14,8 +14,54 @@ use Drupal\Core\Site\Settings; /** * Provides an entity autocomplete form element. * - * The #default_value accepted by this element is either an entity object or an - * array of entity objects. + * The autocomplete form element allows users to select one or multiple + * entities, which can come from all or specific bundles of an entity type. + * + * Properties: + * - #target_type: (required) The ID of the target entity type. + * - #tags: (optional) TRUE if the element allows multiple selection. Defaults + * to FALSE. + * - #default_value: (optional) The default entity or an array of default + * entities, depending on the value of #tags. + * - #selection_handler: (optional) The plugin ID of the entity reference + * selection handler (a plugin of type EntityReferenceSelection). The default + * value is the lowest-weighted plugin that is compatible with #target_type. + * - #selection_settings: (optional) An array of settings for the selection + * handler. Settings for the default selection handler + * \Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection are: + * - target_bundles: Array of bundles to allow (omit to allow all bundles). + * - sort: Array with 'field' and 'direction' keys, determining how results + * will be sorted. Defaults to unsorted. + * - #autocreate: (optional) Array of settings used to auto-create entities + * that do not exist (omit to not auto-create entities). Elements: + * - bundle: (required) Bundle to use for auto-created entities. + * - uid: User ID to use as the author of auto-created entities. Defaults to + * the current user. + * - #process_default_value: (optional) Set to FALSE if the #default_value + * property is processed and access checked elsewhere (such as by a Field API + * widget). Defaults to TRUE. + * - #validate_reference: (optional) Set to FALSE if validation of the selected + * entities is performed elsewhere. Defaults to TRUE. + * + * Usage example: + * @code + * $form['my_element'] = [ + * '#type' => 'entity_autocomplete', + * '#target_type' => 'node', + * '#tags' => TRUE, + * '#default_value' => $node, + * '#selection_handler' => 'default', + * '#selection_settings' => [ + * 'target_bundles' => ['article', 'page'], + * ], + * '#autocreate' => [ + * 'bundle' => 'article', + * 'uid' => , + * ], + * ]; + * @endcode + * + * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection * * @FormElement("entity_autocomplete") */ diff --git a/web/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php b/web/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php index 426dee11..465de1d6 100644 --- a/web/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php +++ b/web/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php @@ -395,13 +395,16 @@ class DefaultSelection extends SelectionPluginBase implements ContainerFactoryPl */ public function createNewEntity($entity_type_id, $bundle, $label, $uid) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); - $bundle_key = $entity_type->getKey('bundle'); - $label_key = $entity_type->getKey('label'); - $entity = $this->entityTypeManager->getStorage($entity_type_id)->create([ - $bundle_key => $bundle, - $label_key => $label, - ]); + $values = [ + $entity_type->getKey('label') => $label, + ]; + + if ($bundle_key = $entity_type->getKey('bundle')) { + $values[$bundle_key] = $bundle; + } + + $entity = $this->entityTypeManager->getStorage($entity_type_id)->create($values); if ($entity instanceof EntityOwnerInterface) { $entity->setOwnerId($uid); diff --git a/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index a3454fc3..b3b085ca 100644 --- a/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -846,8 +846,19 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage // Add the bundle column. if ($bundle = $this->entityType->getKey('bundle')) { - if ($base_table) { - $select->join($base_table, 'base_table', "entity_table.{$this->entityType->getKey('id')} = %alias.{$this->entityType->getKey('id')}"); + // The bundle field is not stored in the revision table, so we need to + // join the data (or base) table and retrieve it from there. + if ($base_table && $base_table !== $table_name) { + $join_condition = "entity_table.{$this->entityType->getKey('id')} = %alias.{$this->entityType->getKey('id')}"; + + // If the entity type is translatable, we also need to add the langcode + // to the join, otherwise we'll get duplicate rows for each language. + if ($this->entityType->isTranslatable()) { + $langcode = $this->entityType->getKey('langcode'); + $join_condition .= " AND entity_table.{$langcode} = %alias.{$langcode}"; + } + + $select->join($base_table, 'base_table', $join_condition); $select->addField('base_table', $bundle, 'bundle'); } else { diff --git a/web/core/lib/Drupal/Core/Entity/entity.api.php b/web/core/lib/Drupal/Core/Entity/entity.api.php index 7e1277fd..0b163dc3 100644 --- a/web/core/lib/Drupal/Core/Entity/entity.api.php +++ b/web/core/lib/Drupal/Core/Entity/entity.api.php @@ -616,6 +616,18 @@ use Drupal\node\Entity\NodeType; * are invoked are hook_entity_create_access() and * hook_ENTITY_TYPE_create_access() instead. * + * The access to an entity can be influenced in several ways: + * - To explicitly allow access, return an AccessResultInterface object with + * isAllowed() returning TRUE. Other modules can override this access by + * returning TRUE for isForbidden(). + * - To explicitly forbid access, return an AccessResultInterface object with + * isForbidden() returning TRUE. Access will be forbidden even if your module + * (or another module) also returns TRUE for isNeutral() or isAllowed(). + * - To neither allow nor explicitly forbid access, return an + * AccessResultInterface object with isNeutral() returning TRUE. + * - If your module does not return an AccessResultInterface object, neutral + * access will be assumed. + * * The Node entity type has a complex system for determining access, which * developers can interact with. This is described in the * @link node_access Node access topic. @endlink @@ -643,7 +655,10 @@ use Drupal\node\Entity\NodeType; * @param string $operation * The operation that is to be performed on $entity. * @param \Drupal\Core\Session\AccountInterface $account - * The account trying to access the entity. + * The account trying to access the entity. Usually one of: + * - "view" + * - "update" + * - "delete" * * @return \Drupal\Core\Access\AccessResultInterface * The access result. The final result is calculated by using @@ -677,7 +692,10 @@ function hook_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operat * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to check access to. * @param string $operation - * The operation that is to be performed on $entity. + * The operation that is to be performed on $entity. Usually one of: + * - "view" + * - "update" + * - "delete" * @param \Drupal\Core\Session\AccountInterface $account * The account trying to access the entity. * diff --git a/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php b/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php index 7a39969b..998213ea 100644 --- a/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php +++ b/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php @@ -42,6 +42,7 @@ class ExceptionLoggingSubscriber implements EventSubscriberInterface { // why access was denied. $exception = $event->getException(); $error = Error::decodeException($exception); + unset($error['@backtrace_string']); $error['@uri'] = $event->getRequest()->getRequestUri(); $this->logger->get('access denied')->warning('Path: @uri. %type: @message in %function (line %line of %file).', $error); } diff --git a/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/BooleanCheckboxWidget.php b/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/BooleanCheckboxWidget.php index 660a0646..7991a6f6 100644 --- a/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/BooleanCheckboxWidget.php +++ b/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/BooleanCheckboxWidget.php @@ -49,7 +49,7 @@ class BooleanCheckboxWidget extends WidgetBase { $summary = []; $display_label = $this->getSetting('display_label'); - $summary[] = t('Use field label: @display_label', ['@display_label' => ($display_label ? t('Yes') : 'No')]); + $summary[] = t('Use field label: @display_label', ['@display_label' => ($display_label ? t('Yes') : t('No'))]); return $summary; } diff --git a/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php b/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php index af3c80a9..d9f5b581 100644 --- a/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php +++ b/web/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php @@ -117,7 +117,7 @@ class EntityReferenceAutocompleteWidget extends WidgetBase { '#placeholder' => $this->getSetting('placeholder'), ]; - if ($this->getSelectionHandlerSetting('auto_create') && ($bundle = $this->getAutocreateBundle())) { + if ($bundle = $this->getAutocreateBundle()) { $element['#autocreate'] = [ 'bundle' => $bundle, 'uid' => ($entity instanceof EntityOwnerInterface) ? $entity->getOwnerId() : \Drupal::currentUser()->id(), @@ -154,16 +154,23 @@ class EntityReferenceAutocompleteWidget extends WidgetBase { * Returns the name of the bundle which will be used for autocreated entities. * * @return string - * The bundle name. + * The bundle name. If autocreate is not active, NULL will be returned. */ protected function getAutocreateBundle() { $bundle = NULL; - if ($this->getSelectionHandlerSetting('auto_create') && $target_bundles = $this->getSelectionHandlerSetting('target_bundles')) { + if ($this->getSelectionHandlerSetting('auto_create')) { + $target_bundles = $this->getSelectionHandlerSetting('target_bundles'); + // If there's no target bundle at all, use the target_type. It's the + // default for bundleless entity types. + if (empty($target_bundles)) { + $bundle = $this->getFieldSetting('target_type'); + } // If there's only one target bundle, use it. - if (count($target_bundles) == 1) { + elseif (count($target_bundles) == 1) { $bundle = reset($target_bundles); } - // Otherwise use the target bundle stored in selection handler settings. + // If there's more than one target bundle, use the autocreate bundle + // stored in selection handler settings. elseif (!$bundle = $this->getSelectionHandlerSetting('auto_create_bundle')) { // If no bundle has been set as auto create target means that there is // an inconsistency in entity reference field settings. diff --git a/web/core/lib/Drupal/Core/Form/FormBuilder.php b/web/core/lib/Drupal/Core/Form/FormBuilder.php index 5e8e22a6..1a422d84 100644 --- a/web/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/web/core/lib/Drupal/Core/Form/FormBuilder.php @@ -861,7 +861,8 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS // https://www.drupal.org/node/2504709. $parsed = UrlHelper::parse($request_uri); unset($parsed['query'][static::AJAX_FORM_REQUEST], $parsed['query'][MainContentViewSubscriber::WRAPPER_FORMAT]); - return $parsed['path'] . ($parsed['query'] ? ('?' . UrlHelper::buildQuery($parsed['query'])) : ''); + $action = $parsed['path'] . ($parsed['query'] ? ('?' . UrlHelper::buildQuery($parsed['query'])) : ''); + return UrlHelper::filterBadProtocol($action); } /** diff --git a/web/core/lib/Drupal/Core/Link.php b/web/core/lib/Drupal/Core/Link.php index c4fbd0df..90cbac9e 100644 --- a/web/core/lib/Drupal/Core/Link.php +++ b/web/core/lib/Drupal/Core/Link.php @@ -66,8 +66,8 @@ class Link implements RenderableInterface { /** * Creates a Link object from a given Url object. * - * @param string $text - * The text of the link. + * @param string|array|\Drupal\Component\Render\MarkupInterface $text + * The link text for the anchor tag as a translated string or render array. * @param \Drupal\Core\Url $url * The Url to create the link for. * diff --git a/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php b/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php index cff99fa5..76a83ca4 100644 --- a/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php +++ b/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php @@ -10,13 +10,13 @@ use Drupal\Core\StringTranslation\TranslatableMarkup; * Logging severity levels as defined in RFC 5424. * * The constant definitions of this class correspond to the logging severity - * levels defined in RFC 5424, section 4.1.1. PHP supplies predefined LOG_* + * levels defined in RFC 5424, section 6.2.1. PHP supplies predefined LOG_* * constants for use in the syslog() function, but their values on Windows * builds do not correspond to RFC 5424. The associated PHP bug report was * closed with the comment, "And it's also not a bug, as Windows just have less * log levels," and "So the behavior you're seeing is perfectly normal." * - * @see http://tools.ietf.org/html/rfc5424 + * @see https://tools.ietf.org/html/rfc5424#section-6.2.1 * @see http://bugs.php.net/bug.php?id=18090 * @see http://php.net/manual/function.syslog.php * @see http://php.net/manual/network.constants.php diff --git a/web/core/lib/Drupal/Core/Render/Element/Email.php b/web/core/lib/Drupal/Core/Render/Element/Email.php index 84bb3526..908d71ea 100644 --- a/web/core/lib/Drupal/Core/Render/Element/Email.php +++ b/web/core/lib/Drupal/Core/Render/Element/Email.php @@ -15,14 +15,14 @@ use Drupal\Core\Render\Element; * * Example usage: * @code - * $form['email'] = array( + * $form['email'] = [ * '#type' => 'email', * '#title' => $this->t('Email'), * '#pattern' => '*@example.com', - * ); - * @end + * ]; + * @endcode * - * @see \Drupal\Core\Render\Element\Render\Textfield + * @see \Drupal\Core\Render\Element\Textfield * * @FormElement("email") */ diff --git a/web/core/lib/Drupal/Core/Render/Element/StatusReport.php b/web/core/lib/Drupal/Core/Render/Element/StatusReport.php index 85b12e25..3d9313af 100644 --- a/web/core/lib/Drupal/Core/Render/Element/StatusReport.php +++ b/web/core/lib/Drupal/Core/Render/Element/StatusReport.php @@ -52,7 +52,7 @@ class StatusReport extends RenderElement { // Order the grouped requirements by a set order. $order = array_flip($element['#priorities']); uksort($grouped_requirements, function ($a, $b) use ($order) { - return $order[$a] > $order[$b]; + return $order[$a] <=> $order[$b]; }); $element['#grouped_requirements'] = $grouped_requirements; diff --git a/web/core/lib/Drupal/Core/Render/theme.api.php b/web/core/lib/Drupal/Core/Render/theme.api.php index 605c91b1..082f139f 100644 --- a/web/core/lib/Drupal/Core/Render/theme.api.php +++ b/web/core/lib/Drupal/Core/Render/theme.api.php @@ -414,13 +414,16 @@ * render array contained: * @code * $build['my_element'] = [ - * '#attached' => ['placeholders' => ['@foo' => 'replacement']], - * '#markup' => ['Something about @foo'], + * '#markup' => 'Something about @foo', + * '#attached' => [ + * 'placeholders' => [ + * '@foo' => ['#markup' => 'replacement'], + * ], * ]; * @endcode * then #markup would end up containing 'Something about replacement'. * - * Note that each placeholder value can itself be a render array, which will be + * Note that each placeholder value *must* itself be a render array. It will be * rendered, and any cache tags generated during rendering will be added to the * cache tags for the markup. * diff --git a/web/core/lib/Drupal/Core/Security/PharExtensionInterceptor.php b/web/core/lib/Drupal/Core/Security/PharExtensionInterceptor.php index 0d8e8e83..6f6e161e 100644 --- a/web/core/lib/Drupal/Core/Security/PharExtensionInterceptor.php +++ b/web/core/lib/Drupal/Core/Security/PharExtensionInterceptor.php @@ -60,8 +60,8 @@ class PharExtensionInterceptor implements Assertable { return FALSE; } // If the stream wrapper is registered by invoking a phar file that does - // not not have .phar extension then this should be allowed. For - // example, some CLI tools recommend removing the extension. + // not have .phar extension then this should be allowed. For example, some + // CLI tools recommend removing the extension. $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // Find the last entry in the backtrace containing a 'file' key as // sometimes the last caller is executed outside the scope of a file. For diff --git a/web/core/lib/Drupal/Core/Template/AttributeHelper.php b/web/core/lib/Drupal/Core/Template/AttributeHelper.php index 4beb5208..c4b0fbfa 100644 --- a/web/core/lib/Drupal/Core/Template/AttributeHelper.php +++ b/web/core/lib/Drupal/Core/Template/AttributeHelper.php @@ -26,7 +26,7 @@ class AttributeHelper { * An Attribute object or an array of attributes. * * @return bool - * TRUE if the attibute exists, FALSE otherwise. + * TRUE if the attribute exists, FALSE otherwise. * * @throws \InvalidArgumentException * When the input $collection is neither an Attribute object nor an array. diff --git a/web/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php b/web/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php index bc7846e8..ee85a625 100644 --- a/web/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php +++ b/web/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php @@ -205,7 +205,7 @@ class PhpUnitTestRunner implements ContainerInjectionInterface { */ public function runTests($test_id, array $unescaped_test_classnames, &$status = NULL) { $phpunit_file = $this->xmlLogFilePath($test_id); - // Store ouptut from our test run. + // Store output from our test run. $output = []; $this->runCommand($unescaped_test_classnames, $phpunit_file, $status, $output); @@ -217,7 +217,7 @@ class PhpUnitTestRunner implements ContainerInjectionInterface { 'test_id' => $test_id, 'test_class' => implode(",", $unescaped_test_classnames), 'status' => TestStatus::label($status), - 'message' => 'PHPunit Test failed to complete; Error: ' . implode("\n", $output), + 'message' => 'PHPUnit Test failed to complete; Error: ' . implode("\n", $output), 'message_group' => 'Other', 'function' => implode(",", $unescaped_test_classnames), 'line' => '0', diff --git a/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php index 9ac018c3..aab5850a 100644 --- a/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -169,7 +169,15 @@ class TypedDataManager extends DefaultPluginManager implements TypedDataManagerI $parts[] = json_encode($settings); } // Property path for the requested data object. - $parts[] = $object->getPropertyPath() . '.' . $property_name; + $parts[] = $object->getPropertyPath(); + // Only property instances of complex data types should be cached by the + // property name, as they represent different properties. Properties of list + // data types are the items of the list and the property name represents + // only the delta in that list and not an unique property, which is why all + // items should use the same prototype. + if ($object instanceof ComplexDataInterface) { + $parts[] = $property_name; + } $key = implode(':', $parts); // Create the prototype if needed. diff --git a/web/core/lib/Drupal/Core/Update/UpdateCompilerPass.php b/web/core/lib/Drupal/Core/Update/UpdateCompilerPass.php index 6ac05886..73cef024 100644 --- a/web/core/lib/Drupal/Core/Update/UpdateCompilerPass.php +++ b/web/core/lib/Drupal/Core/Update/UpdateCompilerPass.php @@ -27,16 +27,28 @@ class UpdateCompilerPass implements CompilerPassInterface { do { $has_changed = FALSE; foreach ($container->getDefinitions() as $key => $definition) { + // Ensure all the definition's arguments are valid. foreach ($definition->getArguments() as $argument) { - if ($argument instanceof Reference) { - $argument_id = (string) $argument; - if (!$container->has($argument_id) && $argument->getInvalidBehavior() === ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) { - // If the container does not have the argument and would throw an - // exception, remove the service. + if ($this->isArgumentMissingService($argument, $container)) { + $container->removeDefinition($key); + $container->log($this, sprintf('Removed service "%s"; reason: depends on non-existent service "%s".', $key, (string) $argument)); + $has_changed = TRUE; + $process_aliases = TRUE; + // Process the next definition. + continue 2; + } + } + + // Ensure all the method call arguments are valid. + foreach ($definition->getMethodCalls() as $call) { + foreach ($call[1] as $argument) { + if ($this->isArgumentMissingService($argument, $container)) { $container->removeDefinition($key); - $container->log($this, sprintf('Removed service "%s"; reason: depends on non-existent service "%s".', $key, $argument_id)); + $container->log($this, sprintf('Removed service "%s"; reason: method call "%s" depends on non-existent service "%s".', $key, $call[0], (string) $argument)); $has_changed = TRUE; $process_aliases = TRUE; + // Process the next definition. + continue 3; } } } @@ -58,4 +70,26 @@ class UpdateCompilerPass implements CompilerPassInterface { } } + /** + * Checks if a reference argument is to a missing service. + * + * @param mixed $argument + * The argument to check. + * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container + * The container. + * + * @return bool + * TRUE if the argument is a reference to a service that is missing from the + * container and the reference is required, FALSE if not. + */ + private function isArgumentMissingService($argument, ContainerBuilder $container) { + if ($argument instanceof Reference) { + $argument_id = (string) $argument; + if (!$container->has($argument_id) && $argument->getInvalidBehavior() === ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) { + return TRUE; + } + } + return FALSE; + } + } diff --git a/web/core/lib/Drupal/Core/Url.php b/web/core/lib/Drupal/Core/Url.php index 82c2c600..7465e34a 100644 --- a/web/core/lib/Drupal/Core/Url.php +++ b/web/core/lib/Drupal/Core/Url.php @@ -297,7 +297,7 @@ class Url implements TrustedCallbackInterface { // Extract query parameters and fragment and merge them into $uri_options, // but preserve the original $options for the fallback case. $uri_options = $options; - if (isset($uri_parts['fragment'])) { + if (isset($uri_parts['fragment']) && $uri_parts['fragment'] !== '') { $uri_options += ['fragment' => $uri_parts['fragment']]; unset($uri_parts['fragment']); } diff --git a/web/core/lib/Drupal/Core/Utility/ProjectInfo.php b/web/core/lib/Drupal/Core/Utility/ProjectInfo.php index 395a23bf..63e17da2 100644 --- a/web/core/lib/Drupal/Core/Utility/ProjectInfo.php +++ b/web/core/lib/Drupal/Core/Utility/ProjectInfo.php @@ -35,11 +35,11 @@ class ProjectInfo { * @param bool $status * Boolean that controls what status (enabled or uninstalled) to process out * of the $list and add to the $projects array. - * @param array $additional_whitelist + * @param array $additional_elements * (optional) Array of additional elements to be collected from the .info.yml * file. Defaults to array(). */ - public function processInfoList(array &$projects, array $list, $project_type, $status, array $additional_whitelist = []) { + public function processInfoList(array &$projects, array $list, $project_type, $status, array $additional_elements = []) { foreach ($list as $file) { // Just projects with a matching status should be listed. if ($file->status != $status) { @@ -111,7 +111,7 @@ class ProjectInfo { 'name' => $project_name, // Only save attributes from the .info.yml file we care about so we do // not bloat our RAM usage needlessly. - 'info' => $this->filterProjectInfo($file->info, $additional_whitelist), + 'info' => $this->filterProjectInfo($file->info, $additional_elements), 'datestamp' => $file->info['datestamp'], 'includes' => [$file->getName() => $file->info['name']], 'project_type' => $project_display_type, @@ -165,7 +165,7 @@ class ProjectInfo { * @param array $info * Array of .info.yml file data as returned by * \Drupal\Core\Extension\InfoParser. - * @param $additional_whitelist + * @param $additional_elements * (optional) Array of additional elements to be collected from the .info.yml * file. Defaults to array(). * @@ -174,8 +174,8 @@ class ProjectInfo { * * @see \Drupal\Core\Utility\ProjectInfo::processInfoList() */ - public function filterProjectInfo($info, $additional_whitelist = []) { - $whitelist = [ + public function filterProjectInfo($info, $additional_elements = []) { + $elements = [ '_info_file_ctime', 'datestamp', 'major', @@ -185,8 +185,8 @@ class ProjectInfo { 'project status url', 'version', ]; - $whitelist = array_merge($whitelist, $additional_whitelist); - return array_intersect_key($info, array_combine($whitelist, $whitelist)); + $elements = array_merge($elements, $additional_elements); + return array_intersect_key($info, array_combine($elements, $elements)); } } diff --git a/web/core/misc/ajax.es6.js b/web/core/misc/ajax.es6.js index 6eeddf3d..119642db 100644 --- a/web/core/misc/ajax.es6.js +++ b/web/core/misc/ajax.es6.js @@ -559,6 +559,7 @@ } }, dataType: 'json', + jsonp: false, type: 'POST', }; diff --git a/web/core/misc/ajax.js b/web/core/misc/ajax.js index cc3936ca..b817b77b 100644 --- a/web/core/misc/ajax.js +++ b/web/core/misc/ajax.js @@ -243,6 +243,7 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr }, dataType: 'json', + jsonp: false, type: 'POST' }; diff --git a/web/core/misc/autocomplete.es6.js b/web/core/misc/autocomplete.es6.js index 65f6332a..1b5d8791 100644 --- a/web/core/misc/autocomplete.es6.js +++ b/web/core/misc/autocomplete.es6.js @@ -281,6 +281,7 @@ }, ajax: { dataType: 'json', + jsonp: false, }, }; diff --git a/web/core/misc/autocomplete.js b/web/core/misc/autocomplete.js index 52ddfd2a..fc90d775 100644 --- a/web/core/misc/autocomplete.js +++ b/web/core/misc/autocomplete.js @@ -156,7 +156,8 @@ isComposing: false }, ajax: { - dataType: 'json' + dataType: 'json', + jsonp: false } }; diff --git a/web/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php b/web/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php index 2b74d300..8a4f7ab8 100644 --- a/web/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php +++ b/web/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php @@ -197,11 +197,8 @@ abstract class AggregatorTestBase extends BrowserTestBase { $this->clickLink('Update items'); // Ensure we have the right number of items. - $iids = \Drupal::entityQuery('aggregator_item')->condition('fid', $feed->id())->execute(); - $feed->items = []; - foreach ($iids as $iid) { - $feed->items[] = $iid; - } + $item_ids = \Drupal::entityQuery('aggregator_item')->condition('fid', $feed->id())->execute(); + $feed->items = array_values($item_ids); if ($expected_count !== NULL) { $feed->item_count = count($feed->items); diff --git a/web/core/modules/aggregator/tests/src/Functional/FeedParserTest.php b/web/core/modules/aggregator/tests/src/Functional/FeedParserTest.php index 4e76ad76..bc3ed26c 100644 --- a/web/core/modules/aggregator/tests/src/Functional/FeedParserTest.php +++ b/web/core/modules/aggregator/tests/src/Functional/FeedParserTest.php @@ -64,16 +64,16 @@ class FeedParserTest extends AggregatorTestBase { $this->assertText('Atom-Powered Robots Run Amok'); $this->assertLinkByHref('http://example.org/2003/12/13/atom03'); $this->assertText('Some text.'); - $iids = \Drupal::entityQuery('aggregator_item')->condition('link', 'http://example.org/2003/12/13/atom03')->execute(); - $item = Item::load(array_values($iids)[0]); + $item_ids = \Drupal::entityQuery('aggregator_item')->condition('link', 'http://example.org/2003/12/13/atom03')->execute(); + $item = Item::load(array_values($item_ids)[0]); $this->assertEqual('urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', $item->getGuid(), 'Atom entry id element is parsed correctly.'); // Check for second feed entry. $this->assertText('We tried to stop them, but we failed.'); $this->assertLinkByHref('http://example.org/2003/12/14/atom03'); $this->assertText('Some other text.'); - $iids = \Drupal::entityQuery('aggregator_item')->condition('link', 'http://example.org/2003/12/14/atom03')->execute(); - $item = Item::load(array_values($iids)[0]); + $item_ids = \Drupal::entityQuery('aggregator_item')->condition('link', 'http://example.org/2003/12/14/atom03')->execute(); + $item = Item::load(array_values($item_ids)[0]); $this->assertEqual('urn:uuid:1225c695-cfb8-4ebb-bbbb-80da344efa6a', $item->getGuid(), 'Atom entry id element is parsed correctly.'); } diff --git a/web/core/modules/aggregator/tests/src/Functional/UpdateFeedItemTest.php b/web/core/modules/aggregator/tests/src/Functional/UpdateFeedItemTest.php index fdbcc04e..4c5a3d3a 100644 --- a/web/core/modules/aggregator/tests/src/Functional/UpdateFeedItemTest.php +++ b/web/core/modules/aggregator/tests/src/Functional/UpdateFeedItemTest.php @@ -54,8 +54,8 @@ class UpdateFeedItemTest extends AggregatorTestBase { $feed = Feed::load(array_values($fids)[0]); $feed->refreshItems(); - $iids = \Drupal::entityQuery('aggregator_item')->condition('fid', $feed->id())->execute(); - $before = Item::load(array_values($iids)[0])->getPostedTime(); + $item_ids = \Drupal::entityQuery('aggregator_item')->condition('fid', $feed->id())->execute(); + $before = Item::load(array_values($item_ids)[0])->getPostedTime(); // Sleep for 3 second. sleep(3); @@ -67,7 +67,7 @@ class UpdateFeedItemTest extends AggregatorTestBase { ->save(); $feed->refreshItems(); - $after = Item::load(array_values($iids)[0])->getPostedTime(); + $after = Item::load(array_values($item_ids)[0])->getPostedTime(); $this->assertTrue($before === $after, new FormattableMarkup('Publish timestamp of feed item was not updated (@before === @after)', ['@before' => $before, '@after' => $after])); // Make sure updating items works even after uninstalling a module diff --git a/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php b/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php index 0df08b0f..1b4ecd84 100644 --- a/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php +++ b/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php @@ -39,7 +39,7 @@ class IpAddressBlockingTest extends BrowserTestBase { $edit = []; $edit['ip'] = '1.2.3.3'; $this->drupalPostForm('admin/config/people/ban', $edit, t('Add')); - $ip = $connection->query("SELECT iid from {ban_ip} WHERE ip = :ip", [':ip' => $edit['ip']])->fetchField(); + $ip = $connection->select('ban_ip', 'bi')->fields('bi', ['iid'])->condition('ip', $edit['ip'])->execute()->fetchField(); $this->assertNotEmpty($ip, 'IP address found in database.'); $this->assertRaw(t('The IP address %ip has been banned.', ['%ip' => $edit['ip']]), 'IP address was banned.'); @@ -70,7 +70,7 @@ class IpAddressBlockingTest extends BrowserTestBase { // Pass an IP address as a URL parameter and submit it. $submit_ip = '1.2.3.4'; $this->drupalPostForm('admin/config/people/ban/' . $submit_ip, [], t('Add')); - $ip = $connection->query("SELECT iid from {ban_ip} WHERE ip = :ip", [':ip' => $submit_ip])->fetchField(); + $ip = $connection->select('ban_ip', 'bi')->fields('bi', ['iid'])->condition('ip', $submit_ip)->execute()->fetchField(); $this->assertNotEmpty($ip, 'IP address found in database'); $this->assertRaw(t('The IP address %ip has been banned.', ['%ip' => $submit_ip]), 'IP address was banned.'); diff --git a/web/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php b/web/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php index 3e0f460e..bd022f2e 100644 --- a/web/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php +++ b/web/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php @@ -210,7 +210,7 @@ class BigPipeStrategy implements PlaceholderStrategyInterface { 'library' => [ 'big_pipe/big_pipe', ], - // Inform BigPipe' JavaScript known BigPipe placeholder IDs (a whitelist). + // Inform BigPipe' JavaScript known BigPipe placeholder IDs. 'drupalSettings' => [ 'bigPipePlaceholderIds' => [$big_pipe_placeholder_id => TRUE], ], diff --git a/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php b/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php index e059f983..5d6775c0 100644 --- a/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php +++ b/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php @@ -153,7 +153,7 @@ class BigPipeTest extends BrowserTestBase { $this->assertBigPipeNoJsCookieExists(FALSE); $connection = Database::getConnection(); - $log_count = $connection->query('SELECT COUNT(*) FROM {watchdog}')->fetchField(); + $log_count = $connection->select('watchdog')->countQuery()->execute()->fetchField(); // By not calling performMetaRefresh() here, we simulate JavaScript being // enabled, because as far as the BigPipe module is concerned, JavaScript is @@ -186,15 +186,16 @@ class BigPipeTest extends BrowserTestBase { $this->assertRaw('', 'Closing body tag present.'); - $this->pass('Verifying BigPipe assets are present…', 'Debug'); + // Verifying BigPipe assets are present. $this->assertFalse(empty($this->getDrupalSettings()), 'drupalSettings present.'); $this->assertContains('big_pipe/big_pipe', explode(',', $this->getDrupalSettings()['ajaxPageState']['libraries']), 'BigPipe asset library is present.'); // Verify that the two expected exceptions are logged as errors. - $this->assertEqual($log_count + 2, $connection->query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), 'Two new watchdog entries.'); - // Using the method queryRange() allows contrib database drivers the ability - // to insert their own limit and offset functionality. - $records = $connection->queryRange('SELECT * FROM {watchdog} ORDER BY wid DESC', 0, 2)->fetchAll(); + $this->assertEqual($log_count + 2, (int) $connection->select('watchdog')->countQuery()->execute()->fetchField(), 'Two new watchdog entries.'); + // Using dynamic select queries with the method range() allows contrib + // database drivers the ability to insert their own limit and offset + // functionality. + $records = $connection->select('watchdog', 'w')->fields('w')->orderBy('wid', 'DESC')->range(0, 2)->execute()->fetchAll(); $this->assertEqual(RfcLogLevel::ERROR, $records[0]->severity); $this->assertStringContainsString('Oh noes!', (string) unserialize($records[0]->variables)['@message']); $this->assertEqual(RfcLogLevel::ERROR, $records[1]->severity); @@ -205,7 +206,8 @@ class BigPipeTest extends BrowserTestBase { $this->drupalGet(Url::fromUri('base:non-existing-path')); // Simulate development. - $this->pass('Verifying BigPipe provides useful error output when an error occurs while rendering a placeholder if verbose error logging is enabled.', 'Debug'); + // Verifying BigPipe provides useful error output when an error occurs + // while rendering a placeholder if verbose error logging is enabled. $this->config('system.logging')->set('error_level', ERROR_REPORTING_DISPLAY_VERBOSE)->save(); $this->drupalGet(Url::fromRoute('big_pipe_test')); // The 'edge_case__html_exception' case throws an exception. @@ -259,13 +261,13 @@ class BigPipeTest extends BrowserTestBase { $cases['exception__embedded_response']->bigPipePlaceholderId => NULL, ]); - $this->pass('Verifying there are no BigPipe placeholders & replacements…', 'Debug'); + // Verifying there are no BigPipe placeholders & replacements. $this->assertEqual('', $this->drupalGetHeader('BigPipe-Test-Placeholders')); - $this->pass('Verifying BigPipe start/stop signals are absent…', 'Debug'); + // Verifying BigPipe start/stop signals are absent. $this->assertNoRaw(BigPipe::START_SIGNAL, 'BigPipe start signal absent.'); $this->assertNoRaw(BigPipe::STOP_SIGNAL, 'BigPipe stop signal absent.'); - $this->pass('Verifying BigPipe assets are absent…', 'Debug'); + // Verifying BigPipe assets are absent. $this->assertTrue(!isset($this->getDrupalSettings()['bigPipePlaceholderIds']) && empty($this->getDrupalSettings()['ajaxPageState']), 'BigPipe drupalSettings and BigPipe asset library absent.'); $this->assertRaw('', 'Closing body tag present.'); @@ -274,7 +276,8 @@ class BigPipeTest extends BrowserTestBase { $this->drupalGet(Url::fromUri('base:non-existing-path')); // Simulate development. - $this->pass('Verifying BigPipe provides useful error output when an error occurs while rendering a placeholder if verbose error logging is enabled.', 'Debug'); + // Verifying BigPipe provides useful error output when an error occurs + // while rendering a placeholder if verbose error logging is enabled. $this->config('system.logging')->set('error_level', ERROR_REPORTING_DISPLAY_VERBOSE)->save(); $this->drupalGet(Url::fromRoute('big_pipe_test')); // The 'edge_case__html_exception' case throws an exception. @@ -322,7 +325,6 @@ class BigPipeTest extends BrowserTestBase { } protected function assertBigPipeResponseHeadersPresent() { - $this->pass('Verifying BigPipe response headers…', 'Debug'); // Check that Cache-Control header set to "private". $this->assertSession()->responseHeaderContains('Cache-Control', 'private'); $this->assertEqual('no-store, content="BigPipe/1.0"', $this->drupalGetHeader('Surrogate-Control')); @@ -337,10 +339,10 @@ class BigPipeTest extends BrowserTestBase { * markup. */ protected function assertBigPipeNoJsPlaceholders(array $expected_big_pipe_nojs_placeholders) { - $this->pass('Verifying BigPipe no-JS placeholders & replacements…', 'Debug'); $this->assertSetsEqual(array_keys($expected_big_pipe_nojs_placeholders), array_map('rawurldecode', explode(' ', $this->drupalGetHeader('BigPipe-Test-No-Js-Placeholders')))); foreach ($expected_big_pipe_nojs_placeholders as $big_pipe_nojs_placeholder => $expected_replacement) { - $this->pass('Checking whether the replacement for the BigPipe no-JS placeholder "' . $big_pipe_nojs_placeholder . '" is present:'); + // Checking whether the replacement for the BigPipe no-JS placeholder + // $big_pipe_nojs_placeholder is present. $this->assertNoRaw($big_pipe_nojs_placeholder); if ($expected_replacement !== NULL) { $this->assertRaw($expected_replacement); @@ -358,12 +360,10 @@ class BigPipeTest extends BrowserTestBase { * defined in the order that they are expected to be rendered & streamed. */ protected function assertBigPipePlaceholders(array $expected_big_pipe_placeholders, array $expected_big_pipe_placeholder_stream_order) { - $this->pass('Verifying BigPipe placeholders & replacements…', 'Debug'); $this->assertSetsEqual(array_keys($expected_big_pipe_placeholders), explode(' ', $this->drupalGetHeader('BigPipe-Test-Placeholders'))); $placeholder_positions = []; $placeholder_replacement_positions = []; foreach ($expected_big_pipe_placeholders as $big_pipe_placeholder_id => $expected_ajax_response) { - $this->pass('BigPipe placeholder: ' . $big_pipe_placeholder_id, 'Debug'); // Verify expected placeholder. $expected_placeholder_html = ''; $this->assertRaw($expected_placeholder_html, 'BigPipe placeholder for placeholder ID "' . $big_pipe_placeholder_id . '" found.'); @@ -396,14 +396,15 @@ class BigPipeTest extends BrowserTestBase { $this->assertSetsEqual(array_keys($expected_big_pipe_placeholders_with_replacements), array_values($placeholder_replacement_positions)); $this->assertEqual(count($expected_big_pipe_placeholders_with_replacements), preg_match_all('/' . preg_quote(' Lorem ipsum"]); - $wid = Database::getConnection()->query('SELECT MAX(wid) FROM {watchdog}')->fetchField(); + $query = Database::getConnection()->select('watchdog'); + $query->addExpression('MAX(wid)'); + $wid = $query->execute()->fetchField(); $this->drupalGet('admin/reports/dblog/event/' . $wid); $this->assertNoRaw(""); $this->assertRaw("alert('foo'); Lorem ipsum"); @@ -864,7 +881,9 @@ class DbLogTest extends BrowserTestBase { $this->drupalLogin($this->adminUser); $this->drupalGet('/error-test/generate-warnings'); - $wid = Database::getConnection()->query('SELECT MAX(wid) FROM {watchdog}')->fetchField(); + $query = Database::getConnection()->select('watchdog'); + $query->addExpression('MAX(wid)'); + $wid = $query->execute()->fetchField(); $this->drupalGet('admin/reports/dblog/event/' . $wid); $error_user_notice = [ diff --git a/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php b/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php index 4914f9f4..b17c138d 100644 --- a/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php +++ b/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php @@ -39,7 +39,10 @@ class ConnectionFailureTest extends KernelTestBase { // Re-establish the default database connection. $database = Database::getConnection(); - $wid = $database->query("SELECT MAX(wid) FROM {watchdog} WHERE message = 'testConnectionFailureLogging'")->fetchField(); + $query = $database->select('watchdog') + ->condition('message', 'testConnectionFailureLogging'); + $query->addExpression('MAX(wid)'); + $wid = $query->execute()->fetchField(); $this->assertNotEmpty($wid, 'Watchdog entry has been stored in database.'); } diff --git a/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php b/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php index b211cc74..3d0af4ce 100644 --- a/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php +++ b/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php @@ -40,7 +40,7 @@ class DbLogTest extends KernelTestBase { // Generate additional log entries. $this->generateLogEntries($row_limit + 10); // Verify that the database log row count exceeds the row limit. - $count = Database::getConnection()->query('SELECT COUNT(wid) FROM {watchdog}')->fetchField(); + $count = Database::getConnection()->select('watchdog')->countQuery()->execute()->fetchField(); $this->assertGreaterThan($row_limit, $count, new FormattableMarkup('Dblog row count of @count exceeds row limit of @limit', ['@count' => $count, '@limit' => $row_limit])); // Get the number of enabled modules. Cron adds a log entry for each module. @@ -66,13 +66,17 @@ class DbLogTest extends KernelTestBase { // Get last ID to compare against; log entries get deleted, so we can't // reliably add the number of newly created log entries to the current count // to measure number of log entries created by cron. - $last_id = $connection->query('SELECT MAX(wid) FROM {watchdog}')->fetchField(); + $query = $connection->select('watchdog'); + $query->addExpression('MAX(wid)'); + $last_id = $query->execute()->fetchField(); // Run a cron job. $this->container->get('cron')->run(); // Get last ID after cron was run. - $current_id = $connection->query('SELECT MAX(wid) FROM {watchdog}')->fetchField(); + $query = $connection->select('watchdog'); + $query->addExpression('MAX(wid)'); + $current_id = $query->execute()->fetchField(); return $current_id - $last_id; } diff --git a/web/core/modules/editor/tests/src/Functional/EditorSecurityTest.php b/web/core/modules/editor/tests/src/Functional/EditorSecurityTest.php index c6bd6495..4f5b50b4 100644 --- a/web/core/modules/editor/tests/src/Functional/EditorSecurityTest.php +++ b/web/core/modules/editor/tests/src/Functional/EditorSecurityTest.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\editor\Functional; -use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Serialization\Json; use Drupal\editor\Entity\Editor; use Drupal\filter\Entity\FilterFormat; @@ -282,10 +281,6 @@ class EditorSecurityTest extends BrowserTestBase { // Log in as each user that may edit the content, and assert the value. foreach ($expected as $case) { foreach ($case['users'] as $account) { - $this->pass(new FormattableMarkup('Scenario: sample %sample_id, %format.', [ - '%sample_id' => $case['node_id'], - '%format' => $case['format'], - ])); $this->drupalLogin($account); $this->drupalGet('node/' . $case['node_id'] . '/edit'); $dom_node = $this->xpath('//textarea[@id="edit-body-0-value"]'); @@ -407,12 +402,6 @@ class EditorSecurityTest extends BrowserTestBase { // Switch to every other text format/editor and verify the results. foreach ($case['switch_to'] as $format => $expected_filtered_value) { - $this->pass(new FormattableMarkup('Scenario: sample %sample_id, switch from %original_format to %format.', [ - '%sample_id' => $case['node_id'], - '%original_format' => $case['format'], - '%format' => $format, - ])); - $post = [ 'value' => self::$sampleContent, 'original_format_id' => $case['format'], diff --git a/web/core/modules/editor/tests/src/Kernel/EditorFileReferenceFilterTest.php b/web/core/modules/editor/tests/src/Kernel/EditorFileReferenceFilterTest.php index f9bdcfa9..4912904d 100644 --- a/web/core/modules/editor/tests/src/Kernel/EditorFileReferenceFilterTest.php +++ b/web/core/modules/editor/tests/src/Kernel/EditorFileReferenceFilterTest.php @@ -71,44 +71,44 @@ class EditorFileReferenceFilterTest extends KernelTestBase { $uuid_2 = $image_2->uuid(); $cache_tag_2 = ['file:' . $id_2]; - $this->pass('No data-entity-type and no data-entity-uuid attribute.'); + // No data-entity-type and no data-entity-uuid attribute. $input = ''; $output = $test($input); $this->assertIdentical($input, $output->getProcessedText()); - $this->pass('A non-file data-entity-type attribute value.'); + // A non-file data-entity-type attribute value. $input = ''; $output = $test($input); $this->assertIdentical($input, $output->getProcessedText()); - $this->pass('One data-entity-uuid attribute.'); + // One data-entity-uuid attribute. $input = ''; $expected_output = ''; $output = $test($input); $this->assertIdentical($expected_output, $output->getProcessedText()); $this->assertEqual($cache_tag, $output->getCacheTags()); - $this->pass('One data-entity-uuid attribute with odd capitalization.'); + // One data-entity-uuid attribute with odd capitalization. $input = ''; $expected_output = ''; $output = $test($input); $this->assertIdentical($expected_output, $output->getProcessedText()); $this->assertEqual($cache_tag, $output->getCacheTags()); - $this->pass('One data-entity-uuid attribute on a non-image tag.'); + // One data-entity-uuid attribute on a non-image tag. $input = '
', + 'filter_html_help' => FALSE, + 'filter_html_nofollow' => FALSE, + ], + ]); foreach ($xpath->query('//*[@data-caption]') as $node) { // Read the data-caption attribute's value, then delete it. $caption = Html::escape($node->getAttribute('data-caption')); @@ -39,10 +84,19 @@ class FilterCaption extends FilterBase { // Sanitize caption: decode HTML encoding, limit allowed HTML tags; only // allow inline tags that are allowed by default, plus
. $caption = Html::decodeEntities($caption); - $caption = FilteredMarkup::create(Xss::filter($caption, ['a', 'em', 'strong', 'cite', 'code', 'br'])); + $raw_caption = $caption; + $filtered_caption = $html_filter->process($caption, $langcode); + $result->addCacheableDependency($filtered_caption); + $caption = FilteredMarkup::create($filtered_caption->getProcessedText()); - // The caption must be non-empty. - if (mb_strlen($caption) === 0) { + // The caption must be non-empty - however the Media Embed CKEditor + // plugin uses a single space to represent a newly added caption. The + // HTML filter will transform this into an empty string and prevent the + // content editor from adding a new caption. To allow for this we treat + // a raw caption value of ' ' as valid and adding the wrapping figure + // element. + // @see core/modules/media/js/plugins/drupalmedia/plugin.es6.js + if (mb_strlen($caption) === 0 && $raw_caption !== ' ') { continue; } diff --git a/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php b/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php index 86b8bbde..9c1c9c2a 100644 --- a/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php +++ b/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php @@ -113,7 +113,7 @@ class FilterHtml extends FilterBase { $xpath = new \DOMXPath($html_dom); foreach ($restrictions['allowed'] as $allowed_tag => $tag_attributes) { // By default, no attributes are allowed for a tag, but due to the - // globally whitelisted attributes, it is impossible for a tag to actually + // globally allowed attributes, it is impossible for a tag to actually // completely disallow attributes. if ($tag_attributes === FALSE) { $tag_attributes = []; @@ -149,23 +149,23 @@ class FilterHtml extends FilterBase { } /** - * Filter attributes on an element by name and value according to a whitelist. + * Filters attributes on an element according to a list of allowed values. * * @param \DOMElement $element * The element to be processed. * @param array $allowed_attributes - * The attributes whitelist as an array of names and values. + * The list of allowed attributes as an array of names and values. */ protected function filterElementAttributes(\DOMElement $element, array $allowed_attributes) { $modified_attributes = []; foreach ($element->attributes as $name => $attribute) { - // Remove attributes not in the whitelist. + // Remove attributes not in the list of allowed attributes. $allowed_value = $this->findAllowedValue($allowed_attributes, $name); if (empty($allowed_value)) { $modified_attributes[$name] = FALSE; } elseif ($allowed_value !== TRUE) { - // Check the attribute values whitelist. + // Check the list of allowed attribute values. $attribute_values = preg_split('/\s+/', $attribute->value, -1, PREG_SPLIT_NO_EMPTY); $modified_attributes[$name] = []; foreach ($attribute_values as $value) { @@ -247,8 +247,8 @@ class FilterHtml extends FilterBase { return $this->restrictions; } - // Parse the allowed HTML setting, and gradually make the whitelist more - // specific. + // Parse the allowed HTML setting, and gradually make the list of allowed + // tags more specific. $restrictions = ['allowed' => []]; // Make all the tags self-closing, so they will be parsed into direct @@ -283,7 +283,7 @@ class FilterHtml extends FilterBase { // but one allowed attribute value that some may be tempted to use // is specifically nonsensical: the asterisk. A prefix is required for // allowed attribute values with a wildcard. A wildcard by itself - // would mean whitelisting all possible attribute values. But in that + // would mean allowing all possible attribute values. But in that // case, one would not specify an attribute value at all. $allowed_attribute_values = array_filter($allowed_attribute_values, function ($value) use ($star_protector) { return $value !== '*'; @@ -311,14 +311,14 @@ class FilterHtml extends FilterBase { // The 'style' and 'on*' ('onClick' etc.) attributes are always forbidden, // and are removed by Xss::filter(). // The 'lang', and 'dir' attributes apply to all elements and are always - // allowed. The value whitelist for the 'dir' attribute is enforced by - // self::filterAttributes(). Note that those two attributes are in the + // allowed. The list of allowed values for the 'dir' attribute is enforced + // by self::filterAttributes(). Note that those two attributes are in the // short list of globally usable attributes in HTML5. They are always // allowed since the correct values of lang and dir may only be known to // the content author. Of the other global attributes, they are not usually // added by hand to content, and especially the class attribute can have // undesired visual effects by allowing content authors to apply any - // available style, so specific values should be explicitly whitelisted. + // available style, so specific values should be explicitly allowed. // @see http://www.w3.org/TR/html5/dom.html#global-attributes $restrictions['allowed']['*'] = [ 'style' => FALSE, diff --git a/web/core/modules/filter/src/Plugin/migrate/process/FilterID.php b/web/core/modules/filter/src/Plugin/migrate/process/FilterID.php index 8358cd62..a58bea03 100644 --- a/web/core/modules/filter/src/Plugin/migrate/process/FilterID.php +++ b/web/core/modules/filter/src/Plugin/migrate/process/FilterID.php @@ -234,7 +234,7 @@ class FilterID extends StaticMap implements ContainerFactoryPluginInterface { return FilterInterface::TYPE_HTML_RESTRICTOR; // https://www.drupal.org/project/entity_embed - case 'emtity_embed': + case 'entity_embed': return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE; case 'filter_align': diff --git a/web/core/modules/filter/tests/src/Functional/FilterFormTest.php b/web/core/modules/filter/tests/src/Functional/FilterFormTest.php index 3eb5ae3f..22bc6d7f 100644 --- a/web/core/modules/filter/tests/src/Functional/FilterFormTest.php +++ b/web/core/modules/filter/tests/src/Functional/FilterFormTest.php @@ -207,10 +207,6 @@ class FilterFormTest extends BrowserTestBase { foreach ($found_options as $found_key => $found_option) { $expected_key = array_search($found_option->getValue(), $expected_options); if ($expected_key !== FALSE) { - $this->pass(new FormattableMarkup('Option @option for field @id exists.', [ - '@option' => $expected_options[$expected_key], - '@id' => $id, - ])); unset($found_options[$found_key]); unset($expected_options[$expected_key]); } diff --git a/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php b/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php index 5c2ea33a..a0637e38 100644 --- a/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php +++ b/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php @@ -404,8 +404,8 @@ class FilterKernelTest extends KernelTestBase { * @todo It is possible to add script, iframe etc. to allowed tags, but this * makes HTML filter completely ineffective. * - * @todo Class, id, name and xmlns should be added to disallowed attributes, - * or better a whitelist approach should be used for that too. + * @todo Class, id, name and xmlns should be added to the list of forbidden + * attributes, or, better yet, use an allowed attribute list. */ public function testHtmlFilter() { // Get FilterHtml object. @@ -460,11 +460,11 @@ class FilterKernelTest extends KernelTestBase { $f = (string) $filter->process('
', Language::LANGCODE_NOT_SPECIFIED); $this->assertNormalized($f, '
', 'HTML filter should allow self-closing line breaks.'); - // All attributes of whitelisted tags are stripped by default. + // All attributes of allowed tags are stripped by default. $f = (string) $filter->process('
link', Language::LANGCODE_NOT_SPECIFIED); $this->assertNormalized($f, 'link', 'HTML filter should remove attributes that are not explicitly allowed.'); - // Now whitelist the "llama" attribute on . + // Now allow the "llama" attribute on . $filter->setConfiguration([ 'settings' => [ 'allowed_html' => '