spatie/opening-hours
Define and query business opening hours with weekly schedules and exceptions. Check if a date/time is open or closed, get next open/close times, and format hours per day. Integrates with Carbon via cmixin/business-time for date-based queries.
OpeningHours model) and integrates with Carbon for date/time handling, reducing friction in PHP/Laravel ecosystems. The package’s design aligns with Laravel’s conventions (e.g., hasMany relationships, query builders).OpeningHours class and a database-backed model, allowing adoption in greenfield or legacy systems. No forced ORM dependency (though Eloquent is recommended).create_opening_hours_table.php) and seeder, simplifying database setup. Supports JSON-based configuration for dynamic hours (e.g., fetched from an API).isOpen(), getOpeningHoursFor()) and serialization (e.g., toArray()), easing frontend integration.UTC). Misconfiguration could lead to incorrect results for location-specific businesses. Mitigation: Document time zone requirements and enforce validation in the model.Cache::remember) or precompute opening hours for common queries.validate() method in the model.date-fns) for client-side checks, but this package is PHP-first.isOpen()).v1.x of the package.spatie/laravel-activitylog (if tracking hour changes).nesbot/carbon (if using custom date logic).| Phase | Task | Dependencies |
|---|---|---|
| Setup | Install package, publish config, run migration. | Database access. |
| Model Integration | Extend OpeningHours model with custom validation/accessors. |
Basic package usage. |
| Query Replacement | Replace isOpen() logic in controllers/services. |
Model integration. |
| Testing | Write tests for edge cases (holidays, time zones). | All prior phases. |
| Caching | Add caching for performance-critical queries. | Testing phase. |
| Frontend Sync | Expose API endpoints or pass data to JS for client-side checks. | Backend integration. |
Log::debug() to OpeningHours methods for troubleshooting.ValidateOpeningHours trait for input sanitization.location_id, date, and day_of_week columns.whereIn() and process in chunks.isOpen()) for 5 minutes with a cache key like opening_hours:{location_id}:{date}.getOpeningHoursFor()).isOpen()) scale well; avoid caching invalidation bottlenecks.| Scenario | Impact | Mitigation |
|---|---|---|
| Database downtime | Opening hours queries fail. | Fallback to cached data or static config. |
| Time zone misconfiguration | Incorrect open/closed status. | Enforce time zone validation in model. |
| Malformed input | Invalid date ranges. | Use Laravel’s ValidateOpeningHours trait. |
| Cache stampede | High DB load during cache misses. | Use probabilistic early expiration. |
| Schema changes | Migration failures. | Test migrations in staging. |
isOpen(), getOpeningHoursFor()).How can I help you explore Laravel packages today?