1
votes

I have been able to upload and retrieve images from MongoDB in Symfony2 with Doctrine thanks to this example in the Cookbook: http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html

But when I open the form to update the image (change the existing with another image), this exception is raised:

The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is an instance of class Doctrine\MongoDB\GridFSFile. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms an instance of class Doctrine\MongoDB\GridFSFile to an instance of Symfony\Component\HttpFoundation\File\File.

I tried to change the 'data_class' to null like the solution of this thread: Symfony 2 | Form exception when modifying an object that has a file(picture) field but another exception is raised:

The form's view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is an instance of class Doctrine\MongoDB\GridFSFile. You can avoid this error by setting the "data_class" option to "Doctrine\MongoDB\GridFSFile" or by adding a view transformer that transforms an instance of class Doctrine\MongoDB\GridFSFile to scalar, array or an instance of \ArrayAccess.

Here is my Document Class:

<?php

namespace ChildCare\AdminBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * @MongoDB\Document
 */
class Carousel {

    /**
     * @MongoDB\Id
     */
    protected $id;

    /**
     * @MongoDB\String
     */
    protected $title;

    /**
     * @MongoDB\String
     */
    protected $path;

    public function getAbsolutePath() {
        return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path;
    }

    public function getWebPath() {
        return null === $this->path ? null : $this->getUploadDir() . '/' . $this->path;
    }

    protected function getUploadRootDir() {
        return __DIR__ . '/../../../../web/' . $this->getUploadDir();
    }

    protected function getUploadDir() {
        return 'bundles/childcare/img/carousel';
    }

    /**
     * @MongoDB\File
     */
    protected $file;

    /**
     * @MongoDB\String
     */
    protected $content;

    /**
     * @MongoDB\Date
     */
    protected $date;

    /**
     * Get id
     *
     * @return id $id
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set title
     *
     * @param string $title
     * @return self
     */
    public function setTitle($title) {
        $this->title = $title;
        return $this;
    }

    /**
     * Get title
     *
     * @return string $title
     */
    public function getTitle() {
        return $this->title;
    }

    /**
     * Set path
     *
     * @param string $path
     * @return self
     */
    public function setPath($path) {
        $this->path = $path;
        return $this;
    }

    /**
     * Get path
     *
     * @return string $path
     */
    public function getPath() {
        return $this->path;
    }


    /**
     * Set file.
     *
     * @param UploadedFile $file
     */
    public function setFile(UploadedFile $file = null) {
        $this->file = $file;
    }

    /**
     * Get file.
     *
     * @return UploadedFile
     */
    public function getFile() {
        return $this->file;
    }

    /**
     * Set content
     *
     * @param string $content
     * @return self
     */
    public function setContent($content) {
        $this->content = $content;
        return $this;
    }

    /**
     * Get content
     *
     * @return string $content
     */
    public function getContent() {
        return $this->content;
    }

    /**
     * Set date
     *
     * @param date $date
     * @return self
     */
    public function setDate($date) {
        $this->date = $date;
        return $this;
    }

    /**
     * Get date
     *
     * @return date $date
     */
    public function getDate() {
        return $this->date;
    }

    public function upload() {
        if (null === $this->getFile()) {
            return;
        }

        $this->getFile()->move(
                $this->getUploadRootDir(), $this->getFile()->getClientOriginalName()
        );

        $this->path = $this->getUploadDir() . '/' . $this->getFile()->getClientOriginalName();

        $this->file = null;
    }

}

And this is a part of the Action in my Controller:

$form = $this->createFormBuilder($carousel)
                ->add('title', 'text')
                ->add('file', 'file', array(
                    'data_class' => null
                ))
                ->add('content', 'textarea', array(
                    'attr' => array('cols' => '5', 'rows' => '10')
                ))
                ->add('save', 'submit')
                ->getForm();

        $form->handleRequest($request);

        if ($form->isValid()) {
            $carousel->setTitle($form['title']->getData());
            $carousel->setContent($form['content']->getData());
            $carousel->setDate(new \DateTime());
            $carousel->upload();
            if ($id == 'create') {
                $dm->persist($carousel);
                $dm->flush();
                return $this->redirect($this->generateUrl('admin_page_info'));
            } else {
                $dm->flush();
                return $this->redirect($this->generateUrl('admin_page_info'));
            }
        }
        return $this->render('ChildCareAdminBundle:WebInfo:editCarousel.html.twig', array(
                    'form' => $form->createView()));
1

1 Answers

2
votes

Solution found by myself! Just set 'data_class' => 'Doctrine\MongoDB\GridFSFile' as following:

$form = $this->createFormBuilder($carousel)
                ->add('title', 'text')
                ->add('file', 'file', array(
                    'data_class' => 'Doctrine\MongoDB\GridFSFile'
                ))
                ->add('content', 'textarea', array(
                    'attr' => array('cols' => '5', 'rows' => '10')
                ))
                ->add('save', 'submit')
                ->getForm();