Search code examples
phpsymfonysonata-admin

SonataAdmin onComplete


It's posible to handle the postFlush event or something like that? I need to access to some data of the new register to generate another things, but must be after flush, because im using Gedmo Slug and one of data i need is the slug.


Solution

  • Yes, create a listener in your services.yml/xml file and then the listener itself to change the code you need.

    #src/Acme/Bundle/YourBundle/Resources/config/services.yml
    services:
        contact_onflush.listener:
            class: Acme\Bundle\YourBundle\Listener\YourListener
            arguments: [@request_stack]
            tags:
                - { name: doctrine.event_listener, event: onFlush }
        contact_postflush.eventlistener:
            class: Acme\Bundle\YourBundle\Listener\YourListener
            tags:
                -  { name: doctrine.event_listener, event: postFlush}
    

    In the listener class:

    <?php
    
    namespace Acme\YourBundle\YourListener;
    
    use Doctrine\Common\EventArgs;
    use Doctrine\Common\EventSubscriber;
    use Doctrine\ORM\Event\OnFlushEventArgs;
    use Doctrine\ORM\Event\PostFlushEventArgs;
    use Symfony\Component\HttpFoundation\RequestStack;
    
    class YourListener implements EventSubscriber
    {
        private $requestStack;
        private $needsFlush;
    
        public function __construct(Request $requestStack)
        {
            $this->requestStack= $requestStack;
            $this->needsFlush= false;
        }
    
        public function onFlush(OnFlushEventArgs $args)
        {
            $em = $args->getEntityManager();
            $uow = $em->getUnitOfWork();
    
            // we would like to listen on insertions and updates events
            $entities = array_merge(
                $uow->getScheduledEntityInsertions(),
                $uow->getScheduledEntityUpdates()
        );
    
        foreach ($entities as $entity) {
            // every time we update or insert a new [Slug entity] we do the work
            if ($entity instanceof Slug) {
                //modify your code here
                $x = new SomeEntity();
                $em->persist($x);
                //other modifications
                $this-needsFlush  = true;
                $uow->computeChangeSets();
            }
        }
    }
    
    public function postFlush(PostFlushEventArgs $eventArgs) {
        if ($this->needsFlush) {
            $this->needsFlush = false;
            $eventArgs->getEntityManager()->flush();
        }
    }
    

    You may be able to use computeChangeSet (singular) but I had problems using it. Instead of using onFlush, you can use preUpdate to find the fields that changed, but this event has restrictions when trying to persist and you need to pair it with something like the needFlush to trigger a postFlush.

    If you still have errors, can you post more of you code to show what you are modifying?