Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

FIX Hierarchy#liveChildren couldnt handle lots of pages

Hierarchy#liveChildren was generating a list of all IDs of all pages
on staging. When a site had lots of pages, this basically killed the
tree.

Fix by adding new versioned mode, stage_unique, which uses a
subselect to only return items from a stage that are in no
other stage.
  • Loading branch information...
commit d0bc9c6d233a0a64aab7569ce0e42b70bc9a36ac 1 parent 4916b36
@hafriedlander hafriedlander authored
Showing with 24 additions and 17 deletions.
  1. +2 −15 model/Hierarchy.php
  2. +22 −2 model/Versioned.php
View
17 model/Hierarchy.php
@@ -575,22 +575,9 @@ public function liveChildren($showAll = false, $onlyDeletedFromStage = false) {
if(!$showAll) $children = $children->where('"ShowInMenus" = 1');
// Query the live site
- $children->dataQuery()->setQueryParam('Versioned.mode', 'stage');
+ $children->dataQuery()->setQueryParam('Versioned.mode', $onlyDeletedFromStage ? 'stage_unique' : 'stage');
$children->dataQuery()->setQueryParam('Versioned.stage', 'Live');
-
- if($onlyDeletedFromStage) {
- // Note that this makes a second query, and could be optimised to be a join
- $stageChildren = DataObject::get($baseClass)
- ->where("\"{$baseClass}\".\"ID\" != $id");
- $stageChildren->dataQuery()->setQueryParam('Versioned.mode', 'stage');
- $stageChildren->dataQuery()->setQueryParam('Versioned.stage', '');
-
- $ids = $stageChildren->column("ID");
- if($ids) {
- $children = $children->where("\"$baseClass\".\"ID\" NOT IN (" . implode(',',$ids) . ")");
- }
- }
-
+
return $children;
}
View
24 model/Versioned.php
@@ -181,8 +181,28 @@ function augmentSQL(SQLQuery &$query, DataQuery &$dataQuery = null) {
}
}
break;
-
-
+
+ // Reading a specific stage, but only return items that aren't in any other stage
+ case 'stage_unique':
+ $stage = $dataQuery->getQueryParam('Versioned.stage');
+
+ // Recurse to do the default stage behavior (must be first, we rely on stage renaming happening before below)
+ $dataQuery->setQueryParam('Versioned.mode', 'stage');
+ $this->augmentSQL($query, $dataQuery);
+
+ // Now exclude any ID from any other stage. Note that we double rename to avoid the regular stage rename
+ // renaming all subquery references to be Versioned.stage
+ foreach($this->stages as $excluding) {
+ if ($excluding == $stage) continue;
+
+ $tempName = 'ExclusionarySource_'.$excluding;
+ $excludingTable = $baseTable . ($excluding && $excluding != $this->defaultStage ? "_$excluding" : '');
+
+ $query->addWhere('"'.$baseTable.'"."ID" NOT IN (SELECT ID FROM "'.$tempName.'")');
+ $query->renameTable($tempName, $excludingTable);
+ }
+ break;
+
// Return all version instances
case 'all_versions':
case 'latest_versions':
Please sign in to comment.
Something went wrong with that request. Please try again.