Fluentný builder a súbežnosť
OpeningHours::edit($owner) — alebo editOpeningHours() na vlastníkovi — vráti CalendarBuilder naplnený aktuálnou definíciou. Zreťazte zmeny a zavolajte save() — zvaliduje ich a zapíše optimisticky:
use RoundlyConsulting\OpeningHours\Builders\ScheduleBuilder;
use RoundlyConsulting\OpeningHours\Enums\Weekday;
use RoundlyConsulting\OpeningHours\Facades\OpeningHours;
OpeningHours::edit($clinic) // or $clinic->editOpeningHours()
->timezone('Europe/Bratislava')
->baseSchedule(fn (ScheduleBuilder $week) => $week
->weekdays('08:00-12:00', '13:00-17:00')
->saturday('09:00-12:00')
->closedOn(Weekday::Sunday))
->schedule(fn (ScheduleBuilder $week) => $week
->label('Summer')->yearly('07-01', '08-31')->priority(10)
->weekdays('07:00-14:00'))
->closed('2026-12-24', '2026-12-26', label: 'Christmas')
->closedYearly('01-01', label: 'New Year')
->exception('2026-10-17', ranges: ['10:00-12:00'], label: 'Short day')
->save();Builder rozvrhu
- monday() … sunday(), weekdays(), weekend(), everyDay() a days([...], ...) nastavujú rozsahy; každý setter dňa nahradí rozsahy daného dňa.
- closedOn(Weekday ...) a open24Hours(Weekday ...) označia zatvorené alebo nonstop dni.
- yearly('07-01', '08-31') nastaví každoročné okno; between(), from() a until() jednorazové okná; withoutWindow() z rozvrhu opäť urobí základný.
- label(), priority() a meta() rozvrh popisujú.
Builder kalendára
- timezone(), label() a meta() nastavujú hlavičku kalendára.
- baseSchedule(fn …) upraví aktuálny základný rozvrh (alebo ho vytvorí): builder v closure vychádza z jeho dní, popisu, priority a meta, nastavenie dňa ten deň nahradí a closedOn() ho vyprázdni — ak odovzdáte ScheduleData, základný rozvrh sa nahradí celý. schedule(fn …) vždy pridá nový rozvrh; removeSchedule($id) a withoutSchedules() rozvrhy odstránia.
- exception($from, $until, ranges:, label:, yearly:, meta:), closed() a closedYearly() pridávajú výnimky; removeException($id) a withoutExceptions() ich odstránia.
- mergeOverlapping() prekrývajúce sa a nadväzujúce rozsahy zlúči namiesto odmietnutia — rozsah, ktorý sa s ničím neprekrýva, zostane presne taký, aký je, a zlúčený rozsah si ponechá popis, kapacitu či položku meta, len ak sa na nich zhodujú všetky pohltené rozsahy.
- violations() a toData() umožnia kontrolu pred uložením; build() vráti OpeningHours v pamäti; save() zapisuje.
Optimistická súbežnosť
Builder si pamätá revíziu, ktorú načítal. Ak medzitým uložil zmeny niekto iný, save() vyhodí StaleOpeningHoursException (s očakávanou a skutočnou revíziou) a všetko vráti späť — namiesto toho, aby jeho zmenu potichu prepísal:
use RoundlyConsulting\OpeningHours\Exceptions\StaleOpeningHoursException;
use RoundlyConsulting\OpeningHours\Facades\OpeningHours;
try {
OpeningHours::edit($clinic)
->closed('2026-12-24', '2026-12-26', label: 'Christmas')
->save();
} catch (StaleOpeningHoursException $e) {
// someone saved in between: $e->expected, $e->actual — reload and retry
}
OpeningHours::edit($clinic)
->expectRevision($request->integer('revision')) // a revision the client echoed back
->closed('2026-11-17', label: 'Public holiday')
->save();
OpeningHours::edit($clinic)
->ignoreConcurrentChanges() // last writer wins
->closedYearly('01-01', label: 'New Year')
->save();
OpeningHours::sync($clinic, $data, expectedRevision: 0); // "must not exist yet"Bez databázy
Hodiny poskladajte alebo skontrolujte v pamäti — pre náhľad v administrácii, import či test — ešte predtým, než sa čokoľvek zapíše:
use RoundlyConsulting\OpeningHours\Builders\CalendarBuilder;
use RoundlyConsulting\OpeningHours\Builders\ScheduleBuilder;
use RoundlyConsulting\OpeningHours\OpeningHours;
$preview = OpeningHours::make(['week' => ['saturday' => ['22:00-03:00']]], 'Europe/Bratislava');
$builder = CalendarBuilder::make()
->timezone('Europe/Bratislava')
->baseSchedule(fn (ScheduleBuilder $week) => $week->weekdays('09:00-17:00'));
$builder->violations(); // ViolationList — empty when the definition is valid
$builder->toData(); // CalendarData
$builder->build(); // OpeningHours, in memoryPrejavte 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.