PHPackages                             shirokovnv/innkeeper - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. shirokovnv/innkeeper

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

shirokovnv/innkeeper
====================

The library for your next Laravel booking app

2.0.0(2y ago)116[2 PRs](https://github.com/shirokovnv/innkeeper/pulls)MITPHPPHP &gt;=8.0CI passing

Since Aug 17Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/shirokovnv/innkeeper)[ Packagist](https://packagist.org/packages/shirokovnv/innkeeper)[ Docs](https://github.com/shirokovnv/innkeeper)[ RSS](/packages/shirokovnv-innkeeper/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (6)Versions (5)Used By (0)

Innkeeper
=========

[](#innkeeper)

[![ci.yml](https://github.com/shirokovnv/innkeeper/actions/workflows/ci.yml/badge.svg)](https://github.com/shirokovnv/innkeeper/actions/workflows/ci.yml/badge.svg)[![Latest Version on Packagist](https://camo.githubusercontent.com/db37821b6f66963f6407cc43a1a79264a9b7697f7552d380969715cd4e85bce7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736869726f6b6f766e762f696e6e6b65657065722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/shirokovnv/innkeeper)[![Total Downloads](https://camo.githubusercontent.com/59779d4baa78dde0e379100807273a158deceb9bfe6498a2d33b89b99e37cdde/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736869726f6b6f766e762f696e6e6b65657065722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/shirokovnv/innkeeper)

The library for your next [Laravel](https://laravel.com/) booking app.

**Supported Laravel versions: `>=9.x`**

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

[](#installation)

1. Install package via composer

```
$ composer require shirokovnv/innkeeper
```

2. Run migrations

```
$ php artisan migrate
```

3. Done!

Usage
-----

[](#usage)

### Add bookable functionality to your eloquent model

[](#add-bookable-functionality-to-your-eloquent-model)

```
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Shirokovnv\Innkeeper\Contracts\Bookable;
use Shirokovnv\Innkeeper\Traits\HasBooking;

class Room extends Model implements Bookable {
    use HasBooking;
}
```

That's basically it. Now your rooms can be booked.

### Checking opportunity for the booking:

[](#checking-opportunity-for-the-booking)

The `Innkeeper` service provides functionality to check wether its possible to book something in a date range:

```
use \Shirokovnv\Innkeeper\Contracts\Innkeepable;

$room = \App\Models\Room::find(1);

$innkeeper = app()->make(Innkeepable::class);

// Has bookings in a date range ?
$has_bookings = $innkeeper->exists(
    $room,
    new DateTime('2022-08-01 15:00'),
    new DateTime('2022-08-07 12:00')
);
```

### Create a new booking

[](#create-a-new-booking)

Creating a new booking is straight forward and could be done the following way:

```
use \Shirokovnv\Innkeeper\Contracts\Innkeepable;

$room = \App\Models\Room::find(1);

$innkeeper = app()->make(Innkeepable::class);
$booking_hash = generateBookingHash();

$innkeeper->book(
    $room,
    $booking_hash,
    new DateTime('2022-08-01 15:00'),
    new DateTime('2022-08-07 12:00')
);
```

Or if you like facades, you can do it like this:

```
use Shirokovnv\Innkeeper\Facades\Innkeeper;

Innkeeper::book(
    $room,
    $booking_hash,
    new DateTime('2022-08-01 15:00'),
    new DateTime('2022-08-07 12:00')
);
```

> **Notes:**
>
> Why we need `booking_hash` and what is it ?
>
> - The hash is a field in a database with a unique constraint
> - It serves purpose to prevent some duplicate bookings without explicitly locking tables

Let me show you and example:

Suppose, you have a few visitors on your booking site. And all the visitors asks for booking the same room at a time.

In this particular case, you probably need to assign the room to the first customer and notify others the room already booked.

You can do it by these simple steps:

1. Define hash function

```
function generateBookingHash(int $room_id, string $started_at, string $ended_at) {
    return $room_id . $started_at . $ended_at;
}
```

2. In your business logic code

```
use Illuminate\Database\QueryException;

$room = \App\Models\Room::find(1);
$booking_hash = generateBookingHash($room->id, $started_at, $ended_at);

try {
    $innkeeper->book($room, $booking_hash, $started_at, $ended_at);
} catch (QueryException $exception) {
    // Catch SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: bookings.hash
    // show user popup with apologies or
    // redirect to another free room or ...
}
```

This example covers only the case, when you have deterministic booking schedule without intersections. Like this:

- 09:00 - 10:00
- 10:00 - 11:00
- 11:00 - 12:00
- ...

If you have some intersections, like:

- 09:00 - 10:00
- 09:30 - 10:30

you may still have a problem with duplicates.

Of course, you can check the availability of the room:

```
$can_be_booked = ! $innkeeper->exists($room, $started_at, $ended_at);
if ($can_be_booked) {
    $innkeeper->book($room, $booking_hash, $started_at, $ended_at);
} else {
    // show user an error message
}
```

But it doesn't guarantee resolving concurrent requests for your schedule.

So, please, let me know what can be a solution if it is your case.

### Query bookings

[](#query-bookings)

```
use \Shirokovnv\Innkeeper\Contracts\Innkeepable;

$room = \App\Models\Room::find(1);

$innkeeper = app()->make(Innkeepable::class);

// All the bookings for the room
$bookings = $innkeeper->all($room);

// All the bookings for the room in a range.
$bookings = $innkeeper->allInRange($room, $started_at, $ended_at);

// The first started booking
$first_booking = $innkeeper->first($room);

// The last ended booking
$last_booking = $innkeeper->last($room);
```

### Delete bookings

[](#delete-bookings)

```
$room = \App\Models\Room::find(1);

$booking_hash = 'some hash';

// Delete by predefined hash
$innkeeper->deleteByHash($room, $booking_hash);

$started_at = new DateTime('2022-08-01 09:00');
$ended_at = new DateTime('2022-08-02 09:00');

// Delete by specific date range.
$innkeeper->deleteByRange($room, $started_at, $ended_at);
```

Change log
----------

[](#change-log)

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

Testing
-------

[](#testing)

```
$ composer test
```

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

[](#contributing)

Please see [contributing.md](contributing.md) for details and a todolist.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Shirokov Nickolai](https://github.com/shirokovnv)
- [All Contributors](../../contributors)

License
-------

[](#license)

MIT. Please see the [license file](license.md) for more information.

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance50

Moderate activity, may be stable

Popularity7

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 90% 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 ~384 days

Total

2

Last Release

977d ago

Major Versions

1.0.0 → 2.0.02023-09-06

PHP version history (2 changes)1.0.0PHP ^7.4 || ^8.0

2.0.0PHP &gt;=8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/5b6eee3a1104304577fab48df60136b13f5207972c2b644f1030c92ee28d9891?d=identicon)[shirokovnv](/maintainers/shirokovnv)

---

Top Contributors

[![shirokovnv](https://avatars.githubusercontent.com/u/43547352?v=4)](https://github.com/shirokovnv "shirokovnv (45 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")

---

Tags

bookinglaravelphplaravelbookingInnkeeper

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/shirokovnv-innkeeper/health.svg)

```
[![Health](https://phpackages.com/badges/shirokovnv-innkeeper/health.svg)](https://phpackages.com/packages/shirokovnv-innkeeper)
```

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M686](/packages/barryvdh-laravel-ide-helper)[laracraft-tech/laravel-useful-additions

A collection of useful Laravel additions!

58109.4k](/packages/laracraft-tech-laravel-useful-additions)[glhd/special

1929.4k](/packages/glhd-special)[bjuppa/laravel-blog

Add blog functionality to your Laravel project

483.3k2](/packages/bjuppa-laravel-blog)

PHPackages © 2026

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