Reputation: 198
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
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:
Doctrine\Common\EventSubscriber
with getSubscribedEvents
- more advanced and flexible. One logic could be applied for several entitiesSo here are examples for symfony 4.4 and doctrine 2.7:
/**
* @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
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
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