Skip to content
Snippets Groups Projects
Commit 01d2ac85 authored by jurgenhaas's avatar jurgenhaas
Browse files

drupal-config#2 Move default config and patches to the new...

drupal-config#2 Move default config and patches to the new project composer/plugin/drupal-config
parent 412609f7
No related branches found
No related tags found
1 merge request!382Merging develop into main
Pipeline #1383945 passed
Showing
with 0 additions and 2592 deletions
{
"preferred-install": {
"*": "dist"
},
"sort-packages": true,
"discard-changes": true,
"gitlab-domains": [
"gitlab.lakedrops.com"
],
"allow-plugins": {
"composer/installers": true,
"cweagans/composer-patches": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"drupal/core-composer-scaffold": true,
"drupal/core-vendor-hardening": true,
"endroid/installer": true,
"lakedrops/*": true,
"mxr576/ddqg-composer-audit": true,
"oomphinc/composer-installers-extender": true,
"php-http/discovery": true,
"phpstan/extension-installer": true,
"zodiacmedia/drupal-libraries-installer": true
}
}
[
"DDQG-deprecated-drupal-variationcache-1.5.0.0",
"DDQG-unsupported-drupal-activitypub-1.0.0.0-alpha19",
"DDQG-unsupported-drupal-advanced_cors-1.5.0.0",
"DDQG-unsupported-drupal-analog_digital_clock-10.1.2.0",
"DDQG-unsupported-drupal-apitools-2.0.0.0-alpha3",
"DDQG-unsupported-drupal-blazy-2.16.0.0",
"DDQG-unsupported-drupal-blazy-2.27.0.0",
"DDQG-unsupported-drupal-block_field-1.0.0.0-RC5",
"DDQG-unsupported-drupal-book-2.0.0.0-alpha5",
"DDQG-unsupported-drupal-commerce_xquantity-2.0.0.0-beta1",
"DDQG-unsupported-drupal-conditional_fields-4.0.0.0-alpha6",
"DDQG-unsupported-drupal-config_update-2.0.0.0-alpha4",
"DDQG-unsupported-drupal-content_access-2.0.0.0",
"DDQG-unsupported-drupal-core-10.4.9999999.9999999-dev",
"DDQG-unsupported-drupal-default_content-2.0.0.0-alpha2",
"DDQG-unsupported-drupal-eca-2.1.0.0-RC1",
"DDQG-unsupported-drupal-elasticsearch_connector-8.0.0.0-alpha2",
"DDQG-unsupported-drupal-entitygroupfield-1.0.0.0-beta1",
"DDQG-unsupported-drupal-entity_import-0.0.0.0-dev",
"DDQG-unsupported-drupal-facets-3.0.0.0-beta4",
"DDQG-unsupported-drupal-feeds-3.0.0.0-beta5",
"DDQG-unsupported-drupal-flag-4.0.0.0-beta4",
"DDQG-unsupported-drupal-hacked-2.0.0.0-beta5",
"DDQG-unsupported-drupal-hide_submit_d8-0.0.0.0-dev",
"DDQG-unsupported-drupal-ief_popup-2.2.2.0",
"DDQG-unsupported-drupal-inline_entity_form-3.0.0.0-RC20",
"DDQG-unsupported-drupal-invoice_ninja-1.0.0.0-beta7",
"DDQG-unsupported-drupal-layout_library-1.0.0.0-beta4",
"DDQG-unsupported-drupal-matomo-2.0.0.0-alpha1",
"DDQG-unsupported-drupal-media_entity_link-2.0.1.0",
"DDQG-unsupported-drupal-menu_breadcrumb-2.0.0.0-alpha0",
"DDQG-unsupported-drupal-name-1.0.0.0-RC6",
"DDQG-unsupported-drupal-navigation_extra_tools-1.0.0.0-beta4",
"DDQG-unsupported-drupal-office_hours-0.0.0.0-dev",
"DDQG-unsupported-drupal-openai-1.0.0.0-beta6",
"DDQG-unsupported-drupal-openid_connect-3.0.0.0-alpha4",
"DDQG-unsupported-drupal-peertube-2.0.0.0-beta2",
"DDQG-unsupported-drupal-phone_number-2.0.0.0-alpha7",
"DDQG-unsupported-drupal-project_browser-2.0.0.0-alpha5",
"DDQG-unsupported-drupal-reader-1.0.0.0-beta2",
"DDQG-unsupported-drupal-readmehelp-2.0.0.0-beta1",
"DDQG-unsupported-drupal-schema_diff-1.0.0.0-alpha2",
"DDQG-unsupported-drupal-services-5.0.0.0-beta10",
"DDQG-unsupported-drupal-shs-2.0.0.0-RC12",
"DDQG-unsupported-drupal-simple_oauth-6.0.0.0-beta8",
"DDQG-unsupported-drupal-slick-2.9.0.0",
"DDQG-unsupported-drupal-slick-2.11.0.0",
"DDQG-unsupported-drupal-slick_views-2.7.0.0",
"DDQG-unsupported-drupal-slick_views-2.8.0.0",
"DDQG-unsupported-drupal-tamper-1.0.0.0-alpha5",
"DDQG-unsupported-drupal-term_merge-2.0.0.0-beta6",
"DDQG-unsupported-drupal-term_reference_change-2.0.0.0-beta5",
"DDQG-unsupported-drupal-toolbar_language_switcher-2.0.0.0-alpha2",
"DDQG-unsupported-drupal-viewfield-3.0.0.0-beta11",
"DDQG-unsupported-drupal-viewsreference-2.0.0.0-beta10",
"DDQG-unsupported-drupal-views_base_url-2.1.0.0-beta1",
"DDQG-unsupported-drupal-views_field_view-1.0.0.0-beta5",
"DDQG-unsupported-drupal-views_menu_children_filter-3.0.0.0-RC4",
"DDQG-unsupported-drupal-views_tree-2.0.0.0-RC1",
"DDQG-unsupported-drupal-xls_serialization-0.0.0.0-dev",
"DDQG-unsupported-drupal-xnumber-2.0.0.0-beta2",
"GHSA-mg8j-w93w-xjgc"
]
{
"blazy": "https://github.com/dinbror/blazy/archive/1.8.2.zip",
"codemirror": "https://github.com/components/codemirror/archive/refs/tags/5.65.12.zip",
"colorbox": "https://github.com/jackmoore/colorbox/archive/refs/tags/1.6.4.zip",
"dompurify": "https://github.com/cure53/DOMPurify/archive/refs/tags/3.0.9.zip",
"dropzone": "https://github.com/dropzone/dropzone/releases/download/v5.9.3/dist.zip",
"imagesloaded": "https://api.github.com/repos/desandro/imagesloaded/zipball/67c4e57453120935180c45c6820e7d3fbd2ea1f9",
"fontawesome": "https://use.fontawesome.com/releases/v6.5.1/fontawesome-free-6.5.1-web.zip",
"friendly-challenge": "https://registry.npmjs.org/friendly-challenge/-/friendly-challenge-0.9.16.tgz",
"fullcalendar": "https://github.com/fullcalendar/fullcalendar-workspace/releases/download/v6.1.11/fullcalendar-scheduler-6.1.11.zip",
"jquery.chosen": "https://github.com/harvesthq/chosen/releases/download/v1.8.7/chosen_v1.8.7.zip",
"jquery.geocomplete": "https://github.com/ubilabs/geocomplete/archive/refs/tags/1.7.0.zip",
"jquery.hotkeys": "https://github.com/jeresig/jquery.hotkeys/archive/refs/tags/0.2.0.zip",
"jquery.icheck": "https://github.com/drgullin/icheck/archive/refs/heads/1.0.3.zip",
"jquery.image-picker": "https://github.com/rvera/image-picker/archive/refs/tags/0.3.1.zip",
"jquery.inputmask": "https://github.com/RobinHerbots/jquery.inputmask/archive/refs/tags/5.0.8.zip",
"jquery.intl-tel-input": "https://github.com/jackocnr/intl-tel-input/archive/refs/tags/v17.0.19.zip",
"jquery.rateit": "https://github.com/gjunge/rateit.js/archive/refs/tags/1.1.5.zip",
"jquery.select2": "https://github.com/select2/select2/archive/refs/tags/4.0.13.zip",
"jquery-simple-color": "https://github.com/recurser/jquery-simple-color/archive/refs/tags/v1.2.3.tar.gz",
"jquery.textcounter": "https://github.com/ractoon/jQuery-Text-Counter/archive/refs/tags/0.9.1.zip",
"jquery.timepicker": "https://github.com/jonthornton/jquery-timepicker/archive/refs/tags/1.14.0.zip",
"jquery.toggles": "https://github.com/simontabor/jquery-toggles/archive/refs/tags/v4.0.0.zip",
"masonry": "https://api.github.com/repos/desandro/masonry/zipball/3b0883cf4a4a046896719b9cf282ea74be7ffecd",
"popperjs": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
"progress-tracker": "https://github.com/NigelOToole/progress-tracker/archive/refs/tags/2.0.7.zip",
"select2": "https://github.com/select2/select2/archive/4.0.13.zip",
"signature_pad": "https://github.com/szimek/signature_pad/archive/refs/tags/v2.3.0.zip",
"slick": "https://github.com/kenwheeler/slick/archive/1.8.0.zip",
"slide-element": "https://github.com/alexmacarthur/slide-element/archive/refs/tags/v2.3.1.zip",
"spectrum": "https://github.com/bgrins/spectrum/archive/refs/tags/1.8.0.tar.gz",
"svg-pan-zoom": "https://github.com/ariutta/svg-pan-zoom/archive/refs/tags/3.6.1.zip",
"tabby": "https://github.com/cferdinandi/tabby/archive/refs/tags/v12.0.3.zip",
"tippyjs": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz"
}
{
"locations": {
"web-root": "./web"
},
"file-mapping": {
"[project-root]/.editorconfig": false,
"[project-root]/.gitattributes": false,
"[web-root]/example.gitignore": false,
"[web-root]/INSTALL.txt": false,
"[web-root]/README.txt": false,
"[web-root]/sites/README.txt": false,
"[web-root]/sites/development.services.yml": false,
"[web-root]/sites/example.settings.local.php": false,
"[web-root]/sites/example.sites.php": false,
"[web-root]/sites/default/default.services.yml": false,
"[web-root]/sites/default/default.settings.php": false,
"[web-root]/modules/README.txt": false,
"[web-root]/profiles/README.txt": false,
"[web-root]/themes/README.txt": false
}
}
{
"tests/{$name}": [
"type:lakedrops-tests"
]
}
[
"lakedrops-tests"
]
diff --git a/architect.info.yml b/architect.info.yml
index 58e1fc9..0c0b8ce 100644
--- a/architect.info.yml
+++ b/architect.info.yml
@@ -1,8 +1,7 @@
name: Architect
type: theme
description: the ARCHITECT Theme - A DESIGN SAVVY THEME USING UIKITTY.
-# core: 8.x
-core_version_requirement: ^8.8 || ^9
+core_version_requirement: ^10 || ^11
base theme: uikitty
libraries:
- architect/default
diff --git a/scss/components/sidebar.scss b/scss/components/sidebar.scss
index c5ab44c..61121c4 100644
--- a/scss/components/sidebar.scss
+++ b/scss/components/sidebar.scss
@@ -28,6 +28,6 @@
border-bottom: $border-width solid $border-color;
}
nav ul.nav {
- margin: 0 -($spacer);
+ margin: 0 (-($spacer));
}
}
\ No newline at end of file
diff --git a/css/components/form.css b/css/components/form.css
index 199631a57515d8781757760a508f8a7eb2044b1c..01c4b99980d6d7ebf414136099b79a8e366100b8 100644
--- a/css/components/form.css
+++ b/css/components/form.css
@@ -15,8 +15,8 @@
margin: 0 0.3em;
}
-.form-row>fieldset,
-.form-row>div {
+form .form-row>fieldset,
+form .form-row>div {
padding-right: 5px;
padding-left: 5px;
flex: 0 1 auto;
diff --git a/scss/components/form.scss b/scss/components/form.scss
index 61031d9dbf043267d631ed5c3afe2e02994dfbc7..a0be78538cd56f489d79ceadf520b6b147542131 100644
--- a/scss/components/form.scss
+++ b/scss/components/form.scss
@@ -7,7 +7,7 @@
content: '';
vertical-align: super;
display: inline-block;
- background-image: url(../images/required.svg);
+ background-image: url(#{$barrio_path_images}required.svg);
background-repeat: no-repeat;
background-size: ($input-height / 2) ($input-height / 2);
width: ($input-height / 2);
@@ -15,13 +15,15 @@
margin: 0 0.3em;
}
-.form-row>fieldset,
-.form-row>div {
- padding-right: 5px;
- padding-left: 5px;
- flex: 0 1 auto;
- width: auto;
- max-width: none;
+form {
+ .form-row>fieldset,
+ .form-row>div {
+ padding-right: 5px;
+ padding-left: 5px;
+ flex: 0 1 auto;
+ width: auto;
+ max-width: none;
+ }
}
.row .form-actions {
@@ -37,4 +39,4 @@ form .filter-wrapper {
form .form-type-textarea {
margin-bottom: 0;
-}
\ No newline at end of file
+}
diff --git a/scss/barrio.scss b/scss/barrio.scss
index 1d2ea1ac16e7d255c3095df33961ae249de77d64..3d02566aeceb4ca8555de674d039a8cc0ba86cef 100644
--- a/scss/barrio.scss
+++ b/scss/barrio.scss
@@ -1,3 +1,5 @@
+$barrio_path_images: "../../images/" !default;
+
@import "./components/mixins";
@import "./components/affix";
@import "./components/alerts";
@@ -43,4 +45,4 @@
@import "./components/vertical-tabs.component";
@import "./components/vertical-tabs";
@import "./components/views";
-@import "./components/webform";
\ No newline at end of file
+@import "./components/webform";
diff --git a/scss/components/file.scss b/scss/components/file.scss
index fe3500d53450aa0d7576901b12e8c2c346e8208b..ae14d9613953706d719cd865d181a892f35af11b 100644
--- a/scss/components/file.scss
+++ b/scss/components/file.scss
@@ -24,57 +24,57 @@
.file--general,
.file--application-octet-stream {
- background-image: url(../images/icons/application-octet-stream.png);
+ background-image: url(#{$barrio_path_images}icons/application-octet-stream.png);
}
.file--package-x-generic {
- background-image: url(../images/icons/package-x-generic.png);
+ background-image: url(#{$barrio_path_images}icons/package-x-generic.png);
}
.file--x-office-spreadsheet {
- background-image: url(../images/icons/x-office-spreadsheet.png);
+ background-image: url(#{$barrio_path_images}icons/x-office-spreadsheet.png);
}
.file--x-office-document {
- background-image: url(../images/icons/x-office-document.png);
+ background-image: url(#{$barrio_path_images}icons/x-office-document.png);
}
.file--x-office-presentation {
- background-image: url(../images/icons/x-office-presentation.png);
+ background-image: url(#{$barrio_path_images}icons/x-office-presentation.png);
}
.file--text-x-script {
- background-image: url(../images/icons/text-x-script.png);
+ background-image: url(#{$barrio_path_images}icons/text-x-script.png);
}
.file--text-html {
- background-image: url(../images/icons/text-html.png);
+ background-image: url(#{$barrio_path_images}icons/text-html.png);
}
.file--text-plain {
- background-image: url(../images/icons/text-plain.png);
+ background-image: url(#{$barrio_path_images}icons/text-plain.png);
}
.file--application-pdf {
- background-image: url(../images/icons/application-pdf.png);
+ background-image: url(#{$barrio_path_images}icons/application-pdf.png);
}
.file--application-x-executable {
- background-image: url(../images/icons/application-x-executable.png);
+ background-image: url(#{$barrio_path_images}icons/application-x-executable.png);
}
.file--audio {
- background-image: url(../images/icons/audio-x-generic.png);
+ background-image: url(#{$barrio_path_images}icons/audio-x-generic.png);
}
.file--video {
- background-image: url(../images/icons/video-x-generic.png);
+ background-image: url(#{$barrio_path_images}icons/video-x-generic.png);
}
.file--text {
- background-image: url(../images/icons/text-x-generic.png);
+ background-image: url(#{$barrio_path_images}icons/text-x-generic.png);
}
.file--image {
- background-image: url(../images/icons/image-x-generic.png);
-}
\ No newline at end of file
+ background-image: url(#{$barrio_path_images}icons/image-x-generic.png);
+}
diff --git a/scss/components/webform.scss b/scss/components/webform.scss
index 8d5c308e43fba1d0771d6ccc91da836fb3b3a9c5..905c5f2458cb761a0334bfdea5d1068ae181b645 100644
--- a/scss/components/webform.scss
+++ b/scss/components/webform.scss
@@ -9,7 +9,7 @@
content: '';
vertical-align: super;
display: inline-block;
- background-image: url(../../../contrib/bootstrap_barrio/images/required.svg);
+ background-image: url(#{$barrio_path_images}required.svg);
background-repeat: no-repeat;
background-size: 7px 7px;
width: 7px;
@@ -50,4 +50,4 @@
padding: 0;
}
}
-}
\ No newline at end of file
+}
Index: src/PhpSpreadsheet/Writer/Csv.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/PhpSpreadsheet/Writer/Csv.php (date 1563359827000)
+++ src/PhpSpreadsheet/Writer/Csv.php (date 1563359827000)
@@ -120,7 +120,7 @@
// Write rows to file
for ($row = 1; $row <= $maxRow; ++$row) {
// Convert the row to an array...
- $cellsArray = $sheet->rangeToArray('A' . $row . ':' . $maxCol . $row, '', $this->preCalculateFormulas);
+ $cellsArray = $sheet->rangeToArray('D' . $row . ':' . $maxCol . $row, '', $this->preCalculateFormulas);
// ... and write to the file
$this->writeLine($fileHandle, $cellsArray[0]);
}
This diff is collapsed.
This diff is collapsed.
{
"patches": {
"drupal/architect": {
"#3137889 Drupal 9": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3137889.diff",
"#local Drupal 10": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/architect-d10.patch"
},
"drupal/background_image": {
"#3161262 Pre render fix": "https://www.drupal.org/files/issues/2020-07-24/implement_trustedcallbackinterface.patch",
"#3170843 Dom Ready": "https://www.drupal.org/files/issues/2020-09-14/3170843-2.background_image.Library-drupaldomready-does-not-exist-in-Drupal-9.patch",
"#3173283 Cache": "https://www.drupal.org/files/issues/2020-09-26/3173283-2.background_image.Cache-context-also-requires-URL.patch",
"#3173340 Exception": "https://www.drupal.org/files/issues/2020-09-26/3173340-2.background_image.Error-Call-to-a-member-function-hasEntityToken-on-bool-in-DrupalbackgroundimageCacheContextBackgroundImageSettingsTextCacheContextgetContext.patch",
"#3128542 FileScan": "https://www.drupal.org/files/issues/2020-09-11/background_image-missing_folder-3128542-8.patch"
},
"drupal/bootstrap_clean_blog": {
"#3146287 Drupal 9": "https://www.drupal.org/files/issues/2021-10-23/3146287_3.patch"
},
"drupal/book": {
"#2918537 Save unpublished versions of published content without manage book privileges": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/2918537.diff",
"#3090234 Broken node theming for book export": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3090234.patch"
},
"drupal/ckeditor_find": {
"#3252081 Library location": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3252081.diff"
},
"drupal/codesnippet": {
"#3021431 Add Yaml as code format": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3021431.diff"
},
"drupal/comment_notify": {
"#2926228 Always notify admin": "https://www.drupal.org/files/issues/2019-09-11/2926228-11.comment_notify.Optionally-notify-site-admin-of-all-comments.patch"
},
"drupal/commerce_xquantity": {
"#3404050 Exceptions in actions of xquantity_stock": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3404050-2.diff"
},
"drupal/config_devel": {
"#3219083 Export raw data": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3219083.diff",
"#3227881 Support config_rewrite": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3227881.diff?v=2"
},
"drupal/config_sync": {
"#3176955 Drupal 9 test compatibility": "https://www.drupal.org/files/issues/2021-03-19/config_sync-config-sync-test-core-3176955-4.patch"
},
"drupal/config_update": {
"#3436790 Module weight": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3436790.diff?v=2",
"#3056249 Core hash for localisation": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3056249.diff"
},
"drupal/content_lock": {
"#2951652 No content lock für CLI commands": "https://www.drupal.org/files/issues/2022-04-05/2951652-13.patch",
"#3160781 Release lock when browsing away from locked form": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3160781-2.diff"
},
"drupal/core_for_review": {
"#3227732 Book hierarchy migration": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3227732.diff"
},
"drupal/core": {
"#local Hot fix timezoone": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/timezone.patch",
"#2647292 Date/time Views filter tries strotime() relative to Unix epoch": "https://www.drupal.org/files/issues/2022-02-10/with-dependency-injection-2647292-67.patch",
"#2884879 Ignore empty fields for REST export": "https://www.drupal.org/files/issues/2884879-11.patch",
"#2966735 Workaround for DateTime exposed filter": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/2966735.diff",
"#3043879 Layout Builder Config": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3043879.diff",
"#3195171 Fix view header group rendering": "https://www.drupal.org/files/issues/2022-01-05/3195171-7-fix-view-header-group-rendering.patch",
"#3180227 Missing options for entity refernces in views": "https://www.drupal.org/files/issues/2020-11-02/3180227-2.patch",
"#local Json API and entity reference warnings": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/jsonapi-entityref-warning.patch?v=3",
"#3228298 Empty path alias exception": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3228298.diff?v=2",
"#3227816 Hide password reset link": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3227816.diff",
"#3249628 Comments and paragraphs": "https://www.drupal.org/files/issues/2022-12-11/1415-11.diff",
"#2840283 Views action path with EVA": "https://www.drupal.org/files/issues/problem_with_action-2840283-25.patch",
"#2816447 RSS feed titles wrong language": "https://www.drupal.org/files/issues/2023-08-03/2816447-58.patch",
"#2915705 TypedData any": "https://www.drupal.org/files/issues/2022-12-11/2915705-82.patch",
"#3302450 Views field default type": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3302450.diff",
"#3311849 Views exposed filter, empty sections": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3311849.diff",
"#2797583 Actions for content moderation": "https://www.drupal.org/files/issues/2022-09-20/core-provide-moderation-states-as-actions-2797583-207.patch",
"#2918537 Save unpublished versions of published content without manage book privileges": "https://www.drupal.org/files/issues/2022-12-14/2918537-92.patch",
"#3047110 Taxonomy moderation": "https://www.drupal.org/files/issues/2021-07-23/3047110-32.patch",
"#3194462 Big pipe explode issue": "https://www.drupal.org/files/issues/2023-02-28/3194462-30.patch",
"#3090234 Broken node theming for book export": "https://www.drupal.org/files/issues/2020-10-06/3090234-9.patch",
"#3346430 DoPreSave load revision": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3346430.diff",
"#3340973 Media Lib type error on array_filter": "https://www.drupal.org/files/issues/2023-02-10/fix_media_library_php_error-3340973-2.patch",
"#3073822 Error: Call to a member function access() on null in Drupal\\comment\\CommentAccessControlHandler->checkAccess()": "https://www.drupal.org/files/issues/2023-01-12/3073822-12.patch",
"#2761273 Exposed filter values as token": "https://www.drupal.org/files/issues/2022-10-30/2761273-50.patch",
"#2955321 Non-translatable fields": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/2955321.diff",
"#3420862 Empty comment body": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3420862.diff",
"#3413508 Admin page access": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3413508.diff",
"#3053757 Filter for allowed moderation transitions": "https://www.drupal.org/files/issues/2024-03-12/content-moderation-user-filter-3053757-24.patch",
"#944582 File System Permissions": "https://www.drupal.org/files/issues/2024-01-16/944582-10.2.x-192.patch"
},
"drupal/dashboards": {
"#3366586 Shortcut error": "https://git.drupalcode.org/project/dashboards/-/merge_requests/26.diff"
},
"drupal/diff": {
"#3311234 Link to diff with prev rev": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3311234.diff?v=3",
"#3311372 Configure date format": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3311372.diff?v=2",
"#3360589 Form validation": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3360589.diff?v=4"
},
"drupal/dynamic_entity_reference": {
"#3099176 Errors when new entity types are added": "https://www.drupal.org/files/issues/2023-09-08/3099176-3.x-16.diff"
},
"drupal/eca": {
"#3352393 Condition list contains": "https://git.drupalcode.org/project/eca/-/merge_requests/349.diff",
"#3368530 eca_log tokens": "https://git.drupalcode.org/project/eca/-/merge_requests/370.diff",
"#3373537 Plain token replacement": "https://git.drupalcode.org/project/eca/-/merge_requests/375.diff",
"#3351738 Views argument default plugin": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/eca_views_argument.patch",
"#3396915 Improve #3368530 to cleanup context": "https://www.drupal.org/files/issues/2023-10-26/3396915-2.diff"
},
"drupal/elasticsearch_connector": {
"#2952301 Flatten keys": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/elasticsearch_connector.patch"
},
"drupal/entity_import": {
"#3061935 Make it work without content_translation": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3061935.diff"
},
"drupal/entity_share": {
"#3306745 File Share overrides the name of media entity": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3306745.diff",
"#3347453 VBO Dependency": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3347453.diff"
},
"drupal/entitygroupfield": {
"#3228312 Group load fails": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3228312.diff"
},
"drupal/fakeobjects": {
"#3208959 Library path": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3208959.diff"
},
"drupal/field_group": {
"#2858336 Token support": "https://www.drupal.org/files/issues/2019-01-15/field_group-tokens_in_classes-2858336-16.patch"
},
"drupal/flag": {
"#3238783 Fix flag action": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3238783.diff",
"#2500091 Activate token support": "https://www.drupal.org/files/issues/2022-12-30/flag_hook-tokens_2500091-43.patch"
},
"drupal/fullcalendar_view": {
"#3392567 Fix href": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3392567.diff",
"#3084395 Daterange basefield": "https://www.drupal.org/files/issues/2022-03-25/3084395-11.patch"
},
"drupal/gin_toolbar": {
"#3319445 Permission check": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3319445.diff"
},
"drupal/glossify": {
"#3360633 HTML entities": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3360633.diff"
},
"drupal/http_client_manager": {
"#3385117 Code generator": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3385117.diff"
},
"drupal/inline_entity_form": {
"#3204051 Check access": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3204051.diff?v=4"
},
"drupal/layout_library": {
"#3041543 Layout per display mode": "https://www.drupal.org/files/issues/2020-08-17/3041543-4.layout_library.Allow-created-layouts-to-be-limited-to-and-set-for-specific-view-modes.patch"
},
"drupal/ldap": {
"#3227813 Hide password field": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3227813.diff"
},
"drupal/linkchecker": {
"#3376854 Base path": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3376854.diff",
"#3313343 Disable cron": "https://www.drupal.org/files/issues/2022-10-03/support_disabling_cron-3313343-2.patch"
},
"drupal/menu_block": {
"#3082445 Add option to always render parent menu item": "https://www.drupal.org/files/issues/2020-10-12/menu_block-render-parent-3082445-26.patch"
},
"drupal/pluginreference": {
"#2979414 Allow no selection": "https://www.drupal.org/files/issues/2018-07-18/pluginreference-allow_no_plugin_to_be_selected-2979414-2.patch"
},
"drupal/profile": {
"#2899744 Multi-lingual": "https://www.drupal.org/files/issues/2022-04-17/2899744-54.patch"
},
"drupal/recaptcha": {
"#3113837 Downgrade unknown error": "https://www.drupal.org/files/issues/2020-02-15/3113837-2.recaptcha.Downgrade-unknown-error-info.patch"
},
"drupal/role_theme_switcher": {
"#3414975 Missing keys": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3414975.diff"
},
"drupal/select2": {
"#3211796 Z-Index in modal dialog": "https://www.drupal.org/files/issues/2023-04-18/select2-modal-zindex-mult-form-elem-fix-3211796-17.patch"
},
"drupal/simple_menu_icons": {
"#3379128 Do not delete all": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3379128.diff",
"#3404501 Set version and license": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3404501.diff"
},
"drupal/smart_login": {
"#2831386 Error 403 redirect": "https://www.drupal.org/files/issues/this_is_silently-2831386-2.patch",
"#2709529 Redirect after login": "https://www.drupal.org/files/issues/redirect_to_page_of-2709529-2.patch",
"#2901154 Properly handle destination": "https://www.drupal.org/files/issues/setting_form_redirect-2901154-2.patch"
},
"drupal/smtp": {
"#3252427 Add tokens": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3252427.diff"
},
"drupal/social_link_field": {
"#3241310 Add more channels": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3241310.diff"
},
"drupal/social_profile_field": {
"#3242595 Drupal 9": "https://www.drupal.org/files/issues/2021-10-11/3242595-3.patch",
"#2724653 Langparam": "https://www.drupal.org/files/issues/social_profile_field-fix-warnings-in-formatter-1.patch",
"#2799907 Alter icon path": "https://www.drupal.org/files/issues/allow_for_different-2799907-2.patch"
},
"drupal/svg_image_field": {
"#3090673 URL field formatter": "https://www.drupal.org/files/issues/2019-10-29/3090673-2.svg_image_field.Add-support-for-a-URL-image-formatter.patch"
},
"drupal/tamper": {
"#3279973 WordCount plugin": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3279973.diff",
"#3268276 Timezone plugin": "https://www.drupal.org/files/issues/2023-04-06/0001-Issue-3268276-Reworking-timezones.patch"
},
"drupal/taxonomy_machine_name": {
"#3193233 Filter doesn't work": "https://www.drupal.org/files/issues/2021-01-17/taxonomy_machine_name-view-save-error-3193233.patch",
"#3128397 View can not be saved": "https://www.drupal.org/files/issues/2020-04-16/config_schema-3128397-3.patch",
"#3352586 Parameter to disable machine name in terms overview ": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3352586-2.diff"
},
"drupal/title": {
"#3172331 D9 compatibility": "https://www.drupal.org/files/issues/2021-08-24/D9-compatibility_3172331.patch"
},
"drupal/token": {
"#3437013 Referrer tokens": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3437013.diff"
},
"drupal/uikitty": {
"#3149175 Drupal 9": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3149175.diff",
"#local Drupal 10": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/uikitty-d10.patch"
},
"drupal/views_data_export": {
"#3046184 Optional CSV Header (fix missing row on batch run)": "https://www.drupal.org/files/issues/2023-02-09/views_data_export-optional_csv_header-3046184-9.patch"
},
"drupal/video_embed_field": {
"#3238136 Vimeo hash parameter on private video url": "https://www.drupal.org/files/issues/2022-08-23/video_embed_field-vimeo_hash_parameters_private_video-3238136-8.patch"
},
"drupal/views_fieldsets": {
"#3395642 Fieldsets with only images don't display": "https://www.drupal.org/files/issues/2023-10-20/views_fieldset-allow_img.patch"
},
"drupal/views_tree": {
"#3344199 Add event just once": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3344199.diff"
},
"drupal/workflow": {
"#2948377 Do not hide widget when having only one option": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/show-widget-2948377-2.patch"
},
"drupal/wysiwyg_template": {
"#3354588 Drupal 10 compatible": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/d10/3354588.diff"
},
"grahl/ldap": {
"#Local Remove deprecation warnings": "https://gitlab.lakedrops.com/composer/plugin/drupal-environment/-/raw/main/patches/grahl-ldap.patch"
},
"henrywhitaker3/healthchecks-io": {
"#76 Double slashes in URL": "https://patch-diff.githubusercontent.com/raw/henrywhitaker3/PHP-healthchecks.io/pull/77.diff"
},
"phpcollection/phpcollection": {
"#31 PHP 8.1 deprecation": "https://patch-diff.githubusercontent.com/raw/schmittjoh/php-collection/pull/32.diff"
}
}
}
This diff is collapsed.
diff --git a/src/FieldGroupFormatterBase.php b/src/FieldGroupFormatterBase.php
index 5dc4e213e4a8b74379afe871e8f5f03ef2a38104..1f54d0edf7d23bd9fae250540ec541651b16fee3 100644
--- a/src/FieldGroupFormatterBase.php
+++ b/src/FieldGroupFormatterBase.php
@@ -126,6 +126,14 @@ abstract class FieldGroupFormatterBase extends PluginSettingsBase implements Fie
'#element_validate' => [[$class, 'validateCssClass']],
];
+ if (\Drupal::moduleHandler()->moduleExists('token')) {
+ $form['token_help'] = [
+ '#theme' => 'token_tree_link',
+ '#token_types' => [$this->group->entity_type],
+ '#weight' => 12
+ ];
+ $form['classes']['#element_validate'] = [[$class, 'validateCssClassToken']];
+ }
return $form;
}
@@ -222,6 +230,22 @@ abstract class FieldGroupFormatterBase extends PluginSettingsBase implements Fie
return $this->preRender($element, $processed_object);
}
+ /**
+ * Validate the entered css class with token from the submitted format settings.
+ *
+ * @param array $element
+ * The validated element.
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
+ * The state of the form.
+ */
+ public static function validateCssClassToken(array $element, FormStateInterface $form_state) {
+ $form_state_values = $form_state->getValues();
+ $plugin_name = $form_state->get('plugin_settings_edit');
+ if (!empty($form_state_values['fields'][$plugin_name]['settings_edit_form']['settings']['classes']) && !preg_match('![A-Za-z0-9-_ ]*(\[[\w]+:([\w]+:)*[\w]+\])*!', $form_state_values['fields'][$plugin_name]['settings_edit_form']['settings']['classes'])) {
+ $form_state->setError($element, t('The css class must include only letters, numbers, underscores, dashes and token fields.'));
+ }
+ }
+
/**
* Validate the entered css class from the submitted format settings.
*
diff --git a/src/Plugin/field_group/FieldGroupFormatter/HtmlElement.php b/src/Plugin/field_group/FieldGroupFormatter/HtmlElement.php
index 66a11048f5ee2f9fb55a377dabd52b3b9a71d2de..e5a163f82ee066175cd000ef7d16056960c694cc 100644
--- a/src/Plugin/field_group/FieldGroupFormatter/HtmlElement.php
+++ b/src/Plugin/field_group/FieldGroupFormatter/HtmlElement.php
@@ -4,6 +4,7 @@ namespace Drupal\field_group\Plugin\field_group\FieldGroupFormatter;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Xss;
+use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Render\Markup;
use Drupal\Core\Template\Attribute;
@@ -55,6 +56,12 @@ class HtmlElement extends FieldGroupFormatterBase {
// Add the classes to the attributes array.
$classes = $this->getClasses();
+ if (\Drupal::moduleHandler()->moduleExists('token')) {
+ if (isset($processed_object["#{$this->group->entity_type}"])) {
+ $entity = $processed_object["#{$this->group->entity_type}"];
+ $classes = $this->tokenizeClasses($entity, $classes);
+ }
+ }
if (!empty($classes)) {
if (!isset($element_attributes['class'])) {
$element_attributes['class'] = [];
@@ -259,5 +266,21 @@ class HtmlElement extends FieldGroupFormatterBase {
return $defaults;
}
+
+ /**
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * @param array $classes
+ * @return array
+ */
+ private function tokenizeClasses(EntityInterface $entity, array $classes) {
+ $token = \Drupal::token();
+ $variables = [
+ $entity->getEntityTypeId() => $entity
+ ];
+
+ $classString = implode(' ', $classes);
+ $tokenizedClasses = $token->replace($classString, $variables, ['clear' => TRUE]);
+ return explode(' ', $tokenizedClasses);
+ }
}
diff --git a/core/core.services.yml b/core/core.services.yml
index da5011df77..106db6a337 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -895,7 +895,8 @@ services:
arguments: ['@request_stack']
Drupal\Core\Routing\RouteMatchInterface: '@current_route_match'
event_dispatcher:
- class: Symfony\Component\EventDispatcher\EventDispatcher
+ class: Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
+ arguments: ['@service_container']
Psr\EventDispatcher\EventDispatcherInterface: '@event_dispatcher'
Symfony\Contracts\EventDispatcher\EventDispatcherInterface: '@event_dispatcher'
controller_resolver:
diff --git a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
index fd99e0335e..41afec903e 100644
--- a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
+++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
@@ -2,8 +2,6 @@
namespace Drupal\Component\EventDispatcher;
-@trigger_error('The ' . __NAMESPACE__ . '\ContainerAwareEventDispatcher is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use Symfony\Component\EventDispatcher\EventDispatcher instead. See https://www.drupal.org/node/3376090', E_USER_DEPRECATED);
-
use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -32,11 +30,6 @@
* runtime is not affected by this change though.
* </dd>
* </dl>
- *
- * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use
- * \Symfony\Component\EventDispatcher\EventDispatcher instead.
- *
- * @see https://www.drupal.org/node/3376090
*/
class ContainerAwareEventDispatcher implements EventDispatcherInterface {
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 20fd28594a..368692ba7b 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -30,7 +30,6 @@
use Psr\Log\LoggerAwareInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Reference;
-use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
@@ -86,7 +85,7 @@ public function register(ContainerBuilder $container) {
$container->addCompilerPass(new TwigExtensionPass());
// Add a compiler pass for registering event subscribers.
- $container->addCompilerPass(new RegisterEventSubscribersPass(new RegisterListenersPass()), PassConfig::TYPE_AFTER_REMOVING);
+ $container->addCompilerPass(new RegisterEventSubscribersPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new LoggerAwarePass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new RegisterAccessChecksPass());
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php
index 82d1f1614d..0cae61c39f 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php
@@ -4,50 +4,59 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
-use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
- * Wraps the Symfony event subscriber pass to use different tag names.
+ * Registers all event subscribers to the event dispatcher.
*/
class RegisterEventSubscribersPass implements CompilerPassInterface {
- /**
- * Constructs a RegisterEventSubscribersPass object.
- *
- * @param \Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass $pass
- * The Symfony compiler pass that registers event subscribers.
- */
- public function __construct(
- protected RegisterListenersPass $pass,
- ) {}
-
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
- $this->renameTag($container, 'event_subscriber', 'kernel.event_subscriber');
- $this->pass->process($container);
- $this->renameTag($container, 'kernel.event_subscriber', 'event_subscriber');
- }
+ if (!$container->hasDefinition('event_dispatcher')) {
+ return;
+ }
- /**
- * Renames tags in the container.
- *
- * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
- * The container.
- * @param string $source_tag
- * The tag to be renamed.
- * @param string $target_tag
- * The tag to rename with.
- */
- protected function renameTag(ContainerBuilder $container, string $source_tag, string $target_tag): void {
- foreach ($container->getDefinitions() as $definition) {
- if ($definition->hasTag($source_tag)) {
- $attributes = $definition->getTag($source_tag)[0];
- $definition->addTag($target_tag, $attributes);
- $definition->clearTag($source_tag);
+ $definition = $container->getDefinition('event_dispatcher');
+
+ $event_subscriber_info = [];
+ foreach ($container->findTaggedServiceIds('event_subscriber') as $id => $attributes) {
+
+ // We must assume that the class value has been correctly filled, even if
+ // the service is created by a factory.
+ $class = $container->getDefinition($id)->getClass();
+
+ $interface = EventSubscriberInterface::class;
+ if (!is_subclass_of($class, $interface)) {
+ throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
+ }
+
+ // Get all subscribed events.
+ foreach ($class::getSubscribedEvents() as $event_name => $params) {
+ if (is_string($params)) {
+ $priority = 0;
+ $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $params]];
+ }
+ elseif (is_string($params[0])) {
+ $priority = $params[1] ?? 0;
+ $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $params[0]]];
+ }
+ else {
+ foreach ($params as $listener) {
+ $priority = $listener[1] ?? 0;
+ $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $listener[0]]];
+ }
+ }
}
}
+
+ foreach (array_keys($event_subscriber_info) as $event_name) {
+ krsort($event_subscriber_info[$event_name]);
+ }
+
+ $definition->addArgument($event_subscriber_info);
}
}
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
index 63c52f408c..de8ecb220f 100644
--- a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
@@ -4,6 +4,7 @@
namespace Drupal\Tests\layout_builder\Unit;
+use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockManagerInterface;
@@ -23,7 +24,6 @@
use Drupal\layout_builder\SectionComponent;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
-use Symfony\Component\EventDispatcher\EventDispatcher;
/**
* @coversDefaultClass \Drupal\layout_builder\Section
@@ -62,7 +62,7 @@ class SectionRenderTest extends UnitTestCase {
/**
* The event dispatcher.
*
- * @var \Symfony\Component\EventDispatcher\EventDispatcher
+ * @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
*/
protected $eventDispatcher;
@@ -77,7 +77,7 @@ protected function setUp(): void {
$this->contextHandler = $this->prophesize(ContextHandlerInterface::class);
$this->contextRepository = $this->prophesize(ContextRepositoryInterface::class);
// @todo Refactor this into some better tests in https://www.drupal.org/node/2942605.
- $this->eventDispatcher = (new \ReflectionClass(EventDispatcher::class))->newInstanceWithoutConstructor();
+ $this->eventDispatcher = (new \ReflectionClass(ContainerAwareEventDispatcher::class))->newInstanceWithoutConstructor();
$this->account = $this->prophesize(AccountInterface::class);
$subscriber = new BlockComponentRenderArray($this->account->reveal());
diff --git a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
index 9ee42e3f70..a8fd9e87d6 100644
--- a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
+++ b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
@@ -25,7 +25,6 @@
* synchronizations.
*
* @group EventDispatcher
- * @group legacy
*/
class ContainerAwareEventDispatcherTest extends TestCase {
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
index c567bc0398..94ced461bc 100644
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
@@ -4,13 +4,13 @@
namespace Drupal\Tests\Core\EventSubscriber;
+use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher as EventDispatcher;
use Drupal\Core\EventSubscriber\RedirectResponseSubscriber;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
use Drupal\Tests\UnitTestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Container;
-use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
@@ -87,7 +87,7 @@ protected function setUp(): void {
* @dataProvider providerTestDestinationRedirect
*/
public function testDestinationRedirect(Request $request, $expected) {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new RedirectResponse('http://example.com/drupal');
$request->headers->set('HOST', 'example.com');
@@ -128,7 +128,7 @@ public static function providerTestDestinationRedirect() {
* @dataProvider providerTestDestinationRedirectToExternalUrl
*/
public function testDestinationRedirectToExternalUrl($request, $expected) {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new RedirectResponse('http://other-example.com');
@@ -143,7 +143,7 @@ public function testDestinationRedirectToExternalUrl($request, $expected) {
* @covers ::checkRedirectUrl
*/
public function testRedirectWithOptInExternalUrl() {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new TrustedRedirectResponse('http://external-url.com');
$request = Request::create('');
@@ -176,7 +176,7 @@ public static function providerTestDestinationRedirectToExternalUrl() {
* @dataProvider providerTestDestinationRedirectWithInvalidUrl
*/
public function testDestinationRedirectWithInvalidUrl(Request $request) {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new RedirectResponse('http://example.com/drupal');
Subject: [PATCH] Issue #2909185 by longwave, donquixote, andypost, andregp, pounard, jibran, martin107, kostyashupenko, catch, znerol: Replace ContainerAwareEventDispatcher with Symfony EventDispatcher
---
Index: core/core.services.yml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/core.services.yml b/core/core.services.yml
--- a/core/core.services.yml (revision 6e733866fe414d0521be3d781c631c9368b818b1)
+++ b/core/core.services.yml (revision ed13e942030535430a4a8861cbf49808a0934a72)
@@ -873,7 +873,8 @@
arguments: ['@request_stack']
Drupal\Core\Routing\RouteMatchInterface: '@current_route_match'
event_dispatcher:
- class: Symfony\Component\EventDispatcher\EventDispatcher
+ class: Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
+ arguments: ['@service_container']
Psr\EventDispatcher\EventDispatcherInterface: '@event_dispatcher'
Symfony\Contracts\EventDispatcher\EventDispatcherInterface: '@event_dispatcher'
controller_resolver:
Index: core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
--- a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php (revision 6e733866fe414d0521be3d781c631c9368b818b1)
+++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php (revision ed13e942030535430a4a8861cbf49808a0934a72)
@@ -2,8 +2,6 @@
namespace Drupal\Component\EventDispatcher;
-@trigger_error('The ' . __NAMESPACE__ . '\ContainerAwareEventDispatcher is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use Symfony\Component\EventDispatcher\EventDispatcher instead. See https://www.drupal.org/node/3376090', E_USER_DEPRECATED);
-
use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -32,11 +30,6 @@
* runtime is not affected by this change though.
* </dd>
* </dl>
- *
- * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use
- * \Symfony\Component\EventDispatcher\EventDispatcher instead.
- *
- * @see https://www.drupal.org/node/3376090
*/
class ContainerAwareEventDispatcher implements EventDispatcherInterface {
Index: core/lib/Drupal/Core/CoreServiceProvider.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
--- a/core/lib/Drupal/Core/CoreServiceProvider.php (revision 6e733866fe414d0521be3d781c631c9368b818b1)
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php (revision ed13e942030535430a4a8861cbf49808a0934a72)
@@ -29,7 +29,6 @@
use Psr\Log\LoggerAwareInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Reference;
-use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
@@ -83,7 +82,7 @@
$container->addCompilerPass(new TwigExtensionPass());
// Add a compiler pass for registering event subscribers.
- $container->addCompilerPass(new RegisterEventSubscribersPass(new RegisterListenersPass()), PassConfig::TYPE_AFTER_REMOVING);
+ $container->addCompilerPass(new RegisterEventSubscribersPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new LoggerAwarePass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new RegisterAccessChecksPass());
Index: core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php
--- a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php (revision 6e733866fe414d0521be3d781c631c9368b818b1)
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php (revision ed13e942030535430a4a8861cbf49808a0934a72)
@@ -4,50 +4,59 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
-use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
- * Wraps the Symfony event subscriber pass to use different tag names.
+ * Registers all event subscribers to the event dispatcher.
*/
class RegisterEventSubscribersPass implements CompilerPassInterface {
- /**
- * Constructs a RegisterEventSubscribersPass object.
- *
- * @param \Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass $pass
- * The Symfony compiler pass that registers event subscribers.
- */
- public function __construct(
- protected RegisterListenersPass $pass
- ) {}
-
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
- $this->renameTag($container, 'event_subscriber', 'kernel.event_subscriber');
- $this->pass->process($container);
- $this->renameTag($container, 'kernel.event_subscriber', 'event_subscriber');
- }
+ if (!$container->hasDefinition('event_dispatcher')) {
+ return;
+ }
+
+ $definition = $container->getDefinition('event_dispatcher');
+
+ $event_subscriber_info = [];
+ foreach ($container->findTaggedServiceIds('event_subscriber') as $id => $attributes) {
+
+ // We must assume that the class value has been correctly filled, even if
+ // the service is created by a factory.
+ $class = $container->getDefinition($id)->getClass();
+
+ $interface = EventSubscriberInterface::class;
+ if (!is_subclass_of($class, $interface)) {
+ throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
+ }
- /**
- * Renames tags in the container.
- *
- * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
- * The container.
- * @param string $source_tag
- * The tag to be renamed.
- * @param string $target_tag
- * The tag to rename with.
- */
- protected function renameTag(ContainerBuilder $container, string $source_tag, string $target_tag): void {
- foreach ($container->getDefinitions() as $definition) {
- if ($definition->hasTag($source_tag)) {
- $attributes = $definition->getTag($source_tag)[0];
- $definition->addTag($target_tag, $attributes);
- $definition->clearTag($source_tag);
+ // Get all subscribed events.
+ foreach ($class::getSubscribedEvents() as $event_name => $params) {
+ if (is_string($params)) {
+ $priority = 0;
+ $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $params]];
+ }
+ elseif (is_string($params[0])) {
+ $priority = $params[1] ?? 0;
+ $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $params[0]]];
+ }
+ else {
+ foreach ($params as $listener) {
+ $priority = $listener[1] ?? 0;
+ $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $listener[0]]];
+ }
+ }
}
}
+
+ foreach (array_keys($event_subscriber_info) as $event_name) {
+ krsort($event_subscriber_info[$event_name]);
+ }
+
+ $definition->addArgument($event_subscriber_info);
}
}
Index: core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
--- a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php (revision 6e733866fe414d0521be3d781c631c9368b818b1)
+++ b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php (revision ed13e942030535430a4a8861cbf49808a0934a72)
@@ -4,6 +4,7 @@
namespace Drupal\Tests\layout_builder\Unit;
+use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockManagerInterface;
@@ -23,7 +24,6 @@
use Drupal\layout_builder\SectionComponent;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
-use Symfony\Component\EventDispatcher\EventDispatcher;
/**
* @coversDefaultClass \Drupal\layout_builder\Section
@@ -62,7 +62,7 @@
/**
* The event dispatcher.
*
- * @var \Symfony\Component\EventDispatcher\EventDispatcher
+ * @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
*/
protected $eventDispatcher;
@@ -77,7 +77,7 @@
$this->contextHandler = $this->prophesize(ContextHandlerInterface::class);
$this->contextRepository = $this->prophesize(ContextRepositoryInterface::class);
// @todo Refactor this into some better tests in https://www.drupal.org/node/2942605.
- $this->eventDispatcher = (new \ReflectionClass(EventDispatcher::class))->newInstanceWithoutConstructor();
+ $this->eventDispatcher = (new \ReflectionClass(ContainerAwareEventDispatcher::class))->newInstanceWithoutConstructor();
$this->account = $this->prophesize(AccountInterface::class);
$subscriber = new BlockComponentRenderArray($this->account->reveal());
Index: core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
--- a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php (revision 6e733866fe414d0521be3d781c631c9368b818b1)
+++ b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php (revision ed13e942030535430a4a8861cbf49808a0934a72)
@@ -25,7 +25,6 @@
* synchronizations.
*
* @group EventDispatcher
- * @group legacy
*/
class ContainerAwareEventDispatcherTest extends TestCase {
Index: core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php (revision 6e733866fe414d0521be3d781c631c9368b818b1)
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php (revision ed13e942030535430a4a8861cbf49808a0934a72)
@@ -4,13 +4,13 @@
namespace Drupal\Tests\Core\EventSubscriber;
+use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher as EventDispatcher;
use Drupal\Core\EventSubscriber\RedirectResponseSubscriber;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
use Drupal\Tests\UnitTestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Container;
-use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
@@ -87,7 +87,7 @@
* @dataProvider providerTestDestinationRedirect
*/
public function testDestinationRedirect(Request $request, $expected) {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new RedirectResponse('http://example.com/drupal');
$request->headers->set('HOST', 'example.com');
@@ -128,7 +128,7 @@
* @dataProvider providerTestDestinationRedirectToExternalUrl
*/
public function testDestinationRedirectToExternalUrl($request, $expected) {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new RedirectResponse('http://other-example.com');
@@ -143,7 +143,7 @@
* @covers ::checkRedirectUrl
*/
public function testRedirectWithOptInExternalUrl() {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new TrustedRedirectResponse('http://external-url.com');
$request = Request::create('');
@@ -176,7 +176,7 @@
* @dataProvider providerTestDestinationRedirectWithInvalidUrl
*/
public function testDestinationRedirectWithInvalidUrl(Request $request) {
- $dispatcher = new EventDispatcher();
+ $dispatcher = new EventDispatcher(\Drupal::getContainer());
$kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$response = new RedirectResponse('http://example.com/drupal');
diff --git a/book.module b/book.module
index 1760113fe4188101391792b45cfa93e2399089b8..cc02b76fef5e9f44a9fa594292f3bc66f9d2c5ba 100644
--- a/book.module
+++ b/book.module
@@ -136,6 +136,9 @@ function book_node_links_alter(array &$links, NodeInterface $node, array &$conte
*/
function book_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$node = $form_state->getFormObject()->getEntity();
+ if (!book_type_is_allowed($node->getType())) {
+ return;
+ }
$account = \Drupal::currentUser();
$access = $account->hasPermission('administer book outlines');
if (!$access) {
@@ -290,6 +293,9 @@ function book_node_predelete(EntityInterface $node) {
* Implements hook_ENTITY_TYPE_prepare_form() for node entities.
*/
function book_node_prepare_form(NodeInterface $node, $operation, FormStateInterface $form_state) {
+ if (!book_type_is_allowed($node->getType())) {
+ return;
+ }
/** @var \Drupal\book\BookManagerInterface $book_manager */
$book_manager = \Drupal::service('book.manager');
diff --git a/src/Plugin/Validation/Constraint/BookOutlineConstraintValidator.php b/src/Plugin/Validation/Constraint/BookOutlineConstraintValidator.php
index ca8114dad4a661417bed20d375d33f06127b86b8..fc7b4ef7a0ae09b7268472e7f664c23490383862 100644
--- a/src/Plugin/Validation/Constraint/BookOutlineConstraintValidator.php
+++ b/src/Plugin/Validation/Constraint/BookOutlineConstraintValidator.php
@@ -43,7 +43,12 @@ public static function create(ContainerInterface $container) {
* {@inheritdoc}
*/
public function validate($entity, Constraint $constraint) {
- if (isset($entity) && !$entity->isNew() && !$entity->isDefaultRevision()) {
+ // Validate the book structure when the user has access to manage book
+ // outlines. When the user can manage book outlines, the book variable will
+ // be populated even if the node is not part of the book. If the user cannot
+ // manage book outlines, the book variable will be empty and we can safely
+ // ignore the constraints as the outline cannot be changed by this user.
+ if (isset($entity) && !empty($entity->book) && !$entity->isNew() && !$entity->isDefaultRevision()) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $original */
$original = $this->bookManager->loadBookLink($entity->id(), FALSE) ?: [
'bid' => 0,
diff --git a/tests/src/Functional/BookContentModerationTest.php b/tests/src/Functional/BookContentModerationTest.php
index 14898777d91ea52aa2630f6775a2251dc08b1530..3fc60cde1129430488bea2a258596637893bca38 100644
--- a/tests/src/Functional/BookContentModerationTest.php
+++ b/tests/src/Functional/BookContentModerationTest.php
@@ -4,6 +4,7 @@
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
+use Drupal\user\Entity\Role;
/**
* Tests Book and Content Moderation integration.
@@ -15,6 +16,13 @@ class BookContentModerationTest extends BrowserTestBase {
use BookTestTrait;
use ContentModerationTestTrait;
+ /**
+ * A user with permission to make workflow transitions but not manage books.
+ *
+ * @var \Drupal\user\UserInterface
+ */
+ protected $nonBookAdminUser;
+
/**
* Modules to install.
*
@@ -56,6 +64,19 @@ protected function setUp(): void {
'use editorial transition create_new_draft',
'use editorial transition publish',
]);
+
+ // Another user without manage book permissions to test updates to nodes
+ // that are
+ // 1. Not part of a book outline.
+ // 2. Part of a book outline.
+ $this->nonBookAdminUser = $this->drupalCreateUser([
+ 'create book content',
+ 'edit own book content',
+ 'use editorial transition create_new_draft',
+ 'use editorial transition publish',
+ 'access printer-friendly version',
+ 'view any unpublished content',
+ ]);
}
/**
@@ -163,4 +184,112 @@ public function testBookWithPendingRevisions() {
$this->assertSession()->pageTextNotContains('You can only change the book outline for the published version of this content.');
}
+ /**
+ * Tests that users who cannot manage books can still make node updates.
+ */
+ public function testNonBookAdminNodeUpdates() {
+ // 1. First test that users who cannot manage books can make updates to
+ // nodes that are not part of a book outline.
+ $this->drupalLogin($this->nonBookAdminUser);
+ // Create a new book page without actually attaching it to a book and create
+ // a draft.
+ $this->drupalGet('node/add/book');
+ $this->assertSession()->statusCodeEquals(200);
+ $edit = [
+ 'title[0][value]' => 'Some moderated content',
+ 'moderation_state[0][state]' => 'draft',
+ ];
+ $this->submitForm($edit, 'Save');
+ $this->assertSession()->pageTextContains('Some moderated content has been created.');
+ $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
+ $this->assertNotEmpty($node);
+
+ $this->drupalGet('node/' . $node->id() . '/edit');
+ $this->assertSession()->statusCodeEquals(200);
+ // Publish the content.
+ $edit = [
+ 'body[0][value]' => 'Second change non book admin user',
+ 'moderation_state[0][state]' => 'published',
+ ];
+ $this->submitForm($edit, 'Save');
+ $this->assertSession()->pageTextNotContains('You can only change the book outline for the published version of this content.');
+ $this->assertSession()->pageTextContains('Some moderated content has been updated');
+
+ // Now update content again, it should be successfully updated and not throw
+ // any errors.
+ $this->drupalGet('node/' . $node->id() . '/edit');
+ $this->assertSession()->statusCodeEquals(200);
+ $edit = [
+ 'moderation_state[0][state]' => 'draft',
+ ];
+ $this->submitForm($edit, 'Save');
+ $this->assertSession()->pageTextNotContains('You can only change the book outline for the published version of this content.');
+ $this->assertSession()->pageTextContains('Some moderated content has been updated');
+
+ // 2. Now test that users who cannot manage books can make updates to nodes
+ // that are part of a book outline. As the non admin book user, publish the
+ // content created above in order to be added to a book.
+ $this->drupalGet('node/' . $node->id() . '/edit');
+ $this->assertSession()->statusCodeEquals(200);
+ $edit = [
+ 'moderation_state[0][state]' => 'published',
+ ];
+ $this->submitForm($edit, 'Save');
+
+ // Create a book (as a book admin user).
+ $book_1_nodes = $this->createBook(['moderation_state[0][state]' => 'published']);
+ $book_1 = $this->book;
+
+ // Now add the node created previously by the non book admin user to the
+ // book created above. We need to grant additional permission for bookAuthor
+ // to be able to edit the node owned by nonBookAdminUser.
+ $role_ids = $this->bookAuthor->getRoles(TRUE);
+ $role_id = reset($role_ids);
+ $role = Role::load($role_id);
+ $role->grantPermission('edit any book content');
+ $role->save();
+ $this->drupalLogin($this->bookAuthor);
+ $this->drupalGet('node/' . $node->id() . '/edit');
+ $this->assertSession()->statusCodeEquals(200);
+ $edit = [
+ 'book[bid]' => $this->book->id(),
+ 'moderation_state[0][state]' => 'published',
+ ];
+ $this->submitForm($edit, 'Save');
+
+ // Assert that the node has been added to the book.
+ $this->assertSession()->pageTextNotContains('You can only change the book outline for the published version of this content.');
+ $this->assertSession()->pageTextContains('Some moderated content has been updated');
+ $this->checkBookNode($book_1, [
+ $book_1_nodes[0],
+ $book_1_nodes[3],
+ $book_1_nodes[4],
+ $node,
+ ], FALSE, FALSE, $book_1_nodes[0], []);
+
+ // Try to update the non book admin's node in the book as the user
+ // that cannot manage books, it should be successfully updated and not
+ // throw any errors.
+ $this->drupalLogin($this->nonBookAdminUser);
+ $this->drupalGet('node/' . $node->id() . '/edit');
+ $this->assertSession()->statusCodeEquals(200);
+ $edit = [
+ 'body[0][value]' => 'Change by non book admin user again',
+ 'moderation_state[0][state]' => 'draft',
+ ];
+ $this->submitForm($edit, 'Save');
+ $this->assertSession()->pageTextNotContains('You can only change the book outline for the published version of this content.');
+ $this->assertSession()->pageTextContains('Some moderated content has been updated');
+
+ // Check that the book outline did not change.
+ $this->book = $book_1;
+ $this->checkBookNode($book_1, [
+ $book_1_nodes[0],
+ $book_1_nodes[3],
+ $book_1_nodes[4],
+ $node,
+ ], FALSE, FALSE, $book_1_nodes[0], []);
+ $this->checkBookNode($book_1_nodes[0], [$book_1_nodes[1], $book_1_nodes[2]], $book_1, $book_1, $book_1_nodes[1], [$book_1]);
+ }
+
}
diff --git a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityUntranslatableFieldsConstraintValidator.php b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityUntranslatableFieldsConstraintValidator.php
index 56f0da64fe8c6c0b2c7fd1a56b48ddad3ec69186..57e3903d5d7b17c37cd66790dd148e99fc1b6ce8 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityUntranslatableFieldsConstraintValidator.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityUntranslatableFieldsConstraintValidator.php
@@ -71,8 +71,11 @@ public function validate($entity, Constraint $constraint) {
// in default revisions.
if ($this->hasUntranslatableFieldsChanges($entity)) {
if ($entity->isDefaultTranslationAffectedOnly()) {
+ $moderationInformation = \Drupal::hasService('content_moderation.moderation_information') ?
+ \Drupal::service('content_moderation.moderation_information') :
+ NULL;
foreach ($entity->getTranslationLanguages(FALSE) as $langcode => $language) {
- if ($entity->getTranslation($langcode)->hasTranslationChanges()) {
+ if ($entity->getTranslation($langcode)->hasTranslationChanges() && ($moderationInformation === NULL || !$moderationInformation->isModeratedEntity($entity->getTranslation($langcode)))) {
$this->context->addViolation($constraint->defaultTranslationMessage);
break;
}
diff --git a/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php b/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php
index e52a18081064ddcdcd48777a401801253f183803..51eb95e420a63e3f64b0ea3dc6be8732b3213af0 100644
--- a/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php
+++ b/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php
@@ -111,8 +111,11 @@ public function validate($value, Constraint $constraint) {
$original_translation = $this->getOriginalTranslation($entity, $original);
if ($this->hasSynchronizedPropertyChanges($entity, $original_translation, $synchronized_properties)) {
if ($entity->isDefaultTranslationAffectedOnly()) {
+ $moderationInformation = \Drupal::hasService('content_moderation.moderation_information') ?
+ \Drupal::service('content_moderation.moderation_information') :
+ NULL;
foreach ($entity->getTranslationLanguages(FALSE) as $langcode => $language) {
- if ($entity->getTranslation($langcode)->hasTranslationChanges()) {
+ if ($entity->getTranslation($langcode)->hasTranslationChanges() && ($moderationInformation === NULL || !$moderationInformation->isModeratedEntity($entity->getTranslation($langcode)))) {
$this->context->addViolation($constraint->defaultTranslationMessage);
break;
}
diff --git a/core/modules/datetime/src/Plugin/views/filter/Date.php b/core/modules/datetime/src/Plugin/views/filter/Date.php
index f73a675fef0c72f3de88af21cdd759216713cdac..b4152bf730260e619814204140f5e18e15cd0f23 100644
--- a/core/modules/datetime/src/Plugin/views/filter/Date.php
+++ b/core/modules/datetime/src/Plugin/views/filter/Date.php
@@ -4,6 +4,8 @@
use Drupal\Component\Datetime\DateTimePlus;
use Drupal\Core\Datetime\DateFormatterInterface;
+use Drupal\Core\Datetime\DrupalDateTime;
+use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
@@ -98,6 +100,54 @@ public static function create(ContainerInterface $container, array $configuratio
);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function validateExposed(&$form, FormStateInterface $form_state) {
+ // Do not validate value if filter is not exposed or grouped.
+ if (empty($this->options['exposed']) || $this->options['is_grouped']) {
+ return;
+ }
+
+ $identifier = $this->options['expose']['identifier'];
+ $input = $form_state->getValue($identifier);
+
+ $values = [];
+ if (is_array($input)) {
+ if (!empty($input['value'])) {
+ $values[] = $input['value'];
+ }
+ else {
+ if (!empty($input['min'])) {
+ $values[] = $input['min'];
+ }
+ if (!empty($input['max'])) {
+ $values[] = $input['max'];
+ }
+ }
+ }
+ elseif (!empty($input)) {
+ $values[] = $input;
+ }
+
+ foreach ($values as $value) {
+ try {
+ (new DrupalDateTime($value))->getTimestamp();
+ }
+ catch (\Exception $e) {
+ if (isset($form[$identifier])) {
+ $field = &$form[$identifier];
+ }
+ elseif (isset($form[$identifier . '_wrapper'])) {
+ $field = &$form[$identifier . '_wrapper'];
+ }
+ // Set the form error message.
+ $form_state->setError($field, $this->t('Invalid date format.'));
+ break;
+ }
+ }
+ }
+
/**
* Override parent method, which deals with dates as integers.
*/
diff --git a/src/Plugin/CKEditorPlugin/CodeSnippet.php b/src/Plugin/CKEditorPlugin/CodeSnippet.php
index 4cf9ab096ebdc001aaaeb918875e4af525cd001f..d5693bb409ecdec6aab495c88fc6fb799bbb0844 100644
--- a/src/Plugin/CKEditorPlugin/CodeSnippet.php
+++ b/src/Plugin/CKEditorPlugin/CodeSnippet.php
@@ -182,6 +182,7 @@ class CodeSnippet extends CKEditorPluginBase implements CKEditorPluginConfigurab
'vbscript' => 'VBScript',
'xhtml' => 'XHTML',
'xml' => 'XML',
+ 'yaml' => 'Yaml',
];
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment