PluginProbe
Booking Calendar / 11.6
Booking Calendar v11.6
11.8.3 11.8.2 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 All 203 releases
booking / core / timeline / v2 / wpbc-class-timeline_v2.php

wpbc-class-timeline_v2.php in Booking Calendar 11.6, at core/timeline/v2/wpbc-class-timeline_v2.php

3,680 lines 169.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /**
2 * @version 1.1
3 * @package Booking Calendar
4 * @category Timeline for Admin Panel
5 * @author wpdevelop
6 *
7 * @web-site https://wpbookingcalendar.com/
8 * @email info@wpbookingcalendar.com
9 *
10 * @modified 2016-01-18
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
14
15
16 class WPBC_TimelineFlex {
17
18
19 public $bookings; // Booking objects from external function
20 public $booking_types; // Resources objects from external function
21
22 public $dates_array; // Dates for Timeline format
23 public $time_array_new; // Times for Timeline format
24
25 public $request_args; // Parsed paramaters
26
27 private $is_frontend; // Client ot Admin sides.
28
29 public $timeline_titles;
30
31 private $week_days_titles;
32 private $current_user_id;
33
34 private $html_client_id; // ID of border element at client side.
35 public $options; // FixIn: 7.0.1.50.
36
37 private $data_in_previous_cell; // FixIn: 8.5.2.6.
38
39 /**
40 * Exact booking scope resolved from a public booking hash.
41 *
42 * @var array|false
43 */
44 private $booking_hash_scope;
45
46 public function __construct(){// $bookings, $booking_types ) {
47
48 $this->reset_data_in_previous_cell();
49 $this->booking_hash_scope = false;
50
51 $this->options = array(); // FixIn: 7.0.1.50.
52
53 $this->html_client_id = false;
54
55 $this->current_user_id = 0;
56
57 $this->is_frontend = false;
58
59 // FixIn: 8.1.3.31.
60 $calendar_overview_start_time = get_bk_option( 'booking_calendar_overview_start_time' );
61 $calendar_overview_end_time = get_bk_option( 'booking_calendar_overview_end_time' );
62 $hours_limit = ( empty( $calendar_overview_start_time ) ? '0' : $calendar_overview_start_time )
63 . ','
64 . ( empty( $calendar_overview_end_time ) ? '24' : $calendar_overview_end_time );
65 $this->request_args = array(
66 'wh_booking_type' => '1'
67 , 'is_matrix' => false
68 , 'view_days_num' => '90'
69 , 'scroll_start_date' => ''
70 , 'scroll_day' => 0
71 , 'scroll_month' => 0
72 , 'wh_trash' => ''
73 , 'limit_hours' => $hours_limit // '0,24' //FixIn: 7.0.1.14 if ( ! ( ( $tt >= $start_hour_for_1day_view ) && ( $tt <= $end_hour_for_1day_view ) ) ) continue;
74 , 'only_booked_resources' => ( isset( $_REQUEST['only_booked_resources'] ) ) ? 1 : 0 /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */
75 , 'booking_hash' => ( isset( $_REQUEST['booking_hash'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['booking_hash'] ) ) : '', /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */
76
77 );
78
79 $this->timeline_titles = array(
80 'header_column1' => __('Resources', 'booking')
81 , 'header_column2' => __('Dates', 'booking')
82 , 'header_title' => __('Bookings', 'booking')
83 );
84
85
86 $this->week_days_titles = array(
87 'full' => array(
88 1 => __( 'Monday', 'booking' )
89 , 2 => __( 'Tuesday', 'booking' )
90 , 3 => __( 'Wednesday', 'booking' )
91 , 4 => __( 'Thursday', 'booking' )
92 , 5 => __( 'Friday', 'booking' )
93 , 6 => __( 'Saturday', 'booking' )
94 , 7 => __( 'Sunday', 'booking' )
95 )
96 , '3' => array( // FixIn: 7.0.1.11.
97 1 => __( 'Mon', 'booking' )
98 , 2 => __( 'Tue', 'booking' )
99 , 3 => __( 'Wed', 'booking' )
100 , 4 => __( 'Thu', 'booking' )
101 , 5 => __( 'Fri', 'booking' )
102 , 6 => __( 'Sat', 'booking' )
103 , 7 => __( 'Sun', 'booking' )
104 )
105 , '1' => array( //FixIn: 7.0.1.11 // FixIn: 8.7.7.14.
106 1 => mb_substr( __( 'Mon', 'booking' ), 0, -1 )
107 , 2 => mb_substr( __( 'Tue', 'booking' ), 0, -1 )
108 , 3 => mb_substr( __( 'Wed', 'booking' ), 0, -1 )
109 , 4 => mb_substr( __( 'Thu', 'booking' ), 0, -1 )
110 , 5 => mb_substr( __( 'Fri', 'booking' ), 0, -1 )
111 , 6 => mb_substr( __( 'Sat', 'booking' ), 0, -1 )
112 , 7 => mb_substr( __( 'Sun', 'booking' ), 0, -1 )
113 )
114 , 'short' => array(
115 1 => mb_substr( __( 'Mon', 'booking' ), 0, 1 )
116 , 2 => mb_substr( __( 'Tue', 'booking' ), 0, 1 )
117 , 3 => mb_substr( __( 'Wed', 'booking' ), 0, 1 )
118 , 4 => mb_substr( __( 'Thu', 'booking' ), 0, 1 )
119 , 5 => mb_substr( __( 'Fri', 'booking' ), 0, 1 )
120 , 6 => mb_substr( __( 'Sat', 'booking' ), 0, 1 )
121 , 7 => mb_substr( __( 'Sun', 'booking' ), 0, 1 )
122 )
123 );
124
125
126 }
127
128 /**
129 * Apply an exact booking and resource authorization scope to timeline SQL arguments.
130 *
131 * A booking hash is a bearer credential for one booking. It must never be
132 * converted into a customer-data keyword or used to broaden the query. Invalid
133 * hashes deliberately select an impossible booking ID so processing fails closed.
134 *
135 * @param array $query_args Clean timeline query arguments.
136 * @param string $booking_hash Public booking hash supplied by the timeline request.
137 * @return array Query arguments restricted to the authorized booking, when applicable.
138 */
139 private function wpbc_apply_booking_hash_scope_to_query_args( $query_args, $booking_hash ) {
140 $this->booking_hash_scope = false;
141 $booking_hash = sanitize_text_field( (string) $booking_hash );
142
143 if ( empty( $booking_hash ) ) {
144 return $query_args;
145 }
146
147 $this->request_args['only_booked_resources'] = 1;
148 $booking_scope = wpbc_hash__get_booking_id__resource_id( $booking_hash );
149
150 if ( empty( $booking_scope ) || count( $booking_scope ) < 2 ) {
151 $query_args['wh_booking_id'] = '-1';
152 return $query_args;
153 }
154
155 $booking_id = absint( $booking_scope[0] );
156 $resource_id = absint( $booking_scope[1] );
157 $booking_row = wpbc_db_get_booking_details( $booking_id );
158
159 if ( empty( $booking_id ) || empty( $resource_id ) || empty( $booking_row ) || $resource_id !== absint( $booking_row->booking_type ) ) {
160 $query_args['wh_booking_id'] = '-1';
161 return $query_args;
162 }
163
164 $this->booking_hash_scope = array(
165 'booking_id' => $booking_id,
166 'resource_id' => $resource_id,
167 );
168 $query_args['wh_booking_id'] = (string) $booking_id;
169 $query_args['wh_booking_type'] = (string) $resource_id;
170
171 return $query_args;
172 }
173
174 /**
175 * Verify that a returned booking remains inside the resolved hash scope.
176 *
177 * This rendering-layer check is intentionally independent of the SQL restriction
178 * so a future query regression cannot expose another booking's popover data.
179 * Timelines without a booking hash retain their configured public presentation.
180 *
181 * @param int $booking_id Booking ID about to be rendered.
182 * @param array $bookings Booking objects keyed by booking ID.
183 * @return bool True when popover rendering is authorized for this row.
184 */
185 private function wpbc_is_booking_authorized_for_hash( $booking_id, $bookings ) {
186 if ( empty( $this->request_args['booking_hash'] ) ) {
187 return true;
188 }
189
190 $booking_id = absint( $booking_id );
191 if ( empty( $this->booking_hash_scope ) || $booking_id !== $this->booking_hash_scope['booking_id'] || empty( $bookings[ $booking_id ] ) ) {
192 return false;
193 }
194
195 return $this->booking_hash_scope['resource_id'] === absint( $bookings[ $booking_id ]->booking_type );
196 }
197
198
199 /**
200 * Rezet data in previos cell
201 */
202 private function reset_data_in_previous_cell(){
203
204 $this->data_in_previous_cell = array(
205 'bookings_in_cell' => array(),
206 'previous_month' => ''
207 );
208
209 }
210
211 // -----------------------------------------------------------------------------------------------------------------
212 /**
213 * Init Timeline From page shortcode
214 *
215 * @param array $attr = array(
216 'wh_booking_type' => ''
217 , 'is_matrix' => false
218 , 'view_days_num' => '30'
219 , 'scroll_start_date' => ''
220 , 'scroll_day' => 0
221 , 'scroll_month' => 0
222 );
223 */
224 public function client_init( $attr ) {
225
226 $this->is_frontend = true;
227
228 // FixIn: 7.0.1.50.
229 if ( isset( $attr['options'] ) ) {
230
231 $shortcode_param__options = $attr['options'];
232 $shortcode_param__options = html_entity_decode( $shortcode_param__options ); // FixIn: 9.8.15.6.
233 $custom_params = array();
234 if (! empty($shortcode_param__options)) {
235 $param ='\s*([^\s]+)=[\'"]{1}([^\'"]+)[\'"]{1}\s*'; // Find all possible options
236 $pattern_to_search='%\s*{([^\s]+)' . $param .'}\s*[,]?\s*%';
237 preg_match_all($pattern_to_search, $shortcode_param__options, $matches, PREG_SET_ORDER);
238 //debuge($matches);
239 /**
240 * [bookingtimeline ... options='{resource_link 3="http://beta/resource-apartment3-id3/"},{resource_link 4="http://beta/resource-3-id4/"}' ... ]
241 [0] => {resource_link 3="http://beta/resource-apartment3-id3/"},
242 [1] => resource_link // Name
243 [2] => 3 // ID
244 [3] => http://beta/resource-apartment3-id3/ // Value
245 */
246 foreach ( $matches as $matche_value ) {
247
248 if ( ! isset( $this->options[ $matche_value[1] ] ) ) {
249 $this->options[ $matche_value[1] ] = array();
250 }
251 $this->options[ $matche_value[1] ][ $matche_value[2] ] = $matche_value[3];
252 }
253 }
254
255 //debuge($this->options);
256 }
257 // FixIn: 7.0.1.50.
258
259
260 //Ovverride some parameters
261 //if ( isset( $attr['resource_id'] ) ) { $attr['type'] = $attr['resource_id']; }
262 if ( isset( $attr['type'] ) ) {
263 $attr['wh_booking_type'] = $attr['type']; //Instead of 'wh_booking_type' paramter in shortcode is used 'type' parameter
264 }
265
266 // Get paramaters from shortcode paramaters
267 $this->define_request_view_params_from_params( $attr );
268
269 if ( ! $this->request_args['is_matrix'] )
270 $this->timeline_titles['header_column1'] = '';
271
272 //Override any possible titles from shortcode paramaters
273 $this->timeline_titles = wp_parse_args( $attr, $this->timeline_titles );
274
275 // Get clean parameters to request booking data
276 $args = $this->wpbc_get_clean_paramas_from_request_for_timeline();
277
278
279 // A public booking hash authorizes only its exact booking and resource.
280 $args = $this->wpbc_apply_booking_hash_scope_to_query_args( $args, $this->request_args['booking_hash'] );
281
282
283 // Get booking data
284 $bk_listing = wpbc_get_bookings_objects( $args );
285 $this->bookings = $bk_listing['bookings'];
286 $this->booking_types = $bk_listing['resources'];
287
288 //Get Dates and Times for Timeline format
289 //debuge($this->bookings[84]);
290 $bookings_date_time = $this->wpbc_get_dates_and_times_for_timeline( $this->bookings );
291 $this->dates_array = $bookings_date_time[0];
292 $this->time_array_new = $bookings_date_time[1];
293 //debuge($this->time_array_new['2017-01-13']);
294
295
296 //$milliseconds = round(microtime(true) * 1000); //FixIn: 7.0.Beta.18
297 $milliseconds = wp_rand( 10000, 99999 );
298
299 $this->html_client_id = 'wpbc_timeline_' . $milliseconds;
300
301 return $this->html_client_id;
302 }
303
304
305 /**
306 * Init parameters after Ajax Navigation actions
307 *
308 * @param array $attr
309 * @return string html_client_id - exist from input parameters
310 */
311 public function ajax_init( $attr ) {
312
313 if ( ! defined( 'WPBC_TIMELINE_AJAX' ) ) { define( 'WPBC_TIMELINE_AJAX', true ); } // FixIn: 8.4.7.13.
314
315 // FixIn: 10.14.14.2.
316 $is_frontend = (bool) $attr['is_frontend'];
317
318 // Not front-end (or possibly changed parameter by attacker to see the bookings).
319 if ( ! $is_frontend ) {
320
321 // If this is not front-end -- admin side, then allow do this only for logged in users, with minimum user role, defined in the settings.
322 // Get minimum user role to access the Timeline in admin panel (Booking Listing and Timeline Overview (Calendar Overview).
323 $curr_user_role = get_bk_option( 'booking_user_role_booking' );
324
325 // Get current user.
326 $current_user = wpbc_get_current_user();
327 $user_role_map = array(
328 'administrator' => 10,
329 'editor' => 7,
330 'author' => 2,
331 'contributor' => 1,
332 'subscriber' => 0,
333 );
334
335 $level = 0;
336 if ( isset( $user_role_map[ $curr_user_role ] ) ) {
337 $level = $user_role_map[ $curr_user_role ];
338 }
339
340 if ( empty( $current_user ) || empty( $current_user->user_level ) || ( $current_user->user_level < $level ) ) {
341 // Security Fix: Enforce frontend mode for non-admins.
342 $attr['is_frontend'] = 1;
343 }
344 }
345
346 $this->is_frontend = (bool) $attr['is_frontend'];
347
348 //Ovverride some parameters
349 //if ( isset( $attr['resource_id'] ) ) { $attr['type'] = $attr['resource_id']; }
350 if ( isset( $attr['type'] ) ) {
351 $attr['wh_booking_type'] = $attr['type']; //Instead of 'wh_booking_type' paramter in shortcode is used 'type' parameter
352 }
353 //debuge($this->request_args, $attr);
354 // Get paramaters from shortcode paramaters
355 $this->define_request_view_params_from_params( $attr );
356
357 //debuge($this->request_args);
358 if ( ! $this->request_args['is_matrix'] ) {
359
360 switch ( $this->request_args['view_days_num'] ) {
361 case '90':
362 case '30':
363 if ( isset( $this->request_args['scroll_day'] ) ) $scroll_day = intval( $this->request_args['scroll_day'] );
364 else $scroll_day = 0;
365
366 // FixIn: 8.9.4.3.
367 // Here we need to define number of days to scroll depends from selected number of days to show.
368 $days_num_to_scroll = intval( get_bk_option( 'booking_timeline__month_mode__days_number_show' ) );
369 if ( empty( $days_num_to_scroll ) ) {
370 $days_num_to_scroll = 7;
371 }
372
373 if ( $attr['nav_step'] == '-1' ) {
374 $this->request_args['scroll_day'] = intval( $scroll_day - $days_num_to_scroll );
375 }
376 if ( $attr['nav_step'] == '1' ) {
377 $this->request_args['scroll_day'] = intval( $scroll_day + $days_num_to_scroll );
378 }
379
380 /*
381 * From Admin panel:
382 *
383 // Here we need to define number of days to scroll depends from selected number of days to show.
384 $days_num_to_scroll = intval( get_bk_option( 'booking_calendar_overview__day_mode__days_number_show' ) );
385 if ( empty( $days_num_to_scroll ) ) {
386 $days_num_to_scroll = 7;
387 }
388
389 $scroll_params = array( '&scroll_day='.intval( $scroll_day - $days_num_to_scroll * 2 ),
390 '&scroll_day='.intval( $scroll_day - $days_num_to_scroll ),
391 '&scroll_day=0',
392 '&scroll_day='.intval( $scroll_day + $days_num_to_scroll ),
393 '&scroll_day='.intval( $scroll_day + $days_num_to_scroll *2 ) );
394 $scroll_titles = array( __( 'Previous', 'booking' ) . ' ' . ( 2 * $days_num_to_scroll ) . ' ' . __( 'days', 'booking' ),
395 __( 'Previous', 'booking' ) . ' ' . $days_num_to_scroll . ' ' . __( 'days', 'booking' ),
396 __('Current week' ,'booking'),
397 __( 'Next', 'booking' ) . ' ' . $days_num_to_scroll . ' ' . __( 'days', 'booking' ),
398 __( 'Next', 'booking' ) . ' ' . ( 2 * $days_num_to_scroll ) . ' ' . __( 'days', 'booking' ) );
399 */
400 break;
401 default: // 365
402 if ( !isset( $this->request_args['scroll_month'] ) ) $this->request_args['scroll_month'] = 0;
403 $scroll_month = intval( $this->request_args['scroll_month'] );
404
405 if ( $attr['nav_step'] == '-1' ) $this->request_args['scroll_month'] = intval( $scroll_month - 1 );
406 if ( $attr['nav_step'] == '1' ) $this->request_args['scroll_month'] = intval( $scroll_month + 1 );
407 /*
408 $scroll_params = array( '&scroll_month='.intval($scroll_month-3),
409 '&scroll_month='.intval($scroll_month-1),
410 '&scroll_month=0',
411 '&scroll_month='.intval($scroll_month+1 ),
412 '&scroll_month='.intval($scroll_month+3) );
413 $scroll_titles = array( __('Previous 3 months' ,'booking'),
414 __('Previous month' ,'booking'),
415 __('Current month' ,'booking'),
416 __('Next month' ,'booking'),
417 __('Next 3 months' ,'booking') );*/
418 break;
419 }
420 } else { // Matrix
421
422 switch ( $this->request_args['view_days_num'] ) {
423 case '1': //Day
424 if ( isset( $this->request_args['scroll_day'] ) ) $scroll_day = intval( $this->request_args['scroll_day'] );
425 else $scroll_day = 0;
426
427 if ( $attr['nav_step'] == '-1' ) $this->request_args['scroll_day'] = intval( $scroll_day - 1 );
428 if ( $attr['nav_step'] == '1' ) $this->request_args['scroll_day'] = intval( $scroll_day + 1 );
429 /*
430 $scroll_params = array( '&scroll_day='.intval($scroll_day-7),
431 '&scroll_day='.intval($scroll_day-1),
432 '&scroll_day=0',
433 '&scroll_day='.intval($scroll_day+1 ),
434 '&scroll_day='.intval($scroll_day+7) );
435 $scroll_titles = array( __('Previous 7 days' ,'booking'),
436 __('Previous day' ,'booking'),
437 __('Current day' ,'booking'),
438 __('Next day' ,'booking'),
439 __('Next 7 days' ,'booking') );*/
440 break;
441
442 case '7': //Week
443
444 if ( isset( $this->request_args['scroll_day'] ) ) $scroll_day = intval( $this->request_args['scroll_day'] );
445 else $scroll_day = 0;
446
447 if ( $attr['nav_step'] == '-1' ) $this->request_args['scroll_day'] = intval( $scroll_day - 7 );
448 if ( $attr['nav_step'] == '1' ) $this->request_args['scroll_day'] = intval( $scroll_day + 7 );
449 /*
450 $scroll_params = array( '&scroll_day='.intval($scroll_day-4*7),
451 '&scroll_day='.intval($scroll_day-7),
452 '&scroll_day=0',
453 '&scroll_day='.intval($scroll_day+7 ),
454 '&scroll_day='.intval($scroll_day+4*7) );
455 $scroll_titles = array( __('Previous 4 weeks' ,'booking'),
456 __('Previous week' ,'booking'),
457 __('Current week' ,'booking'),
458 __('Next week' ,'booking'),
459 __('Next 4 weeks' ,'booking') );*/
460 break;
461
462 case '30':
463 case '60':
464 case '90': //3 months
465
466 if ( !isset( $this->request_args['scroll_month'] ) ) $this->request_args['scroll_month'] = 0;
467 $scroll_month = intval( $this->request_args['scroll_month'] );
468
469 if ( $attr['nav_step'] == '-1' ) $this->request_args['scroll_month'] = intval( $scroll_month - 1 );
470 if ( $attr['nav_step'] == '1' ) $this->request_args['scroll_month'] = intval( $scroll_month + 1 );
471 /*
472 $scroll_params = array( '&scroll_month='.intval($scroll_month-3),
473 '&scroll_month='.intval($scroll_month-1),
474 '&scroll_month=0',
475 '&scroll_month='.intval($scroll_month+1 ),
476 '&scroll_month='.intval($scroll_month+3) );
477 $scroll_titles = array( __('Previous 3 months' ,'booking'),
478 __('Previous month' ,'booking'),
479 __('Current month' ,'booking'),
480 __('Next month' ,'booking'),
481 __('Next 3 months' ,'booking') );*/
482 break;
483
484 default: // 30, 60, 90...
485 if ( !isset( $this->request_args['scroll_month'] ) ) $this->request_args['scroll_month'] = 0;
486 $scroll_month = intval( $this->request_args['scroll_month'] );
487
488 if ( $attr['nav_step'] == '-1' ) $this->request_args['scroll_month'] = intval( $scroll_month - 1 );
489 if ( $attr['nav_step'] == '1' ) $this->request_args['scroll_month'] = intval( $scroll_month + 1 );
490 /*
491 $scroll_params = array( '&scroll_month='.intval($scroll_month-3),
492 '&scroll_month='.intval($scroll_month-1),
493 '&scroll_month=0',
494 '&scroll_month='.intval($scroll_month+1 ),
495 '&scroll_month='.intval($scroll_month+3) );
496 $scroll_titles = array( __('Previous 3 months' ,'booking'),
497 __('Previous month' ,'booking'),
498 __('Current month' ,'booking'),
499 __('Next month' ,'booking'),
500 __('Next 3 months' ,'booking') );
501 */
502 break;
503 }
504 }
505
506 // Titles
507 if ( ! $this->request_args['is_matrix'] )
508 $this->timeline_titles['header_column1'] = '';
509
510 //Override any possible titles from shortcode paramaters
511 $this->timeline_titles = wp_parse_args( $attr, $this->timeline_titles );
512
513
514 // Get clean parameters to request booking data
515 $args = $this->wpbc_get_clean_paramas_from_request_for_timeline();
516
517
518 // Apply the same exact-booking scope to every unauthenticated navigation request.
519 $booking_hash = isset( $attr['booking_hash'] ) ? $attr['booking_hash'] : '';
520 $args = $this->wpbc_apply_booking_hash_scope_to_query_args( $args, $booking_hash );
521
522
523 // Get booking data
524 $bk_listing = wpbc_get_bookings_objects( $args );
525
526 $this->bookings = $bk_listing['bookings'];
527 $this->booking_types = $bk_listing['resources'];
528
529 //Get Dates and Times for Timeline format
530 $bookings_date_time = $this->wpbc_get_dates_and_times_for_timeline( $this->bookings );
531 $this->dates_array = $bookings_date_time[0];
532 $this->time_array_new = $bookings_date_time[1];
533
534
535 $this->html_client_id = $attr['html_client_id'];
536
537 return $this->html_client_id;
538 }
539
540
541 /**
542 * Define initial REQUEST parameters for Admin Panel and Get bookings and resources
543 */
544 public function admin_init() {
545
546 // User ////////////////////////////////////////////////////////////////
547 $user = wpbc_get_current_user();
548 $this->current_user_id = $user->ID;
549
550 $this->is_frontend = false;
551
552 // Get paramaters from REQUEST
553 $this->define_request_view_params();
554
555 if ( ! $this->request_args['is_matrix'] )
556 $this->timeline_titles['header_column1'] = '';
557
558 // debuge($this->request_args);
559
560 // Get clean parameters to request booking data
561 $args = $this->wpbc_get_clean_paramas_from_request_for_timeline();
562
563 // Get booking data
564 $bk_listing = wpbc_get_bookings_objects( $args );
565 $this->bookings = $bk_listing['bookings'];
566 $this->booking_types = $bk_listing['resources'];
567
568 //Get Dates and Times for Timeline format
569 $bookings_date_time = $this->wpbc_get_dates_and_times_for_timeline( $this->bookings );
570 $this->dates_array = $bookings_date_time[0];
571 $this->time_array_new = $bookings_date_time[1];
572 }
573
574
575 public function client_navigation( $param ) {
576 ?>
577 <script type="text/javascript">
578 wpbc_timeline_obj["<?php echo esc_js( $this->html_client_id ); ?>"] = {
579 is_frontend : "<?php echo esc_js( $this->is_frontend ? '1' : '0' ); ?>",
580 html_client_id : "<?php echo esc_js( $this->html_client_id ); ?>",
581 wh_booking_type : "<?php echo esc_js( $this->request_args['wh_booking_type'] ); ?>",
582 is_matrix : "<?php echo esc_js( $this->request_args['is_matrix'] ? '1' : '0' ); ?>",
583 view_days_num : "<?php echo esc_js( $this->request_args['view_days_num'] ); ?>",
584 scroll_start_date : "<?php echo esc_js( $this->request_args['scroll_start_date'] ); ?>",
585 scroll_day : "<?php echo esc_js( $this->request_args['scroll_day'] ); ?>",
586 scroll_month : "<?php echo esc_js( $this->request_args['scroll_month'] ); ?>",
587 'header_column1' : "<?php echo esc_js( $this->timeline_titles['header_column1'] ); ?>",
588 'header_column2' : "<?php echo esc_js( $this->timeline_titles['header_column2'] ); ?>",
589 'header_title' : "<?php echo esc_js( $this->timeline_titles['header_title'] ); ?>",
590 'wh_trash' : "<?php echo esc_js( $this->request_args['wh_trash'] ); ?>",
591 'limit_hours' : "<?php echo esc_js( $this->request_args['limit_hours'] ); ?>",
592 'only_booked_resources': "<?php echo esc_js( $this->request_args['only_booked_resources'] ); ?>",
593 'options' : '<?php echo wp_json_encode( $this->options ); ?>',
594 'booking_hash' : "<?php echo esc_js( $this->request_args['booking_hash'] ); ?>"
595 };
596 </script>
597 <div class="flex_tl_nav">
598 <div class="flex_tl_prev" href="javascript:void(0)"
599 onclick="javascript:wpbc_flextimeline_nav( wpbc_timeline_obj['<?php echo esc_js( $this->html_client_id ); ?>'], -1 );">
600 <a>&laquo;</a></div>
601 <div class="flex_tl_title"><?php echo esc_html( $param['title'] ); ?></div>
602 <div class="flex_tl_next" href="javascript:void(0)"
603 onclick="javascript:wpbc_flextimeline_nav( wpbc_timeline_obj['<?php echo esc_js( $this->html_client_id ); ?>'], 1 );">
604 <a>&raquo;</a></div>
605 </div>
606 <?php
607 }
608
609 // -----------------------------------------------------------------------------------------------------------------
610 // S u p p o r t
611 // -----------------------------------------------------------------------------------------------------------------
612 /**
613 * Get array of cleaned (limited number) paramas from request for getting bookings by "wpbc_get_bookings_objects"
614 *
615 * @return array
616 */
617 public function wpbc_get_clean_paramas_from_request_for_timeline() {
618
619 //Replacing in this file from gmdate( to date_i18n( to wpbc_datetime__no_wp_timezone( // FixIn: 9.9.0.18.
620 $start_year = intval( wpbc_datetime__no_wp_timezone( "Y" ) );
621 $start_month = intval( wpbc_datetime__no_wp_timezone( "m" ) );
622 $start_day = 1;
623 //debuge( '1.( $start_year, $start_month, $start_day , $this->request_args ', $start_year, $start_month, $start_day , $this->request_args );
624 if ( ! empty( $this->request_args['scroll_start_date'] ) ) { // scroll_start_date=2013-07-01
625
626 list( $start_year, $start_month, $start_day ) = explode( '-', $this->request_args['scroll_start_date'] );
627 $start_year = intval( $start_year );
628 $start_month = intval( $start_month );
629 $start_day = intval( $start_day );
630 }
631 //debuge( '2.( $start_year, $start_month, $start_day )', $start_year, $start_month, $start_day );
632 $scroll_day = 0;
633 $scroll_month = 0;
634
635 if ( ( isset( $this->request_args['view_days_num'] ) )
636 //&& ($this->request_args['view_days_num'] != '30')
637 )
638 $view_days_num = $this->request_args['view_days_num'];
639 else
640 $view_days_num = get_bk_option( 'booking_view_days_num' );
641
642 $view_days_num = intval( $view_days_num );
643 //debuge( '2.1( $view_days_num )', $view_days_num );
644 $is_matrix = (bool) $this->request_args['is_matrix'];
645
646 if ( $is_matrix ) {
647
648 switch ( $view_days_num ) {
649
650 case '1':
651 if ( empty( $this->request_args['scroll_start_date'] ) )
652 $start_day = intval( wpbc_datetime__no_wp_timezone( "d" ) ); // Today date
653
654 if ( isset( $this->request_args['scroll_day'] ) )
655 $scroll_day = intval( $this->request_args['scroll_day'] );
656
657 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
658 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date );
659
660 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
661 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date );
662 break;
663
664 case '7':
665 if ( empty( $this->request_args['scroll_start_date'] ) )
666 $start_day = intval( wpbc_datetime__no_wp_timezone( "d" ) ); //Today date
667 $start_week_day_num = intval( wpbc_datetime__no_wp_timezone( "w" ) );
668 $start_day_weeek = intval( get_bk_option( 'booking_start_day_weeek' ) ); //[0]:Sun .. [6]:Sut
669 if ( $start_week_day_num != $start_day_weeek ) {
670 for ( $d_inc = 1; $d_inc < 8; $d_inc++ ) { // Just get week back
671 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) - intval( $d_inc ) ), intval( $start_year ) );
672 $start_week_day_num = intval( wpbc_datetime__no_wp_timezone( "w", $real_date ) );
673 if ( $start_week_day_num == $start_day_weeek ) {
674 $start_day = intval( wpbc_datetime__no_wp_timezone( "d", $real_date ) );
675 $start_year = intval( wpbc_datetime__no_wp_timezone( "Y", $real_date ) );
676 $start_month = intval( wpbc_datetime__no_wp_timezone( "m", $real_date ) );
677 $d_inc = 9;
678 }
679 }
680 }
681
682 if ( isset( $this->request_args['scroll_day'] ) )
683 $scroll_day = intval( $this->request_args['scroll_day'] );
684
685 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
686 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date );
687
688 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + 7 + intval( $scroll_day ) ), intval( $start_year ) );
689 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date );
690 break;
691
692 case '30':
693 if ( isset( $this->request_args['scroll_month'] ) )
694 $scroll_month = intval( $this->request_args['scroll_month'] );
695
696 //debuge('3.$scroll_month, $start_month, $start_day, $start_year', $scroll_month, $start_month, $start_day, $start_year );
697 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
698 //debuge('4.$real_date',$real_date);
699 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date );
700 //debuge('5.$wh_booking_date',$wh_booking_date);
701 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + 1 + intval( $scroll_month ) ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
702 //debuge('6.$real_date',$real_date);
703 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date );
704 //debuge('7.$wh_booking_date2', $wh_booking_date2);
705 break;
706
707 case '60':
708 if ( isset( $this->request_args['scroll_month'] ) )
709 $scroll_month = intval( $this->request_args['scroll_month'] );
710
711 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
712 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2012-12-01';
713
714 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + 2 + intval( $scroll_month ) ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
715 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2013-02-31';
716 break;
717
718 ////////////////////////////////////////////////////////////////////////////////
719 default: // 30 - default
720 if ( isset( $this->request_args['scroll_month'] ) )
721 $scroll_month = intval( $this->request_args['scroll_month'] );
722
723 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
724 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2012-12-01';
725
726 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + 1 + intval( $scroll_month ) ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
727 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2012-12-31';
728 break;
729 }
730
731 } else { // Single resource
732
733 switch ( $view_days_num ) {
734
735 case '90':
736
737 if ( empty( $this->request_args['scroll_start_date'] ) )
738 $start_day = intval( wpbc_datetime__no_wp_timezone( "d" ) ); //Today Date
739 $start_week_day_num = intval( wpbc_datetime__no_wp_timezone( "w" ) );
740 $start_day_weeek = intval( get_bk_option( 'booking_start_day_weeek' ) ); //[0]:Sun .. [6]:Sut
741
742 if ( $start_week_day_num != $start_day_weeek ) {
743 for ( $d_inc = 1; $d_inc < 8; $d_inc++ ) { // Just get week back
744 $real_date = mktime( 0, 0, 0, intval($start_month), (intval($start_day) - intval($d_inc) ), intval($start_year) );
745 $start_week_day_num = intval( wpbc_datetime__no_wp_timezone( "w", $real_date ) );
746 if ( $start_week_day_num == $start_day_weeek ) {
747 $start_day = intval( wpbc_datetime__no_wp_timezone( "d", $real_date ) );
748 $start_year = intval( wpbc_datetime__no_wp_timezone( "Y", $real_date ) );
749 $start_month = intval( wpbc_datetime__no_wp_timezone( "m", $real_date ) );
750 $d_inc = 9;
751 }
752 }
753 }
754
755 if ( isset( $this->request_args['scroll_day'] ) )
756 $scroll_day = intval( $this->request_args['scroll_day'] );
757
758 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
759 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2012-12-01';
760
761 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + 7 * 12 + 7 + intval( $scroll_day ) ), intval( $start_year ) );
762 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2013-12-31';
763 break;
764
765 case '30':
766 if ( empty( $this->request_args['scroll_start_date'] ) )
767 $start_day = intval( wpbc_datetime__no_wp_timezone( "d" ) ); //Today Date
768
769 if ( isset( $this->request_args['scroll_day'] ) )
770 $scroll_day = intval( $this->request_args['scroll_day'] );
771
772 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
773 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2012-12-01';
774
775 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + 31 + intval( $scroll_day ) ), intval( $start_year ) );
776 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2013-12-31';
777 break;
778
779 default: // 365
780
781 if ( isset( $this->request_args['scroll_month'] ) )
782 $scroll_month = intval( $this->request_args['scroll_month'] );
783 else
784 $scroll_month = 0;
785
786 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
787 $wh_booking_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2012-12-01';
788
789 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) + 13 ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
790 $wh_booking_date2 = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date ); // '2013-12-31';
791
792 break;
793 }
794 }
795
796 $or_sort = '';
797
798 $args = array(
799 'wh_booking_type' => $this->request_args['wh_booking_type'],
800 'wh_approved' => '',
801 'wh_booking_id' => '',
802 'wh_is_new' => '',
803 'wh_pay_status' => 'all',
804 'wh_keyword' => '',
805 'wh_booking_date' => $wh_booking_date,
806 'wh_booking_date2' => $wh_booking_date2,
807 'wh_modification_date' => '3',
808 'wh_modification_date2' => '',
809 'wh_cost' => '',
810 'wh_cost2' => '',
811 'or_sort' => $or_sort,
812 'page_num' => '1',
813 'wh_trash' => $this->request_args['wh_trash'],
814 'limit_hours' => $this->request_args['limit_hours'],
815 'only_booked_resources' => $this->request_args['only_booked_resources'], // FixIn: 7.0.1.51.
816 'page_items_count' => '100000'
817 );
818 //debuge('8.',$args);
819 return $args;
820 }
821
822
823 /**
824 * Define View Params from $_REQUEST
825 */
826 public function define_request_view_params() {
827
828 // All other sanitizing and escaping are inside of this function wpbc_check_request_paramters(), which executing before. // FixIn: 8.9.2.1.
829
830 // Used once for comma seperated resources only.
831 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
832 if ( isset( $_REQUEST['wh_booking_type'] ) ) {
833 $this->request_args['wh_booking_type'] = wpbc_clean_digit_or_csd( $_REQUEST['wh_booking_type'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized // FixIn: 8.9.2.1.
834 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
835 } elseif ( isset( $_GET['booking_type'] ) ) {
836 $this->request_args['wh_booking_type'] = wpbc_clean_digit_or_csd( $_GET['booking_type'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized // FixIn: 8.9.2.1.
837 }
838 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
839 if ( ( isset( $_REQUEST['wh_booking_type'] ) ) && ( strpos( $_REQUEST['wh_booking_type'], ',' ) !== false ) ) {
840 $this->request_args['is_matrix'] = true;
841 }
842 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
843 if ( isset( $_REQUEST['view_days_num'] ) ) {
844 $this->request_args['view_days_num'] = sanitize_text_field( wp_unslash( $_REQUEST['view_days_num'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
845 }
846 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
847 if ( isset( $_REQUEST['scroll_start_date'] ) ) {
848 $this->request_args['scroll_start_date'] = sanitize_text_field( wp_unslash( $_REQUEST['scroll_start_date'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
849 }
850 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
851 if ( isset( $_REQUEST['scroll_day'] ) ) {
852 $this->request_args['scroll_day'] = sanitize_text_field( wp_unslash( $_REQUEST['scroll_day'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
853 }
854 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
855 if ( isset( $_REQUEST['scroll_month'] ) ) {
856 $this->request_args['scroll_month'] = sanitize_text_field( wp_unslash( $_REQUEST['scroll_month'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
857 }
858 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
859 if ( isset( $_REQUEST['wh_trash'] ) ) {
860 $this->request_args['wh_trash'] = sanitize_text_field( wp_unslash( $_REQUEST['wh_trash'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
861 }
862 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
863 if ( isset( $_REQUEST['limit_hours'] ) ) {
864 $this->request_args['limit_hours'] = sanitize_text_field( wp_unslash( $_REQUEST['limit_hours'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
865 } // FixIn: 7.0.1.14.
866 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
867 if ( isset( $_REQUEST['only_booked_resources'] ) ) {
868 $this->request_args['only_booked_resources'] = 1;
869 } //$_REQUEST['only_booked_resources']; // FixIn: 7.0.1.51.
870 }
871
872
873 /**
874 * Define Request View Params
875 *
876 * @param array $param = = array(
877 * 'wh_booking_type' => ''
878 * , 'is_matrix' => false
879 * , 'view_days_num' => '30'
880 * , 'scroll_start_date' => ''
881 * , 'scroll_day' => 0
882 * , 'scroll_month' => 0
883 * );
884 */
885 public function define_request_view_params_from_params( $param ) {
886 //debuge( $param , $this->options , maybe_unserialize( wp_unslash( $param['options'] ) ) );die;
887 if ( isset( $param['wh_booking_type'] ) ) {
888 $this->request_args['wh_booking_type'] = $param['wh_booking_type'];
889 } // Used once for comma seperated resources only.
890
891 if ( ( isset( $param['wh_booking_type'] ) ) && ( strpos( $param['wh_booking_type'], ',' ) !== false ) ) {
892 $this->request_args['is_matrix'] = true;
893 }
894 if ( isset( $param['view_days_num'] ) ) {
895 $this->request_args['view_days_num'] = $param['view_days_num'];
896 }
897 if ( isset( $param['scroll_start_date'] ) ) {
898 $this->request_args['scroll_start_date'] = $param['scroll_start_date'];
899 }
900 if ( isset( $param['scroll_day'] ) ) {
901 $this->request_args['scroll_day'] = $param['scroll_day'];
902 }
903 if ( isset( $param['scroll_month'] ) ) {
904 $this->request_args['scroll_month'] = $param['scroll_month'];
905 }
906 if ( isset( $param['wh_trash'] ) ) {
907 $this->request_args['wh_trash'] = $param['wh_trash'];
908 }
909 if ( isset( $param['limit_hours'] ) ) {
910 $this->request_args['limit_hours'] = $param['limit_hours'];
911 } // FixIn: 7.0.1.14.
912 if ( isset( $param['only_booked_resources'] ) ) {
913 $this->request_args['only_booked_resources'] = $param['only_booked_resources'];
914 } // FixIn: 7.0.1.14.
915 if ( isset( $param['booking_hash'] ) ) {
916 $this->request_args['booking_hash'] = $param['booking_hash'];
917 } // FixIn: 8.1.3.5.
918 if ( ( empty( $this->options ) ) && ( isset( $param['options'] ) ) ) {
919 $this->options = json_decode( wp_unslash( $param['options'] ), true ); // FixIn: 9.2.1.8.
920 }
921
922 }
923
924
925 /**
926 * Get D A T E S and T I M E S from B o o k i n g s
927 *
928 * @param array $bookings - Booking input array
929 * @return array - array( $dates_array, $time_array_new )
930 */
931 public function wpbc_get_dates_and_times_for_timeline( $bookings ) {
932
933 // Generate: Array ( [0] => array(), [3600] => array(), [7200] => array(), ..... [43200] => array(),.... [82800] => array() )
934 $fixed_time_hours_array = array();
935 for ( $tt = 0; $tt < 24; $tt++ ) {
936 $fixed_time_hours_array[$tt * 60 * 60] = array();
937 }
938 //debuge($bookings);
939 // Dates array: { '2012-12-24' => array( Booking ID 1, Booking ID 2, ....), ... }
940 $dates_array = $time_array = array();
941 foreach ( $bookings as $bk ) {
942
943
944 /**
945 * Check situation , while we are having end time but do not have start time, like here:
946 * $bk->dates = Array(
947 [0] => stdClass Object (
948 [booking_id] => 911
949 [booking_date] => 2019-07-22 00:00:00
950 [approved] => 1
951 [type_id] => )
952
953 [1] => stdClass Object (
954 [booking_id] => 911
955 [booking_date] => 2019-07-23 00:00:00
956 [approved] => 1
957 [type_id] => )
958
959 [2] => stdClass Object (
960 [booking_id] => 911
961 [booking_date] => 2019-07-24 15:00:02
962 [approved] => 1
963 [type_id] => )
964 )
965 *
966 * So we need to add the new Start time before End time, like this:
967 *
968 [0] => stdClass Object (
969 [booking_id] => 911
970 [booking_date] => 2019-07-22 00:00:00
971 [approved] => 1
972 [type_id] => )
973
974 [1] => stdClass Object (
975 [booking_id] => 911
976 [booking_date] => 2019-07-23 00:00:00
977 [approved] => 1
978 [type_id] => )
979 [2] => stdClass Object (
980 [booking_id] => 911
981 [booking_date] => 2019-07-24 00:00:01
982 [approved] => 1
983 [type_id] => )
984 [2] => stdClass Object (
985 [booking_id] => 911
986 [booking_date] => 2019-07-24 15:00:02
987 [approved] => 1
988 [type_id] => )
989 *
990 */
991 $dates_to_check = array();
992 $is_started = 0;
993 foreach ( $bk->dates as $dt ) {
994
995 $last_second = substr( $dt->booking_date, -1);
996
997 // Count start end end times started.
998 switch ( $last_second ) {
999 case '1': // Start
1000 $is_started++;
1001 break;
1002 case '2': // End
1003 case '8': // FixIn: 9.0.1.2.
1004 $is_started--;
1005 break;
1006 case '0': // Full
1007 default:
1008 }
1009
1010 // Its means that we have now end time, but was not having start time
1011 if ( $is_started < 0 ) {
1012 $is_started++;
1013 $my_temp_start_time = clone $dt;
1014
1015 $temp_time = explode( ' ' ,$my_temp_start_time->booking_date );
1016 $temp_time = $temp_time[0] . ' 00:00:01';
1017
1018 $my_temp_start_time->booking_date = $temp_time;
1019 // Add start time day
1020 $dates_to_check[] = $my_temp_start_time;
1021 }
1022 $dates_to_check[] = $dt;
1023 }
1024
1025 if ( 0 != $is_started ) {
1026 ?><div class="warning_check_in_out_not_equal"><?php
1027 // FixIn: 9.2.4.5.
1028 ?><div style="margin:0 10px 10px;font-weight:600;font-size:1.1em;"><?php
1029 echo( 'Warning! Structure of your booking dates has an issue.');
1030 ?></div><?php
1031 ?><div style="margin:0 10px 30px;font-weight:400;font-size:1.1em;"><?php
1032 printf( 'Number of check in times != check out times in a booking, or check-in time is older than the check-out time on the same date in the same booking.' );
1033 ?></div><?php
1034 ?><div style="margin:10px;font-weight:600;font-size:1.05em;color:#752;"><?php
1035 printf( 'To resolve this issue, you need to delete the following bookings and create new bookings with the same booking details.' );
1036 ?></div><?php
1037 $bookings_to_del = array();
1038 for( $day_i = 0; $day_i <= ( count( $dates_to_check ) - 1 ); $day_i++) {
1039 $bookings_to_del[] = $dates_to_check[$day_i]->booking_id;
1040 }
1041 $bookings_to_del = array_unique( $bookings_to_del );
1042 for ( $bk_i = 0; $bk_i <= ( count( $bookings_to_del ) - 1 ); $bk_i ++ ) {
1043 $booking_id__to_del = $bookings_to_del [ $bk_i ];
1044
1045 ?><div style="margin:10px;font-weight:600;font-size:1.05em;"><?php
1046
1047 echo wp_kses_post( sprintf( 'Delete booking with %s', htmlspecialchars_decode( '<strong></strong><a href="' . esc_url( wpbc_get_bookings_url() . '&tab=vm_booking_listing&wh_booking_id=' . $booking_id__to_del ) . '">' . 'ID = ' . $booking_id__to_del . '</a></strong>' ) ) );
1048
1049 ?></div><?php
1050 }
1051
1052 ?><div style="margin:50px;font-weight:600;font-size:1.05em;"></div><?php
1053
1054 debuge( $dates_to_check, $is_started) ;
1055
1056 ?></div><script type="text/javascript"> jQuery( '.warning_check_in_out_not_equal' ).animate( {opacity: 1}, 15000 ).toggle(1000); </script><?php
1057 }
1058
1059
1060 foreach ( $dates_to_check as $dt ) {
1061 //foreach ( $bk->dates as $dt ) {
1062
1063 // Transform from MySQL date to PHP date
1064 $dt->booking_date = trim( $dt->booking_date );
1065 $dta = explode( ' ', $dt->booking_date );
1066 $tms = $dta[1];
1067 // FixIn: 8.2.1.21.
1068 //if ( substr( $dta[1], - 1 ) == '2' ) { continue; }
1069 $tms = explode( ':', $tms ); // array('13','30','40')
1070 $dta = $dta[0];
1071 $dta = explode( '-', $dta ); // array('2012','12','30')
1072 $php_dt = mktime( intval( $tms[0] ), intval( $tms[1] ), intval( $tms[2] ), intval( $dta[1] ), intval( $dta[2] ), intval( $dta[0] ) );
1073
1074 if ( ( isset( $dt->type_id ) ) && (!empty( $dt->type_id )) )
1075 $date_bk_res_id = $dt->type_id;
1076 else
1077 $date_bk_res_id = $bk->booking_type;
1078
1079 //FixIn: 9.9.0.18 - booking
1080 $my_date = wpbc_datetime__no_wp_timezone( "Y-m-d", $php_dt ); // '2012-12-01';
1081
1082 if ( !isset( $dates_array[$my_date] ) ) {
1083 $dates_array[$my_date] = array( array( 'id' => $bk->booking_id, 'resource' => $date_bk_res_id ) );
1084 } else {
1085 $dates_array[$my_date][] = array( 'id' => $bk->booking_id, 'resource' => $date_bk_res_id );
1086 }
1087
1088 //FixIn: 9.9.0.18 - booking
1089 $my_time = wpbc_datetime__no_wp_timezone( "H:i:s", $php_dt ); // '21:55:01';
1090
1091 $my_time_index = explode( ':', $my_time );
1092 $my_time_index = (int) ($my_time_index[0] * 60 * 60 + $my_time_index[1] * 60 + $my_time_index[2]);
1093
1094 $my_time = strtotime( $my_time ); // FixIn: 8.1.1.6.
1095
1096 if ( !isset( $time_array[$my_date] ) ) {
1097 $time_array[$my_date] = array( $my_time_index => array( $my_time => array( 'id' => $bk->booking_id, 'resource' => $date_bk_res_id ) ) );
1098 } else {
1099
1100 if ( !isset( $time_array[$my_date][$my_time_index] ) )
1101 $time_array[$my_date][$my_time_index] = array( $my_time => array( 'id' => $bk->booking_id, 'resource' => $date_bk_res_id ) );
1102 else {
1103 if ( !isset( $time_array[$my_date][$my_time_index][$my_time] ) )
1104 $time_array[$my_date][$my_time_index][$my_time] = array( 'id' => $bk->booking_id, 'resource' => $date_bk_res_id );
1105 else {
1106 $my_time_inc = 3;
1107 while ( isset( $time_array[$my_date][$my_time_index][$my_time + $my_time_inc] ) ) {
1108 $my_time_inc++;
1109 }
1110 //Just in case if we are have the booking in the same time, so we are
1111 $time_array[$my_date][$my_time_index][($my_time + $my_time_inc)] = array( 'id' => $bk->booking_id, 'resource' => $date_bk_res_id );
1112 }
1113 }
1114 }
1115 }
1116 }
1117
1118
1119 //debuge($time_array);
1120 // Sorting ..........
1121 foreach ( $time_array as $key => $value_t ) { // Sort the times from lower to higher
1122 ksort( $value_t );
1123 $time_array[$key] = $value_t;
1124 }
1125 ksort( $time_array ); // Sort array by dates from lower to higher.
1126 /* $time_array:
1127 $key_date $value_t
1128 [2012-12-13] => Array ( $tt_index $times_bk_id_array
1129 [44401] => Array ( [12:20:01] => 19)
1130 ),
1131 [2012-12-14] => Array (
1132 [10802] => Array([03:00:02] => 19),
1133 [43801] => Array([12:10:01] => 2)
1134 ),
1135 .... */
1136
1137 //debuge($time_array);
1138
1139 $time_array_new = array();
1140 foreach ( $time_array as $key_date => $value_t ) { // fill the $time_array_new - by bookings of full dates....
1141 $new_times_array = $fixed_time_hours_array; // Array ( [0] => Array, [3600] => Array, [7200] => Array .....
1142
1143 foreach ( $value_t as $tt_index => $times_bk_id_array ) { // [44401] => Array ( [12:20:01] => 19 ), .....
1144 $tt_index_round = floor( ($tt_index / 60) / 60 ) * 60 * 60; // 14400, 18000,
1145 $is_bk_for_full_date = $tt_index % 10; // 0, 1, 2
1146
1147 switch ( $is_bk_for_full_date ) {
1148 case 0: // Full date - fill every time slot
1149 foreach ( $new_times_array as $round_time_slot => $bk_id_array ) {
1150 $new_times_array[$round_time_slot] = array_merge( $bk_id_array, array_values( $times_bk_id_array ) );
1151 }
1152 //debuge('$time_array[$key_date][$tt_index]',$time_array[$key_date][$tt_index], $round_time_slot);
1153 unset( $time_array[$key_date][$tt_index] );
1154 break;
1155
1156 case 1: break;
1157 case 2: break;
1158 default: break;
1159 }
1160 }
1161 if ( count( $time_array[$key_date] ) == 0 )
1162 unset( $time_array[$key_date] );
1163
1164 $time_array_new[$key_date] = $new_times_array;
1165 }
1166 //$time_array_new - Array filled by bookings FOR FULL DAY booking only
1167
1168 //debuge($time_array_new);
1169
1170
1171 foreach ( $time_array as $key_date => $value_t ) {
1172 $new_times_array_for_day_start = $new_times_array_for_day_end = array();
1173 foreach ( $value_t as $tt_index => $times_bk_id_array ) { // [44401] => Array ( [12:20:01] => 19 ), .....
1174 $tt_index_round = floor( ($tt_index / 60) / 60 ) * 60 * 60; // 14400, 18000,
1175 //debuge($tt_index, $tt_index_round);
1176 $is_bk_for_full_date = $tt_index % 10; // 0, 1, 2
1177
1178 if ( $is_bk_for_full_date == 1 ) {
1179 if ( !isset( $new_times_array_for_day_start[$tt_index_round] ) )
1180 $new_times_array_for_day_start[$tt_index_round] = array();
1181 $new_times_array_for_day_start[$tt_index_round] = array_merge( $new_times_array_for_day_start[$tt_index_round], array_values( $times_bk_id_array ) );
1182 }
1183 if ( $is_bk_for_full_date == 2 ) {
1184
1185 // Its mean that the booking is finished exactly at the beginig of this hour,
1186 // so we will not fill the end of booking in this hour, but in previous
1187 if ( ($tt_index_round - $tt_index) == -2 ) {
1188 $tt_index_round = $tt_index_round - 60 * 60;
1189 }
1190
1191 if ( !isset( $new_times_array_for_day_end[$tt_index_round] ) )
1192 $new_times_array_for_day_end[$tt_index_round] = array();
1193 $new_times_array_for_day_end[$tt_index_round] = array_merge( $new_times_array_for_day_end[$tt_index_round], array_values( $times_bk_id_array ) );
1194 }
1195 }
1196 $time_array[$key_date] = array( 'start' => $new_times_array_for_day_start, 'end' => $new_times_array_for_day_end );
1197 }
1198
1199 //debuge($time_array);
1200 //$time_array['2019-07-24']['start'][0] = $time_array['2019-07-24']['end'][82800];
1201
1202 /* $time_array
1203 [2012-12-24] => Array
1204 (
1205 [start] => Array (
1206 [68400] => Array ( [0] => 15 ) )
1207 [end] => Array (
1208 [64800] => Array ( [0] => 6 ) )
1209
1210 ) */
1211 $fill_this_date = array();
1212 //debuge($time_array_new['2017-01-13']);
1213
1214 //debuge($time_array_new);
1215 // Fil specific times based on start and end times
1216 foreach ( $time_array_new as $ddate => $ttime_round_array ) {
1217 foreach ( $ttime_round_array as $ttime_round => $bk_id_array ) { // [3600] => Array( [0] => Array ( [id] => 214 [resource] => 9 ), [1] => Array ( [id] => 154 [resource] => 7
1218
1219 //if ('2019-11-27' == $ddate ) {
1220 //debuge( ' $fill_this_date', $dates_array[ $ddate ], $fill_this_date );
1221 //}
1222
1223 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1224 /**
1225 * Search for situation, when at some previous date was started some booking at specific start time, like:
1226 * Booking #77: "October 30 18:00; December 4; December 25 20:00"
1227 * This booking exist in $fill_this_date - array ( [0] => array( [id] => 77, [resource] => 1 ) )
1228 *
1229 * but at current date "November 6" (where start other Booking #76: November 6 18:00; November 13; November 27 20:00"
1230 * this booking #77 does not exist at all !!!
1231 * so we nee to remove this booking(s) from array $fill_this_date
1232 */
1233 // FixIn: 8.7.1.1.
1234 if(1){
1235 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1236 // Search to remove
1237 $remove_arr_keys = array();
1238 foreach ( $fill_this_date as $is_remove_key => $is_remove_value ) {
1239 /**
1240 * Remove elements from $fill_this_date
1241 * if such elements does not exist in $dates_array[$ddate]
1242 */
1243 if ( ! in_array( $is_remove_value, $dates_array[ $ddate ] ) ) {
1244 $remove_arr_keys[] = $is_remove_key;
1245 //if ($is_remove_value['id']==76) {
1246 //debuge('$ddate,$ttime_round_array',$ddate);
1247 //}
1248 }
1249 }
1250 // Removing
1251 foreach ( $remove_arr_keys as $is_remove_key ) {
1252 unset($fill_this_date[$is_remove_key]); // Remove item at index 1 which is 'for'
1253 }
1254 $fill_this_date = array_values($fill_this_date); // Re-index the array elements
1255 }
1256 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1257
1258 //if ('2019-11-27' == $ddate ) {
1259 //debuge( 'updated $fill_this_date', $fill_this_date );
1260 //}
1261
1262
1263 if ( isset( $time_array[$ddate] ) ) {
1264
1265 if ( isset( $time_array[$ddate]['start'][$ttime_round] ) ) // array
1266 $fill_this_date = array_merge( $fill_this_date, array_values( $time_array[$ddate]['start'][$ttime_round] ) );
1267
1268 //debuge($fill_this_date);
1269
1270 $time_array_new[$ddate][$ttime_round] = array_merge( $time_array_new[$ddate][$ttime_round], $fill_this_date );
1271 //debuge('$ttime_round',$ttime_round);
1272 //debuge($ddate, $ttime_round, $time_array_new[$ddate][$ttime_round]);
1273
1274 //FixIn: 7.0.1.16 - advanced checking about delettion of times in $time_array[$ddate]['end']
1275
1276 // End array checking for deleting.
1277 if ( isset( $time_array[$ddate]['end'][$ttime_round] ) ) // array
1278 foreach ( $time_array[$ddate]['end'][$ttime_round] as $toDelete ) {
1279 //debuge($ddate, $ttime_round, $fill_this_date);
1280 //if ( $ddate == '2019-07-24' ) {
1281 // debuge('$toDelete, $fill_this_date',$toDelete, $fill_this_date);
1282 //}
1283 //debuge($toDelete);
1284 $fill_this_date_keys_to_delete = array();
1285 foreach ( $fill_this_date as $fill_this_date_key => $check_element_array ) { // [0] => Array ( [id] => 54 [resource] => 5 )
1286 //debuge($ddate,'$toDelete, $check_element_array', $toDelete, $check_element_array);
1287 if ( // Check if arrays equals - identical
1288 ( is_array( $toDelete ) && is_array( $check_element_array ) )
1289 && ( count( $toDelete ) == count( $check_element_array ) )
1290 && ( array_diff( $toDelete, $check_element_array ) === array_diff( $check_element_array, $toDelete ) )
1291 ) {
1292 $fill_this_date_keys_to_delete[] = $fill_this_date_key; // $toDelete element exist so save key in original array
1293 }
1294 }
1295
1296
1297 //FixIn: on 2019-07-24 14:22
1298 /**
1299 // Fix, when we are having END time but was not having START time (usually when first booking
1300 // was booked for entire day, and last day booking, have the end time.
1301 // So in this case at day with end time we need to fill all "round times" with End time data
1302 */
1303 // FixIn: 8.7.1.1.
1304 if(1)
1305 if ( empty( $fill_this_date_keys_to_delete ) ) {
1306 // Fill the date by data $toDelete
1307 foreach ( $time_array_new[ $ddate ] as $time_round_refill => $time_array_new_value_refill ) {
1308
1309 if ( $time_round_refill <= $ttime_round ) {
1310 // Refill
1311 $time_array_new[ $ddate ][ $time_round_refill ][] = $toDelete;
1312 }
1313 }
1314 }
1315
1316
1317 //debuge(' $fill_this_date_keys_to_delete ',$fill_this_date_keys_to_delete );
1318 $fill_this_date_new = array();
1319 foreach ( $fill_this_date as $fill_this_date_key => $fill_this_date_value ) {
1320 if ( ! in_array( $fill_this_date_key, $fill_this_date_keys_to_delete ) ) {
1321 $fill_this_date_new[] = $fill_this_date_value;
1322 }
1323 }
1324 $fill_this_date = $fill_this_date_new; // Reassign cleared array (with deleted values)
1325
1326 //debuge($toDelete);
1327 if ( !empty( $fill_this_date ) ) {
1328 // $fill_this_date = array_diff( $fill_this_date, array( $toDelete ) );
1329
1330 //if ( $ddate == '2017-01-13' ) {
1331 // debuge('AFTER:: $toDelete, $fill_this_date',$toDelete, $fill_this_date);
1332 //}
1333 }
1334 }
1335 }
1336 }
1337 }
1338 //debuge( '$dates_array, $time_array_new',$dates_array, $time_array_new );
1339 return array( $dates_array, $time_array_new );
1340 }
1341
1342
1343 // -----------------------------------------------------------------------------------------------------------------
1344 // C a l e n d a r T i m e l i n e ///////////////////////////////
1345 // -----------------------------------------------------------------------------------------------------------------
1346 private function wpbc_dates_only_of_specific_resource( $booked_dates_array, $resource_id, $bookings ) {
1347
1348 foreach ( $booked_dates_array as $key => $value ) {
1349
1350 $new_array = array();
1351 foreach ( $value as $bk_id ) {
1352 if ( $bk_id['resource'] == $resource_id ) {
1353 $new_array[] = $bk_id['id'];
1354 }
1355 }
1356 if ( !empty( $new_array ) )
1357 $booked_dates_array[$key] = $new_array;
1358 else
1359 unset( $booked_dates_array[$key] );
1360 }
1361 return $booked_dates_array;
1362 }
1363
1364
1365 private function wpbc_times_only_of_specific_resource( $time_array_new, $resource_id, $bookings ) {
1366
1367 foreach ( $time_array_new as $date_key => $times_array ) {
1368
1369 foreach ( $times_array as $time_key => $value ) {
1370
1371 $new_array = array();
1372 foreach ( $value as $bk_id ) {
1373
1374 if ( $bk_id['resource'] == $resource_id ) {
1375 $new_array[] = $bk_id['id'];
1376 }
1377 }
1378 $time_array_new[$date_key][$time_key] = $new_array;
1379 }
1380 }
1381 return $time_array_new;
1382 }
1383
1384
1385 private function wpbc_write_bk_id_css_classes( $prefix, $previous_booking_id ) {
1386
1387 if ( (!isset( $previous_booking_id )) || (empty( $previous_booking_id )) )
1388 return '';
1389
1390 if ( is_string( $previous_booking_id ) )
1391 $bk_id_array = explode( ',', $previous_booking_id );
1392 else if ( is_array( $previous_booking_id ) )
1393 $bk_id_array = $previous_booking_id;
1394 else // Some Unknown situation
1395 return '';
1396
1397 $bk_id_array = array_unique( $bk_id_array );
1398
1399 // If we are have several bookings, so add this special class
1400 if ( count( $bk_id_array ) > 1 )
1401 $css_class = 'here_several_bk_id ';
1402 else
1403 $css_class = '';
1404
1405 foreach ( $bk_id_array as $bk_id ) {
1406 $css_class .= $prefix . $bk_id . ' ';
1407 }
1408
1409 return $css_class;
1410 }
1411
1412
1413 // -----------------------------------------------------------------------------------------------------------------
1414 // Header
1415 // -----------------------------------------------------------------------------------------------------------------
1416 /** Header */
1417 public function wpbc_show_timeline_header_row( $start_date = false ) {
1418
1419 $current_resource_id = '';
1420 $is_matrix = $this->request_args['is_matrix'];
1421 $view_days_num = $this->request_args['view_days_num'];
1422 $start_hour_for_1day_view = 0; // FixIn: 7.0.1.14.
1423 $end_hour_for_1day_view = 24;
1424 $limit_hours = 24;
1425
1426 if ( $is_matrix ) {
1427
1428 // MATRIX VIEW
1429 switch ( $view_days_num ) {
1430 case '1':
1431 $days_num = 1;
1432 $dwa = $this->week_days_titles['full'];
1433 $time_selles_num = 24;
1434 if ( isset( $this->request_args[ 'limit_hours' ] ) ) { // FixIn: 7.0.1.14.
1435 $limit_hours = explode(',',$this->request_args[ 'limit_hours' ]);
1436 $start_hour_for_1day_view = intval( $limit_hours[0] );
1437 $end_hour_for_1day_view = intval( $limit_hours[1] );
1438 $limit_hours = $limit_hours[1] - $limit_hours[0];
1439 }
1440 break;
1441 case '7':
1442 $days_num = 7;
1443 //$dwa = $this->week_days_titles['3'];
1444 $dwa = $this->week_days_titles['1'];
1445 $time_selles_num = 1;
1446 break;
1447 case '30':
1448 $days_num = 31;
1449 $days_num = intval( wpbc_datetime__no_wp_timezone('t',$start_date) ); // num of days in the specific month, wchih relative to $real_date from header // FixIn: 7.0.1.47.
1450 $dwa = $this->week_days_titles['1'];
1451 $time_selles_num = 1;
1452 break;
1453 case '60':
1454 $days_num = 62;
1455 //$dwa = $this->week_days_titles['short'];
1456 $dwa = $this->week_days_titles['1'];
1457 $time_selles_num = 1;
1458 break;
1459 default: // 30
1460 $days_num = 31;
1461 $dwa = $this->week_days_titles['3'];
1462 $time_selles_num = 1;
1463 break;
1464 }
1465
1466 } else {
1467
1468 switch ( $view_days_num ) {
1469 case '90':
1470 $days_num = 7;
1471 $dwa = $this->week_days_titles['3'];
1472 $time_selles_num = 1;
1473 break;
1474 case '365':
1475 $days_num = 31; // FixIn: 8.7.6.5.
1476 //$days_num = intval( wpbc_datetime__no_wp_timezone('t',$start_date) ); // num of days in the specific month, wchih relative to $real_date from header // FixIn: 7.0.1.47.
1477 $dwa = $this->week_days_titles['3'];
1478 $time_selles_num = 1;
1479 break;
1480 default: // 30
1481 $days_num = 1;
1482 $dwa = $this->week_days_titles['full'];
1483 $time_selles_num = 24;
1484 if ( isset( $this->request_args[ 'limit_hours' ] ) ) { // FixIn: 7.0.1.14.
1485 $limit_hours = explode(',',$this->request_args[ 'limit_hours' ]);
1486 $start_hour_for_1day_view = intval( $limit_hours[0] );
1487 $end_hour_for_1day_view = intval( $limit_hours[1] );
1488 $limit_hours = $limit_hours[1] - $limit_hours[0];
1489 }
1490 break;
1491 }
1492 }
1493
1494 if ( $start_date === false ) {
1495
1496 if ( ! empty( $this->request_args['scroll_start_date'] ) )
1497 list( $start_year, $start_month, $start_day ) = explode( '-', $this->request_args['scroll_start_date'] ); // scroll_start_date=2013-07-01
1498 else
1499 list( $start_year, $start_month, $start_day ) = explode( '-', wpbc_datetime__no_wp_timezone( 'Y-n-j' ) );
1500
1501 } else {
1502 list( $start_year, $start_month, $start_day ) = explode( '-', wpbc_datetime__no_wp_timezone( 'Y-m-d', $start_date ) );
1503 }
1504
1505 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1506 // Month Line
1507 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1508 ?><div class="flex_tl_dates_bar flex_tl_dates_bar_month"><?php
1509 $previous_month = '';
1510 //Scroll months Firstly
1511 for ( $d_inc = 0; $d_inc < $days_num; $d_inc++ ) {
1512
1513 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $d_inc ) ), intval( $start_year ) );
1514 $yy = wpbc_datetime__no_wp_timezone( "Y", $real_date ); //2012
1515 $mm = wpbc_datetime__no_wp_timezone( "m", $real_date ); //09
1516 $dd = wpbc_datetime__no_wp_timezone( "d", $real_date ); //31
1517 $ww = wpbc_datetime__no_wp_timezone( "N", $real_date ); //7
1518 $day_week = $dwa[$ww]; //Su
1519
1520 $month_title = '';
1521 $month_class = '';
1522
1523
1524 if ( ($view_days_num == 30) || ($view_days_num == 60) ) {
1525 if (( (intval($ww)-1) === intval(get_bk_option( 'booking_start_day_weeek' )) )){
1526 $month_class = ' new_month ';
1527 }
1528 } else {
1529 if(( $previous_month != $mm ) || ( 1 == $dd )){
1530 $month_class = ' new_month ';
1531 }
1532 }
1533 if ($month_class == ' new_month '){
1534 $previous_month = $mm;
1535 $month_title = wpbc_datetime__no_wp_timezone( "F", $real_date ); //09
1536 }
1537
1538 ?>
1539 <div class="<?php echo implode(' ', array(
1540 'flex_tl_day_cell',
1541 'flex_tl_day_cell_header',
1542 'flex_time_in_days_num_' . esc_attr( $view_days_num ),
1543 esc_attr( $month_class )
1544 )); ?>"
1545 ><?php
1546 // New Month !
1547 if ( $month_title != '' ) {
1548 ?>
1549 <div class="in_cell_month_year"><?php
1550
1551 if ( $is_matrix ) {
1552
1553 echo esc_attr( $dd . ' ' . $month_title . ', ' . $yy );
1554
1555 if ( '1' == $view_days_num ) {
1556 echo ' &nbsp; (' . esc_attr( $day_week ) . ')';
1557 }
1558
1559 } else {
1560 if ( '30' == $view_days_num ) {
1561 //echo '(' . esc_attr($day_week) . ') &nbsp; ' . esc_attr($dd) . ' ';
1562 }
1563 }
1564 ?></div><?php
1565 }
1566 ?> </div> <?php
1567 }
1568 ?>
1569 </div><?php
1570
1571
1572 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1573 // Dates / Times Line
1574 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1575 ?><div class="flex_tl_dates_bar <?php echo esc_attr( $is_matrix ? ' flex_tl_matrix_resources ' : ' flex_tl_single_resource ' ); ?>"
1576 id="timeline_scroller<?php echo esc_attr( $current_resource_id ); ?>"
1577 ><?php
1578 $previous_month = '';
1579
1580 $bk_admin_url_today = wpbc_get_params_in_url( wpbc_get_bookings_url( false, false ), array( 'scroll_month', 'scroll_day', 'scroll_start_date' ) );
1581
1582 for ( $d_inc = 0; $d_inc < $days_num; $d_inc++ ) {
1583
1584 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $d_inc ) ), intval( $start_year ) );
1585
1586 if ( wpbc_datetime__no_wp_timezone( 'm.d.Y' ) == wpbc_datetime__no_wp_timezone( "m.d.Y", $real_date ) )
1587 $is_today = ' today_date ';
1588 else
1589 $is_today = '';
1590
1591 $yy = wpbc_datetime__no_wp_timezone( "Y", $real_date ); //2012
1592 $mm = wpbc_datetime__no_wp_timezone( "m", $real_date ); //09
1593 $dd = wpbc_datetime__no_wp_timezone( "d", $real_date ); //31
1594 $ww = wpbc_datetime__no_wp_timezone( "N", $real_date ); //7
1595 $day_week = $dwa[$ww]; //Su
1596
1597 $day_title = $dd . ' ' . $day_week;
1598 if ( $is_matrix ) {
1599 if ( $view_days_num == 1 ) {
1600 $day_title = '<div class="in_cell_day_num">' . esc_html__( 'Times', 'booking' ) . '</div>';
1601 }
1602 if ( $view_days_num == 7 ) {
1603 $day_title = '<div class="in_cell_day_num">' . $dd . '</div><div class="in_cell_day_week">' . $day_week . '</div>';
1604 }
1605 if ( $view_days_num == 30 ) {
1606 $day_title = '<div class="in_cell_day_num">' . $dd . '</div><div class="in_cell_day_week">' . $day_week . '</div>';
1607 }
1608 if ( $view_days_num == 60 ) {
1609 $day_title = '<div class="in_cell_day_num">' . $dd . '</div><div class="in_cell_day_week">' . $day_week . '</div>';
1610 }
1611 } else {
1612 if ( $view_days_num == 30 ) {
1613 $day_title = '<div class="in_cell_day_num">' . esc_html__( 'Times', 'booking' ) . '</div>';
1614 }
1615 if ( $view_days_num == 90 ) {
1616 $day_title = '<div class="in_cell_day_week">' . $day_week . '</div>';
1617 }
1618 if ( $view_days_num == 365 ) {
1619 $day_title = '<div class="in_cell_day_num">' . $dd . '</div>';
1620 }
1621 }
1622 $day_filter_id = $yy . '-' . $mm . '-' . $dd;
1623
1624 if ( ( $previous_month != $mm ) || ( 1 == $dd ) ) {
1625 $previous_month = $mm;
1626 $month_class = ' new_month ';
1627 } else {
1628 $month_class = '';
1629 }
1630
1631 ?>
1632 <div id="cell_<?php echo esc_attr( $current_resource_id . '_' . $day_filter_id ); ?>"
1633 class="<?php echo esc_attr( implode(' ', array(
1634 'flex_tl_day_cell',
1635 'flex_tl_day_cell_header',
1636 'flex_time_in_days_num_' . $view_days_num,
1637 'flex_tl_weekday' . $ww,
1638 $day_filter_id,
1639 $month_class
1640 ))); ?>"
1641 ><?php
1642
1643 if ( ( $is_matrix ) && ( ( $view_days_num == 30 ) || ( $view_days_num == 60 ) ) ) {
1644
1645 ?><div class="in_cell_date_container day_num<?php echo esc_attr( $d_inc ); ?>"><?php
1646
1647 if ( ! $this->is_frontend ) {
1648 ?><a href='<?php echo esc_url( $bk_admin_url_today . '&scroll_start_date=' . $yy . '-' . $mm . '-' . $dd ); ?>'><?php
1649 }
1650 echo wp_kses_post( $day_title );
1651
1652 if ( ! $this->is_frontend ) {
1653 ?></a><?php
1654 }
1655
1656 ?></div><?php
1657
1658 } else {
1659 ?>
1660 <div class="in_cell_date_container day_num<?php echo esc_attr( $d_inc ); ?>"><?php echo wp_kses_post( $day_title ); ?></div><?php
1661 }
1662
1663 ////////////////////////////////////////////////////////////////////////////////////////
1664 // T i m e c e l l s
1665 ////////////////////////////////////////////////////////////////////////////////////////
1666 $tm = floor( 24 / $time_selles_num );
1667 if ( $time_selles_num > 1 ) {
1668 ?><div class="<?php echo esc_attr( implode(' ', array(
1669 'in_cell_time_section_in_day',
1670 'flex_time_section_in_day_header',
1671 'flex_time_in_days_num_' . $view_days_num
1672 ) ) ); ?>"><?php
1673
1674 for ( $tt = 0; $tt < $time_selles_num; $tt++ ) { ?>
1675
1676 <?php if ( ( $tt < $start_hour_for_1day_view ) || ( $tt > $end_hour_for_1day_view ) ) { continue; } //FixIn: 7.0.1.14 ?>
1677
1678 <div class="<?php echo esc_attr( 'in_cell_time_hour time_hour' . ( $tt * $tm ) ); ?>" ><?php
1679
1680 $this->show_time_number_in_correct_format( $tt * $tm , $view_days_num );
1681
1682 ?></div><?php
1683 }
1684 ?></div><?php
1685 }
1686 ?></div><?php
1687
1688 }
1689 ?></div><?php
1690
1691 return $real_date ;
1692 }
1693
1694
1695 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1696 // Booking Row Support functions
1697 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1698
1699 /**
1700 * Define Init Row settings parameters
1701 *
1702 * @param $row_settings array
1703 *
1704 * @return array
1705 */
1706 private function get_init_row_settings( $row_settings ){
1707
1708 // Initial params
1709 $row_settings['is_matrix'] = $this->request_args['is_matrix'];
1710 $row_settings['start_hour_for_1day_view'] = 0;
1711 $row_settings['end_hour_for_1day_view'] = 24;
1712 $row_settings['limit_hours'] = 24;
1713 $row_settings['view_days_num'] = $this->request_args['view_days_num'];
1714
1715 // Single booking resource
1716 if ( ! $row_settings['is_matrix'] ) {
1717
1718 switch ($row_settings['view_days_num']) {
1719 case '90':
1720 $row_settings['days_num'] = 7;
1721 $row_settings['dwa'] = $this->week_days_titles['full'];
1722 $row_settings['time_selles_num'] = 1;
1723 break;
1724 case '365':
1725 $row_settings['days_num'] = 31;
1726 //$row_settings['days_num'] = intval( wpbc_datetime__no_wp_timezone('t',$row_settings['start_date']) ); // num of days in the specific month, wchih relative to $row_settings['real_date'] from header // FixIn: 7.0.1.47.
1727 $row_settings['dwa'] = $this->week_days_titles['1'];
1728 $row_settings['time_selles_num'] = 1;
1729 break;
1730 default: // 30
1731 $row_settings['days_num'] = 1;
1732 $row_settings['dwa'] = $this->week_days_titles['3'];
1733 $row_settings['time_selles_num'] = 24;//25;
1734
1735 if ( isset( $this->request_args[ 'limit_hours' ] ) ) { // FixIn: 7.0.1.14.
1736 $row_settings['limit_hours'] = explode(',',$this->request_args[ 'limit_hours' ]);
1737 $row_settings['start_hour_for_1day_view'] = intval( $row_settings['limit_hours'][0] );
1738 $row_settings['end_hour_for_1day_view'] = intval( $row_settings['limit_hours'][1] );
1739 $row_settings['limit_hours'] = $row_settings['limit_hours'][1] - $row_settings['limit_hours'][0];
1740 }
1741
1742 //$row_settings['view_days_num'] = 1;
1743 break;
1744 }
1745
1746 } else { // Multiple booking resources
1747
1748 //$row_settings['view_days_num'] = 365;
1749 switch ($row_settings['view_days_num']) {
1750 case '1':
1751 $row_settings['days_num'] = 1;
1752 $row_settings['dwa'] = $this->week_days_titles['full'];
1753 $row_settings['time_selles_num'] = 24;
1754
1755 if ( isset( $this->request_args[ 'limit_hours' ] ) ) { // FixIn: 7.0.1.14.
1756 $row_settings['limit_hours'] = explode(',',$this->request_args[ 'limit_hours' ]);
1757 $row_settings['start_hour_for_1day_view'] = intval( $row_settings['limit_hours'][0] );
1758 $row_settings['end_hour_for_1day_view'] = intval( $row_settings['limit_hours'][1] );
1759 $row_settings['limit_hours'] = $row_settings['limit_hours'][1] - $row_settings['limit_hours'][0];
1760 }
1761
1762 break;
1763 case '7':
1764 $row_settings['days_num'] = 7;
1765 $row_settings['dwa'] = $this->week_days_titles['full'];
1766 $row_settings['time_selles_num'] = 1;
1767 break;
1768 case '60':
1769 $row_settings['days_num'] = 62;
1770 $row_settings['dwa'] = $this->week_days_titles['1'];
1771 $row_settings['time_selles_num'] = 1;
1772 break;
1773 case 'old_365':
1774 $row_settings['days_num'] = 365;
1775 $row_settings['time_selles_num'] = 1;
1776 $row_settings['dwa'] = $this->week_days_titles['1'];
1777 break;
1778
1779 default: // 30
1780 $row_settings['days_num'] = 32;
1781 $row_settings['days_num'] = intval( wpbc_datetime__no_wp_timezone('t',$row_settings['start_date']) ); // num of days in the specific month, wchih relative to $row_settings['real_date'] from header // FixIn: 7.0.1.47.
1782 $row_settings['dwa'] = $this->week_days_titles['3'];
1783 $row_settings['time_selles_num'] = 1;//25;
1784 break;
1785 }
1786 }
1787
1788 return $row_settings;
1789 }
1790
1791
1792 /**
1793 * Show time in correct format - showing in Header, and in time CELLs
1794 *
1795 * @param $time_milliseconds
1796 * @param $view_days_num
1797 */
1798 private function show_time_number_in_correct_format( $time_milliseconds, $view_days_num ) {
1799
1800 // FixIn: 8.1.3.34.
1801 $bc_time_format = get_bk_option( 'booking_time_format' );
1802 if ( ! empty( $bc_time_format ) ) { // FixIn: 8.2.1.2.
1803 $time_show = wpbc_datetime__no_wp_timezone( str_replace( ':i', '', get_bk_option( 'booking_time_format' ) ), mktime( intval( $time_milliseconds ), 0, 0 ) );
1804 echo wp_kses_post( ( $view_days_num < 31 ) ? $time_show : '' );
1805 } else {
1806 echo wp_kses_post( ( $view_days_num < 31 ) ? ( ( ( $time_milliseconds ) < 10 ? '0' : '' ) . ( $time_milliseconds ) . '<sup>:00</sup>' ) : '' );
1807 }
1808 }
1809
1810
1811 /**
1812 * Is show Day View ( showing days || times )
1813 *
1814 * @param $row_settings
1815 *
1816 * @return bool
1817 */
1818 private function is_show_day_view( $row_settings ) {
1819 if (
1820 ( ( 30 == $row_settings['view_days_num'] ) && ( ! $row_settings['is_matrix'] ) ) // Day View for Single
1821 || ( ( 1 == $row_settings['view_days_num'] ) && ( $row_settings['is_matrix'] ) ) // Day View for Matrix
1822 ) {
1823 return true;
1824 } else {
1825 return false;
1826 }
1827 }
1828
1829
1830 /**
1831 * Check, if starting new booking (something changed) relative to previous CELL
1832 *
1833 * @param array $bookings_in_cell
1834 * @param array $previous_bookings_in_cell
1835 *
1836 * @return bool
1837 */
1838 private function is_start_new_booking_cell( $bookings_in_cell, $previous_bookings_in_cell ) {
1839
1840 $bookings_in_cell = implode( '|', $bookings_in_cell );
1841 $previous_bookings_in_cell = implode( '|', $previous_bookings_in_cell );
1842
1843 if ( $bookings_in_cell !== $previous_bookings_in_cell ) {
1844 return true;
1845 } else {
1846 return false;
1847 }
1848 }
1849
1850
1851 /**
1852 * Check method 2, if starting new booking (something changed) relative to previous CELL
1853 *
1854 * @param array $bookings_in_cell
1855 * @param array $previous_bookings_in_cell
1856 *
1857 * @return bool
1858 */
1859 private function is_start_new_booking_cell2( $bookings_in_cell, $previous_bookings_in_cell ) {
1860
1861 $bookings_in_cell = implode( '|', $bookings_in_cell );
1862 $previous_bookings_in_cell = implode( '|', $previous_bookings_in_cell );
1863
1864 $bookings_in_cell_arr = explode( '|', $bookings_in_cell );
1865 $previous_bookings_in_cell_arr = explode( '|', $previous_bookings_in_cell );
1866
1867 $is_check1 = empty( array_diff( $bookings_in_cell_arr, $previous_bookings_in_cell_arr ) );
1868 $is_check2 = empty( array_diff( $previous_bookings_in_cell_arr, $bookings_in_cell_arr ) );
1869
1870 return ( ( ! $is_check1 ) && ( ! $is_check2 ) );
1871 }
1872
1873 /**
1874 * Get Text for booking Title in PIPELINE
1875 *
1876 * @param $bk_id
1877 * @param $bookings
1878 *
1879 * @return string
1880 */
1881 private function get_booking_title_for_timeline( $bk_id, $bookings ){
1882
1883 $text_in_day_cell = '';
1884
1885 if ( $this->is_frontend ) $what_show_in_day_template = get_bk_option( 'booking_default_title_in_day_for_timeline_front_end' );
1886 else $what_show_in_day_template = get_bk_option( 'booking_default_title_in_day_for_calendar_view_mode' );
1887
1888 if ( function_exists( 'get_title_for_showing_in_day' ) ) {
1889 $text_in_day_cell .= esc_textarea( get_title_for_showing_in_day( $bk_id, $bookings, $what_show_in_day_template ) ); // FixIn: 7.1.1.2.
1890 } else {
1891 if ( ! $this->is_frontend ) {
1892 // Default Free // FixIn: 7.1.1.2.
1893 $text_in_day_cell .= $bk_id . ':' ;
1894 if ( isset( $bookings[ $bk_id ]->form_data['_all_fields_']['name'] ) ) {
1895 $text_in_day_cell .= ' ' . esc_textarea( $bookings[ $bk_id ]->form_data['_all_fields_']['name'] );
1896 }
1897 // FixIn: 10.0.0.24.
1898 if ( isset( $bookings[ $bk_id ]->form_data['_all_fields_']['secondname'] ) ) {
1899 $text_in_day_cell .= ' ' . esc_textarea( $bookings[ $bk_id ]->form_data['_all_fields_']['secondname'] );
1900 }
1901 if ( isset( $bookings[ $bk_id ]->form_data['_all_fields_']['lastname'] ) ) {
1902 $text_in_day_cell .= ' ' . esc_textarea( $bookings[ $bk_id ]->form_data['_all_fields_']['lastname'] );
1903 }
1904 }
1905 }
1906
1907 return $text_in_day_cell;
1908 }
1909
1910
1911 /**
1912 * Title, when mouse-over booking Pipeline (bar with background)
1913 *
1914 * @param $booking_id
1915 * @param $row_settings
1916 */
1917 private function show_booking_title_for_pipeline_bar( $booking_id, $row_settings ){
1918
1919 // FixIn: 8.7.1.4.
1920 $bk_title = '';
1921
1922 $is_date = wpbc_get_date_in_correct_format( wpbc_datetime__no_wp_timezone( "Y-m-d", $row_settings['real_date'] ) );
1923 if ( ( is_array( $is_date ) ) && ( ! empty( $is_date ) ) ) {
1924 $bk_title = $is_date[0];
1925 }
1926
1927 $bk_title .= " \n" . $this->get_booking_title_for_timeline( $booking_id, $row_settings['bookings'] );
1928
1929 $bk_title .= " \n" . wp_strip_all_tags( wpbc_get_short_dates_formated_to_show( $row_settings['bookings'][ $booking_id ]->dates_short ) ) ;
1930
1931 $bk_title = apply_filters( 'wpbc_timeline_booking_pipeline_title', $bk_title, $booking_id, $row_settings['bookings'] );
1932
1933 ?><a href="javascript:void(0)"
1934 class="in_cell_date_booking_pipeline_a"
1935 title="<?php echo esc_attr( $bk_title ); ?>"
1936 ><?php
1937 ?><div class="in_cell_date_booking_pipeline_a_sizer"></div><?php
1938 ?></a><?php
1939 }
1940
1941
1942 /**
1943 * Show booking TITLE in PIPELINE
1944 *
1945 * @param $bookings_in_cell
1946 * @param $row_settings
1947 */
1948 private function show_booking_title_for_timeline( $bookings_in_cell, $row_settings ){
1949
1950 $bk_a_title_arr = array();
1951 $popup_content_arr = array();
1952 $popup_title_arr = array();
1953
1954 $is_show_popover_in_timeline = wpbc_is_show_popover_in_flex_timeline( $this->is_frontend, $this->request_args['booking_hash'] ); // FixIn: 8.1.3.5.
1955
1956 foreach ( $bookings_in_cell as $booking_id ) {
1957
1958 $bk_a_title = $this->get_booking_title_for_timeline( $booking_id, $row_settings['bookings'] );
1959 $bk_a_title = htmlspecialchars_decode( $bk_a_title, ENT_NOQUOTES ); // FixIn: 8.7.11.5.
1960 $bk_a_title_arr[] = $bk_a_title;
1961
1962 $title_in_day = $title = $title_hint = '';
1963
1964 $can_show_booking_popover = $is_show_popover_in_timeline && $this->wpbc_is_booking_authorized_for_hash( $booking_id, $row_settings['bookings'] );
1965 if ( $can_show_booking_popover ) {
1966 $popup_content = $this->wpbc_get_booking_info_4_popover( $booking_id, $row_settings['bookings'], $row_settings['booking_types'] );
1967
1968
1969 $popup_title_arr[] = $popup_content['title'];
1970 //FixIn: 9.7.4.1 - escape coded html/xss
1971 $popup_content_arr[] = '<div class="popover-title">' . esc_html($popup_content['title']) . '</div><div class="popover-content">' . esc_html( $popup_content['content'] ) . '</div>';
1972 }
1973 //$popup_content_arr[] = $bk_a_title . ': ' . wp_strip_all_tags( wpbc_get_short_dates_formated_to_show( $row_settings['bookings'][ $booking_id ]->dates_short ) ) ;
1974 }
1975
1976 // Title A link
1977 $bk_a_title__text = implode( ', ', $bk_a_title_arr );
1978
1979 if ( strlen( $bk_a_title__text ) > 20 ) {
1980 $bk_a_title__text = substr( $bk_a_title__text, 0, 20 ) . '...';
1981 }
1982 if ( count( $bookings_in_cell ) > 1 ) {
1983
1984 if ( ! $this->is_bookings_use_check_in_out( $bookings_in_cell, $row_settings['bookings'] ) ) {
1985 $bk_a_title__text = '<sup>[' . count( $bookings_in_cell ) . ']</sup> ' . $bk_a_title__text;
1986 } else {
1987 //return; // FixIn: 10.6.3.1.
1988 }
1989
1990 }
1991
1992
1993 if ( ! $this->is_frontend ) { $line_separator = '<div class=\'clear\'></div>'; }
1994 else { $line_separator = ''; }
1995 $popup_title_arr = implode( $line_separator, $popup_title_arr );
1996
1997 $line_separator = ''; // '<hr class="wpbc_tl_popover_booking_separator" />';
1998 $popup_content_arr = implode( $line_separator, $popup_content_arr );
1999
2000 // Booking CELL Title
2001 ?><a href="javascript:void(0)"
2002 class="<?php echo esc_attr( implode(' ', array(
2003 'in_cell_date_booking_title',
2004 ( ! empty( $popup_content_arr ) ) ? 'popover_bottom' : '',
2005 ( ! empty( $popup_content_arr ) ) ? 'popover_click' : '',
2006 ( count( $bookings_in_cell ) > 1 ) ? 'several_bookings_in_cell' : ''
2007 ))); ?>"
2008 <?php
2009 // FixIn: 8.9.3.3.
2010 if ( ! empty( $popup_content_arr ) ) { ?>
2011 data-content="<?php echo esc_html( str_replace( '"', "", $popup_content_arr ) ); ?>"
2012 data-original-title="<?php echo esc_html( str_replace( '"', "", $popup_title_arr ) ); ?>"
2013 <?php } ?>
2014 ><?php
2015 echo wp_kses_post( $bk_a_title__text );
2016 ?></a><?php
2017 }
2018
2019 /**
2020 * Check if some bookings used check in / out functionality
2021 *
2022 * @param $bookings_id_arr
2023 * @param $bookings_obj_arr
2024 *
2025 * @return false
2026 */
2027 function is_bookings_use_check_in_out( $bookings_id_arr, $bookings_obj_arr ) {
2028
2029 // -----------------------------------------------------------------------------------------------------
2030 // Is Check In/out ?
2031 // -----------------------------------------------------------------------------------------------------
2032 $is_use_check_in_out_time = ( get_bk_option( 'booking_range_selection_time_is_active' ) == 'On' );
2033
2034 if ( $is_use_check_in_out_time ) {
2035 foreach ( $bookings_id_arr as $booking_id ) {
2036
2037 if ( isset( $bookings_obj_arr[ $booking_id ] ) ) {
2038 foreach ( $bookings_obj_arr[ $booking_id ]->dates as $booking_date_obj ) {
2039 $booking_date_ymdhis = $booking_date_obj->booking_date;
2040
2041 $is_check_in_out__or_full = substr( $booking_date_ymdhis, - 1 ); // '1', '2' (not '0')
2042
2043 if ( '1' === $is_check_in_out__or_full ) {
2044 return true;
2045 }
2046 if ( '2' === $is_check_in_out__or_full ) {
2047 return true;
2048 }
2049 }
2050 }
2051 }
2052 }
2053 return false;
2054 }
2055
2056
2057 /**
2058 * Get array of CSS classes for booking bar
2059 * @param int $booking_id
2060 * @param array $bookings
2061 *
2062 * @return array
2063 */
2064 function get_booking_class_arr( $booking_id, $row_settings , $real_date, $time_hour ){
2065
2066 $bookings = $row_settings['bookings'];
2067
2068 $class_arr = array();
2069
2070 if ( ( ! empty( $booking_id ) ) && isset( $bookings[ $booking_id ] ) ) {
2071
2072 // Appoved | Pending
2073 if ( count( $bookings[ $booking_id ]->dates ) > 0 ) {
2074 $is_approved = $bookings[ $booking_id ]->dates[0]->approved;
2075 } else {
2076 $is_approved = 0;
2077 }
2078 $class_arr[] = $is_approved ? 'approved_booking' : 'pending_booking';
2079
2080 // -----------------------------------------------------------------------------------------------------
2081 // Is Check In/out ?
2082 // -----------------------------------------------------------------------------------------------------
2083 $is_use_check_in_out_time = ( get_bk_option( 'booking_range_selection_time_is_active' ) == 'On' );
2084 $one_date__one_booking__check_in_out__arr = array();
2085 if (
2086 ( $is_use_check_in_out_time )
2087 && ( ( $row_settings['is_matrix'] ) || ( 30 != $row_settings['view_days_num'] ) )
2088 && ( ( ! $row_settings['is_matrix'] ) || ( 1 != $row_settings['view_days_num'] ) )
2089 ){
2090 $real_date_ymd = wpbc_datetime__no_wp_timezone( "Y-m-d", $real_date );
2091 foreach ( $bookings[ $booking_id ]->dates as $booking_date_obj ) {
2092 $booking_date_ymdhis = $booking_date_obj->booking_date;
2093 if ( substr( $booking_date_ymdhis, 0, 10 ) === $real_date_ymd ) {
2094 $is_check_in_out__or_full = substr( $booking_date_ymdhis, -1 ); // '1', '2' (not '0')
2095
2096 if ('1'=== $is_check_in_out__or_full ){
2097 $one_date__one_booking__check_in_out__arr[] = 'booking_check_in';
2098 }
2099 if ('2'=== $is_check_in_out__or_full ){
2100 $one_date__one_booking__check_in_out__arr[] = 'booking_check_out';
2101 }
2102 //break;
2103 }
2104 }
2105 }
2106 // If we have 2 or more like: [ 'booking_check_in', 'booking_check_out' ], in the same date for same booking, then it is time slots bookings
2107 if ( count( $one_date__one_booking__check_in_out__arr ) == 1 ) {
2108 $class_arr[] = $one_date__one_booking__check_in_out__arr[0];
2109 $class_arr[] = 'booking_change_over';
2110 }
2111 if ( count( $one_date__one_booking__check_in_out__arr ) > 1 ) {
2112 $class_arr[] = 'booking_time_slots';
2113 }
2114
2115 // -----------------------------------------------------------------------------------------------------
2116
2117 if ( isset( $bookings[ $booking_id ]->trash ) ) {
2118 $is_trash = $bookings[ $booking_id ]->trash;
2119 } else {
2120 $is_trash = false;
2121 }
2122 $class_arr[] = $is_trash ? 'booking_trash' : '';
2123
2124 /////////////////////////////////////////////////////////////////
2125
2126 if ( ( isset( $bookings[ $booking_id ]->form_data['email'] ) )
2127 && (
2128 ( 'blank@wpbookingmanager.com' == $bookings[ $booking_id ]->form_data['email'] )
2129 || ( 'admin@blank.com' == $bookings[ $booking_id ]->form_data['email'] )
2130 )
2131 ) {
2132 $is_blank_bookings = true;
2133 } else {
2134 $is_blank_bookings = false;
2135 }
2136 $class_arr[] = $is_blank_bookings ? 'booking_blank' : '';
2137
2138 /////////////////////////////////////////////////////////////////
2139
2140 if ( wpbc_datetime__no_wp_timezone( 'Y.m.d' ) > wpbc_datetime__no_wp_timezone( "Y.m.d", $real_date ) ) {
2141 $class_arr[] = 'past_date';
2142 }
2143 if ( wpbc_datetime__no_wp_timezone( 'Y.m.d' ) == wpbc_datetime__no_wp_timezone( "Y.m.d", $real_date ) ) {
2144 $class_arr[] = 'today_date';
2145 }
2146
2147 if ( $this->is_show_day_view( $row_settings ) ) {
2148 if ( ( wpbc_datetime__no_wp_timezone( 'm.d.Y' ) == wpbc_datetime__no_wp_timezone( "m.d.Y", $real_date ) ) // Today Date
2149 && ( intval( wpbc_datetime__no_wp_timezone( 'H' ) ) > intval( $time_hour ) ) ) {
2150 $class_arr[] = 'past_date';
2151 }
2152 }
2153 /////////////////////////////////////////////////////////////////
2154
2155 $css_class_additional = apply_filters( 'wpbc_timeline_booking_header_css', '', $booking_id, $bookings ); // FixIn: 7.0.1.41.
2156 $class_arr[] = $css_class_additional;
2157 }
2158
2159 // Remove empty values from array
2160 $class_arr = array_filter( $class_arr );
2161
2162 return $class_arr;
2163 }
2164
2165
2166 /**
2167 * Show Date cell :: 3 variants :: Date Number | Booking Pipeline | Booking Title
2168 * @param $row_settings
2169 */
2170 private function show_day_cell( $row_settings ){
2171
2172 $data_in_previous_cell = $this->data_in_previous_cell;
2173
2174 $yy = wpbc_datetime__no_wp_timezone( "Y", $row_settings[ 'real_date' ] ); // 2012
2175 $mm = wpbc_datetime__no_wp_timezone( "m", $row_settings[ 'real_date' ] ); // 09
2176 $dd = wpbc_datetime__no_wp_timezone( "d", $row_settings[ 'real_date' ] ); // 31
2177 $ww = wpbc_datetime__no_wp_timezone( "N", $row_settings[ 'real_date' ] ); // 7
2178 $day_week = $row_settings[ 'dwa' ][$ww]; // Su
2179
2180 $row_settings['day_filter_id'] = $yy . '-' . $mm . '-' . $dd;
2181
2182
2183 // <editor-fold defaultstate="collapsed" desc=" = $bookings_in_day_cell - Array of booking ID - Sorted by Time in this date cell = " >
2184
2185 $bookings_in__times_arr = array();
2186 /**
2187 * $bookings_in__times_arr = array( [0] => array( [0] => 918, [1] => 917 ), [3600] => array( [0] => 918 [1] => 917 ), ...
2188 [82800] => Array (
2189 [0] => 918
2190 [1] => 917
2191 )
2192 )
2193 */
2194 if ( ! empty ( $row_settings['time_array_new'][ $row_settings['day_filter_id'] ] ) ) { // $row_settings['time_array_new'][ '2019-07-19' ]
2195 $bookings_in__times_arr = $row_settings['time_array_new'][ $row_settings['day_filter_id'] ];
2196 }
2197
2198 $bookings_in_day_cell = array();
2199 if ( ! empty ( $bookings_in__times_arr ) ) {
2200 foreach ( $bookings_in__times_arr as $times_milliseconds => $bookings_in_times_arr ) {
2201
2202 foreach ( $bookings_in_times_arr as $booking_id_in_time_interval ) {
2203
2204 if ( ! in_array( $booking_id_in_time_interval, $bookings_in_day_cell ) ) {
2205 /**
2206 * Array ( [0] => 15 [1] => 16 [2] => 13 [3] => 14 )
2207 */
2208 $bookings_in_day_cell[] = $booking_id_in_time_interval;
2209 }
2210 }
2211 }
2212 }
2213 // </editor-fold>
2214
2215 //debuge($bookings_in__times_arr);
2216 // <editor-fold defaultstate="collapsed" desc=" = $cell_css[] - Define CSS classes of day cell = " >
2217
2218 $cell_css = array();
2219 $cell_css[] = 'flex_tl_day_cell';
2220 $cell_css[] = 'flex_tl_weekday' . $ww;
2221 $cell_css[] = $row_settings['day_filter_id'];
2222
2223 if ( wpbc_datetime__no_wp_timezone( 'm.d.Y' ) == wpbc_datetime__no_wp_timezone( "m.d.Y", $row_settings['real_date'] ) ) {
2224 $cell_css[] = 'today_date';
2225 } else if ( wpbc_datetime__no_wp_timezone( 'Y.m.d' ) > wpbc_datetime__no_wp_timezone( "Y.m.d", $row_settings['real_date'] ) ) {
2226 $cell_css[] = 'past_date';
2227 }
2228
2229 if ( ( $data_in_previous_cell['previous_month'] != $mm ) || ( 1 == $dd ) ) {
2230
2231 $data_in_previous_cell['previous_month'] = $mm;
2232 $cell_css[] = 'new_month';
2233 }
2234
2235 if ( ! empty( $bookings_in_day_cell ) ) {
2236 $cell_css[] = 'exist_booking_in_cell';
2237 } else {
2238 $cell_css[] = 'no_booking_in_cell';
2239 }
2240
2241 // </editor-fold>
2242
2243
2244 ?><div id="cell_<?php echo esc_attr( $row_settings[ 'current_resource_id' ] . '_' . $row_settings['day_filter_id'] ); ?>"
2245 class="<?php echo esc_attr( implode(' ', $cell_css ) ); ?>"
2246 ><?php
2247
2248 ////////////////////////////////////////////////////////////////////////////////////////
2249 // T i m e c e l l s
2250 ////////////////////////////////////////////////////////////////////////////////////////
2251 $time_selles_num = $row_settings['time_selles_num'];
2252 $tm = floor( 24 / $time_selles_num );
2253
2254
2255 ?><div class="<?php echo esc_attr(implode(' ', array(
2256 'in_cell_time_section_in_day',
2257 'flex_time_section_in_day_booking',
2258 'flex_time_in_days_num_' . $row_settings['view_days_num']
2259 )) ); ?>"
2260 ><?php
2261
2262 for ( $tt = 0; $tt < $time_selles_num; $tt++ ) {
2263
2264 // Get bookings for time-slot
2265 if ( $this->is_show_day_view( $row_settings ) ) {
2266
2267 $time_ms = $tt * 60 * 60;
2268 $bookings_in_this_time_arr = empty( $bookings_in__times_arr[ $time_ms ] ) ? array() : $bookings_in__times_arr[ $time_ms ];
2269 $is_start_new_booking = $this->is_start_new_booking_cell( $bookings_in_this_time_arr, $data_in_previous_cell['bookings_in_cell'] );
2270 $is_start_new_booking2 = $this->is_start_new_booking_cell2( $bookings_in_this_time_arr, $data_in_previous_cell['bookings_in_cell'] );
2271
2272 $bookings_in_day_cell = $bookings_in_this_time_arr;
2273
2274 } else { // Get bookings for a day
2275
2276 $is_start_new_booking = $this->is_start_new_booking_cell( $bookings_in_day_cell, $data_in_previous_cell['bookings_in_cell'] );
2277 $is_start_new_booking2 = $this->is_start_new_booking_cell2( $bookings_in_day_cell, $data_in_previous_cell['bookings_in_cell'] );
2278
2279 }
2280
2281 // Skip timeslots for day view
2282 if ( $this->is_show_day_view( $row_settings ) ) {
2283 if ( ( $tt < $row_settings['start_hour_for_1day_view'] ) || ( $tt > $row_settings['end_hour_for_1day_view'] ) ) {
2284 continue;
2285 }
2286 }
2287
2288
2289 $today_time_css_class=''; // FixIn: 10.0.0.40.
2290 if ( wpbc_datetime__use_wp_timezone( 'Y.m.d' ) == wpbc_datetime__use_wp_timezone( "Y.m.d", $row_settings[ 'real_date' ] ) ) {
2291 if ( $this->is_show_day_view( $row_settings ) ) {
2292 if ( ( wpbc_datetime__use_wp_timezone( 'm.d.Y' ) == wpbc_datetime__use_wp_timezone( "m.d.Y", $row_settings[ 'real_date' ] ) ) // Today Date
2293 && ( intval( wpbc_datetime__use_wp_timezone( 'H' ) ) == intval( $tt ) ) ) {
2294 $today_time_css_class = 'today_time';
2295 }
2296 }
2297
2298 }
2299
2300 ?><div class="<?php echo esc_attr( 'in_cell_time_hour time_hour' . ( $tt * $tm ) . ' ' . $today_time_css_class ); ?>" ><?php
2301
2302 if ( 'show_dates' == $row_settings['what_to_show'] ) {
2303
2304 ?>
2305 <div class="in_cell_date_container in_cell_date_container_<?php echo esc_attr( $row_settings['what_to_show'] ); ?>"><?php
2306 //if ( empty( $bookings_in_day_cell ) ) {
2307 if ( $this->is_show_day_view( $row_settings ) ) {
2308 $this->show_time_number_in_correct_format( $tt * $tm , $row_settings['view_days_num'] );
2309 } else {
2310 echo esc_html( $dd );
2311 }
2312 //}
2313 ?></div><?php
2314 }
2315
2316
2317 if ( 'show_bookings' == $row_settings['what_to_show'] ) {
2318
2319 if ( ! empty( $bookings_in_day_cell ) ) {
2320
2321 $booking_id_title = array();
2322
2323 ?>
2324 <div class="in_cell_date_container in_cell_date_container_<?php echo esc_attr( $row_settings['what_to_show'] );
2325
2326 // FixIn: 10.5.0.1.
2327 if (count($bookings_in_day_cell)>1){
2328 echo ' in_cell_date_container_has_several_bookings ';
2329 }
2330
2331 ?>"><?php
2332
2333 foreach ( $bookings_in_day_cell as $booking_id ) {
2334
2335 $booking_css_class_arr = $this->get_booking_class_arr( $booking_id, $row_settings, $row_settings['real_date'], $tt );
2336
2337 if ( ! in_array( 'booking_change_over', $booking_css_class_arr ) ) {
2338 if ( $is_start_new_booking2 ) {
2339 $booking_css_class_arr[] = 'start_new_booking';
2340 }
2341 }
2342
2343 ?>
2344 <div class="<?php echo esc_attr( implode( ' ', array(
2345 'booking_id',
2346 'booking_id_' . $booking_id,
2347 //$is_start_new_booking ? 'start_new_booking' : '',
2348 ) ) );
2349 echo ' ' . esc_attr( implode( ' ', $booking_css_class_arr ) );
2350 ?>"
2351 ><?php
2352
2353 // Booking CELL background
2354 $this->show_booking_title_for_pipeline_bar( $booking_id, $row_settings ); // Title, when mouse-over booking Pipeline (bar with background)
2355
2356 ?></div><?php
2357 }
2358 ?></div><?php
2359 }
2360 }
2361
2362
2363 if ( 'show_booking_titles' == $row_settings['what_to_show'] ) {
2364
2365 if ( ! empty( $bookings_in_day_cell ) ) {
2366
2367 // Title of new booking(s)
2368 if ( $is_start_new_booking ) {
2369
2370 ?><div class="<?php echo esc_attr( implode( ' ', array(
2371 'in_cell_date_container',
2372 'in_cell_date_container_booking_id_title',
2373 'in_cell_date_container_' . $row_settings['what_to_show']
2374 ) ) );
2375 echo esc_attr( ' booking_id_' . implode( '_', $bookings_in_day_cell ) );
2376 ?>"
2377 ><?php
2378
2379 $this->show_booking_title_for_timeline( $bookings_in_day_cell, $row_settings );
2380
2381 ?></div><?php
2382 }
2383 }
2384 }
2385
2386 ?></div><?php
2387
2388 $data_in_previous_cell['bookings_in_cell'] = $bookings_in_day_cell;
2389 }
2390
2391 ?></div><?php
2392
2393 ?></div><?php
2394
2395
2396 $this->data_in_previous_cell = $data_in_previous_cell;
2397 }
2398
2399 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2400 // Booking R O W
2401 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2402
2403 /** Row */
2404 public function wpbc_show_timeline_booking_row( $start_date, $booking_arr = array() ) {
2405
2406 $row_settings = array( 'start_date' => $start_date );
2407
2408 $row_settings = $this->get_init_row_settings( $row_settings );
2409
2410 if ( $row_settings['start_date'] !== false ) {
2411 list( $start_year, $start_month, $start_day ) = explode( '-', wpbc_datetime__no_wp_timezone( 'Y-m-d', $row_settings['start_date'] ) );
2412 } else {
2413 if ( ! empty( $this->request_args['scroll_start_date'] ) )
2414 list( $start_year, $start_month, $start_day ) = explode( '-', $this->request_args['scroll_start_date'] ); // scroll_start_date=2013-07-01
2415 else
2416 list( $start_year, $start_month, $start_day ) = explode( '-', wpbc_datetime__no_wp_timezone( 'Y-n-j' ) );
2417 }
2418
2419 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2420 // Dates / Times Line
2421 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2422
2423 $this->data_in_previous_cell['previous_booking_id'] = false;
2424
2425 $saved_previos_data_cell = $this->data_in_previous_cell;
2426
2427 foreach ( array( 'show_dates', 'show_bookings', 'show_booking_titles' ) as $what_to_show ) {
2428
2429 $this->data_in_previous_cell = $saved_previos_data_cell;
2430
2431 ?><div id="flex_resource_row_<?php echo esc_attr( $what_to_show . '_' . $booking_arr['current_resource_id'] ); ?>"
2432 class="<?php echo esc_attr( implode(' ', array(
2433 'flex_tl_dates_bar', 'flex_tl_row_height',
2434 'flex_tl_row_bar_' . $what_to_show ,
2435 $row_settings['is_matrix'] ? 'flex_tl_matrix_resources' : 'flex_tl_single_resource'
2436 ) ) ); ?>"
2437 ><?php
2438
2439 for ( $d_inc = 0; $d_inc < $row_settings['days_num']; $d_inc ++ ) {
2440
2441 $row_settings['real_date'] = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $d_inc ) ), intval( $start_year ) );
2442
2443 $day_cell_params = array_merge( $row_settings, $booking_arr );
2444
2445 $day_cell_params['what_to_show'] = $what_to_show;
2446
2447 $this->show_day_cell( $day_cell_params );
2448 }
2449
2450 ?></div><?php
2451 }
2452 }
2453
2454
2455 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2456 // Timeline
2457 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2458
2459 /** Show Structure of the TimeLine */
2460 public function wpbc_show_timeline( $dates_array, $bookings, $booking_types, $time_array_new = array() ){
2461
2462 // Skip showing rows of booking resource(s) in TimeLine or Calendar Overview, if no any exist booking(s) for current view
2463 $booked_booking_resources = array(); //FixIn: 7.0.1.51
2464 if ( ! empty( $this->request_args['only_booked_resources'] ) ) {
2465
2466 foreach ( $bookings as $single_booking ) {
2467
2468 if ( ! empty( $single_booking->booking_type ) )
2469 $booked_booking_resources[] = $single_booking->booking_type;
2470
2471 foreach ( $single_booking->dates as $booking_date_obj ) {
2472 if ( ( isset( $booking_date_obj->type_id ) ) && ( ! empty( $booking_date_obj->type_id ) ) )
2473 $booked_booking_resources[] = $booking_date_obj->type_id;
2474 }
2475 }
2476 $booked_booking_resources = array_unique( $booked_booking_resources );
2477 }
2478
2479 $view_days_num = $this->request_args['view_days_num']; // Get start date and number of rows, which is depend from the view days mode
2480 $is_matrix = $this->request_args['is_matrix'];
2481 $scroll_day = 0;
2482 $scroll_month = 0;
2483 $start_year = wpbc_datetime__no_wp_timezone( "Y" );
2484 $start_month = wpbc_datetime__no_wp_timezone( "m" ); // 09
2485
2486 if ( ! empty( $this->request_args['scroll_start_date'] ) ) { // scroll_start_date=2013-07-01
2487 // Set the correct start date, if was selected the stard date different from the today in the Filters Tab.
2488 list( $start_year, $start_month, $start_day ) = explode( '-', $this->request_args['scroll_start_date'] );
2489 }
2490
2491 ////////////////////////////////////////////////////////////////////////
2492 // Get Start Date and Scroll Day/Month Variables
2493 ////////////////////////////////////////////////////////////////////////
2494 if ( $is_matrix ) { // MATRIX VIEW
2495
2496 $bk_resources_id = explode( ',', $this->request_args['wh_booking_type'] );
2497 $max_rows_number = count( $bk_resources_id );
2498
2499 switch ( $view_days_num ) {
2500 case '1':
2501 if ( isset( $this->request_args['scroll_day'] ) )
2502 $scroll_day = $this->request_args['scroll_day'];
2503 if ( empty( $this->request_args['scroll_start_date'] ) )
2504 $start_day = wpbc_datetime__no_wp_timezone( "d" ); // FixIn: 7.0.1.13.
2505 break;
2506
2507 case '30':
2508 case '60':
2509 if ( isset( $this->request_args['scroll_month'] ) )
2510 $scroll_month = $this->request_args['scroll_month'];
2511 if ( empty( $this->request_args['scroll_start_date'] ) )
2512 $start_day = 1;
2513 break;
2514
2515 case '7': // 7 Week - start from Monday (or other start week day)
2516 if ( isset( $this->request_args['scroll_day'] ) )
2517 $scroll_day = $this->request_args['scroll_day'];
2518 if ( empty( $this->request_args['scroll_start_date'] ) )
2519 $start_day = wpbc_datetime__no_wp_timezone( "d" );
2520 $start_week_day_num = wpbc_datetime__no_wp_timezone( "w" );
2521 $start_day_weeek = esc_js(get_bk_option( 'booking_start_day_weeek' )); //[0]:Sun .. [6]:Sut
2522
2523 if ( $start_week_day_num != $start_day_weeek ) {
2524 for ( $d_inc = 1; $d_inc < 8; $d_inc++ ) { // Just get week back
2525
2526 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) - intval( $d_inc ) ), intval( $start_year ) );
2527
2528 $start_week_day_num = wpbc_datetime__no_wp_timezone( "w", $real_date );
2529 if ( $start_week_day_num == $start_day_weeek ) {
2530 $start_day = wpbc_datetime__no_wp_timezone( "d", $real_date );
2531 $start_year = wpbc_datetime__no_wp_timezone( "Y", $real_date );
2532 $start_month = wpbc_datetime__no_wp_timezone( "m", $real_date );
2533 $d_inc = 9;
2534 }
2535 }
2536 }
2537 break;
2538
2539 default: //30
2540 if ( isset( $this->request_args['scroll_month'] ) )
2541 $scroll_month = $this->request_args['scroll_month'];
2542 if ( empty( $this->request_args['scroll_start_date'] ) )
2543 $start_day = 1;
2544 break;
2545 }
2546
2547 } else { // SINGLE Resource VIEW
2548
2549 switch ( $view_days_num ) {
2550 case '90':
2551 if ( isset( $this->request_args['scroll_day'] ) )
2552 $scroll_day = $this->request_args['scroll_day'];
2553 else
2554 $scroll_day = 0;
2555
2556 $max_rows_number = 12;
2557 if ( empty( $this->request_args['scroll_start_date'] ) )
2558 $start_day = wpbc_datetime__no_wp_timezone( "d" );
2559 $start_week_day_num = wpbc_datetime__no_wp_timezone( "w" );
2560 $start_day_weeek = esc_js(get_bk_option( 'booking_start_day_weeek' )); //[0]:Sun .. [6]:Sut
2561
2562 if ( $start_week_day_num != $start_day_weeek ) {
2563 for ( $d_inc = 1; $d_inc < 8; $d_inc++ ) { // Just get week back
2564 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) - intval( $d_inc ) ), intval( $start_year ) );
2565
2566 $start_week_day_num = wpbc_datetime__no_wp_timezone( "w", $real_date );
2567 if ( $start_week_day_num == $start_day_weeek ) {
2568 $start_day = wpbc_datetime__no_wp_timezone( "d", $real_date );
2569 $start_year = wpbc_datetime__no_wp_timezone( "Y", $real_date );
2570 $start_month = wpbc_datetime__no_wp_timezone( "m", $real_date );
2571 $d_inc = 9;
2572 }
2573 }
2574 }
2575 break;
2576
2577 case '365':
2578 if ( isset( $this->request_args['scroll_month'] ) )
2579 $scroll_month = $this->request_args['scroll_month'];
2580 else
2581 $scroll_month = 0;
2582 $max_rows_number = 12;
2583 if ( empty( $this->request_args['scroll_start_date'] ) )
2584 $start_day = 1;
2585 break;
2586
2587 default: // 30
2588 if ( isset( $this->request_args['scroll_day'] ) )
2589 $scroll_day = $this->request_args['scroll_day'];
2590 else
2591 $scroll_day = 0;
2592
2593 // FixIn: 8.9.4.3.
2594 if ( $this->is_frontend ) {
2595 $max_rows_number = intval( get_bk_option( 'booking_timeline__month_mode__days_number_show' ) );
2596 } else {
2597 $max_rows_number = intval( get_bk_option( 'booking_calendar_overview__day_mode__days_number_show' ) );;
2598 }
2599 if (empty($max_rows_number)) {
2600 $max_rows_number = 31;
2601 }
2602
2603 if ( empty( $this->request_args['scroll_start_date'] ) )
2604 $start_day = wpbc_datetime__no_wp_timezone( "d" ); // FixIn: 7.0.1.13.
2605 break;
2606 }
2607 }
2608
2609 ////////////////////////////////////////////////////////////////////////////////////////////////
2610
2611 // FixIn: 10.0.0.25.
2612 if ( ! $this->is_frontend ){
2613 $this->show_timeline_header_start__admin_panel();
2614 }
2615 // New Spinner Loader // FixIn: 10.0.0.25.
2616 ?><div class="flex_tl_table_loading wpbc_spins_loading_container">
2617 <div class="wpbc_booking_form_spin_loader"><div class="wpbc_spins_loader_wrapper"><div class="wpbc_spin_loader_one_new"></div></div></div>
2618 <?php // echo '<span class="0glyphicon 0glyphicon-refresh wpbc_icn_autorenew wpbc_spin"></span>' ?>
2619 <span><?php esc_html_e('Loading','booking'); ?>...</span>
2620 </div><?php
2621
2622
2623 ?><div class="flex_timeline_frame<?php
2624 if ( $this->is_frontend ) echo ' wpbc_timeline_front_end' ?> flex_frame_view_days_num_<?php echo esc_attr( $view_days_num );
2625 if ($is_matrix) { echo ' flex_tl_matrix_resources '; } else { echo ' flex_tl_single_resource '; }
2626 ?>">
2627 <div class="flex_tl_table">
2628 <div class="flex_tl_table_header" style="<?php if ( ! $this->is_frontend ) { echo 'display:none;'; /* //FixIn: 10.0.0.25 */ } ?>">
2629 <?php
2630 if ( $this->is_frontend ) {
2631 ?><div class="flex_tl_collumn_2"><?php
2632
2633 $title = wpbc_lang( $this->timeline_titles['header_title'] );
2634
2635 $params_nav = array();
2636 $params_nav['title'] = $title;
2637 $this->client_navigation( $params_nav );
2638
2639 ?></div><?php
2640
2641 } else {
2642 ?>
2643 <div class="flex_tl_collumn_1"><?php
2644 $title = wpbc_lang( $this->timeline_titles['header_column1'] );
2645 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2646 echo $title; // Resources .
2647 ?></div>
2648 <div class="flex_tl_collumn_2"><?php
2649 $title = wpbc_lang( $this->timeline_titles['header_column2'] );
2650 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2651 echo $title; // Dates.
2652 ?></div>
2653 <?php } ?>
2654 </div><?php
2655
2656 ?><div class="flex_tl__scrolling_sections"><?php
2657 ?><div class="flex_tl__scrolling_section1">
2658 <div class="flex_tl_table_titles"><div class="flex_tl_collumn_1"></div></div><?php
2659 for ( $d_inc = 0; $d_inc < $max_rows_number; $d_inc++ ) {
2660
2661 // Skip showing rows of booking resource(s) in TimeLine or Calendar Overview, if no any exist booking(s) for current view
2662 if ( ! empty( $this->request_args['only_booked_resources'] ) ) {
2663
2664 $resource_id = ( $is_matrix ) ? $bk_resources_id[ $d_inc ] : $this->request_args['wh_booking_type'];
2665
2666 if ( ! in_array( $resource_id, $booked_booking_resources ) ) { continue; }
2667 }
2668
2669 // Ger Start Date to real_date variable
2670 $real_date = $this->get_start_day__to_real_date( array( 'is_matrix' => $is_matrix, 'view_days_num' => $view_days_num, 'start_month' => $start_month, 'start_day' => $start_day, 'start_year' => $start_year, 'scroll_month' => $scroll_month, 'scroll_day' => $scroll_day, 'd_inc' => $d_inc ) );
2671
2672 ?><div class="flex_tl_table_row_bookings">
2673 <div class="flex_tl_collumn_1"><?php
2674
2675 // Title in first column of each row in calendar
2676 if ( ( $is_matrix ) && ( isset( $bk_resources_id[$d_inc] ) ) && (isset( $booking_types[$bk_resources_id[$d_inc]] )) ) { // Matrix - resource titles
2677
2678 $resource_value = $booking_types[$bk_resources_id[$d_inc]];
2679 $bk_admin_url = wpbc_get_params_in_url( wpbc_get_bookings_url( false, false ), array( 'wh_booking_type' ) );
2680
2681 ?><div class="flex_tl_resource_title flex_tl_row_height <?php
2682 if ( isset( $resource_value->parent ) ) { if ( $resource_value->parent == 0 ) { echo 'parent'; } else { echo 'child'; } }
2683 ?> "><?php
2684 if ( $this->is_frontend ) {
2685
2686 if ( ( isset( $this->options['resource_link'] ) ) && ( isset( $this->options['resource_link'][ $resource_value->booking_type_id ] ) ) ){ // FixIn: 7.0.1.50.
2687
2688 ?><a href="<?php echo esc_url( $this->options['resource_link'][ $resource_value->booking_type_id ] ); ?>" ><?php // FixIn: 7.2.1.14.
2689 }
2690
2691 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2692 echo wpbc_lang( $resource_value->title ); // FixIn: 7.0.1.11.
2693
2694 if ( ( isset( $this->options['resource_link'] ) ) && ( isset( $this->options['resource_link'][ $resource_value->booking_type_id ] ) ) ){ // FixIn: 7.0.1.50.
2695 ?></a><?php
2696 }
2697 } else {
2698 ?><a href="<?php echo esc_url( $bk_admin_url . '&wh_booking_type=' . $bk_resources_id[$d_inc] ); ?>"
2699 title="<?php echo esc_attr( wpbc_lang( $resource_value->title ) ); ?>"
2700 ><?php
2701 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2702 echo wpbc_lang( $resource_value->title );
2703 ?></a><?php
2704 }
2705 ?></div><?php
2706
2707 } else { // Single Resource - Dates titles
2708
2709 ?><div class="flex_tl_resource_title flex_tl_row_height"><?php
2710
2711 switch ( $view_days_num ) {
2712 case '90':
2713 $end_real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $d_inc ) * 7 + intval( $scroll_day ) ) + 6, intval( $start_year ) );
2714 $date_format = ' j, Y'; //get_bk_option( 'booking_date_format');
2715 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2716 echo wpbc_datetime__no_wp_timezone( "M", $real_date ) . wpbc_datetime__no_wp_timezone( $date_format, $real_date ) . ' - ' . wpbc_datetime__no_wp_timezone( "M", $end_real_date ) . wpbc_datetime__no_wp_timezone( $date_format, $end_real_date );
2717 break;
2718
2719 case '365':
2720 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2721 echo wpbc_datetime__no_wp_timezone( "F", $real_date ) . ', ' . wpbc_datetime__no_wp_timezone( "Y", $real_date );
2722 break;
2723
2724 default: // 30
2725 //$date_format = 'd / m / Y';
2726 $date_format = get_bk_option( 'booking_date_format' ); // FixIn: 5.4.5.13.
2727 $ww = wpbc_datetime__no_wp_timezone( "N", $real_date ); //7
2728 ?>
2729 <div class="flex_tl_resource_title_dates_container">
2730 <div class="flex_tl_resource_title_dates_days flex_tl_weekday<?php echo esc_attr( $ww ); ?>"><?php
2731 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2732 echo wpbc_datetime__no_wp_timezone( $date_format, $real_date ); ?></div>
2733 <div class="flex_tl_resource_title_dates_weeks flex_tl_weekday<?php echo esc_attr( $ww ); ?>"><?php
2734 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2735 echo wpbc_datetime__no_wp_timezone( "D", $real_date ); ?></div>
2736 </div>
2737 <?php
2738 break;
2739 }
2740
2741 ?></div><?php
2742 }
2743 ?>
2744 </div>
2745 </div><?php
2746 }
2747
2748
2749 ?></div><?php
2750 ?><div class="flex_tl__scrolling_section2">
2751 <div class="flex_tl_table_titles flex_tl_row_max_width">
2752 <div class="flex_tl_collumn_2"><?php
2753 // Header above the calendar table
2754 $real_date = mktime( 0, 0, 0, intval( $start_month ), intval( $start_day ), intval( $start_year ) );
2755
2756 // Ger Start Date to real_date variable
2757 $real_date = $this->get_start_day__to_real_date( array( 'is_matrix' => $is_matrix, 'view_days_num' => $view_days_num, 'start_month' => $start_month, 'start_day' => $start_day, 'start_year' => $start_year, 'scroll_month' => $scroll_month, 'scroll_day' => $scroll_day, 'd_inc' => $d_inc ) );
2758
2759 $this->wpbc_show_timeline_header_row( $real_date );
2760 ?>
2761 </div>
2762 </div><?php
2763
2764 for ( $d_inc = 0; $d_inc < $max_rows_number; $d_inc++ ) {
2765
2766 // Skip showing rows of booking resource(s) in TimeLine or Calendar Overview, if no any exist booking(s) for current view
2767 if ( ! empty( $this->request_args['only_booked_resources'] ) ) {
2768
2769 $resource_id = ( $is_matrix ) ? $bk_resources_id[ $d_inc ] : $this->request_args['wh_booking_type'];
2770
2771 if ( ! in_array( $resource_id, $booked_booking_resources ) ) { continue; }
2772 }
2773
2774 // Ger Start Date to real_date variable
2775 $real_date = $this->get_start_day__to_real_date( array( 'is_matrix' => $is_matrix, 'view_days_num' => $view_days_num, 'start_month' => $start_month, 'start_day' => $start_day, 'start_year' => $start_year, 'scroll_month' => $scroll_month, 'scroll_day' => $scroll_day, 'd_inc' => $d_inc ) );
2776
2777 ?>
2778 <div class="flex_tl_table_row_bookings flex_tl_row_max_width">
2779
2780 <div class="flex_tl_collumn_2"><?php
2781
2782 if ( $is_matrix ) {
2783
2784 $this->reset_data_in_previous_cell();
2785
2786 $resource_id = $bk_resources_id[ $d_inc ];
2787
2788 } else {
2789 $resource_id = $this->request_args['wh_booking_type'];
2790 } // Request from GET or REQUEST
2791
2792 $booking_arr = array(
2793 'current_resource_id' => ( ( ! empty( $resource_id ) ) ? $resource_id : 1 ), // Remove dates and Times from the arrays, which is not belong to the $booking_arr['current_resource_id'] We do not remove it only, when the $booking_arr['current_resource_id'] - is empty - OLD ALL Resources VIEW
2794 'booked_dates_array' => $dates_array,
2795 'bookings' => $bookings,
2796 'booking_types' => $booking_types,
2797 'time_array_new' => $time_array_new
2798 );
2799
2800 /**
2801 * FROM: [2019-07-19] => Array ( [0] => Array (
2802 * [id] => 19
2803 [resource] => 3
2804 )
2805 [1] => Array (
2806 [id] => 19
2807 [resource] => 3
2808 ), ....
2809 * TO
2810 *
2811 * [2019-07-19] => Array (
2812 * [0] => 19
2813 * [1] => 19
2814 * [2] => 18
2815 * [3] => 18 ...
2816 */
2817 $booking_arr['booked_dates_array'] = $this->wpbc_dates_only_of_specific_resource(
2818 $booking_arr['booked_dates_array'],
2819 $booking_arr['current_resource_id'],
2820 $booking_arr['bookings']
2821 );
2822 /**
2823 * FROM: [2019-07-19] => Array ( ... , [28800] => Array(
2824 [0] => Array (
2825 [id] => 15
2826 [resource] => 3
2827 )
2828 [1] => Array (
2829 [id] => 16
2830 [resource] => 3
2831 )
2832 [2] => Array (
2833 [id] => 13
2834 [resource] => 3
2835 ) ....
2836 * TO
2837 * [2019-07-19] => Array ( ... , [28800] => Array(
2838 [0] => 15
2839 [1] => 16
2840 [2] => 13
2841 )
2842 */
2843 $booking_arr['time_array_new'] = $this->wpbc_times_only_of_specific_resource(
2844 $booking_arr['time_array_new'],
2845 $booking_arr['current_resource_id'],
2846 $booking_arr['bookings']
2847 );
2848
2849 $this->wpbc_show_timeline_booking_row( $real_date, $booking_arr );
2850
2851
2852 ?>
2853 </div>
2854 </div><?php
2855 }
2856 ?></div><?php
2857 ?></div><?php
2858
2859 ?></div></div><?php
2860
2861
2862 if ( ! $this->is_frontend ){
2863 $this->show_timeline_header_end__admin_panel(); // FixIn: 10.0.0.25.
2864 }
2865
2866 }
2867
2868
2869 /**
2870 * Ger Start Date to real_date variable
2871 *
2872 * @param $params = array(
2873 * 'is_matrix' => $is_matrix,
2874 * 'view_days_num' => $view_days_num,
2875 * 'start_month' => $start_month,
2876 * 'start_day' => $start_day,
2877 * 'start_year' => $start_year,
2878 * 'scroll_month' => $scroll_month
2879 * 'scroll_day' => $scroll_day
2880 * 'd_inc' => $d_inc
2881 * )
2882 *
2883 * @return false|int
2884 */
2885 private function get_start_day__to_real_date( $params ) {
2886
2887 if ( $params['is_matrix'] ) { // MATRIX VIEW
2888 switch ( $params['view_days_num'] ) { // Set real start date for the rows in calendar
2889 case '1':
2890 case '7':
2891 $real_date = mktime( 0, 0, 0, intval( $params['start_month'] ), ( intval( $params['start_day'] ) + intval( $params['scroll_day'] ) ), intval( $params['start_year'] ) );
2892 break;
2893
2894 case '30':
2895 case '90':
2896 $real_date = mktime( 0, 0, 0, ( intval( $params['start_month'] ) + intval( $params['scroll_month'] ) ), intval( $params['start_day'] ), intval( $params['start_year'] ) );
2897 break;
2898
2899 default: // 30
2900 $real_date = mktime( 0, 0, 0, ( intval( $params['start_month'] ) + intval( $params['scroll_month'] ) ), intval( $params['start_day'] ), intval( $params['start_year'] ) );
2901 break;
2902 }
2903 } else { // Single Resource View
2904 switch ( $params['view_days_num'] ) { // Set real start date for the rows in calendar
2905 case '90':
2906 $real_date = mktime( 0, 0, 0, intval( $params['start_month'] ), ( intval( $params['start_day'] ) + intval( $params['d_inc'] ) * 7 + intval( $params['scroll_day'] ) ), intval( $params['start_year'] ) );
2907 break;
2908
2909 case '365':
2910 $real_date = mktime( 0, 0, 0, ( intval( $params['start_month'] ) + intval( $params['d_inc'] ) + intval( $params['scroll_month'] ) ), intval( $params['start_day'] ), intval( $params['start_year'] ) );
2911 break;
2912
2913 default: // 30
2914 $real_date = mktime( 0, 0, 0, intval( $params['start_month'] ), ( intval( $params['start_day'] ) + intval( $params['d_inc'] ) + intval( $params['scroll_day'] ) ), intval( $params['start_year'] ) );
2915 break;
2916 }
2917 }
2918
2919 return $real_date;
2920 }
2921
2922 /**
2923 * Show timeline
2924 * All parameters must be defined.
2925 */
2926 public function show_timeline() {
2927
2928 $this->wpbc_show_timeline( $this->dates_array, $this->bookings, $this->booking_types, $this->time_array_new );
2929
2930 //FixIn: 10.0.0.25 // removed loader text from here
2931
2932 // FixIn: 9.1.2.4.
2933 echo '<script type="text/javascript">
2934 if ( ( document.readyState !== "loading" ) && ( ( "undefined" !== typeof jQuery ) && ( window.jQuery ) ) ){
2935 jQuery( ".flex_tl_table_loading").hide();
2936 jQuery( ".flex_tl_table" ).show();
2937 } else { ' ;
2938 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2939 echo wpbc_jq_ready_start(); // FixIn: 10.1.3.7.
2940 ?> jQuery( '.flex_tl_table_loading').hide();
2941 jQuery( '.flex_tl_table' ).show();
2942 <?php
2943 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2944 echo wpbc_jq_ready_end() . ' } </script>'; // FixIn: 10.1.3.7.
2945 }
2946
2947 /**
2948 * Show Header for Timeline in Calendar Overview page in admin panel. Header contain switches of modes and novigation buttons
2949 * @return void
2950 */
2951 public function show_timeline_header_start__admin_panel(){ // FixIn: 10.0.0.25.
2952
2953 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2954 $is_show_resources_matrix = ( ( isset( $_REQUEST['wh_booking_type'] ) ) && ( strpos( $_REQUEST['wh_booking_type'], ',' ) !== false ) )
2955 ? true : false;
2956
2957 $view_days_num = ( isset( $_REQUEST['view_days_num'] ) ) ? intval( $_REQUEST['view_days_num'] ) : get_bk_option( 'booking_view_days_num' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
2958
2959 $bk_admin_url = wpbc_get_params_in_url( wpbc_get_bookings_url( false ), array( 'view_days_num' ) );
2960
2961 ?><div class="wpbc_calendar_overview__header" >
2962 <div class="wpdvlp-top-tabs ">
2963 <div class="wpdvlp-tabs-wrapper">
2964 <div class="nav-tabs"><?php
2965 if ( $is_show_resources_matrix ) {
2966 ?>
2967 <a href="<?php echo esc_url( $bk_admin_url . '&view_days_num=1' ); ?>"
2968 class="nav-tab <?php echo ( 1 == $view_days_num ) ? 'nav-tab-active' : ''; ?>"><i class="menu_icon icon-1x wpbc-bi-calendar-event"></i>
2969 <span class="nav-tab-text">&nbsp;&nbsp;<?php echo esc_html__('Day', 'booking') ; ?></span>
2970 </a>
2971 <a href="<?php echo esc_url( $bk_admin_url . '&view_days_num=7' ); ?>"
2972 class="nav-tab <?php echo ( 7 == $view_days_num ) ? 'nav-tab-active' : ''; ?>"><i class="menu_icon icon-1x wpbc-bi-calendar-week"></i>
2973 <span class="nav-tab-text">&nbsp;&nbsp;<?php echo esc_html__('Week', 'booking'); ?></span>
2974 </a>
2975 <a href="<?php echo esc_url( $bk_admin_url . '&view_days_num=30' ); ?>"
2976 class="nav-tab <?php echo ( 30 == $view_days_num ) ? 'nav-tab-active' : ''; ?>"><i class="menu_icon icon-1x wpbc-bi-calendar3"></i>
2977 <span class="nav-tab-text">&nbsp;&nbsp;<?php echo esc_html__('Month', 'booking'); ?></span>
2978 </a>
2979 <a href="<?php echo esc_url( $bk_admin_url . '&view_days_num=60' ); ?>"
2980 class="nav-tab <?php echo ( 60 == $view_days_num ) ? 'nav-tab-active' : ''; ?>"><i class="menu_icon icon-1x wpbc-bi-calendar2-week"></i>
2981 <span class="nav-tab-text">&nbsp;&nbsp;2 <?php echo esc_html__('Months', 'booking'); ?></span>
2982 </a>
2983 <?php
2984 } else {
2985 ?>
2986 <a href="<?php echo esc_url( $bk_admin_url . '&view_days_num=30' ); ?>"
2987 class="nav-tab <?php echo ( 30 == $view_days_num ) ? 'nav-tab-active' : ''; ?>"><i class="menu_icon icon-1x wpbc-bi-calendar-event"></i>
2988 <span class="nav-tab-text">&nbsp;&nbsp;<?php echo esc_html__('Day', 'booking') ; ?></span>
2989 </a>
2990 <a href="<?php echo esc_url( $bk_admin_url . '&view_days_num=90' ); ?>"
2991 class="nav-tab <?php echo ( 90 == $view_days_num ) ? 'nav-tab-active' : ''; ?>"><i class="menu_icon icon-1x wpbc-bi-calendar-week"></i>
2992 <span class="nav-tab-text">&nbsp;&nbsp;<?php echo esc_html__('Week', 'booking'); ?></span>
2993 </a>
2994 <a href="<?php echo esc_url( $bk_admin_url . '&view_days_num=365' ); ?>"
2995 class="nav-tab <?php echo ( 365 == $view_days_num ) ? 'nav-tab-active' : ''; ?>"><i class="menu_icon icon-1x wpbc-bi-calendar3"></i>
2996 <span class="nav-tab-text">&nbsp;&nbsp;<?php echo esc_html__('Month', 'booking'); ?></span>
2997 </a>
2998 <?php
2999 }
3000 ?><div class="wpbc_calendar_overview__navigation"><?php
3001
3002 wpbc_toolbar_btn__timeline_navigation();
3003
3004 ?></div>
3005 </div><!-- nav-tabs -->
3006 </div><!-- wpdvlp-tabs-wrapper -->
3007 </div><!-- wpdvlp-top-tabs -->
3008 </div>
3009 <div class="clear"></div>
3010 <div class="wpbc_calendar_overview__container">
3011 <?php
3012 }
3013
3014 function show_timeline_header_end__admin_panel(){ // FixIn: 10.0.0.25.
3015 ?></div><?php // End: .wpbc_calendar_overview__container
3016 }
3017
3018 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3019 // P O P O V E R
3020 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3021
3022 //TODO: Refactor this: 2019-07-29 09:01
3023
3024 /**
3025 * Get Data for Popover
3026 *
3027 * @param int $bk_id
3028 * @param array $bookings
3029 * @param array $booking_types
3030 * @param string $text_in_day_cell
3031 * @param string $header_title
3032 * @param string $content_text
3033 *
3034 * @return array
3035 */
3036 public function wpbc_get_booking_info_4_popover( $bk_id, $bookings, $booking_types ){
3037
3038 if ( ! $this->wpbc_is_booking_authorized_for_hash( $bk_id, $bookings ) ) {
3039 return array(
3040 'title' => '',
3041 'content' => '',
3042 );
3043 }
3044
3045 if ( isset( $bookings[ $bk_id ] ) ) {
3046 //$bookings[ $bk_id ]->form_show = str_replace( "&amp;", '&', $bookings[ $bk_id ]->form_show ); // FixIn: 7.1.2.12.
3047 // We escaping at other place: wpbc__legacy__get_form_content_arr()
3048 }
3049
3050 if ( count( $bookings[ $bk_id ]->dates ) > 0 ) {
3051 $is_approved = $bookings[ $bk_id ]->dates[0]->approved;
3052 } else {
3053 $is_approved = 0;
3054 }
3055
3056 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3057 // Title
3058 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3059 $header_title = '<div class=\'popover-title-id\' > ID: ' . $bk_id . '</div>'; // ID
3060
3061
3062 $is_can = true; //current_user_can( 'edit_posts' );
3063
3064 if (
3065 ( ( $is_can ) && ( ! $this->is_frontend ) )
3066 || ( ( $this->is_frontend ) && ( ! empty( $this->request_args['booking_hash'] ) ) )
3067 ) {
3068
3069 // Buttons
3070 $header_title .= '<div class=\'popover-title-buttons control-group timeline_info_bk_actionsbar_' . $bk_id . '\' >';
3071
3072
3073 if ( ( ! $this->is_frontend ) && ( $is_can ) ) {
3074 // Link
3075 $header_title .= '<a class=\'button button-secondary\'
3076 title=\'' . esc_attr( str_replace( "'", '', __( 'Booking Listing', 'booking' ) ) ) . '\'
3077 href=\''.wpbc_get_bookings_url( true, false ).'&wh_booking_id='.$bk_id.'&tab=vm_booking_listing\' ><i class=\'wpbc_icn_gps_fixed\'></i></a>';
3078 //Edit
3079 if ( class_exists( 'wpdev_bk_personal' ) ) {
3080 $bk_url_add = wpbc_get_new_booking_url( true, false );
3081 $bk_hash = (isset( $bookings[$bk_id]->hash )) ? $bookings[$bk_id]->hash : '';
3082 $bk_booking_type = $bookings[$bk_id]->booking_type;
3083 $edit_booking_url = $bk_url_add . '&booking_type=' . $bk_booking_type . '&booking_hash=' . $bk_hash . '&parent_res=1';
3084 // FixIn: 10.10.1.2 $edit_booking_url .= ( 'Off' !== get_bk_option( 'booking_is_resource_no_update__during_editing' ) ) ? '&resource_no_update=1' : ''; // FixIn: 9.4.2.3.
3085
3086 $custom_booking_form = '';
3087 if ( ! empty( $bookings[ $bk_id ]->form_data['_all_fields_']['wpbc_custom_booking_form'] ) ) {
3088 $custom_booking_form = $bookings[ $bk_id ]->form_data['_all_fields_']['wpbc_custom_booking_form'];
3089 $edit_booking_url .= '&booking_form=' . rawurlencode( $custom_booking_form ); // FixIn: 9.4.3.12.
3090 }
3091
3092 $edit_booking_onclick = "if ( 'function' === typeof wpbc_boo_listing__click__add_booking_modal_from_row ) {"
3093 . ' wpbc_boo_listing__click__add_booking_modal_from_row('
3094 . absint( $bk_id ) . ','
3095 . absint( $bk_booking_type ) . ','
3096 . "'" . esc_js( $bk_hash ) . "',"
3097 . "'" . esc_js( $custom_booking_form ) . "'"
3098 . ' ); return false; }';
3099
3100 $header_title .= '<a class=\'button button-secondary\'
3101 title=\'' . esc_attr( str_replace( "'", '', __( 'Edit', 'booking' ) ) ) . '\'
3102 href=\'' . esc_url( $edit_booking_url ) . '\' onclick=\'' . esc_attr( $edit_booking_onclick ) . '\' ><i class=\'wpbc_icn_draw\'></i></a>';
3103
3104
3105 $header_title .= '<span class=\'wpbc-buttons-separator\'></span>';
3106 }
3107 // Trash
3108 //$header_title .= '<a class=\'button button-secondary\' href=\'javascript:;\' onclick=\'javascript:delete_booking(' . $bk_id . ', ' . $this->current_user_id . ', &quot;' . wpbc_get_maybe_reloaded_booking_locale() . '&quot; , 1 );\' ><i class=\'wpbc_icn_delete_outline\'></i></a>';
3109 // FixIn: 6.1.1.10.
3110 $is_trash = $bookings[$bk_id]->trash;
3111
3112 // Trash
3113 $header_title .= '<a class=\'button button-secondary trash_bk_link'.(( $is_trash)?' hidden_items ':'').'\'
3114 title=\'' . esc_attr( str_replace( "'", '', __( 'Trash / Reject', 'booking' ) ) ) . '\'
3115 href=\'javascript:;\' onclick=\'javascript:if ( wpbc_are_you_sure_popup() ) trash__restore_booking(1,' . $bk_id . ', ' . $this->current_user_id . ', &quot;' . wpbc_get_maybe_reloaded_booking_locale() . '&quot; , 1 );\' ><i class=\'wpbc_icn_delete_outline\'></i></a>'; // FixIn: 8.4.7.14.
3116 // Restore
3117 $header_title .= '<a class=\'button button-secondary restore_bk_link'.((!$is_trash)?' hidden_items ':'').'\'
3118 title=\'' . esc_attr( str_replace( "'", '', __( 'Restore', 'booking' ) ) ) . '\'
3119 href=\'javascript:;\' onclick=\'javascript:trash__restore_booking(0,' . $bk_id . ', ' . $this->current_user_id . ', &quot;' . wpbc_get_maybe_reloaded_booking_locale() . '&quot; , 1 );\' ><i class=\'wpbc_icn_rotate_left\'></i></a>';
3120 // Delete
3121 $header_title .= '<a class=\'button button-secondary delete_bk_link'.((!$is_trash)?' hidden_items ':'').'\'
3122 title=\'' . esc_attr( str_replace( "'", '', __( 'Delete', 'booking' ) ) ) . '\'
3123 href=\'javascript:;\' onclick=\'javascript:if ( wpbc_are_you_sure_popup() ) delete_booking(' . $bk_id . ', ' . $this->current_user_id . ', &quot;' . wpbc_get_maybe_reloaded_booking_locale() . '&quot; , 1 );\' ><i class=\'wpbc_icn_close\'></i></a>'; // FixIn: 8.4.7.14.
3124 //End FixIn: 6.1.1.10
3125
3126 // Approve | Decline
3127 $header_title .= '<a class=\'button button-secondary approve_bk_link ' . ($is_approved ? 'hidden_items' : '') . '\'
3128 title=\'' . esc_attr( str_replace( "'", '', __( 'Approve', 'booking' ) ) ) . '\'
3129 href=\'javascript:;\' onclick=\'javascript:approve_unapprove_booking(' . $bk_id . ',1, ' . $this->current_user_id . ', &quot;' . wpbc_get_maybe_reloaded_booking_locale() . '&quot; , 1 );\' ><i class=\'wpbc_icn_check_circle_outline\'></i></a>';
3130 $header_title .= '<a class=\'button button-secondary pending_bk_link ' . ($is_approved ? '' : 'hidden_items') . '\'
3131 title=\'' . esc_attr( str_replace( "'", '', __( 'Pending', 'booking' ) ) ) . '\'
3132 href=\'javascript:;\' onclick=\'javascript:approve_unapprove_booking(' . $bk_id . ',0, ' . $this->current_user_id . ', &quot;' . wpbc_get_maybe_reloaded_booking_locale() . '&quot; , 1 );\' ><i class=\'wpbc_icn_block\'></i></a>';
3133
3134
3135 }
3136
3137 else if ( ( $this->is_frontend ) && ( ! empty( $this->request_args['booking_hash'] ) ) ) { // FixIn: 8.1.3.5.
3138 // Valid or not valid hash we was checked at beginning of function.
3139
3140 //Edit
3141 if ( class_exists( 'wpdev_bk_personal' ) ) {
3142
3143 // $edit_booking_url_admin = wpbc_get_bookings_url( true, false ).'&wh_booking_id='.$bk_id.'&tab=vm_booking_listing';
3144 // $trash_booking_url_admin = wpbc_get_bookings_url( true, false ).'&wh_booking_id='.$bk_id.'&tab=vm_booking_listing';
3145
3146 $is_change_hash_after_approvement = get_bk_option( 'booking_is_change_hash_after_approvement' ); // FixIn: 8.6.1.6.
3147 if ( ( ! $is_approved ) || ( 'On' != $is_change_hash_after_approvement ) ) { // FixIn: 8.2.1.14.
3148 $visitorbookingediturl = apply_bk_filter( 'wpdev_booking_set_booking_edit_link_at_email', '[visitorbookingediturl]', $bk_id );
3149 $visitorbookingcancelurl = apply_bk_filter( 'wpdev_booking_set_booking_edit_link_at_email', '[visitorbookingcancelurl]', $bk_id );
3150 $visitorbookingpayurl = apply_bk_filter( 'wpdev_booking_set_booking_edit_link_at_email', '[visitorbookingpayurl]', $bk_id );
3151
3152 $header_title .= '<a class=\'btn btn-default wpbc_btn_in_timeline\' title=\''. esc_attr( __( 'Edit', 'booking' ) ).'\' href=\'' . $visitorbookingediturl . '\' ><i class=\'wpbc_icn_draw\'></i></a>';
3153 $header_title .= '<a class=\'btn btn-default wpbc_btn_in_timeline\' title=\''. esc_attr( __( 'Cancel', 'booking' ) ).'\' href=\'' . $visitorbookingcancelurl . '\' ><i class=\'wpbc_icn_delete_outline\'></i></a>';
3154 $header_title .= '<a class=\'btn btn-default wpbc_btn_in_timeline\' title=\''. esc_attr( __( 'Pay', 'booking' ) ).'\' href=\'' . $visitorbookingpayurl . '\' ><i class=\'wpbc_icn_forward_to_inbox\'></i></a>';
3155 }
3156 }
3157 }
3158
3159 $header_title .= '</div>';
3160 }
3161
3162 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3163 // Content
3164 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3165
3166 // Container
3167 $content_text = '<div id=\'wpbc-booking-id-'.$bk_id.'\' class=\'flex-popover-content-data\' >';
3168
3169
3170 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3171 // Labels
3172 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3173 $content_text .= '<div class=\'flex-popover-bars\' >';
3174
3175 $content_text .= '<div class=\'flex-popover-labels-bar\' >';
3176
3177 // ID
3178 $content_text .= '<div class=\'flex-label flex-label-id\'>';
3179 $content_text .= '<span class=\'label0\'>' . $bk_id . '</span>';
3180 $content_text .= '</div>';
3181
3182 // Labels
3183 $content_text .= '<div class=\'flex-label flex-label-booking-status label-pending' . ( $is_approved ? ' hidden_items' : '' ) . '\'>'
3184 . __('Pending' ,'booking')
3185 . '</div>';
3186 $content_text .= '<div class=\'flex-label flex-label-booking-status label-approved' . ( ! $is_approved ? ' hidden_items' : '' ) . '\'>'
3187 . __('Approved' ,'booking')
3188 . '</div>';
3189
3190 // Resource
3191 if ( function_exists( 'wpbc_db__get_resource_title' ) ) {
3192
3193 if ( isset( $booking_types[ $bookings[ $bk_id ]->booking_type ] ) ) {
3194 $bk_title = wpbc_lang( $booking_types[ $bookings[ $bk_id ]->booking_type ]->title );
3195 } else {
3196 $bk_title = wpbc_get_resource_title( $bookings[ $bk_id ]->booking_type );
3197 }
3198
3199 $content_text .= '<div class=\'flex-label flex-label-resource\'>';
3200 $content_text .= '<span class=\'\'>' . esc_textarea( $bk_title ) . '</span>'; // FixIn: 7.1.1.2.
3201 $content_text .= '</div>';
3202 }
3203
3204 // Payment Status
3205 if ( ( function_exists( 'wpdev_bk_get_payment_status_simple' ) )
3206 && ( floatval( $bookings[ $bk_id ]->cost ) > 0 )
3207 ) {
3208 $pay_status = wpdev_bk_get_payment_status_simple( $bookings[ $bk_id ]->pay_status );
3209 $is_payment_ok = wpbc_is_payment_status_ok( trim( $bookings[ $bk_id ]->pay_status ) );
3210
3211 $payment_label_status = $is_payment_ok ? 'payment-label-success' : 'payment-label-unknown';
3212
3213 $content_text .= '<div class=\'flex-label flex-label-payment '. $payment_label_status .'\'>';
3214
3215 if ( $is_payment_ok )
3216 $content_text .= '<span class=\'label-prefix\'>' . esc_js( __( 'Payment', 'booking' ) ). '</span> ' . esc_js( $pay_status );
3217 else {
3218 $content_text .= '<span class=\'label-prefix\'>' . esc_js( __( 'Payment', 'booking' ) ) . '</span> ' . esc_js( $pay_status ); // FixIn: 7.1.1.3.
3219 }
3220
3221 $content_text .= '</div>';
3222 }
3223
3224 if ( ! $this->is_frontend ) {
3225 // Trash
3226 $content_text .= '<div class=\'flex-label flex-label-trash' . ( ( ! $bookings[$bk_id]->trash ) ? ' hidden_items ' : '' ) . '\'>';
3227 $content_text .= '<span class=\'\'>' . esc_js( __('Trash / Reject' ,'booking') ) . '</span>'; //FixIn: 6.1.1.10 // FixIn: 7.1.1.3.
3228 $content_text .= '</div>';
3229 }
3230
3231
3232 $content_text .= '</div>';
3233
3234
3235 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
3236 // Cost Bar
3237 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
3238 if ( ( class_exists( 'wpdev_bk_biz_s' ) ) ) { //&& ( ! $this->is_frontend ) ){
3239
3240 $content_text .= '<div class=\'flex-popover-cost-bar\' >';
3241
3242 // FixIn: 8.3.3.9.
3243 if ( floatval( $bookings[ $bk_id ]->cost ) > 0 ) {
3244 // Cost
3245 $booking_cost = wpbc_get_cost_with_currency_for_user( $bookings[ $bk_id ]->cost, $bookings[ $bk_id ]->booking_type );
3246
3247 $content_text .= '<div class=\'flex-label flex-label-cost\' >';
3248 //$content_text .= '<div class=\'text-left field-labels booking-labels\'>';
3249 $content_text .= '<div class=\'\'>' . $booking_cost . '</div>';
3250 //$content_text .= '</div>';
3251 $content_text .= '</div>';
3252 }
3253
3254 $content_text .= '</div>';
3255
3256 }
3257
3258 $content_text .= '</div>';
3259
3260
3261
3262 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3263 // Booking Data
3264 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3265
3266 // Booking Data
3267 $content_text .= '<div class=\'clear\'></div>'; // FixIn: 8.7.9.4.
3268 $content_text .= '<div class=\'flex-popover-booking-data\'>' . esc_textarea( $bookings[$bk_id]->form_show ) . '</div>'; // FixIn: 7.1.1.2.
3269 $content_text .= '<div class=\'clear\'></div>'; // FixIn: 8.7.9.4.
3270
3271 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3272 // Notes
3273 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3274
3275 // Notes
3276 if ( ! empty( $bookings[$bk_id]->remark ) ) {
3277 $content_text .= '<div class=\'wpbc-popover-booking-notes\'>' . '<strong>' . esc_js( __('Note', 'booking') ). ':</strong> ' . esc_textarea( $bookings[$bk_id]->remark ) . '</div>'; //FixIn: 7.1.1.2 // FixIn: 7.1.1.3.
3278 }
3279
3280 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3281 // Dates
3282 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3283
3284 $bk_dates_short_id = array(); //BL
3285 if ( count( $bookings[$bk_id]->dates ) > 0 )
3286 $bk_dates_short_id = (isset( $bookings[$bk_id]->dates_short_id )) ? $bookings[$bk_id]->dates_short_id : array(); // Array ([0] => [1] => .... [4] => 6... [11] => [12] => 8 )
3287
3288 $short_dates_content = wpbc_get_short_dates_formated_to_show( $bookings[$bk_id]->dates_short, $is_approved, $bk_dates_short_id, $booking_types );
3289 $short_dates_content = str_replace( '"', "'", $short_dates_content );
3290
3291 $content_text .= '<div class=\'flex-label-dates \'>';
3292 $content_text .= $short_dates_content;
3293 $content_text .= '</div>';
3294
3295 // FixIn: 8.9.4.14.
3296 $date_format = get_bk_option( 'booking_date_format' );
3297 if ( empty( $date_format ) ) {
3298 $date_format = 'm / d / Y, D';
3299 }
3300 $time_format = get_bk_option( 'booking_time_format' );
3301 if ( empty( $time_format ) ) {
3302 $time_format = 'h:i a';
3303 }
3304 $cr_date = wpbc_datetime__no_wp_timezone( $date_format . ' ' . $time_format, mysql2date( 'U', $bookings[ $bk_id ]->modification_date ) );
3305 $content_text .= '<div class=\'wpbc-listing-collumn field-system-info \'>';
3306 $content_text .= __( 'Created', 'booking' ) . ': ' . $cr_date;
3307 $content_text .= '</div>';
3308
3309
3310 $content_text .= '</div>'; // Main Container: 'flex-popover-content-data'
3311
3312 $popover = array(
3313 'title' => $header_title,
3314 'content' => $content_text
3315 );
3316
3317 $popover = apply_filters( 'wpbc_timeline_booking_popover', $popover, $bk_id, $bookings, $this->is_frontend );
3318
3319 return $popover;
3320 }
3321
3322 }
3323
3324
3325
3326 /** Navigation of Timeline in Ajax request */
3327 function wpbc_ajax_flex_timeline() {
3328 /*
3329 [timeline_obj] => Array
3330 (
3331 [is_frontend] => 1
3332 [html_client_id] => wpbc_timeline_1454680376080
3333 [wh_booking_type] => 3,4,1,5,6,7,8,9,2,10,11,12,14
3334 [is_matrix] => 1
3335 [view_days_num] => 30
3336 [scroll_start_date] =>
3337 [scroll_day] => 0
3338 [scroll_month] => 0
3339 )
3340 */
3341
3342 // Public timeline navigation accepts only one flat scalar attribute map.
3343 // phpcs:ignore WordPress.Security.NonceVerification.Missing
3344 if ( ! isset( $_POST['timeline_obj'] ) || ! is_array( $_POST['timeline_obj'] ) ) {
3345 status_header( 400 );
3346 wp_die( '' );
3347 }
3348
3349 $attr = array();
3350 $allowed_timeline_keys = array_fill_keys(
3351 array(
3352 'is_frontend',
3353 'html_client_id',
3354 'wh_booking_type',
3355 'is_matrix',
3356 'view_days_num',
3357 'scroll_start_date',
3358 'scroll_day',
3359 'scroll_month',
3360 'header_column1',
3361 'header_column2',
3362 'header_title',
3363 'wh_trash',
3364 'limit_hours',
3365 'only_booked_resources',
3366 'options',
3367 'booking_hash',
3368 ),
3369 true
3370 );
3371 // phpcs:ignore WordPress.Security.NonceVerification.Missing
3372 foreach ( $_POST['timeline_obj'] as $tl_key => $tl_value ) {
3373 if ( ! is_scalar( $tl_key ) || ! is_scalar( $tl_value ) ) {
3374 status_header( 400 );
3375 wp_die( '' );
3376 }
3377
3378 $clean_key = sanitize_key( wp_unslash( (string) $tl_key ) );
3379 if ( '' === $clean_key || ! isset( $allowed_timeline_keys[ $clean_key ] ) ) {
3380 continue;
3381 }
3382 $attr[ $clean_key ] = wpbc_clean_text_value( wp_unslash( (string) $tl_value ) );
3383 }
3384
3385 // phpcs:ignore WordPress.Security.NonceVerification.Missing
3386 if ( isset( $_POST['nav_step'] ) && ! is_scalar( $_POST['nav_step'] ) ) {
3387 status_header( 400 );
3388 wp_die( '' );
3389 }
3390
3391 $attr['nav_step'] = isset( $_POST['nav_step'] ) ? wpbc_clean_text_value( wp_unslash( (string) $_POST['nav_step'] ) ) : '0'; // phpcs:ignore WordPress.Security.NonceVerification.Missing
3392 $attr['is_frontend'] = isset( $attr['is_frontend'] ) ? $attr['is_frontend'] : '1';
3393 if ( empty( $attr['html_client_id'] ) ) {
3394 status_header( 400 );
3395 wp_die( '' );
3396 }
3397
3398 // FixIn: 9.9.0.18.
3399 $server_zone = date_default_timezone_get(); // If in 'Theme' or 'other plugin' set default timezone other than UTC. Save it.
3400 if ( 'UTC' !== $server_zone ) { // Needed for WP date functions - set timezone to UTC.
3401 // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
3402 @date_default_timezone_set( 'UTC' );
3403 }
3404
3405 ob_start();
3406
3407 $timeline = new WPBC_TimelineFlex();
3408
3409 $html_client_id = $timeline->ajax_init( $attr ); // Define arameters and get bookings
3410 //debuge($timeline->options);
3411
3412 //echo '<div class="wpbc_timeline_ajax_replace">'; // Replace content of this container
3413 $timeline->show_timeline();
3414
3415
3416 $is_show_popover_in_timeline = wpbc_is_show_popover_in_flex_timeline( $attr['is_frontend'], $attr['booking_hash'] ); // FixIn: 8.1.3.5.
3417
3418 if ( $is_show_popover_in_timeline ) { // Update New Popovers
3419
3420 $html = '<script type="text/javascript"> ' . wpbc_jq_ready_start(); // FixIn: 10.1.3.7.
3421 $html .= ' wpbc_define_tippy_popover(); ';
3422 $html .= wpbc_jq_ready_end() . '</script>'; // FixIn: 10.1.3.7.
3423
3424 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
3425 echo $html;
3426
3427 /* ?><script type="text/javascript"> wpbc_define_tippy_popover(); </script><?php */
3428 }
3429 //echo '</div>';
3430
3431
3432 $timeline_results = ob_get_contents();
3433
3434 ob_end_clean();
3435
3436 // FixIn: 9.9.0.18.
3437 if ( 'UTC' !== $server_zone ) { // Back to previos state, if it was changed.
3438 // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
3439 @date_default_timezone_set( $server_zone );
3440 }
3441
3442 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
3443 echo $timeline_results ;
3444 }
3445 add_bk_action('wpbc_ajax_flex_timeline', 'wpbc_ajax_flex_timeline');
3446
3447
3448
3449 /** Check if we are showing booking details or not
3450 * Admin panel - always show
3451 * Timeline - show if activated setting option
3452 * Customer listing - show always, if valid hash.
3453 *
3454 * @param $is_frontend
3455 * @param $booking_hash
3456 *
3457 * @return bool
3458 */
3459 function wpbc_is_show_popover_in_flex_timeline( $is_frontend, $booking_hash ) {
3460
3461 // Default for admin.
3462 $is_show_popover_in_timeline = true;
3463
3464 // For client Timeline.
3465 if ( $is_frontend ) {
3466
3467 // FixIn: 10.14.11.1.
3468 if ( WPBC_DISABLE_POPOVER_IN_TIMELINE ) {
3469 $is_show_popover_in_timeline = false;
3470 } else {
3471 $is_show_popover_in_timeline = ( get_bk_option( 'booking_is_show_popover_in_timeline_front_end' ) == 'On' ) ? true : false;
3472 if ( ! class_exists( 'wpdev_bk_personal' ) ) {
3473 $is_show_popover_in_timeline = false; // FixIn: 10.14.9.2.
3474 }
3475 }
3476 }
3477
3478 // For customer booking listing with ability to edit.
3479 // FixIn: 8.1.3.5.
3480 if ( ( $is_frontend ) && ( ! empty( $booking_hash ) ) ) {
3481
3482 // In case if we have valid valid hash then show booking details.
3483 $my_booking_id_type = wpbc_hash__get_booking_id__resource_id( $booking_hash );
3484
3485 if ( ! empty( $my_booking_id_type ) ) {
3486 $is_show_popover_in_timeline = true;
3487 } else {
3488 $is_show_popover_in_timeline = false;
3489 }
3490 }
3491 return $is_show_popover_in_timeline;
3492 }
3493
3494
3495
3496 /**
3497 * TimeLine shortcode
3498 *
3499 * @param type $attr
3500 * @return type
3501 *
3502 * Shortcodes exmaples:
3503 *
3504 *
3505 ** Matrix:
3506 * 1 Month View Mode:
3507 [bookingtimeline type="3,4,1,5,6,7,8,9,2,10,11,12,14" view_days_num=30 scroll_start_date="" scroll_month=0 header_title='All Bookings']
3508 * 2 Months View Mode:
3509 [bookingtimeline type="1,5,6,7,8,9,2,10,11,12,3,4,14" view_days_num=60 scroll_start_date="" scroll_month=-1 header_title='All Bookings']
3510 * 1 Week View Mode:
3511 [bookingtimeline type="3,4" view_days_num=7 scroll_start_date="" scroll_day=-7 header_title='All Bookings']
3512 * 1 Day View Mode:
3513 [bookingtimeline type="3,4" view_days_num=1 scroll_start_date="" scroll_day=0 header_title='All Bookings']
3514
3515 ** Single:
3516 * 1 Month View Mode:
3517 [bookingtimeline type="4" view_days_num=30 scroll_start_date="" scroll_day=-15 scroll_month=0 header_title='All Bookings']
3518 * 3 Months View Mode:
3519 [bookingtimeline type="4" view_days_num=90 scroll_start_date="" scroll_day=-30]
3520 * 1 Year View Mode:
3521 [bookingtimeline type="4" view_days_num=365 scroll_start_date="" scroll_month=-3]
3522
3523
3524 */
3525 function bookingflextimeline_shortcode($attr) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound
3526
3527 if ( wpbc_is_on_edit_page() ) {
3528 return wpbc_get_preview_for_shortcode( 'bookingflextimeline', $attr ); // FixIn: 9.9.0.39.
3529 }
3530
3531 $attr = wpbc_escape_shortcode_params( $attr ); //FixIn: 9.7.3.6.1
3532
3533 if ( '' === $attr ) {
3534 $attr = array(); // FixIn: 9.9.0.30.
3535 }
3536
3537 //if ( function_exists( 'wpbc_br_cache' ) ) $br_cache = wpbc_br_cache(); // Init booking resources cache
3538 if ( isset( $attr['resource_id'] ) ) { $attr['type'] = $attr['resource_id']; }
3539 if ( empty( $attr['type'] ) ) { // 8.7.7.4
3540 if ( class_exists( 'wpdev_bk_personal' ) ) {
3541 $br_list = wpbc_get_all_booking_resources_list();
3542 $br_list = array_keys( $br_list );
3543 $br_list = implode( ',', $br_list );
3544 $attr['type'] = $br_list;
3545 } else {
3546 $attr['type'] = wpbc_get_default_resource();
3547 }
3548 }
3549
3550 if ( ! isset( $attr['view_days_num' ] ) ) {
3551 $attr['view_days_num' ] = 30;
3552 }
3553 if ( ! isset( $attr['scroll_start_date' ] ) ) {
3554 $attr['scroll_start_date' ] = '';
3555 }
3556 if ( ! isset( $attr['scroll_day' ] ) ) {
3557 $attr['scroll_day' ] = 0;
3558 }
3559 if ( ! isset( $attr['scroll_month' ] ) ) {
3560 $attr['scroll_month' ] = 0;
3561 }
3562 if ( ! isset( $attr['header_title' ] ) ) {
3563 $attr['header_title' ] = '';
3564 }
3565
3566 // FixIn: 9.9.0.18.
3567 $server_zone = date_default_timezone_get(); // If in 'Theme' or 'other plugin' set default timezone other than UTC. Save it.
3568 if ( 'UTC' !== $server_zone ) { // Needed for WP date functions - set timezone to UTC
3569 // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
3570 @date_default_timezone_set( 'UTC' );
3571 }
3572
3573 ob_start();
3574
3575 $timeline = new WPBC_TimelineFlex();
3576
3577 $html_client_id = $timeline->client_init( $attr ); // Define arameters and get bookings
3578
3579 //wpbc_datepicker_js(); // JS Datepicker
3580 //wpbc_datepicker_css(); // CSS DatePicker
3581
3582
3583 echo '<div class="wpdevelop">';
3584
3585 echo '<div id="' . esc_attr( $html_client_id ) . '" class="wpbc_timeline_client_border">';
3586
3587 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
3588 echo wp_nonce_field( 'WPBC_FLEXTIMELINE_NAV', 'wpbc_nonce_' . esc_attr( $html_client_id ), true, false );
3589 echo '<div id="ajax_respond_insert' . esc_attr( $html_client_id ) . '" class="ajax_respond_insert" style="display:none;"></div>';
3590
3591 echo '<div class="wpbc_timeline_ajax_replace">';
3592 if ( ! WPBC()->booking_obj->popover_front_end_js_is_writed ) { //Write this JS only once at page
3593 wpbc_bs_javascript_popover(); // JS Popover
3594 WPBC()->booking_obj->popover_front_end_js_is_writed = true;
3595 } // FixIn: 9.2.1.3.
3596
3597 //Define Global JavaScript Object - array of objects. // FixIn: 9.2.1.3.
3598 ?>
3599 <script type="text/javascript">
3600 var wpbc_timeline_obj;
3601 if ( undefined === wpbc_timeline_obj ){
3602 wpbc_timeline_obj = [];
3603 }
3604 </script>
3605 <?php
3606
3607 $timeline->show_timeline();
3608 echo '</div>';
3609
3610 echo '</div>';
3611
3612 echo '</div>';
3613
3614 // Fix for "Twenty Two" theme.
3615 // Theme incorrectly closing HTML elements with attributes that contain HTML tags in content of the posts and pages.
3616 // For example, if the HTML element have tags like this
3617 // <div data-content="<div class='flex-popover-content-data'>Data</div>" data-original-title="<div class='popover-title-id' > ID: 19</div>" >My text</div>
3618 // Theme show info like this
3619 // <div data-content="<div class='flex-popover-content-data'>Data</div>” data-original-title=”<div class='popover-title-id' > ID: 19</div>” >My text</div>
3620 /*
3621 ?><script type="text/javascript">
3622 wpbc_flextimeline_nav( wpbc_timeline_obj['<?php echo $html_client_id; ?>'], 0 );
3623 </script><?php
3624 */
3625
3626 $timeline_results = ob_get_contents();
3627
3628 ob_end_clean();
3629
3630 // FixIn: 9.9.0.18.
3631 if ( 'UTC' !== $server_zone ) { // Back to previos state, if it was changed.
3632 // phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
3633 @date_default_timezone_set( $server_zone );
3634 }
3635
3636 return $timeline_results ;
3637 }
3638 add_shortcode( 'bookingflextimeline', 'bookingflextimeline_shortcode' );
3639
3640
3641
3642 /** JSS */
3643 function wpbc_timeline_js_load_files( $where_to_load ) {
3644
3645 // FixIn: 8.6.1.13.
3646
3647 $is_in_footer = ! true;
3648
3649 if ( in_array( $where_to_load, array( 'admin', 'both', 'client' ) ) ) {
3650
3651 wp_enqueue_script( 'wpbc-timeline-flex'
3652 , trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/timeline_v2.js' /* wpbc_plugin_url( '/core/timeline/wpbc-flex-timeline.js' ) */
3653 , array( 'wpbc_all' /*, 'wp-element'*/ )
3654 , WP_BK_VERSION_NUM
3655 , array( 'in_footer' => WPBC_JS_IN_FOOTER ) //, $is_in_footer
3656 );
3657 }
3658 }
3659 add_action( 'wpbc_enqueue_js_files', 'wpbc_timeline_js_load_files', 50 );
3660
3661
3662 /** CSS */
3663 function wpbc_timeline_enqueue_css_files( $where_to_load ) {
3664
3665 // FixIn: 8.6.1.13.
3666
3667 if ( in_array( $where_to_load, array( 'admin', 'both', 'client' ) ) ) {
3668
3669 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
3670 if ( ( ( isset($_REQUEST['tab']) ) && ( $_REQUEST['tab']== 'vm_calendar' ) ) || ( 'client' == $where_to_load ) ){
3671
3672 wp_enqueue_style( 'wpbc-flex-timeline'
3673 , trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/timeline_v2.1.css' /* wpbc_plugin_url( '/src/css/code_mirror.css' ) */
3674 , array()
3675 , WP_BK_VERSION_NUM );
3676 }
3677 }
3678 }
3679 add_action( 'wpbc_enqueue_css_files', 'wpbc_timeline_enqueue_css_files', 50 );
3680