Completed
Push — master ( 4059cd...ef58c8 )
by Simonas
84:03 queued 19:25
created

Filter/Widget/Dynamic/MultiDynamicAggregate.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace ONGR\FilterManagerBundle\Filter\Widget\Dynamic;
4
5
use ONGR\ElasticsearchBundle\Result\Aggregation\AggregationValue;
6
use ONGR\ElasticsearchBundle\Result\DocumentIterator;
7
use ONGR\ElasticsearchDSL\Aggregation\FilterAggregation;
8
use ONGR\ElasticsearchDSL\Aggregation\NestedAggregation;
9
use ONGR\ElasticsearchDSL\Aggregation\TermsAggregation;
10
use ONGR\ElasticsearchDSL\BuilderInterface;
11
use ONGR\ElasticsearchDSL\Query\BoolQuery;
12
use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
13
use ONGR\ElasticsearchDSL\Query\NestedQuery;
14
use ONGR\ElasticsearchDSL\Query\TermQuery;
15
use ONGR\ElasticsearchDSL\Query\TermsQuery;
16
use ONGR\ElasticsearchDSL\Search;
17
use ONGR\FilterManagerBundle\Filter\FilterState;
18
use ONGR\FilterManagerBundle\Filter\ViewData;
19
use ONGR\FilterManagerBundle\Search\SearchRequest;
20
use Symfony\Component\HttpFoundation\Request;
21
22
class MultiDynamicAggregate extends DynamicAggregate
23
{
24
    /**
25
     * {@inheritdoc}
26
     */
27
    public function getState(Request $request)
28
    {
29
        $state = new FilterState();
30
        $value = $request->get($this->getRequestField());
31
32
        if (isset($value) && is_array($value) && reset($value) && is_array(reset($value))) {
33
            $state->setActive(true);
34
            $state->setValue($value);
35
            $state->setUrlParameters([$this->getRequestField() => $value]);
36
        }
37
38
        return $state;
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function modifySearch(Search $search, FilterState $state = null, SearchRequest $request = null)
45
    {
46
        list($path, $field) = explode('>', $this->getField());
47
48
        if ($state && $state->isActive()) {
49
            $boolQuery = new BoolQuery();
50
51
            foreach ($state->getValue() as $groupName => $values) {
52
                $innerBoolQuery = new BoolQuery();
53
54
                foreach ($values as $value) {
55
                    $innerBoolQuery->add(
56
                        new NestedQuery(
57
                            $path,
58
                            new TermQuery($field, $value)
59
                        ),
60
                        BoolQuery::SHOULD
61
                    );
62
                }
63
64
                $boolQuery->add($innerBoolQuery);
65
            }
66
67
            $search->addPostFilter($boolQuery);
68
        }
69
    }
70
71
    /**
72
     * Fetches buckets from search results.
73
     *
74
     * @param DocumentIterator $result     Search results.
75
     * @param string           $filterName Filter name.
76
     * @param array            $values     Values from the state object
77
     *
78
     * @return array Buckets.
79
     */
80 View Code Duplication
    protected function fetchAggregation(DocumentIterator $result, $filterName, $values)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
    {
82
        $data = [];
83
        $aggregation = $result->getAggregation(sprintf('%s-filter', $filterName));
84
85
        if ($aggregation->getAggregation($filterName)) {
86
            $aggregation = $aggregation->find($filterName.'.query');
87
            $data['all-selected'] = $aggregation;
88
89
            return $data;
90
        }
91
92
        if (!empty($values)) {
93
            foreach ($values as $name => $value) {
94
                $data[$name] = $aggregation->find(sprintf('%s.%s.query', $name, $filterName));
95
            }
96
97
            $data['all-selected'] = $aggregation->find(sprintf('all-selected.%s.query', $filterName));
98
99
            return $data;
100
        }
101
102
        return [];
103
    }
104
105
    /**
106
     * A method used to add an additional filter to the aggregations
107
     * in preProcessSearch
108
     *
109
     * @param FilterAggregation $filterAggregation
110
     * @param NestedAggregation $deepLevelAggregation
111
     * @param array             $terms Terms of additional filter
112
     * @param string            $aggName
113
     *
114
     * @return BuilderInterface
115
     */
116 View Code Duplication
    protected function addSubFilterAggregation(
117
        $filterAggregation,
118
        $deepLevelAggregation,
119
        $terms,
120
        $aggName
121
    ) {
122
        list($path, $field) = explode('>', $this->getField());
123
        $boolQuery = new BoolQuery();
124
125
        foreach ($terms as $namedTerms) {
126
            $boolQuery->add(
127
                new NestedQuery($path, new TermsQuery($field, array_values($namedTerms)))
128
            );
129
        }
130
131
        if ($boolQuery->getQueries() == []) {
132
            $boolQuery->add(new MatchAllQuery());
133
        }
134
135
        $innerFilterAggregation = new FilterAggregation(
136
            $aggName,
137
            $boolQuery
138
        );
139
        $innerFilterAggregation->addAggregation($deepLevelAggregation);
140
        $filterAggregation->addAggregation($innerFilterAggregation);
141
    }
142
143
    /**
144
     * @param string   $key
145
     * @param string   $name
146
     * @param ViewData $data
147
     * @param bool     $active True when the choice is active
148
     *
149
     * @return array
150
     */
151
    protected function getOptionUrlParameters($key, $name, ViewData $data, $active)
152
    {
153
        $value = $data->getState()->getValue();
154
        $parameters = $data->getResetUrlParameters();
155
156 View Code Duplication
        if (!empty($value)) {
157
            if ($active) {
158
                unset($value[$name][array_search($key, $value[$name])]);
159
                $parameters[$this->getRequestField()] = $value;
160
161
                return $parameters;
162
            }
163
164
            $parameters[$this->getRequestField()] = $value;
165
        }
166
167
        $parameters[$this->getRequestField()][$name][] = $key;
168
169
        return $parameters;
170
    }
171
172
    /**
173
     * Returns whether choice with the specified key is active.
174
     *
175
     * @param string   $key
176
     * @param ViewData $data
177
     * @param string   $activeName
178
     *
179
     * @return bool
180
     */
181
    protected function isChoiceActive($key, ViewData $data, $activeName)
182
    {
183
        if ($data->getState()->isActive()) {
184
            $value = $data->getState()->getValue();
185
186
            if (isset($value[$activeName]) && in_array($key, $value[$activeName])) {
187
                return true;
188
            }
189
        }
190
191
        return false;
192
    }
193
}
194