Reputation: 450
I have a problem with my uploader files system. First of all I followed this : http://symfony.com/doc/current/controller/upload_file.html
In fact the uploader is "simply" a file input -> filetype, in a form. A user can publish an article with an image. Ok.
Currently my uploader works well. But my problem occurs when I try to edit an existing entity : Because in the edit form, the user have to select his file even if he want not change his file. Is not userfriendly. I would like change that.
my controller :
public function editAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$article = $em->getRepository('PMPlatformBundle:Article')->find($id);
if (null === $article) {
throw new NotFoundHttpException("L'article d'id " . $id . " n'existe pas.");
}
$article->setImgName(
new File($this->getParameter('images_directory').'/'.$article->getImgName())
);
$form = $this->get('form.factory')->create(TextOnlyType::class, $article);
if ($request->isMethod('POST'))
{
if ($form->handleRequest($request)->isValid())
{
$em->flush();
$this->addFlash(
);
return $this->redirectToRoute('pm_platform_view', array('slug' => $article->getSlug()));
}
else
{
$this->addFlash(
);
}
}
return $this->render('PMPlatformBundle:Article:edit.html.twig', array(
'article' => $article,
'form' => $form->createView(),
));
}
my event listener :
class ImageUploadListener
{
private $uploader;
protected $oldImg;
protected $imageDir;
public function __construct(PMImageUploader $uploader, $oldImg = null, $imageDir)
{
$this->uploader = $uploader;
$this->oldImg = $oldImg;
$this->imagetDir = $imageDir;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof Image) {
$this->oldImg = $args->getOldValue('imgName');
$this->uploadFile($entity);
}
}
public function postUpdate(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity->getImgName() instanceof UploadedFile) {
return;
}
if ($entity instanceof Image) {
$oldImg = $this->oldImg;
$this->removeOldFile($entity, $oldImg);
}
}
public function postRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof Image) {
$imgName = $entity->getImgName();
$this->removeOldFile($entity, $imgName);
}
}
private function uploadFile($entity)
{
if ($entity instanceof Image) {
$image = $entity->getImgName();
if (!$image instanceof UploadedFile) {
return;
}
$imageName = $this->uploader->fileSave($image, "image");
$entity->setOriginalImgName($image->getClientOriginalName());
$entity->setImgName($imageName);
}
}
private function removeOldFile($entity, $fileName)
{
if ($entity instanceof Image && $fileName) {
$this->uploader->fileRemove($fileName, "image");
}
}
}
Article entity :
class Image extends Article
{
/**
* @var string
*
* @ORM\Column(name="img_name", type="string", length=255, nullable=false)
* @Assert\Image(
* maxSize = "10Mi",
* minWidth = 400,
* maxWidth = 10000,
* minHeight = 400,
* maxHeight = 10000
* )
*/
private $imgName;
/**
* @var string
*
* @ORM\Column(name="original_img_name", type="string", length=255, nullable=false)
*/
private $originalImgName;
/**
* Set imgName
*
* @param string $imgName
*
* @return Image
*/
public function setImgName($imgName)
{
$this->imgName = $imgName;
return $this;
}
/**
* Get imgName
*
* @return string
*/
public function getImgName()
{
return $this->imgName;
}
and my form type :
class ImageType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class)
->add('description', TextareaType::class)
->add('imgName', FileType::class, array(
'label' => 'Importer votre image',
'required' => false,
))
->add('tags', TextType::class, array('required' => false))
->add('send', SubmitType::class, array('label' => 'Envoyer'));
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'PM\PlatformBundle\Entity\Image'
));
}
}
Ok so as I tell you before, when a user edit his article, and not selects a file whit input file, this article is updated with a NULL file. How I can change that for this article to be updated with the same file as one before update ?
Upvotes: 0
Views: 64
Reputation: 450
Ok it's done whit that changes :
class ImageUploadListener
{
private $uploader;
protected $oldImg;
protected $imageDir;
public function __construct(PMImageUploader $uploader, $oldImg = null, $imageDir)
{
$this->uploader = $uploader;
$this->oldImg = $oldImg;
$this->imagetDir = $imageDir;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof Image) {
$this->oldImg = $entity->getImgName();
}
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof Image) {
if (!$entity->getImgName()) {
$entity->setImgName($this->oldImg);
}
else {
$this->uploadFile($entity);
$this->removeOldFile($entity, $this->oldImg);
}
}
}
public function postRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof Image) {
$imgName = $entity->getImgName();
$this->removeOldFile($entity, $imgName);
}
}
private function uploadFile($entity)
{
if ($entity instanceof Image) {
$image = $entity->getImgName();
if (!$image instanceof UploadedFile) {
return;
}
$imageName = $this->uploader->fileSave($image, "image");
$entity->setOriginalImgName($image->getClientOriginalName());
$entity->setImgName($imageName);
}
}
private function removeOldFile($entity, $fileName)
{
if ($entity instanceof Image && $fileName) {
$this->uploader->fileRemove($fileName, "image");
}
}
}
Upvotes: 0
Reputation: 4363
The postLoad event occurs every time you load an entity from the database. In your case the best approach is to create a custom event and dispatch it from the editAction.
Upvotes: 1