diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index d570aa61..9b421dd9 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -36,8 +36,8 @@ class AssetAdmin extends LeftAndMain { public static $apply_restrictions_to_admin = false; static $allowed_actions = array( - 'addfolder', - 'deletefolder', + 'doAdd', + 'AddForm', 'deletemarked', 'DeleteItemsForm', 'deleteUnusedThumbnails', @@ -50,7 +50,9 @@ class AssetAdmin extends LeftAndMain { 'savefile', 'uploadiframe', 'UploadForm', - 'deleteUnusedThumbnails' => 'ADMIN' + 'deleteUnusedThumbnails' => 'ADMIN', + 'batchactions', + 'BatchActionsForm' ); /** @@ -105,6 +107,8 @@ class AssetAdmin extends LeftAndMain { }; JS ); + + CMSBatchActionHandler::register('delete', 'AssetAdmin_DeleteBatchAction', 'Folder'); } /** @@ -506,10 +510,33 @@ JS; // Data saving handlers + /** + * @return Form + */ + function AddForm() { + $typeMap = array('Folder' => singleton('Folder')->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 folder and return its details suitable for ajax. */ - public function addfolder() { + public function doAdd() { $parent = ($_REQUEST['ParentID'] && is_numeric($_REQUEST['ParentID'])) ? (int)$_REQUEST['ParentID'] : 0; $name = (isset($_REQUEST['Name'])) ? basename($_REQUEST['Name']) : _t('AssetAdmin.NEWFOLDER',"NewFolder"); @@ -552,63 +579,51 @@ JS; } /** - * @return Form + * Batch Actions Handler */ - function DeleteItemsForm() { - $form = new Form( - $this, - 'DeleteItemsForm', - new FieldSet( - new LiteralField('SelectedPagesNote', - sprintf('

%s

', _t('AssetAdmin_left.ss.SELECTTODEL','Select the folders that you want to delete and then click the button below')) - ), - new HiddenField('csvIDs') - ), - new FieldSet( - new FormAction('deletefolder', _t('AssetAdmin_left.ss.DELFOLDERS','Delete the selected folders')) - ) - ); - $form->addExtraClass('actionparams'); - - return $form; + function batchactions() { + return new CMSBatchActionHandler($this, 'batchactions', 'Folder'); } /** - * Delete a folder + * @return Form */ - public function deletefolder() { - $script = ''; - $ids = split(' *, *', $_REQUEST['csvIDs']); - $script = ''; + function BatchActionsForm() { + $actions = $this->batchactions()->batchActionList(); + $actionsMap = array(); + foreach($actions as $action) $actionsMap[$action->Link] = $action->Title; - if(!$ids) return false; + $form = new Form( + $this, + 'BatchActionsForm', + new FieldSet( + new LiteralField( + 'Intro', + sprintf('

%s

', + _t( + 'CMSMain_left.ss.SELECTPAGESACTIONS', + 'Select the pages that you want to change & then click an action:' + ) + ) + ), + new HiddenField('csvIDs'), + new DropdownField( + 'Action', + false, + $actionsMap + ) + ), + new FieldSet( + // TODO i18n + new FormAction('submit', "Go") + ) + ); + $form->addExtraClass('actionparams'); + $form->unsetValidator(); - foreach($ids as $id) { - if(is_numeric($id)) { - $record = DataObject::get_by_id($this->stat('tree_class'), $id); - if($record) { - $record->delete(); - $record->destroy(); - } - } - } - - $size = sizeof($ids); - if($size > 1) { - $message = $size.' '._t('AssetAdmin.FOLDERSDELETED', 'folders deleted.'); - } else { - $message = $size.' '._t('AssetAdmin.FOLDERDELETED', 'folder deleted.'); - } - - if(isset($brokenPageList)) { - $message .= ' '._t('AssetAdmin.NOWBROKEN', 'The following pages now have broken links:').''. - _t('AssetAdmin.NOWBROKEN2', 'Their owners have been emailed and they will fix up those pages.'); - } - - $script .= "statusMessage('$message');"; - echo $script; + return $form; } - + public function removefile(){ if($fileID = $this->urlParams['ID']) { $file = DataObject::get_by_id('File', $fileID); @@ -754,4 +769,38 @@ JS; } } +/** + * Delete multiple {@link Folder} records (and the associated filesystem nodes). + * Usually used through the {@link AssetAdmin} interface. + * + * @package cms + * @subpackage batchactions + */ +class AssetAdmin_DeleteBatchAction extends CMSBatchAction { + function getActionTitle() { + // _t('AssetAdmin_left.ss.SELECTTODEL','Select the folders that you want to delete and then click the button below') + return _t('AssetAdmin_DeleteBatchAction.TITLE', 'Delete folders'); + } + + function run(DataObjectSet $records) { + $status = array( + 'modified'=>array(), + 'deleted'=>array() + ); + + foreach($records as $record) { + $id = $record->ID; + + // Perform the action + if($record->canDelete()) $record->delete(); + + $status['deleted'][$id] = array(); + + $record->destroy(); + unset($record); + } + + return Convert::raw2json($status); + } +} ?> diff --git a/css/AssetAdmin.css b/css/AssetAdmin.css index 8e88a14d..c638adb2 100644 --- a/css/AssetAdmin.css +++ b/css/AssetAdmin.css @@ -21,4 +21,21 @@ } .DraggedHandle { width: 30em !important; +} +form#Form_AddForm fieldset { + float: left; + margin-right: 1em; +} +form#Form_AddForm .field span.readonly { + background: none; + border: none; + margin: 0; + padding: 0; + width: auto; +} + +#TreeActions-sync { + /* Same as .checkboxAboveTree */ + border-top: 1px solid #CCCCCC; + padding: .5em; } \ No newline at end of file diff --git a/javascript/AssetAdmin.js b/javascript/AssetAdmin.js index b0d62a90..53b329b8 100755 --- a/javascript/AssetAdmin.js +++ b/javascript/AssetAdmin.js @@ -10,132 +10,146 @@ SiteTreeHandlers.showRecord_url = 'admin/assets/show/'; SiteTreeHandlers.controller_url = 'admin/assets'; var _HANDLER_FORMS = { - addpage : 'Form_AddPageOptionsForm', + addpage : 'Form_AddForm', deletepage : 'Form_DeleteItemsForm', sortitems : 'sortitems_options' }; (function($) { /** - * Overload the "Create" tab to execute action instead of - * opening the tab content. + * @class Simple form with a page type dropdown + * which creates a new page through #Form_EditForm and adds a new tree node. + * @name ss.Form_AddForm + * @requires ss.i18n + * @requires ss.Form_EditForm */ - $('#TreeActions-create-btn').concrete('ss', function($) { - return { + $('#Form_AddForm').concrete(function($) { + return/** @lends ss.Form_AddForm */{ + /** + * @type DOMElement + */ + Tree: null, + + /** + * @type Array Internal counter to create unique page identifiers prior to ajax saving + */ + _NewPages: [], + onmatch: function() { - this.bind('click', function(e) { - var form = $('form#addpage_options'); - jQuery.post( - form.attr('action'), - form.serialize(), - function(data) { + var self = this; + + this.bind('submit', function(e) { + return self._submit(e); + }); + + Observable.applyTo(this[0]); + + var tree = jQuery('#sitetree')[0]; + this.setTree(tree); + }, + + _submit: function(e) { + var newPages = this._NewPages(); + var tree = this.Tree(); + var parentID = (tree.firstSelected()) ? tree.getIdxOf(tree.firstSelected()) : 0; - } - ); - return false; - }) + // TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875 + if(parentID && parentID.substr(0,3) == 'new') { + alert(ss.i18n._t('CMSMAIN.WARNINGSAVEPAGESBEFOREADDING')); + } + + if(tree.firstSelected() && jQuery(tree.firstSelected()).hasClass("nochildren")) { + alert(ss.i18n._t('CMSMAIN.CANTADDCHILDREN') ); + } + + // Optionally initalize the new pages tracker + if(!newPages[parentID] ) newPages[parentID] = 1; + + // default to first button + var button = jQuery(this).find(':submit:first'); + button.addClass('loading'); + + // collect data and submit the form + var data = jQuery(this).serializeArray(); + data.push({name:'Suffix',value:newPages[parentID]++}); + data.push({name:button.attr('name'),value:button.val()}); + jQuery('#Form_EditForm').concrete('ss').loadForm( + jQuery(this).attr('action'), + function() { + button.removeClass('loading'); + }, + {type: 'POST', data: data} + ); + + this.set_NewPages(newPages); + + return false; } }; }); -}(jQuery)); - - -/** - * Add File Action - */ -addfolder = Class.create(); -addfolder.applyTo('#addpage'); -addfolder.prototype = { - initialize: function () { - Observable.applyTo($(this.id + '_options')); - this.getElementsByTagName('button')[0].onclick = returnFalse; - $(this.id + '_options').onsubmit = this.form_submit; - - }, - onclick : function() { - statusMessage('Creating new folder...'); - this.form_submit(); -/* - if(treeactions.toggleSelection(this)) { - var selectedNode = $('sitetree').firstSelected(); - - if(selectedNode) { - while(selectedNode.parentTreeNode && !selectedNode.hints.defaultChild) { - $('sitetree').changeCurrentTo(selectedNode.parentTreeNode); - selectedNode = selectedNode.parentTreeNode; + $('#Form_SyncForm').concrete('ss', function($) { + return { + onmatch: function() { + this.bind('submit', this._onsubmit); + this._super(); + }, + _onsubmit: function(e) { + var button = jQuery(this).find(':submit:first'); + button.addClass('loading'); + $.get( + jQuery(this).attr('action'), + function() { + button.removeClass('loading'); + } + ); + + return false; + } + }; + }); + + $('#Form_DeleteItemsForm').concrete('ss', function($) { + return { + onmatch: function() { + $('#TreeActions').bind('tabsselect', function(e, ui) { + if($(ui.tab).attr('id') == 'TreeActions-delete-btn') { + + } + }); + }, + /** + * @param {Boolean} + */ + toggleTree: function(bool) { + if(bool) { + deletefolder.o1 = $('sitetree').observeMethod('SelectionChanged', deletefolder.treeSelectionChanged); + deletefolder.o2 = $('Form_DeleteItemsForm').observeMethod('Close', deletefolder.popupClosed); + + jQuery('#sitetree').addClass('multiselect'); + + deletefolder.selectedNodes = { }; + + var sel = $('sitetree').firstSelected() + if(sel) { + var selIdx = $('sitetree').getIdxOf(sel); + deletefolder.selectedNodes[selIdx] = true; + sel.removeNodeClass('current'); + sel.addNodeClass('selected'); + } } } - } -*/ - return false; - }, - - form_submit : function() { - var st = $('sitetree'); - - $('Form_AddPageOptionsForm').elements.ParentID.value = st.getIdxOf(st.firstSelected()); - Ajax.SubmitForm('Form_AddPageOptionsForm', null, { - onSuccess : this.onSuccess, - onFailure : this.showAddPageError - }); - return false; - }, - onSuccess: function(response) { - Ajax.Evaluator(response); - // Make it possible to drop files into the new folder - DropFileItem.applyTo('#sitetree li'); - }, - showAddPageError: function(response) { - errorMessage('Error adding folder', response); - } -} - -/** - * Look for new files (FilesystemSync) action - */ -FilesystemSyncClass = Class.create(); -FilesystemSyncClass.applyTo('#filesystemsync'); -FilesystemSyncClass.prototype = { - initialize: function () { - this.getElementsByTagName('button')[0].onclick = returnFalse; - }, - - onclick : function() { - statusMessage('Looking for new files'); - new Ajax.Request('dev/tasks/FilesystemSyncTask', { - onSuccess: function(t) { - statusMessage(t.responseText, "good"); - }, - onFailure: function(t) { - errorMessage("There was an error looking for new files"); - } - }); - return false; - } -} + + }; + }); +}(jQuery)); /** * Delete folder action */ deletefolder = { button_onclick : function() { - if(treeactions.toggleSelection(this)) { - deletefolder.o1 = $('sitetree').observeMethod('SelectionChanged', deletefolder.treeSelectionChanged); - deletefolder.o2 = $('Form_DeleteItemsForm').observeMethod('Close', deletefolder.popupClosed); - - jQuery('#sitetree').addClass('multiselect'); - - deletefolder.selectedNodes = { }; - - var sel = $('sitetree').firstSelected() - if(sel) { - var selIdx = $('sitetree').getIdxOf(sel); - deletefolder.selectedNodes[selIdx] = true; - sel.removeNodeClass('current'); - sel.addNodeClass('selected'); - } - } + return false; }, diff --git a/templates/Includes/AssetAdmin_left.ss b/templates/Includes/AssetAdmin_left.ss index a748f6c4..3a041ff8 100755 --- a/templates/Includes/AssetAdmin_left.ss +++ b/templates/Includes/AssetAdmin_left.ss @@ -13,34 +13,18 @@
  • - - <% _t('DELETE','Delete',PR_HIGH) %> - -
  • -
  • - - <% _t('FILESYSTEMSYNC','Look for new files') %> + + <% _t('BATCHACTIONS','Batch Actions',PR_HIGH) %>
  • -
    -
    - - -
    -
    + $AddForm
    -
    - +
    + $BatchActionsForm
    @@ -56,6 +40,10 @@ $SiteTreeAsUL +
    + $SyncForm +
    + \ No newline at end of file