Skip to content

Instantly share code, notes, and snippets.

@mlewis-everley
Last active November 21, 2022 02:58
Show Gist options
  • Save mlewis-everley/e3608e2e814ca55f50da4454a62d9bbf to your computer and use it in GitHub Desktop.
Save mlewis-everley/e3608e2e814ca55f50da4454a62d9bbf to your computer and use it in GitHub Desktop.
Version of SilverStripe GridField that checks canView permissions before handing records over to components
---
Name: appconfig
---
# ...
SilverStripe\Core\Injector\Injector:
SilverStripe\Forms\GridField\GridField:
class: App\Forms\GridField\PermissableGridField
<?php
namespace App\Forms\GridField;
use SilverStripe\ORM\SS_List;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_DataManipulator;
/**
* Custom gridfield that applies canView permissions to list before manipulation
*
*/
class PermissableGridField extends GridField
{
/**
* Data source after manipulation
*
* @var \SilverStripe\ORM\SS_List
*/
protected $manipulated_list;
/**
* Get the data source, check view permissions and then
* apply every {@link GridField_DataManipulator} to it.
*
* @return SS_List
*/
public function getManipulatedList()
{
// Return cached list if set
if (!empty($this->manipulated_list)) {
return $this->manipulated_list;
}
$list = $this->getList();
if ($list->exists()) {
$allowed = [];
// Ensure list is filtered by canView state first
foreach ($list as $item) {
if ($item->hasMethod('canView') && $item->canView()) {
$allowed[] = $item->ID;
}
}
$list = $list->filter("ID", $allowed);
}
foreach ($this->getComponents() as $item) {
if ($item instanceof GridField_DataManipulator) {
$list = $item->getManipulatedData($this, $list);
}
}
// Set cached list and return
$this->setManipulatedList($list);
return $list;
}
/**
* Set data source after manipulation
*
* @param \SilverStripe\ORM\SS_List $manipulated_list list of data
*
* @return self
*/
public function setManipulatedList(SS_List $list)
{
$this->manipulated_list = $list;
return $this;
}
}
@samandeggs
Copy link

If anyone sees this, and simply wants to apply this to the Security section, a simple fix is the following:

SecurityAdminExtension.php

<?php

use SilverStripe\Forms\Form;
use SilverStripe\ORM\DataExtension;
use SilverStripe\Security\Member;

class SecurityAdminExtension extends DataExtension
{
    public function updateEditForm(Form $form)
    {
        $fields = $form->Fields();

        $members = $fields->dataFieldByName('Members');

        if ($members) {
            $members->setList(Member::get()->filterByCallback(fn ($Member) => $Member->canView()));
        }

        return $form;
    }
}

and add the following to your extensions.yml

SilverStripe\Admin\SecurityAdmin:
  extensions:
    - SecurityAdminExtension

Can get you over the line from a super ugly grid field breaking when you have some custom permissions on the Security visibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment