Výnimky a sviatky
Výnimky prepisujú týždenný rozvrh v konkrétne dátumy. Po jednej ich pridáte, vypíšete a odstránite cez OpeningHours::exceptions($owner):
use RoundlyConsulting\OpeningHours\DataTransferObjects\ExceptionData;
use RoundlyConsulting\OpeningHours\Facades\OpeningHours;
OpeningHours::exceptions($clinic)->closed('2026-12-24', label: 'Christmas Eve');
OpeningHours::exceptions($clinic)->closed('2026-12-24', '2026-12-26', label: 'Christmas'); // a span
OpeningHours::exceptions($clinic)->closed('01-01', label: 'New Year'); // m-d = every year
OpeningHours::exceptions($clinic)->open('2026-12-31', ['09:00-13:00'], label: 'Short day'); // custom hours
OpeningHours::exceptions($clinic, 'pickup')->add(ExceptionData::make('12-26', label: 'St Stephen'));
OpeningHours::exceptions($clinic)->all(); // list<ExceptionData>, with ids
OpeningHours::exceptions($clinic)->remove($ruleId); // false for another calendar's ruleNa rozdiel od edit()->…->save(), ktoré prepíše celú definíciu a vyhodí StaleOpeningHoursException, ak medzitým uložil niekto iný, tento handle zamkne riadok kalendára a pridá len jedno pravidlo zvalidované voči celej definícii — keď dvaja administrátori pridávajú sviatky naraz, uspejú obaja, a builder so starou revíziou sa odmietne namiesto toho, aby novú výnimku zmazal.
Dátum m-d sa opakuje každý rok; Y-m-d platí raz. Ak vlastník pod daným kľúčom nemá živý kalendár, zápis výnimky vyhodí CalendarNotFoundException — kalendár najprv vytvorte cez sync(). remove() sa dotkne len pravidiel daného kalendára a pre akékoľvek iné id vráti false.
Ktoré pravidlo vyhráva
Pre každý dátum vyhráva prvá zhoda v tomto poradí:
- Jednorazové výnimky obsahujúce dátum — vyhráva najužšie obdobie.
- Dynamickí poskytovatelia výnimiek — prvý výsledok iný ako null v poradí registrácie.
- Každoročné výnimky — vyhráva najužšie obdobie.
- Platný rozvrh — najvyššia priorita, rozvrh s oknom pred základným.
- Inak je deň zatvorený.
Rozsah patrí k dátumu, v ktorý začína, takže nočný rozsah z predošlého dňa zasahuje aj do dňa, ktorý je výnimkou zatvorený.
Dotazy na výnimky
$hours->exceptionalClosingDates(); // default: today … +365 days (within max_query_days)
$hours->exceptionalClosingDates('2026-01-01', '2026-12-31');
$hours->exceptionsBetween('2026-12-01', '2026-12-31'); // list<DayHours>Sviatky viazané na Veľkú noc
Pohyblivé sviatky pochádzajú z DynamicExceptionProvider. EasterOffsetProvider je vstavaný — Veľký piatok je -2, Veľkonočný pondelok 1, Nanebovstúpenie 39, Svätodušný pondelok 50 — a deň zatvorí, pokiaľ nezadáte rozsahy. Poskytovateľov zaregistrujete na vlastníkovi alebo priamo pri dotaze:
use RoundlyConsulting\OpeningHours\Dynamic\EasterOffsetProvider;
// On the owner:
public function openingHoursDynamicExceptions(): array
{
return [
new EasterOffsetProvider(-2, 'Good Friday'),
new EasterOffsetProvider(1, 'Easter Monday', ['10:00-12:00']),
];
}
// Or ad hoc:
$hours->withDynamicExceptions(new EasterOffsetProvider(50, 'Whit Monday'));Vlastné pravidlá
Akékoľvek pravidlo, ktoré viete zapísať v kóde — napríklad prvý pondelok v mesiaci —, je trieda implementujúca DynamicExceptionProvider. Pre dátumy, ktoré pokrýva, vráťte ExceptionData, inak null; vrátené okno sa ignoruje a výnimka platí pre dopytovaný dátum:
use RoundlyConsulting\OpeningHours\Contracts\DynamicExceptionProvider;
use RoundlyConsulting\OpeningHours\DataTransferObjects\ExceptionData;
use RoundlyConsulting\OpeningHours\ValueObjects\AbsoluteWindow;
use RoundlyConsulting\OpeningHours\ValueObjects\LocalDate;
final class FirstMondayInventory implements DynamicExceptionProvider
{
public function exceptionFor(LocalDate $date): ?ExceptionData
{
return $date->day <= 7 && $date->weekday()->iso() === 1
? new ExceptionData(AbsoluteWindow::single($date), [], 'Inventory')
: null;
}
}Poskytovatelia sa vyhodnocujú pri každom volaní a nikdy sa necachujú. Veľká noc sa počíta natívne — bez PHP rozšírenia. Balík neobsahuje štátne kalendáre sviatkov; sviatky s pevným dátumom pridajte ako každoročné výnimky.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.