mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
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:
parent
4916b361f1
commit
d0bc9c6d23
@ -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;
|
||||
}
|
||||
|
||||
|
@ -182,6 +182,26 @@ 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':
|
||||
|
Loading…
Reference in New Issue
Block a user