Completed
Push — master ( 639ab6...c3e126 )
by Vincent
01:54
created

ChoiceFilter::filter()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.2222
c 0
b 0
f 0
cc 6
nc 3
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\DoctrineORMAdminBundle\Filter;
15
16
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
17
use Sonata\AdminBundle\Form\Type\Filter\DefaultType;
18
use Sonata\AdminBundle\Form\Type\Operator\EqualOperatorType;
19
20
class ChoiceFilter extends Filter
21
{
22
    public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data): void
23
    {
24
        if (!$data || !\is_array($data) || !\array_key_exists('type', $data) || !\array_key_exists('value', $data)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
25
            return;
26
        }
27
28
        if (\is_array($data['value'])) {
29
            $this->filterWithMultipleValues($queryBuilder, $alias, $field, $data);
30
        } else {
31
            $this->filterWithSingleValue($queryBuilder, $alias, $field, $data);
32
        }
33
    }
34
35
    public function getDefaultOptions()
36
    {
37
        return [
38
            'operator_type' => EqualOperatorType::class,
39
            'operator_options' => [],
40
        ];
41
    }
42
43
    public function getRenderSettings()
44
    {
45
        return [DefaultType::class, [
46
            'operator_type' => $this->getOption('operator_type'),
47
            'operator_options' => $this->getOption('operator_options'),
48
            'field_type' => $this->getFieldType(),
49
            'field_options' => $this->getFieldOptions(),
50
            'label' => $this->getLabel(),
51
        ]];
52
    }
53
54
    private function filterWithMultipleValues(ProxyQueryInterface $queryBuilder, string $alias, string $field, array $data = []): void
55
    {
56
        if (0 === \count($data['value'])) {
57
            return;
58
        }
59
60
        $isNullSelected = \in_array(null, $data['value'], true);
61
        $data['value'] = array_filter($data['value'], static function ($value): bool {
62
            return null !== $value;
63
        });
64
65
        // Have to pass IN array value as parameter. See: http://www.doctrine-project.org/jira/browse/DDC-3759
66
        $completeField = sprintf('%s.%s', $alias, $field);
67
        $parameterName = $this->getNewParameterName($queryBuilder);
68
        if (EqualOperatorType::TYPE_NOT_EQUAL === $data['type']) {
69
            $andConditions = [$queryBuilder->expr()->isNotNull($completeField)];
70
            if (0 !== \count($data['value'])) {
71
                $andConditions[] = $queryBuilder->expr()->notIn($completeField, ':'.$parameterName);
72
                $queryBuilder->setParameter($parameterName, $data['value']);
73
            }
74
            $this->applyWhere($queryBuilder, $queryBuilder->expr()->andX()->addMultiple($andConditions));
75
        } else {
76
            $orConditions = [$queryBuilder->expr()->in($completeField, ':'.$parameterName)];
77
            if ($isNullSelected) {
78
                $orConditions[] = $queryBuilder->expr()->isNull($completeField);
79
            }
80
            $this->applyWhere($queryBuilder, $queryBuilder->expr()->orX()->addMultiple($orConditions));
81
            $queryBuilder->setParameter($parameterName, $data['value']);
82
        }
83
    }
84
85
    private function filterWithSingleValue(ProxyQueryInterface $queryBuilder, string $alias, string $field, array $data = []): void
86
    {
87
        if ('' === $data['value'] || false === $data['value']) {
88
            return;
89
        }
90
91
        $parameterName = $this->getNewParameterName($queryBuilder);
92
93
        if (EqualOperatorType::TYPE_NOT_EQUAL === $data['type']) {
94
            if (null === $data['value']) {
95
                $this->applyWhere($queryBuilder, $queryBuilder->expr()->isNotNull(sprintf('%s.%s', $alias, $field)));
96
            } else {
97
                $this->applyWhere($queryBuilder, sprintf('%s.%s != :%s', $alias, $field, $parameterName));
98
                $queryBuilder->setParameter($parameterName, $data['value']);
99
            }
100
        } else {
101
            if (null === $data['value']) {
102
                $this->applyWhere($queryBuilder, $queryBuilder->expr()->isNull(sprintf('%s.%s', $alias, $field)));
103
            } else {
104
                $this->applyWhere($queryBuilder, sprintf('%s.%s = :%s', $alias, $field, $parameterName));
105
                $queryBuilder->setParameter($parameterName, $data['value']);
106
            }
107
        }
108
    }
109
}
110