Использование событий (events) в Yii

В этой статье речь пойдет о событиях (events) в yii. Кратко, внятно и с примером. Ничего лишнего, только суть.

В любом высокоуровневым языке программирования мы можем определять действия пользователя и как-то реагировать на них. Пользователь инициирует событие, а мы пишем код, который обрабатывает это событие. Яркий пример – javascript. Например, по событию click, мы меняем цвет текста, по событию hover скрываем кнопку и т.д.

Похожая ситуация и с yii. Мы имеем некоторый набор действий (событий), который совершает фрэймворк и на эти действия мы можем вешать свой код.

Я приведу пример некоторых предопределенных событий в yii.

Предопределенные события в yii
События модели.

beforeValidate() – вызывается до валидации;
afterValidate() – вызывается после валидации;
beforeSave() – вызывается перед сохранением данных;
afterSave() – вызывается после сохранением данных;
beforeDelete() – вызывается перед удалением данных;
afterDelete() – вызывается после удалениея данных;
afterConstruct();
afterFind();
beforeFind();
А вот таких событий как beforeUpdate () и afterUpdate() нет.

События контроллера.

beforeAction() – вызывается до каких-либо действий контрллера;
afterActione() – вызывается после каких-либо действий контрллера;
beforeRender() – вызывается перед отрисовкой вида;
afterRender() – вызывается после отрисовки вида;
Класс CWebUser (с версии 1.1.3)

afterLogin() - Вызывается из CWebUser после логинизации
beforeLogin() - - Вызывается из CWebUser перед логинизацией
afterLogout() - - Вызывается из CWebUser после выхода пользователя
Пример использования.
Допустим, в модели User нам нужно сохранять метку времени, используя php-функцию time(). Для этого описываем событие:

public function beforeSave() {
    // если новая запись в таблицу
    if ($this->isNewRecord) {
    	$this->date = time();
    }
    // обязательно перегружаем родительский метод
    return parent::beforeSave();
}

Теперь перед сохранением данных в базу, будет вызываться событие beforeSave() и выполняться нужный нам код. Вданном примере - присваивание полю date значения метки времени, если это новая запись (insert,а не update).

Или представим, что после редирединга вида 'view', нам нужно очисить куки, а перед выполнением действия 'index'- что-то залогировать. Для этого в контроллер добавим:

public function afterRender($view){
	 // только после вида 'view'
    if($view == 'view'){
        unset(Yii::app()->request->cookies['option_by_city_value']);
    }
    return true;
}
 
public function afterAction($action) {
    if ($action->id == 'index') {
    	// логируем
    }
   return true;
}

В классе CWebUser вызываем событие afterLogin(), чтобы залогировать выход юзера

public function afterLogin($fromCookie){
    parent::afterLogin($fromCookie);
    // например логируем, что пользователь такой-то вышел тогда-то
}

Своё событие
Для начала установим последовательность действий:

Объявляем некоторое событие описанием соответствующего метода.
Назначаем событию один или несколько обработчиков.
Событие вызывается компонентом через метод CComponent::raiseEvent.
При вызове события автоматически срабатывают все подписанные на него методы-обработчики.
Приведу самый простой и примитивный пример, какой только можно. Предположим, что мы хотим, чтобы при успешной логинизации юзера, нам приходило письмо с его данными.

В стандартном контроллере SiteController создадим метод onLogin в котором опишем инициализацию события:

public function onLogin($event) {
    // вызов события
    $this->raiseEvent('onLogin', $event);
}

Теперь нам надо связать событие и обработчик. В обрабочике и будет хранится весь основной код, где мы будем слать себе письмо с данными юзера. Сам код привязки можно поместить в родительский компонент контроллера SiteController.

// onLogin - имя инициализованного события, $this - то что придет в метод onLogin на место $event
CComponent::getEventHandlers('onLogin')->add( 
	function($this){ 
		echo 'Сработало событие логинизации';
	}
);

Теперь нам в нужно вызывать проинициализированный метод onLogin, который в свою очередь внутри себя вызовет одноименное событие. Естественно, вызывать метод onLogin() нужно в том месте, после которого понятно, что авторизация "удалась":

if ($model->validate() && $model->login()) {
	// вызов события
   $this->onLogin($this);
	// труту-ту
}
Теги:
events
Добавлено: 20 Апреля 2018 18:27:37 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...