mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT GridField passes in context for canCreate
This commit is contained in:
parent
c99ed2d262
commit
afd1575267
@ -3,6 +3,8 @@
|
||||
namespace SilverStripe\Forms\GridField;
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\RelationList;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\View\SSViewer;
|
||||
|
||||
@ -35,9 +37,16 @@ class GridFieldAddNewButton implements GridField_HTMLProvider
|
||||
public function getHTMLFragments($gridField)
|
||||
{
|
||||
$singleton = singleton($gridField->getModelClass());
|
||||
$context = [];
|
||||
if ($gridField->getList() instanceof RelationList) {
|
||||
$record = $gridField->getForm()->getRecord();
|
||||
if ($record && $record instanceof DataObject) {
|
||||
$context['Parent'] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$singleton->canCreate()) {
|
||||
return array();
|
||||
if (!$singleton->canCreate(null, $context)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!$this->buttonName) {
|
||||
@ -46,14 +55,14 @@ class GridFieldAddNewButton implements GridField_HTMLProvider
|
||||
$this->buttonName = _t('SilverStripe\\Forms\\GridField\\GridField.Add', 'Add {name}', array('name' => $objectName));
|
||||
}
|
||||
|
||||
$data = new ArrayData(array(
|
||||
$data = new ArrayData([
|
||||
'NewLink' => Controller::join_links($gridField->Link('item'), 'new'),
|
||||
'ButtonName' => $this->buttonName,
|
||||
));
|
||||
]);
|
||||
|
||||
$templates = SSViewer::get_templates_by_class($this, '', __CLASS__);
|
||||
return array(
|
||||
return [
|
||||
$this->targetFragment => $data->renderWith($templates),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -80,11 +80,11 @@ class HasManyList extends RelationList
|
||||
|
||||
// Validate foreignID
|
||||
if (!$foreignID) {
|
||||
user_error("ManyManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
|
||||
user_error("HasManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
if (is_array($foreignID)) {
|
||||
user_error("ManyManyList::add() can't be called on a list linked to mulitple foreign IDs", E_USER_WARNING);
|
||||
user_error("HasManyList::add() can't be called on a list linked to mulitple foreign IDs", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
|
124
tests/php/Forms/GridField/GridFieldAddNewButtonTest.php
Normal file
124
tests/php/Forms/GridField/GridFieldAddNewButtonTest.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Forms\Tests\GridField;
|
||||
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Forms\Form;
|
||||
use SilverStripe\Forms\GridField\GridField;
|
||||
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
|
||||
use SilverStripe\Forms\GridField\GridFieldConfig;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PeopleGroup;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Category;
|
||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
|
||||
class GridFieldAddNewButtonTest extends SapphireTest
|
||||
{
|
||||
protected static $fixture_file = 'GridFieldDetailFormTest.yml';
|
||||
|
||||
protected static $extra_dataobjects = [
|
||||
Person::class,
|
||||
PeopleGroup::class,
|
||||
Category::class,
|
||||
];
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Injector::nest();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
Injector::unnest();
|
||||
}
|
||||
|
||||
public function testButtonPassesParentContextToSingletonWhenRelationListIsUsed()
|
||||
{
|
||||
$group = $this->objFromFixture(PeopleGroup::class, 'group');
|
||||
$list = $group->People();
|
||||
$this->mockSingleton(Person::class)
|
||||
->expects($this->once())
|
||||
->method('canCreate')
|
||||
->with(
|
||||
$this->anything(),
|
||||
$this->callback(function ($arg) use ($group) {
|
||||
return isset($arg['Parent']) && $arg['Parent']->ID == $group->ID;
|
||||
})
|
||||
);
|
||||
|
||||
$this->mockButtonFragments($list, $group);
|
||||
}
|
||||
|
||||
public function testButtonPassesNoParentContextToSingletonWhenRelationListIsNotUsed()
|
||||
{
|
||||
$group = $this->objFromFixture(PeopleGroup::class, 'group');
|
||||
$this->mockSingleton(Person::class)
|
||||
->expects($this->once())
|
||||
->method('canCreate')
|
||||
->with(
|
||||
$this->anything(),
|
||||
$this->callback(function ($arg) {
|
||||
return !isset($arg['Parent']);
|
||||
})
|
||||
);
|
||||
|
||||
$this->mockButtonFragments(Person::get(), $group);
|
||||
}
|
||||
|
||||
public function testButtonPassesNoParentContextToSingletonWhenNoParentRecordExists()
|
||||
{
|
||||
$group = $this->objFromFixture(PeopleGroup::class, 'group');
|
||||
$list = $group->People();
|
||||
|
||||
$this->mockSingleton(Person::class)
|
||||
->expects($this->once())
|
||||
->method('canCreate')
|
||||
->with(
|
||||
$this->anything(),
|
||||
$this->callback(function ($arg) {
|
||||
return !isset($arg['Parent']);
|
||||
})
|
||||
);
|
||||
|
||||
$this->mockButtonFragments($list, null);
|
||||
}
|
||||
|
||||
protected function mockButtonFragments(SS_List $list, $parent = null)
|
||||
{
|
||||
$form = Form::create(
|
||||
new TestController(),
|
||||
'test',
|
||||
FieldList::create(
|
||||
$fakeGrid = GridField::create(
|
||||
'dummy',
|
||||
'dummy',
|
||||
$list,
|
||||
new GridFieldConfig(
|
||||
$button = new GridFieldAddNewButton()
|
||||
)
|
||||
)
|
||||
),
|
||||
FieldList::create()
|
||||
);
|
||||
if ($parent) {
|
||||
$form->loadDataFrom($parent);
|
||||
}
|
||||
|
||||
$button->getHTMLFragments($fakeGrid);
|
||||
}
|
||||
|
||||
protected function mockSingleton($class)
|
||||
{
|
||||
$mock = $this->getMockBuilder($class)
|
||||
->setMethods(['canCreate'])
|
||||
->getMock();
|
||||
Injector::inst()->registerService($mock, $class);
|
||||
|
||||
return $mock;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user