From 0117b32fee08f78fe72988226c6e43c90b3f1459 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Mon, 5 Mar 2012 17:35:10 +0100 Subject: [PATCH] API CHANGE Removed MemberTableField, use GridField with GridFieldConfig_RelationEditor instead --- admin/code/MemberTableField.php | 370 ------------------- admin/code/SecurityAdmin.php | 48 --- admin/javascript/MemberTableField.js | 347 ----------------- admin/javascript/MemberTableField_popup.js | 21 -- admin/javascript/SecurityAdmin.js | 65 ++-- admin/templates/Includes/MemberTableField.ss | 62 ---- admin/tests/MemberTableFieldTest.php | 139 ------- admin/tests/MemberTableFieldTest.yml | 31 -- docs/en/changelogs/3.0.0.md | 1 + 9 files changed, 36 insertions(+), 1048 deletions(-) delete mode 100644 admin/code/MemberTableField.php delete mode 100644 admin/javascript/MemberTableField.js delete mode 100644 admin/javascript/MemberTableField_popup.js delete mode 100644 admin/templates/Includes/MemberTableField.ss delete mode 100644 admin/tests/MemberTableFieldTest.php delete mode 100644 admin/tests/MemberTableFieldTest.yml diff --git a/admin/code/MemberTableField.php b/admin/code/MemberTableField.php deleted file mode 100644 index 9309eacc4..000000000 --- a/admin/code/MemberTableField.php +++ /dev/null @@ -1,370 +0,0 @@ -group = $group; - $members = $group->Members(); - - } elseif(isset($_REQUEST['ctf'][$this->getName()]["ID"]) && is_numeric($_REQUEST['ctf'][$this->getName()]["ID"])) { - throw new Exception("Is this still being used? It's a hack and we should remove it."); - $group = DataObject::get_by_id('Group', $_REQUEST['ctf'][$this->getName()]["ID"]); - $this->group = $group; - $members = $group->Members(); - } else { - $members = DataObject::get("Member"); - } - } - - $SNG_member = singleton('Member'); - $fieldList = $SNG_member->summaryFields(); - $memberDbFields = $SNG_member->db(); - $csvFieldList = array(); - - foreach($memberDbFields as $field => $dbFieldType) { - $csvFieldList[$field] = $field; - } - - if(!$hidePassword) { - $fieldList["SetPassword"] = "Password"; - } - - $this->hidePassword = $hidePassword; - - // Add a search filter - $SQL_search = isset($_REQUEST['MemberSearch']) ? Convert::raw2sql($_REQUEST['MemberSearch']) : null; - if(!empty($_REQUEST['MemberSearch'])) { - $searchFilters = array(); - foreach($SNG_member->searchableFields() as $fieldName => $fieldSpec) { - if(strpos($fieldName, '.') === false) $searchFilters[] = "\"$fieldName\" LIKE '%{$SQL_search}%'"; - } - $members = $members->where('(' . implode(' OR ', $searchFilters) . ')'); - } - - parent::__construct($controller, $name, $members, $fieldList); - - $this->setFieldListCsv($csvFieldList); - $this->setPageSize($this->stat('page_size')); - } - - function FieldHolder() { - $ret = parent::FieldHolder(); - - Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/scriptaculous/controls.js"); - Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/javascript/MemberTableField.js'); - Requirements::javascript(SAPPHIRE_ADMIN_DIR . "/javascript/MemberTableField_popup.js"); - - return $ret; - } - - function SearchForm() { - $groupID = (isset($this->group)) ? $this->group->ID : 0; - $query = isset($_GET['MemberSearch']) ? $_GET['MemberSearch'] : null; - - $searchFields = new FieldGroup( - new TextField('MemberSearch', _t('MemberTableField.SEARCH', 'Search'), $query), - new HiddenField("ctf[ID]", '', $groupID), - new HiddenField('MemberFieldName', '', $this->name), - new HiddenField('MemberDontShowPassword', '', $this->hidePassword) - ); - - $actionFields = new LiteralField('MemberFilterButton',''); - - $fieldContainer = new FieldGroup( - $searchFields, - $actionFields - ); - - return $fieldContainer->FieldHolder(); - } - - /** - * Add existing member to group rather than creating a new member - */ - function addtogroup() { - // Protect against CSRF on destructive action - $token = $this->getForm()->getSecurityToken(); - if(!$token->checkRequest($this->controller->getRequest())) return $this->httpError(400); - - $data = $_REQUEST; - - $groupID = (isset($data['ctf']['ID'])) ? $data['ctf']['ID'] : null; - - if(!is_numeric($groupID)) { - FormResponse::status_messsage(_t('MemberTableField.ADDINGFIELD', 'Adding failed'), 'bad'); - return; - } - - // Get existing record either by ID or unique identifier. - $identifierField = Member::get_unique_identifier_field(); - $className = 'Member'; - $record = null; - if(isset($data[$identifierField])) { - $record = DataObject::get_one( - $className, - sprintf('"%s" = \'%s\'', $identifierField, $data[$identifierField]) - ); - - if($record && !$record->canEdit()) return $this->httpError('401'); - } - - // Fall back to creating a new record - if(!$record) $record = new $className(); - - // Update an existing record, or populate a new one. - // If values on an existing (autocompleted) record have been changed, - // they will overwrite current data. We need to unset 'ID' - // record as it points to the group rather than the member record, and would - // cause the member to be written to a potentially existing record. - unset($data['ID']); - $record->update($data); - - // Validate record, mainly password restrictions. - // Note: Doesn't use Member_Validator - $valid = $record->validate(); - if($valid->valid()) { - $record->write(); - $this->getDataList()->add($record); - - $this->sourceItems(); - - // TODO add javascript to highlight added row (problem: might not show up due to sorting/filtering) - FormResponse::update_dom_id($this->id(), $this->renderWith($this->template), true); - FormResponse::status_message( - _t( - 'MemberTableField.ADDEDTOGROUP','Added member to group' - ), - 'good' - ); - - } else { - $message = sprintf( - _t( - 'MemberTableField.ERRORADDINGUSER', - 'There was an error adding the user to the group: %s' - ), - Convert::raw2xml($valid->starredList()) - ); - - FormResponse::status_message($message, 'bad'); - } - - return FormResponse::respond(); - } - - /** - * ################################# - * Custom Functions - * ################################# - */ - - /** - * @return Group - */ - function getGroup() { - return $this->group; - } - - /** - * Add existing member to group by name (with JS-autocompletion) - */ - function AddRecordForm() { - $fields = new FieldList(); - foreach($this->FieldList() as $fieldName => $fieldTitle) { - // If we're adding the set password field, we want to hide the text from any peeping eyes - if($fieldName == 'SetPassword') { - $fields->push(new PasswordField($fieldName)); - } else { - $fields->push(new TextField($fieldName)); - } - } - if($this->group) { - $fields->push(new HiddenField('ctf[ID]', null, $this->group->ID)); - } - $actions = new FieldList( - new FormAction('addtogroup', _t('MemberTableField.ADD','Add')) - ); - - return new TabularStyle( - new NestedForm( - new Form( - $this, - 'AddRecordForm', - $fields, - $actions - ) - ) - ); - } - - function AddForm() { - $form = parent::AddForm(); - - // Set default groups - also implemented in MemberTableField_Popup::__construct() - if($this->group) { - $groupsField = $form->Fields()->dataFieldByName('Groups'); - // TODO Needs to be a string value (not int) because of TreeMultiselectField->getItems(), - // see http://open.silverstripe.org/ticket/5836 - if($groupsField) $groupsField->setValue((string)$this->group->ID); - } - - return $form; - } - - /** - * Same behaviour as parent class, but adds the - * member to the passed GroupID. - * - * @return string - */ - function saveComplexTableField($data, $form, $params) { - $className = $this->sourceClass(); - $childData = new $className(); - - // Needs to write before saveInto() to ensure the 'Groups' TreeMultiselectField saves - $childData->write(); - - try { - $form->saveInto($childData); - $childData->write(); - } catch(ValidationException $e) { - $form->sessionMessage($e->getResult()->message(), 'bad'); - return Director::redirectBack(); - } - - $closeLink = sprintf( - '(%s)', - _t('ComplexTableField.CLOSEPOPUP', 'Close Popup') - ); - $message = sprintf( - _t('ComplexTableField.SUCCESSADD', 'Added %s %s %s'), - $childData->singular_name(), - '' . htmlspecialchars($childData->Title, ENT_QUOTES, 'UTF-8') . '', - $closeLink - ); - $form->sessionMessage($message, 'good'); - - $this->controller->redirectBack(); - } -} - -/** - * Popup window for {@link MemberTableField}. - * @package cms - * @subpackage security - */ -class MemberTableField_Popup extends ComplexTableField_Popup { - - function __construct($controller, $name, $fields, $validator, $readonly, $dataObject) { - $group = ($controller instanceof MemberTableField) ? $controller->getGroup() : $controller->getParentController()->getGroup(); - // Set default groups - also implemented in AddForm() - if($group) { - $groupsField = $fields->dataFieldByName('Groups'); - if($groupsField) $groupsField->setValue($group->ID); - } - - parent::__construct($controller, $name, $fields, $validator, $readonly, $dataObject); - } - - function forTemplate() { - $ret = parent::forTemplate(); - - Requirements::css(SAPPHIRE_ADMIN_DIR . '/css/SecurityAdmin.css'); - Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/javascript/MemberTableField.js'); - Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/javascript/MemberTableField_popup.js'); - - return $ret; - } - -} - -/** -* @package cms -* @subpackage security -*/ -class MemberTableField_Item extends ComplexTableField_Item { - - function Actions() { - $actions = parent::Actions(); - - foreach($actions as $action) { - if($action->Name == 'delete') { - if($this->parent->getGroup()) { - $action->TitleText = _t('MemberTableField.DeleteTitleText', - 'Delete from this group', - PR_MEDIUM, - 'Delete button hover text' - ); - } else { - $action->TitleText = _t('MemberTableField.DeleteTitleTextDatabase', - 'Delete from database and all groups', - PR_MEDIUM, - 'Delete button hover text' - ); - } - } - } - - return $actions; - } -} - diff --git a/admin/code/SecurityAdmin.php b/admin/code/SecurityAdmin.php index 7537b7a64..8e9e62f12 100755 --- a/admin/code/SecurityAdmin.php +++ b/admin/code/SecurityAdmin.php @@ -17,9 +17,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { static $subitem_class = 'Member'; static $allowed_actions = array( - 'autocomplete', - 'removememberfromgroup', - 'AddRecordForm', 'EditForm', 'MemberImportForm', 'memberimport', @@ -223,51 +220,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { return $form; } - public function AddRecordForm() { - $m = Object::create('MemberTableField', - $this, - "Members", - $this->currentPageID() - ); - return $m->AddRecordForm(); - } - - /** - * Ajax autocompletion - */ - public function autocomplete() { - $fieldName = $this->urlParams['ID']; - $fieldVal = $_REQUEST[$fieldName]; - $result = ''; - $uidField = Member::get_unique_identifier_field(); - - // Make sure we only autocomplete on keys that actually exist, and that we don't autocomplete on password - if(!singleton($this->stat('subitem_class'))->hasDatabaseField($fieldName) || $fieldName == 'Password') return; - - $matches = DataObject::get($this->stat('subitem_class'),"\"$fieldName\" LIKE '" . Convert::raw2sql($fieldVal) . "%'"); - if($matches) { - $result .= ""; - return $result; - } - } - function getCMSTreeTitle() { return _t('SecurityAdmin.SGROUPS', 'Security Groups'); } diff --git a/admin/javascript/MemberTableField.js b/admin/javascript/MemberTableField.js deleted file mode 100644 index 1d3516353..000000000 --- a/admin/javascript/MemberTableField.js +++ /dev/null @@ -1,347 +0,0 @@ -/** - * File: MemberTableField.js - */ -(function($) { - $.entwine('ss', function($){ - /** - * Class: #Permissions .checkbox[value=ADMIN] - * - * Automatically check and disable all checkboxes if ADMIN permissions are selected. - * As they're disabled, any changes won't be submitted (which is intended behaviour), - * checking all boxes is purely presentational. - */ - $('#Permissions .checkbox[value=ADMIN]').entwine({ - onmatch: function() { - this.toggleCheckboxes(); - - this._super(); - }, - /** - * Function: onclick - */ - onclick: function(e) { - this.toggleCheckboxes(); - }, - /** - * Function: toggleCheckboxes - */ - toggleCheckboxes: function() { - var self = this, checkboxes = this.parents('.field:eq(0)').find('.checkbox').not(this); - - if(this.is(':checked')) { - checkboxes.each(function() { - $(this).data('SecurityAdmin.oldChecked', $(this).attr('checked')); - $(this).data('SecurityAdmin.oldDisabled', $(this).attr('disabled')); - $(this).attr('disabled', 'disabled'); - $(this).attr('checked', 'checked'); - }); - } else { - checkboxes.each(function() { - $(this).attr('checked', $(this).data('SecurityAdmin.oldChecked')); - $(this).attr('disabled', $(this).data('SecurityAdmin.oldDisabled')); - }); - } - } - }); - }); -}(jQuery)); - -/** - * Modified 2006-10-05, Ingo Schommer - * This is more or less a copy of Member.js, with additions and changes - * to match the switch from Member.php to MemberTableField.php all over the UI. - * Eventually it will replace Member.js (please remove this message then). - */ - -// no confirm message for removal from a group -if(typeof(ComplexTableField) != 'undefined') { - ComplexTableField.prototype.deleteConfirmMessage = null; -} - -/** - * Class: AjaxMemberLookup - * - * Auto-lookup on ajax fields - */ -AjaxMemberLookup = { - initialise : function() { - var div = document.createElement('div'); - div.id = this.id + '_ac'; - div.className = 'autocomplete'; - this.parentNode.appendChild(div); - if(this.id) { - new Ajax.Autocompleter(this.id, div.id, 'admin/security/autocomplete/' + this.name, { - afterUpdateElement : this.afterAutocomplete.bind(this) - }); - - } - }, - afterAutocomplete : function(field, selectedItem) { - var items = jQuery(selectedItem).data('fields'), form = jQuery(selectedItem).parents('form:first'); - for(name in items) { - jQuery(form).find('input[name='+name+']').val(items[name]); - } - } -} - -/** - * Class: MemberTableField - */ -MemberTableField = Class.create(); -MemberTableField.applyTo('.cms-edit-form div.MemberTableField'); -MemberTableField.prototype = { - - initialize: function() { - Behaviour.register({ - '.cms-edit-form div.MemberFilter input' : { - onkeypress : this.prepareSearch.bind(this) - }, - - '.cms-edit-form div.MemberTableField table.data tr.addtogrouprow input' : { - onkeypress : this.prepareAddToGroup.bind(this) - }, - - '.cms-edit-form div.MemberTableField table.data tr.addtogrouprow #Form_AddRecordForm_action_addtogroup' : { - onclick : this.prepareAddToGroup.bind(this) - }, - - '.cms-edit-form div.MemberTableField table.data tr.addtogrouprow td.actions input' : { - initialise: function() { - data = this.parentNode.parentNode.getElementsByTagName('input'); - var i,item,error = []; - for(i=0;item=data[i];i++) { - item.originalSerialized = Form.Element.serialize(item); - } - }, - onclick : this.addToGroup.bind(this) - }, - - //'.cms-edit-form div.MemberTableField input' : AjaxMemberLookup, - - '.cms-edit-form' : { - changeDetection_fieldsToIgnore : { - 'ctf[start]' : true, - 'ctf[ID]' : true, - 'MemberOrderByField' : true, - 'MemberOrderByOrder' : true, - 'MemberGroup' : true, - 'MemberFilterButton' : true, - 'MemberFieldName' : true, - 'MemberDontShowPassword' : true, - 'MemberSearch' : true - } - } - }); - }, - - // prevent submission of wrong form-button (MemberFilterButton) - prepareAddToGroup: function(e) { - // IE6 doesnt send an event-object with onkeypress - var event = (e) ? e : window.event; - var keyCode = (event.keyCode) ? event.keyCode : event.which; - if(keyCode == Event.KEY_RETURN) { - var el = Event.element(event); - this.addToGroup(event); - Event.stop(event); - return false; - } - }, - - // prevent submission of wrong form-button (MemberFilterButton) - prepareSearch: function(e) { - // IE6 doesnt send an event-object with onkeypress - var event = (e) ? e : window.event; - var keyCode = (event.keyCode) ? event.keyCode : event.which; - - if(keyCode == Event.KEY_RETURN) { - var el = Event.element(event); - $('MemberFilterButton').onclick(event); - Event.stop(event); - return false; - } - }, - - addToGroup: function(e) { - // only submit parts of the form - var data = this.parentNode.parentNode.getElementsByTagName('input'); - var i,item,error = []; - var form = Event.findElement(e,"form"); - - for(i=0;item=data[i];i++) { - if(item.name == 'Email' && !item.value) error[error.length] = "Email"; - if(item.name == 'Password' && !item.value) error[error.length] = "Password"; - } - - if(error.length > 0) { - alert('Please enter a ' + error.join(' and a ') + ' to add a member.'); - } else { - updateURL = ""; - updateURL += Event.findElement(e,"form").action; - // we can't set "fieldName" as a HiddenField because there might be multiple ComplexTableFields in a single EditForm-container - updateURL += "?fieldName="+$('MemberFieldName').value; - updateURL += "&action_callfieldmethod&methodName=addtogroup"; - - ajaxSubmitFieldSet(updateURL, data); - } - - return false; - } - - /* - initialise : function() { - this.headerMap = []; - - var i, item, headers = this.getElementsByTagName('thead')[0].getElementsByTagName('tr')[0].getElementsByTagName('td'); - for(i=0;item=headers[i];i++) { - this.headerMap[i] = item.className; - } - }, - - setRecordDetails : function(id, details, groupID) { - var row = document.getElementById('member-' + id); - if(row) { - var i, item, cells = row.getElementsByTagName('td'); - for(i=0;item=cells[i];i++) { - if(details[this.headerMap[i]]) { - item.innerHTML = details[this.headerMap[i]]; - } - } - } else { - this.createRecord(id, details, groupID); - } - }, - createRecord : function (id, details, groupId) { - var row = document.createElement('tr'); - row.id = 'member-' + id; - var i, cell, cellField; - for(i=0;cellField=this.headerMap[i];i++) { - cell = document.createElement('td') - if(details[cellField]) { - cell.innerHTML = details[cellField]; - } - row.appendChild(cell); - } - - // Add the delete icon - if(typeof groupId == 'undefined') - var groupId = $('Form_EditForm').elements.ID.value; - cell = document.createElement('td') - cell.innerHTML = 'delete'; - cell.getElementsByTagName('0'); - row.appendChild(cell); - - var tbody = this.getElementsByTagName('tbody')[0]; - var addRow = document.getElementsByClassName('addrow',tbody)[0]; - if(addRow) tbody.insertBefore(row, addRow); - else tbody.appendChild(row); - Behaviour.apply(row, true); - }, - clearAddForm : function() { - var tbody = this.getElementsByTagName('tbody')[0]; - var addRow = document.getElementsByClassName('addrow',tbody)[0]; - if(addRow) { - var i,field,fields = addRow.getElementsByTagName('input'); - for(i=0;field=fields[i];i++) { - if(field.type != 'hidden' && field.type != 'submit') field.value = ''; - } - } - }, - removeMember : function(memberID) { - var record; - if(record = $('member-' + memberID)) { - record.parentNode.removeChild(record); - } - } - */ -} - -/** - * Class: MemberFilterButton - */ -MemberFilterButton = Class.create(); -MemberFilterButton.applyTo('#MemberFilterButton'); -MemberFilterButton.prototype = { - initialize: function() { - this.inputFields = new Array(); - - var childNodes = this.parentNode.parentNode.getElementsByTagName('input'); - - for( var index = 0; index < childNodes.length; index++ ) { - if( childNodes[index].tagName ) { - childNodes[index].resetChanged = function() { return false; } - childNodes[index].isChanged = function() { return false; } - this.inputFields.push( childNodes[index] ); - } - } - - childNodes = this.parentNode.getElementsByTagName('select'); - - for( var index = 0; index < childNodes.length; index++ ) { - if( childNodes[index].tagName ) { - childNodes[index].resetChanged = function() { return false; } - childNodes[index].field_changed = function() { return false; } - this.inputFields.push( childNodes[index] ); - } - } - }, - - isChanged: function() { - return false; - }, - - onclick: function(e) { - if(!$('ctf-ID') || !$('MemberFieldName')) { - return false; - } - - try { - var form = Event.findElement(e,"form"); - var fieldName = $('MemberFieldName').value; - var fieldID = form.id + '_' + fieldName; - - var updateURL = form.action + '/field/' + fieldName + '?ajax=1'; - for( var index = 0; index < this.inputFields.length; index++ ) { - if( this.inputFields[index].tagName ) { - updateURL += '&' + this.inputFields[index].name + '=' + encodeURIComponent( this.inputFields[index].value ); - } - } - - jQuery($(fieldID)).get(updateURL, null, function() {Behaviour.apply($(fieldID), true);}); - } catch(er) { - errorMessage('Error searching'); - } - - return false; - } -} - -// has to be external from initialize() because otherwise request will double on each reload - WTF -Behaviour.register({ - '.cms-edit-form div.MemberTableField table.data input.text' : AjaxMemberLookup -}); - -/** - * Post the given fields to the given url - */ -function ajaxSubmitFieldSet(href, fieldSet, extraData) { - // Build data - var i,field,data = "ajax=1"; - for(i=0;field=fieldSet[i];i++) { - data += '&' + Form.Element.serialize(field); - } - if(extraData){ - data += '&'+extraData; - } - // Send request - jQuery.ajax({ - 'url': href, - 'method' : 'post', - 'data' : data, - 'success' : function(response) { - eval(response); - }, - 'error' : function(response) { - alert(response.responseText); - } - }); -} \ No newline at end of file diff --git a/admin/javascript/MemberTableField_popup.js b/admin/javascript/MemberTableField_popup.js deleted file mode 100644 index 1436bbaa5..000000000 --- a/admin/javascript/MemberTableField_popup.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * File: MemberTableField_popup.js - */ - -/** - * Class: MemberTableFieldPopupForm - */ -MemberTableFieldPopupForm = Class.extend("ComplexTableFieldPopupForm"); -MemberTableFieldPopupForm.prototype = { - initialize: function() { - this.ComplexTableFieldPopupForm.initialize(); - - Behaviour.register('MemberTableFieldPopupForm',{ - "div.MemberTableField_Popup .Actions input.action": { - onclick: this.submitForm.bind(this) - } - }); - } -} - -MemberTableFieldPopupForm.applyTo('div.MemberTableField_Popup .Actions'); \ No newline at end of file diff --git a/admin/javascript/SecurityAdmin.js b/admin/javascript/SecurityAdmin.js index 7607cfa34..4493e5b5f 100644 --- a/admin/javascript/SecurityAdmin.js +++ b/admin/javascript/SecurityAdmin.js @@ -30,42 +30,47 @@ $(this).bind('load', refreshAfterImport); } }); - }) - - /** - * Delete selected folders through "batch actions" tab. - */ - $(document).ready(function() { - $('#Form_BatchActionsForm').entwine('ss').register( - // TODO Hardcoding of base URL - 'admin/security/batchactions/delete', - function(ids) { - var confirmed = confirm( - ss.i18n.sprintf( - ss.i18n._t('SecurityAdmin.BATCHACTIONSDELETECONFIRM'), - ids.length - ) - ); - return (confirmed) ? ids : false; - } - ); }); $.entwine('ss', function($){ /** - * Class: .cms-edit-form .Actions #Form_EditForm_action_addmember + * Class: #Permissions .checkbox[value=ADMIN] + * + * Automatically check and disable all checkboxes if ADMIN permissions are selected. + * As they're disabled, any changes won't be submitted (which is intended behaviour), + * checking all boxes is purely presentational. */ - $('.cms-edit-form .Actions #Form_EditForm_action_addmember').entwine({ - // Function: onclick + $('#Permissions .checkbox[value=ADMIN]').entwine({ + onmatch: function() { + this.toggleCheckboxes(); + + this._super(); + }, + /** + * Function: onclick + */ onclick: function(e) { - // CAUTION: Assumes that a MemberTableField-instance is present as an editing form - var t = $('#Form_EditForm_Members'); - t[0].openPopup( - null, - $('base').attr('href') + t.find('a.addlink').attr('href'), - t.find('table')[0] - ); - return false; + this.toggleCheckboxes(); + }, + /** + * Function: toggleCheckboxes + */ + toggleCheckboxes: function() { + var self = this, checkboxes = this.parents('.field:eq(0)').find('.checkbox').not(this); + + if(this.is(':checked')) { + checkboxes.each(function() { + $(this).data('SecurityAdmin.oldChecked', $(this).attr('checked')); + $(this).data('SecurityAdmin.oldDisabled', $(this).attr('disabled')); + $(this).attr('disabled', 'disabled'); + $(this).attr('checked', 'checked'); + }); + } else { + checkboxes.each(function() { + $(this).attr('checked', $(this).data('SecurityAdmin.oldChecked')); + $(this).attr('disabled', $(this).data('SecurityAdmin.oldDisabled')); + }); + } } }); }); diff --git a/admin/templates/Includes/MemberTableField.ss b/admin/templates/Includes/MemberTableField.ss deleted file mode 100644 index 9796a93a2..000000000 --- a/admin/templates/Includes/MemberTableField.ss +++ /dev/null @@ -1,62 +0,0 @@ -
-
- $SearchForm -
-
- <% if Markable %> - <% include TableListField_SelectOptions %> - <% end_if %> - <% include TableListField_PageControls %> - - - - <% if Markable %><% end_if %> - <% control Headings %> - - <% end_control %> - <% if Can(show) %><% end_if %> - <% if Can(edit) %><% end_if %> - <% if Can(delete) %><% end_if %> - - - - <% if Can(inlineadd) %> - - <% if Markable %> - - <% end_if %> - - <% if Markable %><% end_if %> - - <% if Can(show) %><% end_if %> - <% if Can(edit) %><% end_if %> - <% if Can(delete) %><% end_if %> - - - - <% if Items %> - <% control Items %> - <% include TableListField_Item %> - <% end_control %> - <% else %> - - <% if Markable %><% end_if %> - - <% control Actions %><% end_control %> - - <% end_if %> - -
 $Title   
 <% end_if %> - $AddRecordForm.CellFields - $AddRecordForm.CellActions
  - - - add<% _t('ADDNEW','Add new',50,'Followed by a member type') %> $Title -    
 <% _t('NOITEMSFOUND', 'No items found') %> 
-
- <% control Utility %> - $Title - <% end_control %> -
-
-
\ No newline at end of file diff --git a/admin/tests/MemberTableFieldTest.php b/admin/tests/MemberTableFieldTest.php deleted file mode 100644 index f61edd47c..000000000 --- a/admin/tests/MemberTableFieldTest.php +++ /dev/null @@ -1,139 +0,0 @@ -objFromFixture('Member', 'member1'); - $member2 = $this->objFromFixture('Member', 'member2'); - $member3 = $this->objFromFixture('Member', 'member3'); - $group1 = $this->objFromFixture('Group', 'group1'); - - $tf = new MemberTableField( - $this, - "Members", - $group1 - ); - $members = $tf->sourceItems(); - - $this->assertContains($member1->ID, $members->column('ID'), - 'Members in the associated group are listed' - ); - $this->assertContains($member2->ID, $members->column('ID'), - 'Members in children groups are listed as well' - ); - $this->assertNotContains($member3->ID, $members->column('ID'), - 'Members in other groups are filtered out' - ); - } - - function testShowsAllMembersWithoutGroupParameter() { - $member1 = $this->objFromFixture('Member', 'member1'); - $member2 = $this->objFromFixture('Member', 'member2'); - $member3 = $this->objFromFixture('Member', 'member3'); - $group1 = $this->objFromFixture('Group', 'group1'); - - $tf = new MemberTableField( - $this, - "Members" - // no group assignment - ); - $members = $tf->sourceItems(); - - $this->assertContains($member1->ID, $members->column('ID'), - 'Members in the associated group are listed' - ); - $this->assertContains($member2->ID, $members->column('ID'), - 'Members in children groups are listed as well' - ); - $this->assertContains($member3->ID, $members->column('ID'), - 'Members in other groups are listed' - ); - } - - function testDeleteWithGroupOnlyDeletesRelation() { - $member1 = $this->objFromFixture('Member', 'member1'); - $group1 = $this->objFromFixture('Group', 'group1'); - - $response = $this->get('MemberTableFieldTest_Controller'); - $token = SecurityToken::inst(); - $url = sprintf('MemberTableFieldTest_Controller/Form/field/Members/item/%d/delete/?usetestmanifest=1', $member1->ID); - $url = $token->addToUrl($url); - $response = $this->get($url); - - $group1->flushCache(); - - $this->assertNotContains($member1->ID, $group1->Members()->column('ID'), - 'Member relation to group is removed' - ); - $this->assertType( - 'DataObject', - DataObject::get_by_id('Member', $member1->ID), - 'Member record still exists' - ); - } - - function testDeleteWithoutGroupDeletesFromDatabase() { - $member1 = $this->objFromFixture('Member', 'member1'); - $member1ID = $member1->ID; - $group1 = $this->objFromFixture('Group', 'group1'); - - $response = $this->get('MemberTableFieldTest_Controller'); - $token = SecurityToken::inst(); - $url = sprintf('MemberTableFieldTest_Controller/FormNoGroup/field/Members/item/%d/delete/?usetestmanifest=1', $member1->ID); - $url = $token->addToUrl($url); - $response = $this->get($url); - - $group1->flushCache(); - - $this->assertNotContains($member1->ID, $group1->Members()->column('ID'), - 'Member relation to group is removed' - ); - DataObject::flush_and_destroy_cache(); - $this->assertFalse( - DataObject::get_by_id('Member', $member1ID), - 'Member record is removed from database' - ); - } -} - -class MemberTableFieldTest_Controller extends Controller implements TestOnly { - - protected $template = 'BlankPage'; - - function Link($action = null) { - return Controller::join_links('MemberTableFieldTest_Controller', $action); - } - - function Form() { - $group1 = DataObject::get_one('Group', '"Code" = \'group1\''); - return new Form( - $this, - 'FormNoGroup', - new FieldList(new MemberTableField($this, "Members", $group1)), - new FieldList(new FormAction('submit')) - ); - } - - function FormNoGroup() { - $tf = new MemberTableField( - $this, - "Members" - // no group - ); - - return new Form( - $this, - 'FormNoGroup', - new FieldList(new MemberTableField($this, "Members")), - new FieldList(new FormAction('submit')) - ); - } - -} \ No newline at end of file diff --git a/admin/tests/MemberTableFieldTest.yml b/admin/tests/MemberTableFieldTest.yml deleted file mode 100644 index bc9785f26..000000000 --- a/admin/tests/MemberTableFieldTest.yml +++ /dev/null @@ -1,31 +0,0 @@ -Group: - admin: - Title: Administrators - Code: admin - group1: - Title: Group1 - Code: group1 - group1_child: - Title: Group1 Child - Parent: =>Group.group1 - Code: group1_child - group2: - Title: Group2 - Code: group2 -Member: - admin: - Email: admin@example.com - Groups: =>Group.admin - member1: - Email: member1@test.com - Groups: =>Group.group1 - member2: - Email: member2@test.com - Groups: =>Group.group1_child - member3: - Email: member3@test.com - Groups: =>Group.group2 -Permission: - admin: - Code: ADMIN - GroupID: =>Group.admin \ No newline at end of file diff --git a/docs/en/changelogs/3.0.0.md b/docs/en/changelogs/3.0.0.md index fb3b43c93..29261345c 100644 --- a/docs/en/changelogs/3.0.0.md +++ b/docs/en/changelogs/3.0.0.md @@ -182,3 +182,4 @@ BreadcrumbsTemplate.ss from cms/template to your theme or application. * `DataObjectLog`: There is no replacement for this. * `GeoIP`: Moved to separate ["geoip" module](https://github.com/silverstripe-labs/silverstripe-geoip) * `NZGovtPasswordValidator`: Moved to ["securityextras" module](https://github.com/silverstripe-labs/silverstripe-securityextras) +* `MemberTableField`: Use GridField with GridFieldConfig_RelationEditor instead \ No newline at end of file