FIX GridFieldOrderableRows to support polymorphic ManyManyThroughList

This commit is contained in:
Michal Kleiner 2019-12-11 15:50:13 +13:00 committed by Serge Latyntcev
parent a710c81941
commit 9944b67632
6 changed files with 147 additions and 3 deletions

View File

@ -715,7 +715,7 @@ class GridFieldOrderableRows extends RequestHandler implements
$introspector->getExtraFields() : $introspector->getExtraFields() :
DataObjectSchema::create()->fieldSpecs($introspector->getJoinClass(), DataObjectSchema::DB_ONLY); DataObjectSchema::create()->fieldSpecs($introspector->getJoinClass(), DataObjectSchema::DB_ONLY);
$key = $introspector->getLocalKey(); $key = $introspector->getLocalKey();
$foreignKey = $introspector->getForeignKey(); $foreignKey = $this->getManyManyInspectorForeignKey($introspector);
$foreignID = (int) $list->getForeignID(); $foreignID = (int) $list->getForeignID();
if ($extra && array_key_exists($this->getSortField(), $extra)) { if ($extra && array_key_exists($this->getSortField(), $extra)) {
@ -755,6 +755,24 @@ class GridFieldOrderableRows extends RequestHandler implements
return $inspector; 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 * Used to get sort orders from a many many through list relationship record, rather than the current
* record itself. * record itself.
@ -768,7 +786,7 @@ class GridFieldOrderableRows extends RequestHandler implements
// Find the foreign key name, ID and class to look up // Find the foreign key name, ID and class to look up
$joinClass = $manipulator->getJoinClass(); $joinClass = $manipulator->getJoinClass();
$fromRelationName = $manipulator->getForeignKey(); $fromRelationName = $this->getManyManyInspectorForeignKey($manipulator);
$toRelationName = $manipulator->getLocalKey(); $toRelationName = $manipulator->getLocalKey();
// Create a list of the MMTL relations // Create a list of the MMTL relations

View File

@ -7,6 +7,9 @@ use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use Symbiote\GridFieldExtensions\GridFieldOrderableRows; 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\StubOrderableChild;
use Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered; use Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered;
use Symbiote\GridFieldExtensions\Tests\Stub\StubOrderedVersioned; use Symbiote\GridFieldExtensions\Tests\Stub\StubOrderedVersioned;
@ -25,10 +28,14 @@ class GridFieldOrderableRowsTest extends SapphireTest
{ {
protected static $fixture_file = [ protected static $fixture_file = [
'GridFieldOrderableRowsTest.yml', 'GridFieldOrderableRowsTest.yml',
'OrderableRowsThroughTest.yml' 'OrderableRowsThroughTest.yml',
// 'OrderablePolymorphicManyToMany.yml' // TODO: introduce this tests in the next minor release
]; ];
protected static $extra_dataobjects = [ protected static $extra_dataobjects = [
// PolymorphM2MChild::class,
// PolymorphM2MMapper::class,
// PolymorphM2MParent::class,
StubParent::class, StubParent::class,
StubOrdered::class, StubOrdered::class,
StubSubclass::class, StubSubclass::class,
@ -46,6 +53,7 @@ class GridFieldOrderableRowsTest extends SapphireTest
return [ return [
[StubParent::class . '.parent', 'MyManyMany', 'ManyManySort'], [StubParent::class . '.parent', 'MyManyMany', 'ManyManySort'],
[ThroughDefiner::class . '.DefinerOne', 'Belongings', 'Sort'], [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() public function testSortableChildClass()
{ {
$orderable = new GridFieldOrderableRows('Sort'); $orderable = new GridFieldOrderableRows('Sort');

View File

@ -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

View File

@ -0,0 +1,15 @@
<?php
namespace Symbiote\GridFieldExtensions\Tests\Stub;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class PolymorphM2MChild extends DataObject implements TestOnly
{
private static $table_name = 'TestOnly_PolymorphM2MChild';
private static $has_many = [
'Parents' => PolymorphM2MMapper::class
];
}

View File

@ -0,0 +1,22 @@
<?php
namespace Symbiote\GridFieldExtensions\Tests\Stub;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class PolymorphM2MMapper extends DataObject implements TestOnly
{
private static $table_name = 'TestOnly_PolymorphM2MMapper';
private static $db = [
'Sort' => 'Int'
];
private static $has_one = [
'Parent' => DataObject::class, // PolymorphM2MParent
'Child' => PolymorphM2MChild::class,
];
private static $default_sort = '"Sort" ASC';
}

View File

@ -0,0 +1,19 @@
<?php
namespace Symbiote\GridFieldExtensions\Tests\Stub;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class PolymorphM2MParent extends DataObject implements TestOnly
{
private static $table_name = 'TableOnly_PolymorphM2MParent';
private static $many_many = [
'Children' => [
'through' => PolymorphM2MMapper::class,
'from' => 'Parent',
'to' => 'Child',
]
];
}