جدول المحتويات
لفرض أن لدينا في المشروع فورم تسجيل، ونريد عند أي عملية تسجيل، تعديل، حذف... أن يتم إرسال إشعار لمدير الموقع.
على سبيل المثال نريد أن يتم إشعار عند أي عملية تسجيل
public function store(Request $request) { $user = User::create([ 'name'=>$request->name, 'email'=>$request->email, 'password'=>Hash::make($request->password) ]); $user->notify(new NewUser()); return $user; }
كما نلاحظ في الكود أعلاه، أنه تم وضع دالة notify بداخل الدالة store، هذا صحيح، إلا أن ذلك يعتبر مخالف للـ Design Patern حيث أن الدالة store يجب أن تكون مسؤولة عن شيئ واحد فقط، وهو حفظ البيانات.
من هنا تبرز أهمية الـ observers، فما هو observers.
إقرأ أيضا : ما هي الإشعارات في لارافيل Laravel Notifications
حسب موقع لارافيل الرسمي
If you are listening for many events on a given model, you may use observers to group all of your listeners into a single class. Observers classes have method names which reflect the Eloquent events you wish to listen for. Each of these methods receives the model as their only argument. The make:observer Artisan command is the easiest way to create a new observer class.
يساعدنا observers في تنظيم الكونترولر وجعلة clean، حيث يساعدنا في عمل أي action عند أي تغيير على الموديل مثل ( حفظ، تعديل، حذف ...)
يمكن إنشاء observer من خلال الكود التالي
php artisan make:observer UserObserver --model=User
UserObserver : هو إسم الـ observer.
--model=User : حيث يجب تحديد الموديل.
بعد تنفيذ الأمر، يتم إنشاء مجلد جديد بداخل المشروع بإسم Observers وبه الكلاس UserObserver
لو ألقينا نظره على UserObserver نجد إنه يحتوي على الدوال (events) التالية
<?php namespace App\Observers; use App\Models\User; class UserObserver { public function created(User $user) { // } public function updated(User $user) { // } public function deleted(User $user) { // } public function restored(User $user) { // } public function forceDeleted(User $user) { // } }
إلا إنه يمكن إضافة دوال أخرى مثل Retrieved، Creating, Updating, Saving, Saved, Deleting, Restoring...
الدوال أعلاه يتم تنفيذها عند حدوث أي تغيير على الموديل، فمتى يتم تنفيذ كل دالة
Retrived : يتم تنفيذ هذه الدالة عند جلب model record من قاعدة البيانات
Model::findOrFail($id); //this triggers the retrieved method in the observer class
Creating : يتنم تنفيذه هذه الدالة عند حفظ البيانات لكن قبل أن يتم الحفظ أي قبل أن يتم تعيين (id, timestamp).
Created : يتم تنفيذها عند حفظ البيانات لكن بعد أن يتم حفظها في قاعدة البيانات.
Updating : يتم تنفيذها عندما تكون البيانات في عملية التعديل، لكن قبل أن يتم تعديلها في قاعدة البيانات.
Updated: يتم تنفيذها بعد أن يتم تعديل البيانات بنجاح.
Saving and Saved : هذه الدوال يتم تنفيذها قبل وبعد حفظ البيانات ( إنشاء موديل جديد )، يتم تنفيذ saving ثم creating ثم created ومن ثم saved، كذلك الأمر يتم تنفيذه عند عملية التعديل على الموديل saving, updating, updated, saved.
Deleting : يتم تنفيذه اثناء عملية الحذف.
Deleted : يتم تنفيذها بعد إتمال عملية الحذف بنجاح.
Restoring and Restored : يتم تنفيذها عند إسترجاع الموديل المحذف ( using soft delete ).
حتى يتم تفعيل الـ Observer فإننا بحاجة لتسجيلهـ وللقيام بذلك نذهب للملف AppServiceProvider.php وبداخل الدالة boot نقوم بعملية التسجيل
public function boot() { User::observe(new UserObserver()); }
إرسال notification عند تسجيل مستخدم جديد في التطبيق
قبل إستخدام observer
public function store(Request $request) { $user = User::create([ 'name'=>$request->name, 'email'=>$request->email, 'password'=>Hash::make($request->password) ]); $user->notify(new NewUser()); return $user; }
بعد إستخدام ovserver
public function store(Request $request) { return User::create([ 'name'=>$request->name, 'email'=>$request->email, 'password'=>Hash::make($request->password) ]); }
وبداخل الكلاس UserObserver بداخل الدالة created
public function created(User $user) { $user->notify(new NewUser()); }
ماذا إذا كان لدينا Article Model وكذلك Comment Model، أي أن لدينا جدول مقالات وكذلك جدول للتعليقات، حيث أن كل مقال يمكن أن يكون له مجموعة من التعليقات، ونريد أنه عند حذف مقال أن يتم حذف التعليقات التابعة له.
بداية كما نعلم يجب إنشاء العلاقة بين Article Model و Comment Model
public function comments() { return $this->hasMany(Comment::class); }
الحذف قبل إستخدام observer
في الدالة destroy نقوم بإنشاء دالة حذف المقال وكذلك دالة حذف التعليقات
public function destroy(Article $article) { $article->delete(); $article->comments()->delete(); }
وكما نعلم أن الدالة يجب أن تكون مسؤولة عن شيئ واحد فقط، وفي هذه الحالة يجب أن تكون مسؤولة عن حذف المقالات فقط.
الحذف بعد إنشاء observer
إنشاء ArticleObserver
php artisan make:observer ArticleObserver --model=Article
تسجيل ArticleObserver
في الكلاس AppServiceProvider بداخل الدالة boot
public function boot() { Article::observe(new ArticleObserver()); }
الأن بما إننا نتعامل مع عملية حذف نذهب للدالة deleted في الكلاس ArticleObserver أو ننشئ الدالة deleting ونضع جملة الحذف
public function deleted(Article $article) { $article->comments()->delete(); }
تنظيف الـ ArticleController
نعود للدالة destroy ونقوم بإزالة $article->comment_Delete فتصبح بالشكل التالي
public function destroy(Article $article) { $article->delete(); }
إقرأ أيضا : ما هي الإشعارات في لارافيل Laravel Notifications
عاااش جداااا والله شرح ممتاز ❤❤
الشرح واضح جدا شكرا 🙏
يعطيك العافية انا من متابعين موقعك بشكل دوري شرح جدا منظم و مفيد و جميل بارك الله فيك
شرح سهل نتمني المزيد
شرح سهل نتمني المزيد
رائع , جزاك الله كل خير , استمر و اتمنى لو تشرح اي مواضيع جديدة مهمة جدا تم اضافتها في لارافيل 9
تسلم ايدك استمر
شرح بسيط وجميل.. شكرا لك.
جزاك الله عنا خيرا
جزاك الله خيرا
شكرا
أنت رائع
رووووووووووعة
رائع استمر ،، لدي بعض الاستفسارات حول تطويرك لهذا الموقع اذا ممكن تتواصل معي عبر الايميل
زائر
شرح أكثر من رائع، عاشت ايدك