Completed
Pull Request — master (#4831)
by Jordi Sala
10:38 queued 05:56
created

Datagrid::buildPager()   D

Complexity

Conditions 14
Paths 169

Size

Total Lines 75
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 75
rs 4.9339
c 0
b 0
f 0
cc 14
eloc 45
nc 169
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[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 Sonata\AdminBundle\Datagrid;
13
14
use Sonata\AdminBundle\Admin\FieldDescriptionCollection;
15
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
16
use Sonata\AdminBundle\Filter\FilterInterface;
17
use Symfony\Component\Form\CallbackTransformer;
18
use Symfony\Component\Form\Exception\UnexpectedTypeException;
19
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
20
use Symfony\Component\Form\FormBuilderInterface;
21
use Symfony\Component\Form\FormInterface;
22
23
/**
24
 * @author Thomas Rabaix <[email protected]>
25
 */
26
class Datagrid implements DatagridInterface
27
{
28
    /**
29
     * The filter instances.
30
     *
31
     * @var array
32
     */
33
    protected $filters = [];
34
35
    /**
36
     * @var array
37
     */
38
    protected $values;
39
40
    /**
41
     * @var FieldDescriptionCollection
42
     */
43
    protected $columns;
44
45
    /**
46
     * @var PagerInterface
47
     */
48
    protected $pager;
49
50
    /**
51
     * @var bool
52
     */
53
    protected $bound = false;
54
55
    /**
56
     * @var ProxyQueryInterface
57
     */
58
    protected $query;
59
60
    /**
61
     * @var FormBuilderInterface
62
     */
63
    protected $formBuilder;
64
65
    /**
66
     * @var FormInterface
67
     */
68
    protected $form;
69
70
    /**
71
     * @var array
72
     */
73
    protected $results;
74
75
    /**
76
     * @param ProxyQueryInterface        $query
77
     * @param FieldDescriptionCollection $columns
78
     * @param PagerInterface             $pager
79
     * @param FormBuilderInterface       $formBuilder
80
     * @param array                      $values
81
     */
82
    public function __construct(ProxyQueryInterface $query, FieldDescriptionCollection $columns, PagerInterface $pager, FormBuilderInterface $formBuilder, array $values = [])
83
    {
84
        $this->pager = $pager;
85
        $this->query = $query;
86
        $this->values = $values;
87
        $this->columns = $columns;
88
        $this->formBuilder = $formBuilder;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function getPager()
95
    {
96
        return $this->pager;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function getResults()
103
    {
104
        $this->buildPager();
105
106
        if (null === $this->results) {
107
            $this->results = $this->pager->getResults();
108
        }
109
110
        return $this->results;
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function buildPager()
117
    {
118
        if ($this->bound) {
119
            return;
120
        }
121
122
        foreach ($this->getFilters() as $name => $filter) {
123
            list($type, $options) = $filter->getRenderSettings();
124
125
            $this->formBuilder->add($filter->getFormName(), $type, $options);
126
        }
127
128
        $hiddenType = HiddenType::class;
129
130
        $this->formBuilder->add('_sort_by', $hiddenType);
131
        $this->formBuilder->get('_sort_by')->addViewTransformer(new CallbackTransformer(
132
            function ($value) {
133
                return $value;
134
            },
135
            function ($value) {
136
                return $value instanceof FieldDescriptionInterface ? $value->getName() : $value;
137
            }
138
        ));
139
140
        $this->formBuilder->add('_sort_order', $hiddenType);
141
        $this->formBuilder->add('_page', $hiddenType);
142
        $this->formBuilder->add('_per_page', $hiddenType);
143
144
        $this->form = $this->formBuilder->getForm();
145
        $this->form->submit($this->values);
146
147
        $data = $this->form->getData();
148
149
        foreach ($this->getFilters() as $name => $filter) {
150
            $this->values[$name] = isset($this->values[$name]) ? $this->values[$name] : null;
151
            $filter->apply($this->query, $data[$filter->getFormName()]);
152
        }
153
154
        if (isset($this->values['_sort_by'])) {
155
            if (!$this->values['_sort_by'] instanceof FieldDescriptionInterface) {
156
                throw new UnexpectedTypeException($this->values['_sort_by'], FieldDescriptionInterface::class);
157
            }
158
159
            if ($this->values['_sort_by']->isSortable()) {
160
                $this->query->setSortBy($this->values['_sort_by']->getSortParentAssociationMapping(), $this->values['_sort_by']->getSortFieldMapping());
161
                $this->query->setSortOrder(isset($this->values['_sort_order']) ? $this->values['_sort_order'] : null);
162
            }
163
        }
164
165
        $maxPerPage = 25;
166
        if (isset($this->values['_per_page'])) {
167
            if (isset($this->values['_per_page']['value'])) {
168
                $maxPerPage = $this->values['_per_page']['value'];
169
            } else {
170
                $maxPerPage = $this->values['_per_page'];
171
            }
172
        }
173
        $this->pager->setMaxPerPage($maxPerPage);
174
175
        $page = 1;
176
        if (isset($this->values['_page'])) {
177
            if (isset($this->values['_page']['value'])) {
178
                $page = $this->values['_page']['value'];
179
            } else {
180
                $page = $this->values['_page'];
181
            }
182
        }
183
184
        $this->pager->setPage($page);
185
186
        $this->pager->setQuery($this->query);
187
        $this->pager->init();
188
189
        $this->bound = true;
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195
    public function addFilter(FilterInterface $filter)
196
    {
197
        $this->filters[$filter->getName()] = $filter;
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     */
203
    public function hasFilter($name)
204
    {
205
        return isset($this->filters[$name]);
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211
    public function removeFilter($name)
212
    {
213
        unset($this->filters[$name]);
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     */
219
    public function getFilter($name)
220
    {
221
        return $this->hasFilter($name) ? $this->filters[$name] : null;
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227
    public function getFilters()
228
    {
229
        return $this->filters;
230
    }
231
232
    /**
233
     * {@inheritdoc}
234
     */
235
    public function reorderFilters(array $keys)
236
    {
237
        $this->filters = array_merge(array_flip($keys), $this->filters);
238
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243
    public function getValues()
244
    {
245
        return $this->values;
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     */
251
    public function setValue($name, $operator, $value)
252
    {
253
        $this->values[$name] = [
254
            'type' => $operator,
255
            'value' => $value,
256
        ];
257
    }
258
259
    /**
260
     * {@inheritdoc}
261
     */
262
    public function hasActiveFilters()
263
    {
264
        foreach ($this->filters as $name => $filter) {
265
            if ($filter->isActive()) {
266
                return true;
267
            }
268
        }
269
270
        return false;
271
    }
272
273
    /**
274
     * {@inheritdoc}
275
     */
276
    public function hasDisplayableFilters()
277
    {
278
        foreach ($this->filters as $name => $filter) {
279
            $showFilter = $filter->getOption('show_filter', null);
280
            if (($filter->isActive() && null === $showFilter) || (true === $showFilter)) {
281
                return true;
282
            }
283
        }
284
285
        return false;
286
    }
287
288
    /**
289
     * {@inheritdoc}
290
     */
291
    public function getColumns()
292
    {
293
        return $this->columns;
294
    }
295
296
    /**
297
     * {@inheritdoc}
298
     */
299
    public function getQuery()
300
    {
301
        return $this->query;
302
    }
303
304
    /**
305
     * {@inheritdoc}
306
     */
307
    public function getForm()
308
    {
309
        $this->buildPager();
310
311
        return $this->form;
312
    }
313
}
314