These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the Blast Project package. |
||
5 | * |
||
6 | * Copyright (C) 2015-2017 Libre Informatique |
||
7 | * |
||
8 | * This file is licenced under the GNU LGPL v3. |
||
9 | * For the full copyright and license information, please view the LICENSE.md |
||
10 | * file that was distributed with this source code. |
||
11 | */ |
||
12 | |||
13 | namespace Blast\CoreBundle\Admin; |
||
14 | |||
15 | use Sonata\AdminBundle\Datagrid\DatagridMapper; |
||
16 | use Sonata\AdminBundle\Datagrid\ListMapper; |
||
17 | use Sonata\AdminBundle\Form\FormMapper; |
||
18 | use Sonata\AdminBundle\Mapper\BaseMapper; |
||
19 | use Sonata\AdminBundle\Show\ShowMapper; |
||
20 | use Sonata\AdminBundle\Route\RouteCollection; |
||
21 | use Sonata\AdminBundle\Admin\AbstractAdmin as SonataAdmin; |
||
22 | use Sonata\DoctrineORMAdminBundle\Admin\FieldDescription; |
||
23 | use Blast\CoreBundle\Tools\Reflection\ClassAnalyzer; |
||
24 | use Blast\CoreBundle\Admin\Traits\CollectionsManager; |
||
25 | use Blast\CoreBundle\Admin\Traits\Mapper; |
||
26 | use Blast\CoreBundle\Admin\Traits\Templates; |
||
27 | use Blast\CoreBundle\Admin\Traits\PreEvents; |
||
28 | use Blast\CoreBundle\Admin\Traits\ManyToManyManager; |
||
29 | use Blast\CoreBundle\Admin\Traits\Actions; |
||
30 | use Blast\CoreBundle\Admin\Traits\ListActions; |
||
31 | use Blast\CoreBundle\CodeGenerator\CodeGeneratorRegistry; |
||
32 | use Symfony\Component\PropertyAccess\PropertyAccess; |
||
33 | |||
34 | abstract class CoreAdmin extends SonataAdmin implements \JsonSerializable |
||
35 | { |
||
36 | use CollectionsManager, |
||
37 | ManyToManyManager, |
||
38 | Mapper, |
||
39 | Templates, |
||
40 | PreEvents, |
||
41 | Actions, |
||
42 | ListActions |
||
43 | ; |
||
44 | |||
45 | protected $extraTemplates = []; |
||
46 | |||
47 | /** |
||
48 | * Configure routes for list actions. |
||
49 | * |
||
50 | * @param RouteCollection $collection |
||
51 | */ |
||
52 | protected function configureRoutes(RouteCollection $collection) |
||
53 | { |
||
54 | parent::configureRoutes($collection); |
||
55 | $collection->add('duplicate', $this->getRouterIdParameter() . '/duplicate'); |
||
56 | $collection->add('generateEntityCode'); |
||
57 | } |
||
58 | |||
59 | View Code Duplication | public function getBaseRouteName() |
|
0 ignored issues
–
show
|
|||
60 | { |
||
61 | $configuredBaseRoute = $this->getBaseRouteMapping(); |
||
62 | |||
63 | if (count($configuredBaseRoute) > 0) { |
||
64 | $this->cachedBaseRouteName = null; |
||
65 | if (isset($configuredBaseRoute['name']) && $this->baseRouteName === null) { |
||
66 | $this->baseRouteName = $configuredBaseRoute['name']; |
||
67 | } |
||
68 | } |
||
69 | |||
70 | return parent::getBaseRouteName(); |
||
71 | } |
||
72 | |||
73 | View Code Duplication | public function getBaseRoutePattern() |
|
0 ignored issues
–
show
This method seems to be duplicated in 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...
|
|||
74 | { |
||
75 | $configuredBaseRoute = $this->getBaseRouteMapping(); |
||
76 | |||
77 | if (count($configuredBaseRoute) > 0) { |
||
78 | $this->cachedBaseRoutePattern = null; |
||
79 | if (isset($configuredBaseRoute['pattern']) && $this->baseRoutePattern === null) { |
||
80 | $this->baseRoutePattern = $configuredBaseRoute['pattern']; |
||
81 | } |
||
82 | } |
||
83 | |||
84 | return parent::getBaseRoutePattern(); |
||
85 | } |
||
86 | |||
87 | public function getFormTheme() |
||
88 | { |
||
89 | return array_merge($this->formTheme, $this->getFormThemeMapping()); |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * @param DatagridMapper $mapper |
||
94 | */ |
||
95 | protected function configureDatagridFilters(DatagridMapper $mapper) |
||
96 | { |
||
97 | if (!$this->configureMapper($mapper)) { |
||
98 | $this->fallbackConfiguration($mapper, __FUNCTION__); |
||
99 | } |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * @param ListMapper $mapper |
||
104 | */ |
||
105 | protected function configureListFields(ListMapper $mapper) |
||
106 | { |
||
107 | if (!$this->configureMapper($mapper)) { |
||
108 | $this->fallbackConfiguration($mapper, __FUNCTION__); |
||
109 | } |
||
110 | } |
||
111 | |||
112 | /** |
||
113 | * @param FormMapper $mapper |
||
114 | */ |
||
115 | protected function configureFormFields(FormMapper $mapper) |
||
116 | { |
||
117 | if (!$this->configureMapper($mapper)) { |
||
118 | $this->fallbackConfiguration($mapper, __FUNCTION__); |
||
119 | } |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * @param ShowMapper $mapper |
||
124 | */ |
||
125 | protected function configureShowFields(ShowMapper $mapper) |
||
126 | { |
||
127 | if (!$this->configureMapper($mapper)) { |
||
128 | $this->fallbackConfiguration($mapper, __FUNCTION__); |
||
129 | } |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * @param BaseMapper $mapper |
||
134 | */ |
||
135 | protected function fixShowRoutes(BaseMapper $mapper) |
||
136 | { |
||
137 | foreach (['getShow', 'getList'] as $fct) { |
||
138 | foreach ($this->$fct()->getElements() as $field) { |
||
139 | if ($field instanceof FieldDescription) { |
||
140 | $options = $field->getOptions(); |
||
141 | if ($options['route']['name'] != 'edit') { |
||
142 | continue; |
||
143 | } |
||
144 | |||
145 | $options['route']['name'] = 'show'; |
||
146 | $field->setOptions($options); |
||
147 | } |
||
148 | } |
||
149 | } |
||
150 | |||
151 | return $this; |
||
152 | } |
||
153 | |||
154 | protected function getCurrentComposition() |
||
155 | { |
||
156 | // traits of the current Entity |
||
157 | $classes = ClassAnalyzer::getTraits($this->getClass()); |
||
158 | // inheritance of the current Entity |
||
159 | foreach (array_reverse([$this->getClass()] + class_parents($this->getClass())) as $class) { |
||
160 | $classes[] = $class; |
||
161 | } |
||
162 | // inheritance of the current Admin |
||
163 | foreach (array_reverse([$this->getOriginalClass()] + $this->getParentClasses()) as $admin) { |
||
164 | $classes[] = $admin; |
||
165 | } |
||
166 | |||
167 | return $classes; |
||
168 | } |
||
169 | |||
170 | private function fallbackConfiguration(BaseMapper $mapper, $function) |
||
171 | { |
||
172 | // fallback |
||
173 | $rm = new \ReflectionMethod($this->getParentClass(), $function); |
||
174 | if ($rm->class == $this->getParentClass()) { |
||
175 | $this->configureFields($function, $mapper, $this->getParentClass()); |
||
176 | } |
||
177 | } |
||
178 | |||
179 | /** |
||
180 | * Returns the level of depth of an array. |
||
181 | * |
||
182 | * @param array $array |
||
183 | * @param int $level : do not use, just used for recursivity |
||
184 | * |
||
185 | * @return int : depth |
||
186 | */ |
||
187 | private static function arrayDepth($array, $level = 0) |
||
188 | { |
||
189 | if (!$array) { |
||
190 | return $level; |
||
191 | } |
||
192 | |||
193 | if (!is_array($array)) { |
||
194 | return $level; |
||
195 | } |
||
196 | |||
197 | ++$level; |
||
198 | foreach ($array as $key => $value) { |
||
199 | if (is_array($value)) { |
||
200 | $level = $level < self::arrayDepth($value, $level) ? self::arrayDepth($value, $level) : $level; |
||
201 | } |
||
202 | } |
||
203 | |||
204 | return $level; |
||
205 | } |
||
206 | |||
207 | protected function getOriginalClass() |
||
208 | { |
||
209 | return get_called_class(); |
||
210 | } |
||
211 | |||
212 | protected function getParentClasses() |
||
213 | { |
||
214 | return class_parents($this->getOriginalClass()); |
||
215 | } |
||
216 | |||
217 | protected function getParentClass() |
||
218 | { |
||
219 | return get_parent_class($this->getOriginalClass()); |
||
220 | } |
||
221 | |||
222 | protected function getGrandParentClass() |
||
223 | { |
||
224 | return get_parent_class(get_parent_class($this->getOriginalClass())); |
||
225 | } |
||
226 | |||
227 | /** |
||
228 | * @param string $view 'list', 'show', 'form', etc |
||
229 | * @param string $template template name |
||
230 | */ |
||
231 | public function addExtraTemplate($view, $template) |
||
232 | { |
||
233 | if (empty($this->extraTemplates[$view])) { |
||
234 | $this->extraTemplates[$view] = []; |
||
235 | } |
||
236 | if (!in_array($template, $this->extraTemplates[$view])) { |
||
237 | $this->extraTemplates[$view][] = $template; |
||
238 | } |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * @param string $view 'list', 'show', 'form', etc |
||
243 | * |
||
244 | * @return array array of template names |
||
245 | */ |
||
246 | public function getExtraTemplates($view) |
||
247 | { |
||
248 | if (empty($this->extraTemplates[$view])) { |
||
249 | $this->extraTemplates[$view] = []; |
||
250 | } |
||
251 | |||
252 | return $this->extraTemplates[$view]; |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * @param string $view 'list', 'show', 'form', etc |
||
257 | * @param array $link link (array keys should be: 'label', 'url', 'class', 'title') |
||
258 | */ |
||
259 | public function addHelperLink($view, $link) |
||
260 | { |
||
261 | if (empty($this->helperLinks[$view])) { |
||
262 | $this->helperLinks[$view] = []; |
||
263 | } |
||
264 | |||
265 | // Do not add links without URL |
||
266 | if (empty($link['url'])) { |
||
267 | return; |
||
268 | } |
||
269 | |||
270 | // Do not add two links with the same URL |
||
271 | foreach ($this->helperLinks[$view] as $l) { |
||
272 | if ($l['url'] == $link['url']) { |
||
273 | return; |
||
274 | } |
||
275 | } |
||
276 | |||
277 | $this->helperLinks[$view][] = $link; |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * @param string $view 'list', 'show', 'form', etc |
||
282 | * |
||
283 | * @return array array of links (each link is an array with keys 'label', 'url', 'class' and 'title') |
||
284 | */ |
||
285 | public function getHelperLinks($view) |
||
286 | { |
||
287 | if (empty($this->helperLinks[$view])) { |
||
288 | $this->helperLinks[$view] = []; |
||
289 | } |
||
290 | |||
291 | return $this->helperLinks[$view]; |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Checks if a Bundle is installed. |
||
296 | * |
||
297 | * @param string $bundle Bundle name or class FQN |
||
298 | */ |
||
299 | public function bundleExists($bundle) |
||
300 | { |
||
301 | $kernelBundles = $this->getConfigurationPool()->getContainer()->getParameter('kernel.bundles'); |
||
302 | if (array_key_exists($bundle, $kernelBundles)) { |
||
303 | return true; |
||
304 | } |
||
305 | if (in_array($bundle, $kernelBundles)) { |
||
306 | return true; |
||
307 | } |
||
308 | |||
309 | return false; |
||
310 | } |
||
311 | |||
312 | /** |
||
313 | * Rename a form tab after form fields have been configured. |
||
314 | * |
||
315 | * TODO: groups of the renamed tab are still prefixed with the old tab name |
||
316 | * |
||
317 | * @param type $tabName the name of the tab to be renamed |
||
318 | * @param type $newTabName the new name for the tab |
||
319 | */ |
||
320 | View Code Duplication | public function renameFormTab($tabName, $newTabName, $keepOrder = true) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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...
|
|||
321 | { |
||
322 | $tabs = $this->getFormTabs(); |
||
323 | |||
324 | if (!$tabs) { |
||
325 | return; |
||
326 | } |
||
327 | |||
328 | if (!isset($tabs[$tabName])) { |
||
329 | throw new \Exception(sprintf('Tab %s does not exist.', $tabName)); |
||
330 | } |
||
331 | if (isset($tabs[$newTabName])) { |
||
332 | return; |
||
333 | } |
||
334 | |||
335 | if ($keepOrder) { |
||
336 | $keys = array_keys($tabs); |
||
337 | $keys[array_search($tabName, $keys)] = $newTabName; |
||
338 | $tabs = array_combine($keys, $tabs); |
||
339 | } else { |
||
340 | $tabs[$newTabName] = $tabs[$tabName]; |
||
341 | unset($tabs[$tabName]); |
||
342 | } |
||
343 | |||
344 | $this->setFormTabs($tabs); |
||
345 | } |
||
346 | |||
347 | /** |
||
348 | * Rename a show tab after show fields have been configured. |
||
349 | * |
||
350 | * TODO: groups of the renamed tab are still prefixed with the old tab name |
||
351 | * |
||
352 | * @param type $tabName the name of the tab to be renamed |
||
353 | * @param type $newTabName the new name for the tab |
||
354 | */ |
||
355 | View Code Duplication | public function renameShowTab($tabName, $newTabName, $keepOrder = true) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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...
|
|||
356 | { |
||
357 | $tabs = $this->getShowTabs(); |
||
358 | |||
359 | if (!$tabs) { |
||
360 | return; |
||
361 | } |
||
362 | |||
363 | if (!isset($tabs[$tabName])) { |
||
364 | throw new \Exception(sprintf('Tab %s does not exist.', $tabName)); |
||
365 | } |
||
366 | if (isset($tabs[$newTabName])) { |
||
367 | return; |
||
368 | } |
||
369 | |||
370 | if ($keepOrder) { |
||
371 | $keys = array_keys($tabs); |
||
372 | $keys[array_search($tabName, $keys)] = $newTabName; |
||
373 | $tabs = array_combine($keys, $tabs); |
||
374 | } else { |
||
375 | $tabs[$newTabName] = $tabs[$tabName]; |
||
376 | unset($tabs[$tabName]); |
||
377 | } |
||
378 | |||
379 | $this->setShowTabs($tabs); |
||
380 | } |
||
381 | |||
382 | /** |
||
383 | * Rename a form group. |
||
384 | * |
||
385 | * @param string $group the old group name |
||
386 | * @param string $tab the tab the group belongs to |
||
387 | * @param string $newGroupName the new group name |
||
388 | * |
||
389 | * @return self |
||
390 | */ |
||
391 | public function renameFormGroup($group, $tab, $newGroupName) |
||
392 | { |
||
393 | $groups = $this->getFormGroups(); |
||
394 | |||
395 | // When the default tab is used, the tabname is not prepended to the index in the group array |
||
396 | if ($tab !== 'default') { |
||
397 | $group = $tab . '.' . $group; |
||
398 | } |
||
399 | $newGroup = ($tab !== 'default') ? $tab . '.' . $newGroupName : $newGroupName; |
||
400 | |||
401 | if (isset($groups[$newGroup])) { |
||
402 | throw new \Exception(sprintf('%s form group already exists.', $newGroup)); |
||
403 | } |
||
404 | if (!array_key_exists($group, $groups)) { |
||
405 | throw new \Exception(sprintf('form group « %s » doesn\'t exist.', $group)); |
||
406 | } |
||
407 | |||
408 | $groups[$newGroup] = $groups[$group]; |
||
409 | $groups[$newGroup]['name'] = $newGroupName; |
||
410 | unset($groups[$group]); |
||
411 | |||
412 | $tabs = $this->getFormTabs(); |
||
413 | $key = array_search($group, $tabs[$tab]['groups']); |
||
414 | |||
415 | if (false !== $key) { |
||
416 | $tabs[$tab]['groups'][$key] = $newGroup; |
||
417 | } |
||
418 | |||
419 | $this->setFormTabs($tabs); |
||
420 | $this->setFormGroups($groups); |
||
421 | |||
422 | return $this; |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * Removes tab in current form Mapper. |
||
427 | * |
||
428 | * @param string|array $tabNames name or array of names of tabs to be removed |
||
429 | * @param FormMapper $mapper Sonata Admin form mapper |
||
430 | */ |
||
431 | public function removeTab($tabNames, $mapper) |
||
432 | { |
||
433 | $currentTabs = $this->getFormTabs(); |
||
434 | foreach ($currentTabs as $k => $item) { |
||
435 | if (is_array($tabNames) && in_array($item['name'], $tabNames) || !is_array($tabNames) && $item['name'] === $tabNames) { |
||
436 | foreach ($item['groups'] as $groupName) { |
||
437 | $this->removeAllFieldsFromFormGroup($groupName, $mapper); |
||
438 | } |
||
439 | unset($currentTabs[$k]); |
||
440 | } |
||
441 | } |
||
442 | $this->setFormTabs($currentTabs); |
||
443 | } |
||
444 | |||
445 | /** |
||
446 | * Removes all fields from form groups and remove them from mapper. |
||
447 | * |
||
448 | * @param string $groupName Name of the group to remove |
||
449 | * @param FormMapper $mapper Sonata Admin form mapper |
||
450 | */ |
||
451 | public function removeAllFieldsFromFormGroup($groupName, $mapper) |
||
452 | { |
||
453 | $formGroups = $this->getFormGroups(); |
||
454 | foreach ($formGroups as $name => $formGroup) { |
||
455 | if ($name === $groupName) { |
||
456 | foreach ($formGroups[$name]['fields'] as $key => $field) { |
||
457 | $mapper->remove($key); |
||
458 | } |
||
459 | } |
||
460 | } |
||
461 | } |
||
462 | |||
463 | public function jsonSerialize() |
||
464 | { |
||
465 | $propertiesToShow = [ |
||
466 | 'baseRouteName', |
||
467 | 'baseRoutePattern', |
||
468 | 'extraTemplates', |
||
469 | 'listFieldDescriptions', |
||
470 | 'showFieldDescriptions', |
||
471 | 'formFieldDescriptions', |
||
472 | 'filterFieldDescriptions', |
||
473 | 'maxPerPage', |
||
474 | 'maxPageLinks', |
||
475 | 'classnameLabel', |
||
476 | 'translationDomain', |
||
477 | 'formOptions', |
||
478 | 'datagridValues', |
||
479 | 'perPageOptions', |
||
480 | 'pagerType', |
||
481 | 'code', |
||
482 | 'label', |
||
483 | 'routes', |
||
484 | 'subject', |
||
485 | 'children', |
||
486 | 'parent', |
||
487 | 'baseCodeRoute', |
||
488 | 'uniqid', |
||
489 | 'extensions', |
||
490 | 'class', |
||
491 | 'subClasses', |
||
492 | 'list', |
||
493 | 'show', |
||
494 | 'form', |
||
495 | 'filter', |
||
496 | 'formGroups', |
||
497 | 'formTabs', |
||
498 | 'showGroups', |
||
499 | 'showTabs', |
||
500 | 'managedCollections', |
||
501 | 'helperLinks', |
||
502 | 'titles', |
||
503 | ]; |
||
504 | |||
505 | $properties = []; |
||
506 | foreach ($this as $key => $value) { |
||
507 | if (in_array($key, $propertiesToShow)) { |
||
508 | $properties[$key] = $value; |
||
509 | } |
||
510 | } |
||
511 | |||
512 | return $properties; |
||
513 | } |
||
514 | |||
515 | /** |
||
516 | * {@inheritdoc} |
||
517 | */ |
||
518 | public function prePersist($object) |
||
519 | { |
||
520 | parent::prePersist($object); |
||
521 | |||
522 | $hasCodeGenerator = CodeGeneratorRegistry::hasGeneratorForClass(get_class($object)); |
||
523 | if ($hasCodeGenerator) { |
||
524 | $accessor = PropertyAccess::createPropertyAccessor(); |
||
525 | foreach (CodeGeneratorRegistry::getCodeGenerators(get_class($object)) as $name => $generator) { |
||
526 | $accessor->setValue($object, $name, $generator->generate($object)); |
||
527 | } |
||
528 | } |
||
529 | } |
||
530 | } |
||
531 |
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.