TsarS
TsarS

Reputation: 198

Doctrine error with LifecycleEventArgs arguments

I want to use Listener in my project with postLoad method but I got an error

 [TypeError] App\Company\Infrastructure\Persistence\ORM\EventListener\LoadLicensesListener::postLoad(): Argument #1 ($args) must be of type Do
ctrine\ORM\Event\LifecycleEventArgs, App\Company\Domain\Entity\Company given, called in D:\OpenServer\domains\project\vendor\doctrine\orm\lib\Doc
trine\ORM\Event\ListenersInvoker.php on line 108

My Listener

  use Doctrine\ORM\Event\LifecycleEventArgs;

  final class LoadLicensesListener
   {
    /**
     * @param LifecycleEventArgs $args
     */
    public function postLoad(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();

        if (!$entity instanceof Copmany) {
            // Something to do
            $licenses = $entity->relatedLicenses;           
            $entity->initializeObject($licenses);
        }

    }
}

And I registered it in Company.orm.xml

   <entity-listeners>
            <entity-listener class="App\Company\Infrastructure\Persistence\ORM\EventListener\LoadLicensesListener">
                <lifecycle-callback type="postLoad" method="postLoad"/>
            </entity-listener>
        </entity-listeners>

services.yml

   App\Company\Infrastructure\Persistence\ORM\EventListener\LoadLicensesListener:
        tags:
            - { name: doctrine.event_listener, event: postLoad, connection: default }

Where did I go wrong? Maybe I misunderstood the documentation - Symfony Events or Doctrine Events Or I should do something in services.yml because I've changed a folder with EventListeners? "doctrine/orm": "2.8.4"

Upvotes: 0

Views: 1859

Answers (2)

V-Light
V-Light

Reputation: 3115

I would say it looks like you've configured it wrong.

try to implement postLoad method inside your Campany.php (Note! Without any params) and see what it outputs.

class Company {

// ...

public function postLoad() {
 dump(__METHOD__);
}

}

also take a look at this https://symfony.com/doc/4.1/doctrine/event_listeners_subscribers.html and this one https://symfony.com/doc/current/bundles/DoctrineBundle/entity-listeners.html I am unfortunately not familiar with xml-configs, so I can't spot anything suspicious.

As always, there are several ways to get it done:

  • simple EntityLifeCycles (docs) - useful for basic stuff and if you don't rely on additional services for this particular task. Logic applies only for that specific Entity.
  • an Doctrine\Common\EventSubscriber with getSubscribedEvents - more advanced and flexible. One logic could be applied for several entities
  • an EventListener.

So here are examples for symfony 4.4 and doctrine 2.7:

  1. Entity LifeCylcles:

/**
 * @ORM\Entity()
 * @ORM\Table(name="company")
 * @ORM\HasLifecycleCallbacks
*/
class Company {
   /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

   // ... props and methods

   /**
    * @ORM\PostLoad()
    */
   public function doStuffAfterLoading(): void
   {
        // yor logic
        // you can work with $this as usual
        // no-return values!
        
        // dump(__METHOD__);
   }

}

with these annotations no extra entries in services.yml|xml necessary

    • Subscriber - to apply same logic for one or several Entities
use App\Entity\Company;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Events;

final class PostLoadSubscriber implements EventSubscriber {

  public functuin __construct()
  { 
    // you can inject some additional services if you need to
    // e.g. EntityManager  

  }

  public function getSubscribedEvents()
  {
     return [
         Events::postLoad,
     ];
  }

 public function postLoad(LifecycleEventArgs $args)
 {
     // check if it's right entity and do your stuff
    $entity = $args->getObject();
    if ($entity instanceof Company) {
     // magic...
    }
 }

}

You need to register this PostLoadSubscriber as a service in services.yaml|xml

Upvotes: 1

qdequippe
qdequippe

Reputation: 1155

Doctrine provide different type of listeners, "Default" event listener and Entity Listener, here your registered an entity listener in your file Company.orm.xml and also for the same class a "default" event listener.

Choose which type of listener you want and register it according to the documentation.

If you choose a Entity Listener then the first argument will be the Entity itself, that's why you get this error.

Upvotes: 1

Related Questions