FormExtension.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  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 Symfony\Bridge\Twig\Extension;
  11. use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser;
  12. use Symfony\Bridge\Twig\Form\TwigRendererInterface;
  13. use Symfony\Component\DependencyInjection\ContainerInterface;
  14. use Symfony\Component\Form\ChoiceList\View\ChoiceView;
  15. use Twig\Environment;
  16. use Twig\Extension\AbstractExtension;
  17. use Twig\Extension\InitRuntimeInterface;
  18. use Twig\TwigFilter;
  19. use Twig\TwigFunction;
  20. use Twig\TwigTest;
  21. /**
  22. * FormExtension extends Twig with form capabilities.
  23. *
  24. * @author Fabien Potencier <fabien@symfony.com>
  25. * @author Bernhard Schussek <bschussek@gmail.com>
  26. */
  27. class FormExtension extends AbstractExtension implements InitRuntimeInterface
  28. {
  29. /**
  30. * @deprecated since version 3.2, to be removed in 4.0 alongside with magic methods below
  31. */
  32. private $renderer;
  33. public function __construct($renderer = null)
  34. {
  35. if ($renderer instanceof TwigRendererInterface) {
  36. @trigger_error(sprintf('Passing a Twig Form Renderer to the "%s" constructor is deprecated since version 3.2 and won\'t be possible in 4.0. Pass the Twig\Environment to the TwigRendererEngine constructor instead.', static::class), E_USER_DEPRECATED);
  37. } elseif (null !== $renderer && !(is_array($renderer) && isset($renderer[0], $renderer[1]) && $renderer[0] instanceof ContainerInterface)) {
  38. throw new \InvalidArgumentException(sprintf('Passing any arguments the constructor of %s is reserved for internal use.', __CLASS__));
  39. }
  40. $this->renderer = $renderer;
  41. }
  42. /**
  43. * {@inheritdoc}
  44. *
  45. * To be removed in 4.0
  46. */
  47. public function initRuntime(Environment $environment)
  48. {
  49. if ($this->renderer instanceof TwigRendererInterface) {
  50. $this->renderer->setEnvironment($environment);
  51. } elseif (null !== $this->renderer) {
  52. $this->renderer[2] = $environment;
  53. }
  54. }
  55. /**
  56. * {@inheritdoc}
  57. */
  58. public function getTokenParsers()
  59. {
  60. return array(
  61. // {% form_theme form "SomeBundle::widgets.twig" %}
  62. new FormThemeTokenParser(),
  63. );
  64. }
  65. /**
  66. * {@inheritdoc}
  67. */
  68. public function getFunctions()
  69. {
  70. return array(
  71. new TwigFunction('form_widget', null, array('node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => array('html'))),
  72. new TwigFunction('form_errors', null, array('node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => array('html'))),
  73. new TwigFunction('form_label', null, array('node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => array('html'))),
  74. new TwigFunction('form_row', null, array('node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => array('html'))),
  75. new TwigFunction('form_rest', null, array('node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => array('html'))),
  76. new TwigFunction('form', null, array('node_class' => 'Symfony\Bridge\Twig\Node\RenderBlockNode', 'is_safe' => array('html'))),
  77. new TwigFunction('form_start', null, array('node_class' => 'Symfony\Bridge\Twig\Node\RenderBlockNode', 'is_safe' => array('html'))),
  78. new TwigFunction('form_end', null, array('node_class' => 'Symfony\Bridge\Twig\Node\RenderBlockNode', 'is_safe' => array('html'))),
  79. new TwigFunction('csrf_token', array('Symfony\Bridge\Twig\Form\TwigRenderer', 'renderCsrfToken')),
  80. );
  81. }
  82. /**
  83. * {@inheritdoc}
  84. */
  85. public function getFilters()
  86. {
  87. return array(
  88. new TwigFilter('humanize', array('Symfony\Bridge\Twig\Form\TwigRenderer', 'humanize')),
  89. );
  90. }
  91. /**
  92. * {@inheritdoc}
  93. */
  94. public function getTests()
  95. {
  96. return array(
  97. new TwigTest('selectedchoice', 'Symfony\Bridge\Twig\Extension\twig_is_selected_choice'),
  98. );
  99. }
  100. /**
  101. * @internal
  102. */
  103. public function __get($name)
  104. {
  105. if ('renderer' === $name) {
  106. @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
  107. if (is_array($this->renderer)) {
  108. $renderer = $this->renderer[0]->get($this->renderer[1]);
  109. if (isset($this->renderer[2])) {
  110. $renderer->setEnvironment($this->renderer[2]);
  111. }
  112. $this->renderer = $renderer;
  113. }
  114. }
  115. return $this->$name;
  116. }
  117. /**
  118. * @internal
  119. */
  120. public function __set($name, $value)
  121. {
  122. if ('renderer' === $name) {
  123. @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
  124. }
  125. $this->$name = $value;
  126. }
  127. /**
  128. * @internal
  129. */
  130. public function __isset($name)
  131. {
  132. if ('renderer' === $name) {
  133. @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
  134. }
  135. return isset($this->$name);
  136. }
  137. /**
  138. * @internal
  139. */
  140. public function __unset($name)
  141. {
  142. if ('renderer' === $name) {
  143. @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
  144. }
  145. unset($this->$name);
  146. }
  147. /**
  148. * {@inheritdoc}
  149. */
  150. public function getName()
  151. {
  152. return 'form';
  153. }
  154. }
  155. /**
  156. * Returns whether a choice is selected for a given form value.
  157. *
  158. * This is a function and not callable due to performance reasons.
  159. *
  160. * @param string|array $selectedValue The selected value to compare
  161. *
  162. * @return bool Whether the choice is selected
  163. *
  164. * @see ChoiceView::isSelected()
  165. */
  166. function twig_is_selected_choice(ChoiceView $choice, $selectedValue)
  167. {
  168. if (is_array($selectedValue)) {
  169. return in_array($choice->value, $selectedValue, true);
  170. }
  171. return $choice->value === $selectedValue;
  172. }