اهلا بيك صديقى مطور لارفيل تعالى انهارده نتعرف على ميزة فى لارافيل اسمها
Laravel Global Scope
باختصار شديد هى كا شرط كده بتطبق على مودل معين أو اكثر من مودل وبالشكل ده هتطبق على اى كويرى خاصة بالمودل من غير ما تكتبها لو مش فاهم تعالى اوضحلك الموضوع اكتر
قبل ما نبدأ تعالى اوضحلك المشكله بمثال عملى فى البدايه
هفترض على سبيل المثال ان عندى فى المشروع متجر للكتب والكتب هذه يتم اضافتها من قبل مستخدمين وانا هنا محتاج المستخدم اللى يقوم بتسجيل الدخول هو اللى يتعرضله الكتب اللى تم اضافتها فقط
ويقدر يتحكم فى الحذف والتعديل وكل العمليات
فا انت هنا مطالب فى كل كويرى تتأكد ان المستخدم اللى مسجل دخول تتأكد انه حقل ال
user_id == auth()->id()
فا بدل ماتكتب ده بقا كل الكويرى اللى هستخدمها ظهر عندنا بقا ال
Laravel Global Scope
عندى منها نوعين هما
- انك تعملها فى كلاس منفصل وتستخدمها على أكثر من مودل
- انك تعملها فى نفس المودل
نبدأ الاول
--- فى كلاس منفصل
هنكمل على نفس المثال هننشئى اولا مجلد جديد بداخل ال
app
وليكن اسمه
Scopes
هيكون عندى بالشكل ده
app/Scopes
وهنشأ بداخله ملف وليكن اسمه
AuthorScope.php
فى البدايه سوف نعطى الملف
namespace
<?php
namespace App\Scopes;
ثم ننشأ بداخله
class
<?php
namespace App\Scopes;
class AuthorScope{
}
ثم نقوم عمل استدعاء لل
Scope interface
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
class AuthorScope implements Scope{
}
بعد ذلك نقوم بعمل فانكشن جديدة اسمها
apply
تأخذ اتنين براميتر الاول هما
Illuminate\Database\Eloquent\Model;
Illuminate\Database\Eloquent\Builder;
<?php
namespace namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class AuthorScope implements Scope{
/**
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->where('user_id', auth()->id() );
}
}
هكذا تعلمنا كيفية انشاء
--- scope
بشكل منفصل
سنتعلم كيفية تطبيقها على اى مودل موجود عندنا بداخل التطبيق
سنكمل على نفس المثال السابق
namespace App\Models;
use App\Scopes\AuthorScope;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
protected static function boot()
{
parent::boot();
static::addGlobalScope(new AuthorScope);
}
}
وبذلك سوف يتم اضافة هذا الشرط على جميع الكويرى على هذا المودل على سبيل المثال
Book::all();
// سيتم اضافة هذا الشرط تلقائيا طالما هذا المودل مرتبط
// Author Scope
// بمعنى ان الاستعلام السابق هو فى الاصل
// Book::where( 'user_id' , auth()->id() );
_ملاحظات هامة
_
1- فى حالة اردنا اضافة
select
سوف تكتب
addSelect
على سبيل المثال
<?php
namespace namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class AuthorScope implements Scope{
/**
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->addSelect(['id','title' , 'description' , 'user_id','created_at'] );
}
}
2- فى بعض الحالات نحتاج لعدم استخدام هذا ال
Scope
وفى هذه الحاله نقوم باستخدام
Book::withoutGlobalScopes(AuthorScope::class)->all();
وفى حالة كان يوجد عندنا اكثر من واحد ونريد الغاء نقوم بتمريرهم كا مصفوفة
( Array )
Book::withoutGlobalScopes([AuthorScope::class , OtherScope ::class , .......... ])->all();
وفى حالة الغاء الجميع نترك البارميتر فارغ بهذا الشكل
Book::withoutGlobalScopes()->all();
وبهذا الشكل قد تعرفنا على كيفية الانشاء فى كلاس منفصل وتطبيقه على اى مودل متواجد بداخل التطبيق سنتعرف ايضا على كيفية الاستخدام بداخل المودل فى حالة كان بسيط ولا حاجه لفصله فى كلاس منفصل ستكون الطريقة كالاتى
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class Book extends Model
{
/**
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope('author', function (Builder $builder) {
$builder->where('user_id', auth()->id() );
});
}
}
فى حالة اذا اردنا عدم استخدامه فى استعلام ما تكون بنفس الطريقه السابقه ولكن استخدام الاسم لانه لايوجد كلاس هنا بهذه الطريقة
Book::withoutGlobalScopes('author')->all();
Top comments (0)