PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
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 6 months ago AmeliaCatalogBookingElementorWidget.php 2 weeks ago AmeliaCatalogElementorWidget.php 6 months ago AmeliaEventsCalendarBookingElementorWidget.php 2 weeks ago AmeliaEventsElementorWidget.php 2 weeks ago AmeliaEventsListBookingButtonElementorWidget.php 2 weeks ago AmeliaEventsListBookingElementorWidget.php 2 weeks ago AmeliaStepBookingButtonElementorWidget.php 1 month ago AmeliaStepBookingElementorWidget.php 2 weeks ago ElementorBlock.php 2 weeks ago ElementorSharedShortcodeWidget.php 2 weeks ago
AmeliaEventsListBookingButtonElementorWidget.php
321 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="' . esc_attr($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="' . esc_attr($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="' . esc_attr($settings['start_date'] . ' - ' . $settings['end_date']) . '"';
208 } else {
209 $shortcode .= ' range="' . esc_attr($settings['event_to_show']) . '"';
210 }
211 }
212
213 if (!empty($settings['select_location'])) {
214 $location = $toCsvIds($settings['select_location']);
215 if ($location !== '') {
216 $shortcode .= ' location="' . esc_attr($location) . '"';
217 }
218 }
219
220 if (!empty($settings['select_tag'])) {
221 $tags = is_array($settings['select_tag']) ? $settings['select_tag'] : [$settings['select_tag']];
222 $tags = array_values(array_filter($tags));
223
224 if (!empty($tags)) {
225 $shortcode .= ' tag="';
226 foreach ($tags as $index => $tag) {
227 $shortcode .= ($index === 0 ? '' : ',') . '{' . esc_attr($tag) . '}';
228 }
229 $shortcode .= '"';
230 }
231 }
232
233 if (!empty($settings['show_recurring']) && $settings['show_recurring'] === 'yes') {
234 $shortcode .= ' recurring=1';
235 }
236 }
237
238 $shortcode .= ']';
239
240 echo '<div class="amelia-events-list-booking-button-trigger">';
241
242 ob_start();
243 parent::render();
244 $button_html = ob_get_clean();
245
246 // Remove any existing id attribute before injecting the trigger ID
247 $button_html = preg_replace(
248 '/<a\s+([^>]*?)\s*id="[^"]*"\s*([^>]*?)class="([^"]*elementor-button[^"]*)"/',
249 '<a $1$2class="$3"',
250 $button_html
251 );
252
253 // Inject trigger ID and enforce cursor pointer style on the button link.
254 $button_html = preg_replace_callback(
255 '/<a\s+([^>]*?)class="([^"]*elementor-button[^"]*)"([^>]*)>/',
256 static function ($matches) use ($autoTrigger) {
257 $beforeClass = $matches[1];
258 $afterClass = $matches[3];
259
260 $appendCursor = static function ($styleValue) {
261 if (preg_match('/(^|;)\s*cursor\s*:/i', $styleValue)) {
262 return $styleValue;
263 }
264
265 $styleValue = rtrim($styleValue);
266 if ($styleValue !== '' && substr($styleValue, -1) !== ';') {
267 $styleValue .= ';';
268 }
269
270 return $styleValue . ' cursor: pointer;';
271 };
272
273 $styleUpdated = false;
274
275 $beforeClass = preg_replace_callback(
276 '/\sstyle="([^"]*)"/i',
277 static function ($styleMatch) use (&$styleUpdated, $appendCursor) {
278 $styleUpdated = true;
279 return ' style="' . esc_attr($appendCursor($styleMatch[1])) . '"';
280 },
281 $beforeClass,
282 1
283 );
284
285 if (!$styleUpdated) {
286 $afterClass = preg_replace_callback(
287 '/\sstyle="([^"]*)"/i',
288 static function ($styleMatch) use (&$styleUpdated, $appendCursor) {
289 $styleUpdated = true;
290 return ' style="' . esc_attr($appendCursor($styleMatch[1])) . '"';
291 },
292 $afterClass,
293 1
294 );
295 }
296
297 if (!$styleUpdated) {
298 $afterClass .= ' style="cursor: pointer;"';
299 }
300
301 return '<a ' . $beforeClass
302 . 'class="' . esc_attr($matches[2]) . '"'
303 . ' id="' . esc_attr($autoTrigger) . '"'
304 . $afterClass
305 . '>';
306 },
307 $button_html,
308 1
309 );
310
311 echo $button_html;
312
313 echo '</div>';
314
315 // Keep the legacy shortcode class so existing frontend scans also pick this up.
316 echo '<div class="amelia-step-booking-shortcode amelia-events-list-booking-shortcode" style="display:none">'
317 . $shortcode
318 . '</div>';
319 }
320 }
321