diff --git a/src/Plugin/Field/FieldWidget/ParagraphsWidget.php b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php index 58a1cb4..00a0b97 100644 --- a/src/Plugin/Field/FieldWidget/ParagraphsWidget.php +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php @@ -1502,7 +1502,7 @@ class ParagraphsWidget extends WidgetBase { } // If our mode is remove don't save or reference this entity. // @todo: Maybe we should actually delete it here? - elseif($widget_state['paragraphs'][$item['_original_delta']]['mode'] == 'remove') { + elseif(isset ($widget_state['paragraphs'][$item['_original_delta']]['mode']) && $widget_state['paragraphs'][$item['_original_delta']]['mode'] == 'remove') { $item['target_id'] = NULL; $item['target_revision_id'] = NULL; } diff --git a/src/Tests/Experimental/ParagraphsExperimentalDragAndDropModeTest.php b/src/Tests/Experimental/ParagraphsExperimentalDragAndDropModeTest.php index 65189fc..faf49ba 100644 --- a/src/Tests/Experimental/ParagraphsExperimentalDragAndDropModeTest.php +++ b/src/Tests/Experimental/ParagraphsExperimentalDragAndDropModeTest.php @@ -29,6 +29,8 @@ class ParagraphsExperimentalDragAndDropModeTest extends ParagraphsExperimentalTe $this->addParagraphsField('paragraphs_container', 'paragraphs_container_paragraphs', 'paragraph'); $this->addParagraphsType('paragraph_type_test_1'); $this->addParagraphsType('paragraph_type_test_2'); + $this->addParagraphsType('paragraph_type_test_3'); + $this->addParagraphsType('paragraph_type_test_4'); $this->loginAsAdmin([ 'create paragraphed_test content', @@ -79,8 +81,10 @@ class ParagraphsExperimentalDragAndDropModeTest extends ParagraphsExperimentalTe // Check that the parent of the second text paragraph is the paragraph // container. - $parent_id = Paragraph::load($text_paragraph_2->id())->get('parent_id')->value; - $this->assertEqual($parent_id, $paragraph->id()); + \Drupal::entityTypeManager()->getStorage('paragraph')->resetCache(); + $text_paragraph_2 = Paragraph::load($text_paragraph_2->id()); + $this->assertEqual($text_paragraph_2->get('parent_id')->value, $paragraph->id()); + $this->assertEqual($text_paragraph_2->get('parent_type')->value, 'paragraph'); // Change the path of the second text paragraph to the node as its parent. $this->drupalGet('/node/' . $node->id() . '/edit'); @@ -206,8 +210,10 @@ class ParagraphsExperimentalDragAndDropModeTest extends ParagraphsExperimentalTe // Check that the parent of the text paragraph is the paragraph // container. - $parent_id = Paragraph::load($text_paragraph_1->id())->toArray()['parent_id'][0]['value']; - $this->assertEqual($parent_id, $paragraph->id()); + \Drupal::entityTypeManager()->getStorage('paragraph')->resetCache(); + $text_paragraph_1 = Paragraph::load($text_paragraph_1->id()); + $this->assertEqual($text_paragraph_1->get('parent_id')->value, $paragraph->id()); + $this->assertEqual($text_paragraph_1->get('parent_type')->value, 'paragraph'); // Change the path of the text paragraph to the empty container as its // parent. @@ -227,7 +233,132 @@ class ParagraphsExperimentalDragAndDropModeTest extends ParagraphsExperimentalTe // Check that the parent of the text paragraph is the second paragraph // container. - $parent_id = Paragraph::load($text_paragraph_1->id())->toArray()['parent_id'][0]['value']; - $this->assertEqual($parent_id, $paragraph_1->id()); + \Drupal::entityTypeManager()->getStorage('paragraph')->resetCache(); + $text_paragraph_1 = Paragraph::load($text_paragraph_1->id()); + $this->assertEqual($text_paragraph_1->get('parent_id')->value, $paragraph->id()); + $this->assertEqual($text_paragraph_1->get('parent_type')->value, 'paragraph'); + } + + /** + * Tests drag and drop mode with multiple changes on the paragraphs. + */ + public function testMultipleChangesParagraphs() { + // Create text paragraph. + $text_paragraph_1 = Paragraph::create([ + 'type' => 'paragraph_type_test_1', + 'field_text_demo' => [ + 'value' => '
Test text 1.
', + 'format' => 'basic_html', + ], + ]); + $text_paragraph_1->save(); + + // Create a second text paragraph. + $text_paragraph_2 = Paragraph::create([ + 'type' => 'paragraph_type_test_2', + 'field_text_demo' => [ + 'value' => 'Test text 2.
', + 'format' => 'basic_html', + ], + ]); + $text_paragraph_2->save(); + + // Create container that contains the first two text paragraphs. + $paragraph_1 = Paragraph::create([ + 'title' => 'Test Paragraph 1', + 'type' => 'paragraphs_container', + 'paragraphs_container_paragraphs' => [$text_paragraph_1, $text_paragraph_2], + ]); + $paragraph_1->save(); + + // Create another text paragraph. + $text_paragraph_3 = Paragraph::create([ + 'type' => 'paragraph_type_test_3', + 'field_text_demo' => [ + 'value' => 'Test text 3.
', + 'format' => 'basic_html', + ], + ]); + $text_paragraph_3->save(); + + // Create a container that contains the third text paragraph. + $paragraph_2 = Paragraph::create([ + 'title' => 'Test Paragraph 2', + 'type' => 'paragraphs_container', + 'paragraphs_container_paragraphs' => [$text_paragraph_3], + ]); + $paragraph_2->save(); + + // Create a container that contains the second paragraph. + $paragraph_3 = Paragraph::create([ + 'title' => 'Test Paragraph 3', + 'type' => 'paragraphs_container', + 'paragraphs_container_paragraphs' => [$paragraph_2], + ]); + $paragraph_3->save(); + + // Create an empty container paragraph. + $paragraph_4 = Paragraph::create([ + 'title' => 'Test Paragraph 4', + 'type' => 'paragraphs_container', + 'paragraphs_container_paragraphs' => [], + ]); + $paragraph_4->save(); + + // Create a node with the structure of three nested paragraphs, first + // paragraph with two text paragraphs, second paragraph with a nested + // paragraph containing a text paragraph and the third empty paragraph. + $node = Node::create([ + 'type' => 'paragraphed_test', + 'title' => 'Paragraphs Test', + 'field_paragraphs' => [$paragraph_1, $paragraph_3, $paragraph_4], + ]); + $node->save(); + + \Drupal::entityTypeManager()->getStorage('paragraph')->resetCache(); + // Assert the parent ids of the text paragraphs and the second container. + $text_paragraph_1 = Paragraph::load($text_paragraph_1->id()); + $this->assertEqual($text_paragraph_1->get('parent_id')->value, $paragraph_1->id()); + $this->assertEqual($text_paragraph_1->get('parent_type')->value, 'paragraph'); + + $text_paragraph_3 = Paragraph::load($text_paragraph_3->id()); + $this->assertEqual($text_paragraph_3->get('parent_id')->value, $paragraph_2->id()); + $this->assertEqual($text_paragraph_3->get('parent_type')->value, 'paragraph'); + + $paragraph_3 = Paragraph::load($paragraph_3->id()); + $this->assertEqual($paragraph_3->get('parent_id')->value, $node->id()); + $this->assertEqual($paragraph_3->get('parent_type')->value, 'node'); + + // Edit the node. + $this->drupalGet('/node/' . $node->id() . '/edit'); + $this->drupalPostAjaxForm(NULL, [], 'field_paragraphs_2_subform_paragraphs_container_paragraphs_text_add_more'); + + $this->drupalPostAjaxForm(NULL, [], 'enable_reorder_mode'); + + // Change the structure of the node, third text paragraph goes to first + // container, the first text paragraph goes to the third container and the + // third container goes to the fourth container. + $edit = [ + 'field_paragraphs[1][subform][paragraphs_container_paragraphs][0][subform][paragraphs_container_paragraphs][0][_path]' => 'field_paragraphs][0][subform][paragraphs_container_paragraphs', + 'field_paragraphs[0][subform][paragraphs_container_paragraphs][0][_path]' => 'field_paragraphs[1][subform][paragraphs_container_paragraphs', + 'field_paragraphs[1][_path]' => 'field_paragraphs][2][subform][paragraphs_container_paragraphs', + ]; + $this->drupalPostForm(NULL, $edit, 'Save and keep published'); + + // Reset the cache to make sure that the loaded parents are the new ones. + \Drupal::entityTypeManager()->getStorage('paragraph')->resetCache(); + // Assert the new parents of the text paragraphs. + $text_paragraph_1 = Paragraph::load($text_paragraph_1->id()); + $this->assertEqual($text_paragraph_1->get('parent_id')->value, $paragraph_3->id()); + $this->assertEqual($text_paragraph_1->get('parent_type')->value, 'paragraph'); + + $text_paragraph_3 = Paragraph::load($text_paragraph_3->id()); + $this->assertEqual($text_paragraph_3->get('parent_id')->value, $paragraph_1->id()); + $this->assertEqual($text_paragraph_3->get('parent_type')->value, 'paragraph'); + + // Assert the new parent of the container. + $paragraph_3 =Paragraph::load($paragraph_3->id()); + $this->assertEqual($paragraph_3->get('parent_id')->value, $paragraph_4->id()); + $this->assertEqual($paragraph_3->get('parent_type')->value, 'paragraph'); } }