PluginProbe
Booking Calendar / 11.8.4
Booking Calendar v11.8.4
11.8.4 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 All 204 releases
booking / core / timeline / v2 / wpbc-class-timeline_v2.php

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

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