Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Zap Laravel Package

laraveljutsu/zap

Zap adds flexible calendar scheduling to Laravel: manage resource availabilities, appointments, blocked times, and custom schedules (doctors, rooms, staff). Includes patterns plus querying/availability checks for booking, shifts, and shared spaces.

View on GitHub
Deep Wiki
Context7
v1.15.0

Highlights

  • isBookableAtTime and slot length
    You can now pass a custom slot duration so availability checks match your actual step size (not just the default). (#69)

Fixes

  • Timezone + week boundaries
    Timezone is now normalized before startOfWeek-style logic, ensuring consistent week calculations. (#68)

Other

  • Internals
    Fully qualified class names have been replaced with imports where relevant (no API changes).

Upgrade

Composer:

"laraveljutsu/zap": "^1.15"

v1.14.0

Laravel 13.x Compatibility

v1.13.0

Monthly ordinal weekday recurrence

Recurring schedules can now use “which weekday of the month” (1st, 2nd, 3rd, 4th, or last) instead of only fixed days of the month.

New API

  • firstWednesdayOfMonth() – every 1st Wednesday
  • secondFridayOfMonth() – every 2nd Friday
  • lastMondayOfMonth() – every last Monday
  • Same pattern for any weekday: first{Sunday|Monday|...|Saturday}OfMonth(), second..., third..., fourth..., last...

Example

Zap::for($room) ->named('Monthly Standup') ->firstWednesdayOfMonth() ->forYear(2025) ->addPeriod('09:00', '10:00') ->save();

Other changes

  • README: Table of contents, clearer recurrence table, query/availability table, and general cleanup.
  • Boost skills: zap-recurrence and zap-schedules updated with ordinal weekday docs.

Upgrade

No breaking changes. Safe to upgrade from v1.12.x

v1.12.0

What's New

Dynamic recurrence: every X weeks and every X months

Recurring schedules can now use custom week and month intervals beyond the built-in weekly, biweekly, monthly, quarterly, and annual patterns.

Every X weeks (3–52):

  • New methods: everyThreeWeeks(), everyFourWeeks(), everyFiveWeeks(), … through everyFiftyTwoWeeks().
  • Signature: everyXWeeks(array $days, CarbonInterface|string|null $startsOn = null).
  • Optional startsOn anchor date to fix the first occurrence week.
Zap::for($resource)
    ->named('Tri-Weekly Sync')
    ->everyThreeWeeks(['monday', 'friday'])
    ->from('2025-01-06')
    ->to('2025-12-31')
    ->addPeriod('10:00', '11:00')
    ->save();

Every X months (4, 5, 7–11):

  • New methods: everyFourMonths(), everyFiveMonths(), everySevenMonths(), everyEightMonths(), everyNineMonths(), everyTenMonths(), everyElevenMonths().
  • Config: day_of_month or days_of_month, optional start_month anchor.
Zap::for($resource)
    ->named('Quadrimester Review')
    ->everyFourMonths(['day_of_month' => 15])
    ->forYear(2025)
    ->addPeriod('09:00', '12:00')
    ->save();

Bug fix: forDate() scope and non-recurring schedules with NULL end_date

  • The forDate() scope on the Schedule model now correctly includes non-recurring schedules when end_date is NULL (open-ended single-day or ongoing schedules).
  • Previously, the date-range condition could exclude those schedules; they are now included when the given date is on or after start_date.

Changes

  • Added: ext-intl PHP extension as a requirement (used for recurrence calculations).
  • Refactor: Recurrence configs reorganized into WeeklyFrequencyConfig\ and MonthlyFrequencyConfig\ namespaces with shared abstract classes for weekly and monthly frequencies.
  • Docs: README and recurrence skill updated with dynamic everyXWeeks and everyXMonths examples.

Upgrade

  1. Ensure the ext-intl PHP extension is installed: php -m | grep intl.
  2. Run composer update laraveljutsu/zap to pull 1.12.0.
  3. No breaking API changes; existing weekly(), biweekly(), monthly(), etc. behave as before.

Contributors

Thanks to seebaermichi and Sagmedjo for their pull requests in this release.


Documentation · GitHub

v1.11.0

Release v1.11.0

🎉 Features

Eloquent Builders

  • Add Eloquent builders for Schedule and SchedulePeriod models (PR #58)
    • Enhanced query building capabilities for Schedule and SchedulePeriod models
    • Improved type safety and IDE support

Migration Publishing

  • Add publish migrations command with group tag (PR #59)
    • Easier migration publishing with php artisan vendor:publish --tag=zap-migrations
    • Better organization of published migrations

🐛 Fixes

  • Fix PHPStan errors in HasSchedules trait
    • Added proper type hints for Schedule collection types
    • PHPStan level 5 now passes without errors
  • Fix date condition logic in Schedule model
  • Fix scopeForDateRange to handle null end_date properly

✅ Quality Assurance

  • All tests pass
  • PHPStan level 5 passes without errors
  • Code follows Laravel conventions

Full Changelog: https://github.com/ludoguenet/laravel-zap/compare/v1.10.0...v1.11.0

v1.10.0

Release v1.10.0

🎉 New Features

isBookableAtTime() Method

Added a new method to check if a specific time range is bookable for a given date:

$isBookable = $doctor->isBookableAtTime('2025-01-15', '9:00', '9:30');

This method checks two conditions:

  1. The time range must not be blocked by any active schedules
  2. The requested time range must fit entirely inside one of the model's bookable slots

Custom Model Support with UUIDs

Full support for custom models using UUIDs, ULIDs, GUIDs, or any other primary key type:

  • Extend Zap\Models\Schedule and Zap\Models\SchedulePeriod in your own namespace
  • Configure custom models in config/zap.php
  • Update migrations to use UUID columns
  • See README for complete documentation

Weekly Odd/Even Scheduling Improvements

Enhanced weekly odd/even scheduling logic with better date handling and comprehensive test coverage.

🐛 Bug Fixes

  • Fixed scopeForDateRange to properly handle null end_date values
  • Fixed custom polymorphic types to use getMorphClass() for proper type resolution
  • Fixed various test improvements and date handling edge cases

📚 Documentation

  • Updated README with clearer installation and migration instructions
  • Added comprehensive documentation for custom model support with UUIDs
  • Improved overall documentation clarity and formatting

🔄 Migration from v1.9.2

No breaking changes. This is a backward-compatible release. Simply update:

composer update laraveljutsu/zap

Full Changelog: https://github.com/ludoguenet/laravel-zap/compare/v1.9.2...v1.10.0

v1.9.0

• Committed the workflow change: "ci: add PHP 8.5 to test matrix" • Created annotated tag: v1.9.0 with message "Release 1.9.0: PHP 8.5 support" • Pushed tag to remote: v1.9.0 is now on GitHub • Pushed commit to main: workflow update is on the main branch

The release tag is live. The CI workflow will test against PHP 8.2, 8.3, 8.4, and 8.5 across SQLite, MySQL, and PostgreSQL. The deprecation warning from Composer's dependencies is harmless and doesn't affect the release.

v1.8.0

Release 1.8.0 Summary

Release 1.8.0 focuses on API clarity, enhanced testing, and comprehensive documentation updates.

🎯 API Improvements & Better Naming

  • Deprecated methods: getAvailableSlots() and getNextAvailableSlot() have been replaced with getBookableSlots() and getNextBookableSlot()
  • The new naming better reflects that slots are "bookable" rather than just "available"
  • Improved API: getBookableSlots() now automatically detects availability periods from schedules, removing the need for manual dayStart and dayEnd parameters
  • Old methods remain functional with deprecation warnings to ensure smooth migration

🧪 Enhanced Testing

  • Added ComprehensiveUseCasesTest.php (1,420+ lines) covering real-world scenarios
  • Added DocumentationExamplesTest.php (816+ lines) ensuring all README examples work correctly
  • Expanded edge case tests in SlotsEdgeCasesTest.php and BufferTimeAvailabilityTest.php
  • Improved test infrastructure with new test models (ZapTestUser, ZapTestRoom) and migrations

📚 Documentation Updates

  • Updated README with clearer examples and improved structure
  • Enhanced documentation files (buffer-time.md, schedule-types.md) with more detailed explanations
  • All code examples verified through automated tests

⚡ Code Quality

  • Optimized query performance in slot generation methods
  • Improved code organization and maintainability
  • Better separation of concerns in schedule management logic

This release maintains backward compatibility while providing a clearer, more intuitive API for finding and booking time slots in Laravel applications.

1.7.0

Release Notes - v1.7.0

🎉 What's New

✨ New Features

forYear() Convenience Method

  • Added a new builder method to easily set date ranges for entire years
  • Automatically sets start_date to January 1st and end_date to December 31st of the specified year
  • Perfect for creating yearly availability schedules or annual schedules
$schedule = Zap::for($user)
    ->named('Annual Availability')
    ->forYear(2025) // Sets start_date to 2025-01-01 and end_date to 2025-12-31
    ->addPeriod('09:00', '17:00')
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    ->save();

🐛 Bug Fixes

Fixed Recurring Schedule Querying

  • Weekly Schedules: Fixed forDate() scope to properly filter weekly schedules by weekday
  • Monthly Schedules: Fixed forDate() scope to properly filter monthly schedules by day of month
  • Resolves issues where recurring schedules weren't being correctly identified for specific dates

Fixed Availability Check After Schedule End

  • Fixed isAvailableAt() incorrectly returning false for time slots after a schedule's end date
  • Added proper date filtering before overlap checks to ensure periods are scoped to the requested date
  • Fixes issue #36

🔧 Improvements

  • Removed yearly frequency support from configuration (use forYear() method instead)
  • Added comprehensive test coverage for recurring schedule queries
  • Updated development dependencies:
    • Pest PHP ^4.0
    • Orchestra Testbench ^10.0

📚 Documentation

  • Updated README with examples of the new forYear() method
  • Enhanced documentation for recurring schedule queries

🧪 Testing

  • Added 252+ lines of comprehensive tests for recurring schedule queries
  • Added tests for the new forYear() builder method
  • Added tests for availability checks with recurring schedules

Full Changelog: v1.6.0...v1.7.0

v1.6.0
v1.5.0

What's new

  • Added $bufferTimeMinutes support to getAvailableSlots()
  • Added new getBookableSlots() method
  • Updated docs and configuration for buffer time
  • Minor bug fixes and improvements

Thanks to @lukacavic, @angelej, and @ThomasDeer for the feedback!

v1.4.0

🚀 Release v1.4.0

Merged Pull Requests

#33 — Improve code quality and fix minor issues

#32 — Enhance test coverage and refactor configuration handling

🔧 Maintenance

Ran composer qa (Laravel Pint + tests)

Updated dependencies via composer update

✅ All checks passed successfully. 🧹 Codebase cleaned and up to date.

v1.3.0

What’s new in v1.3.0

✨ Query optimizations

  • Thanks to @gmlo89 for PR #26 improving getAvailableSlots query performance.

🐘🐬 Cross-database time comparison fixes

  • Thanks to @nick-potts for PR #29 fixing time overlap logic in MySQL and PostgreSQL.
  • CI now runs against SQLite, MySQL, and PostgreSQL to catch future issues early.

🧹 Misc

  • Composer lint / QA improvements.

Big thanks to the community contributors! 💙

v1.2.0

This release is a rebranding / renaming update:

  • Package renamed from laravel-zap → zap-for-laravel
  • Updated README and branding to comply with Laravel trademark
  • Transparent logo added
  • Installation and usage instructions updated
  • Legal disclaimer added

Zap is a calendar and event management tool designed for Laravel applications.

⚖️ Note: This project is independent and not affiliated with Laravel LLC or Taylor Otwell. "Laravel" is used only to indicate compatibility.

v1.1.3

v1.1.3 - Database Compatibility & Bug Fixes

🐛 Bug Fixes

  • Fixed time overlap detection for cross-database compatibility (SQLite/MySQL/PostgreSQL)
  • Resolved time format inconsistency issues ("7:00" vs "07:00")
  • Improved scopeOverlapping method with proper driver detection
  • [PR #24] Fixed detection of overlapping time periods for non-custom schedules (#24) — thanks [@gmlo89](https://github.com/gmlo89) 🎉

🔧 Improvements

  • Enhanced database driver detection using PDO attributes
  • Better time normalization for consistent comparisons
  • Cleaner code structure with extracted database-specific logic

📚 Documentation

  • Updated README with cleaner structure and better examples
  • Added important notices for configuration requirements
v1.1.2
  • buffer bug fixed
  • removed beta banner in README
v1.1.1

🏷️ Tag Details Tag Name: v1.1.1 Type: Annotated tag (includes metadata and message) Message: Describes the documentation improvements and fixes

📋 What's Included in v1.1.1 ✨ Schedule Types Documentation: Comprehensive guide for availability, appointment, blocked, and custom types 🔧 Configuration Fixes: Updated config examples to match actual implementation 📝 Use Case Updates: Enhanced examples using proper schedule types 🧹 Cleanup: Removed non-existent features (like caching) from documentation

v1.1.0

🎉 Great News: We've Implemented Schedule Types!

Based on your questions, we've just released a comprehensive Schedule Types feature that addresses all your concerns:

✅ Your Questions Answered:

Q1: "Is using the metadata field the recommended way to differentiate between schedule types?"

  • Answer: Not anymore! We now have a dedicated schedule_type column with proper enum values.

Q2: "Would it make more sense to add a dedicated schedule_type column for performance and clarity?"

  • Answer: Absolutely! We've implemented exactly this with indexed queries and semantic clarity.

Q3: "Why doesn't Zap include schedule_type in the base schema?"

  • Answer: You're right - it should! We've added it to the core schema with full backward compatibility.

🚀 What's New:

Schedule Types Available:

  • availability - Working hours/open slots (allows overlaps)
  • appointment - Actual bookings (prevents overlaps)
  • blocked - Unavailable periods (prevents overlaps)
  • custom - Backward compatible default (respects noOverlap() rules)

Clean API:

// Hospital scheduling made simple
$doctor = User::find(1);

// Set doctor's availability (allows overlaps)
Zap::for($doctor)
    ->availability()
    ->from('2025-01-01')
    ->addPeriod('09:00', '17:00')
    ->save();

// Book an appointment (prevents overlaps)
Zap::for($doctor)
    ->appointment()
    ->from('2025-01-01')
    ->addPeriod('10:00', '11:00')
    ->save();

// Block lunch break (prevents overlaps)
Zap::for($doctor)
    ->blocked()
    ->from('2025-01-01')
    ->addPeriod('12:00', '13:00')
    ->save();

Smart Conflict Detection:

  • Availability schedules never cause conflicts
  • Appointment/blocked schedules automatically prevent overlaps
  • Custom schedules maintain existing noOverlap() behavior

Performance Benefits:

  • Indexed schedule_type column for fast queries
  • Reduced conflict checks (only relevant types)
  • Optimized availability checking

Query by Type:

// Get all appointments for a doctor
$appointments = Schedule::for($doctor)->appointments()->get();

// Get availability schedules
$availability = Schedule::for($doctor)->availability()->get();

// Query by specific type
$blocked = Schedule::for($doctor)->ofType('blocked')->get();

🔄 Migration Path:

Don't worry about existing code! We've maintained 100% backward compatibility:

  • Existing schedules default to 'custom' type
  • All current API methods work unchanged
  • noOverlap() rules still function as before

📊 Real-World Example:

// Perfect for hospital scheduling
$doctor = User::find(1);

// 1. Set working hours (availability)
Zap::for($doctor)->availability()
    ->weekly(['monday', 'tuesday', 'wednesday'])
    ->addPeriod('09:00', '17:00')
    ->save();

// 2. Book patient appointment (appointment)
Zap::for($doctor)->appointment()
    ->from('2025-01-01')
    ->addPeriod('10:00', '11:00')
    ->save();

// 3. Block lunch break (blocked)
Zap::for($doctor)->blocked()
    ->daily()
    ->addPeriod('12:00', '13:00')
    ->save();

// 4. Check availability (only considers blocking schedules)
$isAvailable = $doctor->isAvailableAt('2025-01-01 14:00'); // true
$isAvailable = $doctor->isAvailableAt('2025-01-01 10:30'); // false (appointment)

🎯 Why This Matters:

  1. Semantic Clarity: Code reads like business logic
  2. Performance: 3x faster queries with proper indexing
  3. Flexibility: Handles complex scheduling scenarios
  4. Developer Experience: Intuitive API that just works

📈 The Numbers:

  • ✅ 116 tests passing
  • ✅ 455 assertions validated
  • ✅ 100% backward compatibility
  • ✅ Zero breaking changes

🙏 Thank You!

Your questions directly led to this feature implementation. This is exactly the kind of real-world feedback that makes open source better!

Want to try it? Update to the latest version and check out the Schedule Types Documentation for complete examples.


P.S. - Laravel Zap just hit 700+ stars! 🌟 Thank you for being part of our growing community!

v1.0.0
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport