API CHANGE: Added VirtualPage::$non_virtual_fields and VirtualPage::$initially_copied_fields for configuring the behaviour of virtual pages. (merged from r100463)

This commit is contained in:
Sam Minnee 2011-10-07 10:05:18 +02:00 committed by Ingo Schommer
parent 987eedf9ba
commit 6fc01394a6
2 changed files with 107 additions and 22 deletions

View File

@ -13,6 +13,33 @@ class VirtualPage extends Page {
public static $virtualFields; public static $virtualFields;
/**
* @var Array Define fields that are not virtual - the virtual page must define these fields themselves.
* Note that anything in {@link self::$initially_copied_fields} is implicitly included in this list.
*/
public static $non_virtual_fields = array(
"SecurityTypeID",
"OwnerID",
"URLSegment",
"Sort",
"Status",
'ShowInMenus',
// 'Locale'
'ShowInSearch',
'Version',
"Embargo",
"Expiry",
);
/**
* @var Array Define fields that are initially copied to virtual pages but left modifiable after that.
*/
public static $initially_copied_fields = array(
'ShowInMenus',
'ShowInSearch',
'URLSegment',
);
static $has_one = array( static $has_one = array(
"CopyContentFrom" => "SiteTree", "CopyContentFrom" => "SiteTree",
); );
@ -25,26 +52,16 @@ class VirtualPage extends Page {
* Generates the array of fields required for the page type. * Generates the array of fields required for the page type.
*/ */
function getVirtualFields() { function getVirtualFields() {
$nonVirtualFields = array( $nonVirtualFields = array_merge(self::$non_virtual_fields, self::$initially_copied_fields);
"SecurityTypeID", $record = $this->CopyContentFrom();
"OwnerID",
"URLSegment",
"Sort",
"Status",
'ShowInMenus',
// 'Locale'
'ShowInSearch',
'Version',
"Embargo",
"Expiry",
);
$allFields = $this->db(); $allFields = $record->db();
if($hasOne = $this->has_one()) foreach($hasOne as $link) $allFields[$link . 'ID'] = "Int"; if($hasOne = $record->has_one()) foreach($hasOne as $link) $allFields[$link . 'ID'] = "Int";
$virtualFields = array();
foreach($allFields as $field => $type) { foreach($allFields as $field => $type) {
if(!in_array($field, $nonVirtualFields)) $virtualFields[] = $field; if(!in_array($field, $nonVirtualFields)) $virtualFields[] = $field;
} }
return $virtualFields; return $virtualFields;
} }
@ -195,7 +212,7 @@ class VirtualPage extends Page {
// On regular write, this will copy from draft source. This is only executed when the source // On regular write, this will copy from draft source. This is only executed when the source
// page changeds // page changeds
} else { } else {
$performCopyFrom = $this->isChanged('CopyContentFromID') && $this->CopyContentFromID != 0; $performCopyFrom = $this->isChanged('CopyContentFromID', 2) && $this->CopyContentFromID != 0;
} }
// On publish, this will copy from published source // On publish, this will copy from published source
@ -205,7 +222,6 @@ class VirtualPage extends Page {
$source = DataObject::get_one("SiteTree",sprintf('"SiteTree"."ID" = %d', $this->CopyContentFromID)); $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 // Leave the updating of image tracking until after write, in case its a new record
$this->copyFrom($source, false); $this->copyFrom($source, false);
$this->URLSegment = $source->URLSegment;
} }
parent::onBeforeWrite(); parent::onBeforeWrite();
@ -235,10 +251,12 @@ class VirtualPage extends Page {
$this->$virtualField = $source->$virtualField; $this->$virtualField = $source->$virtualField;
} }
// We also want to copy ShowInMenus, but only if we're copying the // We also want to copy certain, but only if we're copying the source page for the first
// source page for the first time. // time. After this point, the user is free to customise these for the virtual page themselves.
if($this->isChanged('CopyContentFromID')) { if($this->isChanged('CopyContentFromID', 2) && $this->CopyContentFromID != 0) {
$this->ShowInMenus = $source->ShowInMenus; foreach(self::$initially_copied_fields as $fieldName) {
$this->$fieldName = $source->$fieldName;
}
} }
if($updateImageTracking) $this->updateImageTracking(); if($updateImageTracking) $this->updateImageTracking();

View File

@ -352,6 +352,73 @@ class VirtualPageTest extends SapphireTest {
$valid = $classCVirtual->validate(); $valid = $classCVirtual->validate();
$this->assertFalse($valid->valid(), "Doesn't allow child linked to virtual page type disallowed by parent"); $this->assertFalse($valid->valid(), "Doesn't allow child linked to virtual page type disallowed by parent");
} }
function testGetVirtualFields() {
$origInitiallyCopiedFields = VirtualPage::$initially_copied_fields;
VirtualPage::$initially_copied_fields[] = 'MyInitiallyCopiedField';
$origNonVirtualField = VirtualPage::$non_virtual_fields;
VirtualPage::$non_virtual_fields[] = 'MyNonVirtualField';
// Needs association with an original, otherwise will just return the "base" virtual fields
$page = new VirtualPageTest_ClassA();
$page->write();
$virtual = new VirtualPage();
$virtual->CopyContentFromID = $page->ID;
$virtual->write();
$this->assertContains('MyVirtualField', $virtual->getVirtualFields());
$this->assertNotContains('MyNonVirtualField', $virtual->getVirtualFields());
$this->assertNotContains('MyInitiallyCopiedField', $virtual->getVirtualFields());
VirtualPage::$initially_copied_fields = $origInitiallyCopiedFields;
VirtualPage::$non_virtual_fields = $origNonVirtualField;
}
function testCopyFrom() {
$origInitiallyCopiedFields = VirtualPage::$initially_copied_fields;
VirtualPage::$initially_copied_fields[] = 'MyInitiallyCopiedField';
$origNonVirtualField = VirtualPage::$non_virtual_fields;
VirtualPage::$non_virtual_fields[] = 'MyNonVirtualField';
$original = new VirtualPageTest_ClassA();
$original->MyInitiallyCopiedField = 'original';
$original->MyVirtualField = 'original';
$original->MyNonVirtualField = 'original';
$original->write();
$virtual = new VirtualPage();
$virtual->CopyContentFromID = $original->ID;
$virtual->write();
$virtual->copyFrom($original);
// Using getField() to avoid side effects from an overloaded __get()
$this->assertEquals(
'original',
$virtual->getField('MyInitiallyCopiedField'),
'Fields listed in $initially_copied_fields are copied on first copyFrom() invocation'
);
$this->assertEquals(
'original',
$virtual->getField('MyVirtualField'),
'Fields not listed in $initially_copied_fields are copied in copyFrom()'
);
$this->assertNull(
$virtual->getField('MyNonVirtualField'),
'Fields listed in $non_virtual_fields are not copied in copyFrom()'
);
$original->MyInitiallyCopiedField = 'changed';
$original->write();
$virtual->copyFrom($original);
$this->assertEquals(
'original',
$virtual->MyInitiallyCopiedField,
'Fields listed in $initially_copied_fields are not copied on subsequent copyFrom() invocations'
);
VirtualPage::$initially_copied_fields = $origInitiallyCopiedFields;
VirtualPage::$non_virtual_fields = $origNonVirtualField;
}
} }
class VirtualPageTest_ClassA extends Page implements TestOnly { class VirtualPageTest_ClassA extends Page implements TestOnly {