PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Form/Extension/Field/Type/FormTypeFieldExtension.php

http://github.com/sonata-project/SonataAdminBundle
PHP | 266 lines | 158 code | 43 blank | 65 comment | 17 complexity | a9f33272a0cdd4b96213528da20a90c2 MD5 | raw file
Possible License(s): JSON, Apache-2.0, MIT
  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\Extension\Field\Type;
  11. use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
  12. use Sonata\AdminBundle\Exception\NoValueException;
  13. use Symfony\Component\Form\AbstractTypeExtension;
  14. use Symfony\Component\Form\FormBuilderInterface;
  15. use Symfony\Component\Form\FormInterface;
  16. use Symfony\Component\Form\FormView;
  17. use Symfony\Component\OptionsResolver\OptionsResolver;
  18. use Symfony\Component\OptionsResolver\OptionsResolverInterface;
  19. /**
  20. * Class FormTypeFieldExtension.
  21. *
  22. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  23. */
  24. class FormTypeFieldExtension extends AbstractTypeExtension
  25. {
  26. /**
  27. * @var array
  28. */
  29. protected $defaultClasses = array();
  30. /**
  31. * @var array
  32. */
  33. protected $options;
  34. /**
  35. * @param array $defaultClasses
  36. * @param array $options
  37. */
  38. public function __construct(array $defaultClasses, array $options)
  39. {
  40. $this->defaultClasses = $defaultClasses;
  41. $this->options = $options;
  42. }
  43. /**
  44. * {@inheritdoc}
  45. */
  46. public function buildForm(FormBuilderInterface $builder, array $options)
  47. {
  48. $sonataAdmin = array(
  49. 'name' => null,
  50. 'admin' => null,
  51. 'value' => null,
  52. 'edit' => 'standard',
  53. 'inline' => 'natural',
  54. 'field_description' => null,
  55. 'block_name' => false,
  56. 'options' => $this->options,
  57. );
  58. $builder->setAttribute('sonata_admin_enabled', false);
  59. $builder->setAttribute('sonata_help', false);
  60. if ($options['sonata_field_description'] instanceof FieldDescriptionInterface) {
  61. $fieldDescription = $options['sonata_field_description'];
  62. $sonataAdmin['admin'] = $fieldDescription->getAdmin();
  63. $sonataAdmin['field_description'] = $fieldDescription;
  64. $sonataAdmin['name'] = $fieldDescription->getName();
  65. $sonataAdmin['edit'] = $fieldDescription->getOption('edit', 'standard');
  66. $sonataAdmin['inline'] = $fieldDescription->getOption('inline', 'natural');
  67. $sonataAdmin['block_name'] = $fieldDescription->getOption('block_name', false);
  68. $sonataAdmin['class'] = $this->getClass($builder);
  69. $builder->setAttribute('sonata_admin_enabled', true);
  70. }
  71. $builder->setAttribute('sonata_admin', $sonataAdmin);
  72. }
  73. /**
  74. * {@inheritdoc}
  75. */
  76. public function buildView(FormView $view, FormInterface $form, array $options)
  77. {
  78. $sonataAdmin = $form->getConfig()->getAttribute('sonata_admin');
  79. /*
  80. * We have a child, so we need to upgrade block prefix
  81. */
  82. if ($view->parent && $view->parent->vars['sonata_admin_enabled'] && !$sonataAdmin['admin']) {
  83. $blockPrefixes = $view->vars['block_prefixes'];
  84. $baseName = str_replace('.', '_', $view->parent->vars['sonata_admin_code']);
  85. $baseType = $blockPrefixes[count($blockPrefixes) - 2];
  86. $blockSuffix = preg_replace('#^_([a-z0-9]{14})_(.++)$#', '$2', array_pop($blockPrefixes));
  87. $blockPrefixes[] = sprintf('%s_%s', $baseName, $baseType);
  88. $blockPrefixes[] = sprintf('%s_%s_%s_%s', $baseName, $baseType, $view->parent->vars['name'], $view->vars['name']);
  89. $blockPrefixes[] = sprintf('%s_%s_%s_%s', $baseName, $baseType, $view->parent->vars['name'], $blockSuffix);
  90. $view->vars['block_prefixes'] = $blockPrefixes;
  91. $view->vars['sonata_admin_enabled'] = true;
  92. $view->vars['sonata_admin'] = array(
  93. 'admin' => false,
  94. 'field_description' => false,
  95. 'name' => false,
  96. 'edit' => 'standard',
  97. 'inline' => 'natural',
  98. 'block_name' => false,
  99. 'class' => false,
  100. 'options' => $this->options,
  101. );
  102. $view->vars['sonata_admin_code'] = $view->parent->vars['sonata_admin_code'];
  103. return;
  104. }
  105. $sonataAdminHelp = isset($options['sonata_help']) ? $options['sonata_help'] : null;
  106. // avoid to add extra information not required by non admin field
  107. if ($sonataAdmin && $form->getConfig()->getAttribute('sonata_admin_enabled', true)) {
  108. $sonataAdmin['value'] = $form->getData();
  109. // add a new block types, so the Admin Form element can be tweaked based on the admin code
  110. $blockPrefixes = $view->vars['block_prefixes'];
  111. $baseName = str_replace('.', '_', $sonataAdmin['admin']->getCode());
  112. $baseType = $blockPrefixes[count($blockPrefixes) - 2];
  113. $blockSuffix = preg_replace('#^_([a-z0-9]{14})_(.++)$#', '$2', array_pop($blockPrefixes));
  114. $blockPrefixes[] = sprintf('%s_%s', $baseName, $baseType);
  115. $blockPrefixes[] = sprintf('%s_%s_%s', $baseName, $sonataAdmin['name'], $baseType);
  116. $blockPrefixes[] = sprintf('%s_%s_%s_%s', $baseName, $sonataAdmin['name'], $baseType, $blockSuffix);
  117. if (isset($sonataAdmin['block_name']) && $sonataAdmin['block_name'] !== false) {
  118. $blockPrefixes[] = $sonataAdmin['block_name'];
  119. }
  120. $view->vars['block_prefixes'] = $blockPrefixes;
  121. $view->vars['sonata_admin_enabled'] = true;
  122. $view->vars['sonata_admin'] = $sonataAdmin;
  123. $view->vars['sonata_admin_code'] = $sonataAdmin['admin']->getCode();
  124. $attr = $view->vars['attr'];
  125. if (!isset($attr['class']) && isset($sonataAdmin['class'])) {
  126. $attr['class'] = $sonataAdmin['class'];
  127. }
  128. $view->vars['attr'] = $attr;
  129. } else {
  130. $view->vars['sonata_admin_enabled'] = false;
  131. }
  132. $view->vars['sonata_help'] = $sonataAdminHelp;
  133. $view->vars['sonata_admin'] = $sonataAdmin;
  134. }
  135. /**
  136. * {@inheritdoc}
  137. */
  138. public function getExtendedType()
  139. {
  140. return
  141. method_exists('Symfony\Component\Form\AbstractType', 'getBlockPrefix') ?
  142. 'Symfony\Component\Form\Extension\Core\Type\FormType' :
  143. 'form';
  144. }
  145. /**
  146. * {@inheritdoc}
  147. *
  148. * @todo Remove it when bumping requirements to SF 2.7+
  149. */
  150. public function setDefaultOptions(OptionsResolverInterface $resolver)
  151. {
  152. $this->configureOptions($resolver);
  153. }
  154. /**
  155. * {@inheritdoc}
  156. */
  157. public function configureOptions(OptionsResolver $resolver)
  158. {
  159. $resolver->setDefaults(array(
  160. 'sonata_admin' => null,
  161. 'sonata_field_description' => null,
  162. // be compatible with mopa if not installed, avoid generating an exception for invalid option
  163. 'label_render' => true,
  164. 'sonata_help' => null,
  165. ));
  166. }
  167. /**
  168. * return the value related to FieldDescription, if the associated object does no
  169. * exists => a temporary one is created.
  170. *
  171. * @param object $object
  172. * @param FieldDescriptionInterface $fieldDescription
  173. *
  174. * @return mixed
  175. */
  176. public function getValueFromFieldDescription($object, FieldDescriptionInterface $fieldDescription)
  177. {
  178. $value = null;
  179. if (!$object) {
  180. return $value;
  181. }
  182. try {
  183. $value = $fieldDescription->getValue($object);
  184. } catch (NoValueException $e) {
  185. if ($fieldDescription->getAssociationAdmin()) {
  186. $value = $fieldDescription->getAssociationAdmin()->getNewInstance();
  187. }
  188. }
  189. return $value;
  190. }
  191. /**
  192. * @param FormBuilderInterface $formBuilder
  193. *
  194. * @return string
  195. */
  196. protected function getClass(FormBuilderInterface $formBuilder)
  197. {
  198. foreach ($this->getTypes($formBuilder) as $type) {
  199. if (!method_exists($type, 'getName')) { // SF3.0+
  200. $name = get_class($type);
  201. } else {
  202. $name = $type->getName();
  203. }
  204. if (isset($this->defaultClasses[$name])) {
  205. return $this->defaultClasses[$name];
  206. }
  207. }
  208. return '';
  209. }
  210. /**
  211. * @param FormBuilderInterface $formBuilder
  212. *
  213. * @return array
  214. */
  215. protected function getTypes(FormBuilderInterface $formBuilder)
  216. {
  217. $types = array();
  218. for ($type = $formBuilder->getType(); null !== $type; $type = $type->getParent()) {
  219. array_unshift($types, $type->getInnerType());
  220. }
  221. return $types;
  222. }
  223. }