Yiiframework Events
1. Februar 2010
Nach einer User-Registrierung können viele Dinge passieren:
- der Admin wird informiert
- der registrierte User bekommt eine Bestätigungsmail
- eventuell wird ein Profil initialisiert
- ein Zähler wird hochgezählt usw
Aktionen werden ausgeführt, wenn bestimmte Ereignisse auftreten (Observer Pattern)
Wenn sich ein User registriert, möchte ich beim Neuanlegen eines User-Datensatzes bestimmte Aktionen ausgeführt haben.
Ich definiere ein neues Ereignis onNewUser im User-model:
public function onNewUser($event) { $this->raiseEvent('onNewUser', $event); }
welches ausgeführt wird, nachdem der Datensatz angelegt wurde:
public function afterSave() { if ($this->isNewRecord) { if ($this->hasEventHandler('onNewUser')) { $event = new CModelEvent($this); $this->onNewUser($event); } } parent::afterSave(); }
Irgendwo kann ich jetzt Aktionen definieren, die daraufhin ausgeführt werden:
public function hello($event) { $user = $event->sender; var_dump($user->firstname, $user->lastname); } public function hello2($event) { $user = $event->sender; var_dump($user->email); exit; }
und irgendwo muss ich das auch festlegen, dass das so geschieht:
public function actionCreate() { $model = new User; if(isset($_POST['User'])) { $model->attributes = $_POST['User']; $model->onNewUser = array($this, 'hello'); $model->onNewUser = array($this, 'hello2'); if ($model->save()) { $this->redirect(array('show','id' => $model->id)); } } $this->render('create', array('model' => $model)); }
Verwandte Artikel:
- Yii Message Translation
- Erste Schritte mit Yii Teil 2
- Einfache Seiten
- Models aus Modulen verwenden
- Ein Modul als Admin Backend
- yiic shell
- Mit Yii eine Datei hochladen
- Widgets
- Ajax Updates
- Yii Module
- Erste Schritte mit Yii
- Parameterized Named Scopes
- Webservice mit Yii
- Smart URLs mit Yii
- yiiframework – Guidelines for good schema design
Bist Du sicher, dass die Registrierung der Event-Handler in actionCreate so funktioniert? $model->onNewUser = array(…) sieht komisch aus: Da werden einer Variable, die genau so heißt wie eine Methode, zwei verschiedene Werte zugewiesen. Selbst wenn es wegen des Namenskonfliktes keinen Fehler gibt, so wie ich das sehe, wird auf jeden Fall nur ein Event-Handler ausgeführt.
schau dir bitte CComponent::__set() an, dann verstehst du, dass obenstehender Code funktioniert.
Die Eigenschaft onNewUser existiert nicht, daher greift magic-__set().
$model->onNewUser bekommt zwei Callbacks an die Backe geheftet (via CList), die ausgeführt werden, nachdem ein Datensatz gespeichert wurde (afterSave()). Ich find das auch ziemlich tricky.
Eine sehr schöne Einführung in das Event Handling in Yii! Erst dieses praxisnahe Beispiel hat mich bei dem Event-Foo von Yii wirklich durchsteigen lassen.
Das Problem ist jetzt, dass man jedem Model erst Handler zuweisen kann, nachdem es erstellt wurde. Grade wenn man eher aus der JavaScript Welt kommt, in der ein globales Event alltäglich ist, kommt man mit dieser Vorstellung nicht ganz klar.
Da ich ein Objekt habe, dass an mehreren Stellen initialisiert werden kann und nicht an jeder dieser Stellen den EventHandler zuweisen möchte, habe ich eine Erweiterung des ActiveRecords gefunden, die es zulässt ein globales Event von einem Observer zuweisen zu lassen.
Link: http://www.yiiframework.com/forum/index.php?/topic/15634-extension-yii-events-observer-for-models/
Außerdem finde ich, dass der Code auf diese Weise deutlich aufgeräumt werden kann, wenn man viele Events verwendent.
PS: Habe entgegen der Beschreibung aus der Erweiterung, meine Observer in einen eigenen Ordner gepackt. Das ist dann noch mal übersichtlicher.