CoolCMS API

InitTrait

Prepares the data of both wizard states (month grid / day slots) and the header with the public calendar switcher.

IMPORTANT: day clickability and the trim of today by leadTimeHours are computed here on the server, not in Latte or JS; the template only renders the ready bookable flag.

Table of Contents

Constants

MONTH_KEYS  : array<string|int, mixed> = ['01' => 'jan', '02' => 'feb', '03' => 'mar', '...
`MM` mapped to a short key under `calendar.months.*` (shared with the old component, see `front.*.neon`).
WEEKDAY_KEYS  : array<string|int, mixed> = [1 => 'mon', 2 => 'tue', 3 => 'wed', 4 => 'thu'...
ISO day number (`N`) mapped to a short key under `calendar.weekdays*.*`.

Methods

bookableStarts()  : array<int, array{from: string, to: string, maxTo: string}>
Returns the offered day starts after the lead-time trim. The Api already trims them (free time is cut from the left by `now + leadTimeHours`), but the front end does not rely on it: time can pass between computing and rendering (cache, long request) and offering a slot the lead time no longer allows would mean a click into an error.
buildWeeks()  : array<int, array<int, array{date: string, dayNumber: int, weekdayKey: string, state: string, freeMinutesLabel: string|null, isPast: bool, isToday: bool, bookable: bool, startCount: int}|null>>
Builds the month grid by weeks (Monday first); a `null` cell is padding outside the month and is never clickable.
currentMonth()  : string
fetchAvailability()  : array<string, mixed>
Returns {@see \App\UI\Front\Company\Models\Managers\TimeSlotManager::availability()} memoized for the lifetime of this component instance (one request), keyed by month and calendar.
findCalendar()  : array{id: int, name: string, description: string|null}|null
formatDayHeading()  : string
Formats `YYYY-MM-DD` as e.g. "Thursday, September 10, 2026" by the `day.heading` pattern of the language.
formatMinutes()  : string
Minutes since midnight to `H:MM` (same as the Api `TimeSlotManager::formatMinutes()`, without a cross-module import).
isDayBookable()  : bool
Applies the day clickability rules: past days are not bookable, `closed` or without starts are not, today only when at least one start remains after the `leadTimeHours` trim. Padding is handled by the template (a `null` cell) and never gets here.
prepareWizard()  : void
resolveCalendarId()  : int
Resolves the calendar id. IMPORTANT: the persistent `calendarId` from the URL is not trusted; only values from the list of public calendars of the presented company are valid. A foreign, non-public or nonsensical id falls back to the first public calendar (and `0` when the company has none).
resolveDay()  : string|null
Accepts the chosen day only when it belongs to the displayed month, exists in the Api response and is bookable; otherwise the wizard returns to the "month" state. Without this check a hand-edited URL could open the slot list of a past or closed day.
resolveMonth()  : string
`YYYY-MM`; empty, invalid or past input falls back to the server's current month.
shiftMonth()  : string

Constants

MONTH_KEYS

`MM` mapped to a short key under `calendar.months.*` (shared with the old component, see `front.*.neon`).

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

WEEKDAY_KEYS

ISO day number (`N`) mapped to a short key under `calendar.weekdays*.*`.

private array<string|int, mixed> WEEKDAY_KEYS = [1 => 'mon', 2 => 'tue', 3 => 'wed', 4 => 'thu', 5 => 'fri', 6 => 'sat', 7 => 'sun']

Methods

bookableStarts()

Returns the offered day starts after the lead-time trim. The Api already trims them (free time is cut from the left by `now + leadTimeHours`), but the front end does not rely on it: time can pass between computing and rendering (cache, long request) and offering a slot the lead time no longer allows would mean a click into an error.

private static bookableStarts(string $date, mixed $dayData, int $leadTimeHours) : array<int, array{from: string, to: string, maxTo: string}>
Parameters
$date : string
$dayData : mixed

raw day payload from the fail-soft Api response (can be anything)

$leadTimeHours : int
Return values
array<int, array{from: string, to: string, maxTo: string}>

buildWeeks()

Builds the month grid by weeks (Monday first); a `null` cell is padding outside the month and is never clickable.

private static buildWeeks(string $month, array<string, mixed> $days, int $leadTimeHours) : array<int, array<int, array{date: string, dayNumber: int, weekdayKey: string, state: string, freeMinutesLabel: string|null, isPast: bool, isToday: bool, bookable: bool, startCount: int}|null>>
Parameters
$month : string
$days : array<string, mixed>
$leadTimeHours : int

trim of today; computed here, not in Latte

Return values
array<int, array<int, array{date: string, dayNumber: int, weekdayKey: string, state: string, freeMinutesLabel: string|null, isPast: bool, isToday: bool, bookable: bool, startCount: int}|null>>

currentMonth()

private static currentMonth() : string
Return values
string

fetchAvailability()

Returns {@see \App\UI\Front\Company\Models\Managers\TimeSlotManager::availability()} memoized for the lifetime of this component instance (one request), keyed by month and calendar.

private fetchAvailability(string $month, int $calendarId) : array<string, mixed>
Parameters
$month : string
$calendarId : int
Return values
array<string, mixed>

findCalendar()

private findCalendar(array<int, array{id: int, name: string, description: string|null}> $calendars, int $calendarId) : array{id: int, name: string, description: string|null}|null
Parameters
$calendars : array<int, array{id: int, name: string, description: string|null}>
$calendarId : int
Return values
array{id: int, name: string, description: string|null}|null

formatDayHeading()

Formats `YYYY-MM-DD` as e.g. "Thursday, September 10, 2026" by the `day.heading` pattern of the language.

private formatDayHeading(string $day) : string

IMPORTANT: built in PHP because both variable parts are translations (calendar.weekdaysLong.*, calendar.monthsInflected.*) and the order differs per language; in Latte this would need a nested {_} inside a {_} parameter.

Parameters
$day : string
Return values
string

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

isDayBookable()

Applies the day clickability rules: past days are not bookable, `closed` or without starts are not, today only when at least one start remains after the `leadTimeHours` trim. Padding is handled by the template (a `null` cell) and never gets here.

private static isDayBookable(string $date, mixed $dayData, int $leadTimeHours) : bool
Parameters
$date : string
$dayData : mixed

raw day payload from the fail-soft Api response (can be anything)

$leadTimeHours : int
Return values
bool

prepareWizard()

private prepareWizard() : void

resolveCalendarId()

Resolves the calendar id. IMPORTANT: the persistent `calendarId` from the URL is not trusted; only values from the list of public calendars of the presented company are valid. A foreign, non-public or nonsensical id falls back to the first public calendar (and `0` when the company has none).

private resolveCalendarId(array<int, array{id: int, name: string, description: string|null}> $calendars) : int
Parameters
$calendars : array<int, array{id: int, name: string, description: string|null}>
Return values
int

resolveDay()

Accepts the chosen day only when it belongs to the displayed month, exists in the Api response and is bookable; otherwise the wizard returns to the "month" state. Without this check a hand-edited URL could open the slot list of a past or closed day.

private resolveDay(array<string, mixed> $days, int $leadTimeHours) : string|null
Parameters
$days : array<string, mixed>
$leadTimeHours : int
Return values
string|null

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
On this page

Search results