TickTackk
Well-known member
Currently the
Developers would be able to do something like this:
and
pls accept this pr because it took me more time to explain what the diff will do than actually figuring everything out :'(
XF\Searcher\Thread
only allows to search the threads based on the thread criteria (as it should) but after implementing the following changes to \XF\Searcher\AbstractSearcher
to implement "proxy searcher" feature:
Diff:
diff --git a/upload/src/XF/Searcher/AbstractSearcher.php b/upload/src/XF/Searcher/AbstractSearcher.php
--- a/upload/src/XF/Searcher/AbstractSearcher.php
+++ b/upload/src/XF/Searcher/AbstractSearcher.php
@@ -29,12 +29,37 @@ abstract class AbstractSearcher
protected $order = [];
+ /**
+ * These are in <relation name> and <searcher class> format
+ *
+ * @var array<string, string>
+ */
+ protected $proxySearcherMaps = [];
+
+ /**
+ * These are in in <relation name> and <searcher> format
+ *
+ * @var array<string, AbstractSearcher>
+ */
+ protected $proxySearchers = [];
+
+ /**
+ * @var Finder|null
+ */
+ protected $parentFinder = null;
+
+ /**
+ * @var string|null
+ */
+ protected $parentFinderRelationPath = null;
+
public function __construct(Manager $em, array $criteria = null)
{
$this->em = $em;
$this->structure = $em->getEntityStructure($this->getEntityType());
$this->orderOptions = $this->getDefaultOrderOptions();
+ $this->initProxySearchers();
$this->init();
if ($criteria)
@@ -52,12 +77,29 @@ abstract class AbstractSearcher
*/
abstract protected function getDefaultOrderOptions();
+ protected function initProxySearchers()
+ {
+ foreach ($this->proxySearcherMaps AS $relation => $identifier)
+ {
+ $this->proxySearchers[$relation] = \XF::app()->searcher($identifier, []);
+ }
+ }
+
protected function init()
{
}
public function setCriteria(array $criteria)
{
+ foreach ($this->proxySearcherMaps AS $relation => $null)
+ {
+ if (!empty($criteria[$relation]))
+ {
+ $this->proxySearchers[$relation]->setCriteria($criteria[$relation]);
+ unset($criteria[$relation]);
+ }
+ }
+
$this->rawCriteria = $criteria;
$this->filteredCriteria = $this->filterCriteria($criteria);
}
@@ -181,6 +223,20 @@ abstract class AbstractSearcher
return $this->order;
}
+ /**
+ * @param Finder $parentFinder
+ * @param string $parentFinderRelationPath
+ *
+ * @return $this
+ */
+ public function setParentFinder(Finder $parentFinder, $parentFinderRelationPath) : self
+ {
+ $this->parentFinder = $parentFinder;
+ $this->parentFinderRelationPath = $parentFinderRelationPath;
+
+ return $this;
+ }
+
protected function filterCriteria(array $criteria, $relation = null)
{
if ($relation === null)
@@ -363,6 +419,7 @@ abstract class AbstractSearcher
public function getFinder()
{
$finder = $this->em->getFinder($this->getEntityType());
+ $this->applyParentFinder($finder);
$this->applyDefaultFinderLimits($finder);
$this->applyCriteria($finder, $this->filteredCriteria);
@@ -371,9 +428,41 @@ abstract class AbstractSearcher
$finder->setDefaultOrder($this->order);
}
+ foreach ($this->proxySearchers AS $relation => $proxySearcher)
+ {
+ // getFinder() needs to be called in order to be apply the conditions
+ $proxySearcher->setParentFinder($finder, $relation)->getFinder();
+ }
+
return $finder;
}
+ /**
+ * @return Finder|null
+ */
+ public function getParentFinder()
+ {
+ return $this->parentFinder;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getParentFinderRelationPath()
+ {
+ return $this->parentFinderRelationPath;
+ }
+
+ protected function applyParentFinder(Finder $finder)
+ {
+ $parentFinder = $this->getParentFinder();
+ $relationPath = $this->getParentFinderRelationPath();
+ if ($parentFinder !== null && $relationPath !== null)
+ {
+ $finder->setParentFinder($parentFinder, $relationPath);
+ }
+ }
+
protected function applyDefaultFinderLimits(\XF\Mvc\Entity\Finder $finder)
{
}
Developers would be able to do something like this:
PHP:
$contentSearcher = \XF::app()->searcher('Iam\Running:OutOfIdeas');
$contentSearcher->setCriteria([
'some_column' => 'naaah',
'Starter' => ['secondary_group_ids' => [69]],
'LastReplier' => ['secondary_group_ids' => [420]]
]);
$contentSearcher->getFinder();
XF:User
searcher will automagically apply its condition checks on the finder we get from $contentSearcher
automagically.pls accept this pr because it took me more time to explain what the diff will do than actually figuring everything out :'(
Upvote
2