Completed
Pull Request — master (#145)
by Mantas
102:22 queued 37:23
created

FiltersManager::handleRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
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 ONGR\ElasticsearchBundle\Service\Repository;
15
use ONGR\ElasticsearchBundle\Result\DocumentIterator;
16
use ONGR\FilterManagerBundle\Filters\FilterInterface;
17
use ONGR\FilterManagerBundle\Filters\FilterState;
18
use ONGR\FilterManagerBundle\Filters\Helper\ViewDataFactoryInterface;
19
use ONGR\FilterManagerBundle\Filters\ViewData;
20
use ONGR\FilterManagerBundle\Relations\ExcludeRelation;
21
use ONGR\FilterManagerBundle\Relations\FilterIterator;
22
use ONGR\FilterManagerBundle\Relations\LogicalJoin\AndRelation;
23
use Symfony\Component\HttpFoundation\Request;
24
25
/**
26
 * This class is entry point for search request execution.
27
 */
28
class FiltersManager implements FiltersManagerInterface
29
{
30
    /**
31
     * @var FiltersContainer
32
     */
33
    private $container;
34
35
    /**
36
     * @var Repository
37
     */
38
    private $repository;
39
40
    /**
41
     * @param FiltersContainer $container
42
     * @param Repository       $repository
43
     */
44
    public function __construct(FiltersContainer $container, Repository $repository)
45
    {
46
        $this->container = $container;
47
        $this->repository = $repository;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function handleRequest(Request $request)
54
    {
55
        return $this->search($this->container->buildSearchRequest($request));
56
    }
57
58
    /**
59
     * Executes search.
60
     *
61
     * @param SearchRequest $request
62
     *
63
     * @return SearchResponse
64
     */
65
    public function search(SearchRequest $request)
66
    {
67
        $search = $this->container->buildSearch($request);
68
69
        /** @var FilterInterface $filter */
70
        foreach ($this->container->all() as $name => $filter) {
71
            // We simply exclude not related filters and current filter itself.
72
            $relatedFilters = $this->container->getFiltersByRelation(
73
                new AndRelation([$filter->getSearchRelation(), new ExcludeRelation([$name])])
74
            );
75
            $filter->preProcessSearch(
76
                $search,
77
                $this->container->buildSearch($request, $relatedFilters),
0 ignored issues
show
Documentation introduced by
$relatedFilters is of type object<ONGR\FilterManage...lations\FilterIterator>, but the function expects a array<integer,object<ONG...\FilterInterface>>|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...
78
                $request->get($name)
79
            );
80
        }
81
82
        $result = $this->repository->execute($search);
83
84
        return new SearchResponse(
85
            $this->getFiltersViewData($result, $request),
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->repository->execute($search) on line 82 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...
86
            $result,
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->repository->execute($search) on line 82 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...
87
            $this->composeUrlParameters($request)
88
        );
89
    }
90
91
    /**
92
     * Composes url parameters related to given filter.
93
     *
94
     * @param SearchRequest   $request Search request.
95
     * @param FilterInterface $filter  Filter.
96
     * @param array           $exclude Additional names of filters to exclude.
97
     *
98
     * @return array
99
     */
100
    protected function composeUrlParameters(SearchRequest $request, FilterInterface $filter = null, $exclude = [])
101
    {
102
        $out = [];
103
104
        $and = [];
105
106
        if ($filter) {
107
            $and[] = $filter->getResetRelation();
108
        }
109
110
        if (!empty($exclude)) {
111
            $and[] = new ExcludeRelation($exclude);
112
        }
113
114
        /** @var FilterState[] $states */
115
        $states = new FilterIterator(new \IteratorIterator($request), new AndRelation($and));
116
117
        foreach ($states as $state) {
118
            $out = array_merge($out, $state->getUrlParameters());
119
        }
120
121
        return $out;
122
    }
123
124
    /**
125
     * Creates view data for each filter.
126
     *
127
     * @param DocumentIterator $result
128
     * @param SearchRequest    $request
129
     *
130
     * @return ViewData[]
131
     */
132
    protected function getFiltersViewData(DocumentIterator $result, SearchRequest $request)
133
    {
134
        $out = [];
135
136
        /** @var FilterInterface[] $filters */
137
        $filters = $this->container->all();
138
139
        foreach ($filters as $name => $filter) {
140
            if ($filter instanceof ViewDataFactoryInterface) {
141
                $viewData = $filter->createViewData();
142
            } else {
143
                $viewData = new ViewData();
144
            }
145
            $viewData->setName($name);
146
            $viewData->setUrlParameters($this->composeUrlParameters($request, $filter));
147
            $viewData->setState($request->get($name));
148
            $viewData->setTags($filter->getTags());
149
            $viewData->setResetUrlParameters($this->composeUrlParameters($request, $filter, [$name]));
150
            $out[$name] = $filter->getViewData($result, $viewData);
151
        }
152
153
        return $out;
154
    }
155
}
156