CakePHP 3 事件

CakePHP 3 events

如果特定的查找方法在我的联系人 table 上具有 return 值,我想在我的通知 table 中创建一个条目 table。

所以我在 ContactsTable 中创建了一个事件。

use Cake\Event\Event;

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

我在 /src/Event

创建了 ContactsListener.php
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');
    }
}

在我的 NotificationsTable.php 中,我有以下代码。

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

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

我猜这部分是问题所在,因为我从来没有得到日志条目。食谱对此不够清楚,我发现的所有代码都与食谱描述的不一样,即使是蛋糕 3。

我应该如何以及在何处附加侦听器?

您正在使用两个独立的本地事件管理器实例,它们永远不会收到彼此的消息。您要么必须在 ContactsTable 实例上明确订阅管理器,要么使用全局事件管理器来获取有关所有事件的通知:

[...]

Each model has a separate event manager, while the View and Controller share one. This allows model events to be self contained, and allow components or controllers to act upon events created in the view if necessary.

Global Event Manager

In addition to instance level event managers, CakePHP provides a global event manager that allows you to listen to any event fired in an application.

[...]

Cookbook > Events System > Accessing Event Managers

所以,要么做一些像

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

这只会在注册表被清除或全局订阅之前有效

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

旁注

为了使其完全起作用,您的 NotificationsTable class 必须在某处实例化。所以,我建议将其包装在一个实用程序 class 中,或者可能是一个组件,它将改为侦听事件,并使用 NotificationsTable 保存通知。