Skip to content

FormTypeGuesser overrides FormBuilder options #19871

Closed
@miguelsimoes

Description

@miguelsimoes

At the Symfony\Component\Form\FormFactory code of release 2.8.x, line 155 we have:

if ($typeGuess) {
    $options = array_merge($typeGuess->getOptions(), $options);
}

This line breaks the generation of the options being added by a custom TypeGuesser as the below example shows. The suggestion is to use array_merge_recursive instead.

Example:
Assume TypeGuesser::guessMaxLength() returns a max_length to be added to the input, and then, on the TypeGuess::guessType() it is returned another attribute to be added to the input (for example: a data-* thing for javascript or even a class attribute).

What happens is shown on the next "dumps".

$typeGuess->getOptions() returns:

array (size=2)
  'label' => string 'Name' (length=4)
  'attr' => 
    array (size=1)
      'class' => string 'cenas' (length=5)

$options is populated with:

array (size=4)
  'required' => boolean true
  'attr' => 
    array (size=1)
      'maxlength' => int 50
  'disabled' => boolean false
  'constraints' => 
    array (size=2)
      0 => 
        object(Symfony\Component\Validator\Constraints\NotBlank)[573]
          public 'message' => string 'This value should not be blank.' (length=31)
          public 'payload' => null
      1 => 
        object(Symfony\Component\Validator\Constraints\Length)[574]
          public 'maxMessage' => string 'This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.' (length=140)
          public 'minMessage' => string 'This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.' (length=142)
          public 'exactMessage' => string 'This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.' (length=108)
          public 'charsetMessage' => string 'This value does not match the expected {{ charset }} charset.' (length=61)
          public 'max' => int 50
          public 'min' => null
          public 'charset' => string 'UTF-8' (length=5)
          public 'payload' => null

When the merge is executed, we get:

array (size=5)
  'label' => string 'Name' (length=4)
  'attr' => 
    array (size=1)
      'maxlength' => int 50
  'required' => boolean true
  'disabled' => boolean false
  'constraints' => 
    array (size=2)
      0 => 
        object(Symfony\Component\Validator\Constraints\NotBlank)[573]
          public 'message' => string 'This value should not be blank.' (length=31)
          public 'payload' => null
      1 => 
        object(Symfony\Component\Validator\Constraints\Length)[574]
          public 'maxMessage' => string 'This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.' (length=140)
          public 'minMessage' => string 'This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.' (length=142)
          public 'exactMessage' => string 'This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.' (length=108)
          public 'charsetMessage' => string 'This value does not match the expected {{ charset }} charset.' (length=61)
          public 'max' => int 50
          public 'min' => null
          public 'charset' => string 'UTF-8' (length=5)
          public 'payload' => null

Instead of the expected result:

array (size=5)
  'label' => string 'Name' (length=4)
  'attr' => 
    array (size=2)
      'class' => string 'cenas' (length=5)
      'maxlength' => int 50
  'required' => boolean true
  'disabled' => boolean false
  'constraints' => 
    array (size=2)
      0 => 
        object(Symfony\Component\Validator\Constraints\NotBlank)[573]
          public 'message' => string 'This value should not be blank.' (length=31)
          public 'payload' => null
      1 => 
        object(Symfony\Component\Validator\Constraints\Length)[574]
          public 'maxMessage' => string 'This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.' (length=140)
          public 'minMessage' => string 'This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.' (length=142)
          public 'exactMessage' => string 'This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.' (length=108)
          public 'charsetMessage' => string 'This value does not match the expected {{ charset }} charset.' (length=61)
          public 'max' => int 50
          public 'min' => null
          public 'charset' => string 'UTF-8' (length=5)
          public 'payload' => null

Notice that on the expected result we have 2 elements on the 'attr' index of the options, but with the current code we only get 1 element (the max_length).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions