This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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\Traits; |
||
14 | |||
15 | use Sonata\AdminBundle\Datagrid\ListMapper; |
||
16 | use Sonata\AdminBundle\Form\FormMapper; |
||
17 | use Sonata\AdminBundle\Mapper\BaseGroupedMapper; |
||
18 | use Sonata\AdminBundle\Mapper\BaseMapper; |
||
19 | use Sonata\AdminBundle\Show\ShowMapper; |
||
20 | use Symfony\Component\Validator\Constraints\NotBlank; |
||
21 | use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; |
||
22 | use Exception; |
||
23 | |||
24 | trait Mapper |
||
25 | { |
||
26 | /** |
||
27 | * Force tabulations on Show views. |
||
28 | * |
||
29 | * @var bool |
||
30 | */ |
||
31 | protected $forceTabs = false; |
||
32 | |||
33 | /** |
||
34 | * Links in the view navbar. |
||
35 | * |
||
36 | * @var array |
||
37 | */ |
||
38 | protected $helperLinks = []; |
||
39 | |||
40 | /** |
||
41 | * Admin titles (for list, show, edit and create). |
||
42 | * |
||
43 | * @var string |
||
44 | */ |
||
45 | public $titles = []; |
||
46 | |||
47 | /** |
||
48 | * Admin title templates (for list, show, edit and create). |
||
49 | * |
||
50 | * @var array |
||
51 | */ |
||
52 | public $titleTemplates = []; |
||
53 | |||
54 | protected function configureMapper(BaseMapper $mapper) |
||
55 | { |
||
56 | $classes = $this->getCurrentComposition(); |
||
0 ignored issues
–
show
|
|||
57 | $blast = $this |
||
58 | ->getConfigurationPool() |
||
59 | ->getContainer() |
||
60 | ->getParameter('blast') |
||
61 | ; |
||
62 | $this |
||
63 | ->getConfigurationPool() |
||
64 | ->getContainer() |
||
65 | ->get('logger') |
||
66 | ->debug(sprintf( |
||
67 | '[BlastCoreBundle] Processing the configuration in this order: %s', |
||
68 | implode(', ', $classes) |
||
69 | )) |
||
70 | ; |
||
71 | |||
72 | $fcts = [ |
||
73 | 'tabs' => $mapper instanceof ShowMapper ? |
||
74 | ['getter' => 'getShowTabs', 'setter' => 'setShowTabs'] : |
||
75 | ['getter' => 'getFormTabs', 'setter' => 'setFormTabs'], |
||
76 | 'groups' => $mapper instanceof ShowMapper ? |
||
77 | ['getter' => 'getShowGroups', 'setter' => 'setShowGroups'] : |
||
78 | ['getter' => 'getFormGroups', 'setter' => 'setFormGroups'], |
||
79 | ]; |
||
80 | |||
81 | // Figure out if we have to display tabs on the Show view |
||
82 | $this->forceTabs = false; |
||
83 | if ($mapper instanceof ShowMapper) { |
||
84 | foreach ($classes as $class) { |
||
85 | if (isset($blast[$class])) { |
||
86 | foreach (array_reverse($list = array_merge([get_class($mapper)], array_values(class_parents($mapper)))) as $mapper_class) { |
||
87 | if (!empty($blast[$class][$mapper_class]['forceTabs'])) { |
||
88 | $this->forceTabs = true; |
||
89 | } |
||
90 | } |
||
91 | } |
||
92 | } |
||
93 | } |
||
94 | |||
95 | // builds the configuration, based on the Mapper class |
||
96 | foreach ($classes as $class) { |
||
97 | if (!isset($blast[$class])) { |
||
98 | continue; |
||
99 | } |
||
100 | |||
101 | // copy stuff from elsewhere |
||
102 | foreach (array_reverse($list = array_merge([get_class($mapper)], array_values(class_parents($mapper)))) as $mapper_class) { |
||
103 | if (isset($blast[$class][$mapper_class]) && !empty($blast[$class][$mapper_class]['_copy'])) { |
||
104 | if (!is_array($blast[$class][$mapper_class]['_copy'])) { |
||
105 | $blast[$class][$mapper_class]['_copy'] = [$blast[$class][$mapper_class]['_copy']]; |
||
106 | } |
||
107 | foreach ($blast[$class][$mapper_class]['_copy'] as $copy) { |
||
108 | $list = array_merge( |
||
109 | $list, array_merge([$copy], array_values(class_parents($copy))) |
||
110 | ); |
||
111 | } |
||
112 | } |
||
113 | } |
||
114 | |||
115 | $specialKeys = ['_actions', '_list_actions', '_batch_actions', '_export_formats', '_extra_templates', '_helper_links']; |
||
116 | |||
117 | // process data... |
||
118 | foreach (array_reverse($list) as $mapper_class) { |
||
119 | if (!isset($blast[$class][$mapper_class])) { |
||
120 | continue; |
||
121 | } |
||
122 | |||
123 | // remove fields |
||
124 | if (isset($blast[$class][$mapper_class]['remove'])) { |
||
125 | View Code Duplication | if (isset($blast['all'][$mapper_class]['remove'])) { |
|
126 | $blast[$class][$mapper_class]['remove'] = array_merge_recursive( |
||
127 | $blast[$class][$mapper_class]['remove'], |
||
128 | $blast['all'][$mapper_class]['remove'] |
||
129 | ); |
||
130 | } |
||
131 | |||
132 | foreach ($blast[$class][$mapper_class]['remove'] as $key => $field) { |
||
133 | if (in_array($key, $specialKeys)) { |
||
134 | continue; |
||
135 | } |
||
136 | |||
137 | if ($mapper->has($key)) { |
||
138 | $mapper->remove($key); |
||
139 | |||
140 | // compensating the partial removal in Sonata Admin, that does not touch the groups when removing a field |
||
141 | View Code Duplication | if ($mapper instanceof BaseGroupedMapper) { |
|
142 | foreach ($groups = $this->{$fcts['groups']['getter']}() as $groupkey => $group) { |
||
143 | if (isset($group['fields'][$key])) { |
||
144 | unset($groups[$groupkey]['fields'][$key]); |
||
145 | if (!$groups[$groupkey]['fields']) { |
||
146 | unset($groups[$groupkey]); |
||
147 | } |
||
148 | $this->{$fcts['groups']['setter']}($groups); |
||
149 | } |
||
150 | } |
||
151 | } |
||
152 | } |
||
153 | } |
||
154 | } |
||
155 | |||
156 | // add fields & more |
||
157 | if (isset($blast[$class][$mapper_class]['add'])) { |
||
158 | View Code Duplication | if (isset($blast['all'][$mapper_class]['add'])) { |
|
159 | $blast[$class][$mapper_class]['add'] = array_merge( |
||
160 | $blast[$class][$mapper_class]['add'], |
||
161 | $blast['all'][$mapper_class]['add'] |
||
162 | ); |
||
163 | } |
||
164 | |||
165 | // do not parse _batch_actions & co |
||
166 | foreach ($specialKeys as $sk) { |
||
167 | View Code Duplication | if (isset($blast[$class][$mapper_class]['add'][$sk])) { |
|
168 | unset($blast[$class][$mapper_class]['add'][$sk]); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | $this->addContent($mapper, $blast[$class][$mapper_class]['add']); |
||
173 | } |
||
174 | |||
175 | // set Admin titles |
||
176 | $titleTemplate = isset($blast[$class][$mapper_class]['titleTemplate']) ? $blast[$class][$mapper_class]['titleTemplate'] : null; |
||
177 | $title = isset($blast[$class][$mapper_class]['title']) ? $blast[$class][$mapper_class]['title'] : null; |
||
178 | $this->setTitles($mapper, $titleTemplate, $title); |
||
179 | } |
||
180 | } |
||
181 | |||
182 | if ($mapper instanceof BaseGroupedMapper) { // ShowMapper and FormMapper |
||
183 | // removing empty groups |
||
184 | $groups = $this->{$fcts['groups']['getter']}(); |
||
185 | if (is_array($groups)) { |
||
186 | foreach ($groups as $groupkey => $group) { |
||
187 | if (!$group['fields']) { |
||
188 | unset($groups[$groupkey]); |
||
189 | } |
||
190 | } |
||
191 | $this->{$fcts['groups']['setter']}($groups); |
||
192 | } |
||
193 | |||
194 | // removing empty tabs |
||
195 | $tabs = $this->{$fcts['tabs']['getter']}(); |
||
196 | View Code Duplication | if (is_array($tabs)) { |
|
197 | foreach ($tabs as $tabkey => $tab) { |
||
198 | foreach ($tab['groups'] as $groupkey => $group) { |
||
199 | if (!isset($this->{$fcts['groups']['getter']}()[$group])) { |
||
200 | unset($tabs[$tabkey]['groups'][$groupkey]); |
||
201 | } |
||
202 | } |
||
203 | |||
204 | if (!$tabs[$tabkey]['groups']) { |
||
205 | unset($tabs[$tabkey]); |
||
206 | } |
||
207 | } |
||
208 | $this->{$fcts['tabs']['setter']}($tabs); |
||
209 | } |
||
210 | } |
||
211 | |||
212 | $this->fixTemplates($mapper); |
||
213 | |||
214 | if (!$mapper instanceof FormMapper) { |
||
215 | $this->fixShowRoutes($mapper); |
||
216 | } |
||
217 | |||
218 | // Debug profiler |
||
219 | $this->getConfigurationPool()->getContainer()->get('blast_core.profiler.collector') |
||
220 | ->collectOnce('Mapper', $mapper) |
||
221 | ->collectOnce('Managed classes', $classes); |
||
222 | |||
223 | return $this; |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * @param BaseMapper $mapper |
||
228 | * @param array $group |
||
229 | * |
||
230 | * @return BaseMapper |
||
231 | */ |
||
232 | protected function addContent(BaseMapper $mapper, $group) |
||
233 | { |
||
234 | // helper links |
||
235 | $this->parseHelperLinks(); |
||
236 | |||
237 | // flat organization (DatagridMapper / ListMapper...) |
||
238 | if (!$mapper instanceof BaseGroupedMapper) { |
||
239 | //list actions |
||
240 | $this->addActions(); |
||
241 | $this->removeActions(); |
||
242 | |||
243 | // options pre-treatment |
||
244 | $options = []; |
||
245 | if (isset($group['_options'])) { |
||
246 | $options = $group['_options']; |
||
247 | unset($group['_options']); |
||
248 | } |
||
249 | |||
250 | // content |
||
251 | foreach ($group as $add => $opts) { |
||
252 | $this->addField($mapper, $add, $opts); |
||
253 | } |
||
254 | |||
255 | // options |
||
256 | if (isset($options['fieldsOrder'])) { |
||
257 | $mapper->reorder($options['fieldsOrder']); |
||
258 | } |
||
259 | |||
260 | // extra templates |
||
261 | $this->parseExtraTemplates(); |
||
262 | |||
263 | return $mapper; |
||
264 | } |
||
265 | |||
266 | $fcts = [ |
||
267 | 'tabs' => $mapper instanceof ShowMapper ? |
||
268 | ['getter' => 'getShowTabs', 'setter' => 'setShowTabs'] : |
||
269 | ['getter' => 'getFormTabs', 'setter' => 'setFormTabs'], |
||
270 | 'groups' => $mapper instanceof ShowMapper ? |
||
271 | ['getter' => 'getShowGroups', 'setter' => 'setShowGroups'] : |
||
272 | ['getter' => 'getFormGroups', 'setter' => 'setFormGroups'], |
||
273 | ]; |
||
274 | |||
275 | // if a grouped organization can be shapped |
||
276 | // options |
||
277 | $tabsOptions = null; |
||
278 | if (isset($group['_options'])) { |
||
279 | $tabsOptions = $group['_options']; |
||
280 | unset($group['_options']); |
||
281 | } |
||
282 | |||
283 | // content |
||
284 | foreach ($group as $tab => $tabcontent) { // loop on content... |
||
285 | if (self::arrayDepth($tabcontent) < 1) { |
||
286 | // direct add |
||
287 | $this->addField($mapper, $tab, $tabcontent); |
||
288 | $mapper->end()->end(); |
||
289 | } else { |
||
290 | // groups/withs order |
||
291 | $groupsOrder = null; |
||
292 | if (isset($tabcontent['_options']['groupsOrder'])) { |
||
293 | $groupsOrder = $tabcontent['_options']['groupsOrder']; |
||
294 | unset($tabcontent['_options']['groupsOrder']); |
||
295 | } |
||
296 | |||
297 | $endgroup = $endtab = false; |
||
298 | |||
299 | // tab |
||
300 | if (!empty($tabcontent['_options']['hideTitle']) || $mapper instanceof ShowMapper && !$this->forceTabs) { |
||
301 | // display tabs as groups |
||
302 | $tabs = $this->{$fcts['tabs']['getter']}(); |
||
303 | $groups = $this->{$fcts['groups']['getter']}(); |
||
304 | if (isset($tabs[$tab])) { |
||
305 | $tabs[$tab]['auto_created'] = true; |
||
306 | $this->{$fcts['tabs']['setter']}($tabs); |
||
307 | |||
308 | foreach ($groups as $groupkey => $group) { |
||
309 | if (!isset($groups[$group['name']])) { |
||
310 | $groups[$group['name']] = $group; |
||
311 | unset($groups[$groupkey]); |
||
312 | } |
||
313 | } |
||
314 | $this->{$fcts['groups']['setter']}($groups); |
||
315 | } |
||
316 | } else { |
||
317 | $mapper->tab($tab, isset($tabcontent['_options']) ? $tabcontent['_options'] : []); |
||
318 | $endtab = true; |
||
319 | } |
||
320 | |||
321 | // adding count of collections items in tab |
||
322 | if (isset($tabcontent['_options']['countChildItems']) && is_array($tabcontent['_options']['countChildItems'])) { |
||
323 | $tabs = $this->{$fcts['tabs']['getter']}(); |
||
324 | if (strpos($tabs[$tab]['class'], 'countable-tab') === false) { |
||
325 | $tabs[$tab]['class'] .= ' countable-tab'; |
||
326 | |||
327 | foreach ($tabcontent['_options']['countChildItems'] as $fieldToCount) { |
||
328 | if (strpos($tabs[$tab]['class'], 'count-' . $fieldToCount) === false) { |
||
329 | $tabs[$tab]['class'] .= ' count-' . $fieldToCount; |
||
330 | } |
||
331 | } |
||
332 | |||
333 | $this->{$fcts['tabs']['setter']}($tabs); |
||
334 | } |
||
335 | } |
||
336 | |||
337 | // clearing tabcontent options |
||
338 | if (isset($tabcontent['_options'])) { |
||
339 | unset($tabcontent['_options']); |
||
340 | } |
||
341 | |||
342 | $finalOrder = null; |
||
343 | |||
344 | // with |
||
345 | if (self::arrayDepth($tabcontent) > 0) { |
||
346 | foreach ($tabcontent as $with => $withcontent) { |
||
347 | $opt = isset($withcontent['_options']) ? $withcontent['_options'] : []; |
||
348 | $finalOrder = (isset($opt['fieldsOrder']) ? $opt['fieldsOrder'] : null); |
||
349 | |||
350 | if (empty($opt['hideTitle'])) { |
||
351 | $endtab = true; |
||
352 | $endgroup = true; |
||
353 | $mapper->with($with, $opt); |
||
354 | } |
||
355 | if (isset($withcontent['_options'])) { |
||
356 | unset($withcontent['_options']); |
||
357 | } |
||
358 | |||
359 | // final adds |
||
360 | if (self::arrayDepth($withcontent) > 0) { |
||
361 | foreach ($withcontent as $name => $options) { |
||
362 | $fieldDescriptionOptions = []; |
||
363 | if (isset($options['_options'])) { |
||
364 | $fieldDescriptionOptions = $options['_options']; |
||
365 | unset($options['_options']); |
||
366 | } |
||
367 | $this->addField($mapper, $name, $options, $fieldDescriptionOptions); |
||
368 | $endgroup = $endtab = true; |
||
369 | } |
||
370 | } |
||
371 | |||
372 | if ($finalOrder != null) { |
||
373 | $mapper->reorder($finalOrder); |
||
374 | } |
||
375 | |||
376 | if ($endgroup) { |
||
377 | $mapper->end(); |
||
378 | } |
||
379 | } |
||
380 | } |
||
381 | |||
382 | // order groups / withs (using tabs, because they are prioritary at the end) |
||
383 | if (isset($groupsOrder)) { |
||
384 | // preparing |
||
385 | $otabs = $mapper->getAdmin()->{$fcts['tabs']['getter']}(); |
||
386 | $groups = $mapper->getAdmin()->{$fcts['groups']['getter']}(); |
||
387 | |||
388 | // pre-ordering |
||
389 | $newgroups = []; |
||
390 | $buf = empty($otabs[$tab]['auto_created']) ? "$tab." : ''; |
||
391 | foreach ($groupsOrder as $groupname) { |
||
392 | if (isset($otabs[$tab]) && in_array("$buf$groupname", $otabs[$tab]['groups'])) { |
||
393 | $newgroups[] = "$buf$groupname"; |
||
394 | } |
||
395 | } |
||
396 | |||
397 | // ordering tabs |
||
398 | foreach (empty($otabs[$tab]['groups']) ? [] : $otabs[$tab]['groups'] as $groupname) { |
||
399 | if (!in_array($groupname, $newgroups)) { |
||
400 | $newgroups[] = $groupname; |
||
401 | } |
||
402 | } |
||
403 | $otabs[$tab]['groups'] = $newgroups; |
||
404 | |||
405 | // "persisting" |
||
406 | $mapper->getAdmin()->{$fcts['tabs']['setter']}($otabs); |
||
407 | } |
||
408 | |||
409 | if ($endtab) { |
||
410 | $mapper->end(); |
||
411 | } |
||
412 | } |
||
413 | } |
||
414 | |||
415 | // ordering tabs |
||
416 | if (isset($tabsOptions['tabsOrder']) && $tabs = $this->{$fcts['tabs']['getter']}()) { |
||
417 | $newtabs = []; |
||
418 | foreach ($tabsOptions['tabsOrder'] as $tabname) { |
||
419 | if (isset($tabs[$tabname])) { |
||
420 | $newtabs[$tabname] = $tabs[$tabname]; |
||
421 | } |
||
422 | } |
||
423 | foreach ($tabs as $tabname => $tab) { |
||
424 | if (!isset($newtabs[$tabname])) { |
||
425 | $newtabs[$tabname] = $tab; |
||
426 | } |
||
427 | } |
||
428 | $this->{$fcts['tabs']['setter']}($newtabs); |
||
429 | } |
||
430 | |||
431 | // ordering the ShowMapper |
||
432 | if ($mapper instanceof ShowMapper) { |
||
433 | foreach ($group as $tabName => $tabContent) { |
||
434 | $tabOptions = null; |
||
435 | if (isset($tabContent['_options'])) { |
||
436 | $tabOptions = $tabContent['_options']; |
||
437 | unset($tabContent['_options']); |
||
438 | } |
||
439 | |||
440 | if (isset($tabOptions['groupsOrder'])) { |
||
441 | $tabs = $this->{$fcts['tabs']['getter']}(); |
||
442 | $groups = $this->{$fcts['groups']['getter']}(); |
||
443 | |||
444 | $groupOrder = $tabOptions['groupsOrder']; |
||
445 | |||
446 | $properOrderedArray = array_merge(array_flip($groupOrder), $groups); |
||
447 | |||
448 | $this->{$fcts['groups']['setter']}($properOrderedArray); |
||
449 | $this->{$fcts['tabs']['setter']}($tabs); |
||
450 | } |
||
451 | } |
||
452 | } |
||
453 | |||
454 | return $mapper; |
||
455 | } |
||
456 | |||
457 | protected function addField(BaseMapper $mapper, $name, $options = [], $fieldDescriptionOptions = []) |
||
458 | { |
||
459 | // avoid duplicates |
||
460 | if ($mapper->has($name)) { |
||
461 | $mapper->remove($name); |
||
462 | } |
||
463 | |||
464 | if (!is_array($options)) { |
||
465 | $options = []; |
||
466 | } |
||
467 | |||
468 | View Code Duplication | if (isset($options['only_new'])) { |
|
469 | if ($options['only_new'] && $this->subject && !$this->subject->isNew()) { |
||
470 | return $mapper; |
||
471 | } |
||
472 | unset($options['only_new']); |
||
473 | } |
||
474 | |||
475 | View Code Duplication | if (isset($options['only_not_new'])) { |
|
476 | if ($options['only_not_new'] && (!$this->subject || $this->subject->isNew())) { |
||
477 | return $mapper; |
||
478 | } |
||
479 | unset($options['only_not_new']); |
||
480 | } |
||
481 | |||
482 | $type = null; |
||
483 | if (isset($options['type'])) { |
||
484 | $type = $options['type']; |
||
485 | unset($options['type']); |
||
486 | } |
||
487 | |||
488 | if (isset($options['constraints'])) { |
||
489 | foreach ($options['constraints'] as $k => $constraint) { |
||
490 | $options['constraints'][$k] = new $constraint(); |
||
491 | } |
||
492 | } |
||
493 | |||
494 | if (isset($options['required']) && $options['required'] === true) { |
||
495 | $options['constraints'] = [new NotBlank()]; |
||
496 | } |
||
497 | |||
498 | if (isset($options['query'])) { |
||
499 | $this->manageQueryCallback($mapper, $options); |
||
500 | } |
||
501 | |||
502 | if (isset($options['choicesCallback'])) { |
||
503 | $this->manageChoicesCallback($mapper, $options); |
||
504 | } |
||
505 | |||
506 | if (isset($options['serviceCallback'])) { |
||
507 | $this->manageServiceCallback($mapper, $options); |
||
508 | } |
||
509 | |||
510 | // save-and-remove CoreBundle-specific options |
||
511 | $extras = []; |
||
512 | foreach ([ |
||
513 | 'template' => 'setTemplate', |
||
514 | 'initializeAssociationAdmin' => null, |
||
515 | ] as $extra => $method) { |
||
516 | if (isset($fieldDescriptionOptions[$extra])) { |
||
517 | $extras[$extra] = [$method, $fieldDescriptionOptions[$extra]]; |
||
518 | unset($fieldDescriptionOptions[$extra]); |
||
519 | } |
||
520 | } |
||
521 | |||
522 | $mapper->add($name, $type, $options, $fieldDescriptionOptions); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Sonata\AdminBundle\Mapper\BaseMapper as the method add() does only exist in the following sub-classes of Sonata\AdminBundle\Mapper\BaseMapper : Sonata\AdminBundle\Datagrid\DatagridMapper , Sonata\AdminBundle\Datagrid\ListMapper , Sonata\AdminBundle\Form\FormMapper , Sonata\AdminBundle\Show\ShowMapper . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
523 | |||
524 | // apply extra options |
||
525 | foreach ($extras as $extra => $call) { |
||
526 | if ($call[0]) { |
||
527 | $mapper->get($name)->{$call[0]}($call[1]); |
||
528 | } else { |
||
529 | switch ($extra) { |
||
530 | case 'initializeAssociationAdmin': |
||
531 | // only if "true" |
||
532 | if (!$call[1]) { |
||
533 | break; |
||
534 | } |
||
535 | |||
536 | // initialize the association-admin |
||
537 | $mapper->get($name)->getAssociationAdmin()->configureShowFields(new ShowMapper( |
||
538 | $mapper->get($name)->getAssociationAdmin()->getShowBuilder(), $mapper->get($name)->getAssociationAdmin()->getShow(), $mapper->get($name)->getAssociationAdmin() |
||
539 | )); |
||
540 | |||
541 | // set the efficient template |
||
542 | if (!isset($extras['template'])) { |
||
543 | $mapper->get($name)->setTemplate('BlastCoreBundle:CRUD:show_association_admin.html.twig'); |
||
544 | } |
||
545 | break; |
||
546 | } |
||
547 | } |
||
548 | } |
||
549 | |||
550 | return $mapper; |
||
551 | } |
||
552 | |||
553 | protected function configureFields($function, BaseMapper $mapper, $class = null) |
||
554 | { |
||
555 | if (!$class) { |
||
556 | $class = $this->getOriginalClass(); |
||
0 ignored issues
–
show
It seems like
getOriginalClass() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the
Loading history...
|
|||
557 | } |
||
558 | |||
559 | return $class::$function($mapper); |
||
560 | } |
||
561 | |||
562 | /** |
||
563 | * @param array $actions |
||
564 | * */ |
||
565 | protected function handleBatchActions(array $actions = []) |
||
566 | { |
||
567 | $blast = $this->getConfigurationPool()->getContainer()->getParameter('blast'); |
||
568 | $mapperClass = ListMapper::class; |
||
569 | $actionKey = '_batch_actions'; |
||
570 | |||
571 | foreach ($this->getCurrentComposition() as $class) { |
||
572 | if (isset($blast[$class][$mapperClass])) { |
||
573 | $config = $blast[$class][$mapperClass]; |
||
574 | |||
575 | View Code Duplication | if (isset($blast['all'][$mapperClass])) { |
|
576 | $config = array_merge_recursive( |
||
577 | $config, |
||
578 | $blast['all'][$mapperClass] |
||
579 | ); |
||
580 | } |
||
581 | |||
582 | // remove / reset |
||
583 | if (isset($config['remove'][$actionKey])) { |
||
584 | $actions = parent::getBatchActions(); |
||
585 | |||
586 | foreach ($config['remove'][$actionKey] as $action) { |
||
587 | if (isset($actions[$action])) { |
||
588 | unset($actions[$action]); |
||
589 | } |
||
590 | } |
||
591 | } |
||
592 | |||
593 | // add |
||
594 | if (isset($config['add'][$actionKey])) { |
||
595 | $buf = $config['add'][$actionKey]; |
||
596 | |||
597 | foreach ($buf as $action => $props) { |
||
598 | $name = 'batch_action_' . $action; |
||
599 | |||
600 | foreach ([ |
||
601 | 'label' => $name, |
||
602 | 'params' => [], |
||
603 | 'translation_domain' => $this->getTranslationDomain(), |
||
604 | 'action' => $name, |
||
605 | 'route' => 'batch_' . $action, |
||
606 | ] as $field => $value) { |
||
607 | if (empty($props[$field])) { |
||
608 | $props[$field] = $value; |
||
609 | } |
||
610 | } |
||
611 | |||
612 | $actions[$action] = $props; |
||
613 | } |
||
614 | } |
||
615 | } |
||
616 | } |
||
617 | |||
618 | return $actions; |
||
619 | } |
||
620 | |||
621 | /** |
||
622 | * @param array $actions |
||
623 | * */ |
||
624 | protected function handleListActions(array $actions = []) |
||
625 | { |
||
626 | $this->_listActionLoaded = true; |
||
0 ignored issues
–
show
The property
_listActionLoaded does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
Loading history...
|
|||
627 | $blast = $this->getConfigurationPool()->getContainer()->getParameter('blast'); |
||
628 | |||
629 | foreach ($this->getCurrentComposition() as $class) { |
||
630 | // remove / reset |
||
631 | View Code Duplication | if (isset($blast[$class][ListMapper::class]['remove']['_list_actions'])) { |
|
632 | foreach ($blast[$class][ListMapper::class]['remove']['_list_actions'] as $action) { |
||
633 | $this->removeListAction($action); |
||
634 | } |
||
635 | } |
||
636 | |||
637 | // add |
||
638 | if (isset($blast[$class][ListMapper::class]['add']['_list_actions'])) { |
||
639 | foreach ($blast[$class][ListMapper::class]['add']['_list_actions'] as $action => $props) { |
||
640 | $props['translation_domain'] = isset($props['translation_domain']) ? $props['translation_domain'] : $this->getTranslationDomain(); |
||
641 | $this->addListAction($action, $props); |
||
642 | } |
||
643 | } |
||
644 | } |
||
645 | |||
646 | return $this->getListActions(); |
||
0 ignored issues
–
show
It seems like
getListActions() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the
Loading history...
|
|||
647 | } |
||
648 | |||
649 | /** |
||
650 | * @param array $formats |
||
651 | * */ |
||
652 | protected function addPresetExportFormats(array $formats = []) |
||
653 | { |
||
654 | $blast = $this->getConfigurationPool()->getContainer()->getParameter('blast'); |
||
655 | $this->exportFields = $formats; |
||
0 ignored issues
–
show
The property
exportFields does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
Loading history...
|
|||
656 | |||
657 | foreach ($this->getCurrentComposition() as $class) { |
||
658 | // remove / reset |
||
659 | if (isset($blast[$class][ListMapper::class]['remove']['_export_format'])) { |
||
660 | $this->exportFields = []; |
||
661 | } |
||
662 | |||
663 | // add |
||
664 | if (isset($blast[$class][ListMapper::class]['add']['_export_format'])) { |
||
665 | foreach ($blast[$class][ListMapper::class]['add']['_export_format'] as $format => $fields) { |
||
666 | // if no fields are defined (not an associative array) |
||
667 | if (intval($format) . '' == '' . $format && !is_array($fields)) { |
||
668 | $format = $fields; |
||
669 | $this->exportFields[$format] = $fields = []; |
||
670 | } |
||
671 | |||
672 | // if a copy of an other format is requested |
||
673 | if (!is_array($fields) && isset($blast[$class][ListMapper::class]['add']['_export_format'][$fields])) { |
||
674 | $blast[$class][ListMapper::class]['add']['_export_format'][$format] = // the global fields array |
||
675 | $fields = // the local fields array |
||
676 | $blast[$class][ListMapper::class]['add']['_export_format'][$fields]; // the source fields array |
||
677 | } |
||
678 | |||
679 | // removes a specific format |
||
680 | if (substr($format, 0, 1) == '-') { |
||
681 | unset($this->exportFields[substr($format, 1)]); |
||
682 | continue; |
||
683 | } |
||
684 | |||
685 | // if an order is defined, use it to order the extracted fields |
||
686 | if (!$fields && isset($blast[$class][ListMapper::class]['add']['_options']['fieldsOrder'])) { |
||
687 | // get back default fields |
||
688 | $tmp = parent::getExportFields(); |
||
689 | $fields = []; |
||
690 | |||
691 | // takes the ordered fields |
||
692 | View Code Duplication | foreach ($blast[$class][ListMapper::class]['add']['_options']['fieldsOrder'] as $field) { |
|
693 | if (in_array($field, $tmp)) { |
||
694 | $fields[] = $field; |
||
695 | } |
||
696 | } |
||
697 | |||
698 | // then the forgotten fields as they come |
||
699 | View Code Duplication | foreach ($tmp as $field) { |
|
700 | if (!in_array($field, $blast[$class][ListMapper::class]['add']['_options']['fieldsOrder'])) { |
||
701 | $fields[] = $field; |
||
702 | } |
||
703 | } |
||
704 | } |
||
705 | $this->exportFields[$format] = $fields; |
||
706 | } |
||
707 | } |
||
708 | } |
||
709 | |||
710 | return $this->exportFields; |
||
711 | } |
||
712 | |||
713 | /** |
||
714 | * @todo parse ShowMapper and FormMapper |
||
715 | */ |
||
716 | protected function parseExtraTemplates() |
||
717 | { |
||
718 | $blast = $this->getConfigurationPool()->getContainer()->getParameter('blast'); |
||
719 | |||
720 | foreach ($this->getCurrentComposition() as $class) { |
||
721 | // remove / reset |
||
722 | if (isset($blast[$class][ListMapper::class]['remove']['_extra_templates'])) { |
||
723 | // TODO |
||
724 | } |
||
725 | |||
726 | // add |
||
727 | View Code Duplication | if (isset($blast[$class][ListMapper::class]['add']['_extra_templates'])) { |
|
728 | foreach ($blast[$class][ListMapper::class]['add']['_extra_templates'] as $template) { |
||
729 | $this->addExtraTemplate('list', $template); |
||
730 | } |
||
731 | } |
||
732 | } |
||
733 | } |
||
734 | |||
735 | protected function parseHelperLinks() |
||
736 | { |
||
737 | $blast = $this->getConfigurationPool()->getContainer()->getParameter('blast'); |
||
738 | $mappers = [ |
||
739 | 'list' => ListMapper::class, |
||
740 | 'show' => ShowMapper::class, |
||
741 | 'form' => FormMapper::class, |
||
742 | ]; |
||
743 | |||
744 | foreach ($this->getCurrentComposition() as $class) { |
||
745 | foreach ($mappers as $mapper => $mapper_class) { |
||
746 | // remove / reset |
||
747 | if (isset($blast[$class][$mapper_class]['remove']['_helper_links'])) { |
||
748 | // TODO |
||
749 | } |
||
750 | |||
751 | // add |
||
752 | View Code Duplication | if (isset($blast[$class][$mapper_class]['add']['_helper_links'])) { |
|
753 | foreach ($blast[$class][$mapper_class]['add']['_helper_links'] as $link) { |
||
754 | $this->addHelperLink($mapper, $link); |
||
755 | } |
||
756 | } |
||
757 | } |
||
758 | } |
||
759 | } |
||
760 | |||
761 | protected function setTitles(BaseMapper $mapper, $titleTemplate, $title) |
||
762 | { |
||
763 | $contexts = [ |
||
764 | ListMapper::class => 'list', |
||
765 | ShowMapper::class => 'show', |
||
766 | FormMapper::class => 'form', |
||
767 | ]; |
||
768 | if (!isset($contexts[get_class($mapper)])) { |
||
769 | return; |
||
770 | } |
||
771 | |||
772 | $context = $contexts[get_class($mapper)]; |
||
773 | if ($titleTemplate) { |
||
774 | $this->titleTemplates[$context] = $titleTemplate; |
||
775 | } |
||
776 | if ($title) { |
||
777 | $this->titles[$context] = $title; |
||
778 | } |
||
779 | } |
||
780 | |||
781 | protected function getFormThemeMapping() |
||
782 | { |
||
783 | $theme = []; |
||
784 | $blast = $this->getConfigurationPool()->getContainer()->getParameter('blast'); |
||
785 | |||
786 | foreach ($this->getCurrentComposition() as $class) { |
||
787 | if (isset($blast[$class])) { |
||
788 | if (isset($blast[$class]['form_theme'])) { |
||
789 | $theme = array_merge($theme, $blast[$class]['form_theme']); |
||
790 | } |
||
791 | } |
||
792 | } |
||
793 | |||
794 | return $theme; |
||
795 | } |
||
796 | |||
797 | protected function getBaseRouteMapping() |
||
798 | { |
||
799 | $baseRoute = []; |
||
800 | $blast = $this->getConfigurationPool()->getContainer()->getParameter('blast'); |
||
801 | |||
802 | foreach ($this->getCurrentComposition() as $class) { |
||
803 | if (isset($blast[$class]) && isset($blast[$class]['baseRoute'])) { |
||
804 | $reflexionClass = new \ReflectionClass($class); |
||
805 | if (!$reflexionClass->isTrait()) { |
||
806 | $baseRoute = array_merge($baseRoute, $blast[$class]['baseRoute']); |
||
807 | } |
||
808 | } |
||
809 | } |
||
810 | |||
811 | return $baseRoute; |
||
812 | } |
||
813 | |||
814 | protected function manageCallback($mapper, &$options, $callbackType) |
||
815 | { |
||
816 | $option = $options[$callbackType]; |
||
817 | |||
818 | $entityClass = isset($options['class']) ? $options['class'] : $this->getClass(); |
||
819 | |||
820 | if (!is_array($option)) { |
||
821 | throw new Exception('« $callbackType » option must be an array : ["FQDN"=>"static method name"]'); |
||
822 | } |
||
823 | |||
824 | list($serviceNameOrClass, $methodName) = $option; |
||
825 | |||
826 | $targetOptions = (isset($option[2]) ? $option[2] : null); |
||
827 | |||
828 | if ($this->getConfigurationPool()->getContainer()->has($serviceNameOrClass)) { |
||
829 | $callBackFunction = [$this->getConfigurationPool()->getContainer()->get($serviceNameOrClass), $methodName]; |
||
830 | } else { |
||
831 | $callBackFunction = call_user_func($serviceNameOrClass . '::' . $methodName, $this->getModelManager(), $entityClass); |
||
832 | } |
||
833 | |||
834 | if ($targetOptions !== null) { |
||
835 | $options[$targetOptions] = $callBackFunction; |
||
836 | unset($options[$callbackType]); |
||
837 | } |
||
838 | |||
839 | return $callBackFunction; |
||
840 | } |
||
841 | |||
842 | protected function manageQueryCallback($mapper, &$options) |
||
843 | { |
||
844 | $callback = $this->manageCallback($mapper, $options, 'query'); |
||
845 | $options['query'] = $callback; |
||
846 | } |
||
847 | |||
848 | protected function manageChoicesCallback($mapper, &$options) |
||
849 | { |
||
850 | $callback = $this->manageCallback($mapper, $options, 'choicesCallback'); |
||
851 | |||
852 | $options['choices'] = $callback; |
||
853 | $options['choice_loader'] = new CallbackChoiceLoader(function () use ($options) { |
||
854 | return $options['choices']; |
||
855 | }); |
||
856 | unset($options['choicesCallback']); |
||
857 | } |
||
858 | |||
859 | public function manageServiceCallback($mapper, &$options) |
||
860 | { |
||
861 | $this->manageCallback($mapper, $options, 'serviceCallback'); |
||
862 | } |
||
863 | } |
||
864 |
This check looks for methods that are used by a trait but not required by it.
To illustrate, let’s look at the following code example
The trait
Idable
provides a methodequalsId
that in turn relies on the methodgetId()
. If this method does not exist on a class mixing in this trait, the method will fail.Adding the
getId()
as an abstract method to the trait will make sure it is available.