CakePHP 3 Events

I want to create an entry in my notification table if a particular lookup method has a return value in my contact table.

So in ContactsTable I am creating an event.

use Cake\Event\Event;

public function checkDuplicates()
{
    //... some code here
    $event = new Event('Model.Contacts.afterDuplicatesCheck', $this, [
            'duplicates' => $duplicates
        ]);
    $this->eventManager()->dispatch($event);
}

      

I created ContactsListener.php at / src / Event

namespace App\Event;

use Cake\Event\Event;
use Cake\Event\EventListenerInterface;
use Cake\Log\Log;

class ContactsListener implements EventListenerInterface
{

    public function implementedEvents()
    {
        return [
            'Model.Contacts.afterDuplicatesCheck' => 'createNotificationAfterCheckDuplicates',
        ];
    }

    public function createNotificationAfterCheckDuplicates(Event $event, array $duplicates)
    {
        Log::debug('Here I am');
    }
}

      

In my NotificationsTable.php, I have the following code.

public function initialize(array $config)
{
    $this->table('notifications');
    $this->displayField('id');
    $this->primaryKey('id');

    $listener = new ContactsListener();
    $this->eventManager()->on($listener);
}

      

I guess this part is the problem since I never get any log entries. The cookbook is not clear enough about this, and all the code I found is not the same as the cookbook describes, even for cake 3.

How and where should I attach the listener?

+3


source to share


1 answer


You are working with two separate local instances of the event dispatcher, they will never hear from each other. You either need to explicitly subscribe to the manager on your instance ContactsTable

, or use a global event dispatcher that gets notified of all events:

[...]

Each model has a separate event dispatcher, while the View and Controller share one. This allows model events to be displayed autonomously and allows components or controllers to act as needed when creating events raised in the view.

Global Event Dispatcher

In addition to instance-level event managers, CakePHP provides a global event dispatcher that allows you to listen to any event triggered in your application.

[...]

Cookbook> Event System> Access to Event Managers

So, do something like

\Cake\ORM\TableRegistry::get('Contacts')->eventManager()->on($listener);

      



which will only work until the registry is cleared or subscribed globally

\Cake\Event\EventManager::instance()->on($listener);

      

On a side note

For this to work at all, your class NotificationsTable

must be instantiated somewhere. So I suggest wrap this in a utitlity class, or perhaps a component that will listen for the event instead and use it NotificationsTable

to persist the notifications.

+5


source







All Articles