BUGFIX: Allow buttons to opt out of display (#8113)

* Allow buttons to opt out of display

* Linting

* Remove redundant function call

* Add test for group delete action

* Add menu group check and test for delete action

* Fix linting
This commit is contained in:
Aaron Carlino 2018-06-06 21:14:29 +12:00 committed by GitHub
parent b20100c2f6
commit 31ad3cdaab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 170 additions and 7 deletions

View File

@ -64,7 +64,9 @@ class GridFieldDeleteAction implements GridField_ColumnProvider, GridField_Actio
*/
public function getGroup($gridField, $record, $columnName)
{
return GridField_ActionMenuItem::DEFAULT_GROUP;
$field = $this->getRemoveAction($gridField, $record, $columnName);
return $field ? GridField_ActionMenuItem::DEFAULT_GROUP: null;
}
/**

View File

@ -41,6 +41,22 @@ class GridFieldGroupDeleteAction extends GridFieldDeleteAction
return null;
}
/**
* Get the ActionMenu group (not related to Member group)
* @param GridField $gridField
* @param DataObject $record
* @param $columnName
* @return null|string
*/
public function getGroup($gridField, $record, $columnName)
{
if (!$this->canUnlink($record)) {
return null;
}
return parent::getGroup($gridField, $record, $columnName);
}
/**
* Handle the actions and apply any changes to the GridField
*

View File

@ -31,15 +31,21 @@ class GridField_ActionMenu implements GridField_ColumnProvider, GridField_Action
return null;
}
$schema = array_map(function (GridField_ActionMenuItem $item) use ($gridField, $record, $columnName) {
return [
$schema = [];
/* @var GridField_ActionMenuItem $item */
foreach ($items as $item) {
$group = $item->getGroup($gridField, $record, $columnName);
if (!$group) {
continue;
}
$schema[] = [
'type' => $item instanceof GridField_ActionMenuLink ? 'link' : 'submit',
'title' => $item->getTitle($gridField, $record, $columnName),
'url' => $item instanceof GridField_ActionMenuLink ? $item->getUrl($gridField, $record, $columnName) : null,
'group' => $item->getGroup($gridField, $record, $columnName),
'group' => $group,
'data' => $item->getExtraData($gridField, $record, $columnName),
];
}, $items);
}
$templateData = ArrayData::create([
'Schema' => Convert::raw2json($schema),

View File

@ -40,14 +40,15 @@ interface GridField_ActionMenuItem extends GridFieldComponent
public function getExtraData($gridField, $record, $columnName);
/**
* Gets the group this menu item will belong to
* Gets the group this menu item will belong to. A null value should indicate
* the button should not display.
*
* @see {@link GridField_ActionMenu->getColumnContent()}
*
* @param GridField $gridField
* @param DataObject $record
*
* @return string $group
* @return string|null $group
*/
public function getGroup($gridField, $record, $columnName);
}

View File

@ -12,6 +12,7 @@ use SilverStripe\Forms\GridField\GridField_ActionMenu;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldEditButton;
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
use SilverStripe\Forms\Tests\GridField\GridFieldConfigTest\MyActionMenuItemComponent;
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader;
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Permissions;
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Player;
@ -84,6 +85,42 @@ class GridFieldActionMenuTest extends SapphireTest
);
}
public function testHiddenActionMenuItems()
{
$config = GridFieldConfig::create()
->addComponent(new MyActionMenuItemComponent(true))
->addComponent(new GridFieldDeleteAction())
->addComponent($menu = new GridField_ActionMenu());
$this->gridField->setConfig($config);
$html = $menu->getColumnContent($this->gridField, new Team(), 'test');
$content = new CSSContentParser($html);
/* @var \SimpleXMLElement $node */
$node = $content->getBySelector('.gridfield-actionmenu__container');
$this->assertNotNull($node);
$this->assertCount(1, $node);
$schema = (string) $node[0]->attributes()['data-schema'];
$json = json_decode($schema, true);
$this->assertCount(2, $json);
// Now set the component to not display
$config = GridFieldConfig::create()
->addComponent(new MyActionMenuItemComponent(false))
->addComponent(new GridFieldDeleteAction())
->addComponent($menu = new GridField_ActionMenu());
$this->gridField->setConfig($config);
$html = $menu->getColumnContent($this->gridField, new Team(), 'test');
$content = new CSSContentParser($html);
/* @var \SimpleXMLElement $node */
$node = $content->getBySelector('.gridfield-actionmenu__container');
$this->assertNotNull($node);
$this->assertCount(1, $node);
$schema = (string) $node[0]->attributes()['data-schema'];
$json = json_decode($schema, true);
$this->assertCount(1, $json);
}
public function testShowEditLinksWithAdminPermission()
{
$this->logInWithPermission('ADMIN');

View File

@ -0,0 +1,22 @@
<?php
namespace SilverStripe\Forms\Tests\GridField\GridFieldConfigTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\GridField\GridField_ActionMenuItem;
use SilverStripe\Forms\GridField\GridFieldEditButton;
class MyActionMenuItemComponent extends GridFieldEditButton implements TestOnly
{
protected $shouldDisplay;
public function __construct($shouldDisplay = true)
{
$this->shouldDisplay = $shouldDisplay;
}
public function getGroup($gridField, $record, $columnName)
{
return $this->shouldDisplay ? GridField_ActionMenuItem::DEFAULT_GROUP : null;
}
}

View File

@ -214,4 +214,20 @@ class GridFieldDeleteActionTest extends SapphireTest
$gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request);
$this->assertEquals(2, $this->list->count(), 'User should be able to delete records with ADMIN permission.');
}
public function testMenuGroup()
{
$this->logInWithPermission('ADMIN');
$config = GridFieldConfig::create()->addComponent($action = new GridFieldDeleteAction(true));
$gridField = new GridField('testfield', 'testfield', $this->list, $config);
new Form(null, 'mockform', new FieldList(array($gridField)), new FieldList());
$group = $action->getGroup($gridField, $this->list->first(), 'dummy');
$this->assertNotNull($group, 'A menu group exists when the user can delete');
$this->logOut();
$group = $action->getGroup($gridField, $this->list->first(), 'dummy');
$this->assertNull($group, 'A menu group does not exist when the user cannot delete');
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace SilverStripe\Forms\Tests\GridField;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldGroupDeleteAction;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
class GridFieldGroupDeleteActionTest extends SapphireTest
{
protected static $fixture_file = 'GridFieldGroupDeleteActionTest.yml';
public function testCanUnlink()
{
/* @var Group $group*/
$group = $this->objFromFixture(Group::class, 'admingroup');
/* @var Group $othergroup*/
$othergroup = $this->objFromFixture(Group::class, 'otheradmingroup');
/* @var Member $member */
$member = $this->objFromFixture(Member::class, 'admin');
Security::setCurrentUser($member);
$gridField = GridField::create('test');
Form::create(null, 'dummy', FieldList::create($gridField), FieldList::create());
$button = new GridFieldGroupDeleteAction($group->ID);
$actionGroup = $button->getGroup($gridField, $member, 'dummy');
$column = $button->getColumnContent($gridField, $member, 'dummy');
$this->assertNotNull($actionGroup, 'The unlink action has a menu group if the member has another admin group');
$this->assertNotNull($column, 'The unlink action has a column content if the member has another admin group');
$member->Groups()->remove($othergroup);
$actionGroup = $button->getGroup($gridField, $member, 'dummy');
$column = $button->getColumnContent($gridField, $member, 'dummy');
$this->assertNull($actionGroup, 'The unlink action has no menu group if the member has no other admin group');
$this->assertNull($column, 'The unlink action has no column content if the member has no other admin group');
}
}

View File

@ -0,0 +1,18 @@
'SilverStripe\Security\Group':
admingroup:
Code: admingroup
otheradmingroup:
Code: otheradmingroup
SilverStripe\Security\Member:
admin:
FirstName: Admin
Groups:
- '=>SilverStripe\Security\Group.admingroup'
- '=>SilverStripe\Security\Group.otheradmingroup'
'SilverStripe\Security\Permission':
admincode:
Code: ADMIN
Group: '=>SilverStripe\Security\Group.admingroup'
otheradmincode:
Code: ADMIN
Group: '=>SilverStripe\Security\Group.otheradmingroup'