{"id":28795501,"url":"https://github.com/cheesytech/booking","last_synced_at":"2026-03-15T04:41:05.860Z","repository":{"id":299588449,"uuid":"1001130640","full_name":"CheesyTech/booking","owner":"CheesyTech","description":"Simple and powerfull booking with Laravel","archived":false,"fork":false,"pushed_at":"2025-07-14T08:20:31.000Z","size":42,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-14T11:28:19.655Z","etag":null,"topics":["booking","laravel","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CheesyTech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-12T21:50:07.000Z","updated_at":"2025-07-14T08:20:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"89d73c78-332f-401e-8e4b-44d5b23ae219","html_url":"https://github.com/CheesyTech/booking","commit_stats":null,"previous_names":["cheesytech/booking"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/CheesyTech/booking","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheesyTech%2Fbooking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheesyTech%2Fbooking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheesyTech%2Fbooking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheesyTech%2Fbooking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CheesyTech","download_url":"https://codeload.github.com/CheesyTech/booking/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheesyTech%2Fbooking/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267685049,"owners_count":24127704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["booking","laravel","php"],"created_at":"2025-06-18T03:09:02.644Z","updated_at":"2026-03-15T04:41:05.785Z","avatar_url":"https://github.com/CheesyTech.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Booking\n\nA flexible and powerful booking system for Laravel applications that supports polymorphic relationships, time slot management, and advanced status tracking.\n\n## Features\n\n- 🕒 Time slot management with overlap prevention\n- 🔄 Polymorphic relationships for bookable and bookerable resources\n- ⚙️ Configurable validation and overlap rules\n- 🎯 Custom booking rules via OverlapRule interface\n- 📅 Business hours and custom rules validation\n- 🔒 Booking duration and minimum interval limits\n- 🎨 Easy to extend with traits and interfaces\n- 📊 Status tracking with full history and metadata\n- 🔄 Event-driven architecture (BookingCreated, BookingUpdated, etc.)\n- 🧪 Comprehensive testing support and model factories\n- 🔍 Advanced querying and duration-based scopes (cross-DB)\n- 💾 Multi-database support (MySQL, PostgreSQL, SQLite, SQL Server)\n- ⏱️ Flexible duration calculations (minutes, hours, days)\n- 🛠️ Publishable config and migration files\n\n## Requirements\n\n- PHP 8.1 or higher\n- Laravel 10.0, 11.0, or 12.0\n- Carbon 2.0 or higher\n\n## Installation\n\n1. Install the package via composer:\n\n```bash\ncomposer require cheesytech/booking\n```\n\n2. The package will automatically register its service provider.\n\n3. Publish and run the migrations:\n\n```bash\nphp artisan vendor:publish --provider=\"CheeasyTech\\Booking\\BookingServiceProvider\" --tag=\"migrations\"\nphp artisan migrate\n```\n\n4. Publish the configuration file:\n\n```bash\nphp artisan vendor:publish --provider=\"CheeasyTech\\Booking\\BookingServiceProvider\" --tag=\"config\"\n```\n\nOr use the install command for all at once:\n\n```bash\nphp artisan package:install cheesytech/booking\n```\n\nThis will create a `config/booking.php` file in your config directory.\n\n## Configuration\n\nThe package is highly configurable through the `config/booking.php` file. Example:\n\n```php\nreturn [\n    'statuses' =\u003e [\n        'pending' =\u003e [\n            'label' =\u003e 'Pending',\n            'color' =\u003e '#FFA500',\n            'can_transition_to' =\u003e ['confirmed', 'cancelled'],\n        ],\n        'confirmed' =\u003e [\n            'label' =\u003e 'Confirmed',\n            'color' =\u003e '#008000',\n            'can_transition_to' =\u003e ['cancelled', 'completed'],\n        ],\n        'cancelled' =\u003e [\n            'label' =\u003e 'Cancelled',\n            'color' =\u003e '#FF0000',\n            'can_transition_to' =\u003e [],\n        ],\n        'completed' =\u003e [\n            'label' =\u003e 'Completed',\n            'color' =\u003e '#0000FF',\n            'can_transition_to' =\u003e [],\n        ],\n    ],\n    'overlap' =\u003e [\n        'enabled' =\u003e true,\n        'allow_same_booker' =\u003e false,\n        'min_time_between' =\u003e 0,\n        'max_duration' =\u003e 0,\n        'rules' =\u003e [\n            'business_hours' =\u003e [\n                'enabled' =\u003e false,\n                'class' =\u003e \\CheeasyTech\\Booking\\Rules\\BusinessHoursRule::class,\n            ],\n        ],\n    ],\n    'events' =\u003e [\n        'enabled' =\u003e true,\n        'classes' =\u003e [\n            'created' =\u003e \\CheeasyTech\\Booking\\Events\\BookingCreated::class,\n            'updated' =\u003e \\CheeasyTech\\Booking\\Events\\BookingUpdated::class,\n            'deleted' =\u003e \\CheeasyTech\\Booking\\Events\\BookingDeleted::class,\n            'status_changed' =\u003e \\CheeasyTech\\Booking\\Events\\BookingStatusChanged::class,\n        ],\n    ],\n];\n```\n\n## Model Setup\n\nImplement the provided interfaces and use the traits for your models:\n\n```php\nuse CheeasyTech\\Booking\\Contracts\\Bookable;\nuse CheeasyTech\\Booking\\Traits\\HasBookings;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Room extends Model implements Bookable {\n    use HasBookings;\n    // ...\n    public function getBookableId(): int { return $this-\u003eid; }\n    public function getBookableType(): string { return static::class; }\n}\n\nuse CheeasyTech\\Booking\\Contracts\\Bookerable;\nuse CheeasyTech\\Booking\\Traits\\HasBookers;\n\nclass User extends Model implements Bookerable {\n    use HasBookers;\n    // ...\n    public function getBookerableId(): int|string { return $this-\u003eid; }\n    public function getBookerableType(): string { return static::class; }\n}\n```\n\n## Quick Start\n\n```php\nuse CheeasyTech\\Booking\\Models\\Booking;\nuse Carbon\\Carbon;\n\n$room = Room::find(1);\n$user = User::find(1);\n\n$booking = new Booking();\n$booking-\u003ebookable()-\u003eassociate($room);\n$booking-\u003ebookerable()-\u003eassociate($user);\n$booking-\u003estart_time = Carbon::tomorrow()-\u003esetHour(10);\n$booking-\u003eend_time = Carbon::tomorrow()-\u003esetHour(11);\n$booking-\u003estatus = 'pending';\n$booking-\u003esave();\n\n// Change booking status\n$booking-\u003echangeStatus('confirmed', 'Approved by admin', ['key' =\u003e 'value']);\n\n// Check for overlap\n$isAvailable = !$booking-\u003ehasOverlap(\n    Carbon::tomorrow()-\u003esetHour(10),\n    Carbon::tomorrow()-\u003esetHour(11)\n);\n```\n\n## Traits \u0026 Interfaces\n\n- **HasBookings**: Add to bookable models (e.g., Room) for convenient booking management (`newBooking`, `deleteBooking`, etc.).\n- **HasBookers**: Add to bookerable models (e.g., User) for managing bookings made by the entity.\n- **Bookable**: Interface for resources to be booked (must implement `getBookableId`, `getBookableType`).\n- **Bookerable**: Interface for entities making bookings (must implement `getBookerableId`, `getBookerableType`).\n- **OverlapRule**: Interface for custom overlap validation rules.\n\n## Database Schema\n\nThe package creates the following database table:\n\n```php\nSchema::create('bookings', function (Blueprint $table) {\n    $table-\u003eid();\n    $table-\u003emorphs('bookable');\n    $table-\u003emorphs('bookerable');\n    $table-\u003edateTime('start_time');\n    $table-\u003edateTime('end_time');\n    $table-\u003estring('status')-\u003edefault('pending');\n    $table-\u003ejson('status_history')-\u003enullable();\n    $table-\u003etimestamp('status_changed_at')-\u003enullable();\n    $table-\u003etimestamps();\n});\n```\n\n## Advanced Usage\n\n### Query Scopes\n\n```php\n// Get bookings longer than 2 hours\nBooking::durationLongerThan(120)-\u003eget();\n// Get bookings between 1 and 2 hours\nBooking::durationBetween(60, 120)-\u003eget();\n// Combine with other conditions\nBooking::durationLongerThan(120)-\u003ewhere('status', 'confirmed')-\u003eget();\n```\n\n### Status Management\n\n```php\n$booking-\u003echangeStatus('confirmed', 'Approved by supervisor', ['approver_id' =\u003e 123]);\n$status = $booking-\u003egetCurrentStatus();\n$history = $booking-\u003egetStatusHistory();\nif ($booking-\u003ehasStatus('confirmed')) { /* ... */ }\n```\n\n### Overlap \u0026 Custom Rules\n\n- Prevents overlapping bookings by default.\n- Supports minimum interval and max duration.\n- Add custom rules by implementing `OverlapRule` and registering in config.\n- Example: BusinessHoursRule restricts bookings to business hours.\n\n### Events\n\nEvents are fired for all major actions:\n- BookingCreated\n- BookingUpdated\n- BookingDeleted\n- BookingStatusChanged\n\n### Testing \u0026 Factories\n\nUse provided factories for testing:\n\n```php\n$booking = Booking::factory()-\u003epending()-\u003ecreate();\n$room = Room::factory()-\u003ecreate();\n$user = User::factory()-\u003ecreate();\n```\n\n## Updating PHPDoc\n\nTo update PHPDoc for models, run:\n\n```bash\n./update-phpdoc.sh\n```\n\n## Contributing\n\nThank you for considering contributing to the Laravel Booking package! Please feel free to submit pull requests or create issues for bugs and feature requests.\n\n## License\n\nThe Laravel Booking package is open-sourced software licensed under the [MIT license](LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheesytech%2Fbooking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcheesytech%2Fbooking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheesytech%2Fbooking/lists"}