From 72e1a9792bcb24a59a2782fe16f8d87618b1bf84 Mon Sep 17 00:00:00 2001
From: Dave Long <dave@longwaveconsulting.com>
Date: Fri, 10 May 2024 16:32:32 +0100
Subject: [PATCH] Issue #3091003 by sukr_s, smustgrave, RaphaelBriskie, FeyP,
 borisson_: Changing a display's machine name while an attachment exist breaks
 Views

(cherry picked from commit 26e5ef207aaeaa8ad4ae31907cb53a5abf7b776a)
---
 core/modules/views_ui/src/ViewEditForm.php    | 12 +++++++
 .../src/Functional/DisplayAttachmentTest.php  | 31 +++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index 4cd808ce81cb..93dc5c88984d 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -300,6 +300,8 @@ public function save(array $form, FormStateInterface $form_state) {
     foreach ($executable->displayHandlers as $id => $display) {
       if (!empty($display->display['new_id']) && $display->display['new_id'] !== $display->display['id'] && empty($display->display['deleted'])) {
         $new_id = $display->display['new_id'];
+        $attachments = $display->getAttachedDisplays();
+        $old_id = $display->display['id'];
         $display->display['id'] = $new_id;
         unset($display->display['new_id']);
         $executable->displayHandlers->set($new_id, $display);
@@ -312,6 +314,16 @@ public function save(array $form, FormStateInterface $form_state) {
           'view' => $view->id(),
           'display_id' => $new_id,
         ]);
+
+        // Find attachments attached to old display id and attach them with new id.
+        if ($attachments) {
+          foreach ($attachments as $attachment) {
+            $attached_options = $executable->displayHandlers->get($attachment)->getOption('displays');
+            unset($attached_options[$old_id]);
+            $attached_options[$new_id] = $new_id;
+            $executable->displayHandlers->get($attachment)->setOption('displays', $attached_options);
+          }
+        }
       }
       elseif (isset($display->display['new_id'])) {
         unset($display->display['new_id']);
diff --git a/core/modules/views_ui/tests/src/Functional/DisplayAttachmentTest.php b/core/modules/views_ui/tests/src/Functional/DisplayAttachmentTest.php
index 346461ed65ab..01c524439391 100644
--- a/core/modules/views_ui/tests/src/Functional/DisplayAttachmentTest.php
+++ b/core/modules/views_ui/tests/src/Functional/DisplayAttachmentTest.php
@@ -103,4 +103,35 @@ public function testRemoveAttachedDisplay() {
 
   }
 
+  /**
+   * Tests the attachment after changing machine name.
+   */
+  public function testAttachmentOnAttachedMachineNameChange(): void {
+
+    $view = $this->randomView();
+    $path_prefix = 'admin/structure/views/view/' . $view['id'] . '/edit';
+    $attachment_display_url = 'admin/structure/views/nojs/display/' . $view['id'] . '/attachment_1/displays';
+
+    // Open the Page display and create the attachment display.
+    $this->drupalGet($path_prefix . '/page_1');
+    $this->submitForm([], 'Add Attachment');
+    $this->assertSession()->pageTextContains('Not defined');
+
+    // Attach the Attachment to the Default and   Page display.
+    $this->drupalGet($attachment_display_url);
+    $this->submitForm(['displays[default]' => 1, 'displays[page_1]' => 1], 'Apply');
+    $this->submitForm([], 'Save');
+
+    // Change the machine name of the page.
+    $this->drupalGet('admin/structure/views/nojs/display/' . $view['id'] . '/page_1/display_id');
+    $this->submitForm(['display_id' => 'page_new_id'], 'Apply');
+    $this->submitForm([], 'Save');
+
+    // Check that the attachment is still attached to the page.
+    $this->drupalGet($attachment_display_url);
+    $this->assertSession()->checkboxChecked("edit-displays-default");
+    $this->assertSession()->checkboxChecked("edit-displays-page-new-id");
+
+  }
+
 }
-- 
GitLab