mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE Security admin supports adding, removing and searching for members by relations via gridfield
This contains some experimental API's when using GridFieldPopupForms on GridFieldPopupForms. - GridFieldRelationAdd - GridFieldRelationDelete
This commit is contained in:
parent
3f682531e6
commit
c396c2d2ae
14
admin/code/SecurityAdmin.php
Normal file → Executable file
14
admin/code/SecurityAdmin.php
Normal file → Executable file
@ -107,12 +107,14 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
|
||||
* @return FieldList
|
||||
*/
|
||||
function RootForm() {
|
||||
$memberList = new MemberTableField(
|
||||
$this,
|
||||
"Members"
|
||||
);
|
||||
// unset 'inlineadd' permission, we don't want inline addition
|
||||
$memberList->setPermissions(array('edit', 'delete', 'add'));
|
||||
$config = new GridFieldConfig();
|
||||
$config->addComponent(new GridFieldRelationAdd('Name'));
|
||||
$config->addComponent(new GridFieldDefaultColumns());
|
||||
$config->addComponent(new GridFieldSortableHeader());
|
||||
$config->addComponent(new GridFieldPaginator());
|
||||
$config->addComponent(new GridFieldAction_Edit());
|
||||
$config->addComponent(new GridFieldPopupForms($this, 'RootForm'));
|
||||
$memberList = new GridField('Members', 'All members', DataList::create('Member'), $config);
|
||||
|
||||
$fields = new FieldList(
|
||||
$root = new TabSet(
|
||||
|
@ -511,7 +511,11 @@ class GridField extends FormField {
|
||||
|
||||
$actionName = $stateChange['actionName'];
|
||||
$args = isset($stateChange['args']) ? $stateChange['args'] : array();
|
||||
$grid->handleAction($actionName, $args, $data);
|
||||
$html = $grid->handleAction($actionName, $args, $data);
|
||||
|
||||
if($html) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
switch($request->getHeader('X-Get-Fragment')) {
|
||||
case 'CurrentField':
|
||||
@ -539,13 +543,13 @@ class GridField extends FormField {
|
||||
*/
|
||||
public function handleAction($actionName, $args, $data) {
|
||||
$actionName = strtolower($actionName);
|
||||
foreach($this->components as $item) {
|
||||
if(!($item instanceof GridField_ActionProvider)) {
|
||||
foreach($this->components as $component) {
|
||||
if(!($component instanceof GridField_ActionProvider)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(in_array($actionName, array_map('strtolower', $item->getActions($this)))) {
|
||||
return $item->handleAction($this, $actionName, $args, $data);
|
||||
if(in_array($actionName, array_map('strtolower', $component->getActions($this)))) {
|
||||
return $component->handleAction($this, $actionName, $args, $data);
|
||||
}
|
||||
}
|
||||
throw new InvalidArgumentException("Can't handle action '$actionName'");
|
||||
@ -564,8 +568,6 @@ class GridField extends FormField {
|
||||
$this->request = $request;
|
||||
$this->setModel($model);
|
||||
|
||||
///
|
||||
|
||||
foreach($this->components as $component) {
|
||||
if(!($component instanceof GridField_URLHandler)) {
|
||||
continue;
|
||||
|
106
forms/gridfield/GridFieldPopupForms.php
Normal file → Executable file
106
forms/gridfield/GridFieldPopupForms.php
Normal file → Executable file
@ -13,16 +13,51 @@ class GridFieldPopupForms implements GridField_URLHandler {
|
||||
* @var String
|
||||
*/
|
||||
protected $template = 'GridFieldItemEditView';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Controller
|
||||
*/
|
||||
protected $popupController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $popupFormName;
|
||||
|
||||
function getURLHandlers($gridField) {
|
||||
return array(
|
||||
'item/$ID' => 'handleItem',
|
||||
'autocomplete' => 'handleAutocomplete',
|
||||
);
|
||||
}
|
||||
|
||||
function handleItem($gridField, $request) {
|
||||
/**
|
||||
* Create a popup component. The two arguments will specify how the popup form's HTML and
|
||||
* behaviour is created. The given controller will be customised, putting the edit form into the
|
||||
* template with the given name.
|
||||
*
|
||||
* The arguments are experimental API's to support partial content to be passed back to whatever
|
||||
* controller who wants to display the getCMSFields
|
||||
*
|
||||
* @param Controller $popupController The controller object that will be used to render the pop-up forms
|
||||
* @param string $popupFormName The name of the edit form to place into the pop-up form
|
||||
*/
|
||||
public function __construct($popupController, $popupFormName) {
|
||||
$this->popupController = $popupController;
|
||||
$this->popupFormName = $popupFormName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $gridField
|
||||
* @param type $request
|
||||
* @return GridFieldPopupForm_ItemRequest
|
||||
*/
|
||||
public function handleItem($gridField, $request) {
|
||||
$record = $gridField->getList()->byId($request->param("ID"));
|
||||
$handler = new GridFieldPopupForm_ItemRequest($gridField, $this, $record);
|
||||
$handler = new GridFieldPopupForm_ItemRequest($gridField, $this, $record, $this->popupController, $this->popupFormName);
|
||||
$handler->setTemplate($this->template);
|
||||
return $handler;
|
||||
}
|
||||
@ -44,12 +79,36 @@ class GridFieldPopupForms implements GridField_URLHandler {
|
||||
|
||||
class GridFieldPopupForm_ItemRequest extends RequestHandler {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var GridField
|
||||
*/
|
||||
protected $gridField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var GridField_URLHandler
|
||||
*/
|
||||
protected $component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var DataObject
|
||||
*/
|
||||
protected $record;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Controller
|
||||
*/
|
||||
protected $popupController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $popupFormName;
|
||||
|
||||
/**
|
||||
* @var String
|
||||
*/
|
||||
@ -57,45 +116,66 @@ class GridFieldPopupForm_ItemRequest extends RequestHandler {
|
||||
|
||||
static $url_handlers = array(
|
||||
'$Action!' => '$Action',
|
||||
'' => 'index',
|
||||
'' => 'edit',
|
||||
);
|
||||
|
||||
function __construct($gridField, $component, $record) {
|
||||
/**
|
||||
*
|
||||
* @param GridFIeld $gridField
|
||||
* @param GridField_URLHandler $component
|
||||
* @param DataObject $record
|
||||
* @param Controller $popupController
|
||||
* @param string $popupFormName
|
||||
*/
|
||||
public function __construct($gridField, $component, $record, $popupController, $popupFormName) {
|
||||
$this->gridField = $gridField;
|
||||
$this->component = $gridField;
|
||||
$this->record = $record;
|
||||
|
||||
$this->popupController = $popupController;
|
||||
$this->popupFormName = $popupFormName;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function Link($action = null) {
|
||||
public function Link($action = null) {
|
||||
return Controller::join_links($this->gridField->Link('item'), $this->record->ID, $action);
|
||||
}
|
||||
|
||||
function edit($request) {
|
||||
$controller = $this->gridField->getForm()->Controller();
|
||||
|
||||
$controller = $this->popupController;
|
||||
|
||||
$return = $this->customise(array(
|
||||
'Backlink' => $controller->Link(),
|
||||
'Backlink' => $this->gridField->getForm()->Controller()->Link(),
|
||||
'ItemEditForm' => $this->ItemEditForm($this->gridField, $request),
|
||||
))->renderWith($this->template);
|
||||
|
||||
if($controller->isAjax()) {
|
||||
return $return;
|
||||
} else {
|
||||
|
||||
// If not requested by ajax, we need to render it within the controller context+template
|
||||
return $controller->customise(array(
|
||||
$this->gridField->getForm()->Name() => $return,
|
||||
$this->popupFormName => $return,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an item edit form. The arguments to getCMSFields() are the popupController and
|
||||
* popupFormName, however this is an experimental API and may change.
|
||||
*
|
||||
* In the future, we will probably need to come up with a tigher object representing a partially
|
||||
* complete controller with gaps for extra functionality. This, for example, would be a better way
|
||||
* of letting Security/login put its log-in form inside a UI specified elsewhere.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
function ItemEditForm() {
|
||||
$request = $this->gridField->getForm()->Controller()->getRequest();
|
||||
$request = $this->popupController->getRequest();
|
||||
$form = new Form(
|
||||
$this,
|
||||
'ItemEditForm',
|
||||
$this->record->getCMSFields(),
|
||||
// WARNING: The arguments passed here are a little arbitrary. This API will need cleanup
|
||||
$this->record->getCMSFields($this->popupController, $this->popupFormName),
|
||||
new FieldList(
|
||||
$saveAction = new FormAction('doSave', _t('GridFieldDetailsForm.Save', 'Save'))
|
||||
)
|
||||
@ -124,7 +204,7 @@ class GridFieldPopupForm_ItemRequest extends RequestHandler {
|
||||
|
||||
$form->sessionMessage($message, 'good');
|
||||
|
||||
return $this->gridField->getForm()->Controller()->redirectBack();
|
||||
return $this->popupController->redirectBack();
|
||||
}
|
||||
|
||||
/**
|
||||
|
198
forms/gridfield/GridFieldRelationAdd.php
Executable file
198
forms/gridfield/GridFieldRelationAdd.php
Executable file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* A GridFieldRelationAdd is responsible for adding objects to another objects
|
||||
* has_many and many_many relation. It will not attach duplicate objects.
|
||||
*
|
||||
* It augments a GridField with fields above the gridfield to search and add
|
||||
* objects to whatever the SS_List passed into the gridfield.
|
||||
*
|
||||
* If the object is set to use autosuggestion it will include jQuery UI
|
||||
* autosuggestion field that searches for current objects that isn't already
|
||||
* attached to the list.
|
||||
*/
|
||||
class GridFieldRelationAdd implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator, GridField_URLHandler {
|
||||
|
||||
/**
|
||||
* Which template to use for rendering
|
||||
*
|
||||
* @var string $itemClass
|
||||
*/
|
||||
protected $itemClass = 'GridFieldRelationAdd';
|
||||
|
||||
/**
|
||||
* Which column that should be used for doing a StartsWith search
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldToSearch = '';
|
||||
|
||||
/**
|
||||
* Use the jQuery.ui.autosuggestion plugin
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $useAutoSuggestion = true;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $fieldToSearch which field on the object in the list should be search
|
||||
* @param bool $autoSuggestion - if you would like to use the javascript autosuggest feature
|
||||
*/
|
||||
public function __construct($fieldToSearch, $autoSuggestion=true) {
|
||||
$this->fieldToSearch = $fieldToSearch;
|
||||
$this->useAutoSuggestion = $autoSuggestion;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return string - HTML
|
||||
*/
|
||||
public function getHTMLFragments($gridField) {
|
||||
$searchState = $gridField->State->GridFieldSearchRelation;
|
||||
|
||||
|
||||
if($this->useAutoSuggestion){
|
||||
Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css');
|
||||
Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang');
|
||||
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery_improvements.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-ui/jquery-ui.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . "/javascript/GridFieldSearch.js");
|
||||
}
|
||||
|
||||
$forTemplate = new ArrayData(array());
|
||||
$forTemplate->Fields = new ArrayList();
|
||||
|
||||
$value = $this->findSingleEntry($gridField, $this->fieldToSearch, $searchState, $gridField->getList()->dataClass);
|
||||
$searchField = new TextField('gridfield_relationsearch', 'Auto Suggest Search field', $value);
|
||||
// Apparently the data-* needs to be double qouted for the jQuery.meta data plugin
|
||||
//
|
||||
$searchField->setAttribute('data-search-url', '\''.Controller::join_links($gridField->Link('search').'\''));
|
||||
|
||||
$findAction = new GridField_Action($gridField, 'gridfield_relationfind', 'Find', 'find', 'find');
|
||||
$addAction = new GridField_Action($gridField, 'gridfield_relationadd', 'Add Relation', 'addto', 'addto');
|
||||
|
||||
// If an object is not found, disable the action
|
||||
if(!is_int($gridField->State->GridFieldAddRelation)) {
|
||||
$addAction->setReadonly(true);
|
||||
}
|
||||
|
||||
$forTemplate->Fields->push($searchField);
|
||||
$forTemplate->Fields->push($findAction);
|
||||
$forTemplate->Fields->push($addAction);
|
||||
return array('before' => $forTemplate->renderWith($this->itemClass));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return array
|
||||
*/
|
||||
public function getActions($gridField) {
|
||||
return array('addto', 'find');
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate the state to either add a new relation, or doing a small search
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param string $actionName
|
||||
* @param string $arguments
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
|
||||
switch($actionName) {
|
||||
case 'addto':
|
||||
if(isset($data['relationID']) && $data['relationID']){
|
||||
$gridField->State->GridFieldAddRelation = $data['relationID'];
|
||||
}
|
||||
$gridField->State->GridFieldSearchRelation = '';
|
||||
break;
|
||||
case 'find' && isset($data['autosuggest_search']):
|
||||
$gridField->State->GridFieldSearchRelation = $data['autosuggest_search'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If an object ID is set, add the object to the list
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param SS_List $dataList
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
|
||||
if(!$gridField->State->GridFieldAddRelation) {
|
||||
return $dataList;
|
||||
}
|
||||
$objectID = Convert::raw2sql($gridField->State->GridFieldAddRelation);
|
||||
if($objectID) {
|
||||
$object = DataObject::get_by_id($dataList->dataclass(), $objectID);
|
||||
if($object) {
|
||||
$dataList->add($object);
|
||||
}
|
||||
}
|
||||
$gridField->State->GridFieldAddRelation = null;
|
||||
return $dataList;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return array
|
||||
*/
|
||||
public function getURLHandlers($gridField) {
|
||||
return array(
|
||||
'search/$ID' => 'doSearch',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param SS_HTTPRequest $request
|
||||
*/
|
||||
public function doSearch($gridField, $request) {
|
||||
$allList = DataList::create($gridField->getList()->dataClass());
|
||||
$results = $allList->subtract($gridField->getList())->filter($this->fieldToSearch.':StartsWith',$request->param('ID'));
|
||||
$results->sort($this->fieldToSearch, 'ASC');
|
||||
|
||||
$json = array();
|
||||
foreach($results as $result) {
|
||||
$json[$result->ID] = $result->{$this->fieldToSearch};
|
||||
}
|
||||
return Convert::array2json($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will provide a StartsWith search that only returns a value if we are
|
||||
* matching ONE object only. We wouldn't want to attach used any object to
|
||||
* the list.
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param string $field
|
||||
* @param string $searchTerm
|
||||
* @param string $dataclass
|
||||
* @return string
|
||||
*/
|
||||
protected function findSingleEntry($gridField, $field, $searchTerm, $dataclass) {
|
||||
$fullList = DataList::create($dataclass);
|
||||
$searchTerm = Convert::raw2sql($searchTerm);
|
||||
if(!$searchTerm) {
|
||||
return;
|
||||
}
|
||||
$existingList = clone $gridField->getList();
|
||||
$searchResults = $fullList->subtract($existingList->limit(0))->filter($field.':StartsWith', $searchTerm);
|
||||
|
||||
// If more than one, skip
|
||||
if($searchResults->count() != 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$gridField->State->GridFieldAddRelation = $searchResults->first()->ID;
|
||||
return $searchResults->first()->$field;
|
||||
}
|
||||
}
|
99
forms/gridfield/GridFieldRelationDelete.php
Normal file
99
forms/gridfield/GridFieldRelationDelete.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* GridFieldRelationDelete
|
||||
*
|
||||
*/
|
||||
class GridFieldRelationDelete implements GridField_ColumnProvider, GridField_ActionProvider {
|
||||
|
||||
/**
|
||||
* Add a column 'UnlinkRelation'
|
||||
*
|
||||
* @param type $gridField
|
||||
* @param array $columns
|
||||
*/
|
||||
public function augmentColumns($gridField, &$columns) {
|
||||
$columns[] = 'UnlinkRelation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return any special attributes that will be used for FormField::createTag()
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param DataObject $record
|
||||
* @param string $columnName
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnAttributes($gridField, $record, $columnName) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't add an title
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param string $columnName
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnMetadata($gridField, $columnName) {
|
||||
if($columnName == 'UnlinkRelation') {
|
||||
return array('title' => '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Which columns are handled by this component
|
||||
*
|
||||
* @param type $gridField
|
||||
* @return type
|
||||
*/
|
||||
public function getColumnsHandled($gridField) {
|
||||
return array('UnlinkRelation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Which GridField actions are this component handling
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return array
|
||||
*/
|
||||
public function getActions($gridField) {
|
||||
return array('unlinkrelation');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param DataObject $record
|
||||
* @param string $columnName
|
||||
* @return string - the HTML for the column
|
||||
*/
|
||||
public function getColumnContent($gridField, $record, $columnName) {
|
||||
$field = new GridField_Action(
|
||||
$gridField,
|
||||
'UnlinkRelation'.$record->ID,
|
||||
_t('GridAction.UnlinkRelation', "Unlink"),
|
||||
"unlinkrelation",
|
||||
array('RecordID' => $record->ID)
|
||||
);
|
||||
$output = $field->Field();
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the actions and apply any changes to the GridField
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param string $actionName
|
||||
* @param mixed $arguments
|
||||
* @param array $data - form data
|
||||
* @return void
|
||||
*/
|
||||
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
|
||||
$id = $arguments['RecordID'];
|
||||
$item = $gridField->getList()->byID($id);
|
||||
if(!$item) return;
|
||||
if($actionName == 'unlinkrelation') {
|
||||
$gridField->getList()->remove($item);
|
||||
}
|
||||
}
|
||||
}
|
36
javascript/GridFieldSearch.js
Normal file
36
javascript/GridFieldSearch.js
Normal file
@ -0,0 +1,36 @@
|
||||
jQuery(function($){
|
||||
|
||||
$(document).delegate("#gridfield_relationsearch", "focus", function (event) {
|
||||
$(this).autocomplete({
|
||||
source: function(request, response){
|
||||
var searchField = $(this.element);
|
||||
var form = $(this.element).closest("form");
|
||||
// Due to some very weird behaviout of jquery.metadata, the url have to be double quoted
|
||||
var suggestionUrl = $(searchField).attr('data-search-url').substr(1,$(searchField).attr('data-search-url').length-2);
|
||||
$.ajax({
|
||||
headers: {
|
||||
"X-Get-Fragment" : 'Partial'
|
||||
},
|
||||
type: "GET",
|
||||
url: suggestionUrl+'/'+request.term,
|
||||
data: form.serialize()+'&'+escape(searchField.attr('name'))+'='+escape(searchField.val()),
|
||||
success: function(data) {
|
||||
response( $.map(JSON.parse(data), function( name, id ) {
|
||||
return { label: name, value: name, id: id }
|
||||
}));
|
||||
},
|
||||
error: function(e) {
|
||||
alert(ss.i18n._t('GRIDFIELD.ERRORINTRANSACTION', 'An error occured while fetching data from the server\n Please try again later.'));
|
||||
}
|
||||
});
|
||||
},
|
||||
select: function(event, ui) {
|
||||
$(this).closest("fieldset.ss-gridfield").find("#action_gridfield_relationfind").replaceWith(
|
||||
'<input type="hidden" name="relationID" value="'+ui.item.id+'" id="relationID"/>'
|
||||
);
|
||||
$(this).closest("fieldset.ss-gridfield").find("#action_gridfield_relationadd").removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
18
security/Group.php
Normal file → Executable file
18
security/Group.php
Normal file → Executable file
@ -62,17 +62,18 @@ class Group extends DataObject {
|
||||
public function getCMSFields() {
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/javascript/PermissionCheckboxSetField.js');
|
||||
|
||||
$config = new GridFieldConfig_ManyManyEditor('FirstName', true, 20);
|
||||
$config->addComponent(new GridFieldPopupForms(Controller::curr(), 'EditForm'));
|
||||
$memberList = new GridField('Members','Members', $this->Members(), $config);
|
||||
|
||||
// @todo Implement permission checking on GridField
|
||||
//$memberList->setPermissions(array('edit', 'delete', 'export', 'add', 'inlineadd'));
|
||||
//$memberList->setPopupCaption(_t('SecurityAdmin.VIEWUSER', 'View User'));
|
||||
$fields = new FieldList(
|
||||
new TabSet("Root",
|
||||
new Tab('Members', _t('SecurityAdmin.MEMBERS', 'Members'),
|
||||
new TextField("Title", $this->fieldLabel('Title')),
|
||||
$memberList = new MemberTableField(
|
||||
(Controller::has_curr()) ? Controller::curr() : new Controller(),
|
||||
"Members",
|
||||
$this,
|
||||
null,
|
||||
false
|
||||
)
|
||||
$memberList
|
||||
),
|
||||
|
||||
$permissionsTab = new Tab('Permissions', _t('SecurityAdmin.PERMISSIONS', 'Permissions'),
|
||||
@ -152,9 +153,6 @@ class Group extends DataObject {
|
||||
$rolesField->setDisabledItems($inheritedRoles->column('ID'));
|
||||
}
|
||||
|
||||
$memberList->setPermissions(array('edit', 'delete', 'export', 'add', 'inlineadd'));
|
||||
$memberList->setPopupCaption(_t('SecurityAdmin.VIEWUSER', 'View User'));
|
||||
|
||||
$fields->push($idField = new HiddenField("ID"));
|
||||
|
||||
$this->extend('updateCMSFields', $fields);
|
||||
|
3
templates/Includes/GridFieldItemEditView.ss
Normal file
3
templates/Includes/GridFieldItemEditView.ss
Normal file
@ -0,0 +1,3 @@
|
||||
<a href="$Backlink"> Go back the way you came!</a>
|
||||
|
||||
$ItemEditForm
|
4
templates/Includes/GridFieldRelationAdd.ss
Normal file
4
templates/Includes/GridFieldRelationAdd.ss
Normal file
@ -0,0 +1,4 @@
|
||||
<div><% control Fields %>
|
||||
<span>$Field</span>
|
||||
<% end_control %>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user