1<?php
2
3namespace Elastica;
4
5use Elastica\Exception\QueryBuilderException;
6use Elastica\QueryBuilder\DSL;
7use Elastica\QueryBuilder\Facade;
8use Elastica\QueryBuilder\Version;
9
10/**
11 * Query Builder.
12 *
13 * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com>
14 */
15class QueryBuilder
16{
17    /**
18     * @var Version
19     */
20    private $_version;
21
22    /**
23     * @var Facade[]
24     */
25    private $_facades = [];
26
27    /**
28     * Constructor.
29     */
30    public function __construct(?Version $version = null)
31    {
32        $this->_version = $version ?? new Version\Latest();
33
34        $this->addDSL(new DSL\Query());
35        $this->addDSL(new DSL\Aggregation());
36        $this->addDSL(new DSL\Suggest());
37        $this->addDSL(new DSL\Collapse());
38    }
39
40    /**
41     * Returns Facade for custom DSL object.
42     *
43     * @throws QueryBuilderException
44     */
45    public function __call(string $dsl, array $arguments): Facade
46    {
47        if (false === isset($this->_facades[$dsl])) {
48            throw new QueryBuilderException('DSL "'.$dsl.'" not supported');
49        }
50
51        return $this->_facades[$dsl];
52    }
53
54    /**
55     * Adds a new DSL object.
56     */
57    public function addDSL(DSL $dsl): void
58    {
59        $this->_facades[$dsl->getType()] = new Facade($dsl, $this->_version);
60    }
61
62    /*
63     * convenience methods
64     */
65
66    /**
67     * Query DSL.
68     *
69     * @return DSL\Query
70     */
71    public function query()
72    {
73        return $this->_facades[DSL::TYPE_QUERY];
74    }
75
76    /**
77     * Aggregation DSL.
78     *
79     * @return DSL\Aggregation
80     */
81    public function aggregation()
82    {
83        return $this->_facades[DSL::TYPE_AGGREGATION];
84    }
85
86    /**
87     * Suggest DSL.
88     *
89     * @return DSL\Suggest
90     */
91    public function suggest()
92    {
93        return $this->_facades[DSL::TYPE_SUGGEST];
94    }
95
96    /**
97     * Collapse DSL.
98     *
99     * @return DSL\Collapse
100     */
101    public function collapse()
102    {
103        return $this->_facades[DSL::TYPE_COLLAPSE];
104    }
105}
106