mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT Removed object state setting in CMSMain/SiteTree publication process: DeletedFromStage, CheckedPublicationDifferences, IsAddedToStage and added getters for them. Improves testability as we don't have to rely on random methods like MenuTitle() being called to set object state.
ENHANCEMENT Flushing cache in SiteTree->onAfterWrite() and SiteTree->onAfterDelete() to ensure the publication state is up to date git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@69410 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
bc430a96df
commit
40215a9937
@ -435,16 +435,6 @@ class Hierarchy extends DataObjectDecorator {
|
|||||||
// First, go through the stage children. They will all be listed but may be different colours
|
// First, go through the stage children. They will all be listed but may be different colours
|
||||||
if($stageChildren) {
|
if($stageChildren) {
|
||||||
foreach($stageChildren as $child) {
|
foreach($stageChildren as $child) {
|
||||||
// Not found on live = new page
|
|
||||||
if(!isset($idxFoundInLive[$child->ID])) {
|
|
||||||
$child->AddedToStage = true;
|
|
||||||
|
|
||||||
// Version different on live = edited page
|
|
||||||
} else if($idxFoundInLive[$child->ID]->Version != $child->Version) {
|
|
||||||
$child->ModifiedOnStage = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$child->CheckedPublicationDifferences = true;
|
|
||||||
$this->allChildrenIncludingDeleted->push($child);
|
$this->allChildrenIncludingDeleted->push($child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,8 +444,6 @@ class Hierarchy extends DataObjectDecorator {
|
|||||||
foreach($liveChildren as $child) {
|
foreach($liveChildren as $child) {
|
||||||
// Not found on stage = deleted page. Anything else is ignored
|
// Not found on stage = deleted page. Anything else is ignored
|
||||||
if(!isset($idxFoundInStage[$child->ID])) {
|
if(!isset($idxFoundInStage[$child->ID])) {
|
||||||
$child->DeletedFromStage = true;
|
|
||||||
$child->CheckedPublicationDifferences = true;
|
|
||||||
$this->allChildrenIncludingDeleted->push($child);
|
$this->allChildrenIncludingDeleted->push($child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,6 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
*/
|
*/
|
||||||
public function duplicate($doWrite = true) {
|
public function duplicate($doWrite = true) {
|
||||||
$page = parent::duplicate($doWrite);
|
$page = parent::duplicate($doWrite);
|
||||||
$page->CheckedPublicationDifferences = $page->AddedToStage = true;
|
|
||||||
return $page;
|
return $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,7 +988,19 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
parent::onBeforeWrite();
|
parent::onBeforeWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onAfterWrite() {
|
||||||
|
// Need to flush cache to avoid outdated versionnumber references
|
||||||
|
$this->flushCache();
|
||||||
|
|
||||||
|
parent::onAfterWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAfterDelete() {
|
||||||
|
// Need to flush cache to avoid outdated versionnumber references
|
||||||
|
$this->flushCache();
|
||||||
|
|
||||||
|
parent::onAfterDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1278,7 +1289,7 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
function getCMSActions() {
|
function getCMSActions() {
|
||||||
$actions = new FieldSet();
|
$actions = new FieldSet();
|
||||||
|
|
||||||
if($this->isPublished() && $this->canPublish()) {
|
if($this->isPublished() && $this->canPublish() && !$this->IsDeletedFromStage) {
|
||||||
// "unpublish"
|
// "unpublish"
|
||||||
$unpublish = FormAction::create('unpublish', _t('SiteTree.BUTTONUNPUBLISH', 'Unpublish'), 'delete');
|
$unpublish = FormAction::create('unpublish', _t('SiteTree.BUTTONUNPUBLISH', 'Unpublish'), 'delete');
|
||||||
$unpublish->describe(_t('SiteTree.BUTTONUNPUBLISHDESC', "Remove this page from the published site"));
|
$unpublish->describe(_t('SiteTree.BUTTONUNPUBLISHDESC', "Remove this page from the published site"));
|
||||||
@ -1286,7 +1297,7 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
$actions->push($unpublish);
|
$actions->push($unpublish);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->stagesDiffer('Stage', 'Live')) {
|
if($this->stagesDiffer('Stage', 'Live') && !$this->IsDeletedFromStage) {
|
||||||
if($this->isPublished() && $this->canEdit()) {
|
if($this->isPublished() && $this->canEdit()) {
|
||||||
// "rollback"
|
// "rollback"
|
||||||
$rollback = FormAction::create('rollback', _t('SiteTree.BUTTONCANCELDRAFT', 'Cancel draft changes'), 'delete');
|
$rollback = FormAction::create('rollback', _t('SiteTree.BUTTONCANCELDRAFT', 'Cancel draft changes'), 'delete');
|
||||||
@ -1296,7 +1307,7 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->DeletedFromStage) {
|
if($this->IsDeletedFromStage) {
|
||||||
if($this->can('CMSEdit')) {
|
if($this->can('CMSEdit')) {
|
||||||
// "restore"
|
// "restore"
|
||||||
$actions->push(new FormAction('revert',_t('CMSMain.RESTORE','Restore')));
|
$actions->push(new FormAction('revert',_t('CMSMain.RESTORE','Restore')));
|
||||||
@ -1315,7 +1326,7 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->canPublish()) {
|
if($this->canPublish() && !$this->IsDeletedFromStage) {
|
||||||
// "publish"
|
// "publish"
|
||||||
$actions->push(new FormAction('publish', _t('SiteTree.BUTTONSAVEPUBLISH', 'Save and Publish')));
|
$actions->push(new FormAction('publish', _t('SiteTree.BUTTONSAVEPUBLISH', 'Save and Publish')));
|
||||||
}
|
}
|
||||||
@ -1599,34 +1610,17 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function TreeTitle() {
|
function TreeTitle() {
|
||||||
// If somthing
|
if($this->IsDeletedFromStage) {
|
||||||
if(!$this->CheckedPublicationDifferences && $this->ID) {
|
$tag ="del title=\"" . _t('SiteTree.REMOVEDFROMDRAFT', 'Removed from draft site') . "\"";
|
||||||
$stageVersion =
|
} elseif($this->IsAddedToStage) {
|
||||||
DB::query("SELECT \"Version\" FROM \"SiteTree\" WHERE \"ID\" = $this->ID")->value();
|
$tag = "ins title=\"" . _t('SiteTree.ADDEDTODRAFT', 'Added to draft site') . "\"";
|
||||||
$liveVersion =
|
} elseif($this->IsModifiedOnStage) {
|
||||||
DB::query("SELECT \"Version\" FROM \"SiteTree_Live\" WHERE \"ID\" = $this->ID")->value();
|
$tag = "span title=\"" . _t('SiteTree.MODIFIEDONDRAFT', 'Modified on draft site') . "\" class=\"modified\"";
|
||||||
|
} else {
|
||||||
if($stageVersion && !$liveVersion)
|
$tag = '';
|
||||||
$this->AddedToStage = true;
|
|
||||||
else if(!$stageVersion && $liveVersion)
|
|
||||||
$this->DeletedFromStage = true;
|
|
||||||
else if($stageVersion != $liveVersion)
|
|
||||||
$this->ModifiedOnStage = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag =
|
return ($tag) ? "<$tag>" . $this->MenuTitle . "</" . strtok($tag,' ') . ">" : $this->MenuTitle;
|
||||||
($this->DeletedFromStage ?
|
|
||||||
"del title=\"" . _t('SiteTree.REMOVEDFROMDRAFT', 'Removed from draft site') . "\"" :
|
|
||||||
($this->AddedToStage ?
|
|
||||||
"ins title=\"" . _t('SiteTree.ADDEDTODRAFT', 'Added to draft site') . "\"" :
|
|
||||||
($this->ModifiedOnStage ?
|
|
||||||
"span title=\"" . _t('SiteTree.MODIFIEDONDRAFT', 'Modified on draft site') . "\" class=\"modified\"" : "")));
|
|
||||||
|
|
||||||
if($tag) {
|
|
||||||
return "<$tag>" . $this->MenuTitle . "</" . strtok($tag,' ') . ">";
|
|
||||||
} else {
|
|
||||||
return $this->MenuTitle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1675,6 +1669,50 @@ class SiteTree extends DataObject implements PermissionProvider {
|
|||||||
return $classes;
|
return $classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares current draft with live version,
|
||||||
|
* and returns TRUE if no draft version of this page exists,
|
||||||
|
* but the page is still published (after triggering "Delete from draft site" in the CMS).
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function getIsDeletedFromStage() {
|
||||||
|
if(!$this->ID) return true;
|
||||||
|
|
||||||
|
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
|
||||||
|
$liveVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
|
||||||
|
|
||||||
|
return (!$stageVersion && $liveVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares current draft with live version,
|
||||||
|
* and returns TRUE if these versions differ,
|
||||||
|
* meaning there have been unpublished changes to the draft site.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function getIsModifiedOnStage() {
|
||||||
|
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
|
||||||
|
$liveVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
|
||||||
|
|
||||||
|
return ($stageVersion != $liveVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares current draft with live version,
|
||||||
|
* and returns true if no live version exists,
|
||||||
|
* meaning the page was never published.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function getIsAddedToStage() {
|
||||||
|
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
|
||||||
|
$liveVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
|
||||||
|
|
||||||
|
return ($stageVersion && !$liveVersion);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops extendCMSFields() being called on getCMSFields().
|
* Stops extendCMSFields() being called on getCMSFields().
|
||||||
* This is useful when you need access to fields added by subclasses
|
* This is useful when you need access to fields added by subclasses
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
class SiteTreeTest extends SapphireTest {
|
class SiteTreeTest extends SapphireTest {
|
||||||
static $fixture_file = 'sapphire/tests/SiteTreeTest.yml';
|
static $fixture_file = 'sapphire/tests/SiteTreeTest.yml';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test generation of the URLSegment values.
|
* Test generation of the URLSegment values.
|
||||||
* - Turns things into lowercase-hyphen-format
|
* - Turns things into lowercase-hyphen-format
|
||||||
@ -122,6 +121,52 @@ class SiteTreeTest extends SapphireTest {
|
|||||||
$this->assertEquals(0, DB::query("SELECT \"ParentID\" FROM \"SiteTree\" WHERE \"ID\" = $page->ID")->value());
|
$this->assertEquals(0, DB::query("SELECT \"ParentID\" FROM \"SiteTree\" WHERE \"ID\" = $page->ID")->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testStageStates() {
|
||||||
|
// newly created page
|
||||||
|
$createdPage = new SiteTree();
|
||||||
|
$createdPage->write();
|
||||||
|
$this->assertFalse($createdPage->IsDeletedFromStage);
|
||||||
|
$this->assertTrue($createdPage->IsAddedToStage);
|
||||||
|
$this->assertTrue($createdPage->IsModifiedOnStage);
|
||||||
|
|
||||||
|
// published page
|
||||||
|
$publishedPage = new SiteTree();
|
||||||
|
$publishedPage->write();
|
||||||
|
$publishedPage->publish('Stage','Live');
|
||||||
|
$this->assertFalse($publishedPage->IsDeletedFromStage);
|
||||||
|
$this->assertFalse($publishedPage->IsAddedToStage);
|
||||||
|
$this->assertFalse($publishedPage->IsModifiedOnStage);
|
||||||
|
|
||||||
|
// published page, deleted from stage
|
||||||
|
$deletedFromDraftPage = new SiteTree();
|
||||||
|
$deletedFromDraftPage->write();
|
||||||
|
$deletedFromDraftPageID = $deletedFromDraftPage->ID;
|
||||||
|
$deletedFromDraftPage->publish('Stage','Live');
|
||||||
|
$deletedFromDraftPage->deleteFromStage('Stage');
|
||||||
|
$this->assertTrue($deletedFromDraftPage->IsDeletedFromStage);
|
||||||
|
$this->assertFalse($deletedFromDraftPage->IsAddedToStage);
|
||||||
|
$this->assertFalse($deletedFromDraftPage->IsModifiedOnStage);
|
||||||
|
|
||||||
|
// published page, deleted from live
|
||||||
|
$deletedFromLivePage = new SiteTree();
|
||||||
|
$deletedFromLivePage->write();
|
||||||
|
$deletedFromLivePage->publish('Stage','Live');
|
||||||
|
$deletedFromLivePage->deleteFromStage('Stage');
|
||||||
|
$deletedFromLivePage->deleteFromStage('Live');
|
||||||
|
$this->assertTrue($deletedFromLivePage->IsDeletedFromStage);
|
||||||
|
$this->assertFalse($deletedFromLivePage->IsAddedToStage);
|
||||||
|
$this->assertFalse($deletedFromLivePage->IsModifiedOnStage);
|
||||||
|
|
||||||
|
// published page, modified
|
||||||
|
$modifiedOnDraftPage = new SiteTree();
|
||||||
|
$modifiedOnDraftPage->write();
|
||||||
|
$modifiedOnDraftPage->publish('Stage','Live');
|
||||||
|
$modifiedOnDraftPage->Content = 'modified';
|
||||||
|
$modifiedOnDraftPage->write();
|
||||||
|
$this->assertFalse($modifiedOnDraftPage->IsDeletedFromStage);
|
||||||
|
$this->assertFalse($modifiedOnDraftPage->IsAddedToStage);
|
||||||
|
$this->assertTrue($modifiedOnDraftPage->IsModifiedOnStage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We make these extend page since that's what all page types are expected to do
|
// We make these extend page since that's what all page types are expected to do
|
||||||
|
Loading…
Reference in New Issue
Block a user