diff --git a/CHANGELOG-WIP.md b/CHANGELOG-WIP.md index b5380f2c707..a629bf8cdbf 100644 --- a/CHANGELOG-WIP.md +++ b/CHANGELOG-WIP.md @@ -9,6 +9,7 @@ ### Extensibility - Added `craft\services\Relations::deleteLeftoverRelations()`. ([#13956](https://github.com/craftcms/cms/issues/13956)) +- Added `craft\services\Search::shouldCallSearchElements()`. ([#14293](https://github.com/craftcms/cms/issues/14293)) ### System - Relations for fields that are no longer included in an element’s field layout are now deleted after element save. ([#13956](https://github.com/craftcms/cms/issues/13956)) diff --git a/src/elements/db/ElementQuery.php b/src/elements/db/ElementQuery.php index c12c7502ae4..869c990685f 100644 --- a/src/elements/db/ElementQuery.php +++ b/src/elements/db/ElementQuery.php @@ -2776,9 +2776,11 @@ private function _applySearchParam(): void return; } - if (isset($this->orderBy['score'])) { + $searchService = Craft::$app->getSearch(); + + if (isset($this->orderBy['score']) || $searchService->shouldCallSearchElements($this)) { // Get the scored results up front - $searchResults = Craft::$app->getSearch()->searchElements($this); + $searchResults = $searchService->searchElements($this); if ($this->orderBy['score'] === SORT_ASC) { $searchResults = array_reverse($searchResults, true); @@ -2804,7 +2806,7 @@ private function _applySearchParam(): void $this->subQuery->andWhere(['elements.id' => array_keys($searchResults)]); } else { // Just filter the main query by the search query - $searchQuery = Craft::$app->getSearch()->createDbQuery($this->search, $this); + $searchQuery = $searchService->createDbQuery($this->search, $this); if ($searchQuery === false) { throw new QueryAbortedException(); diff --git a/src/services/Search.php b/src/services/Search.php index 6684ac90028..05237a58725 100644 --- a/src/services/Search.php +++ b/src/services/Search.php @@ -196,6 +196,22 @@ public function indexElementAttributes(ElementInterface $element, ?array $fieldH return true; } + /** + * Returns whether we should search for the resulting elements up front via [[searchElements()]], + * rather than supply a subquery which should be applied to the main element query via [[createDbQuery()]]. + * + * If the element query is being ordered by `score`, [[searchElements()]] will be called regardless of + * what this returns. + * + * @param ElementQuery $elementQuery + * @return bool + * @since 4.8.0 + */ + public function shouldCallSearchElements(ElementQuery $elementQuery): bool + { + return false; + } + /** * Searches for elements that match the given element query. *