Fixed Adding additional relations for search forums requires ugly hack

Kirby

Well-known member
Affected version
2.2.8 PL 1
Under some conditions, we need to add further relations when loading threads for a search forum (to avoid n additional queries).

This could be accomplished by passing $extraWith to \XF\Entity\SearchForumUserCache::getThreadsByPage(), but unfortunately this method is called rather in the middle of \XF\Pub\Controller\SearchForum::actionView() with no obviois option to set this parameter.

PHP:
$threads = $userCache->getThreadsByPage($page, $perPage);

So short of completely overwriting the action method (or using some rather ugly hack like setting a pseudo-global to change the bevaviour of \XF\Entity\SearchForumUserCache::getThreadsByPage(), calling parent and resetting the pseudo-global aferwards) I don't see a sane way to achive this.

Could this call be moved to its own method (similar to \XF:\Pub\Controller\Forum::applyForumFilters(), also passing $searchForum as a param) within the controller? This would allow to easily modify the behaviour.
 
Thank you for reporting this issue, it has now been resolved. We are aiming to include any changes that have been made in a future XF release (2.2.9).

Change log:
Make it easier to load additional relations with the search forum user cache
There may be a delay before changes are rolled out to the XenForo Community.
 
Diff:
diff --git a/src/XF/Pub/Controller/SearchForum.php b/src/XF/Pub/Controller/SearchForum.php
index e9795faddf..8b05b847d9 100644
--- a/src/XF/Pub/Controller/SearchForum.php
+++ b/src/XF/Pub/Controller/SearchForum.php
@@ -56,7 +56,7 @@ public function actionView(ParameterBag $params)
             $searchForum
         );
 
-        $threads = $userCache->getThreadsByPage($page, $perPage);
+        $threads = $userCache->getThreadsByPage($page, $perPage, $this->getUserCacheExtraWith());
 
         $canInlineMod = false;
         foreach ($threads AS $thread)
@@ -108,6 +108,14 @@ protected function getSearchForumViewExtraWith()
         return ['Cache', "UserCaches|{$visitor->user_id}"];
     }
 
+    /**
+     * @return string[]
+     */
+    protected function getUserCacheExtraWith(): array
+    {
+        return [];
+    }
+
     /**
      * @return \XF\Mvc\Reply\AbstractReply
      */
 
I didn't work on this. I just noticed something missing from your OP. Will passing the search forum entity here still be useful?
 
I didn't work on this. I just noticed something missing from your OP. Will passing the search forum entity here still be useful?
Yes, definitly. If it is not passed it would most likely require a bit more code than necessary as we would only need additional joins depending on the specific search forum that is going to be displayed.

The new method getUserCacheExtraWith() does not have direct access to this information - to get it I would probably have to duplicate some code from actionView() which seems unnecessary overhead if it could just be passed :)

Ideally the patch could be smth. like

Diff:
diff --git a/src/XF/Pub/Controller/SearchForum.php b/src/XF/Pub/Controller/SearchForum.php
index e9795faddf..8b05b847d9 100644
--- a/src/XF/Pub/Controller/SearchForum.php
+++ b/src/XF/Pub/Controller/SearchForum.php
@@ -56,7 +56,7 @@ public function actionView(ParameterBag $params)
             $searchForum
         );
 
-        $threads = $userCache->getThreadsByPage($page, $perPage);
+        $threads = $userCache->getThreadsByPage($page, $perPage, $this->getUserCacheExtraWith($searchForum));
 
         $canInlineMod = false;
         foreach ($threads AS $thread)
@@ -108,6 +108,14 @@ protected function getSearchForumViewExtraWith()
         return ['Cache', "UserCaches|{$visitor->user_id}"];
     }
 
+    /**
+     * @return string[]
+     */
+    protected function getUserCacheExtraWith(\XF\Entity\SearchForum $searchForum): array
+    {
+        return [];
+    }
+
     /**
      * @return \XF\Mvc\Reply\AbstractReply
      */

This way the SearchForum entity could be accessed directly.
 
Last edited:
Top Bottom