Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Easy Image upload with Symfony 4
<?php
/**
* Created by PhpStorm.
* User: ciryk
* Date: 11/07/18
* Time: 19:23
*/
namespace App\Service;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUploader
{
private $targetDirectory;
/**
* FileUploader constructor.
* @param $targetDirectory
*/
public function __construct($targetDirectory)
{
$this->targetDirectory = $targetDirectory;
}
public function upload(UploadedFile $file)
{
$filename = md5(uniqid()) . '.' . $file->guessExtension();
$file->move($this->targetDirectory, $filename);
return $filename;
}
}
<?php
/**
* Created by PhpStorm.
* User: ciryk
* Date: 11/07/18
* Time: 18:56
*/
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="image")
*/
class Image
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var string $file
* @ORM\Column(type="string")
*
* @Assert\NotBlank(message="Please, upload an image first.")
* @Assert\File(mimeTypes={ "image/png", "image/jpeg", "image/jpg" })
*/
private $file;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $alt;
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
*/
public function setId($id): void
{
$this->id = $id;
}
/**
* @return string
*/
public function getFile()
{
return $this->file;
}
/**
* @param string $file
*/
public function setFile($file)
{
if ($file) {
$this->file = $file;
}
}
/**
* @return mixed
*/
public function getAlt()
{
return $this->alt;
}
/**
* @param mixed $alt
*/
public function setAlt($alt)
{
$this->alt = $alt;
}
}
<?php
/**
* Created by PhpStorm.
* User: ciryk
* Date: 9/12/18
* Time: 21:27
*/
namespace App\Form;
use App\Entity\Image;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ImageType extends FileType
{
private $imagePath;
/**
* ImageType constructor.
* @param $imagePath
*/
public function __construct($imagePath)
{
$this->imagePath = $imagePath;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->addModelTransformer(new CallbackTransformer(
function(Image $image = null) {
if ($image instanceof Image) {
return new File($this->imagePath . $image->getFile());
}
},
function(UploadedFile $uploadedFile = null) {
if ($uploadedFile instanceof UploadedFile) {
$image = new Image();
$image->setFile($uploadedFile);
return $image;
}
}
));
}
public function getBlockPrefix()
{
return 'image';
}
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'required' => false
]);
}
}
<?php
/**
* Created by PhpStorm.
* User: ciryk
* Date: 9/12/18
* Time: 21:28
*/
namespace App\EventListener;
use App\Entity\Image;
use App\Service\FileUploader;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class ImageUploadListener
{
private $uploader;
/**
* ImageUploadListener constructor.
* @param $uploader
*/
public function __construct(FileUploader $uploader)
{
$this->uploader = $uploader;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
private function uploadFile($entity)
{
if (!$entity instanceof Image) {
return;
}
$file = $entity->getFile();
if ($file instanceof UploadedFile) {
$filename = $this->uploader->upload($file);
$entity->setFile($filename);
}
}
}
@carteur007

This comment has been minimized.

Copy link

carteur007 commented May 21, 2020

please
how to autowiring arg $imagePath
goodAutowiringArg*

@cirykpopeye

This comment has been minimized.

Copy link
Owner Author

cirykpopeye commented May 21, 2020

please
how to autowiring arg $imagePath
goodAutowiringArg*

Hi @carteur007 You will need to add this as a service. F.e. in config/services.yaml add the following:

App\Form\ImageType:
  arguments:
    - '%kernel.project_dir%/public/uploads/'

This will turn your form type class into a service, you can inject other services inside your constructor or you can add simple strings like above, the %kernel.project_dir% points to the root of you application.

This should work, if you have any problems let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.