user3703456
user3703456

Reputation:

Symfony2 Upload / Cannot save to the folder

Could you help me resolve this issue? I tried this tutorial: Symfony Upload

It works fine(stored to the database path to img), but don't store or move image to the folder.

Entity:

    <?php
namespace DbBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;


/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class File
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    public $name;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    public $path;

    /**
     * @Assert\File(maxSize="6000000")
     */
    private $file;

    private $temp;

    /**
     * Sets file.
     *
     * @param UploadedFile $file
     */
    public function setFile(UploadedFile $file = null)
    {
        $this->file = $file;
        // check if we have an old image path
        if (isset($this->path)) {
            // store the old name to delete after the update
            $this->temp = $this->path;
            $this->path = null;
        } else {
            $this->path = 'initial';
        }
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload()
    {
        if (null !== $this->getFile()) {
            // do whatever you want to generate a unique name
            $filename = sha1(uniqid(mt_rand(), true));
            $this->path = $filename.'.'.$this->getFile()->guessExtension();
        }
    }

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

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload()
    {
        if (null === $this->getFile()) {
            return;
        }

        // if there is an error when moving the file, an exception will
        // be automatically thrown by move(). This will properly prevent
        // the entity from being persisted to the database on error
        $this->getFile()->move($this->getUploadRootDir(), $this->path);

        // check if we have an old image
        if (isset($this->temp)) {
            // delete the old image
            unlink($this->getUploadRootDir().'/'.$this->temp);
            // clear the temp image path
            $this->temp = null;
        }
        $this->file = null;
    }

    /**
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        $file = $this->getAbsolutePath();
        if ($file) {
            unlink($file);
        }
    }

    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()
    {
        // the absolute directory path where uploaded
        // documents should be saved
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }

    protected function getUploadDir()
    {
        // get rid of the __DIR__ so it doesn't screw up
        // when displaying uploaded doc/image in the view.
        return 'uploads/documents';
    }
}

Controller:

    public function uploadAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $document = new File();
        $form = $this->createFormBuilder($document)
            ->add('name')
            ->add('file')
            ->getForm();

        $form->handleRequest($request);
        if ($form->isValid()) {
            $em->persist($document);
            $em->flush();

            return $this->redirectToRoute('web_portal_file');
        }


        return $this->render('WebPortalBundle:Default:file.html.twig',array('file_form' => $form->createView()));
    }

EDIT: Twig:

 <form action="{{ path('web_portal_file') }}" method="post" {{ form_enctype(file_form) }}>
    {{ form_widget(file_form.file) }}
    {{ form_rest(file_form) }}
    <input type="submit"/>
</form>

I don't know what to do to make this work. Every time path is saved to the database, but folder is empty ...

Upvotes: 0

Views: 925

Answers (3)

Ait Friha Zaid
Ait Friha Zaid

Reputation: 1522

The following code works:

protected function getUploadRootDir() {
    // the absolute directory path where uploaded
    // documents should be saved
    return __DIR__ . '/../../../web/' . $this->getUploadDir();
}

Upvotes: -1

Cristian Angulo Nova
Cristian Angulo Nova

Reputation: 451

The problem may be here. On Controller. When you are persisting the entity you call the upload() method


    if($form->isValid()) {

       $em->persist($document);       
       $em->flush();

       return $this->redirectToRoute('web_portal_file');
    }

In CookBook says:

The previous controller will automatically persist the Document entity with the submitted name, but it will do nothing about the file and the path property will be blank.

An easy way to handle the file upload is to move it just before the entity is persisted and then set the path property accordingly. Start by calling a new upload() method on the Document class, which you'll create in a moment to handle the file upload:

Now


    if($form->isValid()) {

         $document->upload();
         $em->persist($document);
         $em->flush();

         return $this->redirectToRoute('web_portal_file');
    }

Upvotes: 0

Cristian Angulo Nova
Cristian Angulo Nova

Reputation: 451

Remember to upload files will be put in the form tag data encryption: PHP method uploads

In Symfony2, with Twig would be:


    form class="" action="" method="post" {{ form_enctype(file_form) }}
       {{ form_widget(file_form) }}
    /form

Upvotes: 2

Related Questions