Completed
Push — master ( 3a4f6f...6dd6fb )
by Grégoire
01:42 queued 01:39
created

StringFilter::filter()   C

Complexity

Conditions 12
Paths 34

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
nc 34
nop 4
dl 0
loc 48
rs 6.9666
c 0
b 0
f 0

How to fix   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
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\ChoiceType;
18
19
class StringFilter extends Filter
20
{
21
    public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data): void
22
    {
23
        if (!$data || !\is_array($data) || !\array_key_exists('value', $data) || null === $data['value']) {
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...
24
            return;
25
        }
26
27
        $data['value'] = trim($data['value']);
28
29
        if (0 === \strlen($data['value'])) {
30
            return;
31
        }
32
33
        $data['type'] = !isset($data['type']) ? ChoiceType::TYPE_CONTAINS : $data['type'];
34
35
        $operator = $this->getOperator((int) $data['type']);
36
37
        if (!$operator) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $operator of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

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

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
38
            $operator = 'LIKE';
39
        }
40
41
        // c.name > '1' => c.name OPERATOR :FIELDNAME
42
        $parameterName = $this->getNewParameterName($queryBuilder);
43
44
        $or = $queryBuilder->expr()->orX();
45
46
        if ($this->getOption('case_sensitive')) {
47
            $or->add(sprintf('%s.%s %s :%s', $alias, $field, $operator, $parameterName));
48
        } else {
49
            $or->add(sprintf('LOWER(%s.%s) %s :%s', $alias, $field, $operator, $parameterName));
50
        }
51
52
        if (ChoiceType::TYPE_NOT_CONTAINS === $data['type']) {
53
            $or->add($queryBuilder->expr()->isNull(sprintf('%s.%s', $alias, $field)));
54
        }
55
56
        $this->applyWhere($queryBuilder, $or);
57
58
        if (ChoiceType::TYPE_EQUAL === $data['type']) {
59
            $queryBuilder->setParameter($parameterName, $data['value']);
60
        } else {
61
            $queryBuilder->setParameter($parameterName,
62
                sprintf(
63
                    $this->getOption('format'),
64
                    $this->getOption('case_sensitive') ? $data['value'] : mb_strtolower($data['value'])
65
                )
66
            );
67
        }
68
    }
69
70
    public function getDefaultOptions()
71
    {
72
        return [
73
            'format' => '%%%s%%',
74
            'case_sensitive' => true,
75
        ];
76
    }
77
78
    public function getRenderSettings()
79
    {
80
        return [ChoiceType::class, [
81
            'field_type' => $this->getFieldType(),
82
            'field_options' => $this->getFieldOptions(),
83
            'label' => $this->getLabel(),
84
        ]];
85
    }
86
87
    /**
88
     * @param string $type
89
     *
90
     * @return bool
91
     */
92
    private function getOperator($type)
93
    {
94
        $choices = [
95
            ChoiceType::TYPE_CONTAINS => 'LIKE',
96
            ChoiceType::TYPE_NOT_CONTAINS => 'NOT LIKE',
97
            ChoiceType::TYPE_EQUAL => '=',
98
        ];
99
100
        return $choices[$type] ?? false;
101
    }
102
}
103