vendor/symfony/form/FormFactory.php line 52

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <[email protected]>
  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;
  11. use Symfony\Component\Form\Extension\Core\Type\FormType;
  12. use Symfony\Component\Form\Extension\Core\Type\TextType;
  13. class FormFactory implements FormFactoryInterface
  14. {
  15. private FormRegistryInterface $registry;
  16. public function __construct(FormRegistryInterface $registry)
  17. {
  18. $this->registry = $registry;
  19. }
  20. public function create(string $type = FormType::class, mixed $data = null, array $options = []): FormInterface
  21. {
  22. return $this->createBuilder($type, $data, $options)->getForm();
  23. }
  24. public function createNamed(string $name, string $type = FormType::class, mixed $data = null, array $options = []): FormInterface
  25. {
  26. return $this->createNamedBuilder($name, $type, $data, $options)->getForm();
  27. }
  28. public function createForProperty(string $class, string $property, mixed $data = null, array $options = []): FormInterface
  29. {
  30. return $this->createBuilderForProperty($class, $property, $data, $options)->getForm();
  31. }
  32. public function createBuilder(string $type = FormType::class, mixed $data = null, array $options = []): FormBuilderInterface
  33. {
  34. return $this->createNamedBuilder($this->registry->getType($type)->getBlockPrefix(), $type, $data, $options);
  35. }
  36. public function createNamedBuilder(string $name, string $type = FormType::class, mixed $data = null, array $options = []): FormBuilderInterface
  37. {
  38. if (null !== $data && !\array_key_exists('data', $options)) {
  39. $options['data'] = $data;
  40. }
  41. $type = $this->registry->getType($type);
  42. $builder = $type->createBuilder($this, $name, $options);
  43. // Explicitly call buildForm() in order to be able to override either
  44. // createBuilder() or buildForm() in the resolved form type
  45. $type->buildForm($builder, $builder->getOptions());
  46. return $builder;
  47. }
  48. public function createBuilderForProperty(string $class, string $property, mixed $data = null, array $options = []): FormBuilderInterface
  49. {
  50. if (null === $guesser = $this->registry->getTypeGuesser()) {
  51. return $this->createNamedBuilder($property, TextType::class, $data, $options);
  52. }
  53. $typeGuess = $guesser->guessType($class, $property);
  54. $maxLengthGuess = $guesser->guessMaxLength($class, $property);
  55. $requiredGuess = $guesser->guessRequired($class, $property);
  56. $patternGuess = $guesser->guessPattern($class, $property);
  57. $type = $typeGuess ? $typeGuess->getType() : TextType::class;
  58. $maxLength = $maxLengthGuess?->getValue();
  59. $pattern = $patternGuess?->getValue();
  60. if (null !== $pattern) {
  61. $options = array_replace_recursive(['attr' => ['pattern' => $pattern]], $options);
  62. }
  63. if (null !== $maxLength) {
  64. $options = array_replace_recursive(['attr' => ['maxlength' => $maxLength]], $options);
  65. }
  66. if ($requiredGuess) {
  67. $options = array_merge(['required' => $requiredGuess->getValue()], $options);
  68. }
  69. // user options may override guessed options
  70. if ($typeGuess) {
  71. $attrs = [];
  72. $typeGuessOptions = $typeGuess->getOptions();
  73. if (isset($typeGuessOptions['attr']) && isset($options['attr'])) {
  74. $attrs = ['attr' => array_merge($typeGuessOptions['attr'], $options['attr'])];
  75. }
  76. $options = array_merge($typeGuessOptions, $options, $attrs);
  77. }
  78. return $this->createNamedBuilder($property, $type, $data, $options);
  79. }
  80. }