PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.8
Booking for Appointments and Events Calendar – Amelia v2.4.8
2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Infrastructure / WP / Elementor / AmeliaEventsListBookingButtonElementorWidget.php
ameliabooking / src / Infrastructure / WP / Elementor Last commit date
AmeliaBookingElementorWidget.php 1 week ago AmeliaCatalogBookingElementorWidget.php 1 week ago AmeliaCatalogElementorWidget.php 1 week ago AmeliaElementorWhiteLabelHelper.php 1 week ago AmeliaEventsCalendarBookingElementorWidget.php 1 week ago AmeliaEventsElementorWidget.php 1 week ago AmeliaEventsListBookingButtonElementorWidget.php 1 week ago AmeliaEventsListBookingElementorWidget.php 1 week ago AmeliaStepBookingButtonElementorWidget.php 1 week ago AmeliaStepBookingElementorWidget.php 1 week ago ElementorBlock.php 1 week ago ElementorSharedShortcodeWidget.php 2 months ago
AmeliaEventsListBookingButtonElementorWidget.php
326 lines
1 <?php
2
3 /**
4 * @copyright © Melograno Ventures. All rights reserved.
5 * @licence See LICENCE.md for license details.
6 */
7
8 namespace Elementor;
9
10 use AmeliaBooking\Infrastructure\WP\Translations\BackendStrings;
11
12 /**
13 * Class AmeliaEventsListBookingButtonElementorWidget
14 *
15 * Extends the native Elementor Button widget so all standard button controls
16 * are inherited. Event list booking filters are added in a dedicated section.
17 *
18 * @package AmeliaBooking\Infrastructure\WP\Elementor
19 */
20 class AmeliaEventsListBookingButtonElementorWidget extends Widget_Button
21 {
22 public function get_name()
23 {
24 return 'ameliaeventslistbookingbutton';
25 }
26
27 public function get_title()
28 {
29 $widgetLabel = BackendStrings::get('events_list_booking_button_gutenberg_block');
30
31 $title = is_array($widgetLabel) ? $widgetLabel['title'] : BackendStrings::get('events_list_booking');
32
33 return AmeliaElementorWhiteLabelHelper::label($title);
34 }
35
36 public function get_icon()
37 {
38 return AmeliaElementorWhiteLabelHelper::icon();
39 }
40
41 public function get_categories()
42 {
43 return ['amelia-elementor'];
44 }
45
46 protected function register_controls()
47 {
48 parent::register_controls();
49
50 $this->update_control(
51 'text',
52 [
53 'default' => BackendStrings::get('event_book_event'),
54 ]
55 );
56
57 $this->remove_control('link');
58 $this->remove_control('button_css_id');
59
60 $this->start_controls_section(
61 'amelia_events_list_booking_options',
62 [
63 'label' => AmeliaElementorWhiteLabelHelper::label(esc_html__('Amelia Events List Options', 'wpamelia')),
64 ]
65 );
66
67 $this->add_control(
68 'preselect',
69 [
70 'label' => BackendStrings::get('filter'),
71 'type' => Controls_Manager::SWITCHER,
72 'default' => false,
73 'label_on' => BackendStrings::get('yes'),
74 'label_off' => BackendStrings::get('no'),
75 ]
76 );
77
78 $this->add_control(
79 'event_to_show',
80 [
81 'label' => BackendStrings::get('event_time_scope'),
82 'type' => Controls_Manager::SELECT,
83 'condition' => ['preselect' => 'yes'],
84 'default' => 'all',
85 'options' => [
86 'all' => BackendStrings::get('all_events'),
87 'future' => BackendStrings::get('future_events'),
88 'past' => BackendStrings::get('past_events'),
89 'custom' => BackendStrings::get('custom_range'),
90 ],
91 ]
92 );
93
94 $this->add_control(
95 'start_date',
96 [
97 'label' => BackendStrings::get('red_start_date'),
98 'type' => Controls_Manager::DATE_TIME,
99 'picker_options' => [
100 'enableTime' => false,
101 'dateFormat' => 'Y-m-d',
102 ],
103 'condition' => [
104 'preselect' => 'yes',
105 'event_to_show' => 'custom'
106 ],
107 ]
108 );
109
110 $this->add_control(
111 'end_date',
112 [
113 'label' => BackendStrings::get('red_end_date'),
114 'type' => Controls_Manager::DATE_TIME,
115 'picker_options' => [
116 'enableTime' => false,
117 'dateFormat' => 'Y-m-d',
118 ],
119 'condition' => [
120 'preselect' => 'yes',
121 'event_to_show' => 'custom'
122 ],
123 ]
124 );
125
126 $this->add_control(
127 'select_event',
128 [
129 'label' => BackendStrings::get('select_event'),
130 'type' => Controls_Manager::SELECT2,
131 'multiple' => true,
132 'options' => AmeliaEventsListBookingElementorWidget::amelia_elementor_get_events(),
133 'condition' => ['preselect' => 'yes'],
134 'placeholder' => BackendStrings::get('show_all_events')
135 ]
136 );
137
138 $this->add_control(
139 'select_tag',
140 [
141 'label' => BackendStrings::get('select_tag'),
142 'type' => Controls_Manager::SELECT2,
143 'multiple' => true,
144 'options' => AmeliaEventsListBookingElementorWidget::amelia_elementor_get_tags(),
145 'condition' => ['preselect' => 'yes'],
146 'placeholder' => BackendStrings::get('show_all_tags')
147 ]
148 );
149
150 $this->add_control(
151 'select_location',
152 [
153 'label' => BackendStrings::get('select_location'),
154 'type' => Controls_Manager::SELECT2,
155 'multiple' => true,
156 'options' => AmeliaEventsListBookingElementorWidget::amelia_elementor_get_locations(),
157 'condition' => ['preselect' => 'yes'],
158 'placeholder' => BackendStrings::get('show_all_locations')
159 ]
160 );
161
162 $this->add_control(
163 'show_recurring',
164 [
165 'label' => BackendStrings::get('recurring_event'),
166 'type' => Controls_Manager::SWITCHER,
167 'condition' => ['preselect' => 'yes'],
168 'default' => false,
169 'label_on' => BackendStrings::get('yes'),
170 'label_off' => BackendStrings::get('no'),
171 ]
172 );
173
174 $this->end_controls_section();
175 }
176
177 protected function render()
178 {
179 $settings = $this->get_settings_for_display();
180
181 $autoTrigger = 'amelia-events-list-booking-btn-' . substr(md5($this->get_id()), 0, 8);
182
183 $shortcode = '[' . AmeliaElementorWhiteLabelHelper::shortcodeTag(
184 'eventslistbooking',
185 'ameliaeventslistbooking'
186 );
187 $shortcode .= ' trigger="' . esc_attr($autoTrigger) . '"';
188 $shortcode .= ' trigger_type="id"';
189 $shortcode .= ' in_dialog=1';
190
191 $toCsvIds = static function ($value): string {
192 $vals = is_array($value) ? $value : [$value];
193 $vals = array_filter(array_map('absint', $vals));
194
195 return implode(',', $vals);
196 };
197
198 if (!empty($settings['preselect'])) {
199 if (!empty($settings['select_event'])) {
200 $event = $toCsvIds($settings['select_event']);
201 if ($event !== '') {
202 $shortcode .= ' event="' . esc_attr($event) . '"';
203 }
204 } elseif (!empty($settings['event_to_show']) && $settings['event_to_show'] !== 'all') {
205 if ($settings['event_to_show'] === 'custom') {
206 if (empty($settings['start_date']) || empty($settings['end_date'])) {
207 echo BackendStrings::get('notice_for_missing_dates');
208
209 return;
210 }
211
212 $shortcode .= ' range="' . esc_attr($settings['start_date'] . ' - ' . $settings['end_date']) . '"';
213 } else {
214 $shortcode .= ' range="' . esc_attr($settings['event_to_show']) . '"';
215 }
216 }
217
218 if (!empty($settings['select_location'])) {
219 $location = $toCsvIds($settings['select_location']);
220 if ($location !== '') {
221 $shortcode .= ' location="' . esc_attr($location) . '"';
222 }
223 }
224
225 if (!empty($settings['select_tag'])) {
226 $tags = is_array($settings['select_tag']) ? $settings['select_tag'] : [$settings['select_tag']];
227 $tags = array_values(array_filter($tags));
228
229 if (!empty($tags)) {
230 $shortcode .= ' tag="';
231 foreach ($tags as $index => $tag) {
232 $shortcode .= ($index === 0 ? '' : ',') . '{' . esc_attr($tag) . '}';
233 }
234 $shortcode .= '"';
235 }
236 }
237
238 if (!empty($settings['show_recurring']) && $settings['show_recurring'] === 'yes') {
239 $shortcode .= ' recurring=1';
240 }
241 }
242
243 $shortcode .= ']';
244
245 echo '<div class="amelia-events-list-booking-button-trigger">';
246
247 ob_start();
248 parent::render();
249 $button_html = ob_get_clean();
250
251 // Remove any existing id attribute before injecting the trigger ID
252 $button_html = preg_replace(
253 '/<a\s+([^>]*?)\s*id="[^"]*"\s*([^>]*?)class="([^"]*elementor-button[^"]*)"/',
254 '<a $1$2class="$3"',
255 $button_html
256 );
257
258 // Inject trigger ID and enforce cursor pointer style on the button link.
259 $button_html = preg_replace_callback(
260 '/<a\s+([^>]*?)class="([^"]*elementor-button[^"]*)"([^>]*)>/',
261 static function ($matches) use ($autoTrigger) {
262 $beforeClass = $matches[1];
263 $afterClass = $matches[3];
264
265 $appendCursor = static function ($styleValue) {
266 if (preg_match('/(^|;)\s*cursor\s*:/i', $styleValue)) {
267 return $styleValue;
268 }
269
270 $styleValue = rtrim($styleValue);
271 if ($styleValue !== '' && substr($styleValue, -1) !== ';') {
272 $styleValue .= ';';
273 }
274
275 return $styleValue . ' cursor: pointer;';
276 };
277
278 $styleUpdated = false;
279
280 $beforeClass = preg_replace_callback(
281 '/\sstyle="([^"]*)"/i',
282 static function ($styleMatch) use (&$styleUpdated, $appendCursor) {
283 $styleUpdated = true;
284 return ' style="' . esc_attr($appendCursor($styleMatch[1])) . '"';
285 },
286 $beforeClass,
287 1
288 );
289
290 if (!$styleUpdated) {
291 $afterClass = preg_replace_callback(
292 '/\sstyle="([^"]*)"/i',
293 static function ($styleMatch) use (&$styleUpdated, $appendCursor) {
294 $styleUpdated = true;
295 return ' style="' . esc_attr($appendCursor($styleMatch[1])) . '"';
296 },
297 $afterClass,
298 1
299 );
300 }
301
302 if (!$styleUpdated) {
303 $afterClass .= ' style="cursor: pointer;"';
304 }
305
306 return '<a ' . $beforeClass
307 . 'class="' . esc_attr($matches[2]) . '"'
308 . ' id="' . esc_attr($autoTrigger) . '"'
309 . $afterClass
310 . '>';
311 },
312 $button_html,
313 1
314 );
315
316 echo $button_html;
317
318 echo '</div>';
319
320 // Keep the legacy shortcode class so existing frontend scans also pick this up.
321 echo '<div class="amelia-step-booking-shortcode amelia-events-list-booking-shortcode" style="display:none">'
322 . $shortcode
323 . '</div>';
324 }
325 }
326