diff --git a/.editorconfig b/.editorconfig index 9d24928..0741b16 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,7 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true -[{*.yml}] +[*.yml] indent_size = 2 indent_style = space diff --git a/_config/adaptors.yml b/_config/adaptors.yml new file mode 100644 index 0000000..e9b43ba --- /dev/null +++ b/_config/adaptors.yml @@ -0,0 +1,12 @@ +--- +Name: discoverer-adaptors +--- +SilverStripe\Core\Injector\Injector: + SilverStripe\Discoverer\Service\Interfaces\ProcessAnalyticsAdaptor: + class: SilverStripe\Discoverer\Service\Adaptors\ProcessAnalyticsAdaptor + SilverStripe\Discoverer\Service\Interfaces\QuerySuggestionAdaptor: + class: SilverStripe\Discoverer\Service\Adaptors\QuerySuggestionAdaptor + SilverStripe\Discoverer\Service\Interfaces\SearchAdaptor: + class: SilverStripe\Discoverer\Service\Adaptors\SearchAdaptor + SilverStripe\Discoverer\Service\Interfaces\SpellingSuggestionAdaptor: + class: SilverStripe\Discoverer\Service\Adaptors\SpellingSuggestionAdaptor diff --git a/_config/analytics.yml b/_config/analytics.yml index 39544cb..85583b7 100644 --- a/_config/analytics.yml +++ b/_config/analytics.yml @@ -1,5 +1,5 @@ --- -Name: search-analytics +Name: discoverer-analytics After: - requestprocessors Only: diff --git a/src/Query/Suggestion.php b/src/Query/Suggestion.php index 55f2254..e9fa63a 100644 --- a/src/Query/Suggestion.php +++ b/src/Query/Suggestion.php @@ -9,8 +9,12 @@ class Suggestion use Injectable; - public function __construct(private string $queryString, private ?int $limit = null, private array $fields = []) - { + public function __construct( + private string $queryString, + private ?int $limit = null, + private array $fields = [], + private bool $formatted = false + ) { } public function getQueryString(): string @@ -54,4 +58,16 @@ public function addField(string $fieldName): self return $this; } + public function isFormatted(): bool + { + return $this->formatted; + } + + public function setFormatted(bool $formatted): Suggestion + { + $this->formatted = $formatted; + + return $this; + } + } diff --git a/src/Service/Adaptors/ProcessAnalyticsAdaptor.php b/src/Service/Adaptors/ProcessAnalyticsAdaptor.php new file mode 100644 index 0000000..43c44e0 --- /dev/null +++ b/src/Service/Adaptors/ProcessAnalyticsAdaptor.php @@ -0,0 +1,17 @@ +suggestions[] = $suggestions; + $this->suggestions[] = $suggestion; return $this; } @@ -83,35 +85,23 @@ public function getSuggestions(): array return $this->suggestions; } - public function getIterator(): Traversable + public function setSuggestions(array $suggestions): self { - if (!$this->suggestions) { - return new ArrayIterator(); + // Specifically using a loop and addSuggestion() to make sure that all items are of type Field + foreach ($suggestions as $suggestion) { + $this->addSuggestion($suggestion); } - return new ArrayIterator($this->convertArrayForTemplate()); + return $this; } - /** - * Silverstripe 5.3 will have native support for looping primitives in templates: - * https://github.com/silverstripe/silverstripe-framework/issues/11196 - * - * We need to support versions of Silverstripe below 5.3 though, so we need this polyfill. It emulates the - * template implementation method from Silverstripe 5.3, so we should be able to remove this later without - * negatively impacting any project's template implementation - */ - private function convertArrayForTemplate(): array + public function getIterator(): Traversable { - $arrayList = []; - - foreach ($this->suggestions as $suggestion) { - $text = DBText::create('suggestion'); - $text->setValue($suggestion); - - $arrayList[] = $text; + if (!$this->suggestions) { + return new ArrayIterator(); } - return $arrayList; + return new ArrayIterator($this->getSuggestions()); } } diff --git a/src/Service/SearchService.php b/src/Service/SearchService.php index 0944d8e..0ce2fa5 100644 --- a/src/Service/SearchService.php +++ b/src/Service/SearchService.php @@ -6,6 +6,10 @@ use SilverStripe\Discoverer\Analytics\AnalyticsData; use SilverStripe\Discoverer\Query\Query; use SilverStripe\Discoverer\Query\Suggestion; +use SilverStripe\Discoverer\Service\Interfaces\ProcessAnalyticsAdaptor; +use SilverStripe\Discoverer\Service\Interfaces\QuerySuggestionAdaptor; +use SilverStripe\Discoverer\Service\Interfaces\SearchAdaptor; +use SilverStripe\Discoverer\Service\Interfaces\SpellingSuggestionAdaptor; use SilverStripe\Discoverer\Service\Results\Results; use SilverStripe\Discoverer\Service\Results\Suggestions; @@ -14,30 +18,59 @@ class SearchService use Injectable; - private ?SearchServiceAdaptor $adaptor = null; + private ?SearchAdaptor $searchAdaptor = null; + + private ?QuerySuggestionAdaptor $querySuggestionAdaptor = null; + + private ?SpellingSuggestionAdaptor $spellingSuggestionAdaptor = null; + + private ?ProcessAnalyticsAdaptor $processAnalyticsAdaptor = null; private static array $dependencies = [ - 'adaptor' => '%$' . SearchServiceAdaptor::class, + 'searchAdaptor' => '%$' . SearchAdaptor::class, + 'querySuggestionAdaptor' => '%$' . QuerySuggestionAdaptor::class, + 'spellingSuggestionAdaptor' => '%$' . SpellingSuggestionAdaptor::class, + 'processAnalyticsAdaptor' => '%$' . ProcessAnalyticsAdaptor::class, ]; - public function setAdaptor(?SearchServiceAdaptor $adaptor): void + public function setSearchAdaptor(?SearchAdaptor $searchAdaptor): void + { + $this->searchAdaptor = $searchAdaptor; + } + + public function setQuerySuggestionAdaptor(?QuerySuggestionAdaptor $querySuggestionAdaptor): void { - $this->adaptor = $adaptor; + $this->querySuggestionAdaptor = $querySuggestionAdaptor; + } + + public function setSpellingSuggestionAdaptor(?SpellingSuggestionAdaptor $spellingSuggestionAdaptor): void + { + $this->spellingSuggestionAdaptor = $spellingSuggestionAdaptor; + } + + public function setProcessAnalyticsAdaptor(?ProcessAnalyticsAdaptor $processAnalyticsAdaptor): void + { + $this->processAnalyticsAdaptor = $processAnalyticsAdaptor; } public function search(Query $query, string $indexName): Results { - return $this->adaptor->search($query, $indexName); + return $this->searchAdaptor->process($query, $indexName); } public function querySuggestion(Suggestion $suggestion, string $indexName): Suggestions { - return $this->adaptor->querySuggestion($suggestion, $indexName); + return $this->querySuggestionAdaptor->process($suggestion, $indexName); + } + + public function spellingSuggestion(Suggestion $suggestion, string $indexName): Suggestions + { + return $this->spellingSuggestionAdaptor->process($suggestion, $indexName); } public function processAnalytics(AnalyticsData $analyticsData): void { - $this->adaptor->processAnalytics($analyticsData); + $this->processAnalyticsAdaptor->process($analyticsData); } } diff --git a/src/Service/SearchServiceAdaptor.php b/src/Service/SearchServiceAdaptor.php deleted file mode 100644 index 2ec28e7..0000000 --- a/src/Service/SearchServiceAdaptor.php +++ /dev/null @@ -1,20 +0,0 @@ - <% loop $Me %> <% if $Up.TargetQueryUrl && $Up.TargetQueryStringField %> -