ModelType.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. /*
  3. * This file is part of the Sonata Project package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Form\Type;
  11. use Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList;
  12. use Sonata\AdminBundle\Form\ChoiceList\ModelChoiceLoader;
  13. use Sonata\AdminBundle\Form\DataTransformer\LegacyModelsToArrayTransformer;
  14. use Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer;
  15. use Sonata\AdminBundle\Form\DataTransformer\ModelToIdTransformer;
  16. use Sonata\AdminBundle\Form\EventListener\MergeCollectionListener;
  17. use Symfony\Component\Form\AbstractType;
  18. use Symfony\Component\Form\FormBuilderInterface;
  19. use Symfony\Component\Form\FormInterface;
  20. use Symfony\Component\Form\FormView;
  21. use Symfony\Component\OptionsResolver\Options;
  22. use Symfony\Component\OptionsResolver\OptionsResolver;
  23. use Symfony\Component\OptionsResolver\OptionsResolverInterface;
  24. /**
  25. * Class ModelType
  26. * This type define a standard select input with a + sign to add new associated object.
  27. *
  28. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  29. */
  30. class ModelType extends AbstractType
  31. {
  32. /**
  33. * {@inheritdoc}
  34. */
  35. public function buildForm(FormBuilderInterface $builder, array $options)
  36. {
  37. if ($options['multiple']) {
  38. if (array_key_exists('choice_loader', $options) && $options['choice_loader'] !== null) { // SF2.7+
  39. $builder->addViewTransformer(new ModelsToArrayTransformer($options['choice_list'], $options['model_manager'], $options['class']), true);
  40. } else {
  41. $builder->addViewTransformer(new LegacyModelsToArrayTransformer($options['choice_list']), true);
  42. }
  43. $builder
  44. ->addEventSubscriber(new MergeCollectionListener($options['model_manager']))
  45. ;
  46. } else {
  47. $builder
  48. ->addViewTransformer(new ModelToIdTransformer($options['model_manager'], $options['class']), true)
  49. ;
  50. }
  51. }
  52. /**
  53. * {@inheritdoc}
  54. */
  55. public function buildView(FormView $view, FormInterface $form, array $options)
  56. {
  57. $view->vars['btn_add'] = $options['btn_add'];
  58. $view->vars['btn_list'] = $options['btn_list'];
  59. $view->vars['btn_delete'] = $options['btn_delete'];
  60. $view->vars['btn_catalogue'] = $options['btn_catalogue'];
  61. }
  62. /**
  63. * {@inheritdoc}
  64. *
  65. * @todo Remove it when bumping requirements to SF 2.7+
  66. */
  67. public function setDefaultOptions(OptionsResolverInterface $resolver)
  68. {
  69. $this->configureOptions($resolver);
  70. }
  71. /**
  72. * {@inheritdoc}
  73. */
  74. public function configureOptions(OptionsResolver $resolver)
  75. {
  76. $options = array();
  77. if (interface_exists('Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface')) { // SF2.7+
  78. $options['choice_loader'] = function (Options $options, $previousValue) {
  79. if ($previousValue && count($choices = $previousValue->getChoices())) {
  80. return $choices;
  81. }
  82. return new ModelChoiceLoader(
  83. $options['model_manager'],
  84. $options['class'],
  85. $options['property'],
  86. $options['query'],
  87. $options['choices']
  88. );
  89. };
  90. } else {
  91. $options['choice_list'] = function (Options $options, $previousValue) {
  92. if ($previousValue && count($choices = $previousValue->getChoices())) {
  93. return $choices;
  94. }
  95. return new ModelChoiceList(
  96. $options['model_manager'],
  97. $options['class'],
  98. $options['property'],
  99. $options['query'],
  100. $options['choices']
  101. );
  102. };
  103. }
  104. $resolver->setDefaults(array_merge($options, array(
  105. 'compound' => function (Options $options) {
  106. if (isset($options['multiple']) && $options['multiple']) {
  107. if (isset($options['expanded']) && $options['expanded']) {
  108. //checkboxes
  109. return true;
  110. }
  111. //select tag (with multiple attribute)
  112. return false;
  113. }
  114. if (isset($options['expanded']) && $options['expanded']) {
  115. //radio buttons
  116. return true;
  117. }
  118. //select tag
  119. return false;
  120. },
  121. 'template' => 'choice',
  122. 'multiple' => false,
  123. 'expanded' => false,
  124. 'model_manager' => null,
  125. 'class' => null,
  126. 'property' => null,
  127. 'query' => null,
  128. 'choices' => array(),
  129. 'preferred_choices' => array(),
  130. 'btn_add' => 'link_add',
  131. 'btn_list' => 'link_list',
  132. 'btn_delete' => 'link_delete',
  133. 'btn_catalogue' => 'SonataAdminBundle',
  134. )));
  135. }
  136. /**
  137. * {@inheritdoc}
  138. */
  139. public function getParent()
  140. {
  141. return 'choice';
  142. }
  143. /**
  144. * {@inheritdoc}
  145. *
  146. * @todo Remove when dropping Symfony <2.8 support
  147. */
  148. public function getName()
  149. {
  150. return $this->getBlockPrefix();
  151. }
  152. /**
  153. * {@inheritdoc}
  154. */
  155. public function getBlockPrefix()
  156. {
  157. return 'sonata_type_model';
  158. }
  159. }