mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
Merge pull request #1203 from tractorcow/pulls/3.2/archive-actions
API Deprecate delete in favour of archive
This commit is contained in:
commit
bb68036854
@ -22,21 +22,49 @@ class CMSBatchAction_Publish extends CMSBatchAction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-publish items batch action.
|
||||
* Unpublish items batch action.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Unpublish extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.UNPUBLISH_PAGES', 'Un-publish');
|
||||
return _t('CMSBatchActions.UNPUBLISH_PAGES', 'Unpublish');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
return $this->batchaction($pages, 'doUnpublish',
|
||||
_t('CMSBatchActions.UNPUBLISHED_PAGES', 'Un-published %d pages')
|
||||
_t('CMSBatchActions.UNPUBLISHED_PAGES', 'Unpublished %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids) {
|
||||
return $this->applicablePagesHelper($ids, 'canDeleteFromLive', false, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Archives a page, removing it from both live and stage
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Archive extends CMSBatchAction {
|
||||
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.ARCHIVE', 'Archive');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
return $this->batchaction($pages, 'doArchive',
|
||||
_t('CMSBatchActions.ARCHIVED_PAGES', 'Archived %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids) {
|
||||
return $this->applicablePagesHelper($ids, 'canArchive', true, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,6 +72,7 @@ class CMSBatchAction_Unpublish extends CMSBatchAction {
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
* @deprecated since version 4.0
|
||||
*/
|
||||
class CMSBatchAction_Delete extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
@ -51,6 +80,7 @@ class CMSBatchAction_Delete extends CMSBatchAction {
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
Deprecation::notice('4.0', 'Delete is deprecated. Use Archive instead');
|
||||
$status = array(
|
||||
'modified'=>array(),
|
||||
'deleted'=>array(),
|
||||
@ -93,14 +123,15 @@ class CMSBatchAction_Delete extends CMSBatchAction {
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
* @deprecated since version 4.0
|
||||
*/
|
||||
class CMSBatchAction_DeleteFromLive extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.DELETE_PAGES', 'Delete from published site');
|
||||
}
|
||||
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
Deprecation::notice('4.0', 'Delete From Live is deprecated. Use Unpublish instead');
|
||||
$status = array(
|
||||
'modified'=>array(),
|
||||
'deleted'=>array()
|
||||
|
@ -36,6 +36,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
private static $page_length = 15;
|
||||
|
||||
private static $allowed_actions = array(
|
||||
'archive',
|
||||
'buildbrokenlinks',
|
||||
'deleteitems',
|
||||
'DeleteItemsForm',
|
||||
@ -56,6 +57,14 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
'ListViewForm',
|
||||
'childfilter',
|
||||
);
|
||||
|
||||
/**
|
||||
* Enable legacy batch actions.
|
||||
* @deprecated since version 4.0
|
||||
* @var array
|
||||
* @config
|
||||
*/
|
||||
private static $enabled_legacy_actions = array();
|
||||
|
||||
public function init() {
|
||||
// set reading lang
|
||||
@ -88,8 +97,24 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
|
||||
CMSBatchActionHandler::register('publish', 'CMSBatchAction_Publish');
|
||||
CMSBatchActionHandler::register('unpublish', 'CMSBatchAction_Unpublish');
|
||||
CMSBatchActionHandler::register('delete', 'CMSBatchAction_Delete');
|
||||
CMSBatchActionHandler::register('deletefromlive', 'CMSBatchAction_DeleteFromLive');
|
||||
|
||||
|
||||
// Check legacy actions
|
||||
$legacy = $this->config()->enabled_legacy_actions;
|
||||
|
||||
// Delete from live is unnecessary since we have unpublish which does the same thing
|
||||
if(in_array('CMSBatchAction_DeleteFromLive', $legacy)) {
|
||||
Deprecation::notice('4.0', 'Delete From Live is deprecated. Use Un-publish instead');
|
||||
CMSBatchActionHandler::register('deletefromlive', 'CMSBatchAction_DeleteFromLive');
|
||||
}
|
||||
|
||||
// Delete action
|
||||
if(in_array('CMSBatchAction_Delete', $legacy)) {
|
||||
Deprecation::notice('4.0', 'Delete from Stage is deprecated. Use Archive instead.');
|
||||
CMSBatchActionHandler::register('delete', 'CMSBatchAction_Delete');
|
||||
} else {
|
||||
CMSBatchActionHandler::register('archive', 'CMSBatchAction_Archive');
|
||||
}
|
||||
}
|
||||
|
||||
public function index($request) {
|
||||
@ -1059,13 +1084,13 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
* @see deletefromlive()
|
||||
*/
|
||||
public function delete($data, $form) {
|
||||
Deprecation::notice('4.0', 'Delete from stage is deprecated. Use archive instead');
|
||||
$id = $data['ID'];
|
||||
$record = DataObject::get_by_id("SiteTree", $id);
|
||||
if($record && !$record->canDelete()) return Security::permissionFailure();
|
||||
if(!$record || !$record->ID) throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404);
|
||||
|
||||
// save ID and delete record
|
||||
$recordID = $record->ID;
|
||||
// Delete record
|
||||
$record->delete();
|
||||
|
||||
$this->response->addHeader(
|
||||
@ -1077,6 +1102,34 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
return $this->getResponseNegotiator()->respond($this->getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this page from both live and stage
|
||||
*
|
||||
* @param type $data
|
||||
* @param type $form
|
||||
*/
|
||||
public function archive($data, $form) {
|
||||
$id = $data['ID'];
|
||||
$record = DataObject::get_by_id("SiteTree", $id);
|
||||
if(!$record || !$record->exists()) {
|
||||
throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404);
|
||||
}
|
||||
if(!$record->canArchive()) {
|
||||
return Security::permissionFailure();
|
||||
}
|
||||
|
||||
// Archive record
|
||||
$record->doArchive();
|
||||
|
||||
$this->response->addHeader(
|
||||
'X-Status',
|
||||
rawurlencode(sprintf(_t('CMSMain.ARCHIVEDPAGE',"Archived page '%s'"), $record->Title))
|
||||
);
|
||||
|
||||
// Even if the record has been deleted from stage and live, it can be viewed in "archive mode"
|
||||
return $this->getResponseNegotiator()->respond($this->getRequest());
|
||||
}
|
||||
|
||||
public function publish($data, $form) {
|
||||
$data['publish'] = '1';
|
||||
|
||||
|
@ -286,7 +286,7 @@ class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_DeletedPages.Title', "All pages, including deleted");
|
||||
return _t('CMSSiteTreeFilter_DeletedPages.Title', "All pages, including archived");
|
||||
}
|
||||
|
||||
public function getFilteredPages() {
|
||||
@ -305,7 +305,7 @@ class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
|
||||
class CMSSiteTreeFilter_ChangedPages extends CMSSiteTreeFilter {
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_ChangedPages.Title', "Changed pages");
|
||||
return _t('CMSSiteTreeFilter_ChangedPages.Title', "Modified pages");
|
||||
}
|
||||
|
||||
public function getFilteredPages() {
|
||||
@ -354,7 +354,7 @@ class CMSSiteTreeFilter_StatusRemovedFromDraftPages extends CMSSiteTreeFilter {
|
||||
class CMSSiteTreeFilter_StatusDraftPages extends CMSSiteTreeFilter {
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_StatusDraftPages.Title', 'Draft unpublished pages');
|
||||
return _t('CMSSiteTreeFilter_StatusDraftPages.Title', 'Draft pages');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,7 +393,7 @@ class CMSSiteTreeFilter_StatusDeletedPages extends CMSSiteTreeFilter {
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_StatusDeletedPages.Title', 'Deleted pages');
|
||||
return _t('CMSSiteTreeFilter_StatusDeletedPages.Title', 'Archived pages');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,7 +119,7 @@ class ContentController extends Controller {
|
||||
|| (Versioned::current_stage() && Versioned::current_stage() != 'Live')
|
||||
)
|
||||
) {
|
||||
if(!$this->dataRecord->canViewStage(Versioned::current_archived_date() ? 'Stage' : Versioned::current_stage())) {
|
||||
if(!$this->dataRecord->canView()) {
|
||||
Session::clear('currentStage');
|
||||
Session::clear('archiveDate');
|
||||
|
||||
|
@ -260,6 +260,7 @@ class ErrorPage extends Page {
|
||||
$this->response->addHeader('X-Status', rawurlencode($fileErrorText));
|
||||
return $this->httpError(405);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -509,7 +509,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
*/
|
||||
public function RelativeLink($action = null) {
|
||||
if($this->ParentID && self::config()->nested_urls) {
|
||||
$base = $this->Parent()->RelativeLink($this->URLSegment);
|
||||
$parent = $this->Parent();
|
||||
// If page is removed select parent from version history (for archive page view)
|
||||
if((!$parent || !$parent->exists()) && $this->IsDeletedFromStage) {
|
||||
$parent = Versioned::get_latest_version('SiteTree', $this->ParentID);
|
||||
}
|
||||
$base = $parent->RelativeLink($this->URLSegment);
|
||||
} elseif(!$action && $this->URLSegment == RootURLController::get_homepage_link()) {
|
||||
// Unset base for root-level homepages.
|
||||
// Note: Homepages with action parameters (or $action === true)
|
||||
@ -2298,20 +2303,50 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
if($this->canDelete() && $this->canDeleteFromLive()) {
|
||||
// "delete from live"
|
||||
$majorActions->push(
|
||||
FormAction::create('deletefromlive',_t('CMSMain.DELETEFP','Delete'))->addExtraClass('ss-ui-action-destructive')
|
||||
FormAction::create('deletefromlive',_t('CMSMain.DELETEFP','Delete'))
|
||||
->addExtraClass('ss-ui-action-destructive')
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Determine if we should force a restore to root (where once it was a subpage)
|
||||
$restoreToRoot = $this->isParentArchived();
|
||||
|
||||
// "restore"
|
||||
$title = $restoreToRoot
|
||||
? _t('CMSMain.RESTORE_TO_ROOT','Restore draft at top level')
|
||||
: _t('CMSMain.RESTORE','Restore draft');
|
||||
$description = $restoreToRoot
|
||||
? _t('CMSMain.RESTORE_TO_ROOT_DESC','Restore the archived version to draft as a top level page')
|
||||
: _t('CMSMain.RESTORE_DESC', 'Restore the archived version to draft');
|
||||
$majorActions->push(
|
||||
FormAction::create('restore',_t('CMSMain.RESTORE','Restore'))->setAttribute('data-icon', 'decline')
|
||||
FormAction::create('restore', $title)
|
||||
->setDescription($description)
|
||||
->setAttribute('data-to-root', $restoreToRoot)
|
||||
->setAttribute('data-icon', 'decline')
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if($this->canDelete()) {
|
||||
// "delete"
|
||||
// Detect use of legacy actions
|
||||
// {@see CMSMain::enabled_legacy_actions}
|
||||
$legacy = CMSMain::config()->enabled_legacy_actions;
|
||||
if(in_array('CMSBatchAction_Delete', $legacy)) {
|
||||
Deprecation::notice('4.0', 'Delete from Stage is deprecated. Use Archive instead.');
|
||||
if($this->canDelete()) {
|
||||
// delete
|
||||
$moreOptions->push(
|
||||
FormAction::create('delete',_t('CMSMain.DELETE','Delete draft'))
|
||||
->addExtraClass('delete ss-ui-action-destructive')
|
||||
);
|
||||
}
|
||||
} elseif($this->canArchive()) {
|
||||
// "archive"
|
||||
$moreOptions->push(
|
||||
FormAction::create('delete',_t('CMSMain.DELETE','Delete draft'))->addExtraClass('delete ss-ui-action-destructive')
|
||||
FormAction::create('archive',_t('CMSMain.ARCHIVE','Archive'))
|
||||
->setDescription(_t(
|
||||
'SiteTree.BUTTONARCHIVEDESC',
|
||||
'Unpublish and send to archive'
|
||||
))
|
||||
->addExtraClass('delete ss-ui-action-destructive')
|
||||
);
|
||||
}
|
||||
|
||||
@ -2353,6 +2388,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
*
|
||||
* @uses SiteTreeExtension->onBeforePublish()
|
||||
* @uses SiteTreeExtension->onAfterPublish()
|
||||
* @return bool True if published
|
||||
*/
|
||||
public function doPublish() {
|
||||
if (!$this->canPublish()) return false;
|
||||
@ -2461,6 +2497,22 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
}
|
||||
|
||||
$this->invokeWithExtensions('onAfterRevertToLive', $this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this page references a parent which is archived, and not available in stage
|
||||
*
|
||||
* @return bool True if there is an archived parent
|
||||
*/
|
||||
protected function isParentArchived() {
|
||||
if($parentID = $this->ParentID) {
|
||||
$parentPage = Versioned::get_latest_version("SiteTree", $parentID);
|
||||
if(!$parentPage || $parentPage->IsDeletedFromStage) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2469,6 +2521,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
* @return self
|
||||
*/
|
||||
public function doRestoreToStage() {
|
||||
// Ensure that the parent page is restored, otherwise restore to root
|
||||
if($this->isParentArchived()) {
|
||||
$this->ParentID = 0;
|
||||
}
|
||||
|
||||
// if no record can be found on draft stage (meaning it has been "deleted from draft" before),
|
||||
// create an empty record
|
||||
if(!DB::prepared_query("SELECT \"ID\" FROM \"SiteTree\" WHERE \"ID\" = ?", array($this->ID))->value()) {
|
||||
@ -2496,6 +2553,50 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the page from both live and stage
|
||||
*
|
||||
* @return bool Success
|
||||
*/
|
||||
public function doArchive() {
|
||||
if($this->doUnpublish()) {
|
||||
$this->delete();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user is allowed to archive this page.
|
||||
* If extended, ensure that both canDelete and canDeleteFromLive are extended also
|
||||
*
|
||||
* @param Member $member
|
||||
* @return bool
|
||||
*/
|
||||
public function canArchive($member = null) {
|
||||
if(!$member) {
|
||||
$member = Member::currentUser();
|
||||
}
|
||||
|
||||
// Standard mechanism for accepting permission changes from extensions
|
||||
$extended = $this->extendedCan('canArchive', $member);
|
||||
if($extended !== null) {
|
||||
return $extended;
|
||||
}
|
||||
|
||||
// Check if this page can be deleted
|
||||
if(!$this->canDelete($member)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If published, check if we can delete from live
|
||||
if($this->ExistsOnLive && !$this->canDeleteFromLive($member)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synonym of {@link doUnpublish}
|
||||
*/
|
||||
@ -2689,9 +2790,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
'title' => _t('SiteTree.REMOVEDFROMDRAFTHELP', 'Page is published, but has been deleted from draft'),
|
||||
);
|
||||
} else {
|
||||
$flags['deletedonlive'] = array(
|
||||
'text' => _t('SiteTree.DELETEDPAGESHORT', 'Deleted'),
|
||||
'title' => _t('SiteTree.DELETEDPAGEHELP', 'Page is no longer published'),
|
||||
$flags['archived'] = array(
|
||||
'text' => _t('SiteTree.ARCHIVEDPAGESHORT', 'Archived'),
|
||||
'title' => _t('SiteTree.ARCHIVEDPAGEHELP', 'Page is removed from draft and live'),
|
||||
);
|
||||
}
|
||||
} else if($this->IsAddedToStage) {
|
||||
|
@ -276,6 +276,116 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_archive
|
||||
*
|
||||
* Informing the user about the archive action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_archive').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t('CMSMain.Archive'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_restore
|
||||
*
|
||||
* Informing the user about the archive action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_restore').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '',
|
||||
toRoot = this.data('toRoot');
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t(toRoot ? 'CMSMain.RestoreToRoot' : 'CMSMain.Restore'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_delete
|
||||
*
|
||||
* Informing the user about the delete from draft action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_delete').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t('CMSMain.DeleteFromDraft'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_unpublish
|
||||
* Informing the user about the unpublish action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_unpublish').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t('CMSMain.Unpublish'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Enable save buttons upon detecting changes to content.
|
||||
* "changed" class is added by jQuery.changetracker.
|
||||
|
@ -36,8 +36,13 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
|
||||
"Tree.ThisPageOnly": "This page only",
|
||||
"Tree.ThisPageAndSubpages": "This page and subpages",
|
||||
"Tree.ShowAsList": "Show children as list",
|
||||
"CMSMain.ConfirmRestoreFromLive": "Do you really want to copy the published content to the draft site?",
|
||||
"CMSMain.ConfirmRestoreFromLive": "Are you sure you want to revert draft to when the page was last published?",
|
||||
"CMSMain.RollbackToVersion": "Do you really want to roll back to version #%s of this page?",
|
||||
"CMSMain.Archive": "Are you sure you want to archive this page?\n\nThe page will be unpublished and sent to the archive.",
|
||||
"CMSMain.Restore": "Are you sure you want to restore this page from archive?",
|
||||
"CMSMain.RestoreToRoot": "Are you sure you want to restore this page from archive?\n\nBecause the parent page is not available this will be restored to the top level.",
|
||||
"CMSMain.Unpublish": "Are you sure you want to remove your page from the published site?\n\nThis page will still be available in the sitetree as draft.",
|
||||
"CMSMain.DeleteFromDraft": "Are you sure you want to remove your page from the draft site?\n\nThis page will remain on the published site.",
|
||||
"URLSEGMENT.Edit": "Edit",
|
||||
"URLSEGMENT.OK": "OK",
|
||||
"URLSEGMENT.Cancel": "Cancel",
|
||||
|
@ -31,8 +31,13 @@
|
||||
"Tree.ThisPageOnly": "This page only",
|
||||
"Tree.ThisPageAndSubpages": "This page and subpages",
|
||||
"Tree.ShowAsList": "Show children as list",
|
||||
"CMSMain.ConfirmRestoreFromLive": "Do you really want to copy the published content to the draft site?",
|
||||
"CMSMain.ConfirmRestoreFromLive": "Are you sure you want to revert draft to when the page was last published?",
|
||||
"CMSMain.RollbackToVersion": "Do you really want to roll back to version #%s of this page?",
|
||||
"CMSMain.Archive": "Are you sure you want to archive this page?\n\nThe page will be unpublished and sent to the archive.",
|
||||
"CMSMain.Restore": "Are you sure you want to restore this page from archive?",
|
||||
"CMSMain.RestoreToRoot": "Are you sure you want to restore this page from archive?\n\nBecause the parent page is not available this will be restored to the top level.",
|
||||
"CMSMain.Unpublish": "Are you sure you want to remove your page from the published site?\n\nThis page will still be available in the sitetree as draft.",
|
||||
"CMSMain.DeleteFromDraft": "Are you sure you want to remove your page from the draft site?\n\nThis page will remain on the published site.",
|
||||
"URLSEGMENT.Edit": "Edit",
|
||||
"URLSEGMENT.OK": "OK",
|
||||
"URLSEGMENT.Cancel": "Cancel",
|
||||
|
21
lang/en.yml
21
lang/en.yml
@ -67,8 +67,8 @@ en:
|
||||
DELETE_PAGES: 'Delete from published site'
|
||||
PUBLISHED_PAGES: 'Published %d pages, %d failures'
|
||||
PUBLISH_PAGES: Publish
|
||||
UNPUBLISHED_PAGES: 'Un-published %d pages'
|
||||
UNPUBLISH_PAGES: Un-publish
|
||||
UNPUBLISHED_PAGES: 'Unpublished %d pages'
|
||||
UNPUBLISH_PAGES: Unpublish
|
||||
CMSMain:
|
||||
ACCESS: 'Access to ''{title}'' section'
|
||||
ACCESS_HELP: 'Allow viewing of the section containing page tree and content. View and edit permissions can be handled through page specific dropdowns, as well as the separate "Content permissions".'
|
||||
@ -100,8 +100,11 @@ en:
|
||||
REMOVED: 'Deleted ''{title}''{description} from live site'
|
||||
REMOVEDPAGE: 'Removed ''{title}'' from the published site'
|
||||
REMOVEDPAGEFROMDRAFT: 'Removed ''%s'' from the draft site'
|
||||
RESTORE: Restore
|
||||
RESTORE: 'Restore draft'
|
||||
RESTORE_TO_ROOT: 'Restore draft at top level'
|
||||
RESTORE_TO_ROOT_DESC: 'Restore the archived version to draft as a top level page'
|
||||
RESTORED: 'Restored ''{title}'' successfully'
|
||||
RESTORE_DESC: 'Restore the archived version to draft'
|
||||
ROLLBACK: 'Roll back to this version'
|
||||
ROLLEDBACKPUBv2: 'Rolled back to published version.'
|
||||
ROLLEDBACKVERSIONv2: 'Rolled back to version #%d.'
|
||||
@ -152,11 +155,19 @@ en:
|
||||
FILTERDATETO: To
|
||||
FILTERLABELTEXT: Content
|
||||
CMSSiteTreeFilter_ChangedPages:
|
||||
Title: 'Changed pages'
|
||||
Title: 'Modified pages'
|
||||
CMSSiteTreeFilter_DeletedPages:
|
||||
Title: 'All pages, including deleted'
|
||||
Title: 'All pages, including archived'
|
||||
CMSSIteTreeFilter_PublishedPages:
|
||||
Title: 'Published pages'
|
||||
CMSSiteTreeFilter_Search:
|
||||
Title: 'All pages'
|
||||
CMSSiteTreeFilter_StatusDeletedPages:
|
||||
Title: 'Archived pages'
|
||||
CMSSiteTreeFilter_StatusDraftPages:
|
||||
Title: 'Draft pages'
|
||||
CMSSiteTreeFilter_StatusRemovedFromDraftPages:
|
||||
Title: 'Live but removed from draft'
|
||||
ContentControl:
|
||||
NOTEWONTBESHOWN: 'Note: this message will not be shown to your visitors'
|
||||
ContentController:
|
||||
|
@ -35,7 +35,7 @@ So that only high quality changes are seen by our visitors
|
||||
When I click "More options" in the "#ActionMenus" element
|
||||
Then I should not see "Unpublish" in the "#ActionMenus_MoreOptions" element
|
||||
And I should see "Not published" in the "#ActionMenus_MoreOptions" element
|
||||
And I should see "Delete draft" in the "#ActionMenus_MoreOptions" element
|
||||
And I should see "Archive" in the "#ActionMenus_MoreOptions" element
|
||||
And I should see a "Save & publish" button
|
||||
And I should see a "Saved" button
|
||||
|
||||
@ -48,7 +48,7 @@ So that only high quality changes are seen by our visitors
|
||||
When I press the "Publish" button
|
||||
And I click "More options" in the "#ActionMenus" element
|
||||
Then I should see "Unpublish" in the "#ActionMenus_MoreOptions" element
|
||||
And I should see "Delete draft" in the "#ActionMenus_MoreOptions" element
|
||||
And I should see "Archive" in the "#ActionMenus_MoreOptions" element
|
||||
And I should see a "Published" button
|
||||
And I should see a "Saved" button
|
||||
|
||||
@ -64,7 +64,7 @@ So that only high quality changes are seen by our visitors
|
||||
And I click on "Hello" in the tree
|
||||
|
||||
When I click "More options" in the "#ActionMenus" element
|
||||
And I press the "Unpublish" button
|
||||
And I press the "Unpublish" button, confirming the dialog
|
||||
|
||||
Then I press the "Log out" button
|
||||
And I go to "/hello"
|
||||
@ -80,16 +80,16 @@ So that only high quality changes are seen by our visitors
|
||||
And I click "More options" in the "#ActionMenus" element
|
||||
Then I should see "Unpublish" in the "#ActionMenus_MoreOptions" element
|
||||
|
||||
When I press the "Unpublish" button
|
||||
When I press the "Unpublish" button, confirming the dialog
|
||||
And I click "More options" in the "#ActionMenus" element
|
||||
Then I should see "Delete draft" in the "#ActionMenus_MoreOptions" element
|
||||
Then I should see "Archive" in the "#ActionMenus_MoreOptions" element
|
||||
|
||||
When I press the "Delete draft" button
|
||||
When I press the "Archive" button, confirming the dialog
|
||||
Then I should see a "Restore" button
|
||||
And I should not see a "Published" button
|
||||
And I should not see a "Save & publish" button
|
||||
And I should not see a "Saved" button
|
||||
And I should not see a "Save draft" button
|
||||
|
||||
When I press the "Restore" button
|
||||
When I press the "Restore" button, confirming the dialog
|
||||
Then I should see a "Save & publish" button
|
||||
|
@ -46,7 +46,7 @@ Feature: Search for a page
|
||||
And the "page" "Deleted Page" is deleted
|
||||
When I press the "Apply Filter" button
|
||||
Then I should not see "Deleted Page" in the tree
|
||||
When I select "All pages, including deleted" from "Pages"
|
||||
When I select "All pages, including archived" from "Pages"
|
||||
And I press the "Apply Filter" button
|
||||
Then I should see "Deleted Page" in the tree
|
||||
|
||||
@ -56,7 +56,7 @@ Feature: Search for a page
|
||||
And the "page" "Deleted Page" is deleted
|
||||
When I press the "Apply Filter" button
|
||||
Then I should not see "Deleted Page" in the tree
|
||||
When I select "Deleted pages" from "Pages"
|
||||
When I select "Archived pages" from "Pages"
|
||||
And I press the "Apply Filter" button
|
||||
Then I should see "Deleted Page" in the tree
|
||||
And I should not see "About Us" in the tree
|
||||
@ -66,7 +66,7 @@ Feature: Search for a page
|
||||
And the "page" "Draft Page" is not published
|
||||
When I press the "Apply Filter" button
|
||||
Then I should see "Draft Page" in the tree
|
||||
When I select "Draft unpublished pages" from "Pages"
|
||||
When I select "Draft pages" from "Pages"
|
||||
And I press the "Apply Filter" button
|
||||
Then I should see "Draft Page" in the tree
|
||||
And I should not see "About Us" in the tree
|
||||
@ -81,7 +81,7 @@ Feature: Search for a page
|
||||
|
||||
When I go to "/admin/pages"
|
||||
And I expand the "Filter" CMS Panel
|
||||
When I select "Changed pages" from "Pages"
|
||||
When I select "Modified pages" from "Pages"
|
||||
And I press the "Apply Filter" button
|
||||
Then I should see "About Us" in the tree
|
||||
And I should not see "Home" in the tree
|
||||
|
86
tests/controller/CMSBatchActionsTest.php
Normal file
86
tests/controller/CMSBatchActionsTest.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Tests CMS Specific subclasses of {@see CMSBatchAction}
|
||||
*/
|
||||
class CMSBatchActionsTest extends SapphireTest {
|
||||
|
||||
protected static $fixture_file = 'CMSBatchActionsTest.yml';
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// published page
|
||||
$published = $this->objFromFixture('Page', 'published');
|
||||
$published->doPublish();
|
||||
|
||||
// Deleted / archived page
|
||||
$archived = $this->objFromFixture('Page', 'archived');
|
||||
$archived->doArchive();
|
||||
|
||||
// Unpublished
|
||||
$unpublished = $this->objFromFixture('Page', 'unpublished');
|
||||
$unpublished->doPublish();
|
||||
$unpublished->doUnpublish();
|
||||
|
||||
// Modified
|
||||
$modified = $this->objFromFixture('Page', 'modified');
|
||||
$modified->doPublish();
|
||||
$modified->Title = 'modified2';
|
||||
$modified->write();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test which pages can be published via batch actions
|
||||
*/
|
||||
public function testBatchPublish() {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$pages = Versioned::get_including_deleted('Page');
|
||||
$ids = $pages->column('ID');
|
||||
$action = new CMSBatchAction_Publish();
|
||||
|
||||
// Test applicable pages
|
||||
$applicable = $action->applicablePages($ids);
|
||||
$this->assertContains($this->idFromFixture('Page', 'published'), $applicable);
|
||||
$this->assertNotContains($this->idFromFixture('Page', 'archived'), $applicable);
|
||||
$this->assertContains($this->idFromFixture('Page', 'unpublished'), $applicable);
|
||||
$this->assertContains($this->idFromFixture('Page', 'modified'), $applicable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test which pages can be unpublished via batch actions
|
||||
*/
|
||||
public function testBatchUnpublish() {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$pages = Versioned::get_including_deleted('Page');
|
||||
$ids = $pages->column('ID');
|
||||
$action = new CMSBatchAction_Unpublish();
|
||||
|
||||
// Test applicable page
|
||||
$applicable = $action->applicablePages($ids);
|
||||
$this->assertContains($this->idFromFixture('Page', 'published'), $applicable);
|
||||
$this->assertNotContains($this->idFromFixture('Page', 'archived'), $applicable);
|
||||
$this->assertNotContains($this->idFromFixture('Page', 'unpublished'), $applicable);
|
||||
$this->assertContains($this->idFromFixture('Page', 'modified'), $applicable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test which pages can be published via batch actions
|
||||
*/
|
||||
public function testBatchArchive() {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$pages = Versioned::get_including_deleted('Page');
|
||||
$ids = $pages->column('ID');
|
||||
$action = new CMSBatchAction_Archive();
|
||||
|
||||
// Test applicable pages
|
||||
$applicable = $action->applicablePages($ids);
|
||||
$this->assertContains($this->idFromFixture('Page', 'published'), $applicable);
|
||||
$this->assertNotContains($this->idFromFixture('Page', 'archived'), $applicable);
|
||||
$this->assertContains($this->idFromFixture('Page', 'unpublished'), $applicable);
|
||||
$this->assertContains($this->idFromFixture('Page', 'modified'), $applicable);
|
||||
}
|
||||
|
||||
}
|
9
tests/controller/CMSBatchActionsTest.yml
Normal file
9
tests/controller/CMSBatchActionsTest.yml
Normal file
@ -0,0 +1,9 @@
|
||||
Page:
|
||||
published:
|
||||
Title: Published
|
||||
archived:
|
||||
Title: archived
|
||||
unpublished:
|
||||
Title: unpublished
|
||||
modified:
|
||||
Title: modified1
|
@ -4,7 +4,7 @@
|
||||
* - action_save
|
||||
* - action_publish
|
||||
* - action_unpublish
|
||||
* - action_delete
|
||||
* - action_archive
|
||||
* - action_deletefromlive
|
||||
* - action_rollback
|
||||
* - action_revert
|
||||
@ -83,7 +83,7 @@ class SiteTreeActionsTest extends FunctionalTest {
|
||||
$this->assertNotNull($actions->dataFieldByName('action_save'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_publish'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_unpublish'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_delete'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_archive'));
|
||||
$this->assertNull($actions->dataFieldByName('action_deletefromlive'));
|
||||
$this->assertNull($actions->dataFieldByName('action_rollback'));
|
||||
$this->assertNull($actions->dataFieldByName('action_revert'));
|
||||
@ -111,7 +111,7 @@ class SiteTreeActionsTest extends FunctionalTest {
|
||||
$this->assertNull($actions->dataFieldByName('action_save'));
|
||||
$this->assertNull($actions->dataFieldByName('action_publish'));
|
||||
$this->assertNull($actions->dataFieldByName('action_unpublish'));
|
||||
$this->assertNull($actions->dataFieldByName('action_delete'));
|
||||
$this->assertNull($actions->dataFieldByName('action_archive'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_deletefromlive'));
|
||||
$this->assertNull($actions->dataFieldByName('action_rollback'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_revert'));
|
||||
@ -135,7 +135,7 @@ class SiteTreeActionsTest extends FunctionalTest {
|
||||
$this->assertNotNull($actions->dataFieldByName('action_save'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_publish'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_unpublish'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_delete'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_archive'));
|
||||
$this->assertNull($actions->dataFieldByName('action_deletefromlive'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_rollback'));
|
||||
$this->assertNull($actions->dataFieldByName('action_revert'));
|
||||
@ -155,7 +155,7 @@ class SiteTreeActionsTest extends FunctionalTest {
|
||||
$this->assertNull($actions->dataFieldByName('action_save'));
|
||||
$this->assertNull($actions->dataFieldByName('action_publish'));
|
||||
$this->assertNull($actions->dataFieldByName('action_unpublish'));
|
||||
$this->assertNull($actions->dataFieldByName('action_delete'));
|
||||
$this->assertNull($actions->dataFieldByName('action_archive'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_email'));
|
||||
$this->assertNotNull($actions->dataFieldByName('action_rollback'));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user