CoolCMS API

BookingCalendar extends BaseComponent
in package
uses InitTrait, SignalTrait, FormTrait, CancelTrait

FinalYes

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

$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]

$componentParameters

protected array<string, mixed> $componentParameters = []

component parameters set by setComponentParameter()

$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

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>

createComponent()

public createComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

getComponentParameter()

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
Container

getSettings()

public getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>

handleBackToMonth()

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
phpstan-assert-if-true

class-string $className

Return values
bool

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

setCancelToken()

public setCancelToken(string|null $cancelToken) : self
Parameters
$cancelToken : string|null
Return values
self

setComponentParameter()

Sets a component parameter.

public setComponentParameter(string $name, mixed $value) : void
Parameters
$name : string
$value : mixed

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
template
Return values
T

createComponentBookingForm()

protected createComponentBookingForm() : Form
Return values
Form

frontPresenter()

Returns the front presenter the component is attached to (null outside the front end or when detached).

protected frontPresenter() : BasePresenter|null
Return values
BasePresenter|null

getTranslator()

protected getTranslator() : ITranslator
Return values
ITranslator

setTemplateFile()

protected setTemplateFile(string $dir, string $filename) : void
Parameters
$dir : string
$filename : string

setTranslator()

protected setTranslator(ITranslator $translator) : self
Parameters
$translator : ITranslator
Return values
self

buildEndOptions()

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|null

createStandardComponent()

Creates a standard component (not a multiplier).

private createStandardComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

currentMonth()

private static currentMonth() : string
Return values
string

fetchAvailability()

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>|null

finishBookingForm()

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
string

prefillIdentity()

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|null

resolveErrorMessageKey()

An unknown or missing code gives the generic message.

private static resolveErrorMessageKey(mixed $code) : string
Parameters
$code : mixed
Return values
string

resolveMonth()

`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
string

shiftMonth()

private static shiftMonth(string $month, int $delta) : string
Parameters
$month : string
$delta : int
Return values
string

str()

`ArrayHash` values are `mixed`; safely narrows to string (a non-string becomes empty).

private static str(mixed $value) : string
Parameters
$value : mixed
Return values
string

toMinutes()

private static toMinutes(string $time) : int
Parameters
$time : string
Return values
int
On this page

Search results