Я тестировал систему событий на CakePHP v3.0.0-RC2 для целей моего проекта. Сначала я должен извиниться за длинный текст.
В основном я создал таблицу пользователей с полями id, name и фамилию. Затем я создал еще одну таблицу с именем user_statistics, которая подсчитывает количество созданий пользователей в месяц. Ниже приведена функция, которая сохраняет пользователя, создает событие для объекта таблицы UserStatistics и, наконец, отправляет событие.
use Cake\Event\Event;
class UsersTable extends Table
{
//Other code
public function createUser($user)
{
if( $this->save( $user )){
$event = new Event('Model.User.afterPlace', $this, array(
'user' => $user
));
$this->eventManager()->dispatch( $event );
return true;
}
return false;
}
}
Эта функция делает то, что она ожидала — частично так — поскольку она, кажется, не отправляет событие, а только сохраняет пользовательские данные. Возможно, проблема заключается в объекте таблицы UserStatistics. Ниже приведен фрагмент кода того, как я реализовал функцию, которая обрабатывает учет пользователей.
use Cake\Event\EventListenerInterface;
class UserStatistics extends Table implements EventListenerInterface
{
//Code ommitted for in account of relevence
public function tallyUsers( $event )
{
$data = array();
if(!empty($event->subject()->user)){
$date = date('Y-m-d');
// Check existing record of today
$record = $this->find()->where(array('date' => $date));
if(empty($record)){
//Insert new record if none exist for the current date
$data = array(
'date' => $date,
'count' => 1
);
}else{
//Update record if date exist by incerementi count field by one
$count = (int) $record->count + 1;
$data = array(
'id' => $record->id,
'date' => $date,
'count' => $count
);
}
if($this->save($data))
return true;
else
return false;
}
}
}
После этого у меня возникло небольшое недопонимание относительно того, где я должен зарегистрировать UserStatistics, чтобы он мог наблюдать объект User. Конечно, я реализовал метод ImpleentEvents () в моем табличном объекте UserStatistics (см. Ниже):
public function implementedEvents()
{
return array(
'Model.User.afterPlace' => 'tallyUsers'
);
}
Я понял, что должен зарегистрировать своего наблюдателя (UserStatistics) внутри UsersController. Вот как я это сделал:
...
publiv function add()
{
if($this->request->is('post')){
$this->loadModel('UserStatistics');
$this->Users->eventManager()->on( $this->UserStatistics );
if($this->Users->createUser( $user )){
....
}
}
}
Вопросы):
Пожалуйста, помогите мне понять, так как я не мог найти четкие сведения по этому вопросу в самом документе или в любом другом месте.
Мне удалось заставить два табличных объекта разговаривать друг с другом. Таблица статистики пользователя обновляется записью каждый раз, когда новый пользователь создается объектом users, который в нашем случае является нашей темой.
Я перенес так много исключений, чтобы заставить его работать. По сути, мне пришлось применять первичный ключ, потому что он не мог создать новую сущность без идентификатора. Я хочу иметь возможность создавать новые записи, когда в этом конкретном месяце не существует записей, иначе обновлять поле счетчика, если запись существует. Так что проблема не в другом, а в коде ниже:
public function update( $event )
{
if(!empty( $event->data)){
// find current month's record
if( empty( $record )){
//Create a new row
$entity = new \App\Model\Entity\UserStatistic(['id' => 1, 'date' => $date, 'count' => 1]);
$update = $this->save($entity);
}else{
$entity = new \App\Model\Entity\UserStatistic(['id' => $record->id + 1, 'count' => (int) $record->count + 1]);
$updated = $this->save( $entity );
}
}
}
Что-то не так с этим кодом, и я не могу разобраться, но в конечном итоге я смог поэкспериментировать с системой событий, предоставляемой платформой, и проблемой, с которой я сейчас сталкиваюсь, я хочу верить, является связанная с системой событий. Любая помощь в отношении объяснения, представленного выше, будет принята с благодарностью.
Других решений пока нет …