PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 2.5.0
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v2.5.0
2.5.0 2.4.0 2.3.0 2.2.5 2.2.0 2.1.2 2.1.1 trunk 1.10.0 1.10.01 1.10.02 1.5.0 1.5.01 1.5.02 1.5.1 1.5.10 1.5.20 1.5.21 1.5.22 1.5.23 1.5.24 1.5.25 1.6.0 1.7.0 1.7.1 All 34 releases
fluent-booking / app / Services / Integrations / FluentForms / BookingElement.php

BookingElement.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution 2.5.0, at app/Services/Integrations/FluentForms/BookingElement.php

324 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBooking\App\Services\Integrations\FluentForms;
4
5
6 use FluentBooking\App\App;
7 use FluentBooking\App\Services\CalendarService;
8 use FluentBooking\App\Services\BookingFieldService;
9 use FluentBooking\Framework\Support\Arr;
10 use FluentBooking\App\Services\Helper;
11 use FluentBooking\App\Models\Booking;
12 use FluentBooking\App\Models\Calendar;
13 use FluentBooking\App\Models\CalendarSlot;
14 use FluentBooking\App\Services\DateTimeHelper;
15 use FluentBooking\App\Services\PermissionManager;
16 use FluentBooking\App\Hooks\Handlers\FrontEndHandler;
17 use FluentForm\App\Services\FormBuilder\BaseFieldManager;
18 use FluentForm\Framework\Helpers\ArrayHelper;
19 use FluentBooking\App\Vite;
20
21 class BookingElement extends BaseFieldManager
22 {
23 /**
24 * Wrapper class for repeat element
25 * @var string
26 */
27 protected $wrapperClass = 'fcal_booking_elem';
28
29 public function __construct()
30 {
31 parent::__construct(
32 'fcal_booking',
33 'Calendar Booking',
34 ['booking', 'calendar'],
35 'advanced'
36 );
37
38 add_filter('fluentform/response_render_fcal_booking', array($this, 'renderResponse'), 10, 3);
39 add_filter('fluentform/select_group_component_ajax_options', array($this, 'getCalendarOptions'), 10, 2);
40
41 add_action('fluentform/loading_editor_assets', function () {
42 wp_enqueue_script('fluentcal_ff_editor_extended', FLUENT_BOOKING_URL . 'assets/admin/fluentform.js', [], FLUENT_BOOKING_ASSETS_VERSION, true);
43 });
44 }
45
46 function getComponent()
47 {
48 return [
49 'index' => 20,
50 'element' => 'fcal_booking',
51 'attributes' => array(
52 'name' => 'fcal_booking',
53 'data-type' => 'fcal_booking'
54 ),
55 'settings' => array(
56 'label' => __('Select Appointment Date & Time', 'fluent-booking'),
57 'admin_field_label' => '',
58 'event_id' => '',
59 'booking_calendar' => '',
60 'conditional_logics' => array(),
61 'container_class' => '',
62 'cal_guest_fields' => [
63 'email_field' => '',
64 'name_field' => '',
65 'host_info' => 'show'
66 ],
67 'validation_rules' => array(
68 'required' => [
69 'value' => false,
70 'message' => __('Appointment Date & Time is required', 'fluent-booking'),
71 ],
72 ),
73 ),
74 'editor_options' => array(
75 'title' => __('FluentBooking Field', 'fluent-booking'),
76 'icon_class' => 'el-icon-date',
77 'template' => 'inputCalendar'
78 ),
79 ];
80 }
81
82 public function getGeneralEditorElements()
83 {
84 return [
85 'booking_calendar',
86 'label',
87 'label_placement',
88 'admin_field_label',
89 'event_id',
90 'cal_guest_fields',
91 'validation_rules',
92 ];
93 }
94
95 public function getAdvancedEditorElements()
96 {
97 return [
98 'container_class',
99 'name',
100 'conditional_logics'
101 ];
102 }
103
104 public function getEditorCustomizationSettings()
105 {
106 return [
107 'event_id' => [
108 'template' => 'selectGroup',
109 'label' => __('Select Calendar', 'fluent-booking'),
110 ],
111 'cal_guest_fields' => [
112 'template' => 'CustomSettingsField',
113 'label' => __('Guest Fields', 'fluent-booking'),
114 'componentName' => 'FluentCalNameEmailChoiceComponent'
115 ],
116 ];
117 }
118
119 /**
120 * Compile and echo the html element
121 * @param array $data [element data]
122 * @param object $form [Form Object]
123 * @return void
124 */
125 public function render($data, $form)
126 {
127 $elementName = $data['element'];
128
129 $data['attributes']['class'] = @trim('ff-el-form-control ' . Arr::get($data, 'attributes.class'));
130 $data['attributes']['id'] = $this->makeElementId($data, $form);
131 if ($tabIndex = \FluentForm\App\Helpers\Helper::getNextTabIndex()) {
132 $data['attributes']['tabindex'] = $tabIndex;
133 }
134
135 $ariaRequired = 'false';
136 if (Arr::get($data, 'settings.validation_rules.required.value')) {
137 $ariaRequired = 'true';
138 }
139
140 $slot_id = (int)Arr::get($data, 'settings.event_id');
141
142 $calendarEvent = CalendarSlot::find($slot_id);
143
144 if (!$calendarEvent || !$calendarEvent->calendar) {
145 esc_html_e('Selected Calendar could not be found', 'fluent-booking');
146 return;
147 }
148
149 $isHostEnabled = Arr::get($data, 'settings.cal_guest_fields.host_info', 'hide') == 'show';
150
151 $showHostInfo = $isHostEnabled || Arr::isTrue($calendarEvent->settings, 'multi_duration.enabled');
152
153 [$localizeData, $element_id] = (new FluentFormInit())->getLocalizedData($calendarEvent, $data, $form);
154
155 $localizeData['time_format'] = (Helper::getGlobalSettings())['time_format'];
156
157 $assetUrl = App::getInstance('url.assets');
158
159 Vite::enqueueScript('fluentform-calendar-public', 'ff_public', [], FLUENT_BOOKING_ASSETS_VERSION);
160
161 if (BookingFieldService::hasPhoneNumberField($localizeData['form_fields'])) {
162 Vite::enqueueScript('fluent-booking-phone-field', 'phone_field', [], FLUENT_BOOKING_ASSETS_VERSION);
163 ?>
164 <style>
165 .fcal_phone_wrapper .flag {
166 background: url(<?php echo esc_url($assetUrl.'images/flags_responsive.png'); ?>) no-repeat;
167 background-size: 100%;
168 }
169 </style>
170 <?php
171 }
172
173 wp_localize_script('fluentform-calendar-public', 'fcal_public_vars_' . $element_id, $localizeData);
174
175 wp_localize_script('fluentform-calendar-public', 'fluentCalendarPublicVars',
176 (new FrontEndHandler())->getGlobalVars()
177 );
178
179 $calClass = 'fluentform_calendar_app';
180
181 if ($showHostInfo) {
182 $calClass .= ' fcal_showing_host';
183 } else {
184 $calClass .= ' fcal_not_showing_host';
185 }
186
187 $elMarkup = '<div class="fcal_cal_wrap"><div class="' . esc_attr($calClass) . '" data-element_id="' . esc_attr($element_id) . '"></div></div>';
188 $html = $this->buildElementMarkup($elMarkup, $data, $form);
189 echo apply_filters('fluentform/rendering_field_html_' . $elementName, $html, $data, $form); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $html is escaped before being passed in.
190 }
191
192 public function renderResponse($data, $field, $form_id)
193 {
194 if (is_string($data)) {
195 $data = json_decode($data, true);
196 }
197
198 if (!$data) {
199 return '';
200 }
201
202 $data = (array)$data;
203
204 $text = Arr::get($data, 'start_time') . ' ( ' . Arr::get($data, 'timezone') . ' )';
205
206 if (defined('FLUENTFORM_RENDERING_ENTRY')) {
207
208 $booking = Booking::find(Arr::get($data, 'booking_id'));
209
210 if ($booking && $booking->calendar) {
211 $calendar = $booking->calendar;
212 $html = '<div class="ff_entry_table_wrapper"><table class="ff_entry_table_field ff-table">';
213 $html .= '<tr>';
214 $html .= '<th>' . __('Booking ID', 'fluent-booking') . '</th>';
215 $html .= '<td>' . $booking->id . ' <a href="' . Helper::getAppBaseUrl('scheduled-events?period=upcoming&booking_id=' . $booking->id) . '" target="_blank">View Booking</a></td>';
216 $html .= '</tr>';
217 $html .= '<tr>';
218 $html .= '<th>' . __('Booking Status', 'fluent-booking') . '</th>';
219 $html .= '<td>' . $booking->status . '</td>';
220 $html .= '</tr>';
221 $html .= '<tr>';
222 $html .= '<th>' . __('Date & Time', 'fluent-booking') . '</th>';
223 $html .= '<td>' . $booking->getFullBookingDateTimeText($calendar->author_timezone, true) . ' (' . $calendar->author_timezone . ')</td>';
224 $html .= '</tr>';
225 $html .= '<tr>';
226 $html .= '<th>' . __('Meeting Duration', 'fluent-booking') . '</th>';
227 $html .= '<td>' . $booking->slot_minutes . ' Minutes</td>';
228 $html .= '</tr>';
229 $html .= '<tr>';
230 $html .= '<th>' . __('Meeting Host', 'fluent-booking') . '</th>';
231 $html .= '<td>' . $calendar->title . '</td>';
232 $html .= '</tr>';
233 $html .= '</html></div>';
234 return $html;
235 }
236 }
237
238 return $text;
239 }
240
241 protected function getResponseHtml($response, $fields, $columns)
242 {
243 return __('HTML Response', 'fluent-booking');
244 }
245
246 protected function getResponseAsText($response, $fields, $columns)
247 {
248 return __('Text Response', 'fluent-booking');
249 }
250
251 public function getCalendarOptions($options = [], $requestData = [])
252 {
253 $eventId = (int) Arr::get($requestData, 'fcal_event_id');
254
255 if (!$eventId) {
256 return apply_filters('fluent_booking/ff_editor_calendar_options', CalendarService::getCalendarOptionsByHost());
257 }
258
259 return $this->getMappableFields($eventId);
260 }
261
262 /**
263 * Custom booking fields of an event that a Fluent Forms field can fill.
264 * File, checkbox and terms fields are left out: their stored value contract
265 * (a FluentBooking upload URL, 'Yes', 'Accepted') differs from what Fluent Forms submits.
266 *
267 * @param int $eventId
268 * @return array field name => label
269 */
270 private function getMappableFields($eventId)
271 {
272 $event = CalendarSlot::find($eventId);
273
274 if (!$event || !$event->calendar) {
275 return [];
276 }
277
278 // Same scope as getCalendarOptionsByHost(): Fluent Forms only checks dashboard access.
279 if (!PermissionManager::hasAllCalendarAccess(true) && $event->calendar->user_id != get_current_user_id()) {
280 return [];
281 }
282
283 $fields = [];
284
285 foreach (BookingFieldService::getCustomFields($event, true) as $fieldKey => $field) {
286 if (in_array(Arr::get($field, 'type'), ['file', 'checkbox', 'terms-and-conditions'], true)) {
287 continue;
288 }
289 $fields[$fieldKey] = Arr::get($field, 'label', $fieldKey);
290 }
291
292 return $fields;
293 }
294
295 /**
296 * Build unique ID concatenating form id and name attribute
297 *
298 * @param array $data $form
299 *
300 * @return string for id value
301 */
302 protected function makeElementId($data, $form)
303 {
304 if (isset($data['attributes']['name'])) {
305 $formInstance = \FluentForm\App\Helpers\Helper::$formInstance;
306 if (!empty($data['attributes']['id'])) {
307 return $data['attributes']['id'];
308 }
309 $elementName = $data['attributes']['name'];
310 $elementName = str_replace(['[', ']', ' '], '_', $elementName);
311
312 $suffix = esc_attr($form->id);
313 if ($formInstance > 1) {
314 $suffix = $suffix . '_' . $formInstance;
315 }
316
317 $suffix .= '_' . $elementName;
318
319 return 'ff_' . esc_attr($suffix);
320 }
321 }
322
323 }
324