Evenimente
Sistemul de evenimente din Leto este bazat pe un fork al WordPress Hooks API. Îl folosești ca să declanșezi cod din alte părți ale aplicației fără să cuplezi modulele între ele: un modul emite un eveniment, iar altele se pot „abona" la el.
Ai două stiluri echivalente: hook-uri procedurale (add_action / do_action) și înregistrare automată prin atribute (EventHandler).
Cel mai simplu: facada Leto\Events
Pentru apeluri directe, folosește facada statică Leto\Events. Este forma recomandată în cod de zi cu zi:
use Leto\Events;
// Abonează un handler la un eveniment
Events::add_action('user.created', function ($user) {
echo "Utilizator creat: " . $user->name;
});
// Declanșează evenimentul (rulează toți handlerii înregistrați)
Events::do_action('user.created', $user);Facada expune toate operațiile: add_action, do_action, remove_action, remove_all_actions, add_filter, apply_filters, remove_filter, has_action. Fiecare deleagă către managerul de mai jos.
Managerul de hook-uri
În spatele facadei stă Leto\Events\Manager, un singleton. Poți lucra direct cu el atunci când ai nevoie de instanța managerului (de exemplu în teste):
use Leto\Events\Manager;
$manager = Manager::getInstance();
$manager->add_action('user.created', fn ($user) => /* ... */ null);
$manager->do_action('user.created', $user);Metode principale
| Metodă | Descriere |
|---|---|
add_action($tag, $callback, $priority) | Abonează un handler la o acțiune |
do_action($tag, $arg) | Declanșează toate handler-urile înregistrate |
remove_action($tag, $callback, $priority) | Elimină un handler |
remove_all_actions($tag) | Elimină toate handler-urile de acțiune |
add_filter($tag, $callback, $priority) | Abonează un filtru (modifică și returnează valoarea) |
apply_filters($tag, $value) | Aplică toate filtrele înregistrate |
remove_all_filters($tag, $priority) | Elimină toate filtrele |
add_action / Events::add_action prioritatea implicită este 50. La înregistrarea prin atribute (EventHandler / #[Priority]) prioritatea implicită este 10. În ambele cazuri numerele mai mici se execută primele.Cum ajung datele la handler
Aici este ușor de greșit, așa că merită citit cu atenție. Un handler primește payload-ul așa cum l-ai trimis, cu o singură excepție importantă:
- Dacă trimiți un singur obiect (
do_action('tag', $obiect)) sau un array cu exact un obiect (do_action('tag', [$obiect])), handlerul primește obiectul direct, nu array-ul. - Dacă trimiți altceva (un array cu mai multe elemente, un scalar, un array cu un scalar), handlerul primește exact acea valoare.
Cu alte cuvinte, pentru cazul obișnuit (un singur obiect payload) semnătura handlerului trebuie să ceară obiectul, nu array.
Parametri tipizați cu Struct
Struct în loc de array. Îți oferă autocompletare în IDE, tipizare și serializare automată. Vezi Struct.use Leto\Data\Struct;
use Leto\Events;
// Definește un Struct pentru datele evenimentului
class UserCreatedEvent extends Struct
{
public int $user_id;
public string $email;
public string $role;
}
// Emite evenimentul cu un Struct
$event = new UserCreatedEvent();
$event->user_id = $user->id;
$event->email = $user->email;
$event->role = 'member';
Events::do_action('user_created', $event);Handlerul primește Struct-ul direct ca argument (nu un array):
public static function user_created(UserCreatedEvent $event): void
{
if ($event->role === 'admin') {
// ...
}
}array $args pentru un payload cu un singur obiect. Framework-ul despachetează obiectul înainte de a apela handlerul, deci array $args ar arunca un TypeError. Tipul array are sens doar când payload-ul chiar este un array cu mai multe elemente.EventHandler cu atribute
Clasa Leto\Events\EventHandler oferă înregistrare automată: metodele publice statice devin handleri, iar numele metodei este tag-ul evenimentului.
use Leto\Events\Attributes\Failable;
use Leto\Events\Attributes\Priority;
use Leto\Events\EventHandler;
class UserEvents extends EventHandler
{
#[Priority(5)]
public static function user_created(UserCreatedEvent $event): void
{
// Trimite email de bun venit
}
#[Priority(20)]
#[Failable]
public static function user_logged_in(UserLoginEvent $event): void
{
// Logare activitate, nu blochează dacă eșuează
}
}
// Înregistrează toate metodele ca handleri
UserEvents::register();Atribute disponibile
| Atribut | Efect |
|---|---|
#[Priority(n)] | Setează prioritatea (implicit 10, mai mic = executat mai devreme) |
#[Failable] | Handlerul nu oprește execuția dacă aruncă excepție, eroarea e logată |
Declanșare
use Leto\Events;
$event = new UserCreatedEvent();
$event->user_id = $user->id;
$event->email = $user->email;
$event->role = 'member';
Events::do_action('user_created', $event);Filtre
Filtrele modifică și returnează o valoare, spre deosebire de acțiuni care doar se execută:
use Leto\Events;
Events::add_filter('page_title', function ($title) {
return strtoupper($title);
});
$title = Events::apply_filters('page_title', 'bun venit');
// $title = 'BUN VENIT'