PluginProbe ʕ •ᴥ•ʔ
OttoKit: All-in-One Automation Platform / 1.1.33
OttoKit: All-in-One Automation Platform v1.1.33
1.1.33 1.1.32 1.1.31 1.1.30 1.1.29 1.1.28 1.1.27 1.1.9 trunk 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.47 1.0.48 1.0.49 1.0.50 1.0.51 1.0.52 1.0.53 1.0.54 1.0.55 1.0.56 1.0.57 1.0.58 1.0.59 1.0.60 1.0.61 1.0.62 1.0.63 1.0.64 1.0.65 1.0.66 1.0.67 1.0.68 1.0.69 1.0.7 1.0.70 1.0.71 1.0.72 1.0.73 1.0.74 1.0.75 1.0.76 1.0.77 1.0.78 1.0.79 1.0.8 1.0.80 1.0.81 1.0.82 1.0.83 1.0.84 1.0.85 1.0.86 1.0.87 1.0.88 1.0.89 1.0.9 1.0.90 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.20 1.1.21 1.1.22 1.1.23 1.1.24 1.1.25 1.1.26 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8
suretriggers / src / Integrations / fluent-booking / actions / create-booking-pro.php
suretriggers / src / Integrations / fluent-booking / actions Last commit date
cancel-booking.php 10 months ago create-booking-pro.php 9 months ago create-booking.php 10 months ago get-booking-details.php 10 months ago update-booking-status.php 10 months ago
create-booking-pro.php
432 lines
1 <?php
2 /**
3 * CreateBookingPro.
4 * php version 5.6
5 *
6 * @category CreateBookingPro
7 * @package SureTriggers
8 * @author BSF <username@example.com>
9 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
10 * @link https://www.brainstormforce.com/
11 * @since 1.1.8
12 */
13
14 namespace SureTriggers\Integrations\FluentBooking\Actions;
15
16 use Exception;
17 use SureTriggers\Integrations\AutomateAction;
18 use SureTriggers\Traits\SingletonLoader;
19
20 /**
21 * CreateBookingPro
22 *
23 * @category CreateBookingPro
24 * @package SureTriggers
25 * @author BSF <username@example.com>
26 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
27 * @link https://www.brainstormforce.com/
28 * @since 1.1.5
29 */
30 class CreateBookingPro extends AutomateAction {
31
32 /**
33 * Integration type.
34 *
35 * @var string
36 */
37 public $integration = 'FluentBooking';
38
39 /**
40 * Action name.
41 *
42 * @var string
43 */
44 public $action = 'fluent_booking_create_booking_pro';
45
46 use SingletonLoader;
47
48 /**
49 * Register a action.
50 *
51 * @param array $actions actions.
52 * @return array
53 */
54 public function register( $actions ) {
55 $actions[ $this->integration ][ $this->action ] = [
56 'label' => __( 'Create Booking (Pro)', 'suretriggers' ),
57 'action' => $this->action,
58 'function' => [ $this, 'action_listener' ],
59 ];
60
61 return $actions;
62 }
63
64 /**
65 * Action listener.
66 *
67 * @param int $user_id user_id.
68 * @param int $automation_id automation_id.
69 * @param array $fields fields.
70 * @param array $selected_options selected_options.
71 *
72 * @return array|void
73 *
74 * @throws Exception Exception.
75 */
76 public function _action_listener( $user_id, $automation_id, $fields, $selected_options ) {
77
78 if ( ! defined( 'FLUENT_BOOKING_VERSION' ) ) {
79 return [
80 'status' => 'error',
81 'message' => __( 'FluentBooking is not installed or activated.', 'suretriggers' ),
82 ];
83 }
84
85 // Check for pro version.
86 if ( ! defined( 'FLUENT_BOOKING_PRO_VERSION' ) ) {
87 return [
88 'status' => 'error',
89 'message' => __( 'FluentBooking Pro is required for this action.', 'suretriggers' ),
90 ];
91 }
92
93 if ( ! class_exists( 'FluentBooking\App\Services\BookingService' ) ) {
94 return [
95 'status' => 'error',
96 'message' => __( 'FluentBooking BookingService class not found.', 'suretriggers' ),
97 ];
98 }
99
100 if ( ! class_exists( 'FluentBooking\App\Models\CalendarSlot' ) ) {
101 return [
102 'status' => 'error',
103 'message' => __( 'FluentBooking CalendarSlot model not found.', 'suretriggers' ),
104 ];
105 }
106
107 if ( ! class_exists( 'FluentBooking\App\Services\DateTimeHelper' ) ) {
108 return [
109 'status' => 'error',
110 'message' => __( 'FluentBooking DateTimeHelper service not found.', 'suretriggers' ),
111 ];
112 }
113
114 if ( ! class_exists( 'FluentBooking\App\Services\Helper' ) ) {
115 return [
116 'status' => 'error',
117 'message' => __( 'FluentBooking Helper service not found.', 'suretriggers' ),
118 ];
119 }
120
121 $event_id = isset( $selected_options['event_id'] ) ? intval( $selected_options['event_id'] ) : 0;
122 $name = isset( $selected_options['name'] ) ? sanitize_text_field( $selected_options['name'] ) : '';
123 $email = isset( $selected_options['email'] ) ? sanitize_email( $selected_options['email'] ) : '';
124 $start_time = isset( $selected_options['start_time'] ) ? sanitize_text_field( $selected_options['start_time'] ) : '';
125 $timezone = isset( $selected_options['timezone'] ) ? sanitize_text_field( $selected_options['timezone'] ) : 'UTC';
126 $phone = isset( $selected_options['phone'] ) ? sanitize_text_field( $selected_options['phone'] ) : '';
127 $message = isset( $selected_options['message'] ) ? sanitize_textarea_field( $selected_options['message'] ) : '';
128 $status = isset( $selected_options['status'] ) ? sanitize_text_field( $selected_options['status'] ) : 'scheduled';
129 $host_user_id = isset( $selected_options['host_user_id'] ) ? intval( $selected_options['host_user_id'] ) : null;
130
131 if ( empty( $event_id ) || empty( $name ) || empty( $email ) || empty( $start_time ) ) {
132 return [
133 'status' => 'error',
134 'message' => __( 'Event ID, Name, Email, and Start Time are required.', 'suretriggers' ),
135 ];
136 }
137
138 if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
139 return [
140 'status' => 'error',
141 'message' => __( 'Invalid email address provided.', 'suretriggers' ),
142 ];
143 }
144
145 try {
146 $calendar_slot = \FluentBooking\App\Models\CalendarSlot::find( $event_id );
147
148 if ( ! $calendar_slot ) {
149 return [
150 'status' => 'error',
151 'message' => sprintf( __( 'Calendar event not found with ID: %d', 'suretriggers' ), $event_id ),
152 ];
153 }
154
155 if ( 'active' !== $calendar_slot->status ) {
156 return [
157 'status' => 'error',
158 'message' => __( 'This calendar event is not accepting bookings.', 'suretriggers' ),
159 ];
160 }
161
162 // Get event location settings to determine link generation.
163 $location_settings = $calendar_slot->location_settings;
164 $primary_location = ! empty( $location_settings ) ? $location_settings[0] : null;
165
166 $start_time_utc = \FluentBooking\App\Services\DateTimeHelper::convertToUtc( $start_time, $timezone );
167 $duration = $calendar_slot->getDuration();
168 $end_time_utc = gmdate( 'Y-m-d H:i:s', strtotime( $start_time_utc ) + ( $duration * 60 ) );
169
170 $booking_data = [
171 'event_id' => $event_id,
172 'calendar_id' => $calendar_slot->calendar_id,
173 'host_user_id' => $host_user_id ? $host_user_id : $calendar_slot->user_id,
174 'name' => $name,
175 'email' => $email,
176 'phone' => $phone,
177 'message' => $message,
178 'person_time_zone' => $timezone,
179 'start_time' => $start_time_utc,
180 'end_time' => $end_time_utc,
181 'slot_minutes' => $duration,
182 'status' => $status,
183 'source' => 'automation_pro',
184 'event_type' => $calendar_slot->event_type,
185 'ip_address' => \FluentBooking\App\Services\Helper::getIp(),
186 ];
187
188 if ( $primary_location ) {
189 $location_type = $primary_location['type'];
190
191 if ( 'google_meet' === $location_type || 'zoom_meeting' === $location_type ) {
192 $location_details = [ 'type' => $location_type ];
193
194 switch ( $location_type ) {
195 case 'google_meet':
196 $meet_link = $this->generate_google_meet_link( $booking_data, $host_user_id ? $host_user_id : $calendar_slot->user_id, $calendar_slot );
197 if ( $meet_link ) {
198 $location_details['online_platform_link'] = $meet_link;
199 $location_details['description'] = $meet_link;
200 }
201 break;
202
203 case 'zoom_meeting':
204 $zoom_link = $this->generate_zoom_meeting_link( $booking_data, $host_user_id ? $host_user_id : $calendar_slot->user_id, $calendar_slot );
205 if ( $zoom_link ) {
206 $location_details['online_platform_link'] = $zoom_link;
207 $location_details['description'] = $zoom_link;
208 }
209 break;
210 }
211
212 $booking_data['location_details'] = $location_details;
213 } else {
214 if ( class_exists( 'FluentBooking\App\Services\LocationService' ) ) {
215 $booking_data['location_details'] = \FluentBooking\App\Services\LocationService::getLocationDetails( $calendar_slot, [], $booking_data );
216 } else {
217 $booking_data['location_details'] = [
218 'type' => $location_type,
219 'description' => isset( $primary_location['description'] ) ? $primary_location['description'] : '',
220 ];
221 }
222 }
223 }
224
225 $booking = \FluentBooking\App\Services\BookingService::createBooking( $booking_data, $calendar_slot );
226
227 if ( is_wp_error( $booking ) ) {
228 return [
229 'status' => 'error',
230 'message' => $booking->get_error_message(),
231 ];
232 }
233
234 $response_data = [
235 'success' => true,
236 'message' => 'Booking created successfully with pro features',
237 'booking_id' => $booking->id,
238 'booking' => $booking->toArray(),
239 ];
240
241 // Add meeting links to response if generated.
242 if ( isset( $location_details['online_platform_link'] ) ) {
243 $response_data['meeting_link'] = $location_details['online_platform_link'];
244 $response_data['location_type'] = $location_details['type'];
245 }
246
247 return $response_data;
248
249 } catch ( Exception $e ) {
250 return [
251 'status' => 'error',
252 'message' => __( 'Failed to create booking: ', 'suretriggers' ) . $e->getMessage(),
253 ];
254 }
255 }
256
257 /**
258 * Generate Google Meet link for the booking.
259 *
260 * @param array $booking_data The booking data.
261 * @param int $user_id The host user ID.
262 * @param object $calendar_slot The calendar slot object.
263 * @return string|null The Google Meet link or null if failed.
264 */
265 private function generate_google_meet_link( $booking_data, $user_id, $calendar_slot ) {
266 try {
267 // Check if Google Calendar integration is available.
268 if ( ! class_exists( 'FluentBookingPro\App\Services\Integrations\Calendars\Google\GoogleHelper' ) ) {
269 return null;
270 }
271
272 // Get Google Calendar client for the user.
273 $google_client = \FluentBookingPro\App\Services\Integrations\Calendars\Google\GoogleHelper::getApiClientByUserId( $user_id );
274
275 if ( ! $google_client ) {
276 // Fallback: Generate a basic Google Meet link.
277 return 'https://meet.google.com/' . $this->generate_meet_id();
278 }
279
280 // Prepare event data for Google Calendar with Meet integration.
281 $host_user = get_userdata( $user_id );
282 $host_name = $host_user ? $host_user->display_name : 'Host';
283 $event_title = 'Meeting';
284
285 // Try multiple ways to get the event title.
286 if ( is_object( $calendar_slot ) ) {
287 if ( isset( $calendar_slot->title ) && ! empty( $calendar_slot->title ) ) {
288 $event_title = $calendar_slot->title;
289 } elseif ( isset( $calendar_slot->event_title ) && ! empty( $calendar_slot->event_title ) ) {
290 $event_title = $calendar_slot->event_title;
291 } elseif ( isset( $calendar_slot->name ) && ! empty( $calendar_slot->name ) ) {
292 $event_title = $calendar_slot->name;
293 }
294 }
295
296 $event_data = [
297 'summary' => sprintf( '%s meeting between %s and %s', $event_title, $host_name, $booking_data['name'] ),
298 'description' => $booking_data['message'],
299 'start' => [
300 'dateTime' => gmdate( 'c', strtotime( $booking_data['start_time'] ) ),
301 ],
302 'end' => [
303 'dateTime' => gmdate( 'c', strtotime( $booking_data['end_time'] ) ),
304 ],
305 'attendees' => [
306 [
307 'email' => $booking_data['email'],
308 ],
309 ],
310 'conferenceData' => [
311 'createRequest' => [
312 'requestId' => 'meet_' . uniqid(),
313 'conferenceSolutionKey' => [
314 'type' => 'hangoutsMeet',
315 ],
316 ],
317 ],
318 ];
319
320 // Create the event with Google Meet.
321 $created_event = $google_client->createEvent( 'primary', $event_data );
322
323 if ( $created_event && isset( $created_event['conferenceData']['entryPoints'] ) ) {
324 foreach ( $created_event['conferenceData']['entryPoints'] as $entry_point ) {
325 if ( 'video' === $entry_point['entryPointType'] ) {
326 return $entry_point['uri'];
327 }
328 }
329 }
330 return 'https://meet.google.com/' . $this->generate_meet_id();
331
332 } catch ( Exception $e ) {
333 return 'https://meet.google.com/' . $this->generate_meet_id();
334 }
335 }
336
337 /**
338 * Generate Zoom meeting link for the booking.
339 *
340 * @param array $booking_data The booking data.
341 * @param int $user_id The host user ID.
342 * @param object $calendar_slot The calendar slot object.
343 * @return string|null The Zoom meeting link or null if failed.
344 */
345 private function generate_zoom_meeting_link( $booking_data, $user_id, $calendar_slot ) {
346 try {
347 // Check if Zoom integration is available.
348 if ( ! class_exists( 'FluentBookingPro\App\Services\Integrations\ZoomMeeting\ZoomHelper' ) ) {
349 return null;
350 }
351
352 // Get Zoom client for the user.
353 $zoom_client = \FluentBookingPro\App\Services\Integrations\ZoomMeeting\ZoomHelper::getZoomClient( $user_id );
354
355 if ( is_wp_error( $zoom_client ) || ! $zoom_client ) {
356 return null;
357 }
358
359 // Prepare meeting data for Zoom.
360 $host_user = get_userdata( $user_id );
361 $host_name = $host_user ? $host_user->display_name : 'Host';
362 $event_title = 'Meeting'; // Default fallback.
363
364 // Try multiple ways to get the event title.
365 if ( is_object( $calendar_slot ) ) {
366 if ( isset( $calendar_slot->title ) && ! empty( $calendar_slot->title ) ) {
367 $event_title = $calendar_slot->title;
368 } elseif ( isset( $calendar_slot->event_title ) && ! empty( $calendar_slot->event_title ) ) {
369 $event_title = $calendar_slot->event_title;
370 } elseif ( isset( $calendar_slot->name ) && ! empty( $calendar_slot->name ) ) {
371 $event_title = $calendar_slot->name;
372 }
373 }
374
375 $meeting_data = [
376 'topic' => sprintf( '%s meeting between %s and %s', $event_title, $host_name, $booking_data['name'] ),
377 'type' => 2,
378 'start_time' => gmdate( 'Y-m-d\TH:i:s\Z', strtotime( $booking_data['start_time'] ) ),
379 'duration' => intval( $booking_data['slot_minutes'] ),
380 'agenda' => $booking_data['message'],
381 'settings' => [
382 'host_video' => true,
383 'participant_video' => true,
384 'join_before_host' => false,
385 'mute_upon_entry' => false,
386 ],
387 ];
388
389 // Create the Zoom meeting.
390 $meeting = $zoom_client->createMeeting( $meeting_data );
391
392 if ( ! is_wp_error( $meeting ) && isset( $meeting['join_url'] ) ) {
393 return $meeting['join_url'];
394 }
395
396 return null;
397
398 } catch ( Exception $e ) {
399 return null;
400 }
401 }
402
403
404 /**
405 * Generate a random Google Meet ID.
406 *
407 * @return string Random meet ID.
408 */
409 private function generate_meet_id() {
410 $chars = 'abcdefghijklmnopqrstuvwxyz';
411 $meet_id = '';
412
413 for ( $i = 0; $i < 3; $i++ ) {
414 $meet_id .= $chars[ wp_rand( 0, 25 ) ];
415 }
416 $meet_id .= '-';
417
418 for ( $i = 0; $i < 4; $i++ ) {
419 $meet_id .= $chars[ wp_rand( 0, 25 ) ];
420 }
421 $meet_id .= '-';
422
423 for ( $i = 0; $i < 3; $i++ ) {
424 $meet_id .= $chars[ wp_rand( 0, 25 ) ];
425 }
426
427 return $meet_id;
428 }
429 }
430
431 CreateBookingPro::get_instance();
432