Installation:
composer require omaralalwi/laravel-time-craft
Publish the config (if needed):
php artisan vendor:publish --provider="OmarAlalwi\TimeCraft\TimeCraftServiceProvider"
First Use Case: Apply a built-in scope to a query:
use OmarAlalwi\TimeCraft\Scopes\TodayScope;
$todayRecords = Model::query()->today()->get();
Key Entry Points:
OmarAlalwi\TimeCraft\Traits\TimeCraft (for models).OmarAlalwi\TimeCraft\Scopes\* (e.g., TodayScope, YesterdayScope).OmarAlalwi\TimeCraft\Helpers\TimeCraft (e.g., formatDate(), humanizeTime()).Model Integration: Use the trait in your Eloquent models to auto-apply scopes:
use OmarAlalwi\TimeCraft\Traits\TimeCraft;
class Event extends Model
{
use TimeCraft;
}
Now call scopes directly:
Event::thisWeek()->get();
Query Builder Usage: Attach scopes dynamically:
$query = Model::query();
$query->applyScopes(['thisMonth', 'active']);
Custom Scopes: Extend existing scopes or create new ones:
namespace App\Scopes;
use OmarAlalwi\TimeCraft\Scopes\BaseScope;
class CustomScope extends BaseScope
{
protected $field = 'created_at';
protected $operator = '>=';
protected $value = now()->subDays(7);
public function apply($query)
{
return $query->where($this->field, $this->operator, $this->value);
}
}
Helper Functions: Format dates in views or controllers:
use OmarAlalwi\TimeCraft\Helpers\TimeCraft;
$formatted = TimeCraft::formatDate(now(), 'Y-m-d H:i');
$humanized = TimeCraft::humanizeTime(now()->subHours(3));
API Responses: Use helpers to standardize date formats in JSON:
return response()->json([
'event' => [
'date' => TimeCraft::formatDate($event->date, 'Y-m-d'),
'time' => TimeCraft::humanizeTime($event->date),
],
]);
Time Zone Handling:
Configure default time zone in config/time-craft.php:
'timezone' => 'America/New_York',
Override per query:
Model::query()->setTimezone('Europe/London')->thisWeek()->get();
Scope Conflicts:
created_at), later scopes may override earlier ones.whereRaw or chain scopes carefully:
Model::query()->where('created_at', '>=', now()->subDays(30))->thisWeek();
Time Zone Mismatches:
time-craft.php. Ensure this matches your app’s timezone.\Log::info('Timezone:', config('time-craft.timezone'));
Dynamic Field Names:
created_at). Override in custom scopes:
protected $field = 'published_at';
Helper Caching:
humanizeTime() caches results for 1 hour by default. Clear cache if dates change unexpectedly:
TimeCraft::clearHumanizeCache();
Inspect Queries: Use Laravel’s query logging to verify scope SQL:
DB::enableQueryLog();
Model::thisWeek()->get();
\Log::info(DB::getQueryLog());
Scope Order:
Scopes are applied in declaration order. Reorder or use where() for control:
Model::query()->where('status', 'active')->thisWeek();
Edge Cases:
now() boundaries (e.g., today() at midnight).$midnight = now()->startOfDay();
Model::where('created_at', '>=', $midnight)->today()->get();
Custom Time Frames:
Extend BaseScope to add reusable logic:
class LastNDaysScope extends BaseScope
{
protected $days;
public function __construct($days)
{
$this->days = $days;
}
public function apply($query)
{
return $query->where('created_at', '>=', now()->subDays($this->days));
}
}
Usage:
Model::query()->applyScopes(['lastNDays:30']);
Localization:
Override humanizeTime() translations in config/time-craft.php:
'humanize' => [
'minutes' => 'minute|minutes',
'hours' => 'hour|hours',
// ...
],
Performance:
select() to limit columns:
Model::thisWeek()->select(['id', 'title'])->get();
remember():
$todayEvents = cache()->remember("events.today", now(), function () {
return Event::today()->get();
});
Testing: Mock time in tests:
use OmarAlalwi\TimeCraft\Facades\TimeCraft;
TimeCraft::shouldReceive('now')->andReturn($mockedDate);
How can I help you explore Laravel packages today?