Add per-embed lesson-type and section options to the booking block
CI / Tests (PHP 8.1) (pull_request) Successful in 47s
CI / Tests (PHP 8.2) (pull_request) Successful in 54s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m51s
CI / Coding Standards (pull_request) Successful in 2m56s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m42s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 47s
CI / Tests (PHP 8.2) (pull_request) Successful in 54s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m51s
CI / Coding Standards (pull_request) Successful in 2m56s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m42s
CI / Build Plugin Zip (pull_request) Skipped
Three sidebar options on the Lesson Booking block, all mirrored as shortcode attributes and carried to the front end as data attributes on #us-booking-app (or as omitted containers): - Lesson type (lessonTypeId / lesson_type) pins the calendar to a single private-lesson type: only the times bookable as it are listed, and it is the only type bookable there, auto-selected on the registration form. A pinned type that is no longer offered says so instead of showing an empty calendar. - Show the lesson-type filter (showTypeFilter / show_filter) drops the "Show Only" control for studios that do not want it. - Sections (displayMode / show) embeds one half of the page — the booking calendar or the student's upcoming lessons — so the two can live on different pages. The script skips the work belonging to a missing half: no availability or catalog request for an upcoming-only embed, no bookings request for a booking-only one. An unrecognised value renders the whole page. The editor preview follows the same setting. Also fixes the expanded filter's first lesson type sharing a line with the "Lesson type" heading — the choices now sit in their own row beneath it. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -9,11 +9,30 @@ use Unsupervised\Schedular\Val;
|
||||
|
||||
class BookingPage {
|
||||
|
||||
/** Booking calendar and the student's upcoming lessons (the default). */
|
||||
public const MODE_BOTH = 'both';
|
||||
|
||||
/** Booking calendar only — no upcoming-lessons panel. */
|
||||
public const MODE_BOOKING = 'booking';
|
||||
|
||||
/** The student's upcoming lessons only — nothing bookable. */
|
||||
public const MODE_UPCOMING = 'upcoming';
|
||||
|
||||
/**
|
||||
* Renders the booking shortcode/block output.
|
||||
*
|
||||
* @param array<int|string, mixed> $atts Block attributes (`loginPageId`) or
|
||||
* shortcode attributes (`login_page_id`).
|
||||
* Supported attributes (block / shortcode form):
|
||||
* - `loginPageId` / `login_page_id` — where logged-out visitors are sent.
|
||||
* - `lessonTypeId` / `lesson_type` — a private-lesson offering id that pins
|
||||
* the calendar to one lesson type: only the times bookable as that type
|
||||
* are listed, and only it can be booked. 0 or absent shows every type.
|
||||
* - `showTypeFilter` / `show_filter` — whether the "Show Only" lesson-type
|
||||
* filter is offered (default true; irrelevant when a type is pinned).
|
||||
* - `displayMode` / `show` — which halves of the page to embed:
|
||||
* {@see self::MODE_BOTH} (default), {@see self::MODE_BOOKING} (calendar
|
||||
* only) or {@see self::MODE_UPCOMING} (the student's lessons only).
|
||||
*
|
||||
* @param array<int|string, mixed> $atts Block or shortcode attributes.
|
||||
*/
|
||||
public function render( array $atts ): string {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
@@ -38,11 +57,42 @@ class BookingPage {
|
||||
wp_enqueue_style( 'us-scheduler' );
|
||||
wp_enqueue_script( 'us-scheduler' );
|
||||
|
||||
$lessonTypeId = absint( Val::int( $atts['lessonTypeId'] ?? $atts['lesson_type'] ?? 0 ) );
|
||||
$showTypeFilter = self::toBool( $atts['showTypeFilter'] ?? $atts['show_filter'] ?? true );
|
||||
|
||||
$mode = self::mode( $atts['displayMode'] ?? $atts['show'] ?? self::MODE_BOTH );
|
||||
$showBooking = self::MODE_UPCOMING !== $mode;
|
||||
$showUpcoming = self::MODE_BOOKING !== $mode;
|
||||
|
||||
ob_start();
|
||||
include USC_PLUGIN_DIR . 'templates/frontend/booking-page.php';
|
||||
return (string) ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalises the display-mode attribute; anything unrecognised embeds the
|
||||
* whole page, so a typo never silently hides half of it.
|
||||
*/
|
||||
private static function mode( mixed $value ): string {
|
||||
$mode = strtolower( trim( Val::string( $value ) ) );
|
||||
|
||||
return in_array( $mode, [ self::MODE_BOOKING, self::MODE_UPCOMING ], true ) ? $mode : self::MODE_BOTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a boolean attribute. Block attributes arrive as real booleans,
|
||||
* shortcode attributes as strings — where the words people actually write
|
||||
* for "off" ("no", "false", "off") are all truthy to PHP, so they are
|
||||
* matched explicitly rather than cast.
|
||||
*/
|
||||
private static function toBool( mixed $value ): bool {
|
||||
if ( is_string( $value ) ) {
|
||||
return ! in_array( strtolower( trim( $value ) ), [ '', '0', 'no', 'false', 'off' ], true );
|
||||
}
|
||||
|
||||
return Val::bool( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* URL the logged-out prompt sends visitors to: the chosen login page when
|
||||
* one is configured (and still exists), otherwise the WordPress login
|
||||
|
||||
Reference in New Issue
Block a user