From 72e1e5b1b2717bccece77c95d8c9bfe7eb2a8d97 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Mon, 22 Aug 2011 17:52:21 +0200 Subject: [PATCH] BUGFIX Overload validateURLSegment() in SubsitesVirtualPage to allow for same URLSegments as linked pages, as long as they only exist in a different subsite (only change the URLSegment if it already exists in the same subsite). (AIR-4) --- code/SubsitesVirtualPage.php | 38 +++++++++++++++++++++++++++++++ tests/SiteTreeSubsitesTest.php | 3 +++ tests/SubsitesVirtualPageTest.php | 38 +++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/code/SubsitesVirtualPage.php b/code/SubsitesVirtualPage.php index 36f6bad..a89fce8 100644 --- a/code/SubsitesVirtualPage.php +++ b/code/SubsitesVirtualPage.php @@ -105,6 +105,44 @@ class SubsitesVirtualPage extends VirtualPage { $this->ExtraMeta = $this->ContentSource()->ExtraMeta ? $this->ContentSource()->ExtraMeta : $this->ExtraMeta; } } + + function validURLSegment() { + $isValid = parent::validURLSegment(); + + // Veto the validation rules if its false. In this case, some logic + // needs to be duplicated from parent to find out the exact reason the validation failed. + if(!$isValid) { + $IDFilter = ($this->ID) ? "AND \"SiteTree\".\"ID\" <> $this->ID" : null; + $parentFilter = null; + + if(self::nested_urls()) { + if($this->ParentID) { + $parentFilter = " AND \"SiteTree\".\"ParentID\" = $this->ParentID"; + } else { + $parentFilter = ' AND "SiteTree"."ParentID" = 0'; + } + } + + Subsite::$disable_subsite_filter = true; + $existingPage = DataObject::get_one( + 'SiteTree', + "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter", + false // disable cache, it doesn't include subsite status in the key + ); + Subsite::$disable_subsite_filter = false; + $existingPageInSubsite = DataObject::get_one( + 'SiteTree', + "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter", + false // disable cache, it doesn't include subsite status in the key + ); + + // If URL has been vetoed because of an existing page, + // be more specific and allow same URLSegments in different subsites + $isValid = !($existingPage && $existingPageInSubsite); + } + + return $isValid; + } } class SubsitesVirtualPage_Controller extends VirtualPage_Controller { diff --git a/tests/SiteTreeSubsitesTest.php b/tests/SiteTreeSubsitesTest.php index 74ffd95..27d4881 100644 --- a/tests/SiteTreeSubsitesTest.php +++ b/tests/SiteTreeSubsitesTest.php @@ -130,6 +130,9 @@ class SiteTreeSubsitesTest extends SapphireTest { ); } + /** + * Similar to {@link SubsitesVirtualPageTest->testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()}. + */ function testTwoPagesWithSameURLOnDifferentSubsites() { // Set up a couple of pages with the same URL on different subsites $s1 = $this->objFromFixture('Subsite','domaintest1'); diff --git a/tests/SubsitesVirtualPageTest.php b/tests/SubsitesVirtualPageTest.php index 29f1e47..1e7bfbb 100644 --- a/tests/SubsitesVirtualPageTest.php +++ b/tests/SubsitesVirtualPageTest.php @@ -206,6 +206,44 @@ class SubsitesVirtualPageTest extends SapphireTest { $onLive = Versioned::get_one_by_stage('SubsitesVirtualPage', 'Live', "\"SiteTree_Live\".\"ID\" = ".$vp2->ID); $this->assertFalse($onLive, 'SVP has been removed from live'); } + + /** + * Similar to {@link SiteTreeSubsitesTest->testTwoPagesWithSameURLOnDifferentSubsites()} + * and {@link SiteTreeSubsitesTest->testPagesInDifferentSubsitesCanShareURLSegment()}. + */ + function testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite() { + Subsite::$write_hostmap = false; + $subsite1 = $this->objFromFixture('Subsite_Template', 'subsite1'); + $subsite2 = $this->objFromFixture('Subsite_Template', 'subsite2'); + Subsite::changeSubsite($subsite1->ID); + + $subsite1Page = $this->objFromFixture('SiteTree', 'subsite1_contactus'); + $subsite1Page->URLSegment = 'contact-us'; + $subsite1Page->write(); + + // saving on subsite1, and linking to subsite1 + $subsite1Vp = new SubsitesVirtualPage(); + $subsite1Vp->CopyContentFromID = $subsite1Page->ID; + $subsite1Vp->SubsiteID = $subsite1->ID; + $subsite1Vp->write(); + $this->assertNotEquals( + $subsite1Vp->URLSegment, + $subsite1Page->URLSegment, + "Doesn't allow explicit URLSegment overrides when already existing in same subsite" + ); + + // saving in subsite2 (which already has a page with URLSegment 'contact-us'), + // but linking to a page in subsite1 + $subsite2Vp = new SubsitesVirtualPage(); + $subsite2Vp->CopyContentFromID = $subsite1Page->ID; + $subsite2Vp->SubsiteID = $subsite2->ID; + $subsite2Vp->write(); + $this->assertEquals( + $subsite2Vp->URLSegment, + $subsite1Page->URLSegment, + "Does allow explicit URLSegment overrides when only existing in a different subsite" + ); + } function fixVersionNumberCache($page) { $pages = func_get_args();