search_api_meilisearch-1.0.x-dev/modules/search_api_meilisearch_autocomplete/src/MeilisearchAutocompleteService.php
modules/search_api_meilisearch_autocomplete/src/MeilisearchAutocompleteService.php
<?php
namespace Drupal\search_api_meilisearch_autocomplete;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\Utility\Error;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Query\QueryInterface;
use Drupal\search_api_autocomplete\SearchInterface;
use Drupal\search_api_autocomplete\Suggestion\SuggestionFactory;
use Drupal\search_api_meilisearch\Api\MeilisearchApiServiceInterface;
use Psr\Log\LoggerInterface;
/**
* Provides autocomplete functionality for meili searches.
*/
class MeilisearchAutocompleteService implements MeilisearchAutocompleteServiceInterface {
/**
* A logger instance.
*
* @var \Psr\Log\LoggerInterface
*/
protected LoggerInterface $logger;
/**
* Meilisearch service for making API calls.
*
* @var \Drupal\search_api_meilisearch\Api\MeilisearchApiServiceInterface
*/
protected MeilisearchApiServiceInterface $meiliService;
/**
* Constructs Meilisearch autocomplete service.
*
* @param \Psr\Log\LoggerInterface $logger
* A LoggerInterface instance.
* @param \Drupal\search_api_meilisearch\Api\MeilisearchApiServiceInterface $meiliService
* A MeiliSearchApiService instance.
*/
public function __construct(LoggerInterface $logger, MeilisearchApiServiceInterface $meiliService) {
$this->logger = $logger;
$this->meiliService = $meiliService;
}
/**
* {@inheritdoc}
*/
public function getSuggestions(QueryInterface $query, SearchInterface $search, string $incompleteKey, string $userInput): array {
$suggestions = [];
$factory = new SuggestionFactory($userInput);
$index = $query->getIndex();
try {
$backend = $index->getServerInstance()->getBackend();
$this->meiliService->setUrl($backend->getConfiguration()['meilisearch_host_address'] . ':' . $backend->getConfiguration()['meilisearch_host_port']);
$this->meiliService->setMasterKey($backend->getConfiguration()['meilisearch_master_key']);
$meiliOptions = [
'limit' => $query->getOption('limit') ?? 10,
];
$data = $this->meiliService->search($index->id(), $userInput, $meiliOptions);
$data = $data->getHits();
$suggestions = $this->getAutocompleteSuggesterSuggestions($data, $index, $factory);
}
catch (\Exception $e) {
$this->logger->log(RfcLogLevel::ERROR, $e->getMessage(), Error::decodeException($e));
}
return $suggestions;
}
/**
* Get the word suggestions from the autocomplete query result.
*
* @param array $data
* An autocomplete query result.
* @param \Drupal\search_api\IndexInterface $index
* The current index.
* @param \Drupal\search_api_autocomplete\Suggestion\SuggestionFactory $factory
* The suggestion factory.
*
* @return array
* An array of suggestions.
*/
protected function getAutocompleteSuggesterSuggestions(array $data, IndexInterface $index, SuggestionFactory $factory): array {
$entities = [];
$suggestions = [];
foreach ($data as $row) {
if (!isset($row['search_api_id'])) {
continue;
}
$entities[] = $row['search_api_id'];
}
$items = $index->loadItemsMultiple($entities);
foreach ($items as $item) {
$suggestion = $factory->createFromSuggestedKeys($item->getString());
$suggestions[] = $suggestion;
}
return $suggestions;
}
}
