Add an interface for each condition factory to allow decorating
Description
Adding an interface to the factory allows to more easily decorate it for use cases such as https://github.com/rollerworks/search/issues/249#issuecomment-445166278
The alternative would be to expand each factory to support that use case out of the box, maybe also something to think about.
@dkarlovi is this Elasticsearch specific? And if so, is it still relevant?
It's definitely relevant, since now I have to extend the existing factory instead of implementing the interface.
Currently I have:
<?php
declare(strict_types=1);
namespace App\Infrastructure\RollerworksSearch\Elasticsearch;
use Rollerworks\Component\Search\Elasticsearch\ConditionGenerator;
use Rollerworks\Component\Search\Elasticsearch\ElasticsearchFactory;
use Rollerworks\Component\Search\SearchCondition;
class DynamicElasticsearchFactory extends ElasticsearchFactory
{
/**
* @var ElasticsearchFactory
*/
private $factory;
/**
* @var array
*/
private $mappings = [];
public function __construct(ElasticsearchFactory $factory)
{
$this->factory = $factory;
}
public function setMapping(string $name, array $mapping): void
{
$this->mappings[$name] = $mapping;
}
public function createConditionGenerator(SearchCondition $searchCondition): ConditionGenerator
{
$condition = $this->factory->createConditionGenerator($searchCondition);
$this->applyMappings($condition);
return $condition;
}
public function createCachedConditionGenerator(ConditionGenerator $conditionGenerator, $ttl = 0): ConditionGenerator
{
$condition = $this->factory->createCachedConditionGenerator($conditionGenerator, $ttl);
$this->applyMappings($condition);
return $condition;
}
private function applyMappings(ConditionGenerator $condition): void
{
foreach ($this->mappings as $name => $mapping) {
$condition->registerField($name, $mapping['mapping'], $mapping['conditions']);
}
}
}
This allows me to decorate the condition factory with one which allows me to attach mappings before the condition is created (via setMapping).
The ElasticsearchFactory should implement an interface which could then be implemented against. This is probably true for all condition factories.