directorytree/cadence 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

directorytree/cadence

最新稳定版本:v1.0.1

Composer 安装命令:

composer require directorytree/cadence

包简介

Model-based scheduling for Laravel

README 文档

README

Model-based scheduling for Laravel.

Cadence provides a driver-based scheduling system for your Eloquent models using cron expressions or RRULE recurrence patterns. Attach one or many schedules to any model, and Cadence will track and dispatch events when they're due.

Index

Requirements

  • PHP >= 8.2
  • Laravel >= 11.0

Installation

You can install the package via composer:

composer require directorytree/cadence

Then, install at least one schedule driver:

# Cron (recommended for simple schedules)
composer require dragonmantank/cron-expression

# RRULE via php-rrule
composer require rlanvin/php-rrule

# RRULE via Recurr
composer require simshaun/recurr

Publish and run the migrations:

php artisan vendor:publish --provider="DirectoryTree\Cadence\CadenceServiceProvider"
php artisan migrate

This creates a schedules table with the following columns:

  • schedulable_type / schedulable_id — polymorphic relation to your model
  • type — the driver type (e.g. cron, rrule, recurr)
  • expression — the schedule expression
  • timezone — optional timezone for the schedule
  • next_run_at — precomputed next occurrence for efficient querying
  • last_run_at — timestamp of the last run

Setup

Implement the Schedulable interface and use the HasSchedules trait on any model you want to schedule:

// app/Models/Report.php

namespace App\Models;

use DirectoryTree\Cadence\HasSchedules;
use DirectoryTree\Cadence\Schedulable;
use Illuminate\Database\Eloquent\Model;

class Report extends Model implements Schedulable
{
    use HasSchedules;
}

Usage

Adding Schedules

Create a driver instance and add it to your model:

use DirectoryTree\Cadence\Drivers\CronSchedule;

$report = Report::find(1);

// Every day at noon
$report->addSchedule(new CronSchedule('0 12 * * *'));

// Every Monday at 9am
$report->addSchedule(new CronSchedule('0 9 * * 1'));

With RRULE expressions:

use DirectoryTree\Cadence\Drivers\RruleSchedule;

// Every weekday
$report->addSchedule(new RruleSchedule('FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR'));

// Monthly on the 15th, starting from a specific date
$report->addSchedule(new RruleSchedule('DTSTART=20260101T000000;FREQ=MONTHLY;BYMONTHDAY=15'));

Timezones

Schedules can be timezone-aware. Pass the timezone as the second argument:

// Every day at 9am Eastern
$report->addSchedule(
    new CronSchedule('0 9 * * *', 'America/New_York')
);

Or set it via the setTimezone() method:

$schedule = new CronSchedule('0 9 * * *');

$schedule->setTimezone('America/New_York');

$report->addSchedule($schedule);

Running Due Schedules

Register the schedules:run command in your application's scheduler to run every minute:

// routes/console.php

use Illuminate\Support\Facades\Schedule;

Schedule::command('schedules:run')
    ->withoutOverlapping()
    ->everyMinute();

This command queries all schedules where next_run_at <= now(), dispatches a ScheduleTriggered event for each, and advances next_run_at to the next occurrence.

Listening for Triggered Schedules

Listen for the ScheduleTriggered event to perform work when a schedule fires:

// app/Listeners/HandleScheduleTriggered.php

namespace App\Listeners;

use DirectoryTree\Cadence\Events\ScheduleTriggered;

class HandleScheduleTriggered
{
    public function handle(ScheduleTriggered $event): void
    {
        $schedule = $event->schedule;

        // Access the parent model
        $model = $schedule->schedulable;

        // Perform work based on the model type
        if ($model instanceof \App\Models\Report) {
            $model->generate();
        }
    }
}

Register it in your EventServiceProvider or use event discovery.

Drivers

Cadence uses a driver-based architecture. Drivers are automatically registered when their backing library is installed.

Cron

Requires dragonmantank/cron-expression:

use DirectoryTree\Cadence\Drivers\CronSchedule;

new CronSchedule('0 12 * * *');         // Every day at noon
new CronSchedule('*/15 * * * *');       // Every 15 minutes
new CronSchedule('0 9 * * 1-5');        // Weekdays at 9am

RRULE (php-rrule)

Requires rlanvin/php-rrule:

use DirectoryTree\Cadence\Drivers\RruleSchedule;

new RruleSchedule('FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR');
new RruleSchedule('FREQ=MONTHLY;BYMONTHDAY=1;COUNT=12');

RRULE (Recurr)

Requires simshaun/recurr:

use DirectoryTree\Cadence\Drivers\RecurrSchedule;

new RecurrSchedule('FREQ=WEEKLY;BYDAY=MO,WE,FR');
new RecurrSchedule('FREQ=YEARLY;BYMONTH=1;BYMONTHDAY=1');

Custom Drivers

Create a class that extends the base Schedule driver:

namespace App\Drivers;

use Carbon\CarbonInterface;
use DirectoryTree\Cadence\Drivers\Schedule;

class CustomSchedule extends Schedule
{
    protected function resolveNextOccurrence(CarbonInterface $after): ?CarbonInterface
    {
        // Your recurrence logic here
    }
}

Then register it in your AppServiceProvider:

use App\Drivers\CustomSchedule;
use DirectoryTree\Cadence\Schedule;

Schedule::driver('custom', CustomSchedule::class);

Customizing Drivers

Each driver exposes a static tap method to configure the underlying library instance before it's used:

use Cron\CronExpression;
use DirectoryTree\Cadence\Drivers\CronSchedule;

CronSchedule::tap(function (CronExpression $cron) {
    // Configure the CronExpression instance
});
use Recurr\Rule;
use Recurr\Transformer\ArrayTransformer;
use Recurr\Transformer\ArrayTransformerConfig;
use DirectoryTree\Cadence\Drivers\RecurrSchedule;

RecurrSchedule::tap(function (Rule $rule, ArrayTransformer $transformer) {
    $transformer->setConfig(
        (new ArrayTransformerConfig)->enableLastDayOfMonthFix()
    );
});

Pass null to clear the callback:

RecurrSchedule::tap(null);

统计信息

  • 总下载量: 2
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 27
  • 点击次数: 7
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 27
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-04

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固