AmeliaBookingButtonRendererTrait.php
2 months ago
AmeliaBookingModule.php
7 months ago
AmeliaCatalogBookingModule.php
1 month ago
AmeliaCatalogModule.php
7 months ago
AmeliaCustomerPanelModule.php
7 months ago
AmeliaEmployeePanelModule.php
7 months ago
AmeliaEventsCalendarModule.php
1 month ago
AmeliaEventsListBookingButtonModule.php
2 months ago
AmeliaEventsListModule.php
1 month ago
AmeliaEventsModule.php
7 months ago
AmeliaSearchModule.php
7 months ago
AmeliaStepBookingButtonModule.php
2 months ago
AmeliaStepBookingModule.php
1 month ago
ModuleMetadata.php
1 month ago
SharedShortcodeModule.php
1 month ago
index.php
1 month ago
AmeliaEventsListBookingButtonModule.php
185 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Divi5Amelia; |
| 4 | |
| 5 | use ET\Builder\Framework\DependencyManagement\Interfaces\DependencyInterface; |
| 6 | use ET\Builder\FrontEnd\Module\Style; |
| 7 | use ET\Builder\Packages\Module\Layout\Components\ModuleElements\ModuleElements; |
| 8 | use ET\Builder\Packages\Module\Options\Element\ElementClassnames; |
| 9 | use ET\Builder\Packages\ModuleLibrary\ModuleRegistration; |
| 10 | use AmeliaBooking\Infrastructure\WP\Translations\LiteBackendStrings; |
| 11 | use WP_Block; |
| 12 | |
| 13 | /** |
| 14 | * Class that handles "Amelia Events List Booking Button" module output in frontend. |
| 15 | */ |
| 16 | class AmeliaEventsListBookingButtonModule implements DependencyInterface |
| 17 | { |
| 18 | use AmeliaBookingButtonRendererTrait; |
| 19 | |
| 20 | private const BUTTON_BASE_CLASS = 'amelia-eventslist-booking-button'; |
| 21 | |
| 22 | /** |
| 23 | * Register module. |
| 24 | */ |
| 25 | public function load() |
| 26 | { |
| 27 | add_action('init', [AmeliaEventsListBookingButtonModule::class, 'registerModule']); |
| 28 | } |
| 29 | |
| 30 | public static function registerModule() |
| 31 | { |
| 32 | $module_json_folder_path = dirname(__DIR__, 1) . '/visual-builder/src/modules/EventsListBookingButton'; |
| 33 | |
| 34 | ModuleRegistration::register_module( |
| 35 | $module_json_folder_path, |
| 36 | [ |
| 37 | 'render_callback' => [AmeliaEventsListBookingButtonModule::class, 'renderCallback'], |
| 38 | ] |
| 39 | ); |
| 40 | } |
| 41 | |
| 42 | /** |
| 43 | * Generate classnames for the module. |
| 44 | */ |
| 45 | public static function module_classnames(array $args): void |
| 46 | { |
| 47 | $classnames_instance = $args['classnamesInstance']; |
| 48 | $attrs = $args['attrs']; |
| 49 | |
| 50 | $classnames_instance->add( |
| 51 | ElementClassnames::classnames([ |
| 52 | 'attrs' => $attrs['module']['decoration'] ?? [], |
| 53 | ]) |
| 54 | ); |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * Module script data. |
| 59 | */ |
| 60 | public static function module_script_data(array $args): void |
| 61 | { |
| 62 | $elements = $args['elements']; |
| 63 | |
| 64 | $elements->script_data([ |
| 65 | 'attrName' => 'module', |
| 66 | ]); |
| 67 | } |
| 68 | |
| 69 | /** |
| 70 | * Module styles. |
| 71 | */ |
| 72 | public static function module_styles(array $args): void |
| 73 | { |
| 74 | $attrs = $args['attrs'] ?? []; |
| 75 | $elements = $args['elements']; |
| 76 | $settings = $args['settings'] ?? []; |
| 77 | |
| 78 | Style::add([ |
| 79 | 'id' => $args['id'], |
| 80 | 'name' => $args['name'], |
| 81 | 'orderIndex' => $args['orderIndex'], |
| 82 | 'storeInstance' => $args['storeInstance'], |
| 83 | 'styles' => [ |
| 84 | // Module styles. |
| 85 | $elements->style([ |
| 86 | 'attrName' => 'module', |
| 87 | 'styleProps' => [ |
| 88 | 'disabledOn' => [ |
| 89 | 'disabledModuleVisibility' => $settings['disabledModuleVisibility'] ?? null, |
| 90 | ], |
| 91 | ], |
| 92 | ]), |
| 93 | // Button styles. |
| 94 | $elements->style([ |
| 95 | 'attrName' => 'button', |
| 96 | ]), |
| 97 | ], |
| 98 | ]); |
| 99 | } |
| 100 | |
| 101 | /** |
| 102 | * Render module HTML output. |
| 103 | */ |
| 104 | public static function renderCallback(array $attrs, string $content, WP_Block $block, ModuleElements $elements): string |
| 105 | { |
| 106 | $auto_trigger = wp_unique_id('amelia-eventslist-booking-btn-'); |
| 107 | |
| 108 | $shortcode = '[ameliaeventslistbooking'; |
| 109 | $shortcode .= ' trigger=' . sanitize_html_class($auto_trigger); |
| 110 | $shortcode .= ' trigger_type=id'; |
| 111 | $shortcode .= ' in_dialog=1'; |
| 112 | |
| 113 | // Preselect/filter parameters |
| 114 | $booking_params = $attrs['booking_params']['innerContent']['desktop']['value'] ?? false; |
| 115 | if ($booking_params === 'on') { |
| 116 | $event = $attrs['events']['innerContent']['desktop']['value'] ?? []; |
| 117 | if ($event && count($event) > 0) { |
| 118 | $shortcode .= ' event=' . implode(',', array_filter(array_map('absint', $event))); |
| 119 | } |
| 120 | |
| 121 | $event_to_show = $attrs['event_to_show']['innerContent']['desktop']['value'] ?? 'all'; |
| 122 | if (count($event) === 0 && $event_to_show !== 'all') { |
| 123 | if ($event_to_show === 'custom') { |
| 124 | $start_date = $attrs['start_date']['innerContent']['desktop']['value'] ?? ''; |
| 125 | $end_date = $attrs['end_date']['innerContent']['desktop']['value'] ?? ''; |
| 126 | |
| 127 | $has_valid_start = $start_date && preg_match('/^\d{4}-\d{2}-\d{2}$/', $start_date); |
| 128 | $has_valid_end = $end_date && preg_match('/^\d{4}-\d{2}-\d{2}$/', $end_date); |
| 129 | |
| 130 | if (!$has_valid_start || !$has_valid_end) { |
| 131 | // Fallback: render without date range filter, or log warning |
| 132 | // For now, skip the range parameter rather than hiding the button |
| 133 | $event_to_show = 'all'; |
| 134 | } else { |
| 135 | $shortcode .= ' range="' . esc_attr($start_date) . ' - ' . esc_attr($end_date) . '"'; |
| 136 | } |
| 137 | } else { |
| 138 | $shortcode .= ' range="' . esc_attr($event_to_show) . '"'; |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | $tag = $attrs['tags']['innerContent']['desktop']['value'] ?? []; |
| 143 | if ($tag && count($tag) > 0) { |
| 144 | $shortcode .= ' tag="' . implode(',', array_map(function ($t) { |
| 145 | return '{' . sanitize_text_field($t) . '}'; |
| 146 | }, $tag)) . '"'; |
| 147 | } |
| 148 | |
| 149 | $recurring = $attrs['recurring']['innerContent']['desktop']['value'] ?? false; |
| 150 | if ($recurring === 'on') { |
| 151 | $shortcode .= ' recurring=1'; |
| 152 | } |
| 153 | |
| 154 | $locations = $attrs['locations']['innerContent']['desktop']['value'] ?? []; |
| 155 | if ($locations && count($locations) > 0) { |
| 156 | $shortcode .= ' location=' . implode(',', array_filter(array_map('absint', $locations))); |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | $shortcode .= ']'; |
| 161 | |
| 162 | // Render shortcode now to preserve quoted attributes (e.g., custom range) reliably. |
| 163 | $shortcode_output = do_shortcode($shortcode); |
| 164 | |
| 165 | $button_html = self::renderTriggerButtonHtml( |
| 166 | $attrs, |
| 167 | $block, |
| 168 | $elements, |
| 169 | $auto_trigger, |
| 170 | self::BUTTON_BASE_CLASS, |
| 171 | LiteBackendStrings::get('event_book_event') |
| 172 | ); |
| 173 | |
| 174 | return self::renderBookingButtonModuleShell( |
| 175 | $attrs, |
| 176 | $block, |
| 177 | $elements, |
| 178 | $button_html, |
| 179 | 'amelia-eventslist-booking-button_wrapper', |
| 180 | $shortcode_output |
| 181 | ); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 |