Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload is not performed if there is no change in the entity #297

Open
K-Phoen opened this issue Aug 13, 2014 · 12 comments
Open

Upload is not performed if there is no change in the entity #297

K-Phoen opened this issue Aug 13, 2014 · 12 comments

Comments

@K-Phoen
Copy link
Collaborator

K-Phoen commented Aug 13, 2014

When using doctrine, event listeners are not called if there have been no column changed. It's a problem because we precisely depend on these events to be fired to handle the uploads.

Right now, we use some boilerplate code to artificially trigger a change in the entity whenever a file is uploaded (by updating the created_at column for instance).

I'd like to find an other way to fix this issue.

@K-Phoen K-Phoen added this to the 1.0 milestone Aug 13, 2014
@ogizanagi
Copy link

I personnaly use FormEvents to achieve this change automatically.

Example:

class ApplicationType extends AbstractType
{
...

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('icon', 'file', array(
                'required' => false,
            ));

        $builder->get('icon')->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $e){
            if(!empty($e->getData())){
                /** @var Application $app */
                $app = $e->getForm()->getParent()->getData();
                $app->setUpdateAt(new \DateTime());
            }
        });
    }

...
}

This code simply checks if the icon field has data. Then, updates the target entity if needed.

I guess it will be possible to consider the creation of a dedicated form type vich_file or else, which would be responsible for update a user configurable entity field via the field options form. These option could be named update_property for instance.

Another and complementary form type could also check if the form entity implements a given interface, in charge to update the updatedAt field when the interface method is called. Therefore, no more configuration is needed from user.

@K-Phoen
Copy link
Collaborator Author

K-Phoen commented Aug 14, 2014

The thing is I don't want to rely on this kind of "hack". We should not have to ask the user to write boilerplate code/implement an interface/add a "updated at" field.

@K-Phoen K-Phoen modified the milestone: 1.0 Dec 19, 2014
@rik43
Copy link

rik43 commented Mar 25, 2015

if we use update date in entity setter as in example

public function setImageFile(File $image = null)
{
    $this->imageFile = $image;

    if ($image) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new \DateTime('now');
    }
}

this is execute in each time where entity is loaded. if after call $em->flush() updatedAt field will be updated in db - one query for each entity.
it generate 1000+ queries in my db in some controllers where many entities loaded and call "flush".

@garak
Copy link
Collaborator

garak commented Apr 22, 2015

@rik43 you must check if File is an UploadedFile. See #8 (comment)

@rik43
Copy link

rik43 commented Apr 22, 2015

good idea, thanks

Mondane added a commit to Mondane/VichUploaderBundle that referenced this issue Jun 30, 2015
Add 'instanceof'  check as written here: dustin10#8 (comment) to avoid this issue dustin10#297 (comment)
Koc added a commit to Koc/VichUploaderBundle that referenced this issue Sep 14, 2016
@acantepie
Copy link

Is there a chance you fix this issue one day ?

Reproduced using :

  • vich/uploader-bundle : 1.16.0
  • symfony : 5.0.11
  • php : 7.4.13

@garak
Copy link
Collaborator

garak commented Dec 13, 2020

Is there a chance you fix this issue one day ?

This is the wrong question.
The right question is: is there a chance we fix this issue one day?

@acantepie
Copy link

acantepie commented Dec 13, 2020

Ok, but this issue was opened 5 years ago...

I you (we) don't manage to fix it, maybe you (we) should change this part of documentation :

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile|null $imageFile
     */

@garak
Copy link
Collaborator

garak commented Dec 13, 2020

@acantepie it's already documented just 4 lines after

@chancegarcia
Copy link

just ran into this issue.

bundle version: 1.19.1
symfony version: 5.4.8

wanting to add in that if the update/created blamable/timestampable values are managed by something like doctrine extensions, that is not enough to trigger the uploader/clean-listener.

ended up making a "dummy" column in the table to just always update as part of the request processing

$formAttachment->setMetadata(uniqid('kittens', true));

@garak
Copy link
Collaborator

garak commented May 20, 2022

wanting to add in that if the update/created blamable/timestampable values are managed by something like doctrine extensions, that is not enough to trigger the uploader/clean-listener.

That's probably a matter of priority in Doctrine listeners

@sudent
Copy link

sudent commented Dec 7, 2022

Hi, I want to add a comment after having been through the issue of file not uploaded for new entity. It may affect you if you're using translatable in any of the field on the entity. After further checking it seems that translatable will trigger a persist early on the form lifecycle (the $form->handleRequest() call) with the uploaded file not being set on the entity yet. And when I call $entityManager->persist($object) the prePersist code from this bundle will not be called (I assume because it have been called in the handleRequest() call. So what I do is I add the code $uploadHandler->upload($object, 'file') before $entityManager->persist($object) to trigger it manually. Of course these only works if you're in the same situation like me. Just for reference for others. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants