Completed
Pull Request — master (#168)
by
unknown
63:02
created

FilterContainer::buildSearchRequest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\FilterManagerBundle\Search;
13
14
use Doctrine\Common\Cache\Cache;
15
use ONGR\ElasticsearchDSL\Search;
16
use ONGR\FilterManagerBundle\Filter\FilterInterface;
17
use ONGR\FilterManagerBundle\Relation\FilterIterator;
18
use ONGR\FilterManagerBundle\Relation\RelationInterface;
19
use Symfony\Component\HttpFoundation\ParameterBag;
20
use Symfony\Component\HttpFoundation\Request;
21
22
/**
23
 * This class holds collection of FilterInterface objects labeled by name.
24
 */
25
class FilterContainer extends ParameterBag
26
{
27
    /**
28
     * @var Cache
29
     */
30
    private $cache;
31
32
    /**
33
     * @var int
34
     */
35
    private $lifeTime;
36
37
    /**
38
     * @var array
39
     */
40
    private $exclude = [];
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function add(array $parameters = [])
46
    {
47
        foreach ($parameters as $key => $value) {
48
            $this->set($key, $value);
49
        }
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function set($key, $value)
56
    {
57
        if ($value instanceof FilterInterface) {
58
            parent::set($key, $value);
59
        }
60
    }
61
62
    /**
63
     * Sets cache engine
64
     *
65
     * @param Cache|null $cache
66
     */
67
    public function setCache(Cache $cache = null)
68
    {
69
        $this->cache = $cache;
70
    }
71
72
    /**
73
     * Sets cached search life time
74
     *
75
     * @param $lifeTime
76
     */
77
    public function setLifeTime($lifeTime)
78
    {
79
        $this->lifeTime = $lifeTime;
80
    }
81
82
    /**
83
     * Sets array of filter names not to be cached
84
     *
85
     * @param array $exclude
86
     */
87
    public function setExclude(array $exclude)
88
    {
89
        $this->exclude = $exclude;
90
    }
91
92
    /**
93
     * Filters accepted.
94
     *
95
     * @param RelationInterface $relation
96
     *
97
     * @return FilterInterface[]
98
     */
99
    public function getFiltersByRelation(RelationInterface $relation)
100
    {
101
        return new FilterIterator($this->getIterator(), $relation);
102
    }
103
104
    /**
105
     * Builds search request according to given filters.
106
     *
107
     * @param Request $request
108
     *
109
     * @return SearchRequest
110
     */
111
    public function buildSearchRequest(Request $request)
112
    {
113
        $search = new SearchRequest();
114
        /** @var FilterInterface[] $filters */
115
        $filters = $this->all();
116
117
        foreach ($filters as $name => $filter) {
118
            $state = $filter->getState($request);
119
            $state->setName($name);
120
            $search->set($name, $state);
121
        }
122
123
        return $search;
124
    }
125
126
    /**
127
     * Builds elastic search query by given SearchRequest and filters.
128
     *
129
     * @param SearchRequest       $request
130
     * @param \ArrayIterator|null $filters
131
     *
132
     * @return Search
133
     */
134
    public function buildSearch(SearchRequest $request, $filters = null)
135
    {
136
        /** @var \ArrayIterator $filters */
137
        $filters = $filters ? $filters : $this->getIterator();
138
        $search = new Search();
139
        $cachedFilters = [];
140
141
        if ($this->cache) {
142
            foreach ($filters as $name => $filter) {
143
                if (!in_array($name, $this->exclude)) {
144
                    $cachedFilters[$name] = $request->get($name)->getSerializableData();
145
                }
146
            }
147
148
            $searchHash = md5(serialize($cachedFilters));
149
150
            if ($this->cache->contains($searchHash)) {
151
                $search = $this->cache->fetch($searchHash);
152
            } else {
153
                foreach ($cachedFilters as $name => $state) {
154
                    $filters->offsetGet($name)->modifySearch($search, $request->get($name), $request);
155
                }
156
                $this->cache->save($searchHash, $search, $this->lifeTime);
157
            }
158
        }
159
160
        foreach ($filters as $name => $filter) {
161
            if (!array_key_exists($name, $cachedFilters)) {
162
                $filter->modifySearch($search, $request->get($name), $request);
163
            }
164
        }
165
166
        return $search;
167
    }
168
}
169