From 9944b67632ffa4ebca7647dc16ee58d2d7442fe0 Mon Sep 17 00:00:00 2001 From: Michal Kleiner Date: Wed, 11 Dec 2019 15:50:13 +1300 Subject: [PATCH] FIX GridFieldOrderableRows to support polymorphic ManyManyThroughList --- src/GridFieldOrderableRows.php | 22 ++++++++++-- tests/GridFieldOrderableRowsTest.php | 44 +++++++++++++++++++++++- tests/OrderablePolymorphicManyToMany.yml | 28 +++++++++++++++ tests/Stub/PolymorphM2MChild.php | 15 ++++++++ tests/Stub/PolymorphM2MMapper.php | 22 ++++++++++++ tests/Stub/PolymorphM2MParent.php | 19 ++++++++++ 6 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 tests/OrderablePolymorphicManyToMany.yml create mode 100644 tests/Stub/PolymorphM2MChild.php create mode 100644 tests/Stub/PolymorphM2MMapper.php create mode 100644 tests/Stub/PolymorphM2MParent.php diff --git a/src/GridFieldOrderableRows.php b/src/GridFieldOrderableRows.php index 24029d9..58ca56d 100755 --- a/src/GridFieldOrderableRows.php +++ b/src/GridFieldOrderableRows.php @@ -715,7 +715,7 @@ class GridFieldOrderableRows extends RequestHandler implements $introspector->getExtraFields() : DataObjectSchema::create()->fieldSpecs($introspector->getJoinClass(), DataObjectSchema::DB_ONLY); $key = $introspector->getLocalKey(); - $foreignKey = $introspector->getForeignKey(); + $foreignKey = $this->getManyManyInspectorForeignKey($introspector); $foreignID = (int) $list->getForeignID(); if ($extra && array_key_exists($this->getSortField(), $extra)) { @@ -755,6 +755,24 @@ class GridFieldOrderableRows extends RequestHandler implements return $inspector; } + + /** + * Depending on the list inspector and the list itself (ManyMany vs ManyManyThrough), the method to obtain + * the foreign key may be different. + * + * @param $inspector + * @return string + */ + private function getManyManyInspectorForeignKey($inspector) + { + if (($inspector instanceof ManyManyThroughQueryManipulator) && (method_exists($inspector, 'getForeignIDKey'))) { + // This method has been introduced in framework 4.1 + return $inspector->getForeignIDKey(); + } + + return $inspector->getForeignKey(); + } + /** * Used to get sort orders from a many many through list relationship record, rather than the current * record itself. @@ -768,7 +786,7 @@ class GridFieldOrderableRows extends RequestHandler implements // Find the foreign key name, ID and class to look up $joinClass = $manipulator->getJoinClass(); - $fromRelationName = $manipulator->getForeignKey(); + $fromRelationName = $this->getManyManyInspectorForeignKey($manipulator); $toRelationName = $manipulator->getLocalKey(); // Create a list of the MMTL relations diff --git a/tests/GridFieldOrderableRowsTest.php b/tests/GridFieldOrderableRowsTest.php index dd71b07..e9ce1d4 100644 --- a/tests/GridFieldOrderableRowsTest.php +++ b/tests/GridFieldOrderableRowsTest.php @@ -7,6 +7,9 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; use Symbiote\GridFieldExtensions\GridFieldOrderableRows; +use Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MChild; +use Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MMapper; +use Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MParent; use Symbiote\GridFieldExtensions\Tests\Stub\StubOrderableChild; use Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered; use Symbiote\GridFieldExtensions\Tests\Stub\StubOrderedVersioned; @@ -25,10 +28,14 @@ class GridFieldOrderableRowsTest extends SapphireTest { protected static $fixture_file = [ 'GridFieldOrderableRowsTest.yml', - 'OrderableRowsThroughTest.yml' + 'OrderableRowsThroughTest.yml', + // 'OrderablePolymorphicManyToMany.yml' // TODO: introduce this tests in the next minor release ]; protected static $extra_dataobjects = [ + // PolymorphM2MChild::class, + // PolymorphM2MMapper::class, + // PolymorphM2MParent::class, StubParent::class, StubOrdered::class, StubSubclass::class, @@ -46,6 +53,7 @@ class GridFieldOrderableRowsTest extends SapphireTest return [ [StubParent::class . '.parent', 'MyManyMany', 'ManyManySort'], [ThroughDefiner::class . '.DefinerOne', 'Belongings', 'Sort'], + // [PolymorphM2MParent::class . '.ParentOne', 'Children', 'Sort'] ]; } @@ -122,6 +130,40 @@ class GridFieldOrderableRowsTest extends SapphireTest ); } + public function testPolymorphicManyManyListSortOrdersAreUsedForInitialRender() + { + $this->markTestSkipped('TODO: Introduce this test in the next minor release (3.3)'); + + $record = $this->objFromFixture(PolymorphM2MParent::class, 'ParentOne'); + + $orderable = new GridFieldOrderableRows('Sort'); + $config = new GridFieldConfig_RelationEditor(); + $config->addComponent($orderable); + + $grid = new GridField( + 'Children', + 'Testing Polymorphic Many Many', + $record->Children()->sort('Sort'), + $config + ); + + // Get the first record, which would be the first one to have column contents generated + $intermediary = $this->objFromFixture(PolymorphM2MMapper::class, 'MapP1ToC1'); + + $result = $orderable->getColumnContent($grid, $record, 'irrelevant'); + + $this->assertContains( + 'Children[GridFieldEditableColumns][' . $record->ID . '][Sort]', + $result, + 'The field name is indexed under the record\'s ID' + ); + $this->assertContains( + 'value="' . $intermediary->Sort . '"', + $result, + 'The value comes from the MMTL intermediary Sort value' + ); + } + public function testSortableChildClass() { $orderable = new GridFieldOrderableRows('Sort'); diff --git a/tests/OrderablePolymorphicManyToMany.yml b/tests/OrderablePolymorphicManyToMany.yml new file mode 100644 index 0000000..e69fd81 --- /dev/null +++ b/tests/OrderablePolymorphicManyToMany.yml @@ -0,0 +1,28 @@ +Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MParent: + ParentOne: + ParentTwo: + +Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MChild: + ChildOne: + ChildTwo: + +Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MMapper: + MapP1ToC1: + Parent: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MParent.ParentOne' + Child: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MChild.ChildOne' + Sort: 1 + + MapP1ToC2: + Parent: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MParent.ParentOne' + Child: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MChild.ChildTwo' + Sort: 2 + + MapP2ToC1: + Parent: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MParent.ParentTwo' + Child: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MChild.ChildOne' + Sort: 2 + + MapP2ToC2: + Parent: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MParent.ParentTwo' + Child: '=>Symbiote\GridFieldExtensions\Tests\Stub\PolymorphM2MChild.ChildTwo' + Sort: 1 \ No newline at end of file diff --git a/tests/Stub/PolymorphM2MChild.php b/tests/Stub/PolymorphM2MChild.php new file mode 100644 index 0000000..3d0b8ee --- /dev/null +++ b/tests/Stub/PolymorphM2MChild.php @@ -0,0 +1,15 @@ + PolymorphM2MMapper::class + ]; +} diff --git a/tests/Stub/PolymorphM2MMapper.php b/tests/Stub/PolymorphM2MMapper.php new file mode 100644 index 0000000..acf100a --- /dev/null +++ b/tests/Stub/PolymorphM2MMapper.php @@ -0,0 +1,22 @@ + 'Int' + ]; + + private static $has_one = [ + 'Parent' => DataObject::class, // PolymorphM2MParent + 'Child' => PolymorphM2MChild::class, + ]; + + private static $default_sort = '"Sort" ASC'; +} diff --git a/tests/Stub/PolymorphM2MParent.php b/tests/Stub/PolymorphM2MParent.php new file mode 100644 index 0000000..a57a9c7 --- /dev/null +++ b/tests/Stub/PolymorphM2MParent.php @@ -0,0 +1,19 @@ + [ + 'through' => PolymorphM2MMapper::class, + 'from' => 'Parent', + 'to' => 'Child', + ] + ]; +}