BUG Fix copy to subsite breaking on sub-pages

Fixes #192

Signed-off-by: Damian Mooyman <damian@silverstripe.com>
Signed-off-by: Ingo Schommer <ingo@silverstripe.com>
This commit is contained in:
Damian Mooyman 2016-05-27 16:35:16 +12:00 committed by Ingo Schommer
parent bdecbe9097
commit ff28ac1b1e
2 changed files with 61 additions and 31 deletions

View File

@ -84,13 +84,17 @@ class SiteTreeSubsites extends DataExtension
if ($isDefaultSubsite && $subsitesMap) { if ($isDefaultSubsite && $subsitesMap) {
$fields->addFieldToTab( $fields->addFieldToTab(
'Root.Main', 'Root.Main',
new DropdownField( $copyField = new DropdownField(
"CopyToSubsiteID", "CopyToSubsiteID",
_t('SiteTreeSubsites.CopyToSubsite', "Copy page to subsite"), _t('SiteTreeSubsites.CopyToSubsite', "Copy page to subsite"),
$subsitesMap, $subsitesMap,
'' ''
) )
); );
$copyField->setDescription(_t(
'SiteTreeSubsites.CopyToSubsiteDescription',
"Note that this page will be copied to the top level and should be re-organised if necessary."
));
$fields->addFieldToTab( $fields->addFieldToTab(
'Root.Main', 'Root.Main',
$copyAction = new InlineFormAction( $copyAction = new InlineFormAction(
@ -208,22 +212,21 @@ class SiteTreeSubsites extends DataExtension
/** /**
* Create a duplicate of this page and save it to another subsite * Create a duplicate of this page and save it to another subsite
* @param $subsiteID int|Subsite The Subsite to copy to, or its ID *
* @param int|Subsite $subsiteID The Subsite to copy to, or its ID
* @return SiteTree duplicated page
*/ */
public function duplicateToSubsite($subsiteID = null) public function duplicateToSubsite($subsiteID = null)
{ {
if (is_object($subsiteID)) { if ($subsiteID instanceof Subsite) {
$subsite = $subsiteID; $subsiteID = $subsiteID->ID;
$subsiteID = $subsite->ID;
} else {
$subsite = DataObject::get_by_id('Subsite', $subsiteID);
} }
$oldSubsite=Subsite::currentSubsiteID(); $oldSubsite = Subsite::currentSubsiteID();
if ($subsiteID) { if ($subsiteID) {
Subsite::changeSubsite($subsiteID); Subsite::changeSubsite($subsiteID);
} else { } else {
$subsiteID=$oldSubsite; $subsiteID = $oldSubsite;
} }
$page = $this->owner->duplicate(false); $page = $this->owner->duplicate(false);
@ -232,6 +235,9 @@ class SiteTreeSubsites extends DataExtension
$subsiteID = ($subsiteID ? $subsiteID : $oldSubsite); $subsiteID = ($subsiteID ? $subsiteID : $oldSubsite);
$page->SubsiteID = $subsiteID; $page->SubsiteID = $subsiteID;
// Remove parent ID, since this parent belongs to another subsite
$page->ParentID = 0;
// MasterPageID is here for legacy purposes, to satisfy the subsites_relatedpages module // MasterPageID is here for legacy purposes, to satisfy the subsites_relatedpages module
$page->MasterPageID = $this->owner->ID; $page->MasterPageID = $this->owner->ID;
$page->write(); $page->write();
@ -326,32 +332,32 @@ class SiteTreeSubsites extends DataExtension
$this->owner->CrossSubsiteLinkTracking()->setByIDList($linkedPages); $this->owner->CrossSubsiteLinkTracking()->setByIDList($linkedPages);
} }
/** /**
* Ensure that valid url segments are checked within the correct subsite of the owner object, * Ensure that valid url segments are checked within the correct subsite of the owner object,
* even if the current subsiteID is set to some other subsite. * even if the current subsiteID is set to some other subsite.
* *
* @return null|bool Either true or false, or null to not influence result * @return null|bool Either true or false, or null to not influence result
*/ */
public function augmentValidURLSegment() public function augmentValidURLSegment()
{ {
// If this page is being filtered in the current subsite, then no custom validation query is required. // If this page is being filtered in the current subsite, then no custom validation query is required.
$subsite = Subsite::$force_subsite ?: Subsite::currentSubsiteID(); $subsite = Subsite::$force_subsite ?: Subsite::currentSubsiteID();
if (empty($this->owner->SubsiteID) || $subsite == $this->owner->SubsiteID) { if (empty($this->owner->SubsiteID) || $subsite == $this->owner->SubsiteID) {
return null; return null;
} }
// Backup forced subsite // Backup forced subsite
$prevForceSubsite = Subsite::$force_subsite; $prevForceSubsite = Subsite::$force_subsite;
Subsite::$force_subsite = $this->owner->SubsiteID; Subsite::$force_subsite = $this->owner->SubsiteID;
// Repeat validation in the correct subsite // Repeat validation in the correct subsite
$isValid = $this->owner->validURLSegment(); $isValid = $this->owner->validURLSegment();
// Restore // Restore
Subsite::$force_subsite = $prevForceSubsite; Subsite::$force_subsite = $prevForceSubsite;
return (bool)$isValid; return (bool)$isValid;
} }
/** /**
* Return a piece of text to keep DataObject cache keys appropriately specific * Return a piece of text to keep DataObject cache keys appropriately specific

View File

@ -175,6 +175,30 @@ class SiteTreeSubsitesTest extends BaseSubsiteTest
); );
} }
public function testCopyToSubsite() {
/** @var Subsite $otherSubsite */
$otherSubsite = $this->objFromFixture('Subsite', 'subsite1');
$staffPage = $this->objFromFixture('Page', 'staff'); // nested page
$contactPage = $this->objFromFixture('Page', 'contact'); // top level page
$staffPage2 = $staffPage->duplicateToSubsite($otherSubsite->ID);
$contactPage2 = $contactPage->duplicateToSubsite($otherSubsite->ID);
$this->assertNotEquals($staffPage->ID, $staffPage2->ID);
$this->assertNotEquals($staffPage->SubsiteID, $staffPage2->SubsiteID);
$this->assertNotEquals($contactPage->ID, $contactPage2->ID);
$this->assertNotEquals($contactPage->SubsiteID, $contactPage2->SubsiteID);
$this->assertEmpty($staffPage2->ParentID);
$this->assertEmpty($contactPage2->ParentID);
$this->assertNotEmpty($staffPage->ParentID);
$this->assertEmpty($contactPage->ParentID);
// Staff is shifted to top level and given a unique url segment
$domain = $otherSubsite->domain();
$this->assertEquals('http://'.$domain.'/staff-2/', $staffPage2->AbsoluteLink());
$this->assertEquals('http://'.$domain.'/contact-us-2/', $contactPage2->AbsoluteLink());
}
public function testPageTypesBlacklistInCMSMain() public function testPageTypesBlacklistInCMSMain()
{ {
$editor = $this->objFromFixture('Member', 'editor'); $editor = $this->objFromFixture('Member', 'editor');