/Widget/AutocompleteDoctrineType.php

https://github.com/cordoval/CULabsjQueryBundle · PHP · 145 lines · 108 code · 19 blank · 18 comment · 10 complexity · 0724cd94b897290cb1aae44455793b29 MD5 · raw file

  1. <?php
  2. namespace CULabs\jQueryBundle\Widget;
  3. use Symfony\Component\Form\AbstractType;
  4. use Symfony\Component\DependencyInjection\ContainerInterface;
  5. use Symfony\Component\Form\FormView;
  6. use Symfony\Component\Form\FormInterface;
  7. use Symfony\Component\Form\FormBuilder;
  8. use Symfony\Bridge\Doctrine\RegistryInterface;
  9. use Symfony\Component\Form\Exception\FormException;
  10. use Symfony\Component\Form\DataTransformerInterface;
  11. class AutocompleteDoctrineType extends AbstractType implements DataTransformerInterface
  12. {
  13. protected $container,
  14. $registry,
  15. $options;
  16. public function __construct(ContainerInterface $container, RegistryInterface $registry)
  17. {
  18. $this->container = $container;
  19. $this->registry = $registry;
  20. }
  21. /**
  22. * {@inheritdoc}
  23. */
  24. public function buildForm(FormBuilder $builder, array $options)
  25. {
  26. if (!$options['url']) {
  27. throw new FormException('The "url" option no must be null');
  28. }
  29. if (!$options['class']) {
  30. throw new FormException('The "class" option no must be null');
  31. }
  32. $this->options = $options;
  33. $builder->setAttribute('url', $options['url'])
  34. ->setAttribute('config', $options['config'])
  35. ->setAttribute('limit', $options['limit'])
  36. ->setAttribute('key_method', $options['key_method'])
  37. ->setAttribute('em', $options['em'])
  38. ->setAttribute('class', $options['class'])
  39. ->setAttribute('method_for_query', $options['method_for_query'])
  40. ->setAttribute('method', $options['method'])
  41. ;
  42. $builder->prependClientTransformer($this);
  43. }
  44. /**
  45. * {@inheritdoc}
  46. */
  47. public function buildView(FormView $view, FormInterface $form)
  48. {
  49. $this->container->get('twig.extension.form.jquery')->setTheme($view, array('CULabsjQueryBundle:Widget:doctrine_autocomplete.html.twig'));
  50. $key = $this->transform($form->getData());
  51. $view->set('id_visible', $view->get('id').'_visible')
  52. ->set('full_name_visible', sprintf('%s_visible[%s]', $view->getParent()->get('full_name'), $view->get('name')))
  53. ->set('value_hidden', $key)
  54. ->set('value_visible', $this->getVisibleValue($key))
  55. ->set('config', $form->getAttribute('config'))
  56. ->set('url', $form->getAttribute('url'))
  57. ->set('limit', $form->getAttribute('limit'))
  58. ;
  59. }
  60. protected function getVisibleValue($value)
  61. {
  62. if (!$value)
  63. return '';
  64. return call_user_func(array($this->reverseTransform($value), $this->options['method']));
  65. }
  66. /**
  67. * {@inheritdoc}
  68. */
  69. public function getDefaultOptions(array $options)
  70. {
  71. $defaultOptions = array(
  72. 'em' => null,
  73. 'class' => null,
  74. 'url' => null,
  75. 'method_for_query' => 'findOneById',
  76. 'method' => '__toString',
  77. 'key_method' => 'getId',
  78. 'config' => '{}',
  79. 'limit' => 10
  80. );
  81. $options = array_merge($defaultOptions, $options);
  82. $options['em'] = $this->registry->getEntityManager($options['em']);
  83. return $options;
  84. }
  85. /**
  86. * {@inheritdoc}
  87. */
  88. public function getParent(array $options)
  89. {
  90. return 'field';
  91. }
  92. /**
  93. * {@inheritdoc}
  94. */
  95. public function getName()
  96. {
  97. return 'jquery_doctrine_autocomplete';
  98. }
  99. /**
  100. * {@inheritdoc}
  101. */
  102. function transform($entity)
  103. {
  104. if (null === $entity || '' === $entity) {
  105. return '';
  106. }
  107. if (!is_object($entity)) {
  108. throw new UnexpectedTypeException($entity, 'object');
  109. }
  110. return call_user_func(array($entity, $this->options['key_method']));
  111. }
  112. function reverseTransform($key)
  113. {
  114. if ('' === $key || null === $key) {
  115. return null;
  116. }
  117. if (!is_numeric($key)) {
  118. throw new UnexpectedTypeException($key, 'numeric');
  119. }
  120. $repository = $this->options['em']->getRepository($this->options['class']);
  121. if (!($entity = call_user_func(array($repository, $this->options['method_for_query']), $key))) {
  122. throw new TransformationFailedException(sprintf('The entity with key "%s" could not be found', $key));
  123. }
  124. return $entity;
  125. }
  126. }