Skip to content

itsmattius/laravel-bluschedule

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Laravel BluSchedule

A Laravel package that enables database-driven task scheduling, allowing you to manage scheduled commands dynamically without modifying code or redeploying your application.

The Problem

In traditional Laravel applications, scheduled tasks must be defined in the app/Console/Kernel.php file:

protected function schedule(Schedule $schedule)
{
    $schedule->command('emails:send')->daily();
    $schedule->command('reports:generate')->weekly();
    $schedule->command('backup:run')->dailyAt('01:00');
}

This static approach has several limitations:

  • Requires Code Changes: Every schedule modification needs code changes and redeployment
  • No Runtime Flexibility: Cannot add, modify, or disable schedules without deploying
  • Lacks Dynamic Control: Difficult to implement user-defined or tenant-specific schedules
  • No Easy Management: No built-in UI or database interface for schedule management

The Solution

Laravel BluSchedule solves these problems by storing scheduled commands in the database, enabling you to:

✅ Add, modify, or remove schedules without touching code
✅ Enable/disable schedules dynamically using status flags
✅ Manage schedules through admin panels or APIs
✅ Implement tenant-specific or user-defined schedules
✅ Use all Laravel's built-in frequency methods or custom cron expressions

Features

  • Database-Driven Scheduling: Store all schedule definitions in the blu_schedules table
  • Active/Inactive Status: Enable or disable schedules without deletion
  • Flexible Frequencies: Support for all Laravel frequency methods (everyMinute(), hourly(), daily(), etc.)
  • Custom Cron Expressions: Use custom cron syntax for advanced scheduling
  • Parameter Support: Pass parameters to commands and frequency methods
  • Zero Configuration: Auto-discovery and auto-migration via Laravel package discovery

Installation

Install the package via Composer:

composer require abedi/bluschedule

The package uses Laravel's auto-discovery feature, so the service provider will be automatically registered.

Run the migration to create the blu_schedules table:

php artisan migrate

Make sure your system cron is configured to run Laravel's scheduler every minute:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Database Schema

The migration creates a blu_schedules table with the following structure:

Column Type Description
id bigint Primary key
name string Descriptive name for the schedule
command string Artisan command name (e.g., emails:send)
frequency string Frequency method or cron expression
frequency_params json Parameters for frequency method (nullable)
params json Parameters for the command (nullable)
status enum ACTIVE or DEACTIVE
created_at timestamp Creation timestamp
updated_at timestamp Last update timestamp

Usage

Basic Example

Insert a schedule into the database:

use Abedi\BluSchedule\Models\Schedule;
use Abedi\BluSchedule\Concerns\ScheduleStatusEnum;

Schedule::create([
    'name' => 'Send Daily Emails',
    'command' => 'emails:send',
    'frequency' => 'daily',
    'status' => ScheduleStatusEnum::ACTIVE,
]);

That's it! The command will now run daily without any code changes.

With Command Parameters

Schedule::create([
    'name' => 'Generate Monthly Report',
    'command' => 'reports:generate',
    'params' => ['--type=monthly', '--format=pdf'],
    'frequency' => 'monthly',
    'status' => ScheduleStatusEnum::ACTIVE,
]);

With Frequency Parameters

Schedule::create([
    'name' => 'Backup Database at 2 AM',
    'command' => 'backup:run',
    'frequency' => 'dailyAt',
    'frequency_params' => ['02:00'],
    'status' => ScheduleStatusEnum::ACTIVE,
]);

Custom Cron Expression

Schedule::create([
    'name' => 'Custom Schedule',
    'command' => 'custom:task',
    'frequency' => '0 */4 * * *', // Every 4 hours
    'status' => ScheduleStatusEnum::ACTIVE,
]);

Disable a Schedule

$schedule = Schedule::find(1);
$schedule->status = ScheduleStatusEnum::DEACTIVE;
$schedule->save();

Supported Frequencies

Simple Frequencies (No Parameters)

'everySecond'
'everyTwoSeconds'
'everyFiveSeconds'
'everyTenSeconds'
'everyFifteenSeconds'
'everyTwentySeconds'
'everyThirtySeconds'
'everyMinute'
'everyTwoMinutes'
'everyThreeMinutes'
'everyFourMinutes'
'everyFiveMinutes'
'everyTenMinutes'
'everyFifteenMinutes'
'everyThirtyMinutes'
'hourly'
'everyTwoHours'
'daily'
'weekly'
'monthly'
'quarterly'
'yearly'

Parameterized Frequencies

'hourlyAt' => ['17'] // Run at 17 minutes past the hour
'dailyAt' => ['13:00'] // Run daily at 1:00 PM
'twiceDaily' => [1, 13] // Run at 1:00 AM and 1:00 PM
'twiceDailyAt' => [1, 13, 15] // Run at 1:15 AM and 1:15 PM
'weeklyOn' => [1, '8:00'] // Run weekly on Monday at 8:00 AM
'monthlyOn' => [4, '15:00'] // Run on the 4th of each month at 3:00 PM
'twiceMonthly' => [1, 16, '13:00'] // Run on 1st and 16th at 1:00 PM
'quarterlyOn' => [4, '14:00'] // Run on 4th of each quarter at 2:00 PM
'yearlyOn' => [6, 1, '17:00'] // Run on June 1st at 5:00 PM

Custom Cron Expressions

For any frequency not listed above, you can use standard cron syntax:

'frequency' => '0 0 * * 0' // Every Sunday at midnight
'frequency' => '*/15 * * * *' // Every 15 minutes
'frequency' => '0 9-17 * * 1-5' // Weekdays 9 AM to 5 PM

How It Works

The package uses a smart detection mechanism in its ServiceProvider:

  1. Detects Schedule Commands: When any schedule:* artisan command runs (e.g., schedule:run, schedule:list)
  2. Loads Active Schedules: Queries the database for all schedules with ACTIVE status
  3. Registers Dynamically: Registers each schedule with Laravel's scheduler using the same API
  4. Executes Normally: Laravel's scheduler handles execution timing and running the commands

This approach ensures zero performance impact on non-scheduling operations and seamless integration with Laravel's existing scheduler.

API Reference

Schedule Model Methods

// Get schedule ID
$schedule->getId(): int

// Get schedule name
$schedule->getName(): string

// Get command name
$schedule->getCommand(): string

// Get frequency
$schedule->getFrequency(): string

// Get frequency parameters
$schedule->getFrequencyParams(): array

// Get command parameters
$schedule->getParams(): array

// Get status
$schedule->getStatus(): ScheduleStatusEnum

// Check if using custom cron expression
$schedule->isCustomFrequency(): bool

Best Practices

1. Use Descriptive Names

// Good
'name' => 'Send Weekly Newsletter to Subscribers'

// Bad
'name' => 'Task 1'

2. Leverage Status Instead of Deletion

// Good - Can be re-enabled later
$schedule->status = ScheduleStatusEnum::DEACTIVE;

// Less flexible - Data is lost
$schedule->delete();

3. Test Commands Independently

Before scheduling, test your commands manually:

php artisan emails:send --type=weekly

4. Monitor Schedule Execution

Use Laravel's built-in schedule commands:

# List all scheduled tasks
php artisan schedule:list

# Test the schedule without running tasks
php artisan schedule:test

5. Add Logging to Your Commands

protected function handle()
{
    $this->info('Starting email send process...');
    
    // Your logic here
    
    $this->info('Email send process completed.');
}

Use Cases

Multi-Tenant Applications

Different tenants can have different schedules:

Schedule::create([
    'name' => 'Tenant A Daily Report',
    'command' => 'tenant:report',
    'params' => ['--tenant=a'],
    'frequency' => 'daily',
    'status' => ScheduleStatusEnum::ACTIVE,
]);

Schedule::create([
    'name' => 'Tenant B Weekly Report',
    'command' => 'tenant:report',
    'params' => ['--tenant=b'],
    'frequency' => 'weekly',
    'status' => ScheduleStatusEnum::ACTIVE,
]);

Admin Panel Control

Build an admin interface to manage schedules:

// Controller method
public function updateSchedule(Request $request, $id)
{
    $schedule = Schedule::findOrFail($id);
    $schedule->update($request->validated());
    
    return redirect()->back()->with('success', 'Schedule updated!');
}

Temporary Schedules

Enable schedules for specific periods:

// Enable promotion task during campaign
$schedule = Schedule::create([
    'name' => 'Black Friday Promotion Emails',
    'command' => 'promotions:send',
    'frequency' => 'hourly',
    'status' => ScheduleStatusEnum::ACTIVE,
]);

// Disable after campaign ends
$schedule->update(['status' => ScheduleStatusEnum::DEACTIVE]);

Requirements

  • PHP 8.2 or higher
  • Laravel 11.0 or higher

License

This package is open-source software. Please check the LICENSE file for more information.

Credits

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

If you encounter any issues or have questions, please open an issue on the GitHub repository.


Transform your Laravel scheduling from static code to dynamic database control with BluSchedule! 🚀

About

A Laravel package that enables database-driven task scheduling, allowing you to manage scheduled commands dynamically without modifying code or redeploying your application.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages