Completed
Push — refonte ( a2bfa7...994918 )
by Arnaud
02:19
created

ActionCollectionField::configureOptions()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 48
rs 8.5123
c 0
b 0
f 0
cc 6
nc 4
nop 2
1
<?php
2
3
namespace LAG\AdminBundle\Field;
4
5
use LAG\AdminBundle\Configuration\ActionConfiguration;
6
use LAG\AdminBundle\Field\Traits\EntityAwareTrait;
7
use LAG\AdminBundle\Field\Traits\TwigAwareTrait;
8
use LAG\AdminBundle\Routing\RoutingLoader;
9
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
10
use Symfony\Component\OptionsResolver\Options;
11
use Symfony\Component\OptionsResolver\OptionsResolver;
12
use Symfony\Component\PropertyAccess\PropertyAccess;
13
14
class ActionCollectionField extends CollectionField implements TwigAwareFieldInterface, EntityAwareFieldInterface
15
{
16
    use TwigAwareTrait, EntityAwareTrait;
17
18
    public function configureOptions(OptionsResolver $resolver, ActionConfiguration $actionConfiguration)
19
    {
20
        parent::configureOptions($resolver, $actionConfiguration);
21
22
        $actions = $actionConfiguration
23
            ->getAdminConfiguration()
24
            ->getParameter('actions')
25
        ;
26
        $defaultActions = [];
27
28
        if (key_exists('edit', $actions)) {
29
            $defaultActions['edit'] = $actions['edit'];
30
        }
31
32
        if (key_exists('delete', $actions)) {
33
            $defaultActions['delete'] = $actions['delete'];
34
        }
35
36
        $resolver
37
            ->setDefaults([
38
                'template' => '@LAGAdmin/Field/actionCollection.html.twig',
39
                'actions' => [],
40
            ])
41
            ->setNormalizer('actions', function (Options $options, $value) use ($actionConfiguration, $defaultActions) {
42
                if (!is_array($value) || 0 === count($value)) {
43
                    $value = $defaultActions;
44
                }
45
                $data = [];
46
47
                foreach ($value as $name => $action) {
48
                    $actionData = [
49
                        'admin' => $actionConfiguration->getAdminName(),
50
                        'action' => $name,
51
                        'title' => $actionConfiguration->getParameter('title'),
52
                        'text' => $actionConfiguration->getParameter('title'),
53
                        'parameters' => [
54
                            // TODO get dynamic id key
55
                            'id' => '',
56
                        ],
57
                    ];
58
59
                    $data[$name] = $this->resolveActionConfiguration($actionConfiguration, $actionData);
60
                }
61
62
                return $data;
63
            })
64
        ;
65
    }
66
67
    public function isSortable(): bool
68
    {
69
        return false;
70
    }
71
72
    public function render($value = null): string
73
    {
74
        $accessor = PropertyAccess::createPropertyAccessor();
75
76 View Code Duplication
        if (key_exists('edit', $this->options['actions'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
            $this->options['actions']['edit']['parameters']['id'] = $accessor->getValue($this->entity, 'id');
78
        }
79
80 View Code Duplication
        if (key_exists('delete', $this->options['actions'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
            $this->options['actions']['delete']['parameters']['id'] = $accessor->getValue($this->entity, 'id');
82
        }
83
84
        return $this->twig->render($this->options['template'], [
85
            'actions' => $this->options['actions'],
86
        ]);
87
    }
88
89
    protected function resolveActionConfiguration(ActionConfiguration $actionConfiguration, $value)
90
    {
91
        $resolver = new OptionsResolver();
92
        $resolver
93
            ->setDefaults([
94
                'title' => '',
95
                'icon' => '',
96
                'target' => '_self',
97
                'route' => '',
98
                'parameters' => [],
99
                'url' => '',
100
                'text' => '',
101
                'admin' => null,
102
                'action' => null,
103
                'class' => '',
104
            ])
105
            ->setAllowedTypes('route', 'string')
106
            ->setAllowedTypes('parameters', 'array')
107
            ->setAllowedTypes('url', 'string')
108
            ->setAllowedValues('target', [
109
                '_self',
110
                '_blank',
111
            ])
112 View Code Duplication
            ->setNormalizer('route', function (Options $options, $value) use ($actionConfiguration) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
                // route or url should be defined
114
                if (!$value && !$options->offsetGet('url') && !$options->offsetGet('admin')) {
115
                    throw new InvalidOptionsException(
116
                        'You must set either an url or a route for the property'
117
                    );
118
                }
119
120
                if ($options->offsetGet('admin')) {
121
                    $value = RoutingLoader::generateRouteName(
122
                        $options->offsetGet('admin'),
123
                        $options->offsetGet('action'),
124
                        $actionConfiguration->getAdminConfiguration()->getParameter('routing_name_pattern')
125
                    );
126
                }
127
128
                return $value;
129
            })
130
            ->setNormalizer('admin', function (Options $options, $value) {
131
                // if a Admin is defined, an Action should be defined too
132
                if ($value && !$options->offsetGet('action')) {
133
                    throw new InvalidOptionsException(
134
                        'An Action should be provided if an Admin is provided'
135
                    );
136
                }
137
138
                return $value;
139
            })
140 View Code Duplication
            ->setNormalizer('parameters', function (Options $options, $values) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
141
                $cleanedValues = [];
142
143
                foreach ($values as $name => $method) {
144
                    if (null === $method) {
145
                        $method = $name;
146
                    }
147
                    $cleanedValues[$name] = $method;
148
                }
149
150
151
                return $cleanedValues;
152
            })
153
        ;
154
155
        return $resolver->resolve($value);
156
    }
157
}
158