Salt la conținut

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
Prioritatea implicită diferă în funcție de cale. La 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

Recomandare: Pentru payload folosește un 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') {
        // ...
    }
}
Nu tipiza parametrul ca 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

AtributEfect
#[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'