Completed
Pull Request — master (#68)
by Daniel
02:11
created

StringFilter::getChoices()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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