Skip to content

Crumbls/timeline

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

crumbls/timeline

A scheduling and occurrence engine for Laravel.

This package is not a calendar UI. It handles the domain model behind recurring events: defining schedules as RRULE strings, pre-generating concrete occurrence records, and giving you a clean query interface to drive any calendar or scheduling feature you build.


Requirements

  • PHP 8.2+
  • Laravel 10, 11, or 12

Installation

composer require crumbls/timeline
php artisan vendor:publish --tag=timeline-migrations
php artisan migrate

Core Concepts

Event — the conceptual thing. "Laravel Meetup" or "Board Meeting". Not a specific date.

Rule — defines when an Event occurs. Stores an RFC 5545 RRULE string. One Event can have multiple Rules.

Occurrence — a concrete scheduled instance. "Laravel Meetup on June 5th." This is the primary query model.

OccurrenceException — a one-off modification to a single Occurrence (cancel, reschedule, modify). Never modifies the parent Rule.

Location — a reusable venue attached to Occurrences.


RRuleBuilder

Writing RRULE strings by hand is error-prone. Use the fluent builder:

use Crumbls\Timeline\Support\RRuleBuilder;

// Every Tuesday
RRuleBuilder::make()->weekly()->onDays('TU')->toString();

// First Friday of the month
RRuleBuilder::make()->monthly()->onNthWeekday(1, 'FR')->toString();

// Every other Monday, 20 times
RRuleBuilder::make()->weekly()->every(2)->onDays('MO')->count(20)->toString();

// Human-readable description of any RRULE
RRuleBuilder::describe('FREQ=WEEKLY;BYDAY=MO,WE,FR');
// "weekly on Monday, Wednesday and Friday"

See IMPLEMENTATION.md for the full builder reference.


Quick Start

use Crumbls\Timeline\Models\Event;
use Crumbls\Timeline\Models\Rule;
use Crumbls\Timeline\Enums\EventStatus;

// Create an event
$event = Event::create([
    'name'     => 'Laravel Meetup',
    'timezone' => 'America/Denver',
    'status'   => EventStatus::Published,
]);

// Add a weekly rule — occurrences generate automatically
Rule::create([
    'event_id'  => $event->id,
    'starts_at' => '2025-06-03 18:00:00',
    'ends_at'   => '2025-06-03 20:00:00',
    'rrule'     => 'FREQ=WEEKLY;BYDAY=TU',
]);

// Query occurrences
use Crumbls\Timeline\Models\Occurrence;
use Carbon\Carbon;

$feed = Occurrence::between(Carbon::parse('2025-06-01'), Carbon::parse('2025-06-30'))
    ->scheduled()
    ->with(['event', 'location'])
    ->orderBy('starts_at')
    ->get();

Occurrence Scopes

Occurrence::upcoming()->get();
Occurrence::today()->get();
Occurrence::between($start, $end)->get();
Occurrence::scheduled()->get();
Occurrence::forEvent($event->id)->get();
Occurrence::atLocation($location->id)->get();

Scopes chain freely:

Occurrence::scheduled()->upcoming()->forEvent($event->id)->paginate(20);

Configuration

// config/timeline.php
return [
    'table_prefix'                 => 'timeline_',
    'occurrence_generation_months' => 12,
    'default_timezone'             => 'UTC',
];

All table names are resolved through table_prefix. Change it before running migrations.


How Occurrence Generation Works

When a Rule is saved, GenerateOccurrencesJob is dispatched. The OccurrenceGenerator service expands the RRULE into concrete dates for the configured window (default: 12 months), then:

  • Creates new Occurrence records for dates not already present
  • Updates ends_at on existing records if the duration changed
  • Deletes future Scheduled occurrences no longer in the expansion
  • Leaves Cancelled and Completed occurrences untouched

You can also trigger generation manually:

use Crumbls\Timeline\Services\OccurrenceGenerator;

app(OccurrenceGenerator::class)->generate($rule);

Testing

composer test

56 Pest tests covering events, rules, occurrences, generator logic, and exceptions.


Further Reading

See IMPLEMENTATION.md for a full implementation guide including calendar feed construction, location usage, exception handling, queue setup, and an RRULE reference table.


License

MIT

About

An event calendar for Laravel

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages