پکیج کربن کمک میکنه تا به صورت بهینهتری تاریخ و زمان رو در PHP و لاراول مدیریت کنیم اما اکثر اوقات پروژه نیازمندیهایی داره که ناخودآگاه کد مارو به سمت پیچیدگی میبره و اینجاست که باید هنر به خرج بدیم و کاری کنیم تا تمیزی رو در کدهای خودمون نگهداریم.
یکی از کارهای رایج موقع کار با تاریخ و زمان فیلتر کردن اونا به کمک Eloquent هست که اگه مراقب نباشیم به راحتی میتونیم کد کثیفی تولید کنیم. در این مقاله بررسی میکنیم که چطور با ایجاد یک trait بتونیم به صورت موثر تاریخ و زمان رو مدیریت کنیم.
پوشه جدیدی با نام Traits
در پوشه app
بسازید و فایلی با نام HasManageableDate.php
در اون پوشه ایجاد کنید و در ادامه namespace
براش مشخص کنید:
namespace App\Traits;
و از اونجایی که قراره به کمک کربن تاریخ و زمان رو مدیریت کنیم پس باید فراخوانیش کنیم:
use Illuminate\Support\Carbon;
چون قراره جنس پارامترهای ورودی و خروجی رو خودمون تعیین کنیم پس لازمه که کلاس Builder
رو فراخوانی کنیم چون یک شی از این کلاس قراره بهمون کمک کنه با eloquent تعامل کنیم.
use Illuminate\Database\Eloquent\Builder;
و نهایتا لازمه که قالب trait خودمون که اسمش HasManageableDate
هست رو ایجاد کنیم:
trait HasManageableDate {}
تا اینجا فایل HasManageableDate.php
به این صورت میشه:
<?php namespace App\Traits; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Carbon; trait HasManageableDate {}
در این مرحله باید از مفهوم scopeها در لاراول استفاده کنیم تا بتونیم متدهایی رو تولید کنیم که بتونند در همه قسمتهای اپلیکیشن با Eloquent کار کنند. اولین متد رو با نام scopeToday
ایجاد کنید و این متد قراره رکوردهایی که امروز در جدول مورد نظر دیتابیس ما تولید شدند رو به ما برگردونه.
public function scopeToday(Builder $query, string $column = 'created_at'): void { $query->whereDate($column, today()); }
تو متد بعدی قراره تمامی رکوردهایی که دیروز از جدول مورد نظر دیتابیس ما تولید شدند رو بگیریم و برای همین اسمش scopeYesterday
هست.
public function scopeYesterday(Builder $query, string $column = 'created_at'): void { $query->whereDate($column, Carbon::yesterday()); }
متد بعدی اسمش scopeCurrentWeek
هست و قراره تمامی رکوردهایی از جدول مورد نظر دیتابیس رو برگردونه که از روز اول هفته فعلی تا روزی که در اون هستیم ایجاد شدند.
public function scopeCurrentWeek(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [now()->startOfWeek(), now()]); }
متد بعدی که اسمش scopeCurrentMonth
هست، قراره تمامی رکوردهایی از جدول مورد نظر دیتابیس رو برگردونه که از روز اول ماه فعلی تا روزی که در اون هستیم ایجاد شدند.
public function scopeCurrentMonth(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [now()->startOfMonth(), now()]); }
متد بعدی scopeCurrentQuarter
هست که تمامی رکوردهایی از جدول مورد نظر دیتابیس رو برمیگردونه که از روز اول ماه فصل فعلی تا روزی که در اون هستیم ایجاد شدند.
public function scopeCurrentQurter(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [now()->startOfQuarter(), now()]); }
متدscopeCurrentYear
هم تمامی رکوردهایی که از جدول مورد نظر دیتابیس از روز اول سال فعلی تا روزی که در اون هستیم ایجاد شدند رو برمیگردونه.
public function scopeCurrentYear(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [now()->startOfYear(), now()]); }
متد بعدی قراره تمامی رکوردهایی از جدول مورد نظر دیتابیس که در 7 روز گذشته (با احتساب امروز) ایجاد شدند رو برگردونه و برای همین اسمش scopeLast7Days
هست.
public function scopeLast7Days(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [today()->subDays(6), now()]); }
متد بعدی تمامی رکوردهایی از جدول مورد نظر دیتابیس که در 30 روز گذشته (با احتساب امروز) ایجاد شدند رو برگردونه و برای همین اسمش scopeLast30Days
هست.
public function scopeLast30Days(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [today()->subDays(29), now()]); }
به کمک متد بعدی تمامی رکوردهایی از جدول مورد نظر دیتابیس که در 90 روز گذشته (با احتساب امروز) ایجاد شدند رو میگیریم و برای همین اسمش scopeLast90Days
هست.
public function scopeLast90Days(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [Carbon::today()->subDays(89), Carbon::now()]); }
متد بعدی قراره scopePreviousWeek
باشه که تمامی رکوردهایی از جدول مورد نظر دیتابیس که هفته گذشته ایجاد شدند رو برای ما میگیره.
public function scopePreviousWeek(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [now()->startOfWeek()->subDays(7), now()->startOfWeek()]); }
متد بعدی هم scopePreviousMonth
هست که تمامی رکوردهایی از جدول مورد نظر دیتابیس که ماه گذشته ایجاد شدند رو برای ما میگیره.
public function scopePreviousMonth(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [now()->startOfMonth()->subMonth(), now()->startOfMonth()]); }
و متد بعدی هم scopePreviousQuarter
هست که تمامی رکوردهایی از جدول مورد نظر دیتابیس که فصل گذشته ایجاد شدند رو برای ما میگیره.
public function scopePreviousQuarter(Builder $query, string $column = 'created_at'): void { $query->whereBetween($column, [now()->startOfQuarter()->subMonths(3), now()->startOfQuarter()]); }
طبق مفهوم accessor در لاراول قراره که تفاوت زمانی تاریخی که یک رکورد ایجاد شد با زمان حال حاضر رو بگیریم و نشون بدیم پس برای همین اسم متد بعدی createdTimeDiff
هست.
public function createdTimeDiff(): Attribute { return Attribute::make( get: fn () => $this->created_at->diffForHumans(), ); }
در متد بعدی قصد داریم تفاوت آخرین زمانی که رکورد موردنظر ما آپدیت شد رو با زمان حال حاضر بگیریم و برای همین اسمش رو lastUpdatedTimeDiff
قرار میدیم.
public function lastUpdatedTimeDiff(): Attribute { return Attribute::make( get: fn () => $this->created_at->diffForHumans(), ); }
لازمه این trait رو رو در Model
موردنظر خودتون فراخوانی کنید تا بتونید ازش استفاده کنید:
<?php namespace App\Models; use App\Traits\HasManageableDate; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasFactory, HasManageableDate; // ... }
حالا هر متدی که در trait تعریف شده میشه استفاده کرد تا رکوردهای موجود در جدول مربوطه رو فیلتر کنیم.
$todayProducts = Product::today()->get();
و برای گرفتن نمایش فاصله زمانی کاربرپسند الان نسبت به زمانی که یک رکورد ایجاد شد به روش پایین عمل میکنیم:
$user = User::find(1); $userCreatedAt = $user->created_time_diff;
فایل نهایی HasManageableDate.php برای کمک به مدیریت بهینهتر تاریخ و زمان رو در گیتهاب قراردادم و مطمئنم که میتونه تو پروژهها مفید باشه.
تو این مقاله برای کار با تاریخ و زمان از کربن استفاده کردیم و برای جلوگیری از تکرار کدها یک trait ایجاد کردیم. شما میتونید براساس نیاز خودتون این trait رو تغییر بدید، مثلا در متدها تغییراتی ایجاد کنید، متد جدیدی اضافه کنید یا متد موجود رو حذف کنید تا مناسب پروژه شما باشه. امیدوارم که این مقاله برای شما مفید بوده باشد و لطفا اگر سوال یا نظری دارید حتما بهم بگید و در آخر ممنونم بابت وقتی که گذاشتید.