Completed
Push — master ( 76ac79...60ae6d )
by Simonas
64:57
created

FilterManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 3
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 ONGR\ElasticsearchDSL\Search;
15
use ONGR\ElasticsearchBundle\Service\Repository;
16
use ONGR\ElasticsearchBundle\Result\DocumentIterator;
17
use ONGR\FilterManagerBundle\Event\PreSearchEvent;
18
use ONGR\FilterManagerBundle\Event\SearchResponseEvent;
19
use ONGR\FilterManagerBundle\Filter\FilterInterface;
20
use ONGR\FilterManagerBundle\Filter\FilterState;
21
use ONGR\FilterManagerBundle\Filter\Helper\ViewDataFactoryInterface;
22
use ONGR\FilterManagerBundle\Filter\ViewData;
23
use ONGR\FilterManagerBundle\ONGRFilterManagerEvents;
24
use ONGR\FilterManagerBundle\Relation\ExcludeRelation;
25
use ONGR\FilterManagerBundle\Relation\FilterIterator;
26
use ONGR\FilterManagerBundle\Relation\LogicalJoin\AndRelation;
27
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
28
use Symfony\Component\HttpFoundation\Request;
29
30
/**
31
 * This class is entry point for search request execution.
32
 */
33
class FilterManager implements FilterManagerInterface
34
{
35
    /**
36
     * @var FilterContainer
37
     */
38
    private $container;
39
40
    /**
41
     * @var Repository
42
     */
43
    private $repository;
44
45
    /**
46
     * @var EventDispatcherInterface
47
     */
48
    private $eventDispatcher;
49
    
50
    /**
51
     * @param FilterContainer          $container
52
     * @param Repository               $repository
53
     * @param EventDispatcherInterface $eventDispatcher
54
     */
55
    public function __construct(
56
        FilterContainer $container,
57
        Repository $repository,
58
        EventDispatcherInterface $eventDispatcher
59
    ) {
60
        $this->container = $container;
61
        $this->repository = $repository;
62
        $this->eventDispatcher = $eventDispatcher;
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function handleRequest(Request $request)
69
    {
70
        return $this->search($this->container->buildSearchRequest($request));
71
    }
72
73
    /**
74
     * Executes search.
75
     *
76
     * @param SearchRequest $request
77
     *
78
     * @return SearchResponse
79
     */
80
    public function search(SearchRequest $request)
81
    {
82
        $this->eventDispatcher->dispatch(ONGRFilterManagerEvents::PRE_SEARCH, new PreSearchEvent($request));
83
84
        $search = $this->container->buildSearch($request);
85
86
        /** @var FilterInterface $filter */
87
        foreach ($this->container->all() as $name => $filter) {
88
            $relatedSearch = new Search();
89
90
            if ($filter->isRelated()) {
91
                // We simply exclude not related filters and current filter itself.
92
                $relatedFilters = $this->container->getFiltersByRelation(
93
                    new AndRelation([$filter->getSearchRelation(), new ExcludeRelation([$name])])
94
                );
95
                $relatedSearch = $this->container->buildSearch($request, $relatedFilters);
0 ignored issues
show
Documentation introduced by
$relatedFilters is of type object<ONGR\FilterManage...elation\FilterIterator>, but the function expects a object<ArrayIterator>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
96
            }
97
98
            $filter->preProcessSearch(
99
                $search,
100
                $relatedSearch,
101
                $request->get($name)
102
            );
103
        }
104
105
        $result = $this->repository->execute($search);
0 ignored issues
show
Deprecated Code introduced by
The method ONGR\ElasticsearchBundle...e\Repository::execute() has been deprecated with message: Use strict execute functions instead. e.g. executeIterator, executeRawIterator.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
106
        $this->eventDispatcher->dispatch(ONGRFilterManagerEvents::SEARCH_RESPONSE, new SearchResponseEvent($result));
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->repository->execute($search) on line 105 can also be of type array or object<ONGR\Elasticsearc...dle\Result\RawIterator>; however, ONGR\FilterManagerBundle...nseEvent::__construct() does only seem to accept object<ONGR\Elasticsearc...esult\DocumentIterator>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
107
108
        return new SearchResponse(
109
            $this->getFiltersViewData($result, $request),
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->repository->execute($search) on line 105 can also be of type array or object<ONGR\Elasticsearc...dle\Result\RawIterator>; however, ONGR\FilterManagerBundle...r::getFiltersViewData() does only seem to accept object<ONGR\Elasticsearc...esult\DocumentIterator>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
110
            $result,
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->repository->execute($search) on line 105 can also be of type array or object<ONGR\Elasticsearc...dle\Result\RawIterator>; however, ONGR\FilterManagerBundle...Response::__construct() does only seem to accept object<ONGR\Elasticsearc...esult\DocumentIterator>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
111
            $this->composeUrlParameters($request)
112
        );
113
    }
114
115
    /**
116
     * Composes url parameters related to given filter.
117
     *
118
     * @param SearchRequest   $request Search request.
119
     * @param FilterInterface $filter  Filter.
120
     * @param array           $exclude Additional names of filters to exclude.
121
     *
122
     * @return array
123
     */
124
    protected function composeUrlParameters(SearchRequest $request, FilterInterface $filter = null, $exclude = [])
125
    {
126
        $out = [];
127
128
        $and = [];
129
130
        if ($filter) {
131
            $and[] = $filter->getResetRelation();
132
        }
133
134
        if (!empty($exclude)) {
135
            $and[] = new ExcludeRelation($exclude);
136
        }
137
138
        /** @var FilterState[] $states */
139
        $states = new FilterIterator(new \IteratorIterator($request), new AndRelation($and));
140
141
        foreach ($states as $state) {
142
            $out = array_merge($out, $state->getUrlParameters());
143
        }
144
145
        return $out;
146
    }
147
148
    /**
149
     * Creates view data for each filter.
150
     *
151
     * @param DocumentIterator $result
152
     * @param SearchRequest    $request
153
     *
154
     * @return ViewData[]
155
     */
156
    protected function getFiltersViewData(DocumentIterator $result, SearchRequest $request)
157
    {
158
        $out = [];
159
160
        /** @var FilterInterface[] $filters */
161
        $filters = $this->container->all();
162
163
        foreach ($filters as $name => $filter) {
164
            if ($filter instanceof ViewDataFactoryInterface) {
165
                $viewData = $filter->createViewData();
166
            } else {
167
                $viewData = new ViewData();
168
            }
169
            $viewData->setName($name);
170
            $viewData->setUrlParameters($this->composeUrlParameters($request, $filter));
171
            $viewData->setState($request->get($name));
172
            $viewData->setTags($filter->getTags());
173
            $viewData->setResetUrlParameters($this->composeUrlParameters($request, $filter, [$name]));
174
            $out[$name] = $filter->getViewData($result, $viewData);
175
        }
176
177
        return $out;
178
    }
179
}
180