|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace LAG\AdminBundle\Twig; |
|
4
|
|
|
|
|
5
|
|
|
use LAG\AdminBundle\Admin\Behaviors\TranslationKeyTrait; |
|
6
|
|
|
use LAG\AdminBundle\Application\Configuration\ApplicationConfiguration; |
|
7
|
|
|
use LAG\AdminBundle\Configuration\Factory\ConfigurationFactory; |
|
8
|
|
|
use LAG\AdminBundle\Field\Field; |
|
9
|
|
|
use LAG\AdminBundle\Field\EntityFieldInterface; |
|
10
|
|
|
use LAG\AdminBundle\Field\FieldInterface; |
|
11
|
|
|
use Symfony\Component\DependencyInjection\Container; |
|
12
|
|
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; |
|
13
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccess; |
|
14
|
|
|
use Symfony\Component\Translation\TranslatorInterface; |
|
15
|
|
|
use Twig_Environment; |
|
16
|
|
|
use Twig_Extension; |
|
17
|
|
|
use Twig_SimpleFilter; |
|
18
|
|
|
use Twig_SimpleFunction; |
|
19
|
|
|
use Symfony\Component\Routing\RouterInterface; |
|
20
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* Class AdminExtension. |
|
24
|
|
|
* |
|
25
|
|
|
* Admin utils functions for twig |
|
26
|
|
|
*/ |
|
27
|
|
|
class AdminExtension extends Twig_Extension |
|
28
|
|
|
{ |
|
29
|
|
|
use TranslationKeyTrait; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @var ApplicationConfiguration |
|
33
|
|
|
*/ |
|
34
|
|
|
protected $configuration; |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* @var RouterInterface |
|
38
|
|
|
*/ |
|
39
|
|
|
protected $router; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* @var TranslatorInterface |
|
43
|
|
|
*/ |
|
44
|
|
|
protected $translator; |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* @var Twig_Environment |
|
48
|
|
|
*/ |
|
49
|
|
|
protected $twig; |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* AdminExtension constructor. |
|
53
|
|
|
* |
|
54
|
|
|
* @param RouterInterface $router |
|
55
|
|
|
* @param TranslatorInterface $translator |
|
56
|
|
|
* @param ConfigurationFactory $configurationFactory |
|
57
|
|
|
* @param Twig_Environment $twig |
|
58
|
|
|
*/ |
|
59
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
|
|
60
|
|
|
RouterInterface $router, |
|
61
|
|
|
TranslatorInterface $translator, |
|
62
|
|
|
ConfigurationFactory $configurationFactory, |
|
63
|
|
|
Twig_Environment $twig |
|
64
|
|
|
) { |
|
65
|
|
|
$this->router = $router; |
|
66
|
|
|
$this->translator = $translator; |
|
67
|
|
|
$this->configuration = $configurationFactory->getApplicationConfiguration(); |
|
68
|
|
|
$this->twig = $twig; |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
/** |
|
72
|
|
|
* @return array |
|
73
|
|
|
*/ |
|
74
|
|
|
public function getFunctions() |
|
75
|
|
|
{ |
|
76
|
|
|
return [ |
|
77
|
|
|
new Twig_SimpleFunction('getSortColumnUrl', [$this, 'getSortColumnUrl']), |
|
78
|
|
|
new Twig_SimpleFunction('getSortColumnIconClass', [$this, 'getSortColumnIconClass']), |
|
79
|
|
|
new Twig_SimpleFunction('field', [$this, 'field']), |
|
80
|
|
|
new Twig_SimpleFunction('field_title', [$this, 'fieldTitle']), |
|
81
|
|
|
new Twig_SimpleFunction('route_parameters', [$this, 'routeParameters']), |
|
82
|
|
|
new Twig_SimpleFunction('function_exists', [$this, 'functionExists']), |
|
83
|
|
|
]; |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
/** |
|
87
|
|
|
* @return array |
|
88
|
|
|
*/ |
|
89
|
|
|
public function getFilters() |
|
90
|
|
|
{ |
|
91
|
|
|
return [ |
|
92
|
|
|
new Twig_SimpleFilter('camelize', [$this, 'camelize']), |
|
93
|
|
|
]; |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* Return sort column url, with existing request parameters, according to field name. |
|
98
|
|
|
* |
|
99
|
|
|
* @param Request $request |
|
100
|
|
|
* @param $fieldName |
|
101
|
|
|
* |
|
102
|
|
|
* @return string |
|
103
|
|
|
*/ |
|
104
|
|
|
public function getSortColumnUrl(Request $request, $fieldName) |
|
105
|
|
|
{ |
|
106
|
|
|
// get query string to not delete existing parameters |
|
107
|
|
|
$queryString = $request->query->all(); |
|
108
|
|
|
$queryString['sort'] = $fieldName; |
|
109
|
|
|
|
|
110
|
|
|
if (array_key_exists('order', $queryString)) { |
|
111
|
|
|
// sort by opposite sorting than current |
|
112
|
|
|
$sort = $queryString['order'] == 'ASC' ? 'DESC' : 'ASC'; |
|
113
|
|
|
$queryString['order'] = $sort; |
|
114
|
|
|
} else { |
|
115
|
|
|
// if no order was provided, it means that list is sorted by default order (ASC), so we must sort by DESC |
|
116
|
|
|
$queryString['order'] = 'DESC'; |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
return $this |
|
120
|
|
|
->router |
|
121
|
|
|
->generate($request->get('_route'), $queryString); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
/** |
|
125
|
|
|
* Return an array of query string parameters, updated with sort field name. |
|
126
|
|
|
* |
|
127
|
|
|
* @param ParameterBagInterface $parameters |
|
128
|
|
|
* @param $fieldName |
|
129
|
|
|
* |
|
130
|
|
|
* @return array |
|
131
|
|
|
*/ |
|
132
|
|
|
public function getOrderQueryString(ParameterBagInterface $parameters, $fieldName) |
|
133
|
|
|
{ |
|
134
|
|
|
$parameters->set('sort', $fieldName); |
|
135
|
|
|
|
|
136
|
|
|
if ($parameters->has('order')) { |
|
137
|
|
|
// sort by opposite order |
|
138
|
|
|
$order = $parameters->get('order') == 'ASC' ? 'DESC' : 'ASC'; |
|
139
|
|
|
$parameters->set('order', $order); |
|
140
|
|
|
} else { |
|
141
|
|
|
// if no order was provided, it means that list is sorted by default order (ASC), so we must sort by DESC |
|
142
|
|
|
$parameters->set('order', 'DESC'); |
|
143
|
|
|
} |
|
144
|
|
|
return $parameters->all(); |
|
145
|
|
|
} |
|
146
|
|
|
|
|
147
|
|
|
/** |
|
148
|
|
|
* @param null $order |
|
149
|
|
|
* @param $fieldName |
|
150
|
|
|
* @param $sort |
|
151
|
|
|
* |
|
152
|
|
|
* @return string |
|
153
|
|
|
*/ |
|
154
|
|
|
public function getSortColumnIconClass($order = null, $fieldName, $sort) |
|
155
|
|
|
{ |
|
156
|
|
|
// when no order is provided, no icon should be displayed |
|
157
|
|
|
$class = ''; |
|
158
|
|
|
|
|
159
|
|
|
if ($fieldName == $sort) { |
|
160
|
|
|
if ($order == 'ASC') { |
|
161
|
|
|
$class = 'fa fa-sort-asc'; |
|
162
|
|
|
} elseif ($order == 'DESC') { |
|
163
|
|
|
$class = 'fa fa-sort-desc'; |
|
164
|
|
|
} |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
return $class; |
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
|
/** |
|
171
|
|
|
* Render a field of an entity. |
|
172
|
|
|
* |
|
173
|
|
|
* @param FieldInterface $field |
|
174
|
|
|
* @param $entity |
|
175
|
|
|
* |
|
176
|
|
|
* @return string |
|
177
|
|
|
*/ |
|
178
|
|
|
public function field(FieldInterface $field, $entity) |
|
179
|
|
|
{ |
|
180
|
|
|
$accessor = PropertyAccess::createPropertyAccessorBuilder() |
|
181
|
|
|
->enableMagicCall() |
|
182
|
|
|
->getPropertyAccessor(); |
|
183
|
|
|
$value = null; |
|
184
|
|
|
|
|
185
|
|
|
// if name starts with a underscore, it is a custom field, not mapped to the entity |
|
186
|
|
View Code Duplication |
if (substr($field->getName(), 0, 1) != '_') { |
|
187
|
|
|
// get raw value from object |
|
188
|
|
|
$value = $accessor->getValue($entity, $field->getName()); |
|
189
|
|
|
} |
|
190
|
|
|
if ($field instanceof EntityFieldInterface) { |
|
191
|
|
|
$field->setEntity($entity); |
|
192
|
|
|
} |
|
193
|
|
|
$render = $field->render($value); |
|
194
|
|
|
|
|
195
|
|
|
return $render; |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
/** |
|
199
|
|
|
* Return a the title of the field, camelized or translated. |
|
200
|
|
|
* |
|
201
|
|
|
* @param $fieldName |
|
202
|
|
|
* @param null $adminName |
|
203
|
|
|
* |
|
204
|
|
|
* @return string |
|
205
|
|
|
*/ |
|
206
|
|
|
public function fieldTitle($fieldName, $adminName = null) |
|
207
|
|
|
{ |
|
208
|
|
|
if ($this->configuration->getParameter('translation')['enabled']) { |
|
209
|
|
|
$title = $this |
|
210
|
|
|
->translator |
|
211
|
|
|
->trans($this->getTranslationKey($this->configuration->getParameter('translation')['pattern'], $fieldName, $adminName)); |
|
212
|
|
|
} else { |
|
213
|
|
|
$title = $this->camelize($fieldName); |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
return $title; |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
|
|
/** |
|
220
|
|
|
* @param array $parameters |
|
221
|
|
|
* @param $entity |
|
222
|
|
|
* |
|
223
|
|
|
* @return array |
|
224
|
|
|
*/ |
|
225
|
|
|
public function routeParameters(array $parameters, $entity) |
|
226
|
|
|
{ |
|
227
|
|
|
$accessor = PropertyAccess::createPropertyAccessor(); |
|
228
|
|
|
$routeParameters = []; |
|
229
|
|
|
|
|
230
|
|
|
foreach ($parameters as $parameterName => $fieldName) { |
|
231
|
|
|
if (is_array($fieldName) && !count($fieldName)) { |
|
232
|
|
|
$fieldName = $parameterName; |
|
233
|
|
|
} |
|
234
|
|
|
$routeParameters[$parameterName] = $accessor->getValue($entity, $fieldName); |
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
return $routeParameters; |
|
238
|
|
|
} |
|
239
|
|
|
|
|
240
|
|
|
/** |
|
241
|
|
|
* Camelize a string (using Container camelize method) |
|
242
|
|
|
* |
|
243
|
|
|
* @param $string |
|
244
|
|
|
* |
|
245
|
|
|
* @return string |
|
246
|
|
|
*/ |
|
247
|
|
|
public function camelize($string) |
|
248
|
|
|
{ |
|
249
|
|
|
return Container::camelize($string); |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
/** |
|
253
|
|
|
* Returns the name of the extension. |
|
254
|
|
|
* |
|
255
|
|
|
* @return string The extension name |
|
256
|
|
|
*/ |
|
257
|
|
|
public function getName() |
|
258
|
|
|
{ |
|
259
|
|
|
return 'lag.admin'; |
|
260
|
|
|
} |
|
261
|
|
|
|
|
262
|
|
|
/** |
|
263
|
|
|
* Return true if the method exists in twig. |
|
264
|
|
|
* |
|
265
|
|
|
* @param string $functionName |
|
266
|
|
|
* |
|
267
|
|
|
* @return bool |
|
268
|
|
|
*/ |
|
269
|
|
|
public function functionExists($functionName) |
|
270
|
|
|
{ |
|
271
|
|
|
return false !== $this |
|
272
|
|
|
->twig |
|
273
|
|
|
->getFunction($functionName); |
|
274
|
|
|
} |
|
275
|
|
|
} |
|
276
|
|
|
|
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.