PHPackages                             masterix21/laravel-bookings - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. masterix21/laravel-bookings

ActiveLibrary

masterix21/laravel-bookings
===========================

Add bookings ability to any Eloquent model

1.2.2(6mo ago)3561MITPHPPHP ^8.4CI failing

Since Nov 11Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/masterix21/laravel-bookings)[ Packagist](https://packagist.org/packages/masterix21/laravel-bookings)[ Docs](https://github.com/masterix21/laravel-bookings)[ GitHub Sponsors](https://github.com/lucalongo)[ RSS](/packages/masterix21-laravel-bookings/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (19)Versions (9)Used By (0)

Laravel Bookings
================

[](#laravel-bookings)

[![Latest Version on Packagist](https://camo.githubusercontent.com/155d9734b231e4c2dc10750f32dcab37bcf873034fc42f807559d83983cc166d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6173746572697832312f6c61726176656c2d626f6f6b696e67732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/masterix21/laravel-bookings)[![GitHub Actions Workflow Status](https://camo.githubusercontent.com/4db1d83c836b539b55a4f1b14cfb245e2780548ba92cdbc02b1dbd3f2a9f2943/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6173746572697832312f6c61726176656c2d626f6f6b696e67732f72756e2d74657374732e796d6c)](https://img.shields.io/github/actions/workflow/status/masterix21/laravel-bookings/run-tests.yml)[![Total Downloads](https://camo.githubusercontent.com/eeaf20f95db863993c23804c708c2eb518b93bf92db96318836944a9a7d64d6f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6173746572697832312f6c61726176656c2d626f6f6b696e67732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/masterix21/laravel-bookings)

A comprehensive Laravel package that adds powerful booking functionality to any Eloquent model. Transform your models into bookable resources with advanced features like time-based reservations, capacity management, planning constraints, overlap detection, and event-driven architecture.

Features
--------

[](#features)

- 🚀 **Make any Eloquent model bookable** with simple traits
- 📅 **Advanced time period management** using Spatie Period library
- 🏢 **Resource capacity control** with configurable limits
- 📋 **Planning constraints** with weekday and time 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 (v1.2.0+)
- 🧪 **Well tested** with comprehensive test suite
- ⚡ **Performance optimized** with efficient database queries
- 🛡️ **Transaction safety** with automatic rollback on failures
- 🔄 **Automatic synchronization** with model events
- 🔗 **Planning source pattern** for business logic separation

Installation
------------

[](#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"
```

Quick Start
-----------

[](#quick-start)

### 1. Make a Model Bookable

[](#1-make-a-model-bookable)

Add the `IsBookable` trait to any model you want to make bookable:

```
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. Create a Bookable Resource

[](#2-create-a-bookable-resource)

```
use Masterix21\Bookings\Models\BookableResource;

// Create a bookable resource for your room
$room = Room::create(['name' => 'Deluxe Suite', 'capacity' => 4]);

$bookableResource = BookableResource::create([
    'resource_type' => Room::class,
    'resource_id' => $room->id,
    'max' => 1, // Maximum concurrent bookings
    'size' => 4, // Resource capacity
    'is_bookable' => true,
    'is_visible' => true,
]);
```

### 3. Make a Booking

[](#3-make-a-booking)

```
use Masterix21\Bookings\Actions\BookResource;
use Spatie\Period\Period;
use Spatie\Period\PeriodCollection;

// Create booking periods
$periods = PeriodCollection::make([
    Period::make('2024-12-25', '2024-12-27'), // 2 nights
]);

// Book the resource
$booking = (new BookResource())->run(
    periods: $periods,
    bookableResource: $bookableResource,
    booker: auth()->user(), // The user making the booking
    label: 'Christmas Holiday',
    note: 'Special dietary requirements',
    meta: ['guests' => 2, 'payment_method' => 'credit_card']
);
```

### 4. Hook into the Booking Lifecycle (Optional)

[](#4-hook-into-the-booking-lifecycle-optional)

Add custom logic before or after booking is saved:

```
use Masterix21\Bookings\Actions\BookResource;
use Masterix21\Bookings\Models\Booking;

$booking = (new BookResource())
    ->onBookingSaving(function (Booking $booking) {
        // Executed before $booking->save()
        $booking->tenant_id = auth()->user()->tenant_id;
    })
    ->onBookingSaved(function (Booking $booking) {
        // Executed after $booking->save()
        Log::info("Booking {$booking->code} created");
    })
    ->run(
        periods: $periods,
        bookableResource: $bookableResource,
        booker: auth()->user(),
    );
```

*For complete documentation, see [docs/actions.md](docs/actions.md#booking-lifecycle-callbacks)*

Core Concepts
-------------

[](#core-concepts)

### BookableResource

[](#bookableresource)

The central entity that represents a bookable item. It's linked to your actual model (Room, Car, etc.) via polymorphic relationships.

### Booking

[](#booking)

Represents a reservation with metadata, booker information, and associated time periods.

### BookedPeriod

[](#bookedperiod)

Individual time slots within a booking, supporting complex multi-period reservations.

### BookablePlanning

[](#bookableplanning)

Defines availability rules, working hours, and constraints for resources.

Advanced Features
-----------------

[](#advanced-features)

### Custom Resource Synchronization

[](#custom-resource-synchronization)

Automatically sync data from your models to bookable resources:

```
use Masterix21\Bookings\Models\BookableResource;
use Masterix21\Bookings\Models\Concerns\Bookable;
use Masterix21\Bookings\Models\Concerns\IsBookable;
use Masterix21\Bookings\Models\Concerns\SyncBookableResource;

class Room extends Model implements Bookable
{
    use IsBookable;
    use SyncBookableResource;

    /**
     * Called automatically when the room is saved
     */
    public function syncBookableResource(BookableResource $resource): void
    {
        $resource->update([
            'is_visible' => $this->is_published,
            'is_bookable' => $this->is_available && $this->is_clean,
            'max' => $this->max_concurrent_bookings,
            'size' => $this->capacity,
        ]);
    }
}
```

**Key Features:**

- Opt-in with `SyncBookableResource` trait
- Automatically called on model save
- Handles both single resource (`bookableResource`) and multiple resources (`bookableResources`)
- N+1 query optimized

*For complete documentation, see [docs/synchronization.md](docs/synchronization.md)*

### Related Bookings (v1.2.0+)

[](#related-bookings-v120)

Link bookings together using parent-child relationships:

```
use Masterix21\Bookings\Actions\BookResource;

// Create a parent booking
$roomBooking = (new BookResource())->run(
    periods: PeriodCollection::make([Period::make('2024-12-25', '2024-12-27')]),
    bookableResource: $room,
    booker: $user,
    label: 'Hotel Room'
);

// Create related child bookings
$parkingBooking = (new BookResource())->run(
    periods: PeriodCollection::make([Period::make('2024-12-25', '2024-12-27')]),
    bookableResource: $parkingSpot,
    booker: $user,
    parent: $roomBooking,
    label: 'Parking Spot'
);

$spaBooking = (new BookResource())->run(
    periods: PeriodCollection::make([Period::make('2024-12-26 14:00', '2024-12-26 15:30')]),
    bookableResource: $spaRoom,
    booker: $user,
    parent: $roomBooking,
    label: 'Spa Treatment'
);

// Access relationships
$children = $roomBooking->childBookings; // Collection of related bookings
$parent = $parkingBooking->parentBooking; // Parent booking instance
```

**Benefits:**

- Link related bookings together (room + parking, appointment + follow-up, etc.)
- Maintain independent booking lifecycle for each resource
- Children survive parent deletion (`nullOnDelete()` behavior)
- Query and filter by relationships

**Migration Required:**This is an opt-in feature requiring an optional migration:

```
php artisan vendor:publish --tag="bookings-migrations"
# Then run: update_bookings_add_parent_booking_id.php
php artisan migrate
```

*For complete documentation, see [docs/related-bookings.md](docs/related-bookings.md)*

### Planning Source Pattern

[](#planning-source-pattern)

Link business models (rates, special offers) directly to planning:

```
use Masterix21\Bookings\Models\Concerns\BookablePlanningSource;
use Masterix21\Bookings\Models\Concerns\IsBookablePlanningSource;
use Masterix21\Bookings\Models\Concerns\SyncBookablePlanning;

class Rate extends Model implements BookablePlanningSource
{
    use IsBookablePlanningSource;
    use SyncBookablePlanning;

    /**
     * Called automatically when the rate is saved
     */
    public function syncBookablePlanning(): void
    {
        $this->planning()->updateOrCreate(
            ['bookable_resource_id' => $this->room->bookableResource->id],
            [
                'starts_at' => $this->valid_from,
                'ends_at' => $this->valid_to,
                'monday' => true,
                'tuesday' => true,
                'wednesday' => true,
                'thursday' => true,
                'friday' => true,
                'saturday' => $this->includes_weekend,
                'sunday' => $this->includes_weekend,
            ]
        );
    }
}
```

**Benefits:**

- Opt-in with `SyncBookablePlanning` trait
- Single source of truth: your business model controls availability
- Automatic synchronization on save
- Bidirectional navigation: `$rate->planning` and `$planning->source`
- Planning auto-deleted when source is deleted

**Migration Required:**If you're upgrading from an older version, run this additional migration:

```
php artisan vendor:publish --tag="bookings-migrations"
# Then manually run: update_bookable_plannings_add_source_columns.php
php artisan migrate
```

*For complete documentation, see [docs/synchronization.md](docs/synchronization.md)*

### Planning Constraints

[](#planning-constraints)

Define when resources are available:

```
use Masterix21\Bookings\Models\BookablePlanning;

BookablePlanning::create([
    'bookable_resource_id' => $bookableResource->id,
    'monday' => true,
    'tuesday' => true,
    'wednesday' => true,
    'thursday' => true,
    'friday' => true,
    'saturday' => false, // Closed on weekends
    'sunday' => false,
    'starts_at' => '2024-01-01 09:00:00', // Available from 9 AM
    'ends_at' => '2024-12-31 18:00:00',   // Until 6 PM
]);
```

### Event System

[](#event-system)

Listen to booking lifecycle events:

```
use Masterix21\Bookings\Events\BookingCompleted;
use Masterix21\Bookings\Events\BookingFailed;

// In your EventServiceProvider
protected $listen = [
    BookingCompleted::class => [
        SendBookingConfirmationEmail::class,
        UpdateInventory::class,
    ],
    BookingFailed::class => [
        LogBookingFailure::class,
        NotifyAdministrators::class,
    ],
];
```

### Checking Availability

[](#checking-availability)

```
// Check if a resource is booked at a specific time
$isBooked = $room->isBookedAt(now());

// Get booked periods for a specific date
$bookedPeriods = $room->bookedPeriodsOfDate(today());

// Get all bookings for a resource
$bookings = $room->bookings;
```

### Overlap Detection

[](#overlap-detection)

The package automatically prevents overlapping bookings:

```
use Masterix21\Bookings\Exceptions\BookingResourceOverlappingException;

try {
    $booking = (new BookResource())->run(/* ... */);
} catch (BookingResourceOverlappingException $e) {
    // Handle booking conflict
    return response()->json(['error' => 'Time slot already booked'], 409);
}
```

Complete Examples
-----------------

[](#complete-examples)

For comprehensive implementation examples, see:

- 📨 [Hotel Booking System](docs/examples/hotel-booking.md) - Complete hotel reservation system
- 🚗 [Car Rental System](docs/examples/car-rental.md) - Vehicle rental management
- 🍽️ [Restaurant Reservations](docs/examples/restaurant-reservations.md) - Table booking system
- 📅 [Service Appointments](docs/examples/service-appointments.md) - Appointment scheduling

Documentation
-------------

[](#documentation)

For detailed documentation, see:

- ⚙️ [Configuration](docs/configuration.md) - Package configuration options
- 🏗️ [Database Schema](docs/database-schema.md) - Database structure and migrations
- 📖 [API Reference](docs/api-reference.md) - Complete API documentation

### Key Topics

[](#key-topics)

- 🏛️ [Architecture](docs/architecture.md) - Package design and structure
- 🚀 [Getting Started](docs/getting-started.md) - Quick start guide
- 📊 [Models](docs/models.md) - Model relationships and usage
- ⚡ [Actions](docs/actions.md) - Core booking operations
- 🔄 [Synchronization](docs/synchronization.md) - Resource and planning synchronization
- 🎯 [Events](docs/events.md) - Event system and listeners
- 🧪 [Testing](docs/testing.md) - Testing strategies and examples
- 🔧 [Extending](docs/extending.md) - Customization and extensions
- 🚨 [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions

Legacy Quick Reference
----------------------

[](#legacy-quick-reference)

*For complete API documentation, see [docs/api-reference.md](docs/api-reference.md)*

The package provides the following core traits and actions:

- `IsBookable` trait - Makes any model bookable
- `HasBookings` trait - For entities that can make bookings
- `BookResource` action - Creates and updates bookings
- `CheckBookingOverlaps` action - Validates booking conflicts

Events are automatically fired during the booking lifecycle for audit trails and integrations.

Testing
-------

[](#testing)

Run the package tests:

```
composer test
```

Run tests with coverage:

```
composer test-coverage
```

Run static analysis:

```
composer analyse
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Luca Longo](https://github.com/masterix21)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance66

Regular maintenance activity

Popularity16

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 91.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~49 days

Recently: every ~3 days

Total

8

Last Release

202d ago

Major Versions

0.0.2 → 1.0.02025-07-28

PHP version history (3 changes)0.0.1PHP ^8.3

0.0.2PHP ^8.3|^8.4

1.1.1PHP ^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/177020fc4adb5c08acee3e6fe0b65002a96665c5d5c522a3ef009b4105fd634f?d=identicon)[masterix](/maintainers/masterix)

---

Top Contributors

[![masterix21](https://avatars.githubusercontent.com/u/6555012?v=4)](https://github.com/masterix21 "masterix21 (175 commits)")[![mikugrunge](https://avatars.githubusercontent.com/u/44170111?v=4)](https://github.com/mikugrunge "mikugrunge (17 commits)")

---

Tags

LucaLongolaravel-bookings

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/masterix21-laravel-bookings/health.svg)

```
[![Health](https://phpackages.com/badges/masterix21-laravel-bookings/health.svg)](https://phpackages.com/packages/masterix21-laravel-bookings)
```

###  Alternatives

[spatie/laravel-honeypot

Preventing spam submitted through forms

1.6k6.0M60](/packages/spatie-laravel-honeypot)[filament/support

Core helper methods and foundation code for all Filament packages.

2323.9M151](/packages/filament-support)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[sunchayn/nimbus

A Laravel package providing an in-browser API client with automatic schema generation, live validation, and built-in authentication with a touch of Laravel-tailored magic for effortless API testing.

29428.0k](/packages/sunchayn-nimbus)[jerome/filterable

Streamline dynamic Eloquent query filtering with seamless API request integration and advanced caching strategies.

19226.1k](/packages/jerome-filterable)[codebar-ag/laravel-flysystem-cloudinary

Cloudinary Flysystem v1 integration with Laravel

1224.9k2](/packages/codebar-ag-laravel-flysystem-cloudinary)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
