<?php declare(strict_types=1);
namespace Swag\EnterpriseSearch\Indexing;
use Elasticsearch\Client;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Elasticsearch\Framework\ElasticsearchHelper;
use Shopware\Elasticsearch\Framework\ElasticsearchRegistry;
use Swag\EnterpriseSearch\Synonym\SynonymProvider;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SynonymUpdateSubscriber implements EventSubscriberInterface
{
private $languageRepository;
private $synonymProvider;
private $helper;
private $client;
private $registry;
/**
* @var array<int, string>
*/
private $languages;
public function __construct(
ElasticsearchRegistry $registry,
ElasticsearchHelper $helper,
EntityRepositoryInterface $languageRepository,
Client $client,
SynonymProvider $synonymProvider
) {
$this->registry = $registry;
$this->helper = $helper;
$this->languageRepository = $languageRepository;
$this->client = $client;
$this->synonymProvider = $synonymProvider;
}
public static function getSubscribedEvents(): array
{
return [
'synonym.written' => 'onSynonymWritten',
];
}
public function onSynonymWritten(): void
{
if (empty($this->languages)) {
$this->languages = $this->getLanguages();
}
$indices = $this->client->indices();
$definitions = $this->registry->getDefinitions();
foreach ($this->languages as $languageId) {
foreach ($definitions as $definition) {
$alias = $this->helper->getIndexName($definition->getEntityDefinition(), $languageId);
$config = $this->getConfigTemplate($languageId);
$indices->close(['index' => $alias]);
$indices->putSettings(['index' => $alias, 'body' => $config]);
$indices->open(['index' => $alias]);
}
}
}
private function getConfigTemplate(string $languageId): array
{
return [
'settings' => [
'analysis' => [
'filter' => [
'synonym' => [
'synonyms' => $this->synonymProvider->getSynonyms($languageId),
],
],
],
],
];
}
private function getLanguages(): array
{
$criteria = new Criteria();
$context = Context::createDefaultContext();
$criteria->addFilter(new NotFilter(NotFilter::CONNECTION_AND, [
new EqualsFilter('salesChannelDomains.id', null),
]));
$criteria->addSorting(new FieldSorting('id'));
return $this->languageRepository->searchIds($criteria, $context)->getIds();
}
}