Skip to main content
Version: 2.0.0

Developer API

Booking Hub is built to be themed: the CP handles service configuration and reservation management, while the public booking form is a set of theme templates a developer wires up against the plugin's services and Twig helpers.

Frontend templates

Booking Hub registers its own frontend template root (bookinghub/...) with starter templates under templates/frontend/services/ — an index (service picker / booking flow), summary, and success page, plus a customer account tab (templates/frontend/customer/account/reservations.twig) when customer account integration is enabled.

These ship intentionally minimal — they extend the shared yui/layouts/* layout and load the plugin's compiled CSS via the craft.getCssStyleContent() helper, but the actual booking UI (service list, date/slot picker, form markup) is left for the site's theme to build against the plugin's services below. Read more on the shared theme structure at craftdocs.yui.sk/docs/frontend/theme-structure.

The site routes behind these templates — booking-hub/services, booking-hub/services/reserve, the per-service get-dates availability endpoints, and so on — are only registered while the plugin itself is enabled (Booking Hub → Settings → General). With the plugin disabled, those routes 404 and the theme's booking pages have nothing to call. The YSCP account routes (booking-hub/account/*) are the one exception — they're registered whenever YSCP support is on, independent of that toggle.

Twig variable and helpers

Booking Hub attaches a craft.bookinghub behavior (Yui\BookingHub\web\twig\CraftVariableBehavior) to the global craft variable, plus a small extension registered directly on Twig:

{# Inline/minified CSS for a compiled asset path or a raw CSS string #}
{{ craft.getCssStyleContent(bookingServicesCssUrl)|raw }}

{# The configured store address, as an array or a formatted string #}
{% set address = craft.bookinghub.getStoreAddress(true) %}

{# Renders a settings-configured agreement text with a {link} placeholder
swapped for the linked entry's URL #}
{{ craft.bookinghub.getAgreementLabel(agreementText, agreementPageId) }}

{# Minutes -> human-readable duration, e.g. "90" -> "1h 30min" #}
{{ 90|formatDuration }}
{{ formatDuration(90) }}

{# Whether the nystudio107 Minify plugin is installed and active #}
{% if isMinifyEnabled() %}...{% endif %}

Service types and availability

Every service is one of two types, each with its own service class under Yui\BookingHub\services\types:

  • EventServicegetAvailableDates(int $eventId, string $date = null) returns the remaining bookable occurrences/seats for a fixed-schedule event; getParticipantsById(int $id) lists who has already reserved a seat.
  • AppointmentServicegetAvailableSlots(int $appointmentId, string $date = null) returns the open time slots for a given day, generated from the service's duration and the business hours/lunch break/holiday configuration in Settings; generateAppointmentTimeSlots() (re)builds the slot set when a service's schedule changes.

Both funnel into ReservationService, the shared entry point for creating and querying bookings regardless of type — used by the CP and the customer account tab alike:

use Yui\BookingHub\Plugin;

$reservationService = Plugin::getInstance()->getReservation();

// Reservations for the logged-in customer / a guest by email
$mine = $reservationService->getCustomerReservations($customerId);
$guest = $reservationService->getGuestReservations($email);

// Upcoming vs already-happened bookings
$active = $reservationService->getActiveReservations();
$past = $reservationService->getPastReservations();

// Save a new booking (validates availability/overlaps before saving)
$reservationService->save($reservationModel);

$reservationService->cancelReservation($reservationId);

Cancellation rules

Each event/appointment service can define whether it's cancellable and, if so, a cutoff window before the start time. ReservationService::getCancellationMinutes() returns how many minutes remain before that cutoff for a given reservation's start date, so a theme can show or hide a "Cancel" button without duplicating the rule.

Console commands

Two reservation reminder jobs are meant to run on a schedule (cron), and one diagnostic command:

# Reminder shortly before a reservation, per the lead time in Settings
* /15 * * * * /path/to/craft bookinghub/reservations/send-notifications

# Optional "reminder before a future/recurring event" pass
0 6 * * * /path/to/craft bookinghub/reservations/send-future-notifications

# Verify the plugin is installed, its tables exist, and report status
./craft bookinghub/plugin/validate

Both notification commands accept an optional --siteId for multi-site installs and log failures through the plugin's own error log (Plugin::error()) rather than failing the cron run.

Editions and licensing

Booking Hub ships three editions — small, medium, enterprise — gating feature availability by license tier. License validation and the CP license screen reuse the shared yui\craftcore license infrastructure (see the platform's own developer docs for the general license/entitlement model); Booking Hub's LicenseService is the plugin-specific entry point into it.