1: <?php
2: namespace TIC\FormBundle\Form\Type;
3:
4: #use Symfony\Component\Form\AbstractType as BaseType;
5: use TIC\FormBundle\Base\TICWidgetType as BaseType;
6:
7: use Symfony\Component\OptionsResolver\OptionsResolver;
8: use Symfony\Component\OptionsResolver\Options;
9: use Symfony\Component\Form\FormBuilderInterface;
10: use Symfony\Component\Form\FormInterface;
11: use Symfony\Component\Form\FormView;
12:
13: use Symfony\Component\Form\CallbackTransformer;
14:
15: /**
16: * Conteneur pour gérer une collection dynamique de widgets.
17: * Reprise du widget Symfony avec support du prototype_data
18: */
19: class CollectionType extends BaseType
20: {
21: protected $form_parent = 'Symfony\Component\Form\Extension\Core\Type\CollectionType';
22:
23:
24: /**
25: * {@inheritdoc}
26: * Note: with default value support by prototype_data option
27: */
28: public function configureOptions(OptionsResolver $resolver): void
29: {
30: parent::configureOptions($resolver);
31:
32: $resolver->setDefaults(array(
33: 'by_reference' => false, // usage sur l'entité des adder/remover (au lieu des getter/setter)
34: 'allow_add' => false,
35: 'allow_del' => null, // alias vers l'option 'allow_delete' originale
36: 'prototype' => true,
37: 'prototype_data' => null,
38: 'prototype_name' => true, // si true nom "unique" (random) utile en cas de collections imbriquées ('__name__' si null)
39: 'display' => 'default', // default | table
40: 'sizing' => 'sm', // bootstrap form sizing : sm | md | lg (héritage si null)
41: 'sortable' => false, // drag n drop de modification de l'ordre, seulement si display = table
42: ));
43:
44: $resolver->setAllowedValues('display', array('default', 'table'));
45: $resolver->setAllowedTypes('allow_del', array('null', 'boolean'));
46: $resolver->setAllowedTypes('prototype_name', array('null', 'string', 'boolean'));
47:
48: $resolver->setNormalizer('allow_delete', function (Options $options, $allow_delete) {
49: if ($options['allow_del'] !== null) $allow_delete = $options['allow_del'];
50: return $allow_delete;
51: });
52: $resolver->setNormalizer('prototype_name', function (Options $options, $prototype_name) {
53: if ($prototype_name === true) return '__name' . rand(100,999) . '__';
54: if (empty($prototype_name)) return '__name__';
55: return $prototype_name;
56: });
57: }
58:
59:
60: /**
61: * {@inheritdoc}
62: * Note: with default value support by prototype_data option
63: */
64: public function buildForm(FormBuilderInterface $builder, array $options): void
65: {
66: parent::buildForm($builder, $options);
67:
68: if ($options['prototype']) {
69: $prototypeFormBuilder = $builder->getAttribute('prototype');
70: if ($prototypeFormBuilder !== null) {
71: /** @var $prototypeFormBuilder FormBuilderInterface */
72: $prototypeFormBuilder->setData($options['prototype_data']);
73: }
74: }
75: }
76:
77:
78: /**
79: * {@inheritdoc}
80: */
81: public function buildView(FormView $view, FormInterface $form, array $options): void
82: {
83: parent::buildView($view, $form, $options);
84:
85: $view->vars['display'] = $options['display'];
86: $view->vars['sortable'] = $options['sortable'];
87: }
88:
89:
90: }
91: