diff --git a/code/model/SiteTree.php b/code/model/SiteTree.php index 45eabc12..359f701e 100644 --- a/code/model/SiteTree.php +++ b/code/model/SiteTree.php @@ -1598,7 +1598,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid // No need to check for subclasses or instanceof, as allowedChildren() already // deconstructs any inheritance trees already. $allowed = $parent->allowedChildren(); - $subject = ($this instanceof VirtualPage) ? $this->CopyContentFrom() : $this; + $subject = ($this instanceof VirtualPage && $this->CopyContentFromID) ? $this->CopyContentFrom() : $this; if(!in_array($subject->ClassName, $allowed)) { $result->error( diff --git a/tests/model/VirtualPageTest.php b/tests/model/VirtualPageTest.php index aa6bd301..fe02a115 100644 --- a/tests/model/VirtualPageTest.php +++ b/tests/model/VirtualPageTest.php @@ -7,6 +7,7 @@ class VirtualPageTest extends SapphireTest { 'VirtualPageTest_ClassA', 'VirtualPageTest_ClassB', 'VirtualPageTest_VirtualPageSub', + 'VirtualPageTest_PageWithAllowedChildren' ); protected $illegalExtensions = array( @@ -591,6 +592,46 @@ class VirtualPageTest extends SapphireTest { 'No field copying from previous original after page type changed' ); } + + public function testVirtualPageAsAnAllowedChild() { + $parentPage = new VirtualPageTest_PageWithAllowedChildren(); + $parentPage->write(); + + $childPage = new VirtualPageTest_ClassA(); + $childPage->ParentID = $parentPage->ID; + $childPage->write(); + + // Check we're allowed to create a VirtualPage without linking it to a page yet + $childVirtualPage = new VirtualPage(); + $childVirtualPage->ParentID = $parentPage->ID; + try { + $childVirtualPage->write(); + } catch(ValidationException $e) { + $this->fail('Failed to write VirtualPage when it is an allowed child'); + } + + // Check that we can link a VirtualPage to a page type that's an allowed child + $childVirtualPage->CopyContentFromID = $childPage->ID; + try { + $childVirtualPage->write(); + } catch(ValidationException $e) { + $this->fail('Failed to write VirtualPage when it is linked to an allowed child'); + } + + // Check that we CAN'T link a VirtualPage to a page that is NOT an allowed child + $disallowedChild = new VirtualPageTest_ClassB(); + $disallowedChild->write(); + $childVirtualPage->CopyContentFromID = $disallowedChild->ID; + $isDetected = false; + try { + $childVirtualPage->write(); + } catch(ValidationException $e) { + $this->assertContains('not allowed as child of this parent page', $e->getMessage()); + $isDetected = true; + } + + if(!$isDetected) $this->fail("Shouldn't be allowed to write a VirtualPage that links to a disallowed child"); + } } class VirtualPageTest_ClassA extends Page implements TestOnly { @@ -632,3 +673,10 @@ class VirtualPageTest_PageExtension extends DataExtension implements TestOnly { ); } + +class VirtualPageTest_PageWithAllowedChildren extends Page implements TestOnly { + private static $allowed_children = array( + 'VirtualPageTest_ClassA', + 'VirtualPage' + ); +}