BookingCalendar
extends BaseComponent
in package
uses
InitTrait, SignalTrait, FormTrait, CancelTrait
Two-step booking calendar of the "time slots" page.
Step 1 (month): a grid of days with a state (closed/free/partial/full, starts), persistent
$month. Step 2 (day): after a click on a day (persistent $day), the day schedule with a
range choice and the booking form; without a chosen day step 2 is not rendered. Cancel:
setCancelToken() switches the whole component to the cancellation confirmation form
(CancelTrait), independently of the step.
Data is read through the bridge TimeSlotManager::availability() (the single source of
truth; the server does not trust the client) and written through
ReservationManager::book() / cancelByToken(); the Result envelope is propagated and
the component builds the flash from it.
Table of Contents
Constants
- ERROR_MESSAGE_KEYS : array<string|int, mixed> = [ 2 => 'form.messages.errors.validationFailed',...
- `ResultCode->value` (Api) mapped to the translated message key; an unknown code gives the generic message.
- MONTH_KEYS : array<string|int, mixed> = ['01' => 'jan', '02' => 'feb', '03' => 'mar', '...
- `MM` mapped to a short key under `calendar.months.*` (own keys; there is no system month localization).
Properties
- $container : Container
- $day : string|null
- Chosen day `YYYY-MM-DD` of step 2; `null` means only the month grid.
- $month : string
- Displayed month `YYYY-MM`; empty means the server's current month (see `resolveMonth()`).
- $routerDispatcher : RouterDispatcher
- $translator : ITranslator
- $appContext : AppContext
- $componentParameters : array<string, mixed>
- $currencyContext : CurrencyContext|null
- $deviceDetector : DeviceDetector|null
- $languageContext : LanguageContext|null
- $localizationContext : LocalizationContext|null
- $settingContext : SettingContext
- $themeContext : ThemeContext|null
- $translatorDomain : string|null
- $availabilityCache : array<string, mixed>|null
- Memoizes {@see TimeSlotManager::availability()} within one request (see `InitTrait::fetchAvailability()`).
- $cancelToken : string|null
- Token from `?cancel=<token>`, set by the presenter; `null` means the normal calendar.
- $reservationManager : ReservationManager
- $timeSlotManager : TimeSlotManager
Methods
- __call() : mixed
- Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
- __construct() : mixed
- createComponent() : IComponent|null
- getAppContext() : AppContext
- getComponentParameter() : mixed
- Returns a component parameter, or null when it is not set.
- getContainer() : Container
- getCurrencyContext() : CurrencyContext|null
- getLanguageContext() : LanguageContext|null
- getLocalizationContext() : LocalizationContext|null
- getRouterDispatcher() : RouterDispatcher
- getSettingContext() : SettingContext
- getSettings() : array<int, array<string, mixed>>
- getThemeContext() : ThemeContext|null
- handleBackToMonth() : void
- handleChangeMonth() : void
- handleSelectDay() : void
- hasServiceByType() : bool
- Returns whether the container has a service of the given type.
- initializeAllContexts() : void
- injectDeviceDetector() : void
- onBookingFormSuccess() : void
- onCancelFormSuccess() : void
- onCreate() : void
- render() : void
- setAppContext() : $this
- setCancelToken() : self
- setComponentParameter() : void
- Sets a component parameter.
- setCurrencyContext() : $this
- setLanguageContext() : $this
- setLocalizationContext() : $this
- setSettingContext() : $this
- setThemeContext() : $this
- setup() : void
- setupAppContext() : void
- typedComponent() : T
- Returns a subcomponent with a verified type.
- createComponentBookingForm() : Form
- createComponentCancelForm() : Form
- frontPresenter() : BasePresenter|null
- Returns the front presenter the component is attached to (null outside the front end or when detached).
- getTranslator() : ITranslator
- setTemplateFile() : void
- setTranslator() : self
- buildEndOptions() : array<string, string>
- Returns the end offer: the union of reachable ends over all starts, in steps of `slotLengthMinutes`, capped by `maxTo` of the given start. The server validates the concrete `(from, to)` pair again in `book()`; this offer only limits choices to sensible values and is not an authoritative check.
- buildStartOptions() : array<string, string>
- Returns the start offer from `starts` (the offer step, not the grid).
- buildWeeks() : array<int, array<int, array{date: string, dayNumber: int, state: string, freeMinutesLabel: string|null, isPast: bool, isToday: bool}|null>>
- Builds the month grid by weeks (Monday first); a `null` cell is padding outside the month.
- createMultiplierComponent() : Multiplier<string|int, IComponent>
- Creates a multiplier for the component.
- createNewComponentInstance() : IComponent|null
- Creates a new component instance without adding it to the presenter; used by the multiplier.
- createStandardComponent() : IComponent|null
- Creates a standard component (not a multiplier).
- currentMonth() : string
- fetchAvailability() : array<string, mixed>
- Returns `TimeSlotManager::availability()` for `$this->month`, memoized for the lifetime of this component instance (one request). Required because the step 2 form can be created before `render()` (a form POST calls `createComponent*()` first, and `render()` would not run at all on a redirect or an error), so `prepareCalendar()` alone cannot be relied on.
- fetchDayData() : array<string, mixed>|null
- Returns the data of the chosen day (`starts`/`free`/`busy`/...), or `null` when no day is chosen or it does not exist.
- finishBookingForm() : void
- formatMinutes() : string
- Minutes since midnight to `H:MM` (same as the Api `TimeSlotManager::formatMinutes()`, without a cross-module import).
- prefillIdentity() : void
- prepareCalendar() : void
- prepareCancelForm() : void
- resolveDay() : string|null
- Accepts the chosen day only when it belongs to the displayed month and exists in the Api response; otherwise a day from another month would stay in the URL after switching months.
- resolveErrorMessageKey() : string
- An unknown or missing code gives the generic message.
- resolveMonth() : string
- `YYYY-MM`; empty, invalid or past input falls back to the server's current month.
- shiftMonth() : string
- str() : string
- `ArrayHash` values are `mixed`; safely narrows to string (a non-string becomes empty).
- toMinutes() : int
Constants
ERROR_MESSAGE_KEYS
`ResultCode->value` (Api) mapped to the translated message key; an unknown code gives the generic message.
private
array<string|int, mixed>
ERROR_MESSAGE_KEYS
= [
2 => 'form.messages.errors.validationFailed',
// occupied, in the past or lead time (the Api does not distinguish by code)
4 => 'form.messages.errors.notAvailable',
303 => 'form.messages.errors.dbDuplicateEntry',
304 => 'form.messages.errors.dbLocked',
404 => 'form.messages.errors.rateLimitExceeded',
]
MONTH_KEYS
`MM` mapped to a short key under `calendar.months.*` (own keys; there is no system month localization).
private
array<string|int, mixed>
MONTH_KEYS
= ['01' => 'jan', '02' => 'feb', '03' => 'mar', '04' => 'apr', '05' => 'may', '06' => 'jun', '07' => 'jul', '08' => 'aug', '09' => 'sep', '10' => 'oct', '11' => 'nov', '12' => 'dec']
Properties
$container
public
Container
$container
Attributes
- #[Inject]
$day
Chosen day `YYYY-MM-DD` of step 2; `null` means only the month grid.
public
string|null
$day
= null
Attributes
- #[Persistent]
$month
Displayed month `YYYY-MM`; empty means the server's current month (see `resolveMonth()`).
public
string
$month
= ''
Attributes
- #[Persistent]
$routerDispatcher
public
RouterDispatcher
$routerDispatcher
$translator
public
ITranslator
$translator
Tags
$appContext
protected
AppContext
$appContext
$componentParameters
protected
array<string, mixed>
$componentParameters
= []
component parameters set by setComponentParameter()
$currencyContext
protected
CurrencyContext|null
$currencyContext
= NULL
$deviceDetector
protected
DeviceDetector|null
$deviceDetector
= NULL
$languageContext
protected
LanguageContext|null
$languageContext
= NULL
$localizationContext
protected
LocalizationContext|null
$localizationContext
= NULL
$settingContext
protected
SettingContext
$settingContext
$themeContext
protected
ThemeContext|null
$themeContext
= NULL
$translatorDomain
protected
string|null
$translatorDomain
= 'front.company.components.bookingCalendar'
$availabilityCache
Memoizes {@see TimeSlotManager::availability()} within one request (see `InitTrait::fetchAvailability()`).
private
array<string, mixed>|null
$availabilityCache
= null
$cancelToken
Token from `?cancel=<token>`, set by the presenter; `null` means the normal calendar.
private
string|null
$cancelToken
= null
$reservationManager read-only
private
ReservationManager
$reservationManager
$timeSlotManager read-only
private
TimeSlotManager
$timeSlotManager
Methods
__call()
Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
public
__call(string $name, array<string|int, mixed> $args) : mixed
Called only when the component has no renderXyz() method of its own.
Parameters
- $name : string
- $args : array<string|int, mixed>
__construct()
public
__construct(TimeSlotManager $timeSlotManager, ReservationManager $reservationManager) : mixed
Parameters
- $timeSlotManager : TimeSlotManager
- $reservationManager : ReservationManager
createComponent()
public
createComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullgetAppContext()
public
getAppContext() : AppContext
Return values
AppContextgetComponentParameter()
Returns a component parameter, or null when it is not set.
public
getComponentParameter(string $name) : mixed
Parameters
- $name : string
getContainer()
public
getContainer() : Container
Return values
ContainergetCurrencyContext()
public
getCurrencyContext() : CurrencyContext|null
Return values
CurrencyContext|nullgetLanguageContext()
public
getLanguageContext() : LanguageContext|null
Return values
LanguageContext|nullgetLocalizationContext()
public
getLocalizationContext() : LocalizationContext|null
Return values
LocalizationContext|nullgetRouterDispatcher()
public
getRouterDispatcher() : RouterDispatcher
Return values
RouterDispatchergetSettingContext()
public
getSettingContext() : SettingContext
Return values
SettingContextgetSettings()
public
getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>getThemeContext()
public
getThemeContext() : ThemeContext|null
Return values
ThemeContext|nullhandleBackToMonth()
public
handleBackToMonth() : void
handleChangeMonth()
public
handleChangeMonth(string $month) : void
Parameters
- $month : string
handleSelectDay()
public
handleSelectDay(string $day) : void
Parameters
- $day : string
hasServiceByType()
Returns whether the container has a service of the given type.
public
hasServiceByType(string $className) : bool
The name is composed dynamically (module plus component), so class_exists() runs first, and
a true result guarantees a valid type.
Parameters
- $className : string
Tags
Return values
boolinitializeAllContexts()
public
initializeAllContexts() : void
injectDeviceDetector()
public
injectDeviceDetector(DeviceDetector $detector) : void
Parameters
- $detector : DeviceDetector
onBookingFormSuccess()
public
onBookingFormSuccess(Form $form, ArrayHash $values) : void
Parameters
- $form : Form
- $values : ArrayHash
onCancelFormSuccess()
public
onCancelFormSuccess(Form $form, ArrayHash $values) : void
Parameters
- $form : Form
- $values : ArrayHash
onCreate()
public
onCreate() : void
render()
public
render() : void
setAppContext()
public
setAppContext(AppContext $appContext) : $this
Parameters
- $appContext : AppContext
Return values
$thissetCancelToken()
public
setCancelToken(string|null $cancelToken) : self
Parameters
- $cancelToken : string|null
Return values
selfsetComponentParameter()
Sets a component parameter.
public
setComponentParameter(string $name, mixed $value) : void
Parameters
- $name : string
- $value : mixed
setCurrencyContext()
public
setCurrencyContext(CurrencyContext|null $currencyContext) : $this
Parameters
- $currencyContext : CurrencyContext|null
Return values
$thissetLanguageContext()
public
setLanguageContext(LanguageContext|null $languageContext) : $this
Parameters
- $languageContext : LanguageContext|null
Return values
$thissetLocalizationContext()
public
setLocalizationContext(LocalizationContext|null $localizationContext) : $this
Parameters
- $localizationContext : LocalizationContext|null
Return values
$thissetSettingContext()
public
setSettingContext(SettingContext $settingContext) : $this
Parameters
- $settingContext : SettingContext
Return values
$thissetThemeContext()
public
setThemeContext(ThemeContext|null $themeContext) : $this
Parameters
- $themeContext : ThemeContext|null
Return values
$thissetup()
public
setup(BasePresenter|BasePresenter $presenter) : void
Parameters
- $presenter : BasePresenter|BasePresenter
setupAppContext()
public
setupAppContext(AppContext $appContext) : void
Parameters
- $appContext : AppContext
typedComponent()
Returns a subcomponent with a verified type.
public
typedComponent(string $name, T> $type) : T
Use it instead of an inline @var above $this['x'] (which does not narrow the type) and
instead of the generic IComponent that $this['x'] returns. See
Form::typedComponent().
Parameters
- $name : string
- $type : T>
Tags
Return values
TcreateComponentBookingForm()
protected
createComponentBookingForm() : Form
Return values
FormcreateComponentCancelForm()
protected
createComponentCancelForm() : Form
Return values
FormfrontPresenter()
Returns the front presenter the component is attached to (null outside the front end or when detached).
protected
frontPresenter() : BasePresenter|null
Return values
BasePresenter|nullgetTranslator()
protected
getTranslator() : ITranslator
Return values
ITranslatorsetTemplateFile()
protected
setTemplateFile(string $dir, string $filename) : void
Parameters
- $dir : string
- $filename : string
setTranslator()
protected
setTranslator(ITranslator $translator) : self
Parameters
- $translator : ITranslator
Return values
selfbuildEndOptions()
Returns the end offer: the union of reachable ends over all starts, in steps of `slotLengthMinutes`, capped by `maxTo` of the given start. The server validates the concrete `(from, to)` pair again in `book()`; this offer only limits choices to sensible values and is not an authoritative check.
private
static buildEndOptions(array<string, mixed>|null $dayData) : array<string, string>
Parameters
- $dayData : array<string, mixed>|null
Return values
array<string, string>buildStartOptions()
Returns the start offer from `starts` (the offer step, not the grid).
private
static buildStartOptions(array<string, mixed>|null $dayData) : array<string, string>
Parameters
- $dayData : array<string, mixed>|null
Return values
array<string, string>buildWeeks()
Builds the month grid by weeks (Monday first); a `null` cell is padding outside the month.
private
static buildWeeks(string $month, array<string, mixed> $days) : array<int, array<int, array{date: string, dayNumber: int, state: string, freeMinutesLabel: string|null, isPast: bool, isToday: bool}|null>>
Parameters
- $month : string
- $days : array<string, mixed>
Return values
array<int, array<int, array{date: string, dayNumber: int, state: string, freeMinutesLabel: string|null, isPast: bool, isToday: bool}|null>>createMultiplierComponent()
Creates a multiplier for the component.
private
createMultiplierComponent(string $name) : Multiplier<string|int, IComponent>
Parameters
- $name : string
Return values
Multiplier<string|int, IComponent>createNewComponentInstance()
Creates a new component instance without adding it to the presenter; used by the multiplier.
private
createNewComponentInstance(string $baseName[, int|string|null $uniqueKey = null ]) : IComponent|null
Parameters
- $baseName : string
- $uniqueKey : int|string|null = null
Return values
IComponent|nullcreateStandardComponent()
Creates a standard component (not a multiplier).
private
createStandardComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullcurrentMonth()
private
static currentMonth() : string
Return values
stringfetchAvailability()
Returns `TimeSlotManager::availability()` for `$this->month`, memoized for the lifetime of this component instance (one request). Required because the step 2 form can be created before `render()` (a form POST calls `createComponent*()` first, and `render()` would not run at all on a redirect or an error), so `prepareCalendar()` alone cannot be relied on.
private
fetchAvailability() : array<string, mixed>
The return type is deliberately loose: availability is fail-soft (a read error gives an empty payload), so consumers guard the keys themselves.
Return values
array<string, mixed>fetchDayData()
Returns the data of the chosen day (`starts`/`free`/`busy`/...), or `null` when no day is chosen or it does not exist.
private
fetchDayData() : array<string, mixed>|null
Return values
array<string, mixed>|nullfinishBookingForm()
private
finishBookingForm(Form $form, bool $success) : void
Parameters
- $form : Form
- $success : bool
formatMinutes()
Minutes since midnight to `H:MM` (same as the Api `TimeSlotManager::formatMinutes()`, without a cross-module import).
private
static formatMinutes(int $minutes) : string
Parameters
- $minutes : int
Return values
stringprefillIdentity()
private
static prefillIdentity(Form $form, User|null $user) : void
Parameters
- $form : Form
- $user : User|null
prepareCalendar()
private
prepareCalendar() : void
prepareCancelForm()
private
prepareCancelForm() : void
resolveDay()
Accepts the chosen day only when it belongs to the displayed month and exists in the Api response; otherwise a day from another month would stay in the URL after switching months.
private
resolveDay(array<string, mixed> $days) : string|null
Parameters
- $days : array<string, mixed>
Return values
string|nullresolveErrorMessageKey()
An unknown or missing code gives the generic message.
private
static resolveErrorMessageKey(mixed $code) : string
Parameters
- $code : mixed
Return values
stringresolveMonth()
`YYYY-MM`; empty, invalid or past input falls back to the server's current month.
private
static resolveMonth(string|null $month) : string
Parameters
- $month : string|null
Return values
stringshiftMonth()
private
static shiftMonth(string $month, int $delta) : string
Parameters
- $month : string
- $delta : int
Return values
stringstr()
`ArrayHash` values are `mixed`; safely narrows to string (a non-string becomes empty).
private
static str(mixed $value) : string
Parameters
- $value : mixed
Return values
stringtoMinutes()
private
static toMinutes(string $time) : int
Parameters
- $time : string