Getting current instance of entity and passing it to a listener in Symfony

1.3k views Asked by At

I have a form which is used to put value's in two different entities. One entity is the listing table and the other is the images table. The images table is handled by a listener that listens for the dropzone PostPersistEvent. Each time an image is dragged and dropped into the zone, it's added to the database. For a while I had a problem that if the user was just creating the form for the first time, the listing didn't exist and so there was no id to tie the image entity to which I solved.

Now I'm trying to, each time the image is dragged and dropped, get the id of the current listing entity that the user is viewing the form for and use it as the value for listing_id in the image entity.

Upload Listener

<?php
namespace DirectoryPlatform\AppBundle\EventListener;

use Doctrine\Common\Persistence\ObjectManager;
use Oneup\UploaderBundle\Event\PostPersistEvent;
use DirectoryPlatform\AppBundle\Entity\MotorsAdsFile;

use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\FOSUserEvents;

class UploadListener
{
    protected $manager;

    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
    }

    // If I could pass a current instance of the currently viewed Listing entity here, that would be ideal
    public function onUpload(PostPersistEvent $event)
    {
        $file = $event->getFile();
        // images entity
        $object = new MotorsAdsFile();
        $object->setImageName($file->getPathName());
        // I'd want to set the listing_id of MotorsAdsFile to the id of the currently viewed listing here
        // $object->setListing($listing->getId());

        $this->manager->persist($object);
        $this->manager->flush();
    }
}

MotorsAdsFile (Image entity)

/**
 * @param Listing $listing
 */
public function setListing($listing)
{
    $this->listing = $listing;
}

services.yml

directory_platform.upload_listener:
    class: DirectoryPlatform\AppBundle\EventListener\UploadListener
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
        - { name: kernel.event_listener, event: oneup_uploader.post_persist, method: onUpload }

My intent is to add the listing id to the image upon it being uploaded to the db. The listing_id in the image entity is tied to the id of the listing entity but I don't have a way of getting the current instance of the form from within the listener Image are loaded into the db at a different time than the form values

My Question is, how do I get the instance of the entity listing that the user is currently viewing in the UploadListener so I can use it's id and set it to the listing_id of the uploaded image.

2

There are 2 answers

0
iiirxs On BEST ANSWER

In your twig you should a javascript script to configure dropzone to pass some extra parameters to your request:

<script>
    Dropzone.options.yourFormId = {
        params: {
            listing: "{{ listing.id }}" // if you pass listing as a variable to your template
            // or listing: "{{ form.vars.value.id }}" if listing is the underlying object of your form
        }
    };
</script>

Then in your UploadListener class get the listing id the request object like this:

class UploadListener
{
    protected $manager;

    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
    }

    // If I could pass a current instance of the currently viewed Listing entity here, that would be ideal
    public function onUpload(PostPersistEvent $event)
    {
        $file = $event->getFile();
        $object = new MotorsAdsFile();
        $object->setImageName($file->getPathName());

        // Get the listing parameter
        $request = $event->getRequest();
        $listingId = $request->get('listing');
        // //
        $object->setListing($listingId);

        $this->manager->persist($object);
        $this->manager->flush();
    }
}
0
Andrew On

Include the Listing ID with the upload.

If the dropzone is a separate form, add a hidden input with the id. You can render the value in your template of fill it on load with JS.

If the dropzone is initialized via JS, add ID to the params option.

Now UploadListener has the listing ID in the request.


As for including images when you create listing, you can generate ID before rendering the create form, e.g. an UUIDv4, set it to the entity, and now it's rendered in the form too, usable for uploads.