vendor/symfony/twig-bridge/Extension/FormExtension.php line 35

Open in your IDE?
  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\Component\Form\ChoiceList\View\ChoiceGroupView;
  13. use Symfony\Component\Form\ChoiceList\View\ChoiceView;
  14. use Symfony\Component\Form\FormError;
  15. use Symfony\Component\Form\FormView;
  16. use Symfony\Contracts\Translation\TranslatorInterface;
  17. use Twig\Extension\AbstractExtension;
  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. final class FormExtension extends AbstractExtension
  28. {
  29.     private $translator;
  30.     public function __construct(TranslatorInterface $translator null)
  31.     {
  32.         $this->translator $translator;
  33.     }
  34.     /**
  35.      * {@inheritdoc}
  36.      */
  37.     public function getTokenParsers(): array
  38.     {
  39.         return [
  40.             // {% form_theme form "SomeBundle::widgets.twig" %}
  41.             new FormThemeTokenParser(),
  42.         ];
  43.     }
  44.     /**
  45.      * {@inheritdoc}
  46.      */
  47.     public function getFunctions(): array
  48.     {
  49.         return [
  50.             new TwigFunction('form_widget'null, ['node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode''is_safe' => ['html']]),
  51.             new TwigFunction('form_errors'null, ['node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode''is_safe' => ['html']]),
  52.             new TwigFunction('form_label'null, ['node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode''is_safe' => ['html']]),
  53.             new TwigFunction('form_help'null, ['node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode''is_safe' => ['html']]),
  54.             new TwigFunction('form_row'null, ['node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode''is_safe' => ['html']]),
  55.             new TwigFunction('form_rest'null, ['node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode''is_safe' => ['html']]),
  56.             new TwigFunction('form'null, ['node_class' => 'Symfony\Bridge\Twig\Node\RenderBlockNode''is_safe' => ['html']]),
  57.             new TwigFunction('form_start'null, ['node_class' => 'Symfony\Bridge\Twig\Node\RenderBlockNode''is_safe' => ['html']]),
  58.             new TwigFunction('form_end'null, ['node_class' => 'Symfony\Bridge\Twig\Node\RenderBlockNode''is_safe' => ['html']]),
  59.             new TwigFunction('csrf_token', ['Symfony\Component\Form\FormRenderer''renderCsrfToken']),
  60.             new TwigFunction('form_parent''Symfony\Bridge\Twig\Extension\twig_get_form_parent'),
  61.             new TwigFunction('field_name', [$this'getFieldName']),
  62.             new TwigFunction('field_value', [$this'getFieldValue']),
  63.             new TwigFunction('field_label', [$this'getFieldLabel']),
  64.             new TwigFunction('field_help', [$this'getFieldHelp']),
  65.             new TwigFunction('field_errors', [$this'getFieldErrors']),
  66.             new TwigFunction('field_choices', [$this'getFieldChoices']),
  67.         ];
  68.     }
  69.     /**
  70.      * {@inheritdoc}
  71.      */
  72.     public function getFilters(): array
  73.     {
  74.         return [
  75.             new TwigFilter('humanize', ['Symfony\Component\Form\FormRenderer''humanize']),
  76.             new TwigFilter('form_encode_currency', ['Symfony\Component\Form\FormRenderer''encodeCurrency'], ['is_safe' => ['html'], 'needs_environment' => true]),
  77.         ];
  78.     }
  79.     /**
  80.      * {@inheritdoc}
  81.      */
  82.     public function getTests(): array
  83.     {
  84.         return [
  85.             new TwigTest('selectedchoice''Symfony\Bridge\Twig\Extension\twig_is_selected_choice'),
  86.             new TwigTest('rootform''Symfony\Bridge\Twig\Extension\twig_is_root_form'),
  87.         ];
  88.     }
  89.     public function getFieldName(FormView $view): string
  90.     {
  91.         $view->setRendered();
  92.         return $view->vars['full_name'];
  93.     }
  94.     /**
  95.      * @return string|array
  96.      */
  97.     public function getFieldValue(FormView $view)
  98.     {
  99.         return $view->vars['value'];
  100.     }
  101.     public function getFieldLabel(FormView $view): ?string
  102.     {
  103.         if (false === $label $view->vars['label']) {
  104.             return null;
  105.         }
  106.         if (!$label && $labelFormat $view->vars['label_format']) {
  107.             $label str_replace(['%id%''%name%'], [$view->vars['id'], $view->vars['name']], $labelFormat);
  108.         } elseif (!$label) {
  109.             $label ucfirst(strtolower(trim(preg_replace(['/([A-Z])/''/[_\s]+/'], ['_$1'' '], $view->vars['name']))));
  110.         }
  111.         return $this->createFieldTranslation(
  112.             $label,
  113.             $view->vars['label_translation_parameters'] ?: [],
  114.             $view->vars['translation_domain']
  115.         );
  116.     }
  117.     public function getFieldHelp(FormView $view): ?string
  118.     {
  119.         return $this->createFieldTranslation(
  120.             $view->vars['help'],
  121.             $view->vars['help_translation_parameters'] ?: [],
  122.             $view->vars['translation_domain']
  123.         );
  124.     }
  125.     /**
  126.      * @return string[]
  127.      */
  128.     public function getFieldErrors(FormView $view): iterable
  129.     {
  130.         /** @var FormError $error */
  131.         foreach ($view->vars['errors'] as $error) {
  132.             yield $error->getMessage();
  133.         }
  134.     }
  135.     /**
  136.      * @return string[]|string[][]
  137.      */
  138.     public function getFieldChoices(FormView $view): iterable
  139.     {
  140.         yield from $this->createFieldChoicesList($view->vars['choices'], $view->vars['choice_translation_domain']);
  141.     }
  142.     private function createFieldChoicesList(iterable $choices$translationDomain): iterable
  143.     {
  144.         foreach ($choices as $choice) {
  145.             $translatableLabel $this->createFieldTranslation($choice->label, [], $translationDomain);
  146.             if ($choice instanceof ChoiceGroupView) {
  147.                 yield $translatableLabel => $this->createFieldChoicesList($choice$translationDomain);
  148.                 continue;
  149.             }
  150.             /* @var ChoiceView $choice */
  151.             yield $translatableLabel => $choice->value;
  152.         }
  153.     }
  154.     private function createFieldTranslation(?string $value, array $parameters$domain): ?string
  155.     {
  156.         if (!$this->translator || !$value || false === $domain) {
  157.             return $value;
  158.         }
  159.         return $this->translator->trans($value$parameters$domain);
  160.     }
  161. }
  162. /**
  163.  * Returns whether a choice is selected for a given form value.
  164.  *
  165.  * This is a function and not callable due to performance reasons.
  166.  *
  167.  * @param string|array $selectedValue The selected value to compare
  168.  *
  169.  * @see ChoiceView::isSelected()
  170.  */
  171. function twig_is_selected_choice(ChoiceView $choice$selectedValue): bool
  172. {
  173.     if (\is_array($selectedValue)) {
  174.         return \in_array($choice->value$selectedValuetrue);
  175.     }
  176.     return $choice->value === $selectedValue;
  177. }
  178. /**
  179.  * @internal
  180.  */
  181. function twig_is_root_form(FormView $formView): bool
  182. {
  183.     return null === $formView->parent;
  184. }
  185. /**
  186.  * @internal
  187.  */
  188. function twig_get_form_parent(FormView $formView): ?FormView
  189. {
  190.     return $formView->parent;
  191. }