Completed
Push — master ( 02db1d...96e327 )
by Daniel
02:23 queued 15s
created

StringFilter::isApplicable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Psi\Component\Grid\Filter;
6
7
use Psi\Component\ObjectAgent\Query\Comparison;
8
use Psi\Component\ObjectAgent\Query\Expression;
9
use Psi\Component\ObjectAgent\Query\Query;
10
use Symfony\Component\Form\Extension\Core\Type\TextType;
11
use Symfony\Component\Form\FormBuilderInterface;
12
use Symfony\Component\OptionsResolver\OptionsResolver;
13
14
class StringFilter extends AbstractComparatorFilter
15
{
16
    const TYPE_EQUAL = 'equal';
17
    const TYPE_EMPTY = 'empty';
18
    const TYPE_NOT_EMPTY = 'not_empty';
19
    const TYPE_CONTAINS = 'contains';
20
    const TYPE_NOT_CONTAINS = 'not_contains';
21
    const TYPE_STARTS_WITH = 'starts_with';
22
    const TYPE_ENDS_WITH = 'ends_with';
23
    const TYPE_IN = 'in';
24
    const TYPE_NOT_IN = 'not_in';
25
26
    private static $comparatorMap = [
27
        self::TYPE_EQUAL => Comparison::EQUALS,
28
        self::TYPE_EMPTY => Comparison::NULL,
29
        self::TYPE_NOT_EMPTY => Comparison::NOT_NULL,
30
        self::TYPE_CONTAINS => Comparison::CONTAINS,
31
        self::TYPE_NOT_CONTAINS => Comparison::NOT_CONTAINS,
32
        self::TYPE_STARTS_WITH => Comparison::CONTAINS,
33
        self::TYPE_ENDS_WITH => Comparison::CONTAINS,
34
        self::TYPE_IN => Comparison::IN,
35
        self::TYPE_NOT_IN => Comparison::NOT_IN,
36
    ];
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function buildForm(FormBuilderInterface $builder, array $options)
42
    {
43
        $this->addComparatorChoice($builder, $options);
44
45
        $builder->add('value', TextType::class, [
46
            'required' => false,
47
        ]);
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function getExpression(string $fieldName, array $data): Expression
54
    {
55
        $comparator = $data['comparator'] ?: self::TYPE_EQUAL;
56
57
        return Query::comparison(
58
            self::$comparatorMap[$comparator],
59
            $fieldName,
60
            $this->getValue($comparator, $data['value'])
61
        );
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function configureOptions(OptionsResolver $options)
68
    {
69
        $options->setDefault('comparators', array_keys(self::$comparatorMap));
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function isApplicable(array $filterData): bool
76
    {
77
        return isset($filterData['value']);
78
    }
79
80
    protected function getComparatorMap(): array
81
    {
82
        return self::$comparatorMap;
83
    }
84
85
    private function getValue($comparator, $value)
86
    {
87
        switch ($comparator) {
88
            case self::TYPE_EQUAL:
89
                return $value;
90
            case self::TYPE_EMPTY:
91
                return;
92
            case self::TYPE_NOT_EMPTY:
93
                return;
94
            case self::TYPE_CONTAINS:
95
                return '%' . $value . '%';
96
            case self::TYPE_NOT_CONTAINS:
97
                return '%' . $value . '%';
98
            case self::TYPE_STARTS_WITH:
99
                return $value . '%';
100
            case self::TYPE_ENDS_WITH:
101
                return '%' . $value;
102
            case self::TYPE_IN:
103
                return array_map('trim', explode(',', $value));
104
            case self::TYPE_NOT_IN:
105
                return array_map('trim', explode(',', $value));
106
        }
107
108
        throw new \InvalidArgumentException(sprintf('Could not determine value for comparator "%s"', $comparator));
109
    }
110
}
111