Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.
Menangani file upload di Symfony 2
Tutorial upload kali ini adalah melanjutkan form posting job. Untuk memungkin user mengupload file kita akan menggunakan virtual field, untuk itu kita akan mengedit file formnya:src/Ibw/JobeetBundle/Entity/Job.php
// ...
public $file;
// ...
Sekarang kita harus mengubah filed logo di form menjadi file input tag:
src/Ibw/JobeetBundle/Form/JobType.php
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('file', 'file', array('label' => 'Company logo', 'required' => false))
// ...
}
// ...
Untuk memastikan bahwa user telah mengupload file maka kita harus melakukan validasi:
src/Ibw/JobeetBundle/Resources/config/validation.yml
Ibw\JobeetBundle\Entity\Job:
properties:
# ...
file:
- Image: ~
Saat tombol submit diklik kita harus memproses dan menyimpan file yang diupload oleh user:
src/Ibw/JobeetBundle/Controller/JobController.php
// ...
public function createAction(Request $request)
{
// ...
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity->file->move(__DIR__.'/../../../../web/uploads/jobs', $entity->file->getClientOriginalName());
$entity->setLogo($entity->file->getClientOriginalName());
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('ibw_job_show', array(
'company' => $entity->getCompanySlug(),
'location' => $entity->getLocationSlug(),
'id' => $entity->getId(),
'position' => $entity->getPositionSlug()
)));
}
// ...
}
// ...
sudo chmod -R 777 web/uploads/jobs/
Untuk membuatnya dapat bekerja dengan baik kita harus mengubah file model Job.php sebagai berikut ini:
src/Ibw/JobeetBundle/Entity/Job.php
class Job
{
// ...
protected function getUploadDir()
{
return 'uploads/jobs';
}
protected function getUploadRootDir()
{
return __DIR__.'/../../../../web/'.$this->getUploadDir();
}
public function getWebPath()
{
return null === $this->logo ? null : $this->getUploadDir().'/'.$this->logo;
}
public function getAbsolutePath()
{
return null === $this->logo ? null : $this->getUploadRootDir().'/'.$this->logo;
}
}
method getAbsolutePath digunakan untuk menyimpan path ke database. Sedangkan method getWebPath digunakan untuk memanggil file dari template.
Ok sekarang kita perlu untuk menambahkan lifecycleCallbacks di entity Job yaitu preUpload, upload dan removeUpload. Untuk melakukannya edit file Job.orm.yml dan tambahkan kode berikut:
src/Ibw/JobeetBundle/Resources/config/doctrine/Job.orm.yml
Ibw\JobeetBundle\Entity\Job:
# ...
lifecycleCallbacks:
prePersist: [ preUpload, setCreatedAtValue, setExpiresAtValue ]
preUpdate: [ preUpload, setUpdatedAtValue ]
postPersist: [ upload ]
postUpdate: [ upload ]
postRemove: [ removeUpload ]
Sekarang jalankan perintah generate entities untuk mengupdate schema di entitinya:
php app/console doctrine:generate:entities IbwJobeetBundle
Edit file entity job.php dan tambahkan script berikut:
src/Ibw/JobeetBundle/Entity/Job.php
class Job
{
// ...
/**
* @ORM\PrePersist
*/
public function preUpload()
{
if (null !== $this->file) {
$this->logo = uniqid().'.'.$this->file->guessExtension();
}
}
/**
* @ORM\PostPersist
*/
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->logo);
unset($this->file);
}
/**
* @ORM\PostRemove
*/
public function removeUpload()
{
if(file_exists($file)) {
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
}
}
src/Ibw/JobeetBundle/Controller/JobController.php
// ...
public function createAction(Request $request)
{
$entity = new Job();
$form = $this->createForm(new JobType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('ibw_job_show', array(
'company' => $entity->getCompanySlug(),
'location' => $entity->getLocationSlug(),
'id' => $entity->getId(),
'position' => $entity->getPositionSlug()
)));
}
return $this->render('IbwJobeetBundle:Job:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
// ...