From 0bff8728b19f7d89cd32f37a1f9134bd7d849a3e Mon Sep 17 00:00:00 2001 From: Maxime Rainville Date: Wed, 14 Nov 2018 18:01:29 +1300 Subject: [PATCH 1/3] MINOR Speed up DependentPages by shifting existence check to table join --- code/Model/SiteTree.php | 70 ++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index 85be8e33..e7347328 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -1727,19 +1727,37 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi /** * Get the back-link tracking objects that link to this page * - * @retun ArrayList|DataObject[] + * @return ArrayList|DataObject[] */ public function BackLinkTracking() { // @todo - Implement PolymorphicManyManyList to replace this $list = ArrayList::create(); - foreach ($this->BackLinks() as $link) { - // Ensure parent record exists - $item = $link->Parent(); - if ($item && $item->isInDB()) { - $list->push($item); - } + + $joinClause = sprintf( + "\"%s\".\"ParentID\"=\"ParentRelationTable\".\"ID\"", + SiteTreeLink::singleton()->baseTable() + ); + + // Get the list of back links classes + $linkClasses = $this->BackLinks()->exclude(['ParentClass' => null])->columnUnique('ParentClass'); + + // Get list of sitreTreelink and join them to the their parent class to make sure we don't get orphan records. + foreach ($linkClasses as $linkClass) { + $links = $this->BackLinks() + ->filter(['ParentClass' => $linkClass]) + ->innerJoin( + DataObject::singleton($linkClass)->baseTable(), + $joinClause, + 'ParentRelationTable' + ) + ->alterDataQuery(function ($query) { + $query->selectField("'Content link'", "DependentLinkType"); + }) + ; + $list->merge($links); } + return $list; } @@ -1761,40 +1779,26 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi // We merge all into a regular SS_List, because DataList doesn't support merge if ($contentLinks = $this->BackLinkTracking()) { - $linkList = new ArrayList(); - foreach ($contentLinks as $item) { - $item->DependentLinkType = 'Content link'; - $linkList->push($item); - } - $items->merge($linkList); + $items->merge($contentLinks); } // Virtual pages if ($includeVirtuals) { - $virtuals = $this->VirtualPages(); - if ($virtuals) { - $virtualList = new ArrayList(); - foreach ($virtuals as $item) { - $item->DependentLinkType = 'Virtual page'; - $virtualList->push($item); - } - $items->merge($virtualList); - } + $virtuals = $this->VirtualPages() + ->alterDataQuery(function ($query) { + $query->selectField("'Virtual page'", "DependentLinkType"); + }); + $items->merge($virtuals); } // Redirector pages $redirectors = RedirectorPage::get()->where(array( - '"RedirectorPage"."RedirectionType"' => 'Internal', - '"RedirectorPage"."LinkToID"' => $this->ID - )); - if ($redirectors) { - $redirectorList = new ArrayList(); - foreach ($redirectors as $item) { - $item->DependentLinkType = 'Redirector page'; - $redirectorList->push($item); - } - $items->merge($redirectorList); - } + '"RedirectorPage"."RedirectionType"' => 'Internal', + '"RedirectorPage"."LinkToID"' => $this->ID + ))->alterDataQuery(function ($query) { + $query->selectField("'Redirector page'", "DependentLinkType"); + }); + $items->merge($redirectors); if (class_exists('Subsite')) { Subsite::disable_subsite_filter($origDisableSubsiteFilter); From b138eb06ff03308021ddffd75626dea73281b489 Mon Sep 17 00:00:00 2001 From: Maxime Rainville Date: Thu, 15 Nov 2018 15:57:17 +1300 Subject: [PATCH 2/3] Revert BackLinkTracking to return Parent Object of the SiteTreeLink rather than SiteTreeLink itself --- code/Model/SiteTree.php | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index e7347328..eb5dfd66 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -1734,27 +1734,32 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi // @todo - Implement PolymorphicManyManyList to replace this $list = ArrayList::create(); - $joinClause = sprintf( - "\"%s\".\"ParentID\"=\"ParentRelationTable\".\"ID\"", - SiteTreeLink::singleton()->baseTable() - ); + $siteTreelinkTable = SiteTreeLink::singleton()->baseTable(); // Get the list of back links classes - $linkClasses = $this->BackLinks()->exclude(['ParentClass' => null])->columnUnique('ParentClass'); + $parentClasses = $this->BackLinks()->exclude(['ParentClass' => null])->columnUnique('ParentClass'); // Get list of sitreTreelink and join them to the their parent class to make sure we don't get orphan records. - foreach ($linkClasses as $linkClass) { - $links = $this->BackLinks() - ->filter(['ParentClass' => $linkClass]) + foreach ($parentClasses as $parentClass) { + $joinClause = sprintf( + "\"%s\".\"ParentID\"=\"%s\".\"ID\"", + $siteTreelinkTable, + $linkTable, + DataObject::singleton($parentClass)->baseTable() + ); + + $links = DataObject::get($parentClass) ->innerJoin( - DataObject::singleton($linkClass)->baseTable(), - $joinClause, - 'ParentRelationTable' + $siteTreelinkTable, + $joinClause ) + ->where([ + "\"$siteTreelinkTable\".\"LinkedID\"" => $this->ID, + "\"$siteTreelinkTable\".\"ParentClass\"" => $parentClass, + ]) ->alterDataQuery(function ($query) { $query->selectField("'Content link'", "DependentLinkType"); - }) - ; + }); $list->merge($links); } From 03869b1627ed934e51f8c2291b2f41f943e53a26 Mon Sep 17 00:00:00 2001 From: Robbie Averill Date: Thu, 15 Nov 2018 13:30:33 +0200 Subject: [PATCH 3/3] Remove undefined variable, should use the baseTable() from the $parentClass --- code/Model/SiteTree.php | 1 - 1 file changed, 1 deletion(-) diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index eb5dfd66..3280a26d 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -1744,7 +1744,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi $joinClause = sprintf( "\"%s\".\"ParentID\"=\"%s\".\"ID\"", $siteTreelinkTable, - $linkTable, DataObject::singleton($parentClass)->baseTable() );