diff --git a/src/Internal/Search/Highlighter/Highlighter.php b/src/Internal/Search/Highlighter/Highlighter.php index adb9049a..7567ba62 100644 --- a/src/Internal/Search/Highlighter/Highlighter.php +++ b/src/Internal/Search/Highlighter/Highlighter.php @@ -17,8 +17,12 @@ public function __construct( ) { } - public function highlight(string $text, TokenCollection $queryTokens): HighlightResult - { + public function highlight( + string $text, + TokenCollection $queryTokens, + string $startTag = '', + string $endTag = '', + ): HighlightResult { if ($text === '') { return new HighlightResult($text, []); } @@ -43,9 +47,6 @@ public function highlight(string $text, TokenCollection $queryTokens): Highlight return $a['start'] <=> $b['start']; }); - $startTag = ''; - $endTag = ''; - $pos = 0; $highlightedText = ''; $spans = $this->extractSpansFromMatches($matches); diff --git a/src/Internal/Search/Searcher.php b/src/Internal/Search/Searcher.php index c48c7ee7..cbc463b1 100644 --- a/src/Internal/Search/Searcher.php +++ b/src/Internal/Search/Searcher.php @@ -612,6 +612,9 @@ private function highlight(array &$hit, TokenCollection $tokenCollection): void $this->searchParameters->getAttributesToHighlight() ; + $highlightStartTag = $this->searchParameters->getHighlightStartTag(); + $highlightEndTag = $this->searchParameters->getHighlightEndTag(); + foreach ($searchableAttributes as $attribute) { // Do not include any attribute not required by the result (limited by attributesToRetrieve) if (!isset($formatted[$attribute])) { @@ -621,7 +624,12 @@ private function highlight(array &$hit, TokenCollection $tokenCollection): void if (\is_array($formatted[$attribute])) { foreach ($formatted[$attribute] as $key => $formattedEntry) { $highlightResult = $this->engine->getHighlighter() - ->highlight($formattedEntry, $tokenCollection); + ->highlight( + $formattedEntry, + $tokenCollection, + $highlightStartTag, + $highlightEndTag + ); if (\in_array($attribute, $attributesToHighlight, true)) { $formatted[$attribute][$key] = $highlightResult->getHighlightedText(); @@ -633,7 +641,12 @@ private function highlight(array &$hit, TokenCollection $tokenCollection): void } } else { $highlightResult = $this->engine->getHighlighter() - ->highlight((string) $formatted[$attribute], $tokenCollection); + ->highlight( + (string) $formatted[$attribute], + $tokenCollection, + $highlightStartTag, + $highlightEndTag + ); if (\in_array($attribute, $attributesToHighlight, true)) { $formatted[$attribute] = $highlightResult->getHighlightedText(); diff --git a/src/SearchParameters.php b/src/SearchParameters.php index b59023f2..06a80e90 100644 --- a/src/SearchParameters.php +++ b/src/SearchParameters.php @@ -28,6 +28,10 @@ final class SearchParameters private string $filter = ''; + private string $highlightEndTag = ''; + + private string $highlightStartTag = ''; + private int $hitsPerPage = 20; private int $page = 1; @@ -94,6 +98,8 @@ public function getHash(): string $hash = []; $hash[] = json_encode($this->getAttributesToHighlight()); + $hash[] = json_encode($this->getHighlightStartTag()); + $hash[] = json_encode($this->getHighlightEndTag()); $hash[] = json_encode($this->getAttributesToRetrieve()); $hash[] = json_encode($this->getAttributesToSearchOn()); $hash[] = json_encode($this->getFilter()); @@ -106,6 +112,16 @@ public function getHash(): string return hash('sha256', implode(';', $hash)); } + public function getHighlightEndTag(): string + { + return $this->highlightEndTag; + } + + public function getHighlightStartTag(): string + { + return $this->highlightStartTag; + } + public function getHitsPerPage(): int { return $this->hitsPerPage; @@ -142,12 +158,17 @@ public function showRankingScore(): bool /** * @param array $attributesToHighlight */ - public function withAttributesToHighlight(array $attributesToHighlight): self - { + public function withAttributesToHighlight( + array $attributesToHighlight, + string $highlightStartTag = '', + string $highlightEndTag = '', + ): self { sort($attributesToHighlight); $clone = clone $this; $clone->attributesToHighlight = $attributesToHighlight; + $clone->highlightStartTag = $highlightStartTag; + $clone->highlightEndTag = $highlightEndTag; return $clone; } diff --git a/tests/Functional/SearchTest.php b/tests/Functional/SearchTest.php index 5e9c3600..3bc6f3b5 100644 --- a/tests/Functional/SearchTest.php +++ b/tests/Functional/SearchTest.php @@ -263,6 +263,36 @@ public static function highlightingProvider(): \Generator ], ]; + yield 'Highlight with custom start and end tag' => [ + 'assasin', + ['title', 'overview'], + ['title', 'overview'], + false, + [ + 'hits' => [ + [ + 'id' => 24, + 'title' => 'Kill Bill: Vol. 1', + 'overview' => 'An assassin is shot by her ruthless employer, Bill, and other members of their assassination circle – but she lives to plot her vengeance.', + 'genres' => ['Action', 'Crime'], + '_formatted' => [ + 'id' => 24, + 'title' => 'Kill Bill: Vol. 1', + 'overview' => 'An assassin is shot by her ruthless employer, Bill, and other members of their assassination circle – but she lives to plot her vengeance.', + 'genres' => ['Action', 'Crime'], + ], + ], + ], + 'query' => 'assasin', + 'hitsPerPage' => 20, + 'page' => 1, + 'totalPages' => 1, + 'totalHits' => 1, + ], + '', + '', + ]; + yield 'Highlight without typo' => [ 'assassin', ['title', 'overview'], @@ -1012,12 +1042,20 @@ public function testGeoSearch(): void } /** + * @param array $searchableAttributes * @param array $attributesToHighlight * @param array $expectedResults */ #[DataProvider('highlightingProvider')] - public function testHighlighting(string $query, array $searchableAttributes, array $attributesToHighlight, bool $showMatchesPosition, array $expectedResults): void - { + public function testHighlighting( + string $query, + array $searchableAttributes, + array $attributesToHighlight, + bool $showMatchesPosition, + array $expectedResults, + string $highlightStartTag = '', + string $highlightEndTag = '', + ): void { $configuration = Configuration::create() ->withSearchableAttributes($searchableAttributes) ->withFilterableAttributes(['genres']) @@ -1029,7 +1067,7 @@ public function testHighlighting(string $query, array $searchableAttributes, arr $searchParameters = SearchParameters::create() ->withQuery($query) - ->withAttributesToHighlight($attributesToHighlight) + ->withAttributesToHighlight($attributesToHighlight, $highlightStartTag, $highlightEndTag) ->withShowMatchesPosition($showMatchesPosition) ->withAttributesToRetrieve(['id', 'title', 'overview', 'genres']) ->withSort(['title:asc'])