I have a problem with saving the path in doctrine from a file upload. I used the example from here: How to handle File Uploads with Doctrine
The upload works, but I don’t get the file path saved to the database and I think the callbacks don’t work. At least my uploads don’t have a file extension.
Here comes my controller:
public function uploadAction()
{
$document = new Document();
//$form = $this->createForm(new DocumentType(), $entity);
$form = $this->createFormBuilder($document)
->add('name')
->add('file')
->getForm()
;
if ($this->getRequest()->getMethod() === 'POST') {
$form->bindRequest($this->getRequest());
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($document);
$em->flush();
$this->redirect($this->generateUrl('document'));
}
}
return $this->render("ISClearanceBundle:Document:upload.html.twig",array('form' => $form->createView()));
}
Here is the Entity:
<?php
namespace IS\ClearanceBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* IS\ClearanceBundle\Entity\Document
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Document
{
/**
* @var string $name
*/
private $name;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
public $path;
/**
* @var integer $projectId
*/
private $projectId;
/**
* @var integer $id
*/
private $id;
/**
* @Assert\File(maxSize="6000000")
*/
public $file;
/**
* Set name
*
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set path
*
* @param integer $path
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Get path
*
* @return integer
*/
public function getPath()
{
return $this->path;
}
/**
* Set projectId
*
* @param integer $projectId
*/
public function setProjectId($projectId)
{
$this->projectId = $projectId;
}
/**
* Get projectId
*
* @return integer
*/
public function getProjectId()
{
return $this->projectId;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
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 when displaying uploaded doc/image in the view.
return 'uploads/documents';
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->file) {
// do whatever you want to generate a unique name
$this->path = uniqid().'.'.$this->file->guessExtension();
}
$this->path = uniqid().'.'.$this->file->guessExtension();
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
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->file->move($this->getUploadRootDir(), $this->path);
$this->setPath($this->path);
unset($this->file);
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
}
I really don’t know how to save the path to the database and how to debug.
Thanks for any help!
Look at upload() method. It have postPersist() which means the entity changes are NOT saved to DB, so changed properties won’t be stored in current save.
You have to update path in method using prePersist annotation and move file in method using postPersist. Also don’t unset %this->file, just assign null value.
Based on you class
And remember that using move should use absolute path on you server so e.g. /var/www/my_app/web/storage/uploads/file.jpg or C:\www\my_app\web\storage\uploads\file.jpg (don’t worry to much about slashed direction, if you use only “/” it should work fine)