diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php b/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php index bd176e0b2387a26fcf020379bbdef0a104a83b4d..1ddcd0354faa5a54d7be1fbc197c418426cbf222 100644 --- a/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php +++ b/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php @@ -326,7 +326,10 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF // to be referenced otherwise we set the variable to false. /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler */ $handler = $this->selectionManager->getInstance($options); - $have_multiple_existing_entities = count($handler->getReferenceableEntities(NULL, 'CONTAINS', 2)) > 1; + // getReferenceableEntities() groups results by bundle, so flatten before + // counting — otherwise a single bundle with many entities counts as 1. + $reference_items = $handler->getReferenceableEntities(NULL, 'CONTAINS', 2); + $have_multiple_existing_entities = array_sum(array_map('count', $reference_items)) > 1; } else { $have_multiple_existing_entities = FALSE; diff --git a/tests/src/FunctionalJavascript/ComplexWidgetTest.php b/tests/src/FunctionalJavascript/ComplexWidgetTest.php index a2b7ab6fc1c103a1738f2abd026142e35a84ee5d..2672a6a497188769260e35e8cfd99bd3bf813712 100644 --- a/tests/src/FunctionalJavascript/ComplexWidgetTest.php +++ b/tests/src/FunctionalJavascript/ComplexWidgetTest.php @@ -847,6 +847,43 @@ class ComplexWidgetTest extends InlineEntityFormTestBase { $this->assertTrue($this->drupalGetNodeByTitle($title5) instanceof NodeInterface, "Fifth inline entity still exists."); } + /** + * Tests the Remove button on a required single-bundle field. + * + * With one entity referenced and other referenceable entities available, the + * Remove button must still appear so the reference can be replaced. + * + * Regression test for #3469864: getReferenceableEntities() groups results by + * bundle, so a naive count of the outer array reports 1 for a single-bundle + * field no matter how many entities that bundle contains, which incorrectly + * suppressed the Remove button on required fields. + */ + public function testRemoveButtonWithSingleBundleMultipleEntities() { + $assert_session = $this->assertSession(); + + // Only allow selecting existing entities — this is the branch that + // consults getReferenceableEntities() to decide whether the last + // reference on a required field can be replaced. + $this->updateSetting('allow_new', FALSE); + $this->updateSetting('allow_existing', TRUE); + + // Create multiple referenceable entities in the one target bundle. + $referenceNodes = $this->createReferenceContent(3); + + // Reference exactly one of them on the parent node, so entities_count == 1 + // and the Remove button depends on $have_multiple_existing_entities. + $this->drupalCreateNode([ + 'type' => 'ief_test_complex', + 'title' => 'Single ref parent', + 'multi' => [reset($referenceNodes)], + ]); + $parent_node = $this->drupalGetNodeByTitle('Single ref parent'); + + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + $assert_session->elementsCount('css', 'tr.ief-row-entity', 1); + $assert_session->elementExists('xpath', '(//input[@value="Remove"])[1]'); + } + /** * Checks that nested IEF entity references can be edited and saved. *