PluginProbe
Booking Calendar / 11.4
Booking Calendar v11.4
11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 10.11.3 10.11.4 All 201 releases
booking / core / sync / wpbc-gcal-class.php

wpbc-gcal-class.php in Booking Calendar 11.4, at core/sync/wpbc-gcal-class.php

842 lines 44.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @version 1.0
4 * @package Booking Calendar
5 * @subpackage Google Calendar Sync
6 * @category Data Sync
7 *
8 * @author wpdevelop
9 * @link https://wpbookingcalendar.com/
10 * @email info@wpbookingcalendar.com
11 *
12 * @modified 2014.06.27
13 * @since 5.2.0
14 */
15
16 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
17
18 // TODO:
19 // 1: Auto import
20 // 1.1 Write description about the Cron working only on opening some page.
21 // 2. Set assignment of form fields between events and bookings
22 // 3. Test MultiUser conception - During import of all resources - its will require to import only booking resources of the actual user
23 // 3.1 Test auto import paramters for multiuser version, which paramters, like maximum number of events is taken during auto import process... etc...
24 // 4. Test everything and refactor if required.
25
26
27 // Membership - create WP users from the bookins
28 // Unlimited number of bookings
29 // Bookings for specific times
30 // Show cost of specific date inside of the date(s).
31
32 class WPBC_Google_Calendar {
33
34 public $events;
35
36 public $messages_arr;
37
38 private $feed_url;
39 private $booking_gcal_events_from;
40 private $booking_gcal_events_until;
41 private $booking_gcal_events_max;
42 private $booking_gcal_timezone;
43 private $start_of_week;
44 private $error;
45 private $bktype;
46 private $user_id;
47 private $is_silent;
48 function __construct() {
49
50 $this->messages_arr = array();
51 $this->error = '';
52 $this->bktype = 1;
53 $this->is_silent = false;
54 $this->events = array();
55 $user = wpbc_get_current_user();
56 $this->setUserID( $user->ID );
57
58 if ( ! $this->start_of_week = get_option('start_of_week') )
59 $this->start_of_week = 0;
60 }
61
62 public function show_message( $message , $is_spin = false, $is_error = false ) {
63
64 $this->messages_arr[] = $message;
65
66 if ( $this->is_silent )
67 return;
68
69 ?><script type="text/javascript">
70 var my_message = '<?php
71 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
72 echo html_entity_decode( esc_js( $message ),ENT_QUOTES) ; ?>';
73 wpbc_admin_show_message( my_message, '<?php echo ( $is_error ? 'error' : 'info' ); ?>', <?php echo ( $is_error ? '60000' : '3000' ); ?> );
74 </script><?php
75
76 return;
77 //Old:
78 //$message = str_replace("'", '&#039;', $message);
79 $message = esc_js($message);
80
81 ?> <script type="text/javascript"> if (jQuery('#ajax_message').length > 0 ) {
82 <?php if ($is_spin ) { ?>
83 jQuery('#ajax_message').html('<div class="updated ajax_message<?php echo ($is_error?' error':''); ?>" id="ajax_message"><div style="float:left;"><?php echo esc_js( $message ); ?></div><div id="ajax_message_wpbc_spin_loader" class="wpbc_spin_loader"></div></div>');
84 wpbc__spin_loader__mini__show( 'ajax_message_wpbc_spin_loader', {'show_here': {'where': 'inside'}} );
85 <?php } else { ?>
86 jQuery('#ajax_message').html('<div class="updated ajax_message<?php echo ($is_error?' error':''); ?>" id="ajax_message"><?php echo esc_js( $message ); ?></div>');
87 <?php } ?>
88 }</script> <?php
89 }
90
91
92 public function setSilent() {
93 $this->is_silent = true;
94 }
95
96 public function setUserID($user_id) {
97 $this->user_id = $user_id;
98 }
99
100 public function getUserID() {
101 return $this->user_id;
102 }
103
104 public function setUrl( $relative_url ) {
105 $this->feed_url = $relative_url ;
106 // $this->feed_url = 'https://www.google.com' . $relative_url ;
107 }
108
109 public function setResource($param) {
110 $this->bktype = $param;
111 }
112
113 public function getResource() {
114 return $this->bktype;
115 }
116
117 public function getErrorMessage(){
118 return $this->error;
119 }
120 public function set_events_from_with_array( $booking_gcal_events_from ) { // array( 'from type', 'offset', 'offset type' );
121
122 if ($booking_gcal_events_from[0]=='date') {
123 $booking_gcal_events_from_offset = $booking_gcal_events_from[1] ;
124 } else {
125 switch ($booking_gcal_events_from[2]) {
126 case "second":
127 $booking_gcal_events_from_offset = intval( $booking_gcal_events_from[1] );
128 break;
129 case "minute":
130 $booking_gcal_events_from_offset = intval( $booking_gcal_events_from[1] ) * 60 ; // FixIn: 9.7.3.15.
131 break;
132 case "hour":
133 $booking_gcal_events_from_offset = intval( $booking_gcal_events_from[1] ) * 3600 ;
134 break;
135 case "day":
136 $booking_gcal_events_from_offset = intval( $booking_gcal_events_from[1] ) * 86400 ;
137 break;
138 default:
139 $booking_gcal_events_from_offset = intval( $booking_gcal_events_from[1] );
140 }
141 }
142 $booking_gcal_events_from = $booking_gcal_events_from[0];
143
144 $this->set_events_from( $booking_gcal_events_from, $booking_gcal_events_from_offset );
145 }
146
147
148 public function set_events_from( $booking_gcal_events_from, $offset = 0 ){
149
150 switch ( $booking_gcal_events_from ) {
151 //Don't just use time() for 'now', as this will effectively make cache duration 1 second. Instead set to previous minute. Events in Google Calendar cannot be set to precision of seconds anyway
152 case 'now':
153 $this->booking_gcal_events_from = mktime( intval( gmdate( 'H' ) ), intval( gmdate( 'i' ) ), 0, intval( gmdate( 'm' ) ), intval( gmdate( 'j' ) ), intval( gmdate( 'Y' ) ) ) + $offset;
154 break;
155 case 'today':
156 $this->booking_gcal_events_from = mktime( 0, 0, 0, intval( gmdate( 'm' ) ), intval( gmdate( 'j' ) ), intval( gmdate( 'Y' ) ) ) + $offset;
157 break;
158 case 'week':
159 $this->booking_gcal_events_from = mktime( 0, 0, 0, intval( gmdate( 'm' ) ), ( intval( gmdate( 'j' ) ) - intval( gmdate( 'w' ) ) + intval( $this->start_of_week ) ), intval( gmdate( 'Y' ) ) ) + $offset;
160 break;
161 case 'month-start':
162 $this->booking_gcal_events_from = mktime( 0, 0, 0, intval( gmdate( 'm' ) ), 1, intval( gmdate( 'Y' ) ) ) + $offset;
163 break;
164 case 'month-end':
165 $this->booking_gcal_events_from = mktime( 0, 0, 0, intval( gmdate( 'm' ) ) + 1, 1, intval( gmdate( 'Y' ) ) ) + $offset;
166 break;
167 case 'date':
168 $offset = explode('-', $offset);
169 $this->booking_gcal_events_from = mktime( 0, 0, 0, intval( $offset[1] ), intval( $offset[2] ), intval( $offset[0] ) );
170 break;
171 default:
172 $this->booking_gcal_events_from = 0 ; //any - 1970-01-01 00:00
173 }
174 }
175
176
177 public function set_events_until_with_array( $booking_gcal_events_until ) { // array( 'from type', 'offset', 'offset type' );
178
179 if ($booking_gcal_events_until[0]=='date') {
180 $booking_gcal_events_until_offset = $booking_gcal_events_until[1] ;
181 } else {
182 switch ($booking_gcal_events_until[2]) {
183 case "second":
184 $booking_gcal_events_until_offset = intval( $booking_gcal_events_until[1] );
185 break;
186 case "minute":
187 $booking_gcal_events_until_offset = intval( $booking_gcal_events_until[1] ) * 60; // FixIn: 9.8.15.1.
188 break;
189 case "hour":
190 $booking_gcal_events_until_offset = intval( $booking_gcal_events_until[1] ) * 3600;
191 break;
192 case "day":
193 $booking_gcal_events_until_offset = intval( $booking_gcal_events_until[1] ) * 86400;
194 break;
195 default:
196 $booking_gcal_events_until_offset = intval( $booking_gcal_events_until[1] );
197 }
198 }
199 $booking_gcal_events_until = $booking_gcal_events_until[0];
200
201 $this->set_events_until( $booking_gcal_events_until, $booking_gcal_events_until_offset );
202 }
203
204 public function set_events_until( $booking_gcal_events_until, $offset = 0 ){
205
206 switch ( $booking_gcal_events_until ) {
207 case 'now':
208 $this->booking_gcal_events_until = mktime( intval( gmdate( 'H' ) ), intval( gmdate( 'i' ) ), 0, intval( gmdate( 'm' ) ), intval( gmdate( 'j' ) ), intval( gmdate( 'Y' ) ) ) + $offset;
209 break;
210 case 'today':
211 $this->booking_gcal_events_until = mktime( 0, 0, 0, intval( gmdate( 'm' ) ), intval( gmdate( 'j' ) ), intval( gmdate( 'Y' ) ) ) + $offset;
212 break;
213 case 'week':
214 $this->booking_gcal_events_until = mktime( 0, 0, 0, intval( gmdate( 'm' ) ), ( intval( gmdate( 'j' ) ) - intval( gmdate( 'w' ) ) + intval( $this->start_of_week ) ), intval( gmdate( 'Y' ) ) ) + $offset;
215 break;
216 case 'month-start':
217 $this->booking_gcal_events_until = mktime( 0, 0, 0, intval( gmdate( 'm' ) ), 1, intval( gmdate( 'Y' ) ) ) + $offset;
218 break;
219 case 'month-end':
220 $this->booking_gcal_events_until = mktime( 0, 0, 0, intval( gmdate( 'm' ) ) + 1, 1, intval( gmdate( 'Y' ) ) ) + $offset;
221 break;
222 case 'date':
223 $offset = explode('-', $offset);
224 $this->booking_gcal_events_until = mktime( 0, 0, 0, intval( $offset[1] ), intval( $offset[2] ), intval( $offset[0] ) );
225 break;
226 case 'any':
227 $this->booking_gcal_events_until = 2145916800; //any - 2038-01-01 00:00
228 }
229
230 }
231
232 public function set_events_max( $booking_gcal_events_max ){
233 $this->booking_gcal_events_max = intval( $booking_gcal_events_max );
234 }
235
236 public function set_timezone( $booking_gcal_timezone ){
237 $this->booking_gcal_timezone = $booking_gcal_timezone;
238 }
239
240
241 //Convert an ISO date/time to a UNIX timestamp
242 private function iso_to_ts( $iso ) {
243 sscanf( $iso, "%u-%u-%uT%u:%u:%uZ", $year, $month, $day, $hour, $minute, $second );
244 $year = intval((string) $year); // FixIn: 9.6.3.7.
245 $month = intval((string) $month);
246 $day = intval((string) $day);
247 $hour = intval((string) $hour);
248 $minute = intval((string) $minute);
249 $second = intval((string) $second);
250 return mktime( $hour, $minute, $second, $month, $day, $year );
251 }
252
253
254 // Google Calendar Sync
255 function run() {
256
257 // Define some variables //////////////////////////////////////////////
258 $is_send_emeils = 0; // ( ( get_bk_option( 'booking_gcal_is_send_email') == 'On' ) ? 1 : 0 );
259
260 $this->events = array();
261
262 // $url = $this->feed_url;
263 //
264 // // Break the feed URL up into its parts (scheme, host, path, query)
265 // $url_parts = wp_parse_url( $url );
266 //
267 // if (! isset($url_parts['path'])) // Something wrong with URL
268 // return false;
269 //
270 // $scheme_and_host = $url_parts['scheme'] . '://' . $url_parts['host'];
271 //
272 // // Remove the exisitng projection from the path, and replace it with '/full-noattendees'
273 // $path = substr( $url_parts['path'], 0, strrpos( $url_parts['path'], '/' ) ) . '/full-noattendees';
274 //
275 // // Add the default parameters to the querystring (retrieving JSON, not XML)
276 // $query = '?alt=json&singleevents=false&sortorder=ascending&orderby=starttime';
277
278 $gmt_offset = get_option( 'gmt_offset' ) * 3600;
279
280
281 //$this->feed_url = '2bfu44fmv0fu8or1duckjj11mo@group.calendar.google.com';
282
283 $url = 'https://www.googleapis.com/calendar/v3/calendars/' . $this->feed_url . '/events';
284
285 // Google API Key -- public Google API key shared across all plugin users. Currently the shared key is limited to 500,000 requests per day and 5 requests per second.
286 $api_key = get_bk_option( 'booking_gcal_api_key');
287
288 // Set API key
289 $url .= '?key=' . $api_key;
290
291
292 $args['timeMin'] = urlencode( gmdate( 'c', $this->booking_gcal_events_from - $gmt_offset ) );
293
294 $args['timeMax'] = urlencode( gmdate( 'c', $this->booking_gcal_events_until - $gmt_offset ) );
295
296 $args['maxResults'] = $this->booking_gcal_events_max;
297
298 $args['singleEvents'] = 'True'; //'False'; // Each recurrent event will be showing as separate booking. Google Description: Whether to expand recurring events into instances and only return single one-off events and instances of recurring events, but not the underlying recurring events themselves. Optional. The default is False.
299
300 if ( ! empty( $this->booking_gcal_timezone ) )
301 $args['timeZone'] = $this->booking_gcal_timezone;
302
303 $url = add_query_arg( $args, $url );
304
305
306 // //Append the feed specific parameters to the querystring
307 // $query .= '&start-min=' . gmdate( 'Y-m-d\TH:i:s', $this->booking_gcal_events_from - $gmt_offset );
308 // $query .= '&start-max=' . gmdate( 'Y-m-d\TH:i:s', $this->booking_gcal_events_until - $gmt_offset );
309 // $query .= '&max-results=' . $this->booking_gcal_events_max;
310 //
311 // if ( ! empty( $this->booking_gcal_timezone ) )
312 // $query .= '&ctz=' . $this->booking_gcal_timezone;
313 //
314 // //If enabled, use experimental 'fields' parameter of Google Data API, so that only necessary data is retrieved. This *significantly* reduces amount of data to retrieve and process
315 // // $query .= '&fields=entry(title,link[@rel="alternate"],content,gd:where,gd:when,gCal:uid)';
316 //
317 // $url = $scheme_and_host . $path . $query;
318
319 $this->show_message( __('Importing Feed' ,'booking') . ': ' . $url , true );
320 //debuge($url);
321 //Retrieve the feed data
322 $raw_data = wp_remote_get( $url, array(
323 'sslverify' => false, //sslverify is set to false to ensure https URLs work reliably. Data source is Google's servers, so is trustworthy
324 'timeout' => 10 //Increase timeout from the default 5 seconds to ensure even large feeds are retrieved successfully
325 ) );
326
327 //debuge($raw_data);
328
329 //If $raw_data is a WP_Error, something went wrong
330 if ( ! is_wp_error( $raw_data ) ) {
331
332 //If response code isn't 200, something went wrong
333 if ( 200 == $raw_data['response']['code'] ) {
334
335 $this->show_message( __('Data Parsing' ,'booking') , true );
336
337 //Attempt to convert the returned JSON into an array
338 $raw_data = json_decode( $raw_data['body'], true );
339 //debuge($raw_data);
340 //If decoding was successful
341 if ( ! empty( $raw_data ) ) {
342
343 //If there are some entries (events) to process
344 if ( isset( $raw_data['items'] ) ) {
345 //Loop through each event, extracting the relevant information
346 foreach ( $raw_data['items'] as $event ) {
347 //debuge($event);
348 $id = esc_html( $event['id'] );
349 $title = (isset($event['summary']))?esc_html( $event['summary'] ):'';
350 $description = (isset($event['description']))?esc_html( $event['description'] ):'';
351 //$link = esc_url( $event['link'][0]['href'] );
352 $location = (isset($event['location']))?esc_html( $event['location'] ):'';
353
354 if ( isset($event['creator']) && isset($event['creator']['email']) )
355 $event_author_email = esc_html( $event['creator']['email'] );
356 else $event_author_email = '';
357
358
359 if ( isset( $event['start'] ) && isset( $event['end'] ) )
360 list($range_dates, $range_time) = $this->getCommaSeparatedDates( $event['start'], $event['end'] );
361 else
362 continue; // Skip if we gave no dates
363
364 //debuge($range_dates, $range_time);
365 $bktype = $this->getResource();
366
367 // FixIn: 8.6.1.4.
368 // if ( ( class_exists( 'wpdev_bk_biz_s' ) )
369 // && ( get_bk_option( 'booking_range_selection_time_is_active') == 'On' )
370 // && ( get_bk_option( 'booking_ics_import_add_change_over_time' ) !== 'Off' )
371 // && ( get_bk_option( 'booking_ics_import_append_checkout_day' ) !== 'Off' )
372 // ) {
373 if ( 'On' == get_bk_option( 'booking_ics_import_append_checkout_day' ) ) { //FixIn: 2.0.27.1 // FixIn: 9.5.4.1.
374 // Add one additional day to .ics event (useful in some cases for bookings with change-over days),
375 // if the imported .ics dates is coming without check in/our times
376 // Later system is adding check in/out times from Booking Calendar to this event
377 $range_dates_arr = explode( ',', $range_dates );
378 $ics_event_check_out = trim( $range_dates_arr[ ( count( $range_dates_arr ) - 1 ) ] );
379 $ics_event_check_out = explode( '.', $ics_event_check_out );
380 $ics_event_check_out = $ics_event_check_out[2] . '-' . $ics_event_check_out[1] . '-' . $ics_event_check_out[0];
381
382 $ics_event_check_out = strtotime( $ics_event_check_out );
383 $ics_event_check_out = strtotime( '+1 day', $ics_event_check_out );
384 $ics_event_check_out = date_i18n( "d.m.Y", $ics_event_check_out );
385 $range_dates .= ', ' . $ics_event_check_out;
386 }
387
388 // FixIn: 8.6.1.1.
389 if ( empty( $range_time ) ) {
390
391 if ( ( class_exists( 'wpdev_bk_biz_s' ) )
392 && ( get_bk_option( 'booking_range_selection_time_is_active') == 'On' )
393 && ( get_bk_option( 'booking_ics_import_add_change_over_time' ) !== 'Off' )
394 ) { // FixIn: 2.0.5.1.
395 //Add check in/out times to full day events
396 $wpbc_check_in = get_bk_option( 'booking_range_selection_start_time' );// . ':01'; // ' 14:00:01'
397 $wpbc_check_out = get_bk_option( 'booking_range_selection_end_time' ); // . ':02'; // ' 10:00:02';
398 $range_time = $wpbc_check_in . ' - ' . $wpbc_check_out;
399 $range_time = "selectbox-one^rangetime{$bktype}^{$range_time}~";
400 }
401 }
402 //debuge($range_dates, $range_time); // array( [0] => 07.08.2017, 08.08.2017, [1] => selectbox-one^rangetime4^03:00 - 07:00~ )
403
404 $previous_active_user = -1;
405 // MU
406 if ( class_exists('wpdev_bk_multiuser') ) {
407 // Get the owner of this booking resource
408 $user_bk_id = apply_bk_filter('get_user_of_this_bk_resource', false, $bktype );
409
410 // Check if its different user
411 if ( ($user_bk_id !== false) && ($this->getUserID() != $user_bk_id) ){
412 // Get possible other active user settings
413 $previous_active_user = apply_bk_filter('get_client_side_active_params_of_user');
414
415 // Set active user of that specific booking resource
416 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $user_bk_id);
417
418 }
419 }
420
421 $booking_gcal_events_form_fields = get_bk_option( 'booking_gcal_events_form_fields');
422 if ( is_serialized( $booking_gcal_events_form_fields ) )
423 $booking_gcal_events_form_fields = unserialize( $booking_gcal_events_form_fields );
424
425 // MU
426 if ( $previous_active_user !== -1 ) {
427 // Reactivate the previous active user
428 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $previous_active_user );
429 }
430
431
432
433 $booking_gcal_events_form_fields1 = explode('^', $booking_gcal_events_form_fields['title']);
434 $booking_gcal_events_form_fields1 = (empty($booking_gcal_events_form_fields1[1]))?false:true;
435
436 $booking_gcal_events_form_fields2 = explode('^', $booking_gcal_events_form_fields['description']);
437 $booking_gcal_events_form_fields2 = (empty($booking_gcal_events_form_fields2[1]))?false:true;
438
439 $booking_gcal_events_form_fields3 = explode('^', $booking_gcal_events_form_fields['where']);
440 $booking_gcal_events_form_fields3 = (empty($booking_gcal_events_form_fields3[1]))?false:true;
441
442
443 $submit_array = array(
444 'bktype' => $bktype
445 , 'dates' => $range_dates
446 , 'form' => $range_time
447 . (($booking_gcal_events_form_fields1)? trim($booking_gcal_events_form_fields['title'])."{$bktype}^{$title}~" :'')
448 . (($booking_gcal_events_form_fields2)? trim($booking_gcal_events_form_fields['description'])."{$bktype}^{$description}~" :'')
449 . (($booking_gcal_events_form_fields3)? trim($booking_gcal_events_form_fields['where'])."{$bktype}^{$location}" :'')
450
451 // . "text^".trim($booking_gcal_events_form_fields['title'])."{$bktype}^{$title}~"
452 // //. "text^secondname{$bktype}^{$title}~"
453 // //. "email^email{$bktype}^{$title}~"
454 // //."text^phone{$bktype}^{$title}~"
455 // ."textarea^".trim($booking_gcal_events_form_fields['description'])."{$bktype}^{$description}~"
456 // ."text^".trim($booking_gcal_events_form_fields['where'])."{$bktype}^{$location}"
457 , 'is_send_emeils' => $is_send_emeils
458 , 'sync_gid' => $id
459 );
460
461
462 // Add imported data to the array of events
463 $this->events[] = array(
464 // 'id'=>$booking_id
465 'sync_gid' => $id
466 , 'title'=> $title
467 , 'description' => $description
468 , 'location' => $location
469 , 'dates' => $range_dates
470 , 'times' => $range_time
471 , 'booking_submit_data'=>$submit_array
472 );
473 }
474 }
475
476 } else {
477 //json_decode failed
478 $this->error = __( 'Some data was retrieved, but could not be parsed successfully. Please ensure your feed URL is correct.', 'booking' );
479 }
480 } else {
481 //debuge($raw_data['response']['code']);
482 //The response code wasn't 200, so generate a helpful(ish) error message depending on error code
483 switch ( $raw_data['response']['code'] ) {
484 case 404:
485 $this->error = __( 'The feed could not be found (404). Please ensure your feed URL is correct.' ,'booking');
486 break;
487 case 403:
488 $this->error = __( 'Access to this feed was denied (403). Please ensure you have public sharing enabled for your calendar.' ,'booking');
489 break;
490 default:
491 /* translators: 1: ... */
492 $this->error = sprintf( __( 'The feed data could not be retrieved. Error code: %s. Please ensure your feed URL is correct.' ,'booking'), '<strong>' . $raw_data['response']['code'] . '</strong>' );
493
494 if (isset( $raw_data['body'] ))
495 $this->error .= '<br><br><strong>' . esc_html__( 'Info', 'booking' ) . '</strong>: <code>' . $raw_data['body'] . '</code>';
496
497 }
498 }
499 } else {
500
501 //Generate an error message from the returned WP_Error
502 $this->error = $raw_data->get_error_message() ;
503 }
504
505
506 if ( ! empty($this->error) ) {
507 $is_spin = false;
508 $is_error = true;
509 $this->show_message( $this->error , $is_spin, $is_error);
510 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
511 if ( ( isset( $_REQUEST['action'] ) ) && ( 'WPBC_AJX_BOOKING_ACTIONS' == $_REQUEST['action'] ) ) {
512 return false;
513 }
514 die;
515 } else
516 $this->show_message( __('Done' ,'booking') );
517
518
519
520 // Get Already exist same bookings
521 $exist_bookings_guid = $this->getExistBookings_gid( $this->events );
522
523
524 // Create New bookings
525 if (! empty($this->events) )
526 $this->createNewBookingsFromEvents( $exist_bookings_guid );
527
528
529 // Show imported Bookings Table
530 if ( (! empty($this->events) ) && ( ! $this->is_silent ) )
531 $this->showImportedEvents();
532
533
534 return true;
535 }
536
537
538 private function getCommaSeparatedDates( $event_dates_start, $event_dates_end ) {
539
540 if ( isset($event_dates_start['date']) && isset($event_dates_end['date']) ) {
541 //$start_date = date_i18n('Y-m-d', $this->iso_to_ts( $event_dates_start['date'] ) );
542 //$end_date = date_i18n('Y-m-d', ( $this->iso_to_ts( $event_dates_end['date'] ) - 86400 ) );
543 $start_date = $this->iso_to_ts( $event_dates_start['date'] ) ;
544 $end_date = $this->iso_to_ts( $event_dates_end['date'] ) - 86400 ;
545 $range_time = '00:00 - 00:00';
546 }
547
548 if ( isset($event_dates_start['dateTime']) && isset($event_dates_end['dateTime']) ) {
549
550
551 $start_date = $this->iso_to_ts( $event_dates_start['dateTime'] );
552 $end_date = $this->iso_to_ts( $event_dates_end['dateTime'] );
553
554 // FixIn: 8.9.4.2.
555 /**
556 * Check for situation, when we are having times starting or ending at the midnight: 00:00:00
557 * Because in this "IF section" we are checking events dates with times (in the previous "IF section" was FULL day events,
558 * we need to be sure that the event do not start or end at 00:00 Otherwise Booking Calendar will
559 * show such date as fully booked!
560 */
561 $start_date_unix = $start_date;
562 $check_start_date = wpbc_datetime_localized( gmdate( 'Y-m-d H:i:s', $start_date_unix ), 'Y-m-d H:i:s' );
563 if ( substr( $check_start_date, 11 ) === '00:00:00' ) {
564 $start_date_unix = $start_date_unix + 61;
565 $start_date = $start_date_unix;
566 }
567 $end_date_unix = $end_date;
568 $check_end_date = wpbc_datetime_localized( gmdate( 'Y-m-d H:i:s', $end_date_unix ), 'Y-m-d H:i:s' );
569 if ( substr( $check_end_date, 11 ) === '00:00:00' ) {
570 $end_date_unix = $end_date_unix - 2;
571 $end_date = $end_date_unix;
572 }
573
574 $range_time = date_i18n('H:i', $start_date ) . ' - ' . date_i18n('H:i', $end_date );
575
576 //$start_date = date_i18n('Y-m-d', $start_date );
577 //$end_date = date_i18n('Y-m-d', $end_date );
578 }
579
580 $dates_comma = wpbc_get_comma_seprated_dates_from_to_day( date_i18n("d.m.Y", $start_date ), date_i18n("d.m.Y", $end_date ) ) ;
581 //$dates = wpbc_get_dates_array_from_start_end_days($start_date, $end_date );
582
583 //$dates_comma = implode(', ', $dates);
584
585
586 // // Get Times
587 // $start_time = $this->iso_to_ts( $event_dates[0]['startTime'] );
588 //
589 // if ( date_i18n('H:i', $this->iso_to_ts( $event_dates[ (count($event_dates)-1) ]['endTime'] ) ) == '00:00' )
590 // $end_time = $this->iso_to_ts( $event_dates[ (count($event_dates)-1) ]['endTime'] ) - 86400; // 24 hours - 60*60*24 = 86400
591 // else
592 // $end_time = $this->iso_to_ts( $event_dates[ (count($event_dates)-1) ]['endTime'] );
593 //
594 //
595 // $range_time = date_i18n('H:i', $start_time ) . ' - ' . date_i18n('H:i', $end_time );
596 if ( $range_time != '00:00 - 00:00' ) {
597 $bktype = $this->getResource();
598 $range_time = "selectbox-one^rangetime{$bktype}^{$range_time}~";
599 } else
600 $range_time = '';
601
602 return array($dates_comma, $range_time);
603 }
604
605
606 // -----------------------------------------------------------------------------------------------------------------
607 // Create New bookings based on $this->events array.
608 // -----------------------------------------------------------------------------------------------------------------
609 public function createNewBookingsFromEvents( $exist_bookings_guid = array() ) {
610
611 foreach ($this->events as $key => $event) {
612
613 if ( ! in_array( $event['sync_gid'], $exist_bookings_guid ) ) {
614
615 $submit_array = $event['booking_submit_data'];
616
617 // Create a new booking
618 $request_save_params = array(
619 'resource_id' => $submit_array['bktype'], // 2
620 'dates_ddmmyy_csv' => $submit_array['dates'], // '04.10.2023, 05.10.2023, 06.10.2023'
621 'form_data' => $submit_array['form'], // 'text^cost_hint2^150.00฿~selectbox-multiple^rangetime2[]^14:00...'
622 'booking_hash' => '', // 'sdfsf34534rf'
623 'custom_form' => '', // 'custom_form_name'
624 'is_emails_send' => $submit_array['is_send_emeils'], // 0 | 1
625 'is_show_payment_form' => 0, // 0 | 1
626 //'request_uri' => $_SERVER['HTTP_REFERER']
627 //'user_id' => wpbc_get_current_user_id()
628 'sync_gid' => $submit_array['sync_gid'],
629 'is_approve_booking' => intval( 'On' === get_bk_option( 'booking_auto_approve_bookings_when_import' ) ) // Auto approve booking if imported
630 );
631
632 if ( 'On' != get_bk_option( 'booking_condition_import_if_available' ) ) { //FixIn: 9.8.15.8 - 'Import only, if days are available'
633 $request_save_params['save_booking_even_if_unavailable'] = 1;
634 }
635
636 $booking_save_arr = wpbc_booking_save( $request_save_params );
637
638 if ( 'ok' === $booking_save_arr['ajx_data']['status'] ) { // Everything Cool :) - booking has been created
639 $booking_id = $booking_save_arr['booking_id'];
640 $this->events[$key]['id'] = $booking_id;
641
642 // Add notes to the booking relative source of imported booking
643 if ( class_exists( 'wpdev_bk_personal' ) ) {
644 /* translators: 1: ... */
645 $remark_text = '[' . wpbc_datetime_localized( gmdate( 'Y-m-d H:i:s' ), 'Y-m-d H:i:s' ) . '] ' . sprintf( __( 'Imported from %s ', 'booking' ), 'Google Calendar' );
646 $remark_text = str_replace( '%', '&#37;', $remark_text );
647 $remark_text = str_replace( array( '"', "'" ), '', $remark_text );
648 $remark_text = trim( $remark_text );
649 $is_append = true;
650 make_bk_action( 'wpdev_make_update_of_remark', $booking_id, $remark_text, $is_append );
651 }
652
653 } else { // Error
654 // Error message: $booking_save_arr['ajx_data']['ajx_after_action_message'];
655 $parsed_booking_data_arr = wpbc_get_parsed_booking_data_arr( $request_save_params['form_data'], $request_save_params['resource_id'], array( 'get' => 'value' ) );
656
657 $plain_form_data_show = wpbc_get__booking_form_data__show( $request_save_params['form_data'], $request_save_params['resource_id'], array( 'unknown_shortcodes_replace_by' => ' ... ' ) );
658
659 // Replace <p> | <br> to ' '
660 $plain_form_data_show = preg_replace( '/<(br|p)[\t\s]*[\/]?>/i', ' ', $plain_form_data_show );
661
662 // Replace \r \n \t
663 $plain_form_data_show = preg_replace( '/(\\r|\\n|\\t)/i', ' ', $plain_form_data_show );
664
665 $this->error .= '<div style="border:1px solid #ccc;padding:10px 1em;margin:1em 0;">'
666 . '<strong> Google Calendar ' . __( 'Event', 'booking' ) . '</strong> '. 'UID' . ': ' . $request_save_params['sync_gid']
667 . '<hr/>'
668 . ' <span style="color:#8b2122;">' . $booking_save_arr['ajx_data']['ajx_after_action_message'] . '</span>'
669 . '<hr/>'
670 . ' <strong>' . esc_html__( 'Resource', 'booking' ) . ' ID : ' . '</strong>' . $request_save_params['resource_id']
671 . ' <strong>' . esc_html__( 'Dates', 'booking' ) .': ' . '</strong>' . $request_save_params['dates_ddmmyy_csv']
672 . ( ( ! empty( $parsed_booking_data_arr['rangetime'] ) )
673 ? ( ' <strong>' . esc_html__( 'Times', 'booking' ) . ': ' . '</strong>' . $parsed_booking_data_arr['rangetime'] )
674 : ''
675 )
676 //. ' <strong>' . esc_html__( 'Data', 'booking' ) . ': ' . ' </strong>'
677 . $plain_form_data_show
678 . '</div>';
679
680 unset( $this->events[ $key ] );
681 }
682 } else {
683 unset($this->events[$key]);
684 }
685 }
686
687 return $this->events;
688 }
689
690
691 // -----------------------------------------------------------------------------------------------------------------
692 // Get Already exist same bookings
693 // -----------------------------------------------------------------------------------------------------------------
694 public function getExistBookings_gid( $events_array ) {
695
696 $sql_sync_gid = array();
697 foreach ( $events_array as $event ) {
698 $sql_sync_gid[] = $event['sync_gid'];
699 }
700 $sql_sync_gid = implode( "','", $sql_sync_gid );
701
702 $exist_bookings_guid = array();
703
704 $booking_condition_import_only_new = get_bk_option( 'booking_condition_import_only_new' ); // FixIn: 9.8.15.8.
705 if ( ( ! empty( $sql_sync_gid ) ) && ( 'On' === $booking_condition_import_only_new ) ) {
706 global $wpdb;
707 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
708 $exist_bookings = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}booking WHERE sync_gid IN ('{$sql_sync_gid}') AND trash != 1" ); // FixIn: 9.8.15.8.
709 foreach ( $exist_bookings as $bk ) {
710 $exist_bookings_guid[] = $bk->sync_gid;
711 }
712 }
713
714 return $exist_bookings_guid;
715 }
716
717
718 // -----------------------------------------------------------------------------------------------------------------
719 // Show Table of imported Events
720 // -----------------------------------------------------------------------------------------------------------------
721 public function showImportedEvents() {
722 ?>
723 <div id="gcal_imported_events<?php echo esc_attr( $this->getResource() ); ?>" class="table-responsive">
724 <table style="width:99%;margin-top:45px;border:1px solid #ccc;"
725
726 class="resource_table0 booking_table0 table table-striped "
727 cellpadding="0" cellspacing="0">
728 <?php
729
730 if (function_exists ('wpbc_db__get_resource_title')) {
731 echo '<tr><td colspan="6" style="padding:5px 10px;font-style:italic;"> <h4>' , wp_kses_post( wpbc_get_resource_title( $this->getResource() ) ) , '</h4></td></tr>';
732 }
733
734 ?>
735 <?php // Headers ?>
736 <tr>
737 <th style="text-align:center;width:15px;"><input type="checkbox" onclick="javascript:jQuery('#gcal_imported_events<?php echo esc_attr( $this->getResource() ); ?> .events_items').attr('checked', this.checked);" class="" id="events_items_all" name="events_items_all" /></th>
738 <th style="text-align:center;width:10px;height:35px;"> <?php esc_html_e('ID' ,'booking'); ?> </th>
739 <th style="text-align:center;height:35px;width:220px;" style="border-left: 1px solid #ccc;"> <?php esc_html_e('Title' ,'booking'); ?> </th>
740 <th style="text-align:center;"> <?php esc_html_e('Info' ,'booking'); ?> </th>
741 <th style="text-align:center;"> <?php esc_html_e('Dates' ,'booking'); ?> </th>
742 <th style="text-align:center;width:10px;height:35px;"> <?php esc_html_e('GID' ,'booking'); ?> </th>
743 </tr>
744 <?php
745 $alternative_color = '';
746 if (! empty($this->events))
747 foreach ($this->events as $bt) {
748
749 if ( $alternative_color == '' ) {
750 $alternative_color = ' class="alternative_color" ';
751 } else {
752 $alternative_color = '';
753 }
754 ?>
755 <tr id="gcal_imported_events_id_<?php echo esc_attr( $bt['id'] ); ?>">
756 <td <?php
757 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
758 echo $alternative_color; ?> style="border-left: 0;border-right: 1px solid #ccc;">
759 <!-- <span class="wpbc_mobile_legend"><?php esc_html_e('Selection' ,'booking'); ?>:</span>-->
760 <input type="checkbox" class="events_items" id="events_items_<?php echo esc_attr( $bt['id'] ); ?>" value="<?php
761 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
762 echo $bt['id']; ?>" name="events_items_<?php echo esc_attr( $bt['id'] ); ?>" /></td>
763 <td style="border-right: 0;border-left: 1px solid #ccc;text-align: center;" <?php
764 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
765 echo $alternative_color; ?> >
766 <!-- <span class="wpbc_mobile_legend"><?php esc_html_e('ID' ,'booking'); ?>:</span>-->
767 <?php echo esc_attr( $bt['id'] ); ?></td>
768 <td <?php
769 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
770 echo $alternative_color; ?> style="border-right: 0;border-left: 1px solid #ccc;">
771 <!-- <span class="wpbc_mobile_legend"><?php esc_html_e('Title' ,'booking'); ?>:</span>-->
772 <span ><?php echo esc_html( $bt['title'] ); ?></span>
773 </td>
774 <td style="border-right: 0;border-left: 1px solid #ccc;text-align: center;" <?php
775 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
776 echo $alternative_color; ?> >
777 <!-- <span class="wpbc_mobile_legend"><?php esc_html_e('Info' ,'booking'); ?>:</span>-->
778 <span ><?php echo esc_html( $bt['description'] ); ?></span><br/>
779 <?php
780 if ( ! empty( $bt['location'] ) ) {
781 echo wp_kses_post( '<span >' . esc_html__( 'Location:', 'booking' ) . ': ' . $bt['location'] . '</span>' );
782 }
783 ?>
784 </td>
785
786 <td style="border-right: 0;border-left: 1px solid #ccc;text-align: center;" <?php
787 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
788 echo $alternative_color; ?> >
789 <span class="wpbc-listing-collumn booking-dates field-dates field-booking-date">
790 <!-- <span class="wpbc_mobile_legend"><?php esc_html_e('Dates' ,'booking'); ?>:</span>-->
791 <div class="booking_dates_full" ><?php
792 $bt['dates'] = explode(', ', $bt['dates']);
793 foreach ($bt['dates'] as $keyd=>$valued) {
794
795 $valued = explode( '.', $valued );
796 $valued = wpbc_get_date_in_correct_format( sprintf("%04d-%02d-%02d" ,$valued[2], $valued[1], $valued[0] ) ) ;
797
798 $bt['dates'][$keyd] = '<a href="javascript:void(0)" class="field-booking-date">' . $valued[0] . '</a>';
799 }
800 $bt['dates'] = implode('<span class="date_tire">, </span>', $bt['dates']);
801 echo wp_kses_post( $bt['dates'] );//date_i18n('d.m.Y H:i',$bt['start_time'] ), ' - ', date_i18n('d.m.Y H:i',$bt['end_time']); ?>
802 </div>
803 </span>
804 </td>
805 <td style="border-right: 0;border-left: 1px solid #ccc;text-align: center;" <?php
806 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
807 echo $alternative_color; ?> >
808 <!-- <span class="wpbc_mobile_legend"><?php esc_html_e('GID' ,'booking'); ?>:</span>-->
809 <?php echo wp_kses_post( $bt['sync_gid'] ); ?></td>
810 </tr>
811 <?php } ?>
812
813 <tr class="wpbc_table_footer">
814 <td colspan="6" style="text-align: center;">
815 <a href="javascript:void(0)" class="button button-primary" style="float:none;margin:10px;"
816 onclick="javascript:location.reload();" ><?php esc_html_e('Reload page' ,'booking'); ?></a>
817 <a href="javascript:void(0)" class="button" style="float:none;margin:10px;"
818 onclick="javascript:jQuery('#gcal_imported_events<?php echo esc_attr( $this->getResource() ); ?>').remove();" ><?php esc_html_e('Hide' ,'booking'); ?></a>
819 <a href="javascript:void(0)" class="button" style="float:none;margin:10px;"
820 onclick="javascript: if ( wpbc_are_you_sure('<?php echo esc_js(__('Do you really want to delete selected booking(s) ?' ,'booking')); ?>') ) {
821 //delete_booking(
822 trash__restore_booking( 1, <?php //FixIn: 7.0.1 ?>
823 get_selected_bookings_id_in_this_list('#gcal_imported_events<?php echo esc_attr( $this->getResource() ); ?> .events_items', 13)
824 , <?php echo esc_attr( $this->getUserID() ); ?>
825 , '<?php echo esc_attr( wpbc_get_maybe_reloaded_booking_locale() ); ?>'
826 , 1
827 );
828 } "
829 ><?php esc_html_e('Delete selected booking(s)' ,'booking'); ?></i></a>
830 </td>
831 </tr>
832
833 </table>
834 </div>
835 <script type="text/javascript">
836 jQuery("#gcal_imported_events<?php echo esc_attr( $this->getResource() ); ?>").insertAfter("#toolbar_booking_listing");
837 </script>
838 <?php
839 }
840
841 }
842