diff --git a/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php b/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php index 008ef845f14..02b96b8be31 100644 --- a/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php +++ b/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php @@ -18,6 +18,7 @@ use SilverStripe\ORM\FieldType\DBHTMLText; use SilverStripe\ORM\HasManyList; use SilverStripe\ORM\ManyManyList; +use SilverStripe\ORM\PolymorphicHasManyList; use SilverStripe\ORM\RelationList; use SilverStripe\ORM\SS_List; use SilverStripe\ORM\ValidationException; @@ -201,6 +202,12 @@ public function ItemEditForm() $key = $list->getForeignKey(); $id = $list->getForeignID(); $this->record->$key = $id; + // If the list is polymorphic, add the foreign class as well. + if ($list instanceof PolymorphicHasManyList) { + $classKey = $list->getForeignClassKey(); + $class = $list->getForeignClass(); + $this->record->$classKey = $class; + } } if (!$this->record->canView()) { diff --git a/src/ORM/PolymorphicHasManyList.php b/src/ORM/PolymorphicHasManyList.php index 49a51cf9723..20f9907c19c 100644 --- a/src/ORM/PolymorphicHasManyList.php +++ b/src/ORM/PolymorphicHasManyList.php @@ -29,6 +29,14 @@ public function getForeignClass() return $this->dataQuery->getQueryParam('Foreign.Class'); } + /** + * Gets the field name which holds the related object class. + */ + public function getForeignClassKey(): string + { + return $this->classForeignKey; + } + /** * Create a new PolymorphicHasManyList relation list. * diff --git a/tests/php/Forms/GridField/GridFieldDetailFormTest.php b/tests/php/Forms/GridField/GridFieldDetailFormTest.php index b4e1b7e12d5..318711e671a 100644 --- a/tests/php/Forms/GridField/GridFieldDetailFormTest.php +++ b/tests/php/Forms/GridField/GridFieldDetailFormTest.php @@ -5,6 +5,7 @@ use SilverStripe\Control\Controller; use SilverStripe\Dev\CSSContentParser; use SilverStripe\Dev\FunctionalTest; +use SilverStripe\Forms\Form; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldDetailForm; use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest; @@ -14,6 +15,7 @@ use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\GroupController; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PeopleGroup; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person; +use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PolymorphicPeopleGroup; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController; /** @@ -26,6 +28,7 @@ class GridFieldDetailFormTest extends FunctionalTest protected static $extra_dataobjects = [ Person::class, PeopleGroup::class, + PolymorphicPeopleGroup::class, Category::class, ]; @@ -119,6 +122,30 @@ public function testAddForm() $this->assertEquals($count + 1, $group->People()->Count()); } + public function testAddFormWithPolymorphicHasOne() + { + // Log in for permissions check + $this->logInWithPermission('ADMIN'); + // Prepare gridfield and other objects + $group = new PolymorphicPeopleGroup(); + $group->write(); + $gridField = $group->getCMSFields()->dataFieldByName('People'); + $gridField->setForm(new Form()); + $detailForm = $gridField->getConfig()->getComponentByType(GridFieldDetailForm::class); + $record = new Person(); + + // Trigger creation of the item edit form + $reflectionDetailForm = new \ReflectionClass($detailForm); + $reflectionMethod = $reflectionDetailForm->getMethod('getItemRequestHandler'); + $reflectionMethod->setAccessible(true); + $itemrequest = $reflectionMethod->invoke($detailForm, $gridField, $record, new Controller()); + $itemrequest->ItemEditForm(); + + // The polymorphic values should be pre-loaded + $this->assertEquals(PolymorphicPeopleGroup::class, $record->PolymorphicGroupClass); + $this->assertEquals($group->ID, $record->PolymorphicGroupID); + } + public function testViewForm() { $this->logInWithPermission('ADMIN'); diff --git a/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php b/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php index 0caf52d1c9d..9b76b3d2c23 100644 --- a/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php +++ b/tests/php/Forms/GridField/GridFieldDetailFormTest/Person.php @@ -18,7 +18,8 @@ class Person extends DataObject implements TestOnly ]; private static $has_one = [ - 'Group' => PeopleGroup::class + 'Group' => PeopleGroup::class, + 'PolymorphicGroup' => DataObject::class, ]; private static $many_many = [ diff --git a/tests/php/Forms/GridField/GridFieldDetailFormTest/PolymorphicPeopleGroup.php b/tests/php/Forms/GridField/GridFieldDetailFormTest/PolymorphicPeopleGroup.php new file mode 100644 index 00000000000..ca5a5e617b5 --- /dev/null +++ b/tests/php/Forms/GridField/GridFieldDetailFormTest/PolymorphicPeopleGroup.php @@ -0,0 +1,38 @@ + 'Varchar' + ]; + + private static $has_many = [ + 'People' => Person::class + ]; + + private static $default_sort = '"Name"'; + + public function getCMSFields() + { + $fields = parent::getCMSFields(); + $fields->replaceField( + 'People', + GridField::create( + 'People', + 'People', + $this->People(), + GridFieldConfig_RelationEditor::create() + ) + ); + return $fields; + } +} diff --git a/tests/php/ORM/PolymorphicHasManyListTest.php b/tests/php/ORM/PolymorphicHasManyListTest.php index 20e5c1fdfe8..916166cee10 100644 --- a/tests/php/ORM/PolymorphicHasManyListTest.php +++ b/tests/php/ORM/PolymorphicHasManyListTest.php @@ -110,4 +110,11 @@ public function testRemoveRelation() $this->assertEmpty($subteam1fan->FavouriteID); $this->assertEmpty($subteam1fan->FavouriteClass); } + + public function testGetForeignClassKey(): void + { + $team = $this->objFromFixture(DataObjectTest\Team::class, 'team1'); + $list = $team->Fans(); + $this->assertSame('FavouriteClass', $list->getForeignClassKey()); + } }