Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an interface for each condition factory to allow decorating #252

Open
dkarlovi opened this issue Dec 7, 2018 · 3 comments
Open

Add an interface for each condition factory to allow decorating #252

dkarlovi opened this issue Dec 7, 2018 · 3 comments

Comments

@dkarlovi
Copy link
Contributor

dkarlovi commented Dec 7, 2018

Description
Adding an interface to the factory allows to more easily decorate it for use cases such as #249 (comment)

@dkarlovi
Copy link
Contributor Author

dkarlovi commented Dec 7, 2018

The alternative would be to expand each factory to support that use case out of the box, maybe also something to think about.

@dkarlovi dkarlovi changed the title Add an interface for each condition factory to allow mocking Add an interface for each condition factory to allow decorating Dec 10, 2018
@sstok sstok added the DX label Feb 18, 2019
@sstok
Copy link
Member

sstok commented Apr 12, 2020

@dkarlovi is this Elasticsearch specific? And if so, is it still relevant?

@dkarlovi
Copy link
Contributor Author

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.

@sstok sstok added this to the 2.0 milestone Sep 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants