Laravel Model Events - I'm a bit confused about where they're meant to go

后端 未结 9 797
长发绾君心
长发绾君心 2020-12-07 13:15

So the way I see it is that a good Laravel application should be very model- and event-driven.

I have a Model called Article. I wish to send email alert

9条回答
  •  再見小時候
    2020-12-07 13:47

    Laravel 6, the shortest solution

    BaseSubscriber class

    namespace App\Listeners;
    
    use Illuminate\Events\Dispatcher;
    use Illuminate\Support\Str;
    
    /**
     * Class BaseSubscriber
     * @package App\Listeners
     */
    abstract class BaseSubscriber
    {
    
        /**
         * Returns the first part of an event name (before the first dot)
         * Can be a class namespace
         * @return string
         */
        protected abstract function getEventSubject(): string;
    
        /**
         * Register the listeners for the subscriber.
         * @param Dispatcher $events
         */
        public function subscribe($events)
        {
            $currentNamespace = get_class($this);
            $eventSubject = strtolower(class_basename($this->getEventSubject()));
    
            foreach (get_class_methods($this) as $method) {
                if (Str::startsWith($method, 'handle')) {
                    $suffix = strtolower(Str::after($method, 'handle'));
                    $events->listen("$eventSubject.$suffix", "$currentNamespace@$method");
                }
            }
        }
    
    }
    

    OrderEventSubscriber class. Handlers for Order model events

    use App\Models\Order;
    
    /**
     * Class OrderEventSubscriber
     * @package App\Listeners
     */
    class OrderEventSubscriber extends BaseSubscriber
    {
    
        /**
         * @return string
         */
        protected function getEventSubject(): string
        {
            return Order::class; // Or just 'order'
        }
    
        /**
         * @param Order $order
         */
        public function handleSaved(Order $order)
        {
          // Handle 'saved' event
        }
    
        /**
         * @param Order $order
         */
        public function handleCreating(Order $order)
        {
           // Handle 'creating' event
        }
    
    }
    

    ModelEvents trait. It goes to your models, in my case - App\Model\Order

    namespace App\Traits;
    
    use Illuminate\Database\Eloquent\Model;
    
    /**
     * Trait ModelEvents
     * @package App\Traits
     */
    trait ModelEvents
    {
    
        /**
         * Register model events
         */
        protected static function bootModelEvents()
        {
            foreach (static::registerModelEvents() as $eventName) {
                static::$eventName(function (Model $model) use ($eventName) {
                    event(strtolower(class_basename(static::class)) . ".$eventName", $model);
                });
            }
        }
    
        /**
         * Returns an array of default registered model events
         * @return array
         */
        protected static function registerModelEvents(): array
        {
            return [
                'created',
                'updated',
                'deleted',
            ];
        }
    }
    

    Register the subscriber in a service provider, e.g AppServiceProvider

    /**
     * @param Dispatcher $events
     */
    public function boot(Dispatcher $events)
    {
        $events->subscribe(OrderEventSubscriber::class);
    }
    

    How just add the ModelEvents trait into your model, adjust the events you want to register instead of default ones:

    protected static function registerModelEvents(): array
        {
            return [
                'creating',
                'saved',
            ];
        }
    

    Done!

提交回复
热议问题