|
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'])) { |
|
|
|
|
|
|
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'])) { |
|
|
|
|
|
|
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) { |
|
|
|
|
|
|
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) { |
|
|
|
|
|
|
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
|
|
|
|
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.