Completed
Push — refonte ( 2cad75...548acb )
by Arnaud
06:10
created

FilterSubscriber::onFilter()   B

Complexity

Conditions 9
Paths 3

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 7.7244
c 0
b 0
f 0
cc 9
nc 3
nop 1
1
<?php
2
3
namespace LAG\AdminBundle\Event\Subscriber;
4
5
use LAG\AdminBundle\Event\Events;
6
use LAG\AdminBundle\Event\FilterEvent;
7
use LAG\AdminBundle\Filter\Filter;
8
use LAG\AdminBundle\Utils\FormUtils;
9
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10
use Symfony\Component\Form\Extension\Core\Type\FormType;
11
use Symfony\Component\Form\FormFactoryInterface;
12
use Symfony\Component\Form\FormInterface;
13
14
class FilterSubscriber implements EventSubscriberInterface
15
{
16
    /**
17
     * @var FormFactoryInterface
18
     */
19
    private $formFactory;
20
21
    public static function getSubscribedEvents()
22
    {
23
        return [
24
            Events::FILTER => 'onFilter',
25
        ];
26
    }
27
28
    public function __construct(FormFactoryInterface $formFactory)
29
    {
30
        $this->formFactory = $formFactory;
31
    }
32
33
    public function onFilter(FilterEvent $event): void
34
    {
35
        // Retrieve the configured filters for the current admin and action
36
        $admin = $event->getAdmin();
37
        $action = $admin->getAction();
38
        $configuration = $action->getConfiguration();
39
        $filters = $configuration->getParameter('filters');
40
41
        // Nothing to do if not filters are configured
42
        if (0 === count($filters)) {
43
            return;
44
        }
45
        // As filters should be applied before entity loading, the filter form is created and submitted at the same
46
        // time, unlike the classic forms
47
        $form = $this->createForm($filters);
48
        $form->handleRequest($event->getRequest());
49
50
        if ($form->isSubmitted() && $form->isValid()) {
51
            $data = $form->getData();
52
53
            foreach ($filters as $name => $options) {
54
                // Nothing to do if the data is not submitted or if it is null
55
                if (!key_exists($name, $data) || null === $data[$name]) {
56
                    continue;
57
                }
58
59
                // Do not submit false boolean values to improve user experience
60
                if (is_bool($data[$name]) && false === $data[$name]) {
61
                    continue;
62
                }
63
64
                // Create a new filter with submitted and configured values
65
                $filter = new Filter($options['name'], $data[$name], $options['operator']);
66
                $event->addFilter($filter);
67
            }
68
        }
69
70
        // Add the newly created form to the form collection to be displayed on the view
71
        $event->addForm($form, 'filter');
72
    }
73
74
    private function createForm(array $filters): FormInterface
75
    {
76
        $form = $this
77
            ->formFactory
78
            ->createNamed('filter', FormType::class)
79
        ;
80
81
        foreach ($filters as $name => $filter) {
82
            $options = array_merge([
83
                // All filters are optional
84
                'required' => false,
85
            ], $filter['options']);
86
            $type = FormUtils::convertShortFormType($filter['type']);
87
88
            $form->add($name, $type, $options);
89
        }
90
91
        return $form;
92
    }
93
}
94