vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/FormType.php line 132

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\Component\Form\Extension\Core\Type;
  11. use Symfony\Component\Form\FormBuilderInterface;
  12. use Symfony\Component\Form\FormInterface;
  13. use Symfony\Component\Form\FormView;
  14. use Symfony\Component\Form\Extension\Core\EventListener\TrimListener;
  15. use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
  16. use Symfony\Component\Form\Exception\LogicException;
  17. use Symfony\Component\OptionsResolver\Options;
  18. use Symfony\Component\OptionsResolver\OptionsResolver;
  19. use Symfony\Component\PropertyAccess\PropertyAccess;
  20. use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
  21. class FormType extends BaseType
  22. {
  23.     private $propertyAccessor;
  24.     public function __construct(PropertyAccessorInterface $propertyAccessor null)
  25.     {
  26.         $this->propertyAccessor $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
  27.     }
  28.     /**
  29.      * {@inheritdoc}
  30.      */
  31.     public function buildForm(FormBuilderInterface $builder, array $options)
  32.     {
  33.         parent::buildForm($builder$options);
  34.         $isDataOptionSet array_key_exists('data'$options);
  35.         $builder
  36.             ->setRequired($options['required'])
  37.             ->setErrorBubbling($options['error_bubbling'])
  38.             ->setEmptyData($options['empty_data'])
  39.             ->setPropertyPath($options['property_path'])
  40.             ->setMapped($options['mapped'])
  41.             ->setByReference($options['by_reference'])
  42.             ->setInheritData($options['inherit_data'])
  43.             ->setCompound($options['compound'])
  44.             ->setData($isDataOptionSet $options['data'] : null)
  45.             ->setDataLocked($isDataOptionSet)
  46.             ->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)
  47.             ->setMethod($options['method'])
  48.             ->setAction($options['action']);
  49.         if ($options['trim']) {
  50.             $builder->addEventSubscriber(new TrimListener());
  51.         }
  52.     }
  53.     /**
  54.      * {@inheritdoc}
  55.      */
  56.     public function buildView(FormView $viewFormInterface $form, array $options)
  57.     {
  58.         parent::buildView($view$form$options);
  59.         $name $form->getName();
  60.         if ($view->parent) {
  61.             if ('' === $name) {
  62.                 throw new LogicException('Form node with empty name can be used only as root form node.');
  63.             }
  64.             // Complex fields are read-only if they themselves or their parents are.
  65.             if (!isset($view->vars['attr']['readonly']) && isset($view->parent->vars['attr']['readonly']) && false !== $view->parent->vars['attr']['readonly']) {
  66.                 $view->vars['attr']['readonly'] = true;
  67.             }
  68.         }
  69.         $view->vars array_replace($view->vars, array(
  70.             'errors' => $form->getErrors(),
  71.             'valid' => $form->isSubmitted() ? $form->isValid() : true,
  72.             'value' => $form->getViewData(),
  73.             'data' => $form->getNormData(),
  74.             'required' => $form->isRequired(),
  75.             'size' => null,
  76.             'label_attr' => $options['label_attr'],
  77.             'compound' => $form->getConfig()->getCompound(),
  78.             'method' => $form->getConfig()->getMethod(),
  79.             'action' => $form->getConfig()->getAction(),
  80.             'submitted' => $form->isSubmitted(),
  81.         ));
  82.     }
  83.     /**
  84.      * {@inheritdoc}
  85.      */
  86.     public function finishView(FormView $viewFormInterface $form, array $options)
  87.     {
  88.         $multipart false;
  89.         foreach ($view->children as $child) {
  90.             if ($child->vars['multipart']) {
  91.                 $multipart true;
  92.                 break;
  93.             }
  94.         }
  95.         $view->vars['multipart'] = $multipart;
  96.     }
  97.     /**
  98.      * {@inheritdoc}
  99.      */
  100.     public function configureOptions(OptionsResolver $resolver)
  101.     {
  102.         parent::configureOptions($resolver);
  103.         // Derive "data_class" option from passed "data" object
  104.         $dataClass = function (Options $options) {
  105.             return isset($options['data']) && is_object($options['data']) ? get_class($options['data']) : null;
  106.         };
  107.         // Derive "empty_data" closure from "data_class" option
  108.         $emptyData = function (Options $options) {
  109.             $class $options['data_class'];
  110.             if (null !== $class) {
  111.                 return function (FormInterface $form) use ($class) {
  112.                     return $form->isEmpty() && !$form->isRequired() ? null : new $class();
  113.                 };
  114.             }
  115.             return function (FormInterface $form) {
  116.                 return $form->getConfig()->getCompound() ? array() : '';
  117.             };
  118.         };
  119.         // Wrap "post_max_size_message" in a closure to translate it lazily
  120.         $uploadMaxSizeMessage = function (Options $options) {
  121.             return function () use ($options) {
  122.                 return $options['post_max_size_message'];
  123.             };
  124.         };
  125.         // For any form that is not represented by a single HTML control,
  126.         // errors should bubble up by default
  127.         $errorBubbling = function (Options $options) {
  128.             return $options['compound'];
  129.         };
  130.         // If data is given, the form is locked to that data
  131.         // (independent of its value)
  132.         $resolver->setDefined(array(
  133.             'data',
  134.         ));
  135.         $resolver->setDefaults(array(
  136.             'data_class' => $dataClass,
  137.             'empty_data' => $emptyData,
  138.             'trim' => true,
  139.             'required' => true,
  140.             'property_path' => null,
  141.             'mapped' => true,
  142.             'by_reference' => true,
  143.             'error_bubbling' => $errorBubbling,
  144.             'label_attr' => array(),
  145.             'inherit_data' => false,
  146.             'compound' => true,
  147.             'method' => 'POST',
  148.             // According to RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt)
  149.             // section 4.2., empty URIs are considered same-document references
  150.             'action' => '',
  151.             'attr' => array(),
  152.             'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
  153.             'upload_max_size_message' => $uploadMaxSizeMessage// internal
  154.         ));
  155.         $resolver->setAllowedTypes('label_attr''array');
  156.         $resolver->setAllowedTypes('upload_max_size_message', array('callable'));
  157.     }
  158.     /**
  159.      * {@inheritdoc}
  160.      */
  161.     public function getParent()
  162.     {
  163.     }
  164.     /**
  165.      * {@inheritdoc}
  166.      */
  167.     public function getBlockPrefix()
  168.     {
  169.         return 'form';
  170.     }
  171. }