From ebac1bf06e82e1651f166f63b28b6b1e73a77b00 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Mon, 13 May 2013 18:03:20 +1200 Subject: [PATCH] BUG Fixing Filesystem::sync breaking subsite pages with same URLSegments Filesystem::sync() tries to run through all pages, without caring which subsite the page came from. The problem with this is code in SiteTree::validURLSegment() will return invalid information, as it will check if the page exists, thinking it does, return false, then the page will get a new URLSegment written, e.g. "home-2". Instead of disabling the subsite filter in Filesystem::sync(), this fix will just loop through each subsite and sync each subsite's pages individually before doing the main site. --- filesystem/Filesystem.php | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/filesystem/Filesystem.php b/filesystem/Filesystem.php index 9930f0a38..5fd8f1db9 100644 --- a/filesystem/Filesystem.php +++ b/filesystem/Filesystem.php @@ -180,14 +180,32 @@ class Filesystem extends Object { // Update the image tracking of all pages if($syncLinkTracking) { if(class_exists('SiteTree')) { - if(class_exists('Subsite')) $origDisableSubsiteFilter = Subsite::$disable_subsite_filter; - if(class_exists('Subsite')) Subsite::$disable_subsite_filter = true; - foreach(DataObject::get("SiteTree") as $page) { + + // if subsites exist, go through each subsite and sync each subsite's pages. + // disabling the filter doesn't work reliably, because writing pages that share + // the same URLSegment between subsites will break, e.g. "home" between two + // sites will modify one of them to "home-2", thinking it's a duplicate. The + // check before a write is done in SiteTree::validURLSegment() + if(class_exists('Subsite')) { + // loop through each subsite ID, changing the subsite, then query it's pages + foreach(Subsite::get()->getIDList() as $id) { + Subsite::changeSubsite($id); + foreach(SiteTree::get() as $page) { + // syncLinkTracking is called by SiteTree::onBeforeWrite(). + // Call it without affecting the page version, as this is an internal change. + $page->writeWithoutVersion(); + } + } + + // change back to the main site so the foreach below works + Subsite::changeSubsite(0); + } + + foreach(SiteTree::get() as $page) { // syncLinkTracking is called by SiteTree::onBeforeWrite(). // Call it without affecting the page version, as this is an internal change. $page->writeWithoutVersion(); } - if(class_exists('Subsite')) Subsite::disable_subsite_filter($origDisableSubsiteFilter); } }