Created
July 7, 2021 13:58
-
-
Save ostrolucky/fb1adf9aa5307270eb7cc7916eb15bb5 to your computer and use it in GitHub Desktop.
Make FOSElasticsearchbundle working without doctrine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event; | |
use Symfony\Contracts\EventDispatcher\Event; | |
class AddDocumentEvent extends Event | |
{ | |
private string $index; | |
private object $model; | |
public function __construct(string $index, object $model) | |
{ | |
$this->index = $index; | |
$this->model = $model; | |
} | |
public function getIndex(): string | |
{ | |
return $this->index; | |
} | |
public function getModel(): object | |
{ | |
return $this->model; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\EventListener; | |
use Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event\AddDocumentEvent; | |
use Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event\DeleteDocumentEvent; | |
use FOS\ElasticaBundle\Persister\PersisterRegistry; | |
class BulkListener | |
{ | |
private PersisterRegistry $persisterRegistry; | |
/** @var object[][] */ | |
private array $toAdd = []; | |
/** @var int[][] */ | |
private array $toDelete = []; | |
public function __construct(PersisterRegistry $persisterRegistry) | |
{ | |
$this->persisterRegistry = $persisterRegistry; | |
} | |
public function onAddDocument(AddDocumentEvent $event): void | |
{ | |
$this->toAdd[$event->getIndex()][] = $event->getModel(); | |
$this->persist(); | |
} | |
public function onDeleteDocument(DeleteDocumentEvent $event): void | |
{ | |
$this->toDelete[$event->getIndex()][] = $event->getDocumentId(); | |
$this->persist(); | |
} | |
public function onTerminate(): void | |
{ | |
$this->persist(); | |
} | |
private function persist(): void | |
{ | |
foreach ($this->toAdd as $indexName => $model) { | |
$this->persisterRegistry->getPersister($indexName)->insertMany($model); | |
} | |
$this->toAdd = []; | |
foreach ($this->toDelete as $indexName => $ids) { | |
$this->persisterRegistry->getPersister($indexName)->deleteManyByIdentifiers($ids); | |
} | |
$this->toDelete = []; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event; | |
use Symfony\Contracts\EventDispatcher\Event; | |
class DeleteDocumentEvent extends Event | |
{ | |
private string $index; | |
private int $documentId; | |
public function __construct(string $index, int $documentId) | |
{ | |
$this->index = $index; | |
$this->documentId = $documentId; | |
} | |
public function getIndex(): string | |
{ | |
return $this->index; | |
} | |
public function getDocumentId(): int | |
{ | |
return $this->documentId; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch; | |
use Elastica\Result; | |
use FOS\ElasticaBundle\Transformer\AbstractElasticaToModelTransformer; | |
/** | |
* @template T | |
*/ | |
class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer | |
{ | |
/** @var class-string<T> */ | |
private string $objectClass; | |
private Normalizer $denormalizer; | |
/** @phpstan-param class-string<T> $objectClass */ | |
public function __construct(string $objectClass, Normalizer $denormalizer) | |
{ | |
$this->objectClass = $objectClass; | |
$this->denormalizer = $denormalizer; | |
} | |
/** @return T[] */ | |
public function transform(array $elasticaObjects): array | |
{ | |
return $this->denormalizer->denormalize( | |
array_map(fn(Result $result) => $result->getSource(), $elasticaObjects), | |
$this->getObjectClass().'[]' | |
); | |
} | |
public function hybridTransform(array $elasticaObjects) | |
{ | |
return $this->transform($elasticaObjects); | |
} | |
/** @return class-string<T> */ | |
public function getObjectClass(): string | |
{ | |
return $this->objectClass; | |
} | |
public function getIdentifierField(): string | |
{ | |
return 'id'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Elektronik\Bl\DomainBundle\DependencyInjection; | |
use Elektronik\Bl\DomainBundle\Domain\Product\Entity\Product; | |
use FOS\ElasticaBundle\Persister\ObjectSerializerPersister; | |
use FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer; | |
use Symfony\Component\Config\FileLocator; | |
use Symfony\Component\DependencyInjection\ContainerBuilder; | |
use Symfony\Component\DependencyInjection\Definition; | |
use Symfony\Component\DependencyInjection\Extension\Extension; | |
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; | |
use Symfony\Component\DependencyInjection\Reference; | |
class ElektronikBlDomainExtension extends Extension | |
{ | |
/** | |
* @param mixed[] $configs | |
* @param ContainerBuilder $container | |
* @throws \Exception | |
*/ | |
public function load(array $configs, ContainerBuilder $container): void | |
{ | |
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | |
$loader->load('services.xml'); | |
$configuration = $this->getConfiguration($configs, $container); | |
$config = $this->processConfiguration($configuration, $configs); | |
$container->prependExtensionConfig('fos_elastica', [ | |
'clients' => ['default' => ['url' => $config['elasticsearch_dsn']]], | |
'serializer' => null, | |
'indexes' => [ | |
'product' => [ | |
'use_alias' => true, | |
'finder' => null, | |
'serializer' => ['groups' => ['Default']], | |
], | |
], | |
]); | |
$container->register('fos_elastica.object_persister.product', ObjectSerializerPersister::class) | |
->setArgument('$index', new Reference('fos_elastica.index.product')) | |
->setArgument('$transformer', (new Definition(ModelToElasticaAutoTransformer::class))->addMethodCall('setPropertyAccessor', [new Reference('property_accessor')]),) | |
->setArgument('$objectClass', Product::class) | |
->setArgument('$serializer', [new Reference('fos_elastica.index.product.serializer.callback'), 'serialize']) | |
->setArgument('$options', []) | |
->addTag('fos_elastica.persister', ['index' => 'product']); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch; | |
use Elektronik\Bl\DomainBundle\Domain\Product\Mock\ProductMock; | |
use FOS\ElasticaBundle\Provider\PagerfantaPager; | |
use FOS\ElasticaBundle\Provider\PagerInterface; | |
use FOS\ElasticaBundle\Provider\PagerProviderInterface; | |
use Pagerfanta\Adapter\ArrayAdapter; | |
use Pagerfanta\Pagerfanta; | |
class ProductProvider implements PagerProviderInterface | |
{ | |
public function provide(array $options = []): PagerInterface | |
{ | |
return new PagerfantaPager(new Pagerfanta(new ArrayAdapter([ProductMock::getMock()]))); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Elektronik\Bl\DomainBundle\Infrastructure\Repository; | |
use Elastica\Query\Term; | |
use Elektronik\Bl\DomainBundle\Domain\Product\Entity\Product; | |
use Elektronik\Bl\DomainBundle\Domain\Product\ProductRepositoryInterface; | |
use Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\EntityNameEnum; | |
use Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event\AddDocumentEvent; | |
use Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event\DeleteDocumentEvent; | |
use FOS\ElasticaBundle\Finder\FinderInterface; | |
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; | |
class ProductRepository implements ProductRepositoryInterface | |
{ | |
private FinderInterface $finder; | |
private EventDispatcherInterface $dispatcher; | |
public function __construct( | |
FinderInterface $finder, | |
EventDispatcherInterface $dispatcher | |
) { | |
$this->finder = $finder; | |
$this->dispatcher = $dispatcher; | |
} | |
public function save(Product $product): void | |
{ | |
$this->dispatcher->dispatch(new AddDocumentEvent( | |
EntityNameEnum::PRODUCT, | |
$product | |
)); | |
} | |
public function get(int $id): ?Product | |
{ | |
return $this->finder->find((new Term())->setTerm('id', $id), 1)[0] ?? null; | |
} | |
public function remove(int $id): void | |
{ | |
$this->dispatcher->dispatch(new DeleteDocumentEvent( | |
EntityNameEnum::PRODUCT, | |
$id | |
)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<container xmlns="http://symfony.com/schema/dic/services" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://symfony.com/schema/dic/services | |
http://symfony.com/schema/dic/services/services-1.0.xsd"> | |
<services> | |
<defaults autowire="true" autoconfigure="true"/> | |
<prototype | |
namespace="Elektronik\Bl\DomainBundle\" | |
resource="../../*" | |
exclude="../../{DependencyInjection,Resources}" | |
/> | |
<service id="Elektronik\Bl\DomainBundle\Infrastructure\Repository\ProductRepository"> | |
<argument key="$finder" type="service" id="fos_elastica.finder.product" /> | |
</service> | |
<service id="fos_elastica.elastica_to_model_transformer.product" class="Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\ElasticaToModelTransformer"> | |
<argument key="$objectClass" type="string">Elektronik\Bl\DomainBundle\Domain\Product\Entity\Product</argument> | |
</service> | |
<service id="Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\ProductProvider"> | |
<tag name="fos_elastica.pager_provider" index="product" /> | |
</service> | |
<!-- Elasticsearch Storage --> | |
<service id="bl.elasticsearch.listener.bulk" class="Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\EventListener\BulkListener"> | |
<argument type="service" id="fos_elastica.persister_registry"/> | |
<tag | |
name="kernel.event_listener" | |
event="Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event\AddDocumentEvent" | |
method="onAddDocument"/> | |
<tag | |
name="kernel.event_listener" | |
event="Elektronik\Bl\DomainBundle\Infrastructure\Elasticsearch\Event\DeleteDocumentEvent" | |
method="onDeleteDocument"/> | |
<tag | |
name="kernel.event_listener" | |
event="kernel.terminate" | |
method="onTerminate"/> | |
<tag | |
name="kernel.event_listener" | |
event="console.terminate" | |
method="onTerminate"/> | |
</service> | |
</services> | |
</container> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment