Mapdev

Posted 4 months ago

Laravel & User Defined Scheduling

View Profile

Laravel & User Defined Scheduling 📅 ⌚️

I wanted to build something that allowed users to define a schedule of when emails were sent — alas nothing by default so I built a Trait that uses Laravel’s existing scheduling to do just this!

30 Second Version ⏱

I have created a trait you can add in Laravel that will give it a schedule on which you can check against. The example for usage is when a user wants to receive their daily email at 16:00 on weekdays only — easy if everyone is the same but not when somebody wants it every day!
It uses the Laravel Scheduler methods such as everyTenMinutes() to make it easy to build a schedule. Trait code is Here


Long Version with Code!

The Idea 💡

Build a Basecamp like check in app that asks “What are you working on?”

The Issue 🤔

In Basecamp you can set for every check in a custom schedule so it sends every X days/weeks at Y time and ignores Z. Laravel does not support this directly using its Scheduler

Basecamp 3 Check In Frequency Input

The End Goal 😎

The aim is that every minute Laravel Scheduler runs and checks through a collection of user generated ‘Check-ins’ to see if they are due to be sent.

The Detail ✍️

Laravel has almost everything built into it already! 
Yay! But it is hidden as a trait and not exposed to you directly; what we want is to add this magic dust to a Model (I am using a model called Checkin) and be able to add a schedule to it, store it and check when it needs to run.

The Laravel goodness hides in Illuminate\Console\Scheduling\ ManagesFrequencies and this is where you can set the schedule using the inline syntax used elsewhere

Examples of Laravel Scheduler frequency options

I went down a rabbit hole of cron on a previous project and when I came across this functionality need I found out Laravel has everything I need by having the cron-expression package included. This allows for parsing and testing a cron string to find out when it should be run.

Instead of creating a bespoke class implementing the scheduling logic I was able to wrap it onto a Trait HasSchedule that links up all the scheduling goodies and cron-expression.

Here is the gist for you to use!

Code breakdown 📑

Implements the built in Laravel Trait for Schedule Frequency syntax
Cron Expression & Timezone properties. This is what is set and should be overridden by a model property if you want it to be saved!
The test of if this schedule is due now. If a timezone is set then it will use that
Two methods that allow you to see when the previous and next times the schedule will be due. Useful for letting a user know how long till something next runs!

All of this code is pretty much covered in Laravel’s Illuminate\Console\Scheduling\Event class but just stripped down to the bare essentials.

Checking When to Run 🏃

So you have a collection of models each with a custom schedule set. How do they get called/ do something with Laravel Scheduler?! Well add it to the App\Console\Kernel.php

Basic verbose example of checking against a schedule and doing something when it is due. I have done it inline here but you could put this into a Command or Job

This code every minute checks every Checkin to see if it is due on this exact minute. If it is a job is dispatched that sends an email using that Checkin.

Things to Add 🚀

The code is super basic but does a lot of lifting so you don’t have to!

What could be added is more interaction with cron-expression so you can pass in a DateTime and it evaluates against that rather than now.

You could also include a scope such as areDue() that return the collection of those due right now

One more thing I think is possible is to auto schedule the minute checks in a model without the intermittent collection check in Kernel.php. This is my next challenge to get this into core so you can call $schedule->callClass(Checkin::class) or similar

My Code (Higher Order Function FTW! 🤘)

High order functions to filter due Checkin’s and then send the Email

I hope this was helpful — if so let me know! And do send me a message with any questions 😄

David
@mapdev

Must be logged in to comment
Laravel & User Defined Scheduling / Welcome to Signl