mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
BUGFIX: Update virtual pages semantics to grab content from the published version of the source page when you publish the virtual page, and to not allow publication before their source page is published. (from r92209) (from r96748)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@102377 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
7c14bd233a
commit
b8246bb433
@ -58,6 +58,24 @@ class VirtualPage extends Page {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We can only publish the page if there is a published source page
|
||||
*/
|
||||
public function canPublish($member = null) {
|
||||
// No source
|
||||
if(!$this->CopyContentFrom()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unpublished source
|
||||
if(!Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->CopyContentFromID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Default behaviour
|
||||
return parent::canPublish($member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the CMS fields from the fields from the original page.
|
||||
*/
|
||||
@ -106,19 +124,25 @@ class VirtualPage extends Page {
|
||||
* We have to change it to copy all the content from the original page first.
|
||||
*/
|
||||
function onBeforeWrite() {
|
||||
// Don't do this stuff when we're publishing
|
||||
if(!$this->extension_instances['Versioned']->migratingVersion) {
|
||||
if(
|
||||
$this->isChanged('CopyContentFromID')
|
||||
&& $this->CopyContentFromID != 0
|
||||
&& $this instanceof VirtualPage
|
||||
) {
|
||||
$source = DataObject::get_one("SiteTree",sprintf('"SiteTree"."ID" = %d', $this->CopyContentFromID));
|
||||
if($source) {
|
||||
$this->copyFrom($source, false);
|
||||
$this->URLSegment = $source->URLSegment . '-' . $this->ID;
|
||||
}
|
||||
}
|
||||
// On regular write, this will copy from published source. This happens on every publish
|
||||
if($this->extension_instances['Versioned']->migratingVersion
|
||||
&& Versioned::current_stage() == 'Live') {
|
||||
$performCopyFrom = true;
|
||||
|
||||
// On regular write, this will copy from draft source. This is only executed when the source
|
||||
// page changeds
|
||||
} else {
|
||||
$performCopyFrom = $this->isChanged('CopyContentFromID') && $this->CopyContentFromID != 0;
|
||||
}
|
||||
|
||||
// On publish, this will copy from published source
|
||||
if($performCopyFrom && $this instanceof VirtualPage) {
|
||||
// This flush is needed because the get_one cache doesn't respect site version :-(
|
||||
singleton('SiteTree')->flushCache();
|
||||
$source = DataObject::get_one("SiteTree",sprintf('"SiteTree"."ID" = %d', $this->CopyContentFromID));
|
||||
// Leave the updating of image tracking until after write, in case its a new record
|
||||
$this->copyFrom($source, false);
|
||||
$this->URLSegment = $source->URLSegment . '-' . $this->ID;
|
||||
}
|
||||
|
||||
parent::onBeforeWrite();
|
||||
|
@ -75,4 +75,55 @@ class VirtualPageTest extends SapphireTest {
|
||||
$this->assertEquals("My Other Page Nav", $vp->MenuTitle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual pages are always supposed to chose the same content as the published source page.
|
||||
* This means that when you publish them, they should show the published content of the source
|
||||
* page, not the draft content at the time when you clicked 'publish' in the CMS.
|
||||
*/
|
||||
function testPublishingAVirtualPageCopiedPublishedContentNotDraftContent() {
|
||||
$p = new Page();
|
||||
$p->Content = "published content";
|
||||
$p->write();
|
||||
$p->doPublish();
|
||||
|
||||
// Don't publish this change - published page will still say 'published content'
|
||||
$p->Content = "draft content";
|
||||
$p->write();
|
||||
|
||||
$vp = new VirtualPage();
|
||||
$vp->CopyContentFromID = $p->ID;
|
||||
$vp->write();
|
||||
|
||||
$vp->doPublish();
|
||||
|
||||
// The draft content of the virtual page should say 'draft content'
|
||||
$this->assertEquals('draft content',
|
||||
DB::query('SELECT "Content" from "SiteTree" WHERE ID = ' . $vp->ID)->value());
|
||||
|
||||
// The published content of the virtual page should say 'published content'
|
||||
$this->assertEquals('published content',
|
||||
DB::query('SELECT "Content" from "SiteTree_Live" WHERE ID = ' . $vp->ID)->value());
|
||||
}
|
||||
|
||||
function testCantPublishVirtualPagesBeforeTheirSource() {
|
||||
// An unpublished source page
|
||||
$p = new Page();
|
||||
$p->Content = "test content";
|
||||
$p->write();
|
||||
|
||||
// With no source page, we can't publish
|
||||
$vp = new VirtualPage();
|
||||
$vp->write();
|
||||
$this->assertFalse($vp->canPublish());
|
||||
|
||||
// When the source page isn't published, we can't publish
|
||||
$vp->CopyContentFromID = $p->ID;
|
||||
$vp->write();
|
||||
$this->assertFalse($vp->canPublish());
|
||||
|
||||
// Once the source page gets published, then we can publish
|
||||
$p->doPublish();
|
||||
$this->assertTrue($vp->canPublish());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user