هر موقع نیاز داشتید بعد از یک اتفاق خاص در نرم افزار(مثل ثبت سفارش یا ثبت نام کاربر) عمل خاصی را انجام بدهید باید(بهتر است) از event ها استفاده کنید.

در این مطلب روش استفاده از event در لاراول را یاد می‌گیریم.

تعریف event

event یک رویداد است که ما در نرم افزارمان تعیین می‌کنیم. مثلا اگر بخواهیم با خرید کاربر یک پیامک برای مدیر سایت ارسال شود، اینجا خرید کاربر می شود همان رویداد یا event.

تعریف listener

listener در واقع یک کلاس است که عمل بعد از صدا زدن event را انجام می‌دهد. در مثال خرید کاربر، listener می‌شود ارسال پیامک برای مدیر سایت.

ایجاد event و listener در لاراول

فرض کنیم قصد داریم وقتی کاربر سفارشی ثبت کرد برای مدیر سایت پیامک ارسال شود.

اینجا اول باید event و listener مربوط به آن را تعریف کنیم.

event و listener هر دو باید در فایل EventServiceProvider ثبت شوند.

اسم کلاس event را می گذاریم CustomerOrdered و اسم کلاس listener هم می‌شود SendAdminOrderNotification.

پس در EventServiceProvider به این شکل این دو را تعریف می کنیم.

use App\Events\CustomerOrdered;
use App\Listeners\SendAdminOrderNotification;
class EventServiceProvider extends ServiceProvider
{
  
    protected $listen = [
        CustomerOrdered::class => [
            SendAdminOrderNotification::class,
        ],
    ];
}

یک آرایه داخل این کلاس وجود دارد به نام $listent که event و listener هر دو داخل آن تعریف می‌شوند.

دقت داشته باشید که باید namespace کلاس‌ها را هم use کنید. با این کار بعد از نوشتن دستور event:generate لاراول خودش این دو کلاس را برای ما درست می‌سازد.

تعریف event در سرویس پرووایدر

حالا اگر دستور php artisan event:generate را اجرا کنیم کلاس event در پوشه app/events و کلاس listeners در پوشه app/listeners ساخته می شوند.

کلاس CustomerOrdered بیاندازید. این کلاس تنها وظیفه اش دریافت اطلاعات از ایونت مورد نظر و پاس دادن آن به کلاس listener است.

وظیفه کلاس SendAdminOrderNotification هم ارسال نوتیفیکیشن بعد از ثبت سفارش(یا هر وظیقه ای شما برایش تعریف کنید) است.

حالا بیایید این event را صدا بزنیم و روند کار با این دو کلاس را ببینیم.

صدا زدن event

قرار شد که بعد از ثبت سفارش این event صدا زده شود شود.

پس ما هم در کنترلری که سفارش ثبت می شود آن را صدا می‌زنیم.

برای این کار از متد dispatch استفاده می‌کنیم. این متد یک پارامتر می‌گیرد که می تواند هر مقداری باشد. اینجا مدل order را به آن پاس می‌دهیم.

use App\Events\CustomerOrdered;
class OrderController extends Controller{
  public function store(Request $request)
    {

        $order = Order::find($request->order_id);

        CustomerOrdered::dispatch($order);

    }
}

هر مقداری که اینجا پاس می‌دهیم را باید در کلاس event مورد نظر دریافت کنیم:

برای این به این شکل در constructor کلاس CustomerOrdered می نویسیم:

class CustomerOrdered
{

    public $order;
    public function __construct($order)
    {
        $this->order;
    }
}

الان مدل order درون کلاس event ای که ساختیم وجود دارد و چون این کلاس در Listener به عنوان پارامتر وارد شده است پس در آن کلاس در متد handle هم قابل دسترسی است.

dependecy injection

نوشتن عملکرد مورد نظر در listener

حالا می‌رسیم به مرحله نوشتن کدی که بعد از صدا زدن event باید اجرا شود. این کار را در متد handle در کلاس SendAdminOrderNotification انجام می‌دهیم.

class SendAdminOrderNotification
{
    

    public function handle(CustomerOrdered $event)
    {
        
    }
}

کلاس CustomerOrdered داخل این متد inject شده است به خاطر همین به مدل order درون متغیر $event دسترسی داریم و با استفاده از آن می‌توانیم اطلاعات مربوط به سفارش ثبت شده را دریافت کنیم و برای مدیر سایت ارسال کنیم.

class SendAdminOrderNotification
{
    public function handle(CustomerOrdered $event)
    {
       $order = $event->order;

       $message = "the user: " . $order->fullname . " has           ordered something";
       
       $admin = User::where('is_admin',true)->first();
        SmsService::send($admin,$message);
    }
}

جمع بندی

به جای اینکه controller ما پر از کدهایی باشد که اصلا ربطی به آن ندارند بهتر است آنها را در کلاس مربوط به خودشان بنویسیم و موقع نیاز آن را صدا بزنیم. به همین علت هم استفاده از event ها در لاراول به تمیزتر شدن کنترلر و در نتیجه maintainable شدن نرم افزار کمک می‌کنند.