CoolCMS API

SlotModal extends BaseComponent
in package
uses ModalAwareTrait, PrivilegeGuardTrait

FinalYes

Time slot edit modal of the admin calendar.

The only entry point is a click on a block of the day timeline (day.latte) or on a bubble of the week grid (week.latte). The clicked block type selects one of three modes:

  • MODE_FILL (free): a new reservation on a free interval, or a block of the same range. The range is editable because the time slot does not exist yet.
  • MODE_RESERVATION (pending or confirmed): edits the client details and state, with tools to shorten or split the time slot and to cancel the reservation. The range is static text: only shortening or splitting may change the time of an occupied row.
  • MODE_BLOCKED (blocked): read-only context plus canceling the block. A block has no client whose time slot could be shortened, so the admin deletes it and creates a new one.

IMPORTANT: admin AJAX modal pitfalls this component works around on purpose:

  1. The context is not carried as a persistent parameter, because link('this') of the form does not carry it (see CommentThread). It goes into the signal as an explicit parameter and into the form as a hidden field, and is read back from the POST on submit (hydrateContext()).
  2. No field has setRequired(). Native HTML5 required on a field that belongs to another button of the same form silently blocks the submit in the browser, even when the server validation of that button ignores the field. All validation is server-side, authoritative in the Api managers.
  3. Fields are added conditionally by mode. The mode comes from a private property when opened by a signal and from a hidden POST field on submit, because handleOpen*() does not run then.
  4. $presenter->flashMessage() is invisible in a component template, so messages live in the per-request buffer $notice and _modal.latte renders them itself (final text, not a key, to avoid a double domain prefix).
  5. No redirect() on AJAX, because it would close the modal. After an action the modal is refilled (showModal()) and the underlying timeline is redrawn with redrawControl($this->returnSnippet).
  6. State is reloaded after every write: mutations through the Api bridge do not change the already hydrated Admin objects, so re-rendering must use freshly read data.

The component neither locks nor validates times. All writes go through the Admin bridge to the Api managers, which run under the per-day lock (TimeSlotManager::dayLockName()); form values are only a proposal.

Table of Contents

Constants

FILL_ACTION_BLOCK  : string = 'block'
`fillAction` switch (mode A): `TimeSlotManager::save()` with `type=blocked`.
FILL_ACTION_OPEN_WINDOW  : string = 'openWindow'
`fillAction` switch (mode A): {@see TimeSlotManager::openWindow()}, creating a time slot on closed time.
FILL_ACTION_RESERVE  : string = 'reserve'
`fillAction` switch (mode A): {@see ReservationManager::bookByAdmin()}.
MODE_BLOCKED  : string = 'blocked'
Click on a `blocked` block: an admin block without a client.
MODE_FILL  : string = 'fill'
Click on a `free` block: a new reservation or block.
MODE_RESERVATION  : string = 'reservation'
Click on a `confirmed`/`pending` block: an existing reservation.
SNIPPET_DAY  : string = 'dayTimeline'
Day timeline snippet (`day.latte`); the default redraw target.
SNIPPET_WEEK  : string = 'weekGrid'
Week grid snippet (`week.latte`).
TIME_ACTION_KEEP  : string = 'keep'
`timeAction` switch (mode B): keeps the range and calls only `updateByAdmin()`.
TIME_ACTION_SHORTEN  : string = 'shorten'
`timeAction` switch (mode B): additionally calls {@see TimeSlotManager::shorten()}.
TIME_ACTION_SPLIT  : string = 'split'
`timeAction` switch (mode B): additionally calls {@see TimeSlotManager::split()}.
EDIT_PRIVILEGE  : string = ':Admin:Company:TimeSlot:edit'
Same key as `SchedulePresenter::handleMergeSlots()` and `TimeSlotPresenter::actionEdit()`.

Properties

$container  : Container
$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
$allCalendars  : bool
Week view of all calendars; must survive the redraw.
$calendarId  : int
$calendarManager  : CalendarManager
$companyId  : int
Company the view is rendered for; context for redrawing the timeline only.
$date  : string
`Y-m-d` of the day whose timeline or grid the modal serves.
$done  : bool
The action finished and nothing is left to offer (canceled reservation or deleted block).
$fromMin  : int
Range of the clicked free block in minutes after midnight ({@see MODE_FILL} only).
$mode  : string
Active mode; `''` means the modal does not open in this request.
$notice  : array{type: string, text: string}|null
Per-request message rendered inside the modal (pitfall 4 in the class docblock).
$reservation  : Reservation|null
Active reservation on {@see $slot} ({@see MODE_RESERVATION}).
$reservationManager  : ReservationManager
$returnSnippet  : string
Snippet to redraw after an action: `dayTimeline` or `weekGrid`.
$slot  : TimeSlot|null
Calendar row ({@see MODE_RESERVATION}/{@see MODE_BLOCKED} modes).
$timeSlotManager  : TimeSlotManager
$toMin  : int

Methods

__call()  : mixed
Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
__construct()  : mixed
createComponent()  : IComponent|null
createComponentSlotForm()  : Form
Builds one form whose fields depend on the mode (pitfalls 2 and 3 in the class docblock).
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
getViewContext()  : array{companyId: int, calendarId: int, date: string, allCalendars: bool}|null
Returns the view context after the signal was handled.
handleOpenBlocked()  : void
Click on a block of a time block ({@see MODE_BLOCKED} mode).
handleOpenFree()  : void
Click on a free block of the day timeline ({@see MODE_FILL} mode).
handleOpenReservation()  : void
Click on a block with an active reservation ({@see MODE_RESERVATION} mode).
hasServiceByType()  : bool
Returns whether the container has a service of the given type.
initializeAllContexts()  : void
injectDeviceDetector()  : void
onCancelReservation()  : void
Mode B, cancel reservation: reuses {@see ReservationManager::cancel()}.
onCreate()  : void
onDeleteBlock()  : void
Mode C, cancel block: reuses {@see TimeSlotManager::delete()}.
onFillSave()  : void
Mode A, single button: calls {@see ReservationManager::bookByAdmin()} or `TimeSlotManager::save()` with `type=blocked`, chosen by the submitted value of the `blocked` switch, not by which button caught the click.
onReservationSave()  : void
Mode B, single save button: always calls {@see ReservationManager::updateByAdmin()} (name, e-mail, phone, note, state; never the time), and additionally acts on the submitted value of the `timeAction` switch: `keep` does nothing more, `shorten`/`split` also call {@see TimeSlotManager::shorten()}/`::split()`.
render()  : void
Renders nothing into the page; it exists for its signals and to fill the shared {@see \App\UI\Admin\System\Components\ModalWindowComponent\ModalWindow} from `@layout.latte`.
setAppContext()  : $this
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.
frontPresenter()  : BasePresenter|null
Returns the front presenter the component is attached to (null outside the front end or when detached).
getModalWindow()  : ModalWindow
getTranslator()  : ITranslator
isTargetAllowed()  : bool
Returns whether the logged-in user may open the given admin target. For visibility (tiles, autocomplete, buttons); it does not throw.
requirePrivilege()  : void
Throws 403 when the logged-in user lacks the given admin privilege.
resolvePageTarget()  : string|null
Returns the RBAC key of the target page: `<presenter>:<action>`, e.g. `:Admin:System:User:show`.
setTemplateFile()  : void
setTranslator()  : self
addBlockedFields()  : void
Mode C: a block with no editable fields; the only action is canceling it.
addFillFields()  : void
Mode A: a new reservation on a free interval, or a block of the same range.
addReservationFields()  : void
Mode B: an existing reservation with details and state, shorten/split tools and cancellation.
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).
failAndReopen()  : void
Turns an Api action failure into a readable message inside the modal (no flash, pitfall 4).
fillActionOptions()  : array<string, string>
Returns the `fillAction` options as translation keys, like {@see timeActionOptions()} (`addRadioList()` translates them through the form `useDomainTranslator()`).
findCalendar()  : Calendar|null
findSlot()  : TimeSlot|null
finish()  : void
Refills the modal and redraws the underlying timeline or grid (pitfall 5 in the class docblock).
formatDate()  : string
Converts `Y-m-d` to `j. n. Y`; an invalid date is returned unchanged.
formatMinutes()  : string
Converts minutes after midnight to `HH:MM`, like Api `TimeSlotManager::formatMinutes()`.
hydrateContext()  : void
Restores the view context from the submitted hidden fields, because the signal link of the form does not carry it (pitfall 1 in the class docblock). Calendar and day of modes B and C are loaded from the time slot, not from here.
int()  : int
loadReservationContext()  : void
Loads a fresh row and its active reservation (pitfall 6 in the class docblock: hydrated objects do not update after a bridge write).
normalizeSnippet()  : string
Allows only the two known values; a foreign string would crash the request in `redrawControl()`.
noticeError()  : void
noticeSuccess()  : void
parseTime()  : DateTime|null
Converts the value of `<input type=time>` to `DateTime`, or null when empty or invalid.
renderModalContent()  : string
Renders the modal content to a string for `ModalWindow`.
requireCalendarInCompany()  : void
403 when an existing calendar does not belong to the company the modal was opened from.
requireReservationOfSlot()  : void
403 when the posted reservation id points to a reservation of a different slot.
requireSlotInCompany()  : void
403 when an existing slot does not belong to the company the modal was opened from.
resolveMode()  : string
Returns the mode used to build the form.
saveBlock()  : Result
Saves a block through `save()` with an entity of `type = blocked` (no dedicated Api action; the same path as `TimeSlotFormTrait`).
saveReservation()  : Result
saveWindow()  : Result
Creates a time slot through {@see TimeSlotManager::openWindow()}.
showModal()  : void
Fills and opens the shared admin modal with the current state.
stateOptions()  : array<string, string>
str()  : string
strOrNull()  : string|null
text()  : string
Returns final translated text (not a key) for the {@see $notice} buffer and select options.
timeActionOptions()  : array<string, string>
Returns the `timeAction` options as translation keys.
values()  : array<string, mixed>
Returns the form values.

Constants

FILL_ACTION_BLOCK

`fillAction` switch (mode A): `TimeSlotManager::save()` with `type=blocked`.

public string FILL_ACTION_BLOCK = 'block'

FILL_ACTION_OPEN_WINDOW

`fillAction` switch (mode A): {@see TimeSlotManager::openWindow()}, creating a time slot on closed time.

public string FILL_ACTION_OPEN_WINDOW = 'openWindow'

Unlike FILL_ACTION_RESERVE no reservation is created; the time is permanently opened for future booking (front end and further admin writes).

FILL_ACTION_RESERVE

`fillAction` switch (mode A): {@see ReservationManager::bookByAdmin()}.

public string FILL_ACTION_RESERVE = 'reserve'

Always enforceWindow=false: bookByAdmin() ignores the offer windows because the admin sees the whole day. A click on a free and on a closed block takes the same path, so no separate origin distinction is needed (see handleOpenFree()).

MODE_BLOCKED

Click on a `blocked` block: an admin block without a client.

public string MODE_BLOCKED = 'blocked'

MODE_FILL

Click on a `free` block: a new reservation or block.

public string MODE_FILL = 'fill'

MODE_RESERVATION

Click on a `confirmed`/`pending` block: an existing reservation.

public string MODE_RESERVATION = 'reservation'

SNIPPET_DAY

Day timeline snippet (`day.latte`); the default redraw target.

public string SNIPPET_DAY = 'dayTimeline'

SNIPPET_WEEK

Week grid snippet (`week.latte`).

public string SNIPPET_WEEK = 'weekGrid'

TIME_ACTION_KEEP

`timeAction` switch (mode B): keeps the range and calls only `updateByAdmin()`.

public string TIME_ACTION_KEEP = 'keep'

TIME_ACTION_SHORTEN

`timeAction` switch (mode B): additionally calls {@see TimeSlotManager::shorten()}.

public string TIME_ACTION_SHORTEN = 'shorten'

TIME_ACTION_SPLIT

`timeAction` switch (mode B): additionally calls {@see TimeSlotManager::split()}.

public string TIME_ACTION_SPLIT = 'split'

EDIT_PRIVILEGE

Same key as `SchedulePresenter::handleMergeSlots()` and `TimeSlotPresenter::actionEdit()`.

private string EDIT_PRIVILEGE = ':Admin:Company:TimeSlot:edit'

Properties

$componentParameters

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

component parameters set by setComponentParameter()

$translatorDomain

protected string|null $translatorDomain = 'admin.company.components.slotModal'

$allCalendars

Week view of all calendars; must survive the redraw.

private bool $allCalendars = false

$companyId

Company the view is rendered for; context for redrawing the timeline only.

private int $companyId = 0

$date

`Y-m-d` of the day whose timeline or grid the modal serves.

private string $date = ''

$done

The action finished and nothing is left to offer (canceled reservation or deleted block).

private bool $done = false

$fromMin

Range of the clicked free block in minutes after midnight ({@see MODE_FILL} only).

private int $fromMin = 0

$mode

Active mode; `''` means the modal does not open in this request.

private string $mode = ''

$notice

Per-request message rendered inside the modal (pitfall 4 in the class docblock).

private array{type: string, text: string}|null $notice = null

Holds final text, not a translation key.

$reservation

Active reservation on {@see $slot} ({@see MODE_RESERVATION}).

private Reservation|null $reservation = null

$returnSnippet

Snippet to redraw after an action: `dayTimeline` or `weekGrid`.

private string $returnSnippet = self::SNIPPET_DAY

$slot

Calendar row ({@see MODE_RESERVATION}/{@see MODE_BLOCKED} modes).

private TimeSlot|null $slot = 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

createComponentSlotForm()

Builds one form whose fields depend on the mode (pitfalls 2 and 3 in the class docblock).

public createComponentSlotForm() : Form

No field has setRequired(); only the server (Api managers) validates.

Return values
Form

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

getViewContext()

Returns the view context after the signal was handled.

public getViewContext() : array{companyId: int, calendarId: int, date: string, allCalendars: bool}|null

The presenter overrides its GET parameter values with it, because those do not reach the component signal link (Nette prefixes all arguments with the component name, so ?date=... is missing on the signal path and renderDay() would redraw a different day).

null means no modal signal ran in this request (a plain GET), so the presenter reads the context as usual.

Return values
array{companyId: int, calendarId: int, date: string, allCalendars: bool}|null

handleOpenBlocked()

Click on a block of a time block ({@see MODE_BLOCKED} mode).

public handleOpenBlocked(int $companyId, int $timeSlotId[, string $returnSnippet = self::SNIPPET_DAY ][, bool $allCalendars = false ]) : void
Parameters
$companyId : int
$timeSlotId : int
$returnSnippet : string = self::SNIPPET_DAY
$allCalendars : bool = false

handleOpenFree()

Click on a free block of the day timeline ({@see MODE_FILL} mode).

public handleOpenFree(int $companyId, int $calendarId, string $date, int $fromMin, int $toMin[, string $returnSnippet = self::SNIPPET_DAY ][, bool $allCalendars = false ]) : void
Parameters
$companyId : int
$calendarId : int
$date : string
$fromMin : int
$toMin : int
$returnSnippet : string = self::SNIPPET_DAY
$allCalendars : bool = false

handleOpenReservation()

Click on a block with an active reservation ({@see MODE_RESERVATION} mode).

public handleOpenReservation(int $companyId, int $timeSlotId[, string $returnSnippet = self::SNIPPET_DAY ][, bool $allCalendars = false ]) : void
Parameters
$companyId : int
$timeSlotId : int
$returnSnippet : string = self::SNIPPET_DAY
$allCalendars : bool = false

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

onCancelReservation()

Mode B, cancel reservation: reuses {@see ReservationManager::cancel()}.

public onCancelReservation(SubmitButton $button) : void
Parameters
$button : SubmitButton

onDeleteBlock()

Mode C, cancel block: reuses {@see TimeSlotManager::delete()}.

public onDeleteBlock(SubmitButton $button) : void
Parameters
$button : SubmitButton

onFillSave()

Mode A, single button: calls {@see ReservationManager::bookByAdmin()} or `TimeSlotManager::save()` with `type=blocked`, chosen by the submitted value of the `blocked` switch, not by which button caught the click.

public onFillSave(SubmitButton $button) : void
Parameters
$button : SubmitButton

onReservationSave()

Mode B, single save button: always calls {@see ReservationManager::updateByAdmin()} (name, e-mail, phone, note, state; never the time), and additionally acts on the submitted value of the `timeAction` switch: `keep` does nothing more, `shorten`/`split` also call {@see TimeSlotManager::shorten()}/`::split()`.

public onReservationSave(SubmitButton $button) : void

IMPORTANT: both operations run under their own per-day lock (updateByAdmin() and shorten()/split() take and release it themselves), so together they are not one atomic transaction. When updateByAdmin() succeeds and the following shorten()/split() fails (for example the new range collides), the field changes stay saved but the time does not change. The admin gets an error message and the form reopens with the current, partly saved state (loadReservationContext() always runs, even after an error). This is accepted for a low-traffic admin UI instead of a new atomic Api method.

Parameters
$button : SubmitButton

render()

Renders nothing into the page; it exists for its signals and to fill the shared {@see \App\UI\Admin\System\Components\ModalWindowComponent\ModalWindow} from `@layout.latte`.

public render() : void

Templates do not mount it with {control slotModal}; they only generate {link slotModal:open...!} links from it.

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

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

isTargetAllowed()

Returns whether the logged-in user may open the given admin target. For visibility (tiles, autocomplete, buttons); it does not throw.

protected isTargetAllowed(string|null $key) : bool

IMPORTANT: fail-closed like requirePrivilege(): an empty key and a presenter without isAllowed() both mean no. A component that skips this question lists the target to everyone.

Parameters
$key : string|null
Return values
bool

requirePrivilege()

Throws 403 when the logged-in user lacks the given admin privilege.

protected requirePrivilege(string $key) : void

Call it as the first statement of a mutating signal, before loading data, so the check cannot be bypassed by something being written first.

Parameters
$key : string

resolvePageTarget()

Returns the RBAC key of the target page: `<presenter>:<action>`, e.g. `:Admin:System:User:show`.

protected static resolvePageTarget(object|null $page) : string|null

Same interpretation as Menu::filterByPrivileges(), BasePresenter::authorizeListing() and PrivilegeCheckTrait::checkCurrentPrivilege(). The key is derived from the page target only, never from a file or class name.

Returns null when the page is missing or has no presenter, so there is nothing to allow.

Parameters
$page : object|null

AdminPage entity (hydrated, hence just object)

Return values
string|null

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

addBlockedFields()

Mode C: a block with no editable fields; the only action is canceling it.

private addBlockedFields(Form $form) : void
Parameters
$form : Form

addFillFields()

Mode A: a new reservation on a free interval, or a block of the same range.

private addFillFields(Form $form) : void
Parameters
$form : Form

addReservationFields()

Mode B: an existing reservation with details and state, shorten/split tools and cancellation.

private addReservationFields(Form $form) : void
Parameters
$form : Form

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

failAndReopen()

Turns an Api action failure into a readable message inside the modal (no flash, pitfall 4).

private failAndReopen(Result $result) : void
Parameters
$result : Result

fillActionOptions()

Returns the `fillAction` options as translation keys, like {@see timeActionOptions()} (`addRadioList()` translates them through the form `useDomainTranslator()`).

private fillActionOptions() : array<string, string>
Return values
array<string, string>

findCalendar()

private findCalendar(int $calendarId) : Calendar|null
Parameters
$calendarId : int
Return values
Calendar|null

finish()

Refills the modal and redraws the underlying timeline or grid (pitfall 5 in the class docblock).

private finish() : void

formatDate()

Converts `Y-m-d` to `j. n. Y`; an invalid date is returned unchanged.

private formatDate(string $date) : string
Parameters
$date : string
Return values
string

formatMinutes()

Converts minutes after midnight to `HH:MM`, like Api `TimeSlotManager::formatMinutes()`.

private static formatMinutes(int $minutes) : string
Parameters
$minutes : int
Return values
string

hydrateContext()

Restores the view context from the submitted hidden fields, because the signal link of the form does not carry it (pitfall 1 in the class docblock). Calendar and day of modes B and C are loaded from the time slot, not from here.

private hydrateContext(array<string, mixed> $values) : void
Parameters
$values : array<string, mixed>

int()

private int(mixed $value) : int
Parameters
$value : mixed
Return values
int

loadReservationContext()

Loads a fresh row and its active reservation (pitfall 6 in the class docblock: hydrated objects do not update after a bridge write).

private loadReservationContext(int $timeSlotId) : void

Without an active reservation the mode falls back to "not found", so the modal does not offer actions on something that no longer exists.

Parameters
$timeSlotId : int

normalizeSnippet()

Allows only the two known values; a foreign string would crash the request in `redrawControl()`.

private static normalizeSnippet(string $snippet) : string
Parameters
$snippet : string
Return values
string

noticeError()

private noticeError(string $text) : void
Parameters
$text : string

noticeSuccess()

private noticeSuccess(string $text) : void
Parameters
$text : string

parseTime()

Converts the value of `<input type=time>` to `DateTime`, or null when empty or invalid.

private parseTime(mixed $value) : DateTime|null
Parameters
$value : mixed
Return values
DateTime|null

renderModalContent()

Renders the modal content to a string for `ModalWindow`.

private renderModalContent() : string
Return values
string

requireCalendarInCompany()

403 when an existing calendar does not belong to the company the modal was opened from.

private requireCalendarInCompany(int $calendarId, int $companyId) : void
Parameters
$calendarId : int
$companyId : int

requireReservationOfSlot()

403 when the posted reservation id points to a reservation of a different slot.

private requireReservationOfSlot(int $reservationId, int $timeSlotId) : void
Parameters
$reservationId : int
$timeSlotId : int

requireSlotInCompany()

403 when an existing slot does not belong to the company the modal was opened from.

private requireSlotInCompany(int $timeSlotId, int $companyId) : void

A missing slot passes — the regular "not found" flow handles it without leaking data.

Parameters
$timeSlotId : int
$companyId : int

resolveMode()

Returns the mode used to build the form.

private resolveMode() : string

When opened, the property holds it (set by handleOpen*()); on submit no handleOpen*() ran, so it is read from the hidden POST field. Without that the form would be built with the fields of another mode and the submit would break.

Return values
string

saveBlock()

Saves a block through `save()` with an entity of `type = blocked` (no dedicated Api action; the same path as `TimeSlotFormTrait`).

private saveBlock(array<string, mixed> $values) : Result
Parameters
$values : array<string, mixed>
Return values
Result

saveReservation()

private saveReservation(array<string, mixed> $values) : Result
Parameters
$values : array<string, mixed>
Return values
Result

saveWindow()

Creates a time slot through {@see TimeSlotManager::openWindow()}.

private saveWindow(array<string, mixed> $values) : Result

Unlike saveBlock() it has no input validation of its own: an empty or invalid time and a reversed range are rejected by the Api method with the same message as the other guards.

Parameters
$values : array<string, mixed>
Return values
Result

showModal()

Fills and opens the shared admin modal with the current state.

private showModal() : void

Idempotent: after a submit it is called again and redraws only the inside (the modal stays open, see ModalWindow::open()).

stateOptions()

private stateOptions() : array<string, string>
Return values
array<string, string>

str()

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

strOrNull()

private strOrNull(mixed $value) : string|null
Parameters
$value : mixed
Return values
string|null

text()

Returns final translated text (not a key) for the {@see $notice} buffer and select options.

private text(string $key) : string
Parameters
$key : string
Return values
string

timeActionOptions()

Returns the `timeAction` options as translation keys.

private timeActionOptions() : array<string, string>

Unlike stateOptions() they are not pre-translated: addRadioList() has no setTranslator(null), so the label and items go through the form translator (useDomainTranslator()) automatically. Reuses the keys shorten.submit and split.submit.

Return values
array<string, string>

values()

Returns the form values.

private values(SubmitButton $button) : array<string, mixed>

Uses getUntrustedValues() on purpose: the form has no validation rule at all (pitfall 2 in the class docblock), so this is the only meaningful source and the only one that survives a validation scope.

Parameters
$button : SubmitButton
Return values
array<string, mixed>
On this page

Search results