mirror of
https://github.com/symbiote/silverstripe-gridfieldextensions.git
synced 2024-10-22 17:05:39 +02:00
Merge branch '3.2' into 3
This commit is contained in:
commit
74126ed6a7
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
vendor/
|
||||
resources/
|
||||
composer.lock
|
||||
|
||||
assets/
|
45
.travis.yml
45
.travis.yml
@ -1,43 +1,4 @@
|
||||
language: php
|
||||
version: ~> 1.0
|
||||
|
||||
dist: xenial
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- postgresql
|
||||
|
||||
env:
|
||||
global:
|
||||
- COMPOSER_ROOT_VERSION="3.x-dev"
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.6
|
||||
env: DB=MYSQL PHPUNIT_TEST=1 RECIPE_VERSION="^1 --prefer-lowest"
|
||||
- php: 7.0
|
||||
env: DB=MYSQL PHPUNIT_TEST=1 RECIPE_VERSION="^1"
|
||||
- php: 7.1
|
||||
env: DB=PGSQL PHPUNIT_TEST=1 RECIPE_VERSION="^4 --prefer-lowest"
|
||||
- php: 7.2
|
||||
env: DB=MYSQL PHPUNIT_TEST=1 PHPCS_TEST=1 RECIPE_VERSION="^4"
|
||||
- php: 7.3
|
||||
env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1 RECIPE_VERSION="4.x-dev"
|
||||
- php: 7.4
|
||||
env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1 RECIPE_VERSION="4.x-dev"
|
||||
|
||||
before_script:
|
||||
- phpenv rehash
|
||||
- phpenv config-rm xdebug.ini
|
||||
|
||||
- composer validate
|
||||
- composer require silverstripe/recipe-cms:$RECIPE_VERSION --no-update
|
||||
- if [[ $DB == PGSQL ]]; then composer require silverstripe/postgresql:^2 --no-update; fi
|
||||
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
|
||||
|
||||
script:
|
||||
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit tests/; fi
|
||||
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
|
||||
- if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs src/ tests/ *.php; fi
|
||||
|
||||
after_success:
|
||||
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi
|
||||
import:
|
||||
- silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range.yml
|
||||
|
@ -23,7 +23,7 @@
|
||||
"silverstripe/framework": "~4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"sminnee/phpunit": "^5.7",
|
||||
"squizlabs/php_codesniffer": "^3.0",
|
||||
"silverstripe/versioned": "^1"
|
||||
},
|
||||
|
@ -2,6 +2,9 @@
|
||||
<ruleset name="SilverStripe">
|
||||
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
|
||||
|
||||
<file>src</file>
|
||||
<file>tests</file>
|
||||
|
||||
<rule ref="PSR2" >
|
||||
<!-- Current exclusions -->
|
||||
<exclude name="PSR1.Methods.CamelCapsMethodName" />
|
||||
|
@ -13,6 +13,7 @@ use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\DataObjectInterface;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\ORM\ManyManyList;
|
||||
use SilverStripe\ORM\ManyManyThroughList;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\View\Requirements;
|
||||
use Exception;
|
||||
@ -189,9 +190,15 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
|
||||
foreach ($value[self::POST_KEY] as $fields) {
|
||||
/** @var DataObject $item */
|
||||
$item = $class::create();
|
||||
|
||||
// Add the item before the form is loaded so that the join-object is available
|
||||
if ($list instanceof ManyManyThroughList) {
|
||||
$list->add($item);
|
||||
}
|
||||
|
||||
$extra = array();
|
||||
|
||||
$form = $editable->getForm($grid, $record);
|
||||
$form = $editable->getForm($grid, $item);
|
||||
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
||||
$form->saveInto($item);
|
||||
|
||||
@ -205,8 +212,12 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
|
||||
$extra = array_intersect_key($form->getData(), (array) $list->getExtraFields());
|
||||
}
|
||||
|
||||
$item->write();
|
||||
$list->add($item, $extra);
|
||||
$item->write(false, false, false, true);
|
||||
|
||||
// Add non-through lists after the write. many_many_extraFields are added there too
|
||||
if (!($list instanceof ManyManyThroughList)) {
|
||||
$list->add($item, $extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,10 +56,6 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||
|
||||
public function getColumnContent($grid, $record, $col)
|
||||
{
|
||||
if (!$record->canEdit()) {
|
||||
return parent::getColumnContent($grid, $record, $col);
|
||||
}
|
||||
|
||||
$fields = $this->getForm($grid, $record)->Fields();
|
||||
|
||||
if (!$this->displayFields) {
|
||||
@ -82,8 +78,13 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||
$field = clone $field;
|
||||
} else {
|
||||
$value = $grid->getDataFieldValue($record, $col);
|
||||
$rel = (strpos($col, '.') === false); // field references a relation value
|
||||
$field = ($rel) ? clone $fields->fieldByName($col) : new ReadonlyField($col);
|
||||
$field = $fields->dataFieldByName($col);
|
||||
|
||||
// Fall back to previous logic
|
||||
if (!$field) {
|
||||
$rel = (strpos($col, '.') === false); // field references a relation value
|
||||
$field = ($rel) ? clone $fields->fieldByName($col) : new ReadonlyField($col);
|
||||
}
|
||||
|
||||
if (!$field) {
|
||||
throw new Exception("Could not find the field '$col'");
|
||||
@ -99,6 +100,10 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||
$field->setName($this->getFieldName($field->getName(), $grid, $record));
|
||||
$field->setValue($value);
|
||||
|
||||
if ($grid->isReadonly() || !$record->canEdit()) {
|
||||
$field = $field->performReadonlyTransformation();
|
||||
}
|
||||
|
||||
if ($field instanceof HtmlEditorField) {
|
||||
return $field->FieldHolder();
|
||||
}
|
||||
@ -138,10 +143,11 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||
|
||||
$extra = array();
|
||||
|
||||
$form = $this->getForm($grid, $record);
|
||||
$form = $this->getForm($grid, $item);
|
||||
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
||||
$form->saveInto($item);
|
||||
|
||||
|
||||
// Check if we are also sorting these records
|
||||
if ($sortable) {
|
||||
$sortField = $sortable->getSortField();
|
||||
@ -154,7 +160,7 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||
$extra = array_intersect_key($form->getData(), (array) $list->getExtraFields());
|
||||
}
|
||||
|
||||
$item->write();
|
||||
$item->write(false, false, false, true);
|
||||
$list->add($item, $extra);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
94
tests/GridFieldEditableColumnsTest.php
Normal file
94
tests/GridFieldEditableColumnsTest.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Symbiote\GridFieldExtensions\Tests;
|
||||
|
||||
use Symbiote\GridFieldExtensions\Tests\Stub\TestController;
|
||||
use Symbiote\GridFieldExtensions\Tests\Stub\StubUnorderable;
|
||||
use Symbiote\GridFieldExtensions\GridFieldEditableColumns;
|
||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
use SilverStripe\Forms\TextField;
|
||||
use SilverStripe\Forms\GridField\GridField;
|
||||
use SilverStripe\Forms\Form;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
|
||||
class GridFieldEditableColumnsTest extends SapphireTest
|
||||
{
|
||||
private function getMockGrid()
|
||||
{
|
||||
$controller = new TestController('Test');
|
||||
$form = new Form($controller, 'TestForm', new FieldList(
|
||||
$grid = new GridField('TestGridField')
|
||||
), new FieldList());
|
||||
$grid->setModelClass(StubUnorderable::class);
|
||||
$grid->setList(StubUnorderable::get());
|
||||
return $grid;
|
||||
}
|
||||
|
||||
private function getMockRecord($id, $title)
|
||||
{
|
||||
$record = new StubUnorderable();
|
||||
$record->ID = $id;
|
||||
$record->Title = $title;
|
||||
return $record;
|
||||
}
|
||||
|
||||
public function testProvidesEditableFieldsInColumns()
|
||||
{
|
||||
$grid = $this->getMockGrid();
|
||||
$component = new GridFieldEditableColumns();
|
||||
$record = $this->getMockRecord(100, "foo");
|
||||
|
||||
$this->assertEquals(
|
||||
[ 'Title' ],
|
||||
$component->getColumnsHandled($grid)
|
||||
);
|
||||
|
||||
$record->setCanEdit(true);
|
||||
$column = $component->getColumnContent($grid, $record, 'Title');
|
||||
|
||||
$this->assertInstanceOf(DBHTMLText::class, $column);
|
||||
$this->assertRegExp(
|
||||
'/<input type="text" name="TestGridField\[GridFieldEditableColumns\]\[100\]\[Title\]" value="foo"[^>]*>/',
|
||||
$column->getValue()
|
||||
);
|
||||
}
|
||||
|
||||
public function testProvidesReadonlyColumnsForNoneditableRecords()
|
||||
{
|
||||
$grid = $this->getMockGrid();
|
||||
$component = new GridFieldEditableColumns();
|
||||
$record = $this->getMockRecord(100, "testval");
|
||||
|
||||
$record->setCanEdit(false);
|
||||
$column = $component->getColumnContent($grid, $record, 'Title');
|
||||
|
||||
$this->assertInstanceOf(DBHTMLText::class, $column);
|
||||
$this->assertRegExp(
|
||||
'/<span[^>]*>\s*testval\s*<\/span>/',
|
||||
$column->getValue()
|
||||
);
|
||||
}
|
||||
|
||||
public function testProvidesReadonlyColumnsForReadonlyGrids()
|
||||
{
|
||||
$grid = $this->getMockGrid();
|
||||
$component = new GridFieldEditableColumns();
|
||||
$record = $this->getMockRecord(100, "testval");
|
||||
|
||||
$record->setCanEdit(true);
|
||||
$grid = $grid->performReadonlyTransformation();
|
||||
|
||||
if (!$grid instanceof GridField) {
|
||||
$this->markTestSkipped('silverstripe/framework <4.2.2 doesn\'t support readonly GridFields');
|
||||
}
|
||||
|
||||
$column = $component->getColumnContent($grid, $record, 'Title');
|
||||
|
||||
$this->assertInstanceOf(DBHTMLText::class, $column);
|
||||
$this->assertRegExp(
|
||||
'/<span[^>]*>\s*testval\s*<\/span>/',
|
||||
$column->getValue()
|
||||
);
|
||||
}
|
||||
}
|
@ -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');
|
||||
|
28
tests/OrderablePolymorphicManyToMany.yml
Normal file
28
tests/OrderablePolymorphicManyToMany.yml
Normal 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
|
15
tests/Stub/PolymorphM2MChild.php
Normal file
15
tests/Stub/PolymorphM2MChild.php
Normal 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
|
||||
];
|
||||
}
|
22
tests/Stub/PolymorphM2MMapper.php
Normal file
22
tests/Stub/PolymorphM2MMapper.php
Normal 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';
|
||||
}
|
19
tests/Stub/PolymorphM2MParent.php
Normal file
19
tests/Stub/PolymorphM2MParent.php
Normal 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',
|
||||
]
|
||||
];
|
||||
}
|
@ -12,4 +12,16 @@ class StubUnorderable extends DataObject implements TestOnly
|
||||
];
|
||||
|
||||
private static $table_name = 'StubUnorderable';
|
||||
|
||||
private $canEdit = false;
|
||||
|
||||
public function setCanEdit($canEdit)
|
||||
{
|
||||
$this->canEdit = $canEdit;
|
||||
}
|
||||
|
||||
public function canEdit($member = null)
|
||||
{
|
||||
return $this->canEdit;
|
||||
}
|
||||
}
|
||||
|
10
tests/Stub/TestController.php
Normal file
10
tests/Stub/TestController.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
|
||||
class TestController extends Controller
|
||||
{
|
||||
private static $url_segment = 'test';
|
||||
}
|
Loading…
Reference in New Issue
Block a user