From 22972e3764d9c631465d44a8a349dbe48ebfe6ed Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Wed, 17 Jul 2024 16:46:30 +0100
Subject: [PATCH] Issue #3454603 by phenaproxima, thejimbirch, Prashant.c,
 alexpott: Many core recipes are not idempotent

(cherry picked from commit 9f3ee1ff550c2a0a0e6481dafc95a607e5544b8f)
---
 .../Core/Config/Entity/ConfigEntityBase.php   |   1 +
 core/modules/block/src/Entity/Block.php       |   4 +
 ...tity_form_display.node.article.default.yml |  87 -------------
 ...tity_view_display.node.article.default.yml |  41 -------
 ...e.entity_view_display.node.article.rss.yml |  21 ----
 ...ntity_view_display.node.article.teaser.yml |  41 -------
 .../config/field.field.node.article.body.yml  |   1 +
 core/recipes/article_content_type/recipe.yml  | 116 ++++++++++++++++++
 .../field.field.block_content.basic.body.yml  |   1 +
 .../config/filter.format.basic_html.yml       |   2 -
 ...eld.field.comment.comment.comment_body.yml |   3 +-
 .../core_recommended_admin_theme/recipe.yml   |  16 ++-
 .../recipe.yml                                |  29 ++++-
 .../config/filter.format.full_html.yml        |   2 -
 .../config/field.field.node.page.body.yml     |   1 +
 .../remote_video_media_type/recipe.yml        |   1 +
 .../config/image.style.max_1300x1300.yml      |   3 +-
 .../config/image.style.max_2600x2600.yml      |   3 +-
 .../config/image.style.max_325x325.yml        |   3 +-
 .../config/image.style.max_650x650.yml        |   3 +-
 .../config/taxonomy.vocabulary.tags.yml       |   1 +
 core/recipes/user_picture/recipe.yml          |   6 +-
 .../Core/Recipe/CoreRecipesTest.php           |   2 +
 23 files changed, 178 insertions(+), 210 deletions(-)
 delete mode 100644 core/recipes/article_content_type/config/core.entity_form_display.node.article.default.yml
 delete mode 100644 core/recipes/article_content_type/config/core.entity_view_display.node.article.default.yml
 delete mode 100644 core/recipes/article_content_type/config/core.entity_view_display.node.article.rss.yml
 delete mode 100644 core/recipes/article_content_type/config/core.entity_view_display.node.article.teaser.yml

diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index e7a692cdaefa..9df51a4bf37a 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -191,6 +191,7 @@ public function disable() {
   /**
    * {@inheritdoc}
    */
+  #[ActionMethod(adminLabel: new TranslatableMarkup('Set status'), pluralize: FALSE)]
   public function setStatus($status) {
     $this->status = (bool) $status;
     return $this;
diff --git a/core/modules/block/src/Entity/Block.php b/core/modules/block/src/Entity/Block.php
index ece8de38abb9..72184ed9ae31 100644
--- a/core/modules/block/src/Entity/Block.php
+++ b/core/modules/block/src/Entity/Block.php
@@ -4,12 +4,14 @@
 
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Condition\ConditionPluginCollection;
+use Drupal\Core\Config\Action\Attribute\ActionMethod;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\block\BlockPluginCollection;
 use Drupal\block\BlockInterface;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
 
 /**
  * Defines a Block configuration entity class.
@@ -310,6 +312,7 @@ protected function conditionPluginManager() {
   /**
    * {@inheritdoc}
    */
+  #[ActionMethod(adminLabel: new TranslatableMarkup('Set region'), pluralize: FALSE)]
   public function setRegion($region) {
     $this->region = $region;
     return $this;
@@ -318,6 +321,7 @@ public function setRegion($region) {
   /**
    * {@inheritdoc}
    */
+  #[ActionMethod(adminLabel: new TranslatableMarkup('Set weight'), pluralize: FALSE)]
   public function setWeight($weight) {
     $this->weight = $weight;
     return $this;
diff --git a/core/recipes/article_content_type/config/core.entity_form_display.node.article.default.yml b/core/recipes/article_content_type/config/core.entity_form_display.node.article.default.yml
deleted file mode 100644
index f29f17bc0465..000000000000
--- a/core/recipes/article_content_type/config/core.entity_form_display.node.article.default.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.field.node.article.body
-    - field.field.node.article.field_image
-    - image.style.thumbnail
-    - node.type.article
-  module:
-    - image
-    - path
-    - text
-id: node.article.default
-targetEntityType: node
-bundle: article
-mode: default
-content:
-  body:
-    type: text_textarea_with_summary
-    weight: 2
-    region: content
-    settings:
-      rows: 9
-      summary_rows: 3
-      placeholder: ''
-      show_summary: false
-    third_party_settings: {  }
-  created:
-    type: datetime_timestamp
-    weight: 10
-    region: content
-    settings: {  }
-    third_party_settings: {  }
-  field_image:
-    type: image_image
-    weight: 1
-    region: content
-    settings:
-      progress_indicator: throbber
-      preview_image_style: thumbnail
-    third_party_settings: {  }
-  path:
-    type: path
-    weight: 30
-    region: content
-    settings: {  }
-    third_party_settings: {  }
-  promote:
-    type: boolean_checkbox
-    weight: 15
-    region: content
-    settings:
-      display_label: true
-    third_party_settings: {  }
-  status:
-    type: boolean_checkbox
-    weight: 120
-    region: content
-    settings:
-      display_label: true
-    third_party_settings: {  }
-  sticky:
-    type: boolean_checkbox
-    weight: 16
-    region: content
-    settings:
-      display_label: true
-    third_party_settings: {  }
-  title:
-    type: string_textfield
-    weight: 0
-    region: content
-    settings:
-      size: 60
-      placeholder: ''
-    third_party_settings: {  }
-  uid:
-    type: entity_reference_autocomplete
-    weight: 5
-    region: content
-    settings:
-      match_operator: CONTAINS
-      match_limit: 10
-      size: 60
-      placeholder: ''
-    third_party_settings: {  }
-hidden: {  }
diff --git a/core/recipes/article_content_type/config/core.entity_view_display.node.article.default.yml b/core/recipes/article_content_type/config/core.entity_view_display.node.article.default.yml
deleted file mode 100644
index a129e14dd6a9..000000000000
--- a/core/recipes/article_content_type/config/core.entity_view_display.node.article.default.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.field.node.article.body
-    - field.field.node.article.field_image
-    - image.style.wide
-    - node.type.article
-  module:
-    - image
-    - text
-    - user
-id: node.article.default
-targetEntityType: node
-bundle: article
-mode: default
-content:
-  body:
-    type: text_default
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    weight: 0
-    region: content
-  field_image:
-    type: image
-    label: hidden
-    settings:
-      image_style: wide
-      image_link: ''
-      image_loading:
-        attribute: eager
-    third_party_settings: {  }
-    weight: -1
-    region: content
-  links:
-    settings: {  }
-    third_party_settings: {  }
-    weight: 100
-    region: content
-hidden: {  }
diff --git a/core/recipes/article_content_type/config/core.entity_view_display.node.article.rss.yml b/core/recipes/article_content_type/config/core.entity_view_display.node.article.rss.yml
deleted file mode 100644
index 05896dd3d74c..000000000000
--- a/core/recipes/article_content_type/config/core.entity_view_display.node.article.rss.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - core.entity_view_mode.node.rss
-    - field.field.node.article.body
-    - field.field.node.article.field_image
-    - node.type.article
-  module:
-    - user
-id: node.article.rss
-targetEntityType: node
-bundle: article
-mode: rss
-content:
-  links:
-    weight: 100
-    region: content
-hidden:
-  body: true
-  field_image: true
diff --git a/core/recipes/article_content_type/config/core.entity_view_display.node.article.teaser.yml b/core/recipes/article_content_type/config/core.entity_view_display.node.article.teaser.yml
deleted file mode 100644
index 5ef60b519f42..000000000000
--- a/core/recipes/article_content_type/config/core.entity_view_display.node.article.teaser.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - core.entity_view_mode.node.teaser
-    - field.field.node.article.body
-    - field.field.node.article.field_image
-    - image.style.medium
-    - node.type.article
-  module:
-    - image
-    - text
-    - user
-id: node.article.teaser
-targetEntityType: node
-bundle: article
-mode: teaser
-content:
-  body:
-    type: text_summary_or_trimmed
-    label: hidden
-    settings:
-      trim_length: 600
-    third_party_settings: {  }
-    weight: 0
-    region: content
-  field_image:
-    type: image
-    label: hidden
-    settings:
-      image_style: medium
-      image_link: content
-      image_loading:
-        attribute: lazy
-    third_party_settings: {  }
-    weight: -1
-    region: content
-  links:
-    weight: 100
-    region: content
-hidden: {  }
diff --git a/core/recipes/article_content_type/config/field.field.node.article.body.yml b/core/recipes/article_content_type/config/field.field.node.article.body.yml
index b36fbd584493..66f00ac4a5ab 100644
--- a/core/recipes/article_content_type/config/field.field.node.article.body.yml
+++ b/core/recipes/article_content_type/config/field.field.node.article.body.yml
@@ -19,4 +19,5 @@ default_value_callback: ''
 settings:
   display_summary: true
   required_summary: false
+  allowed_formats: {  }
 field_type: text_with_summary
diff --git a/core/recipes/article_content_type/recipe.yml b/core/recipes/article_content_type/recipe.yml
index 30eaf30b121a..dfd4371c0c85 100644
--- a/core/recipes/article_content_type/recipe.yml
+++ b/core/recipes/article_content_type/recipe.yml
@@ -26,3 +26,119 @@ config:
       - image.style.medium
       - image.style.thumbnail
       - image.style.wide
+  actions:
+    core.entity_form_display.node.article.default:
+      createIfNotExists:
+        targetEntityType: node
+        bundle: article
+        mode: default
+        status: true
+      setComponents:
+        - name: body
+          options:
+            type: text_textarea_with_summary
+            weight: 2
+            region: content
+        - name: created
+          options:
+            type: datetime_timestamp
+            weight: 10
+            region: content
+        - name: field_image
+          options:
+            type: image_image
+            weight: 1
+            region: content
+        - name: path
+          options:
+            type: path
+            weight: 30
+            region: content
+        - name: promote
+          options:
+            type: boolean_checkbox
+            weight: 15
+            region: content
+        - name: status
+          options:
+            type: boolean_checkbox
+            weight: 120
+            region: content
+        - name: sticky
+          options:
+            type: boolean_checkbox
+            weight: 16
+            region: content
+        - name: title
+          options:
+            type: string_textfield
+            weight: 0
+            region: content
+        - name: uid
+          options:
+            type: entity_reference_autocomplete
+            weight: 5
+            region: content
+    core.entity_view_display.node.article.default:
+      createIfNotExists:
+        targetEntityType: node
+        bundle: article
+        mode: default
+        status: true
+      setComponents:
+        - name: body
+          options:
+            type: text_default
+            label: hidden
+            weight: 0
+            region: content
+        - name: field_image
+          options:
+            type: image
+            label: hidden
+            settings:
+              image_style: wide
+              image_loading:
+                attribute: eager
+            weight: -1
+            region: content
+        - name: links
+          options:
+            weight: 100
+            region: content
+    core.entity_view_display.node.article.rss:
+      createIfNotExists:
+        targetEntityType: node
+        bundle: article
+        mode: rss
+        status: true
+        content:
+          links:
+            weight: 100
+            region: content
+    core.entity_view_display.node.article.teaser:
+      createIfNotExists:
+        targetEntityType: node
+        bundle: article
+        mode: teaser
+        status: true
+        content:
+          links:
+            weight: 100
+            region: content
+      setComponents:
+        - name: body
+          options:
+            type: text_summary_or_trimmed
+            label: hidden
+            weight: 0
+            region: content
+        - name: field_image
+          options:
+            type: image
+            label: hidden
+            settings:
+              image_style: medium
+              image_link: content
+            weight: -1
+            region: content
diff --git a/core/recipes/basic_block_type/config/field.field.block_content.basic.body.yml b/core/recipes/basic_block_type/config/field.field.block_content.basic.body.yml
index dab4f9818109..40968daa4dc9 100644
--- a/core/recipes/basic_block_type/config/field.field.block_content.basic.body.yml
+++ b/core/recipes/basic_block_type/config/field.field.block_content.basic.body.yml
@@ -19,4 +19,5 @@ default_value_callback: ''
 settings:
   display_summary: false
   required_summary: false
+  allowed_formats: {  }
 field_type: text_with_summary
diff --git a/core/recipes/basic_html_format_editor/config/filter.format.basic_html.yml b/core/recipes/basic_html_format_editor/config/filter.format.basic_html.yml
index d81fc17303f2..100ffe73475b 100644
--- a/core/recipes/basic_html_format_editor/config/filter.format.basic_html.yml
+++ b/core/recipes/basic_html_format_editor/config/filter.format.basic_html.yml
@@ -6,8 +6,6 @@ dependencies:
 name: 'Basic HTML'
 format: basic_html
 weight: 0
-roles:
-  - authenticated
 filters:
   editor_file_reference:
     id: editor_file_reference
diff --git a/core/recipes/comment_base/config/field.field.comment.comment.comment_body.yml b/core/recipes/comment_base/config/field.field.comment.comment.comment_body.yml
index 1337070d16b8..8d97e03507be 100644
--- a/core/recipes/comment_base/config/field.field.comment.comment.comment_body.yml
+++ b/core/recipes/comment_base/config/field.field.comment.comment.comment_body.yml
@@ -16,5 +16,6 @@ required: true
 translatable: true
 default_value: {  }
 default_value_callback: ''
-settings: {  }
+settings:
+  allowed_formats: {  }
 field_type: text_long
diff --git a/core/recipes/core_recommended_admin_theme/recipe.yml b/core/recipes/core_recommended_admin_theme/recipe.yml
index cea2f383fbfc..046f5a27fc65 100644
--- a/core/recipes/core_recommended_admin_theme/recipe.yml
+++ b/core/recipes/core_recommended_admin_theme/recipe.yml
@@ -9,16 +9,28 @@ config:
     system:
       - system.menu.account
       - system.menu.main
-      - system.theme
     claro:
       - block.block.claro_breadcrumbs
       - block.block.claro_content
       - block.block.claro_local_actions
       - block.block.claro_messages
-      - block.block.claro_page_title
       - block.block.claro_primary_local_tasks
       - block.block.claro_secondary_local_tasks
   actions:
+    # Create this block dynamically so as not to conflict with the block created
+    # by block_theme_initialize() when Claro is installed.
+    block.block.claro_page_title:
+      createIfNotExists:
+        theme: claro
+        plugin: page_title_block
+        settings:
+          id: page_title_block
+          label: 'Page title'
+          label_display: '0'
+          provider: core
+      setRegion: header
+      setStatus: true
+      setWeight: -30
     system.theme:
       simpleConfigUpdate:
         admin: claro
diff --git a/core/recipes/core_recommended_front_end_theme/recipe.yml b/core/recipes/core_recommended_front_end_theme/recipe.yml
index 643046e68ad6..a7b2e26f40d6 100644
--- a/core/recipes/core_recommended_front_end_theme/recipe.yml
+++ b/core/recipes/core_recommended_front_end_theme/recipe.yml
@@ -9,14 +9,11 @@ config:
     system:
       - system.menu.account
       - system.menu.main
-      - system.theme
     olivero:
       - block.block.olivero_account_menu
       - block.block.olivero_breadcrumbs
       - block.block.olivero_content
       - block.block.olivero_main_menu
-      - block.block.olivero_messages
-      - block.block.olivero_page_title
       - block.block.olivero_powered
       - block.block.olivero_primary_admin_actions
       - block.block.olivero_primary_local_tasks
@@ -24,6 +21,32 @@ config:
       - block.block.olivero_site_branding
       - core.date_format.olivero_medium
   actions:
+    # Create these blocks dynamically so as not to conflict with the blocks created
+    # by block_theme_initialize() when Olivero is installed.
+    block.block.olivero_messages:
+      createIfNotExists:
+        theme: olivero
+        plugin: system_messages_block
+        settings:
+          id: system_messages_block
+          label: 'Status messages'
+          label_display: '0'
+          provider: system
+      setRegion: highlighted
+      setStatus: true
+      setWeight: -5
+    block.block.olivero_page_title:
+      createIfNotExists:
+        theme: olivero
+        plugin: page_title_block
+        settings:
+          id: page_title_block
+          label: 'Page title'
+          label_display: '0'
+          provider: core
+      setRegion: content_above
+      setStatus: true
+      setWeight: -5
     system.theme:
       simpleConfigUpdate:
         default: olivero
diff --git a/core/recipes/full_html_format_editor/config/filter.format.full_html.yml b/core/recipes/full_html_format_editor/config/filter.format.full_html.yml
index a0e616a4989f..07e5c67f00a5 100644
--- a/core/recipes/full_html_format_editor/config/filter.format.full_html.yml
+++ b/core/recipes/full_html_format_editor/config/filter.format.full_html.yml
@@ -6,8 +6,6 @@ dependencies:
 name: 'Full HTML'
 format: full_html
 weight: 2
-roles:
-  - administrator
 filters:
   editor_file_reference:
     id: editor_file_reference
diff --git a/core/recipes/page_content_type/config/field.field.node.page.body.yml b/core/recipes/page_content_type/config/field.field.node.page.body.yml
index 4ff17d0e711a..c81d7034f341 100644
--- a/core/recipes/page_content_type/config/field.field.node.page.body.yml
+++ b/core/recipes/page_content_type/config/field.field.node.page.body.yml
@@ -19,4 +19,5 @@ default_value_callback: ''
 settings:
   display_summary: true
   required_summary: false
+  allowed_formats: {  }
 field_type: text_with_summary
diff --git a/core/recipes/remote_video_media_type/recipe.yml b/core/recipes/remote_video_media_type/recipe.yml
index 1f66ebfc1996..fd6d9cd02b12 100644
--- a/core/recipes/remote_video_media_type/recipe.yml
+++ b/core/recipes/remote_video_media_type/recipe.yml
@@ -21,3 +21,4 @@ config:
       - views.view.media
     image:
       - image.style.medium
+      - image.style.thumbnail
diff --git a/core/recipes/standard_responsive_images/config/image.style.max_1300x1300.yml b/core/recipes/standard_responsive_images/config/image.style.max_1300x1300.yml
index fde3282498d0..2bcee4cda939 100644
--- a/core/recipes/standard_responsive_images/config/image.style.max_1300x1300.yml
+++ b/core/recipes/standard_responsive_images/config/image.style.max_1300x1300.yml
@@ -1,7 +1,5 @@
 langcode: en
 dependencies:
-  module:
-    - responsive_image
   enforced:
     module:
       - responsive_image
@@ -22,3 +20,4 @@ effects:
     weight: 2
     data:
       extension: webp
+status: true
diff --git a/core/recipes/standard_responsive_images/config/image.style.max_2600x2600.yml b/core/recipes/standard_responsive_images/config/image.style.max_2600x2600.yml
index a63e72ab6f35..02d0d777fa71 100644
--- a/core/recipes/standard_responsive_images/config/image.style.max_2600x2600.yml
+++ b/core/recipes/standard_responsive_images/config/image.style.max_2600x2600.yml
@@ -1,7 +1,5 @@
 langcode: en
 dependencies:
-  module:
-    - responsive_image
   enforced:
     module:
       - responsive_image
@@ -22,3 +20,4 @@ effects:
     weight: 2
     data:
       extension: webp
+status: true
diff --git a/core/recipes/standard_responsive_images/config/image.style.max_325x325.yml b/core/recipes/standard_responsive_images/config/image.style.max_325x325.yml
index e820c8bb01da..208d6f621893 100644
--- a/core/recipes/standard_responsive_images/config/image.style.max_325x325.yml
+++ b/core/recipes/standard_responsive_images/config/image.style.max_325x325.yml
@@ -1,7 +1,5 @@
 langcode: en
 dependencies:
-  module:
-    - responsive_image
   enforced:
     module:
       - responsive_image
@@ -22,3 +20,4 @@ effects:
     weight: 2
     data:
       extension: webp
+status: true
diff --git a/core/recipes/standard_responsive_images/config/image.style.max_650x650.yml b/core/recipes/standard_responsive_images/config/image.style.max_650x650.yml
index d5beda6259f3..c92f4347e2f8 100644
--- a/core/recipes/standard_responsive_images/config/image.style.max_650x650.yml
+++ b/core/recipes/standard_responsive_images/config/image.style.max_650x650.yml
@@ -1,7 +1,5 @@
 langcode: en
 dependencies:
-  module:
-    - responsive_image
   enforced:
     module:
       - responsive_image
@@ -22,3 +20,4 @@ effects:
     weight: 2
     data:
       extension: webp
+status: true
diff --git a/core/recipes/tags_taxonomy/config/taxonomy.vocabulary.tags.yml b/core/recipes/tags_taxonomy/config/taxonomy.vocabulary.tags.yml
index 4c754e86c715..0d0313cf6ea1 100644
--- a/core/recipes/tags_taxonomy/config/taxonomy.vocabulary.tags.yml
+++ b/core/recipes/tags_taxonomy/config/taxonomy.vocabulary.tags.yml
@@ -5,3 +5,4 @@ name: Tags
 vid: tags
 description: 'Use tags to group articles on similar topics into categories.'
 weight: 0
+new_revision: false
diff --git a/core/recipes/user_picture/recipe.yml b/core/recipes/user_picture/recipe.yml
index ba84c830020c..773e6b771185 100644
--- a/core/recipes/user_picture/recipe.yml
+++ b/core/recipes/user_picture/recipe.yml
@@ -2,7 +2,9 @@ name: User pictures
 description: 'Adds the ability for user accounts to have pictures (avatars).'
 type: Users
 install:
-  - field
-  - file
   - image
   - user
+config:
+  import:
+    image:
+      - image.style.thumbnail
diff --git a/core/tests/Drupal/FunctionalTests/Core/Recipe/CoreRecipesTest.php b/core/tests/Drupal/FunctionalTests/Core/Recipe/CoreRecipesTest.php
index 6d05f7b97a12..0d4c7f2669fc 100644
--- a/core/tests/Drupal/FunctionalTests/Core/Recipe/CoreRecipesTest.php
+++ b/core/tests/Drupal/FunctionalTests/Core/Recipe/CoreRecipesTest.php
@@ -67,6 +67,8 @@ public static function providerApplyRecipe(): iterable {
   public function testApplyRecipe(string $path): void {
     $this->setUpCurrentUser(admin: TRUE);
     $this->applyRecipe($path);
+    // Apply the recipe again to prove that it is idempotent.
+    $this->applyRecipe($path);
   }
 
 }
-- 
GitLab