Search code examples
jsonsymfonyfosrestbundle

How to create nested objects with FOSRestBundle and FormType?


I'm developing an API with symfony2 + FOSRestBundle and I have two errors. Below is my code:

Property

/**
 * Property
 *
 * @ORM\Table(name="property")
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"house" = "House"})
 */
abstract class Property {

    /**
     * @ORM\OneToMany(targetEntity="Image", mappedBy="property", cascade={"persist"})
     * */
    private $images;


    function getImages() {
        return $this->images;
    }

    function setImages($images) {
        $this->images = $images;
    }


}

House

class House extends Property
{
/* More code */
}

Image

class Image {

    /**
     * @ORM\Column(name="content", type="text", nullable=false)
     */
    private $content;

    /**
     * @ORM\ManyToOne(targetEntity="Property", inversedBy="images")
     * @ORM\JoinColumn(name="propertyId", referencedColumnName="id")
     * */
    private $property;
}

PropertyType

class PropertyType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('images');


        $builder->get('images')
                ->addModelTransformer(new CallbackTransformer(
                        function($images) {
                            $image = new \Cboujon\PropertyBundle\Entity\Image();
                            $image->setContent('test of content');
                            return array($image);
                }, function($imagesContents) {

                }));
    }

HouseRESTController

/**
 * @View(statusCode=201, serializerEnableMaxDepthChecks=true)
 *
 * @param Request $request
 *
 * @return Response
 *
 */
public function postAction(Request $request)
{ 
    $entity = new House(); 
    $form = $this->createForm(new HouseType(), $entity, array("method" => $request->getMethod()));
    $this->removeExtraFields($request, $form);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $entity;
    }

When I create a new house, I send this (simplified) JSON:

{"images":["base64ContentImage_1", "base64ContentImage_2"]}

First Problem: The $images parameter in the first function passed to the CallbackTransformer is NULL. Why?

Second problem: I order to test and understand the first problem, I forced to create an image entity as you can see but I get a JSON response with the error "Entities passed to the choice field must be managed. Maybe persist them in the entity manager?"

Can anyone help me to solve any of two problem?


Solution

  • I have found one solution

    I have been created ImageType

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);
        $builder
            ->add('content')
        ;
    }
    

    And also I have been modified PropertyType

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
                ->add('title')
                ->add('description')
                ->add('price')
                ->add('services')
                ->add('images', 'collection', array(
                    'type' => new ImageType(),
                    'allow_add' => true,
                ))
        ;
    }
    

    And finally, I was changed the JSON structure of my request:

    {"images":[{content: "base64ContentImage_1"}, {content:"base64ContentImage_2"}]}