ENHANCEMENT: implemented CMSPageHistoryController with comparsion view, single version view into new CMSMain API.

This commit is contained in:
Will Rossiter 2011-08-19 12:32:31 +12:00 committed by Ingo Schommer
parent d0b419c5a9
commit d90ea0d236
26 changed files with 592 additions and 499 deletions

View File

@ -1,12 +0,0 @@
<?php
class CMSPageHistoryController extends CMSMain {
static $url_segment = 'page/history';
static $url_rule = '/$Action/$ID/$OtherID';
static $url_priority = 42;
function getEditForm($id = null, $fields = null) {
return "Not implemented yet";
}
}

View File

@ -1,11 +1,12 @@
<?php
/**
* The main "content" area of the CMS.
*
* This class creates a 2-frame layout - left-tree and right-form - to sit beneath the main
* admin menu.
*
* @package cms
* @subpackage content
* @subpackage controller
* @todo Create some base classes to contain the generic functionality that will be replicated.
*/
class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionProvider {
@ -29,13 +30,11 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
static $allowed_actions = array(
'addpage',
'buildbrokenlinks',
'compareversions',
'deleteitems',
'DeleteItemsForm',
'dialog',
'duplicate',
'duplicatewithchildren',
'getversion',
'publishall',
'publishitems',
'PublishItemsForm',
@ -43,8 +42,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
'sidereport',
'SideReportsForm',
'submit',
'versions',
'VersionsForm',
'EditForm',
'AddForm',
'SearchForm',
@ -78,6 +75,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
CMS_DIR . '/javascript/CMSMain.js',
CMS_DIR . '/javascript/CMSMain.EditForm.js',
CMS_DIR . '/javascript/CMSMain.AddForm.js',
CMS_DIR . '/javascript/CMSPageHistoryController.js',
CMS_DIR . '/javascript/SilverStripeNavigator.js'
)
);
@ -172,12 +170,12 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
$fields = new FieldSet(
new TextField('Term', _t('CMSSearch.FILTERLABELTEXT', 'Content')),
$dateGroup = new FieldGroup(
$dateFrom = new DateField('LastEditedFrom', _t('CMSSearch.FilterDateFrom', 'from')),
$dateTo = new DateField('LastEditedTo', _t('CMSSearch.FilterDateFrom', 'to'))
$dateFrom = new DateField('LastEditedFrom', _t('CMSSearch.FILTERDATEFROM', 'From')),
$dateTo = new DateField('LastEditedTo', _t('CMSSearch.FILTERDATETO', 'To'))
),
new DropdownField(
'FilterClass',
_t('CMSMain.SearchTreeFormPagesDropdown', 'Pages'),
_t('CMSMain.PAGES', 'Pages'),
$filterMap
),
new DropdownField(
@ -347,17 +345,24 @@ JS;
return $form->forTemplate();
}
/**
* Get a database record to be managed by the CMS
* Get a database record to be managed by the CMS.
*
* @param int $id Record ID
* @param int $versionID optional Version id of the given record
*/
public function getRecord($id) {
public function getRecord($id, $versionID = null) {
$treeClass = $this->stat('tree_class');
if($id instanceof $treeClass) {
return $id;
} else if($id && is_numeric($id)) {
$version = isset($_REQUEST['Version']) ? $_REQUEST['Version'] : null;
if(is_numeric($version)) {
$versionID = null;
if(isset($_REQUEST['Version'])) $versionID = (int) $_REQUEST['Version'];
if($versionID && is_int($version)) {
$record = Versioned::get_version($treeClass, $id, $version);
} else {
$record = DataObject::get_one($treeClass, "\"$treeClass\".\"ID\" = $id");
@ -470,7 +475,7 @@ JS;
$readonlyFields = $form->Fields()->makeReadonly();
$form->setFields($readonlyFields);
}
$this->extend('updateEditForm', $form);
return $form;
@ -909,100 +914,6 @@ JS;
}
}
/**
* @return Form
*/
function VersionsForm() {
$pageID = ($this->request->requestVar('ID')) ? $this->request->requestVar('ID') : $this->currentPageID();
$page = $this->getRecord($pageID);
if($page) {
$versions = $page->allVersions(
($this->request->requestVar('ShowUnpublished')) ?
"" : "\"SiteTree\".\"WasPublished\" = 1"
);
// inject link to cms
if($versions) foreach($versions as $k => $version) {
$version->CMSLink = sprintf('%s/%s/%s',
$this->Link('getversion'),
$version->ID,
$version->Version
);
}
$vd = new ViewableData();
$versionsHtml = $vd->customise(
array('Versions'=>$versions)
)->renderWith('CMSMain_versions');
} else {
$versionsHtml = '';
}
$form = new Form(
$this,
'VersionsForm',
new FieldSet(
new CheckboxField(
'ShowUnpublished',
_t('CMSMain_left.ss.SHOWUNPUB','Show unpublished versions')
),
new LiteralField('VersionsHtml', $versionsHtml),
new HiddenField('ID', false, $pageID),
new HiddenField('Locale', false, $this->Locale)
),
new FieldSet(
new FormAction(
'versions',
_t('CMSMain.BTNREFRESH','Refresh')
),
new FormAction(
'compareversions',
_t('CMSMain.BTNCOMPAREVERSIONS','Compare Versions')
)
)
);
$form->loadDataFrom($this->request->requestVars());
$form->setFormMethod('GET');
$form->unsetValidator();
return $form;
}
/**
* Get the versions of the current page
*/
function versions() {
$form = $this->VersionsForm();
return (Director::is_ajax()) ? $form->forTemplate() : $form;
}
/**
* Roll a page back to a previous version
*/
function rollback($data, $form) {
$this->extend('onBeforeRollback', $data['ID']);
if(isset($data['Version']) && (bool)$data['Version']) {
$record = $this->performRollback($data['ID'], $data['Version']);
$message = sprintf(
_t('CMSMain.ROLLEDBACKVERSION',"Rolled back to version #%d. New version number is #%d"),
$data['Version'],
$record->Version
);
} else {
$record = $this->performRollback($data['ID'], "Live");
$message = sprintf(
_t('CMSMain.ROLLEDBACKPUB',"Rolled back to published version. New version number is #%d"),
$record->Version
);
}
$this->response->addHeader('X-Status', $message);
$form = $this->getEditForm($record->ID);
return $form->forTemplate();
}
function publish($data, $form) {
$data['publish'] = '1';
@ -1036,179 +947,6 @@ JS;
return $record;
}
/**
* Supports both direct URL links (format: admin/getversion/<page-id>/<version>),
* and through GET parameters: admin/getversion/?ID=<page-id>&Versions[]=<version>
*/
function getversion() {
$id = ($this->request->param('ID')) ?
$this->request->param('ID') : $this->request->requestVar('ID');
$version = ($this->request->param('OtherID')) ?
$this->request->param('OtherID') : $this->request->requestVar('Versions');
$record = Versioned::get_version("SiteTree", $id, $version);
if($record) {
if($record && !$record->canView()) return Security::permissionFailure($this);
$fields = $record->getCMSFields($this);
$fields->removeByName("Status");
$fields->push(new HiddenField("ID"));
$fields->push(new HiddenField("Version"));
$versionAuthor = DataObject::get_by_id('Member', $record->AuthorID);
if(!$versionAuthor) $versionAuthor = new ArrayData(array('Title' => 'Unknown author'));
$fields->insertBefore(
new LiteralField(
'YouAreViewingHeader',
'<p class="message notice">' .
sprintf(
_t(
'CMSMain.VIEWING',
"You are viewing version #%s, created %s by %s",
PR_MEDIUM,
'Version number is a linked string, created is a relative time (e.g. 2 days ago), by a specific author'
),
"<a href=\"admin/getversion/$record->ID/$version\" title=\"" . ($versionAuthor ? $versionAuthor->Title : '') . "\">$version</a>",
$record->obj('LastEdited')->Ago(),
($versionAuthor ? $versionAuthor->Title : '')
) .
'</p>'
),
'Root'
);
$actions = $record->getCMSActions();
// encode the message to appear in the body of the email
$archiveURL = Director::absoluteBaseURL() . $record->URLSegment . '?archiveDate=' . $record->obj('LastEdited')->URLDatetime();
// Ensure that source file comments are disabled
SSViewer::set_source_file_comments(false);
$archiveEmailMessage = urlencode( $this->customise( array( 'ArchiveDate' => $record->obj('LastEdited'), 'ArchiveURL' => $archiveURL ) )->renderWith( 'ViewArchivedEmail' ) );
$archiveEmailMessage = preg_replace( '/\+/', '%20', $archiveEmailMessage );
$fields->push( new HiddenField( 'ArchiveEmailMessage', '', $archiveEmailMessage ) );
$fields->push( new HiddenField( 'ArchiveEmailSubject', '', preg_replace( '/\+/', '%20', urlencode( 'Archived version of ' . $record->Title ) ) ) );
$fields->push( new HiddenField( 'ArchiveURL', '', $archiveURL ) );
$form = new Form($this, "EditForm", $fields, $actions);
$form->loadDataFrom($record);
$form->loadDataFrom(array(
"ID" => $id,
"Version" => $version,
));
// historical version shouldn't be editable
$readonlyFields = $form->Fields()->makeReadonly();
$form->setFields($readonlyFields);
$templateData = $this->customise(array(
"EditForm" => $form
));
SSViewer::setOption('rewriteHashlinks', false);
if(Director::is_ajax()) {
$result = $templateData->renderWith(array($this->class . '_right', 'LeftAndMain_right'));
$parts = split('</?form[^>]*>', $result);
$content = $parts[sizeof($parts)-2];
if($this->ShowSwitchView()) {
$content .= '<div id="AjaxSwitchView">' . $this->SwitchView($record) . '</div>';
}
return $content;
} else {
return $templateData->renderWith('LeftAndMain');
}
}
}
function compareversions() {
$id = ($this->request->param('ID')) ?
$this->request->param('ID') : $this->request->requestVar('ID');
$versions = $this->request->requestVar('Versions');
$version1 = ($versions && isset($versions[0])) ?
$versions[0] : $this->request->getVar('From');
$version2 = ($versions && isset($versions[1])) ?
$versions[1] : $this->request->getVar('To');
if( $version1 > $version2 ) {
$toVersion = $version1;
$fromVersion = $version2;
} else {
$toVersion = $version2;
$fromVersion = $version1;
}
if(!$toVersion || !$toVersion) return false;
$page = DataObject::get_by_id("SiteTree", $id);
if($page && !$page->canView()) return Security::permissionFailure($this);
$record = $page->compareVersions($fromVersion, $toVersion);
$fromVersionRecord = Versioned::get_version('SiteTree', $id, $fromVersion);
$toVersionRecord = Versioned::get_version('SiteTree', $id, $toVersion);
if(!$fromVersionRecord) user_error("Can't find version $fromVersion of page $id", E_USER_ERROR);
if(!$toVersionRecord) user_error("Can't find version $toVersion of page $id", E_USER_ERROR);
if($record) {
$fromDateNice = $fromVersionRecord->obj('LastEdited')->Ago();
$toDateNice = $toVersionRecord->obj('LastEdited')->Ago();
$fromAuthor = DataObject::get_by_id('Member', $fromVersionRecord->AuthorID);
if(!$fromAuthor) $fromAuthor = new ArrayData(array('Title' => 'Unknown author'));
$toAuthor = DataObject::get_by_id('Member', $toVersionRecord->AuthorID);
if(!$toAuthor) $toAuthor = new ArrayData(array('Title' => 'Unknown author'));
$fields = $record->getCMSFields($this);
$fields->push(new HiddenField("ID"));
$fields->push(new HiddenField("Version"));
$fields->insertBefore(
new LiteralField(
'YouAreComparingHeader',
'<p class="message notice">' .
sprintf(
_t('CMSMain.COMPARINGV',"Comparing versions %s and %s"),
"<a href=\"admin/getversion/$id/$fromVersionRecord->Version\" title=\"$fromAuthor->Title\">$fromVersionRecord->Version</a> <small>($fromDateNice)</small>",
"<a href=\"admin/getversion/$id/$toVersionRecord->Version\" title=\"$toAuthor->Title\">$toVersionRecord->Version</a> <small>($toDateNice)</small>"
) .
'</p>'
),
"Root"
);
$actions = new FieldSet();
$form = new Form($this, "EditForm", $fields, $actions);
$form->loadDataFrom($record);
$form->loadDataFrom(array(
"ID" => $id,
"Version" => $fromVersion,
));
$form->addExtraClass('compare');
// comparison views shouldn't be editable
$readonlyFields = $form->Fields()->makeReadonly();
$form->setFields($readonlyFields);
foreach($form->Fields()->dataFields() as $field) {
$field->dontEscape = true;
}
if($this->isAjax()) {
return $form->forTemplate();
} else {
$templateData = $this->customise(array(
"EditForm" => $form
));
return $templateData->renderWith('LeftAndMain');
}
}
}
function sendFormToBrowser($templateData) {
if(Director::is_ajax()) {
SSViewer::setOption('rewriteHashlinks', false);

View File

@ -0,0 +1,322 @@
<?php
/**
* @package cms
* @subpackage controllers
*/
class CMSPageHistoryController extends CMSMain {
static $url_segment = 'page/history';
static $url_rule = '/$Action/$ID/$VersionID/$OtherVersionID';
static $url_priority = 42;
static $menu_title = 'History';
static $allowed_actions = array(
'VersionsForm',
'version',
'compare'
);
public static $url_handlers = array(
'$Action/$ID/$VersionID/$OtherVersionID' => 'handleAction'
);
/**
* @var array
*/
function version() {
return array(
'EditForm' => $this->ShowVersionForm(
$this->request->param('ID')
)
);
}
/**
* @var array
*/
function compare() {
return array(
'EditForm' => $this->CompareVersionsForm(
$this->request->param('VersionID'),
$this->request->param('OtherVersionID')
)
);
}
/**
* Returns the read only version of the edit form. Detaches {@link FormAction}
* instances attached since only action relates to revert.
*
* Permission checking is done at the {@link CMSMain::getEditForm()} level.
*
* @param int $id ID of the record to show
* @param array $fields optional
* @param int $versionID
*/
function getEditForm($id = null, $fields = null, $versionID = null) {
$record = $this->getRecord($id, $versionID);
$form = parent::getEditForm($record, ($record) ? $record->getCMSFields() : null);
$fields = $form->Fields();
$fields->removeByName("Status");
$fields->push(new HiddenField("ID"));
$fields->push(new HiddenField("Version"));
$fields = $fields->makeReadonly();
foreach($fields->dataFields() as $field) {
$field->dontEscape = true;
}
$form->setFields($fields->makeReadonly());
// attach additional information
$form->loadDataFrom(array(
"ID" => $id,
"Version" => $versionID,
));
$form->setActions(new FieldSet(
$revert = new FormAction('doRevert', _t('CMSPageHistoryController.REVERTTOTHISVERSION', 'Revert to this version'))
));
$form->removeExtraClass('cms-content');
return $form;
}
/**
* Compare version selection form. Displays a list of previous versions
* and options for selecting filters on the version
*
* @return Form
*/
function VersionsForm() {
$id = $this->currentPageID();
$page = $this->getRecord($id);
$versionsHtml = '';
if($page) {
$versions = $page->allVersions();
if($versions) {
foreach($versions as $k => $version) {
$version->CMSLink = sprintf('%s/%s/%s',
$this->Link('version'),
$version->ID,
$version->Version
);
}
}
$vd = new ViewableData();
$versionsHtml = $vd->customise(array(
'Versions' => $versions
))->renderWith('CMSPageHistoryController_versions');
}
$form = new Form(
$this,
'VersionsForm',
new FieldSet(
new CheckboxField(
'ShowUnpublished',
_t('CMSPageHistoryController.SHOWUNPUBLISHED','Show unpublished versions')
),
new CheckboxField(
'CompareMode',
_t('CMSPageHistoryController.COMPAREMODE', 'Compare mode')
),
new LiteralField('VersionsHtml', $versionsHtml),
new HiddenField('ID', false, $id)
),
new FieldSet(
new FormAction(
'doCompare', _t('CMSPageHistoryController.COMPAREVERSIONS','Compare Versions')
),
new FormAction(
'doShowVersion', _t('CMSPageHistoryController.SHOWVERSION','Show Version')
)
)
);
$form->loadDataFrom($this->request->requestVars());
$form->unsetValidator();
return $form;
}
/**
* Process the {@link VersionsForm} compare function between two pages.
*
* @param array
* @param Form
*
* @return html
*/
function doCompare($data, $form) {
$versions = $data['Versions'];
if(count($versions) < 2) return null;
$id = $this->currentPageID();
$version1 = array_shift($versions);
$version2 = array_shift($versions);
$form = $this->CompareVersionsForm($version1, $version2);
// javascript solution, render into template
if($this->isAjax()) {
return $this->customise(array(
"EditForm" => $form
))->renderWith(array(
$this->class . '_EditForm',
'LeftAndMain_Content'
));
}
// non javascript, redirect the user to the page
$this->redirect(Controller::join_links(
$this->Link('compare'),
$version1,
$version2
));
}
/**
* Process the {@link VersionsForm} show version function. Only requires
* one page to be selected.
*
* @param array
* @param Form
*
* @return html
*/
function doShowVersion($data, $form) {
$versionID = null;
if(isset($data['Versions']) && is_array($data['Versions'])) {
$versionID = array_shift($data['Versions']);
}
if(!$versionID) return;
if($this->isAjax()) {
return $this->customise(array(
"EditForm" => $this->ShowVersionForm($versionID)
))->renderWith(array(
$this->class . '_EditForm',
'LeftAndMain_Content'
));
}
// non javascript, redirect the user to the page
$this->redirect(Controller::join_links(
$this->Link('version'),
$versionID
));
}
/**
* Rolls a site back to a given version ID
*
* @param array
* @param Form
*
* @return html
*/
function doRollback($data, $form) {
//
}
/**
* @return Form
*/
function ShowVersionForm($versionID = null) {
if(!$versionID) return null;
$id = $this->currentPageID();
$form = $this->getEditForm($id, null, $versionID);
return $form;
}
/**
* @return Form
*/
function CompareVersionsForm($versionID, $otherVersionID) {
if($versionID > $otherVersionID) {
$toVersion = $versionID;
$fromVersion = $otherVersionID;
} else {
$toVersion = $otherVersionID;
$fromVersion = $versionID;
}
if(!$toVersion || !$toVersion) return false;
$id = $this->currentPageID();
$page = DataObject::get_by_id("SiteTree", $id);
if($page && !$page->canView()) {
return Security::permissionFailure($this);
}
$record = $page->compareVersions($fromVersion, $toVersion);
$fromVersionRecord = Versioned::get_version('SiteTree', $id, $fromVersion);
$toVersionRecord = Versioned::get_version('SiteTree', $id, $toVersion);
if(!$fromVersionRecord) {
user_error("Can't find version $fromVersion of page $id", E_USER_ERROR);
}
if(!$toVersionRecord) {
user_error("Can't find version $toVersion of page $id", E_USER_ERROR);
}
if($record) {
$form = $this->getEditForm($id, null, null);
$form->setActions(new FieldSet());
$form->loadDataFrom($record);
$form->loadDataFrom(array(
"ID" => $id,
"Version" => $fromVersion,
));
$form->addExtraClass('compare');
return $form;
}
}
/**
* Roll a page back to a previous version
*/
function rollback($data, $form) {
$this->extend('onBeforeRollback', $data['ID']);
if(isset($data['Version']) && (bool)$data['Version']) {
$record = $this->performRollback($data['ID'], $data['Version']);
$message = sprintf(
_t('CMSMain.ROLLEDBACKVERSION',"Rolled back to version #%d. New version number is #%d"),
$data['Version'],
$record->Version
);
} else {
$record = $this->performRollback($data['ID'], "Live");
$message = sprintf(
_t('CMSMain.ROLLEDBACKPUB',"Rolled back to published version. New version number is #%d"),
$record->Version
);
}
$this->response->addHeader('X-Status', $message);
$form = $this->getEditForm($record->ID);
return $form->forTemplate();
}
}

View File

@ -1,13 +1,19 @@
<?php
/**
* @package cms
*/
class CMSPageSettingsController extends CMSMain {
static $url_segment = 'page/settings';
static $url_rule = '/$Action/$ID/$OtherID';
static $url_priority = 42;
function getEditForm($id = null, $fields = null) {
$record = $this->getRecord($id ? $id : $this->currentPageID());
return parent::getEditForm($record, ($record) ? $record->getSettingsFields() : null);
}
}

View File

@ -1,4 +1,8 @@
<?php
/**
* @package cms
*/
class CMSPagesController extends CMSMain {
static $url_segment = 'pages';
@ -16,18 +20,18 @@ class CMSPagesController extends CMSMain {
if($request->param('ID')) {
$c = new CMSPageEditController();
return $this->redirect(Controller::join_links($c->Link('show'), $request->param('ID')));
} else {
return parent::show($request);
}
return parent::show($request);
}
function Link($action = null) {
// Special case: All show links should redirect to the page edit interface instead (mostly from tree nodes)
if(preg_match('/^show/', $action)) {
return singleton('CMSPageEditController')->Link($action);
} else {
return parent::Link($action);
}
return parent::Link($action);
}
}

View File

@ -0,0 +1,5 @@
/** Style custom to the CMSMain admin interface. CMSMain extends the built in sapphire admin section styles. As much as possible we want to use those built in styles. If anything in this file can be implemented in a generic way then it should be include in the admin scss files. @package cms */
/** ------------------------------------------------------------------ Page History Section. ----------------------------------------------------------------- */
#cms-page-history-versions tr.loading { color: #999; }
#cms-page-history-versions tr.loading td:hover { cursor: none; }
#cms-page-history-versions td:hover { cursor: pointer; }

View File

@ -194,32 +194,6 @@
}
});
/**
* Class: .cms-edit-form .Actions #Form_EditForm_action_email
*
* Email containing the link to the archived version of the page.
* Visible on readonly older versions of a specific page at the moment.
*/
$('.cms-edit-form .Actions #Form_EditForm_action_email').entwine({
/**
* Function: onclick
*
* Parameters:
* (Event) e
*/
onclick: function(e) {
window.open(
'mailto:?subject='
+ $('input[name=ArchiveEmailSubject]', this[0].form).val()
+ '&body='
+ $(':input[name=ArchiveEmailMessage]', this[0].form).val(),
'archiveemail'
);
return false;
}
});
/**
* Class: .cms-edit-form .Actions #Form_EditForm_action_print
*

View File

@ -213,133 +213,5 @@
return false;
}
});
/**
* Class: #Form_VersionsForm
*
* Simple form showing versions of a specific page.
*/
$('#Form_VersionsForm').entwine({
onmatch: function() {
var self = this;
// set button to be available in form submit event later on
this.find(':submit').bind('click', function(e) {
self.data('_clickedButton', this);
});
this.bind('submit', function(e) {
return self._submit();
});
// integrate with sitetree selection changes
jQuery('.cms-tree').bind('select_node.jstree', function(e, data) {
var node = data.rslt.obj;
self.find(':input[name=ID]').val(node ? $(node).data('id') : null);
if(self.is(':visible')) self.trigger('submit');
});
// refresh when field is selected
// TODO coupling
$('#treepanes').bind('accordionchange', function(e, ui) {
if($(ui.newContent).attr('id') == 'Form_VersionsForm') self.trigger('submit');
});
// submit when 'show unpublished versions' checkbox is changed
this.find(':input[name=ShowUnpublished]').bind('change', function(e) {
// force the refresh button, not 'compare versions'
self.data('_clickedButton', self.find(':submit[name=action_versions]'));
self.trigger('submit');
});
// move submit button to the top
// this.find('#ReportClass').after(this.find('.Actions'));
// links in results
this.find('td').bind('click', function(e) {
var td = $(this);
// exclude checkboxes
if($(e.target).is(':input')) return true;
var link = $(this).siblings('.versionlink').find('a').attr('href');
td.addClass('loading');
jQuery('.cms-content').entwine('ss').loadForm(
link,
null,
function(e) {
td.removeClass('loading');
}
);
return false;
});
// compare versions action
this.find(':submit[name=action_compareversions]').bind('click', function(e) {
// validation: only allow selection of exactly two versions
var versions = self.find(':input[name=Versions[]]:checked');
if(versions.length != 2) {
alert(ss.i18n._t(
'CMSMain.VALIDATIONTWOVERSION',
'Please select two versions'
));
return false;
}
// overloaded submission: refresh the right form instead
self.data('_clickedButton', this);
self._submit(true);
return false;
});
this._super();
},
/**
* Function: _submit
*
* Parameters:
* (bool) loadEditForm - Determines if responses should show in current panel,
* or in the edit form (in the case of 'compare versions').
*/
_submit: function(loadEditForm) {
var self = this;
// Don't submit with empty ID
if(!this.find(':input[name=ID]').val()) return false;
var $button = (self.data('_clickedButton')) ? $(self.data('_clickedButton')) : this.find(':submit:first');
$button.addClass('loading');
var data = this.serializeArray();
data.push({name:$button.attr('name'), value: $button.val()});
if(loadEditForm) {
jQuery('.cms-content').entwine('ss').loadForm(
this.attr('action'),
null,
function(e) {
$button.removeClass('loading');
},
{data: data, type: 'POST'}
);
} else {
jQuery.ajax({
url: this.attr('action'),
data: data,
dataType: 'html',
success: function(data, status) {
self.replaceWith(data);
},
complete: function(xmlhttp, status) {
$button.removeClass('loading');
}
});
}
return false;
}
});
});
})(jQuery);

View File

@ -0,0 +1,163 @@
(function($) {
/**
* File: CMSPageHistoryController.js
*
* Handles related interactions between the version selection form on the
* left hand side of the panel and the version displaying on the right
* hand side.
*/
$.entwine('ss', function($){
/**
* Class: #Form_VersionsForm
*
* The left hand side version selection form is the main interface for
* users to select a version to view, or to compare two versions
*/
$('#Form_VersionsForm').entwine({
/**
* Constructor
*/
onmatch: function() {
var self = this;
/**
* Event: :input[name=ShowUnpublished] change
*
* Changing the show unpublished checkbox toggles whether to show
* or hide the unpublished versions. Because those rows may be being
* compared this also ensures those rows are unselected.
*/
this.find(':input[name=ShowUnpublished]').bind('change', function(e) {
if($(this).attr("checked")) {
self.find("tr[data-published=false]").show();
}
else {
self.find("tr[data-published=false]").hide()._unselect();
}
});
this._super();
},
/**
* Function: submit.
*
* Submits either the compare versions form or the view single form
* display based on whether we have two or 1 option selected
*/
onsubmit: function(e, d) {
var id, self = this;
id = this.find(':input[name=ID]').val();
if(!id) return false;
var button, url, selected, to, from, compare;
compare = (this.find(":input[name=CompareMode]").is(":checked"));
selected = this.find("table input[type=checkbox]").filter(":checked");
if(compare) {
if(selected.length != 2) return false;
to = selected.eq(0).val();
from = selected.eq(1).val();
button = this.find(':submit[name=action_doCompare]');
url = 'admin/page/history/compare/'+ [id,from,to].join('/') +"/";
}
else {
to = selected.eq(0).val();
button = this.find(':submit[name=action_doShowVersion]');
url = 'admin/page/history/version/'+ [id,to].join('/') + "/";
}
// we can access this comparsion directly in the url.
window.History.pushState({selector: '.cms-content-fields form:first'}, '', url);
var data = this.serializeArray();
data.push({
name: button.attr('name'), value: button.val()
});
$('.cms-content').loadForm(this.attr('action'), null, function() {}, {
data: data, type: this.attr('method')
});
return false;
}
});
/**
* Class: #Form_VersionsForm tr
*
* An individual row in the versions form. Selecting the row updates
* the edit form depending on whether we're showing individual version
* information or displaying comparsion.
*/
$("#Form_VersionsForm tbody tr").entwine({
/**
* Function: onclick
*
* Selects or deselects the row (if in compare mode). Will trigger
* an update of the edit form if either selected (in single mode)
* or if this is the second row selected (in compare mode)
*/
onclick: function(e) {
var compare, selected;
// compare mode
compare = this.parents("form").find(':input[name=CompareMode]').attr("checked"),
selected = this.siblings(".active");
if(compare && this.hasClass('active')) {
this._unselect();
return;
}
else if(compare) {
// check if we have already selected more than two.
if(selected.length > 1) {
return alert(ss.i18n._t('ONLYSELECTTWO', 'Can only compare two versions at at time.'));
}
this._select();
// if this is the second selected then we can compare.
if(selected.length == 1) {
this.parents('form').submit();
}
return;
}
else {
this._select();
selected._unselect();
this.parents("form").submit();
}
},
/**
* Function: _unselect()
*
* Unselects the row from the form selection.
*/
_unselect: function() {
this.removeClass('active');
this.find(":input[type=checkbox]").attr("checked", false);
},
/**
* Function: _select()
*
* Selects the currently matched row in the form selection
*/
_select: function() {
this.addClass('active');
this.find(":input[type=checkbox]").attr("checked", true);
}
})
});
})(jQuery);

View File

@ -0,0 +1,31 @@
/**
* Style custom to the CMSMain admin interface. CMSMain extends the built in
* sapphire admin section styles. As much as possible we want to use those
* built in styles. If anything in this file can be implemented in a generic
* way then it should be include in the admin scss files.
*
* @package cms
*/
/** ------------------------------------------------------------------
* Page History Section.
* ----------------------------------------------------------------- */
#cms-page-history-versions {
tr {
&.loading {
color: #999;
td {
&:hover {
cursor: none;
}
}
}
}
td {
&:hover {
cursor: pointer;
}
}
}

View File

@ -1,40 +0,0 @@
<table id="Versions">
<thead>
<tr>
<td class="checkbox"></td>
<td>#</td>
<td><% _t('WHEN','When') %></td>
<td><% _t('AUTHOR','User') %></td>
<td><% _t('PUBR','Publisher') %></td>
</tr>
</thead>
<tbody>
<% control Versions %>
<tr id="page-$RecordID-version-$Version" class="$EvenOdd $PublishedClass">
<td class="checkbox">
<input type="checkbox" name="Versions[]" id="Versions_$Version" value="$Version" />
</td>
<td class="versionlink">
<a href="$CMSLink">$Version</a>
</td>
<td class="$LastEdited" title="$LastEdited.Ago - $LastEdited.Nice">
$LastEdited.Ago
</td>
<td>
$Author.FirstName $Author.Surname.Initial
</td>
<td>
<% if Published %>
<% if Publisher %>
$Publisher.FirstName $Publisher.Surname.Initial
<% else %>
<% _t('UNKNOWN','Unknown') %>
<% end_if %>
<% else %>
<% _t('NOTPUB','Not published') %>
<% end_if %>
</td>
</tr>
<% end_control %>
</tbody>
</table>

View File

@ -0,0 +1,23 @@
<table id="cms-page-history-versions">
<thead>
<tr>
<th class="ui-helper-hidden"></th>
<th><% _t('WHEN','When') %></th>
<th><% _t('AUTHOR','Author') %></th>
<th><% _t('PUBLISHER','Publisher') %></th>
</tr>
</thead>
<tbody>
<% control Versions %>
<tr id="page-$RecordID-version-$Version" class="$EvenOdd $PublishedClass<% if not WasPublished %> ui-helper-hidden<% end_if %>" data-published="<% if WasPublished %>true<% else %>false<% end_if %>"data-link="$CMSLink">
<td class="ui-helper-hidden"><input type="checkbox" name="Versions[]" id="cms-_$Version" value="$Version" /></td>
<% control LastEdited %>
<td class="last-edited first-column" title="$Ago - $Nice">$Nice</td>
<% end_control %>
<td><% if Author %>$Author.FirstName $Author.Surname.Initial<% else %><% _t('UNKNOWN','Unknown') %><% end_if %></td>
<td class="last-column"><% if Published %><% if Publisher %>$Publisher.FirstName $Publisher.Surname.Initial<% else %><% _t('UNKNOWN','Unknown') %><% end_if %><% else %><% _t('NOTPUBLISHED','Not published') %><% end_if %></td>
</tr>
<% end_control %>
</tbody>
</table>

View File

@ -1,3 +1,15 @@
<div class="cms-content center $BaseCSSClasses">
<i>Not implemented yet</i>
<div class="cms-content center $BaseCSSClasses" data-layout="{type: 'border'}">
<div class="cms-content-tools west cms-panel" data-expandOnClick="true">
<div class="cms-content-header north">
<div>
<h2><% _t('CMSPageHistoryController.History','History') %></h2>
</div>
</div>
<div class="cms-panel-content cms-helper-hide-actions">
$VersionsForm
</div>
</div>
$EditForm
</div>

View File

@ -1,3 +0,0 @@
<div class="cms-content center $BaseCSSClasses">
<i>Not implemented yet</i>
</div>

View File

@ -22,13 +22,11 @@
<div class="cms-content-tools west cms-panel" data-expandOnClick="true">
<h3 class="cms-panel-header">Filter</h3>
<h3 class="cms-panel-header"><% _t('FILTER', 'Filter') %></h3>
<div class="cms-panel-content">
$SearchForm
</div>
</div>
<div class="cms-content-fields center ui-widget-content">