Evento di campi dispatchabili del modello
L’événement des champs déclenchables est un concept qui garantit le déclenchement d’événements lorsqu’une propriété du modèle change. Contrairement aux événements de modèle classiques, qui sont déclenchés lorsqu’une action spécifique est effectuée (enregistrer, mettre à jour, supprimer, etc.), ici nous avons une implémentation approfondie qui ne se déclenche que si un attribut précis d’un modèle a changé.
Motivo de questa implementazione era evitare l’invio e l’ascolto di eventi quando non è necessario. Ad esempio, un ordine su NexoPOS può essere aggiornato in più modi. Ogni volta che l’ordine viene aggiornato, abbiamo listener predefiniti pronti a eseguire un’azione specifica. Non sarebbe meglio, quando cambia l’assegnatario, calcolare i report per i clienti precedenti e quelli recenti? Non sarebbe meglio se potessimo notificare il conducente solo quando lo stato della consegna passa da “in attesa” a “pronto per la consegna”? È esattamente questo lo scopo di questa funzionalità.
Implementazione
L’implementazione di quella funzionalità consiste solo nel fornire un array $dispatchableFieldsEvents sul modello su cui vogliamo inviare l’evento. Su quel modello, forniremo proprietà ed eventi correlati in questo modo:
<?php
namespace Modules\YourModule\Models;
use App\Models\NsModel;
use Modules\YourModule\Events\DeliveryChangedEvent;
class Order extends NsModel
{
public $dispatchableFieldsEvents = [
'delivery_status' => DeliveryChangedEvent::class
];
}
Ora dobbiamo definire l’evento in modo che non riceva solo il modello come parametro, ma anche il valore precedente e quello nuovo della proprietà:
<?php
namespace Modules\YourModule\Events;
use App\Models\Order;
class DeliveryChangedEvent
{
public function __construct( public Order $order, public mixed $previous, public mixed $new )
{
// ...
}
}
Da qui, puoi ascoltare in sicurezza questo evento dal nostro event listener in questo modo:
<?php
namespace Modules\YourModule\Listeners;
use Modules\YourModule\Events\DeliveryChangedEvent;
use Moduels\YourModules\Services\DriverService;
class DeliveryChangedEventListener
{
public function __construct( public DriverService $driverService ){
{
// ...
}
public function handle( DeliveryChangedEvent $event )
{
if ( $event->previous === 'pending' && $event->new === 'ready-for-delivery' ) {
$this->driverService->notifyAssignedDriver( $event->order );
}
}
}