← Back to overview

Get Cron Expressions From Laravel's Fluent Schedule Builder

For a recent software development project I needed to let the users schedule recurring tasks. Under the hood, I’m just storing the cron expression, but of course that’s not a viable way for non-technical end users to define the schedule for a recurring task.

So I ended up with a user interface where the users could click through their schedule settings. However, in order to store that input as cron expression I needed to reverse the user’s input back to a storable and valid cron expression. As I’m using Laravel, there’s already anything under the hood that is required to achieve exactly that without pulling in any external dependencies.

Building the CronExpressionBuilder

We’re using the magic of reflection to get Laravel’s on-board Schedule class to tell us the cron expression of a schedule that has been built with the well-known and user- and developer-friendly fluent interface.

use Illuminate\Console\Scheduling\Schedule;
use ReflectionProperty;
class CronExpressionBuilder
{
public static function get(\Closure $callback): string
{
$schedule = app(Schedule::class);
// Create a dummy event
$event = $schedule->command('dummy:command');
// Apply the scheduling constraints
$callback($event);
// Extract the cron expression using reflection
$reflection = new ReflectionProperty($event, 'expression');
$reflection->setAccessible(true);
return $reflection->getValue($event);
}
}

Using our CronExpressionBuilder

In order to use the new CronExpressionBuilder, all you need to do is calling the function with a callable that accepts a variable of Illuminate\Console\Scheduling\Event. You can then apply all the scheduling expressions you need to that variable and end up with a cron expression that equals the used expressions.

use Illuminate\Console\Scheduling\Event;
// ...
$cronExpression = CronExpressionBuilder::get(function (Event $event) use ($request) {
$event->daily()->at("04:04");
});
assert($cronExpression === '4 4 * * *')

This of course also works with more complex expressions. Neat little trick to get those cron expressions using pure Laravel and zero additional dependencies.