CollectionAction   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 38
c 0
b 0
f 0
dl 0
loc 150
ccs 43
cts 43
cp 1
rs 10
wmc 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setFilterable() 0 4 1
A prepareCollection() 0 23 2
A filterParsers() 0 5 1
A applyFilter() 0 7 1
A applyPagination() 0 11 1
A getStringFilterField() 0 3 1
A setFilterProperty() 0 4 1
A getArrayFilterFields() 0 3 1
A handle() 0 9 1
1
<?php namespace Pz\Doctrine\Rest\Action;
2
3
use Doctrine\Common\Collections\Criteria;
4
use Doctrine\ORM\QueryBuilder;
5
use Doctrine\ORM\Tools\Pagination\Paginator;
6
use League\Fractal\Pagination\DoctrinePaginatorAdapter;
7
use Pz\Doctrine\Rest\BuilderChain\CriteriaChain;
8
use Pz\Doctrine\Rest\QueryParser\ArrayFilterParser;
9
use Pz\Doctrine\Rest\QueryParser\FilterParserAbstract;
10
use Pz\Doctrine\Rest\QueryParser\SearchFilterParser;
11
use Pz\Doctrine\Rest\Resource\Collection;
12
use Pz\Doctrine\Rest\RestAction;
13
use Pz\Doctrine\Rest\Contracts\RestRequestContract;
14
use Pz\Doctrine\Rest\RestResponse;
15
use Pz\Doctrine\Rest\RestResponseFactory;
16
17
/**
18
 * Action for providing collection (list or array) of data with API.
19
 */
20
class CollectionAction extends RestAction
21
{
22
    /**
23
     * Field that can be filtered if filter is string.
24
     *
25
     * @var string
26
     */
27
    protected $filterProperty;
28
29
    /**
30
     * Get list of filterable entity fields.
31
     *
32
     * @var array
33
     */
34
    protected $filterable = [];
35
36
    /**
37
     * @param string $property
38
     *
39
     * @return $this
40
     */
41 1
    public function setFilterProperty($property)
42
    {
43 1
        $this->filterProperty = $property;
44 1
        return $this;
45
    }
46
47
    /**
48
     * @param array $filterable
49
     *
50
     * @return $this
51
     */
52 1
    public function setFilterable(array $filterable)
53
    {
54 1
        $this->filterable = $filterable;
55 1
        return $this;
56
    }
57
58
    /**
59
     * Param that can be filtered if query is string.
60
     *
61
     * @return null|string
62
     */
63 12
    public function getStringFilterField()
64
    {
65 12
        return $this->filterProperty;
66
    }
67
68
    /**
69
     * Get list of filterable entity properties.
70
     *
71
     * @return array
72
     */
73 12
    public function getArrayFilterFields()
74
    {
75 12
        return $this->filterable;
76
    }
77
78
    /**
79
     * @param RestRequestContract $request
80
     * @return RestResponse
81
     * @throws \Doctrine\ORM\Query\QueryException
82
     */
83 12
    protected function handle($request)
84
    {
85 12
        $this->authorize($request, $this->repository()->getClassName());
86
87 12
        $qb = $this->repository()->sourceQueryBuilder($request);
88 12
        $this->applyPagination($request, $qb);
89 12
        $this->applyFilter($request, $qb);
90
91 12
        return RestResponseFactory::resource($request, $this->prepareCollection($request, $qb));
92
    }
93
94
    /**
95
     * @param RestRequestContract   $request
96
     * @param QueryBuilder          $qb
97
     * @return Collection
98
     */
99 12
    protected function prepareCollection($request, QueryBuilder $qb)
100
    {
101 12
        $paginator = new Paginator($qb, false);
102 12
        $collection = new Collection($paginator, $this->transformer(), $this->repository()->getResourceKey());
103
104 12
        if ($qb->getMaxResults()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $qb->getMaxResults() of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
105 2
            $collection->setPaginator(
106 2
                new DoctrinePaginatorAdapter(
107 2
                    $paginator,
108 2
                    function(int $page) use ($request) {
109
                        // return !$resourceKey ? null : "{$request->getBaseUrl()}/$resourceKey?".http_build_query([
110 2
                        return $request->getBasePath().'?'.http_build_query([
0 ignored issues
show
Bug introduced by
The method getBasePath() does not exist on Pz\Doctrine\Rest\Contracts\RestRequestContract. Did you maybe mean getBaseUrl()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
                        return $request->/** @scrutinizer ignore-call */ getBasePath().'?'.http_build_query([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
111
                            'page' => [
112 2
                                'number'    => $page,
113 2
                                'size'      => $request->getLimit()
114
                            ]
115
                        ]);
116 2
                    }
117
                )
118
            );
119
        }
120
121 12
        return $collection;
122
    }
123
124
    /**
125
     * @param RestRequestContract $request
126
     * @param QueryBuilder        $qb
127
     *
128
     * @throws \Doctrine\ORM\Query\QueryException
129
     * @return $this
130
     */
131 12
    protected function applyPagination(RestRequestContract $request, QueryBuilder $qb)
132
    {
133 12
        $qb->addCriteria(
134 12
            new Criteria(null,
135 12
                $request->getOrderBy(),
136 12
                $request->getStart(),
137 12
                $request->getLimit()
138
            )
139
        );
140
141 12
        return $this;
142
    }
143
144
    /**
145
     * @param RestRequestContract $request
146
     * @param QueryBuilder        $qb
147
     *
148
     * @throws \Doctrine\ORM\Query\QueryException
149
     * @return $this
150
     */
151 12
    protected function applyFilter(RestRequestContract $request, QueryBuilder $qb)
152
    {
153 12
        $qb->addCriteria(
154 12
            CriteriaChain::create($this->filterParsers($request))->process()
155
        );
156
157 12
        return $this;
158
    }
159
160
    /**
161
     * @param RestRequestContract $request
162
     *
163
     * @return array|FilterParserAbstract[]
164
     */
165 12
    protected function filterParsers(RestRequestContract $request)
166
    {
167
        return [
168 12
            new SearchFilterParser($request, $this->getStringFilterField()),
169 12
            new ArrayFilterParser($request, $this->getArrayFilterFields()),
170
        ];
171
    }
172
}
173