masterix21 / laravel-bookings
Add bookings ability to any Eloquent model
Fund package maintenance!
Requires
- php: ^8.4
- illuminate/contracts: ^12.0 || ^13.0
- kirschbaum-development/eloquent-power-joins: ^4.2
- nesbot/carbon: ^3.8
- spatie/laravel-package-tools: ^1.92
- spatie/period: ^2.4
- staudenmeir/belongs-to-through: ^2.16
- staudenmeir/eloquent-has-many-deep: ^1.20
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- mockery/mockery: ^1.5
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^10.0.0 || ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.1
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/pest-plugin-test-time: ^2.2
This package is auto-updated.
Last update: 2026-05-19 09:58:46 UTC
README
Add booking functionality to any Eloquent model. Turn your models into bookable resources with time-based reservations, capacity management, planning constraints, overlap detection, and an event-driven architecture.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- Core Concepts
- Advanced Features
- Documentation
- Testing
- Contributing & Credits
Features
- 🚀 Make any Eloquent model bookable with a single trait
- 📅 Advanced time period management powered by spatie/period
- 🏢 Resource capacity control with configurable concurrency limits
- 📋 Planning constraints for weekday and time-window restrictions
- 🔍 Overlap detection and conflict prevention
- 🎯 Event-driven architecture for audit trails and integrations
- 🗂️ Polymorphic relationships for flexible booker and resource types
- 🔗 Related bookings with parent-child relationships
- 🔄 Automatic synchronization of resources and planning via model events
- 🛡️ Transaction safety with automatic rollback on failures
Requirements
| Requirement | Version |
|---|---|
| PHP | 8.4+ |
| Laravel | 12.x or 13.x |
Installation
Install the package via Composer:
composer require masterix21/laravel-bookings
Publish and run the migrations:
php artisan vendor:publish --tag="bookings-migrations"
php artisan migrate
Optionally, publish the config file:
php artisan vendor:publish --tag="bookings-config"
See the installation guide for optional migrations and upgrade notes.
Quick Start
1. Make a model bookable
Add the IsBookable trait to any model. A BookableResource is created and kept in sync automatically.
use Masterix21\Bookings\Models\Concerns\Bookable; use Masterix21\Bookings\Models\Concerns\IsBookable; class Room extends Model implements Bookable { use IsBookable; protected $fillable = ['name', 'capacity']; }
2. Configure the bookable resource
Each bookable model exposes its BookableResource, where you set availability and capacity:
$room = Room::create(['name' => 'Deluxe Suite', 'capacity' => 4]); $room->bookableResource->update([ 'max' => 1, // Maximum concurrent bookings 'size' => 4, // Resource capacity 'is_bookable' => true, 'is_visible' => true, ]);
3. Make a booking
use Masterix21\Bookings\Actions\BookResource; use Spatie\Period\Period; use Spatie\Period\PeriodCollection; $periods = PeriodCollection::make([ Period::make('2024-12-25', '2024-12-27'), ]); $booking = (new BookResource())->run( periods: $periods, bookableResource: $room->bookableResource, booker: auth()->user(), label: 'Christmas Holiday', meta: ['guests' => 2], );
Overlapping bookings are rejected automatically:
use Masterix21\Bookings\Exceptions\BookingResourceOverlappingException; try { $booking = (new BookResource())->run(/* ... */); } catch (BookingResourceOverlappingException $e) { return response()->json(['error' => 'Time slot already booked'], 409); }
See the getting started guide for a full walkthrough.
Core Concepts
| Concept | Description |
|---|---|
BookableResource |
The bookable item, linked to your model (Room, Car, …) via a polymorphic relation. |
Booking |
A reservation with booker, metadata, and one or more time periods. |
BookedPeriod |
An individual time slot within a booking, enabling multi-period reservations. |
BookablePlanning |
Availability rules: working days, time windows, and constraints for a resource. |
Advanced Features
Each feature below is summarized here and documented in full under docs/.
Booking lifecycle callbacks
Hook custom logic before and after a booking is persisted with onBookingSaving() and onBookingSaved() — useful for multi-tenancy, logging, or side effects. → docs/actions.md
Custom resource synchronization
Add the SyncBookableResource trait and implement syncBookableResource() to push data from your model (visibility, capacity, availability) into its BookableResource automatically on save. → docs/synchronization.md
Planning source pattern
Add the SyncBookablePlanning trait so a business model (rate, special offer, seasonal rule) becomes the single source of truth for a resource's availability, with bidirectional navigation between source and planning. → docs/synchronization.md
Related bookings
Link bookings with parent-child relationships (room + parking, appointment + follow-up). Each booking keeps an independent lifecycle, and children survive parent deletion. Requires an optional migration. → docs/related-bookings.md
Planning constraints
Define when a resource can be booked through BookablePlanning records — available weekdays plus starts_at/ends_at windows. → docs/models.md
Events
The booking lifecycle emits events (BookingInProgress, BookingCompleted, BookingFailed, BookingChanging, BookingChanged, BookingChangeFailed) for audit trails and integrations. → docs/events.md
Checking availability
$room->isBookedAt(now()); // bool $room->bookedPeriodsOfDate(today()); // booked periods for a date $room->bookings; // all bookings for the resource
Documentation
| Guide | Description |
|---|---|
| Getting Started | Step-by-step quick start |
| Installation | Installation and optional migrations |
| Configuration | Configurable models and generators |
| Architecture | Package design and structure |
| Models | Model relationships and usage |
| Actions | Core booking operations |
| Synchronization | Resource and planning synchronization |
| Events | Event system and listeners |
| Database Schema | Tables and migrations |
| API Reference | Complete API documentation |
| Migration Guide | Upgrading between versions |
| Extending | Customization and extension points |
| Troubleshooting | Common issues and solutions |
Examples
Testing
composer test # run the test suite composer test-coverage # run with coverage composer analyse # run static analysis (PHPStan)
See docs/testing.md for testing strategies.
Contributing & Credits
- Please see CONTRIBUTING for contribution guidelines.
- Please see CHANGELOG for recent changes.
- Report security vulnerabilities via our security policy.
Created and maintained by Luca Longo and all contributors.
License
The MIT License (MIT). See the License File for details.