From 165f38361b4e6fc6fb2afc10c9dca7af0eda64e3 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Sun, 22 Nov 2009 18:58:17 +1300 Subject: [PATCH] BUGFIX: Updated Hierarchy::liveChildren() to use DataList over buildDataObjectSet. --- model/Hierarchy.php | 55 ++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/model/Hierarchy.php b/model/Hierarchy.php index eb71f50d3..1ddc08bf4 100755 --- a/model/Hierarchy.php +++ b/model/Hierarchy.php @@ -452,9 +452,10 @@ class Hierarchy extends DataExtension { // Next, go through the live children. Only some of these will be listed $liveChildren = $this->owner->liveChildren(true, true); if($liveChildren) { - foreach($liveChildren as $child) { - $stageChildren->push($child); - } + $merged = new DataObjectSet(); + $merged->merge($stageChildren); + $merged->merge($liveChildren); + $stageChildren = $merged; } } @@ -543,43 +544,31 @@ class Hierarchy extends DataExtension { */ public function liveChildren($showAll = false, $onlyDeletedFromStage = false) { if(!$this->owner->hasExtension('Versioned')) throw new Exception('Hierarchy->liveChildren() only works with Versioned extension applied'); - - if($this->owner->db('ShowInMenus')) { - $extraFilter = ($showAll) ? '' : " AND \"ShowInMenus\"=1"; - } else { - $extraFilter = ''; - } - $join = ""; $baseClass = ClassInfo::baseDataClass($this->owner->class); + $id = $this->owner->ID; + + $children = DataObject::get($baseClass)->filter("\"{$baseClass}\".\"ParentID\" = $id AND \"{$baseClass}\".\"ID\" != $id"); + if(!$showAll) $children = $children->filter('"ShowInMenus" = 1'); - $filter = "\"{$baseClass}\".\"ParentID\" = " . (int)$this->owner->ID - . " AND \"{$baseClass}\".\"ID\" != " . (int)$this->owner->ID; + // Query the live site + $children->dataQuery()->setQueryParam('Versioned.mode', 'stage'); + $children->dataQuery()->setQueryParam('Versioned.stage', 'Live'); if($onlyDeletedFromStage) { - // Note that the lack of double-quotes around $baseClass are the only thing preventing - // it from being rewritten to {$baseClass}_Live. This is brittle and a little clumsy - $join = "LEFT JOIN {$baseClass} ON {$baseClass}.\"ID\" = \"{$baseClass}\".\"ID\""; - $filter .= " AND {$baseClass}.\"ID\" IS NULL"; + // Note that this makes a second query, and could be optimised to be a joi; + $stageChildren = DataObject::get($baseClass) + ->filter("\"{$baseClass}\".\"ParentID\" = $id AND \"{$baseClass}\".\"ID\" != $id"); + $stageChildren->dataQuery()->setQueryParam('Versioned.mode', 'stage'); + $stageChildren->dataQuery()->setQueryParam('Versioned.stage', ''); + + $ids = $stageChildren->column("ID"); + if($ids) { + $children->filter("\"$baseClass\".\"ID\" NOT IN (" . implode(',',$ids) . ")"); + } } - - $oldStage = Versioned::current_stage(); - Versioned::reading_stage('Live'); - // Singleton is necessary and not $this->owner so as not to muck with Translatable's - // behaviour. - $query = singleton($baseClass)->extendedSQL($filter, null, null, $join); - - // Since we didn't include double quotes in the join & filter, we need to add them into the - // SQL now, after Versioned has done is query rewriting - $correctedSQL = str_replace(array("LEFT JOIN {$baseClass}", "{$baseClass}.\"ID\""), - array("LEFT JOIN \"{$baseClass}\"", "\"{$baseClass}\".\"ID\""), $query->sql()); - - $result = $this->owner->buildDataObjectSet(DB::query($correctedSQL)); - - Versioned::reading_stage($oldStage); - - return $result; + return $children; } /**