PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.1
Booking for Appointments and Events Calendar – Amelia v2.4.1
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 8 months ago AmeliaCatalogBookingElementorWidget.php 8 months ago AmeliaCatalogElementorWidget.php 8 months ago AmeliaEventsCalendarBookingElementorWidget.php 2 months ago AmeliaEventsElementorWidget.php 2 months ago AmeliaEventsListBookingButtonElementorWidget.php 3 months ago AmeliaEventsListBookingElementorWidget.php 2 months ago AmeliaStepBookingButtonElementorWidget.php 3 months ago AmeliaStepBookingElementorWidget.php 2 months ago ElementorBlock.php 3 months ago
AmeliaEventsListBookingButtonElementorWidget.php
319 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 return is_array($widgetLabel) ? $widgetLabel['title'] : BackendStrings::get('events_list_booking');
32 }
33
34 public function get_icon()
35 {
36 return 'amelia-logo';
37 }
38
39 public function get_categories()
40 {
41 return ['amelia-elementor'];
42 }
43
44 protected function register_controls()
45 {
46 parent::register_controls();
47
48 $this->update_control(
49 'text',
50 [
51 'default' => BackendStrings::get('event_book_event'),
52 ]
53 );
54
55 $this->remove_control('link');
56 $this->remove_control('button_css_id');
57
58 $this->start_controls_section(
59 'amelia_events_list_booking_options',
60 [
61 'label' => esc_html__('Amelia Events List Options', 'wpamelia'),
62 ]
63 );
64
65 $this->add_control(
66 'preselect',
67 [
68 'label' => BackendStrings::get('filter'),
69 'type' => Controls_Manager::SWITCHER,
70 'default' => false,
71 'label_on' => BackendStrings::get('yes'),
72 'label_off' => BackendStrings::get('no'),
73 ]
74 );
75
76 $this->add_control(
77 'event_to_show',
78 [
79 'label' => BackendStrings::get('event_time_scope'),
80 'type' => Controls_Manager::SELECT,
81 'condition' => ['preselect' => 'yes'],
82 'default' => 'all',
83 'options' => [
84 'all' => BackendStrings::get('all_events'),
85 'future' => BackendStrings::get('future_events'),
86 'past' => BackendStrings::get('past_events'),
87 'custom' => BackendStrings::get('custom_range'),
88 ],
89 ]
90 );
91
92 $this->add_control(
93 'start_date',
94 [
95 'label' => BackendStrings::get('red_start_date'),
96 'type' => Controls_Manager::DATE_TIME,
97 'picker_options' => [
98 'enableTime' => false,
99 'dateFormat' => 'Y-m-d',
100 ],
101 'condition' => [
102 'preselect' => 'yes',
103 'event_to_show' => 'custom'
104 ],
105 ]
106 );
107
108 $this->add_control(
109 'end_date',
110 [
111 'label' => BackendStrings::get('red_end_date'),
112 'type' => Controls_Manager::DATE_TIME,
113 'picker_options' => [
114 'enableTime' => false,
115 'dateFormat' => 'Y-m-d',
116 ],
117 'condition' => [
118 'preselect' => 'yes',
119 'event_to_show' => 'custom'
120 ],
121 ]
122 );
123
124 $this->add_control(
125 'select_event',
126 [
127 'label' => BackendStrings::get('select_event'),
128 'type' => Controls_Manager::SELECT2,
129 'multiple' => true,
130 'options' => AmeliaEventsListBookingElementorWidget::amelia_elementor_get_events(),
131 'condition' => ['preselect' => 'yes'],
132 'placeholder' => BackendStrings::get('show_all_events')
133 ]
134 );
135
136 $this->add_control(
137 'select_tag',
138 [
139 'label' => BackendStrings::get('select_tag'),
140 'type' => Controls_Manager::SELECT2,
141 'multiple' => true,
142 'options' => AmeliaEventsListBookingElementorWidget::amelia_elementor_get_tags(),
143 'condition' => ['preselect' => 'yes'],
144 'placeholder' => BackendStrings::get('show_all_tags')
145 ]
146 );
147
148 $this->add_control(
149 'select_location',
150 [
151 'label' => BackendStrings::get('select_location'),
152 'type' => Controls_Manager::SELECT2,
153 'multiple' => true,
154 'options' => AmeliaEventsListBookingElementorWidget::amelia_elementor_get_locations(),
155 'condition' => ['preselect' => 'yes'],
156 'placeholder' => BackendStrings::get('show_all_locations')
157 ]
158 );
159
160 $this->add_control(
161 'show_recurring',
162 [
163 'label' => BackendStrings::get('recurring_event'),
164 'type' => Controls_Manager::SWITCHER,
165 'condition' => ['preselect' => 'yes'],
166 'default' => false,
167 'label_on' => BackendStrings::get('yes'),
168 'label_off' => BackendStrings::get('no'),
169 ]
170 );
171
172 $this->end_controls_section();
173 }
174
175 protected function render()
176 {
177 $settings = $this->get_settings_for_display();
178
179 $autoTrigger = 'amelia-events-list-booking-btn-' . substr(md5($this->get_id()), 0, 8);
180
181 $shortcode = '[ameliaeventslistbooking';
182 $shortcode .= ' trigger=' . $autoTrigger;
183 $shortcode .= ' trigger_type=id';
184 $shortcode .= ' in_dialog=1';
185
186 $toCsvIds = static function ($value): string {
187 $vals = is_array($value) ? $value : [$value];
188 $vals = array_filter(array_map('absint', $vals));
189
190 return implode(',', $vals);
191 };
192
193 if (!empty($settings['preselect'])) {
194 if (!empty($settings['select_event'])) {
195 $event = $toCsvIds($settings['select_event']);
196 if ($event !== '') {
197 $shortcode .= ' event=' . $event;
198 }
199 } elseif (!empty($settings['event_to_show']) && $settings['event_to_show'] !== 'all') {
200 if ($settings['event_to_show'] === 'custom') {
201 if (empty($settings['start_date']) || empty($settings['end_date'])) {
202 echo BackendStrings::get('notice_for_missing_dates');
203
204 return;
205 }
206
207 $shortcode .= ' range="' . sanitize_text_field((string) $settings['start_date'])
208 . ' - '
209 . sanitize_text_field((string) $settings['end_date']) . '"';
210 } else {
211 $shortcode .= ' range="' . sanitize_key((string) $settings['event_to_show']) . '"';
212 }
213 }
214
215 if (!empty($settings['select_location'])) {
216 $location = $toCsvIds($settings['select_location']);
217 if ($location !== '') {
218 $shortcode .= ' location=' . $location;
219 }
220 }
221
222 if (!empty($settings['select_tag'])) {
223 $tags = is_array($settings['select_tag']) ? $settings['select_tag'] : [$settings['select_tag']];
224 $tags = array_values(array_filter(array_map('sanitize_text_field', $tags)));
225
226 if (!empty($tags)) {
227 $shortcode .= ' tag="{' . implode('},{', $tags) . '}"';
228 }
229 }
230
231 if (!empty($settings['show_recurring']) && $settings['show_recurring'] === 'yes') {
232 $shortcode .= ' recurring=1';
233 }
234 }
235
236 $shortcode .= ']';
237
238 echo '<div class="amelia-events-list-booking-button-trigger">';
239
240 ob_start();
241 parent::render();
242 $button_html = ob_get_clean();
243
244 // Remove any existing id attribute before injecting the trigger ID
245 $button_html = preg_replace(
246 '/<a\s+([^>]*?)\s*id="[^"]*"\s*([^>]*?)class="([^"]*elementor-button[^"]*)"/',
247 '<a $1$2class="$3"',
248 $button_html
249 );
250
251 // Inject trigger ID and enforce cursor pointer style on the button link.
252 $button_html = preg_replace_callback(
253 '/<a\s+([^>]*?)class="([^"]*elementor-button[^"]*)"([^>]*)>/',
254 static function ($matches) use ($autoTrigger) {
255 $beforeClass = $matches[1];
256 $afterClass = $matches[3];
257
258 $appendCursor = static function ($styleValue) {
259 if (preg_match('/(^|;)\s*cursor\s*:/i', $styleValue)) {
260 return $styleValue;
261 }
262
263 $styleValue = rtrim($styleValue);
264 if ($styleValue !== '' && substr($styleValue, -1) !== ';') {
265 $styleValue .= ';';
266 }
267
268 return $styleValue . ' cursor: pointer;';
269 };
270
271 $styleUpdated = false;
272
273 $beforeClass = preg_replace_callback(
274 '/\sstyle="([^"]*)"/i',
275 static function ($styleMatch) use (&$styleUpdated, $appendCursor) {
276 $styleUpdated = true;
277 return ' style="' . esc_attr($appendCursor($styleMatch[1])) . '"';
278 },
279 $beforeClass,
280 1
281 );
282
283 if (!$styleUpdated) {
284 $afterClass = preg_replace_callback(
285 '/\sstyle="([^"]*)"/i',
286 static function ($styleMatch) use (&$styleUpdated, $appendCursor) {
287 $styleUpdated = true;
288 return ' style="' . esc_attr($appendCursor($styleMatch[1])) . '"';
289 },
290 $afterClass,
291 1
292 );
293 }
294
295 if (!$styleUpdated) {
296 $afterClass .= ' style="cursor: pointer;"';
297 }
298
299 return '<a ' . $beforeClass
300 . 'class="' . esc_attr($matches[2]) . '"'
301 . ' id="' . esc_attr($autoTrigger) . '"'
302 . $afterClass
303 . '>';
304 },
305 $button_html,
306 1
307 );
308
309 echo $button_html;
310
311 echo '</div>';
312
313 // Keep the legacy shortcode class so existing frontend scans also pick this up.
314 echo '<div class="amelia-step-booking-shortcode amelia-events-list-booking-shortcode" style="display:none">'
315 . esc_html($shortcode)
316 . '</div>';
317 }
318 }
319