Search code examples
formsdoctrine-ormsymfonyfosrestbundle

Use "not required" in Symfony3 when building forms with FosrestBundle


I'm building an API with FosrestBundle and Symfony3. In some part of my work, I've to build forms, and I want some fields of my form set to "not required". But I got errors when I tried creating them.

Here is how I created a form for one of my entity : "Question".

Firstly I created a QuestionType class where I set a required to false:

class QuestionType extends AbstractType{

public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder->add('libelle');
    $builder->add('description');
    $builder->add('imageRoot');
    $builder->add('page', 'integer', array('required' => false));
    $builder->add('ligne', 'integer', array('required' => false));

}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => 'AppBundle\Entity\Question',
        'csrf_protection' => false
    ]);
}
}

Secondly, I configured validation parameters in my validation.yml file :

AppBundle\Entity\Question:
properties:
    libelle:
        - NotBlank: ~
        - Type: string
    description:
        - NotBlank: ~
        - Type: string
    imageRoot:
        - Type: string
    page:
        - Type: integer
        - GreaterThan:
            value: 0
        - LessThanOrEqual:
            value: 1000

    ligne:
        - Type: integer
        - GreaterThan:
            value: 0
        - LessThanOrEqual:
            value: 1000

Thirdly, I created my form in a controller

class ContenuController extends Controller{

/**
 * @Rest\View(serializerGroups={"contenu"}, statusCode=Response::HTTP_CREATED)
 * @Rest\Post("/lectureContenu/{id}/Questions")
 */
public function postQuestionAction(Request $request)
{
    $em = $this->getDoctrine()->getEntityManager();
    $contenu = $em->getRepository('AppBundle:Contenu')->find($request->get('id'));
    $typeQuestion = $em->getRepository('AppBundle:TypeQuestion')->find(1);

    if (empty($contenu)) {
        return new JsonResponse(['message' => 'Contenu de la question inexistant'], Response::HTTP_NOT_FOUND);
    }

    $question = new Question();
    $question->setContenu($contenu)
             ->setTypeQuestion($typeQuestion);

    $form = $this->createForm(QuestionType::class, $question);
    $form->submit($request->request->all()); // Validation des données

    if ($form->isValid()) {
        $em->persist($question);
        $em->flush();

        return $question;
    } else {
        return $form;
    }

  }
 }

Finally, when I run my code with the example below (using Postman) :

 {
  "libelle": "test",
  "description": "test",
  "imageRoot": "test"
 }

I got this error :

...
"message": "Could not load type \"integer\"",
"class": "Symfony\\Component\\Form\\Exception\\InvalidArgumentException",
...

I don't know why ! For me, everything seems correct. Please help !


Solution

  • I put my comment as an answer to remove this question from the unanswered ones.

    Types names were deprecated in Symfony 2.8 and removed in Symfony 3.

    When you add child to your form type, you have to use the fully qualified name (FQN) of the type. You can do it in 2 ways (exemple with your Integer type)

    $builder->add('page', IntegerType::class)
    

    or

    $builder->add('page', 'Symfony\Component\Form\Extension\Core\Type\IntegerType');
    

    If you use the first option, don't forget to import the class in your class definition:

    use Symfony\Component\Form\Extension\Core\Type\IntegerType;
    

    The list of all types is available here : https://symfony.com/doc/current/reference/forms/types.html