mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
Merge branch '3.4' into 3
This commit is contained in:
commit
3959508463
@ -12,14 +12,14 @@ class CMSPageHistoryController extends CMSMain {
|
||||
private static $menu_title = 'History';
|
||||
private static $required_permission_codes = 'CMS_ACCESS_CMSMain';
|
||||
private static $session_namespace = 'CMSMain';
|
||||
|
||||
|
||||
private static $allowed_actions = array(
|
||||
'VersionsForm',
|
||||
'CompareVersionsForm',
|
||||
'show',
|
||||
'compare'
|
||||
);
|
||||
|
||||
|
||||
private static $url_handlers = array(
|
||||
'$Action/$ID/$VersionID/$OtherVersionID' => 'handleAction'
|
||||
);
|
||||
@ -37,14 +37,14 @@ class CMSPageHistoryController extends CMSMain {
|
||||
});
|
||||
return $negotiator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return array
|
||||
*/
|
||||
public function show($request) {
|
||||
$form = $this->ShowVersionForm($request->param('VersionID'));
|
||||
|
||||
|
||||
$negotiator = $this->getResponseNegotiator();
|
||||
$controller = $this;
|
||||
$negotiator->setCallback('CurrentForm', function() use(&$controller, &$form) {
|
||||
@ -56,7 +56,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
|
||||
return $negotiator->respond($request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return array
|
||||
@ -88,7 +88,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the read only version of the edit form. Detaches all {@link FormAction}
|
||||
* instances attached since only action relates to revert.
|
||||
@ -104,10 +104,10 @@ class CMSPageHistoryController extends CMSMain {
|
||||
*/
|
||||
public function getEditForm($id = null, $fields = null, $versionID = null, $compareID = null) {
|
||||
if(!$id) $id = $this->currentPageID();
|
||||
|
||||
|
||||
$record = $this->getRecord($id, $versionID);
|
||||
$versionID = ($record) ? $record->Version : $versionID;
|
||||
|
||||
|
||||
$form = parent::getEditForm($record, ($record) ? $record->getCMSFields() : null);
|
||||
// Respect permission failures from parent implementation
|
||||
if(!($form instanceof Form)) return $form;
|
||||
@ -118,14 +118,14 @@ class CMSPageHistoryController extends CMSMain {
|
||||
$form->setActions(new FieldList(
|
||||
$revert = FormAction::create('doRollback', _t('CMSPageHistoryController.REVERTTOTHISVERSION', 'Revert to this version'))->setUseButtonTag(true)
|
||||
));
|
||||
|
||||
|
||||
$fields = $form->Fields();
|
||||
$fields->removeByName("Status");
|
||||
$fields->push(new HiddenField("ID"));
|
||||
$fields->push(new HiddenField("Version"));
|
||||
|
||||
$fields = $fields->makeReadonly();
|
||||
|
||||
|
||||
$fields = $fields->makeReadonly();
|
||||
|
||||
if($compareID) {
|
||||
$link = Controller::join_links(
|
||||
$this->Link('show'),
|
||||
@ -133,7 +133,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
);
|
||||
|
||||
$view = _t('CMSPageHistoryController.VIEW',"view");
|
||||
|
||||
|
||||
$message = _t(
|
||||
'CMSPageHistoryController.COMPARINGVERSION',
|
||||
"Comparing versions {version1} and {version2}.",
|
||||
@ -142,7 +142,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
'version2' => sprintf('%s (<a href="%s">%s</a>)', $compareID, Controller::join_links($link, $compareID), $view)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$revert->setReadonly(true);
|
||||
} else {
|
||||
if($record->isLatestVersion()) {
|
||||
@ -155,7 +155,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$fields->addFieldToTab('Root.Main',
|
||||
new LiteralField('CurrentlyViewingMessage', $this->customise(array(
|
||||
'Content' => $message,
|
||||
@ -169,17 +169,17 @@ class CMSPageHistoryController extends CMSMain {
|
||||
"ID" => $id,
|
||||
"Version" => $versionID,
|
||||
));
|
||||
|
||||
|
||||
if(($record && $record->isLatestVersion())) {
|
||||
$revert->setReadonly(true);
|
||||
}
|
||||
|
||||
|
||||
$form->removeExtraClass('cms-content');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Version select form. Main interface between selecting versions to view
|
||||
* and comparing multiple versions.
|
||||
@ -197,7 +197,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
$action = $this->getRequest()->param('Action');
|
||||
$versionID = $this->getRequest()->param('VersionID');
|
||||
$otherVersionID = $this->getRequest()->param('OtherVersionID');
|
||||
|
||||
|
||||
$showUnpublishedChecked = 0;
|
||||
$compareModeChecked = ($action == "compare");
|
||||
|
||||
@ -208,19 +208,19 @@ class CMSPageHistoryController extends CMSMain {
|
||||
if($versions) {
|
||||
foreach($versions as $k => $version) {
|
||||
$active = false;
|
||||
|
||||
|
||||
if($version->Version == $versionID || $version->Version == $otherVersionID) {
|
||||
$active = true;
|
||||
|
||||
|
||||
if(!$version->WasPublished) $showUnpublishedChecked = 1;
|
||||
}
|
||||
|
||||
$version->Active = ($active);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$vd = new ViewableData();
|
||||
|
||||
|
||||
$versionsHtml = $vd->customise(array(
|
||||
'Versions' => $versions
|
||||
))->renderWith('CMSPageHistoryController_versions');
|
||||
@ -263,15 +263,15 @@ class CMSPageHistoryController extends CMSMain {
|
||||
$form->loadDataFrom($this->getRequest()->requestVars());
|
||||
$hiddenID->setValue($id);
|
||||
$form->unsetValidator();
|
||||
|
||||
|
||||
$form
|
||||
->addExtraClass('cms-versions-form') // placeholder, necessary for $.metadata() to work
|
||||
->setAttribute('data-link-tmpl-compare', Controller::join_links($this->Link('compare'), '%s', '%s', '%s'))
|
||||
->setAttribute('data-link-tmpl-show', Controller::join_links($this->Link('show'), '%s', '%s'));
|
||||
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the {@link VersionsForm} compare function between two pages.
|
||||
*
|
||||
@ -283,7 +283,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
public function doCompare($data, $form) {
|
||||
$versions = $data['Versions'];
|
||||
if(count($versions) < 2) return null;
|
||||
|
||||
|
||||
$id = $this->currentPageID();
|
||||
$version1 = array_shift($versions);
|
||||
$version2 = array_shift($versions);
|
||||
@ -299,7 +299,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
'LeftAndMain_Content'
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
// non javascript, redirect the user to the page
|
||||
$this->redirect(Controller::join_links(
|
||||
$this->Link('compare'),
|
||||
@ -316,16 +316,16 @@ class CMSPageHistoryController extends CMSMain {
|
||||
* @param Form
|
||||
*
|
||||
* @return html
|
||||
*/
|
||||
*/
|
||||
public function doShowVersion($data, $form) {
|
||||
$versionID = null;
|
||||
|
||||
|
||||
if(isset($data['Versions']) && is_array($data['Versions'])) {
|
||||
$versionID = array_shift($data['Versions']);
|
||||
}
|
||||
|
||||
|
||||
if(!$versionID) return;
|
||||
|
||||
|
||||
if($request->isAjax()) {
|
||||
return $this->customise(array(
|
||||
"EditForm" => $this->ShowVersionForm($versionID)
|
||||
@ -354,11 +354,11 @@ class CMSPageHistoryController extends CMSMain {
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $versionID
|
||||
* @param int $otherVersionID
|
||||
* @return Form
|
||||
* @return mixed
|
||||
*/
|
||||
public function CompareVersionsForm($versionID, $otherVersionID) {
|
||||
if($versionID > $otherVersionID) {
|
||||
@ -369,51 +369,57 @@ class CMSPageHistoryController extends CMSMain {
|
||||
$fromVersion = $versionID;
|
||||
}
|
||||
|
||||
if(!$toVersion || !$fromVersion) return false;
|
||||
|
||||
$id = $this->currentPageID();
|
||||
$page = DataObject::get_by_id("SiteTree", $id);
|
||||
|
||||
if($page && !$page->canView()) {
|
||||
return Security::permissionFailure($this);
|
||||
if(!$toVersion || !$toVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$record = $page->compareVersions($fromVersion, $toVersion);
|
||||
$id = $this->currentPageID();
|
||||
$page = DataObject::get_by_id("SiteTree", $id);
|
||||
|
||||
if($page && $page->exists()) {
|
||||
if(!$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) {
|
||||
if(isset($record)) {
|
||||
$form = $this->getEditForm($id, null, null, true);
|
||||
$form->setActions(new FieldList());
|
||||
$form->addExtraClass('compare');
|
||||
|
||||
|
||||
// Comparison views shouldn't be editable.
|
||||
// Its important to convert fields *before* loading data,
|
||||
// as the comparison output is HTML and not valid values for the various field types
|
||||
$readonlyFields = $form->Fields()->makeReadonly();
|
||||
$form->setFields($readonlyFields);
|
||||
|
||||
|
||||
$form->loadDataFrom($record);
|
||||
$form->loadDataFrom(array(
|
||||
"ID" => $id,
|
||||
"Version" => $fromVersion,
|
||||
));
|
||||
|
||||
|
||||
foreach($form->Fields()->dataFields() as $field) {
|
||||
$field->dontEscape = true;
|
||||
}
|
||||
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function Breadcrumbs($unlinked = false) {
|
||||
|
@ -2694,7 +2694,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
} else {
|
||||
$subclasses = ClassInfo::subclassesFor($candidate);
|
||||
foreach($subclasses as $subclass) {
|
||||
if($subclass != "SiteTree_root") $allowedChildren[] = $subclass;
|
||||
if ($subclass == 'SiteTree_root' || singleton($subclass) instanceof HiddenClass) {
|
||||
continue;
|
||||
}
|
||||
$allowedChildren[] = $subclass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,13 @@
|
||||
* @subpackage tests
|
||||
*/
|
||||
class SiteTreeTest extends SapphireTest {
|
||||
|
||||
|
||||
protected static $fixture_file = 'SiteTreeTest.yml';
|
||||
|
||||
protected $illegalExtensions = array(
|
||||
'SiteTree' => array('SiteTreeSubsites', 'Translatable')
|
||||
);
|
||||
|
||||
|
||||
protected $extraDataObjects = array(
|
||||
'SiteTreeTest_ClassA',
|
||||
'SiteTreeTest_ClassB',
|
||||
@ -27,7 +27,7 @@ class SiteTreeTest extends SapphireTest {
|
||||
public function logOut() {
|
||||
if($member = Member::currentUser()) $member->logOut();
|
||||
}
|
||||
|
||||
|
||||
public function testCreateDefaultpages() {
|
||||
$remove = SiteTree::get();
|
||||
if($remove) foreach($remove as $page) $page->delete();
|
||||
@ -513,7 +513,7 @@ class SiteTreeTest extends SapphireTest {
|
||||
$this->assertFalse(singleton('SiteTreeTest_ClassA')->canCreate(null, array('Parent' => $parentB)));
|
||||
$this->assertTrue(singleton('SiteTreeTest_ClassC')->canCreate(null, array('Parent' => $parentB)));
|
||||
}
|
||||
|
||||
|
||||
public function testEditPermissionsOnDraftVsLive() {
|
||||
// Create an inherit-permission page
|
||||
$page = new Page();
|
||||
@ -709,7 +709,7 @@ class SiteTreeTest extends SapphireTest {
|
||||
$this->assertEquals($sitetree->URLSegment, 'new-page',
|
||||
'Sets based on default title on first save'
|
||||
);
|
||||
|
||||
|
||||
$sitetree->Title = 'Changed';
|
||||
$sitetree->write();
|
||||
$this->assertEquals($sitetree->URLSegment, 'changed',
|
||||
@ -889,43 +889,73 @@ class SiteTreeTest extends SapphireTest {
|
||||
);
|
||||
}
|
||||
|
||||
public function testAllowedChildren() {
|
||||
/**
|
||||
* Tests that core subclasses of SiteTree are included in allowedChildren() by default, but not instances of
|
||||
* HiddenClass
|
||||
*/
|
||||
public function testAllowedChildrenContainsCoreSubclassesButNotHiddenClass()
|
||||
{
|
||||
$page = new SiteTree();
|
||||
$allowedChildren = $page->allowedChildren();
|
||||
|
||||
$this->assertContains(
|
||||
'VirtualPage',
|
||||
$page->allowedChildren(),
|
||||
'Includes core subclasses by default'
|
||||
);
|
||||
'VirtualPage',
|
||||
$allowedChildren,
|
||||
'Includes core subclasses by default'
|
||||
);
|
||||
|
||||
$classA = new SiteTreeTest_ClassA();
|
||||
$this->assertEquals(
|
||||
array('SiteTreeTest_ClassB'),
|
||||
$classA->allowedChildren(),
|
||||
'Direct setting of allowed children'
|
||||
);
|
||||
$this->assertNotContains(
|
||||
'SiteTreeTest_ClassE',
|
||||
$allowedChildren,
|
||||
'HiddenClass instances should not be returned'
|
||||
);
|
||||
}
|
||||
|
||||
$classB = new SiteTreeTest_ClassB();
|
||||
$this->assertEquals(
|
||||
array('SiteTreeTest_ClassC', 'SiteTreeTest_ClassCext'),
|
||||
$classB->allowedChildren(),
|
||||
'Includes subclasses'
|
||||
);
|
||||
|
||||
$classD = new SiteTreeTest_ClassD();
|
||||
$this->assertEquals(
|
||||
array('SiteTreeTest_ClassC'),
|
||||
$classD->allowedChildren(),
|
||||
'Excludes subclasses if class is prefixed by an asterisk'
|
||||
);
|
||||
|
||||
$classC = new SiteTreeTest_ClassC();
|
||||
$this->assertEquals(
|
||||
array(),
|
||||
$classC->allowedChildren(),
|
||||
'Null setting'
|
||||
);
|
||||
/**
|
||||
* Tests that various types of SiteTree classes will or will not be returned from the allowedChildren method
|
||||
* @dataProvider allowedChildrenProvider
|
||||
* @param string $className
|
||||
* @param array $expected
|
||||
* @param string $assertionMessage
|
||||
*/
|
||||
public function testAllowedChildren($className, $expected, $assertionMessage)
|
||||
{
|
||||
$class = new $className;
|
||||
$this->assertEquals($expected, $class->allowedChildren(), $assertionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function allowedChildrenProvider()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
// Class name
|
||||
'SiteTreeTest_ClassA',
|
||||
// Expected
|
||||
array('SiteTreeTest_ClassB'),
|
||||
// Assertion message
|
||||
'Direct setting of allowed children'
|
||||
),
|
||||
array(
|
||||
'SiteTreeTest_ClassB',
|
||||
array('SiteTreeTest_ClassC', 'SiteTreeTest_ClassCext'),
|
||||
'Includes subclasses'
|
||||
),
|
||||
array(
|
||||
'SiteTreeTest_ClassC',
|
||||
array(),
|
||||
'Null setting'
|
||||
),
|
||||
array(
|
||||
'SiteTreeTest_ClassD',
|
||||
array('SiteTreeTest_ClassC'),
|
||||
'Excludes subclasses if class is prefixed by an asterisk'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAllowedChildrenValidation() {
|
||||
$page = new SiteTree();
|
||||
$page->write();
|
||||
@ -1075,7 +1105,7 @@ class SiteTreeTest extends SapphireTest {
|
||||
$this->assertEquals($breadcrumbs->first()->Title, "Breadcrumbs 4", "First item should be Breadrcumbs 4.");
|
||||
$this->assertEquals($breadcrumbs->last()->Title, "Breadcrumbs 5", "Breadcrumbs 5 should be last.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests SiteTree::MetaTags
|
||||
* Note that this test makes no assumption on the closing of tags (other than <title></title>)
|
||||
@ -1193,11 +1223,11 @@ class SiteTreeTest_PageNode_Controller extends Page_Controller implements TestOn
|
||||
|
||||
class SiteTreeTest_Conflicted extends Page implements TestOnly { }
|
||||
class SiteTreeTest_Conflicted_Controller extends Page_Controller implements TestOnly {
|
||||
|
||||
|
||||
private static $allowed_actions = array (
|
||||
'conflicted-action'
|
||||
);
|
||||
|
||||
|
||||
public function hasActionTemplate($template) {
|
||||
if($template == 'conflicted-template') {
|
||||
return true;
|
||||
@ -1205,7 +1235,7 @@ class SiteTreeTest_Conflicted_Controller extends Page_Controller implements Test
|
||||
return parent::hasActionTemplate($template);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class SiteTreeTest_NullHtmlCleaner extends HTMLCleaner {
|
||||
@ -1217,7 +1247,7 @@ class SiteTreeTest_NullHtmlCleaner extends HTMLCleaner {
|
||||
class SiteTreeTest_ClassA extends Page implements TestOnly {
|
||||
|
||||
private static $need_permission = array('ADMIN', 'CMS_ACCESS_CMSMain');
|
||||
|
||||
|
||||
private static $allowed_children = array('SiteTreeTest_ClassB');
|
||||
}
|
||||
|
||||
@ -1235,6 +1265,10 @@ class SiteTreeTest_ClassD extends Page implements TestOnly {
|
||||
private static $allowed_children = array('*SiteTreeTest_ClassC');
|
||||
}
|
||||
|
||||
class SiteTreeTest_ClassE extends Page implements TestOnly, HiddenClass {
|
||||
|
||||
}
|
||||
|
||||
class SiteTreeTest_ClassCext extends SiteTreeTest_ClassC implements TestOnly {
|
||||
// Override SiteTreeTest_ClassC definitions
|
||||
private static $allowed_children = array('SiteTreeTest_ClassB');
|
||||
|
Loading…
Reference in New Issue
Block a user