diff --git a/code/MemberTableField.php b/code/MemberTableField.php index 8240adbf..91f5647e 100755 --- a/code/MemberTableField.php +++ b/code/MemberTableField.php @@ -99,6 +99,7 @@ class MemberTableField extends ComplexTableField { function FieldHolder() { $ret = parent::FieldHolder(); + Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/scriptaculous/controls.js"); Requirements::javascript(CMS_DIR . '/javascript/MemberTableField.js'); Requirements::javascript(CMS_DIR . "/javascript/MemberTableField_popup.js"); diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index 48191bc7..5beb3a3c 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -17,11 +17,11 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { static $subitem_class = 'Member'; static $allowed_actions = array( - 'addgroup', 'addmember', 'autocomplete', 'removememberfromgroup', 'savemember', + 'AddForm', 'AddRecordForm', 'MemberForm', 'EditForm', @@ -31,54 +31,63 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { public function init() { parent::init(); - Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/scriptaculous/controls.js"); - - // needed for MemberTableField (Requirements not determined before Ajax-Call) - Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang'); - Requirements::javascript(SAPPHIRE_DIR . "/javascript/TableListField.js"); - Requirements::javascript(SAPPHIRE_DIR . "/javascript/TableField.js"); - Requirements::javascript(SAPPHIRE_DIR . "/javascript/ComplexTableField.js"); - Requirements::javascript(CMS_DIR . "/javascript/MemberTableField.js"); - Requirements::css(THIRDPARTY_DIR . "/greybox/greybox.css"); - Requirements::css(SAPPHIRE_DIR . "/css/ComplexTableField.css"); - - Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin_left.js'); - Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin_right.js'); - - Requirements::javascript(THIRDPARTY_DIR . "/greybox/AmiJS.js"); - Requirements::javascript(THIRDPARTY_DIR . "/greybox/greybox.js"); + Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin.js'); + Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin.Tree.js'); + + CMSBatchActionHandler::register('delete', 'SecurityAdmin_DeleteBatchAction', 'Group'); } - - public function getEditForm($id = null) { - $record = null; - - if($id && $id != 'root') { - $record = DataObject::get_by_id($this->stat('tree_class'), $id); - } - - if($record && !$record->canView()) return Security::permissionFailure($this); - - if($record) { - $fields = $record->getCMSFields(); - - $actions = new FieldSet( - new FormAction('addmember',_t('SecurityAdmin.ADDMEMBER','Add Member')), - new FormAction('save',_t('SecurityAdmin.SAVE','Save')) - ); - - $form = new Form($this, "EditForm", $fields, $actions); - $form->loadDataFrom($record); - - if(!$record->canEdit()) { - $readonlyFields = $form->Fields()->makeReadonly(); - $form->setFields($readonlyFields); - } - } else { - $form = $this->EmptyForm(); - } + + function getEditForm($id = null) { + $form = parent::getEditForm($id); + $form->Actions()->insertBefore( + new FormAction('addmember',_t('SecurityAdmin.ADDMEMBER','Add Member')), + 'action_save' + ); return $form; } + + /** + * @return Form + */ + function AddForm() { + $class = $this->stat('tree_class'); + + $typeMap = array('Folder' => singleton($class)->i18n_singular_name()); + $typeField = new DropdownField('Type', false, $typeMap, 'Folder'); + $form = new Form( + $this, + 'AddForm', + new FieldSet( + new HiddenField('ParentID'), + $typeField->performReadonlyTransformation() + ), + new FieldSet( + new FormAction('doAdd', _t('AssetAdmin_left.ss.GO','Go')) + ) + ); + $form->setValidator(null); + $form->addExtraClass('actionparams'); + + return $form; + } + + /** + * Add a new group and return its details suitable for ajax. + */ + public function doAdd($data, $form) { + $parentID = (isset($data['ParentID']) && is_numeric($data['ParentID'])) ? (int)$data['ParentID'] : 0; + + if(!singleton($this->stat('tree_class'))->canCreate()) return Security::permissionFailure($this); + + $record = Object::create($this->stat('tree_class')); + $record->Title = _t('SecurityAdmin.NEWGROUP',"New Group"); + $record->ParentID = $parentID; + $record->write(); + + $form = $this->getEditForm($record->ID); + return $form->formHtmlContent(); + } public function AddRecordForm() { $m = Object::create('MemberTableField', @@ -269,18 +278,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { return $siteTree; } - public function addgroup() { - if(!singleton($this->stat('tree_class'))->canCreate()) return Security::permissionFailure($this); - - $newGroup = Object::create($this->stat('tree_class')); - $newGroup->Title = _t('SecurityAdmin.NEWGROUP',"New Group"); - $newGroup->Code = "new-group"; - $newGroup->ParentID = (is_numeric($_REQUEST['ParentID'])) ? (int)$_REQUEST['ParentID'] : 0; - $newGroup->write(); - - return $this->returnItemToUser($newGroup); - } - public function EditedMember() { if(Session::get('currentMember')) return DataObject::get_by_id('Member', (int) Session::get('currentMember')); } @@ -315,4 +312,35 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { } } +/** + * Delete multiple {@link Group} records. Usually used through the {@link SecurityAdmin} interface. + * + * @package cms + * @subpackage batchactions + */ +class SecurityAdmin_DeleteBatchAction extends CMSBatchAction { + function getActionTitle() { + return _t('AssetAdmin_DeleteBatchAction.TITLE', 'Delete groups'); + } + + function run(DataObjectSet $records) { + $status = array( + 'modified'=>array(), + 'deleted'=>array() + ); + + foreach($records as $record) { + // TODO Provide better feedback if permission was denied + if(!$record->canDelete()) continue; + + $id = $record->ID; + $record->delete(); + $status['deleted'][$id] = array(); + $record->destroy(); + unset($record); + } + + return Convert::raw2json($status); + } +} ?> diff --git a/javascript/SecurityAdmin.Tree.js b/javascript/SecurityAdmin.Tree.js new file mode 100755 index 00000000..8101bd16 --- /dev/null +++ b/javascript/SecurityAdmin.Tree.js @@ -0,0 +1,10 @@ +/** + * Configuration for the left hand tree + */ +if(typeof SiteTreeHandlers == 'undefined') SiteTreeHandlers = {}; +SiteTreeHandlers.parentChanged_url = 'admin/security/ajaxupdateparent'; +SiteTreeHandlers.orderChanged_url = 'admin/security/ajaxupdatesort'; +SiteTreeHandlers.loadPage_url = 'admin/security/getitem'; +SiteTreeHandlers.loadTree_url = 'admin/security/getsubtree'; +SiteTreeHandlers.showRecord_url = 'admin/security/show/'; +SiteTreeHandlers.controller_url = 'admin/security'; \ No newline at end of file diff --git a/javascript/SecurityAdmin_right.js b/javascript/SecurityAdmin.js similarity index 50% rename from javascript/SecurityAdmin_right.js rename to javascript/SecurityAdmin.js index 03daad63..4e89a82c 100755 --- a/javascript/SecurityAdmin_right.js +++ b/javascript/SecurityAdmin.js @@ -1,3 +1,23 @@ +(function($) { + /** + * Delete selected folders through "batch actions" tab. + */ + $(document).ready(function() { + $('#Form_BatchActionsForm').concrete('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; + } + ); + }); +}(jQuery)); /** * CAUTION: Assumes that a MemberTableField-instance is present as an editing form */ diff --git a/javascript/SecurityAdmin_left.js b/javascript/SecurityAdmin_left.js deleted file mode 100755 index c0369286..00000000 --- a/javascript/SecurityAdmin_left.js +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Configuration for the left hand tree - */ -if(typeof SiteTreeHandlers == 'undefined') SiteTreeHandlers = {}; -SiteTreeHandlers.parentChanged_url = 'admin/security/ajaxupdateparent'; -SiteTreeHandlers.orderChanged_url = 'admin/security/ajaxupdatesort'; -SiteTreeHandlers.loadPage_url = 'admin/security/getitem'; -SiteTreeHandlers.loadTree_url = 'admin/security/getsubtree'; -SiteTreeHandlers.showRecord_url = 'admin/security/show/'; -SiteTreeHandlers.controller_url = 'admin/security'; - -_HANDLER_FORMS['deletegroup'] = 'deletegroup_options'; - -/** - * Add page action - * @todo Remove duplication between this and the CMSMain Add page action - */ -var addgroup = { - button_onclick : function() { - addgroup.form_submit(); - return false; - }, - - form_submit : function() { - var st = $('sitetree'); - $('addgroup_options').elements.ParentID.value = st.firstSelected() ? st.getIdxOf(st.firstSelected()) : 0; - Ajax.SubmitForm('addgroup_options', null, { - onSuccess : Ajax.Evaluator, - onFailure : function(response) { - errorMessage('Error adding page', response); - } - }); - - return false; - } -} - -/** - * Delete page action - */ -var deletegroup = { - button_onclick : function() { - /*if( $('deletegroup_options').style.display == 'none' ) - $('deletegroup_options').style.display = 'block'; - else - $('deletegroup_options').style.display = 'none';*/ - - if(treeactions.toggleSelection(this)) { - $('deletegroup_options').style.display = 'block'; - - deletegroup.o1 = $('sitetree').observeMethod('SelectionChanged', deletegroup.treeSelectionChanged); - deletegroup.o2 = $('deletegroup_options').observeMethod('Close', deletegroup.popupClosed); - jQuery('#sitetree').addClass('multiselect'); - - deletegroup.selectedNodes = { }; - - var sel = $('sitetree').firstSelected(); - if(sel && sel.className.indexOf('nodelete') == -1) { - var selIdx = $('sitetree').getIdxOf(sel); - deletegroup.selectedNodes[selIdx] = true; - sel.removeNodeClass('current'); - sel.addNodeClass('selected'); - } - } else - $('deletegroup_options').style.display = 'none'; - - return false; - }, - - treeSelectionChanged : function(selectedNode) { - var idx = $('sitetree').getIdxOf(selectedNode); - - if(selectedNode.className.indexOf('nodelete') == -1) { - if(selectedNode.selected) { - selectedNode.removeNodeClass('selected'); - selectedNode.selected = false; - deletegroup.selectedNodes[idx] = false; - - } else { - selectedNode.addNodeClass('selected'); - selectedNode.selected = true; - deletegroup.selectedNodes[idx] = true; - } - } - - return false; - }, - - popupClosed : function() { - jQuery('#sitetree').removeClass('multiselect'); - $('sitetree').stopObserving(deletegroup.o1); - $('deletegroup_options').stopObserving(deletegroup.o2); - - for(var idx in deletegroup.selectedNodes) { - if(deletegroup.selectedNodes[idx]) { - node = $('sitetree').getTreeNodeByIdx(idx); - if(node) { - node.removeNodeClass('selected'); - node.selected = false; - } - } - } - }, - - form_submit : function() { - var csvIDs = ""; - for(var idx in deletegroup.selectedNodes) { - if(deletegroup.selectedNodes[idx]) csvIDs += (csvIDs ? "," : "") + idx; - } - if(csvIDs) { - if(confirm("Do you really want to delete these groups?")) { - $('deletegroup_options').elements.csvIDs.value = csvIDs; - - Ajax.SubmitForm('deletegroup_options', null, { - onSuccess : function(response) { - Ajax.Evaluator(response); - - var sel; - if((sel = $('sitetree').firstSelected()) && sel.parentNode) sel.addNodeClass('current'); - else $('Form_EditForm').innerHTML = ""; - - treeactions.closeSelection($('deletegroup')); - }, - onFailure : function(response) { - errorMessage('Error deleting pages', response); - } - }); - - $('deletegroup').getElementsByTagName('button')[0].onclick(); - } - } else { - alert("Please select at least one group."); - } - - return false; - } -} - - -/** - * Initialisation function to set everything up - */ -Behaviour.addLoader(function () { - // Set up add page - Observable.applyTo($('addgroup_options')); - if($('addgroup')) { - $('addgroup').onclick = addgroup.button_onclick; - $('addgroup').getElementsByTagName('button')[0].onclick = function() {return false;}; - $('addgroup_options').onsubmit = addgroup.form_submit; - } - - // Set up delete page - Observable.applyTo($('deletegroup_options')); - if($('deletegroup')) { - $('deletegroup').onclick = deletegroup.button_onclick; - $('deletegroup').getElementsByTagName('button')[0].onclick = function() {return false;}; - $('deletegroup_options').onsubmit = deletegroup.form_submit; - } -}); \ No newline at end of file diff --git a/javascript/lang/en_US.js b/javascript/lang/en_US.js index 98380a2c..63d10f7b 100644 --- a/javascript/lang/en_US.js +++ b/javascript/lang/en_US.js @@ -30,6 +30,7 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') { 'CMSMAIN.URLSEGMENTVALIDATION': 'URLs can only be made up of letters, digits and hyphens.', 'AssetAdmin.BATCHACTIONSDELETECONFIRM': "Do you really want to delete %s folders?", 'AssetTableField.REALLYDELETE': 'Do you really want to delete the marked files?', - 'AssetTableField.MOVING': 'Moving %s file(s)' + 'AssetTableField.MOVING': 'Moving %s file(s)', + 'SecurityAdmin.BATCHACTIONSDELETECONFIRM': "Do you really want to delete %s groups?" }); } \ No newline at end of file diff --git a/templates/Includes/SecurityAdmin_left.ss b/templates/Includes/SecurityAdmin_left.ss index 2568c7eb..0b5979f5 100644 --- a/templates/Includes/SecurityAdmin_left.ss +++ b/templates/Includes/SecurityAdmin_left.ss @@ -8,40 +8,37 @@ - -
-
- - -
-
- -
- +
+ $AddForm
- + +
+ $BatchActionsForm +
+
- + +
- $SiteTreeAsUL +
+ $SiteTreeAsUL +