diff --git a/src/Pages/SubsitesVirtualPage.php b/src/Pages/SubsitesVirtualPage.php index 56abb60..fcd39b3 100644 --- a/src/Pages/SubsitesVirtualPage.php +++ b/src/Pages/SubsitesVirtualPage.php @@ -8,7 +8,6 @@ use SilverStripe\CMS\Model\VirtualPage; use SilverStripe\Control\Controller; use SilverStripe\Core\Config\Config; use SilverStripe\Forms\DropdownField; -use SilverStripe\Forms\LabelField; use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\TextareaField; use SilverStripe\Forms\TextField; @@ -226,30 +225,20 @@ class SubsitesVirtualPage extends VirtualPage // 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; + $filters = [ + 'URLSegment' => $this->URLSegment, + 'ID:not' => $this->ID, + ]; if (Config::inst()->get(SiteTree::class, 'nested_urls')) { - if ($this->ParentID) { - $parentFilter = " AND \"SiteTree\".\"ParentID\" = $this->ParentID"; - } else { - $parentFilter = ' AND "SiteTree"."ParentID" = 0'; - } + $filters['ParentID'] = $this->ParentID ?: 0; } $origDisableSubsiteFilter = Subsite::$disable_subsite_filter; - Subsite::$disable_subsite_filter = true; - $existingPage = DataObject::get_one( - SiteTree::class, - "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter", - false // disable cache, it doesn't include subsite status in the key - ); - Subsite::$disable_subsite_filter = $origDisableSubsiteFilter; - $existingPageInSubsite = DataObject::get_one( - SiteTree::class, - "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter", - false // disable cache, it doesn't include subsite status in the key - ); + Subsite::disable_subsite_filter(); + $existingPage = SiteTree::get()->filter($filters)->first(); + Subsite::disable_subsite_filter($origDisableSubsiteFilter); + $existingPageInSubsite = SiteTree::get()->filter($filters)->first(); // If URL has been vetoed because of an existing page, // be more specific and allow same URLSegments in different subsites diff --git a/tests/php/SubsitesVirtualPageTest.php b/tests/php/SubsitesVirtualPageTest.php index 99e9646..527927f 100644 --- a/tests/php/SubsitesVirtualPageTest.php +++ b/tests/php/SubsitesVirtualPageTest.php @@ -311,4 +311,41 @@ class SubsitesVirtualPageTest extends BaseSubsiteTest Versioned::prepopulate_versionnumber_cache(SiteTree::class, 'Live', [$p->ID]); } } + + public function testValidURLSegmentWithUniquePageAndNestedURLs() + { + SiteTree::config()->set('nested_urls', true); + + $newPage = new SubsitesVirtualPage(); + $newPage->Title = 'My new page'; + $newPage->URLSegment = 'my-new-page'; + + $this->assertTrue($newPage->validURLSegment()); + } + + public function testValidURLSegmentWithExistingPageInSubsite() + { + $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); + Subsite::changeSubsite($subsite1->ID); + + SiteTree::config()->set('nested_urls', false); + + $similarContactUsPage = new SubsitesVirtualPage(); + $similarContactUsPage->Title = 'Similar to Contact Us in Subsite 1'; + $similarContactUsPage->URLSegment = 'contact-us'; + + $this->assertFalse($similarContactUsPage->validURLSegment()); + } + + public function testValidURLSegmentWithExistingPageInAnotherSubsite() + { + $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); + Subsite::changeSubsite($subsite1->ID); + + $similarStaffPage = new SubsitesVirtualPage(); + $similarStaffPage->Title = 'Similar to Staff page in main site'; + $similarStaffPage->URLSegment = 'staff'; + + $this->assertFalse($similarStaffPage->validURLSegment()); + } }