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.
This commit is contained in:
Hamish Friedlander 2012-08-21 15:52:12 +12:00
parent 4916b361f1
commit d0bc9c6d23
2 changed files with 24 additions and 17 deletions

View File

@ -575,22 +575,9 @@ class Hierarchy extends DataExtension {
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 File

@ -181,8 +181,28 @@ class Versioned extends DataExtension {
}
}
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':