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');
|
if(!$showAll) $children = $children->where('"ShowInMenus" = 1');
|
||||||
|
|
||||||
// Query the live site
|
// 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');
|
$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;
|
return $children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +181,28 @@ class Versioned extends DataExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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
|
// Return all version instances
|
||||||
case 'all_versions':
|
case 'all_versions':
|
||||||
case 'latest_versions':
|
case 'latest_versions':
|
||||||
|
Loading…
Reference in New Issue
Block a user