PluginProbe
Booking Calendar / 11.8
Booking Calendar v11.8
11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 10.11.3 All 202 releases
booking / includes / ui_settings / class-page-structure.php

class-page-structure.php in Booking Calendar 11.8, at includes/ui_settings/class-page-structure.php

843 lines 31.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Page Structure in Admin Panel
4 *
5 * @version 1.2
6 * @package Any
7 * @category Page Structure in Admin Panel
8 * @author wpdevelop
9 *
10 * @web-site https://wpbookingcalendar.com/
11 * @email info@wpbookingcalendar.com
12 *
13 * @modified 2024-12-23, 2015-11-02
14 */
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit; // Exit, if accessed directly.
18 }
19
20 /**
21 * == All Page Parameters ==
22 *
23 * TODO Refactorig: Continue work with description of the: List of all parameters, that possible to use in public function tabs() { ... }
24
25 'is_default_full_screen' => false, // true | false. Default: false.
26 'is_force_full_screen' => false, // true | false. Default: false.
27 'right_vertical_sidebar__is_show' => false, // true | false. Default: false.
28 'right_vertical_sidebar__default_view_mode' => 'max', // '' | 'min' | 'compact' | 'max' | 'none'. Default: ''.
29 'right_vertical_sidebar__content_click_collapse_mode' => '', // '' | 'min' | 'compact' | 'none'. Collapse or hide an expanded right sidebar when the page content is clicked. Default: ''.
30 'left_navigation__default_view_mode' => 'max', // '' | 'min' | 'compact' | 'max' | 'none'. Default: ''.
31 'left_navigation__force_view_mode' => '', // '' | 'min' | 'compact' | 'max' | 'none'. Default: ''.
32 'right_vertical_sidebar_compact__is_show' => false, // true | false. Default: false.
33
34 // TODO: recheck functionality and ability to use:
35
36 'is_show_top_path' => true, // true | false. By default value is: true.
37 'is_show_top_navigation' => false, // true | false. By default value is: false.
38 'title' => __( 'Booking Form Builder', 'booking' ), // Title of TAB //FixIn: 9.8.15.2.2.
39 'hint' => __( 'Define available days', 'booking' ), // Hint.
40 'page_title' => __( 'Booking Form Builder', 'booking' ), // Title of Page.
41 'link' => '', // Can be skiped, then generated link based on Page and Tab tags. Or can be extenral link.
42 'position' => '', // 'left' / 'right' / ''.
43 'css_classes' => '', // CSS c l a s s(es).
44 'icon' => '', // Icon - link to the real PNG img.
45 'font_icon' => 'wpbc_icn_flip_x0 wpbc-bi-input-cursor-text', // 'wpbc_icn_free_cancellation' // CSS definition of forn Icon.
46 'font_icon_right' => 'wpbc-bi-asterisk',
47 'default' => false, // Is this tab activated by default or not: true || false.
48 'disabled' => false, // Is this tab disbaled: true || false.
49 'hided' => false, // Is this tab hided: true || false.
50 'subtabs' => array(),
51 'folder_style' => 'order:11;',
52
53 */
54
55
56 /**
57 * Define Settings Page Structure
58 */
59 abstract class WPBC_Page_Structure extends WPBC_Menu_Structure {
60
61 // FixIn: 11.0.0.1.
62
63 /**
64 * Constructor
65 */
66 public function __construct() {
67
68 parent::__construct();
69
70 // This Hook fire in the class WPBC_Admin_Menus for showing page content of specific menu.
71 add_action( 'wpbc_page_structure_show', array( $this, 'content_structure' ) );
72
73 add_filter( 'admin_body_class', array( $this, 'wpbc_add_admin_body_class' ) );
74 }
75
76
77 /**
78 * Set the wpbc_admin class to body.
79 *
80 * @param bool $classes Body classes.
81 *
82 * @return array
83 */
84 public function wpbc_add_admin_body_class( $classes ) {
85
86
87 if ( $this->is_page_activated() ) {
88 $classes .= ' wpbc_admin';
89 }
90
91 return $classes;
92 }
93
94
95 // -----------------------------------------------------------------------------------------------------------------
96 // Abstract Methods
97 // -----------------------------------------------------------------------------------------------------------------
98 // FixIn: 10.11.4.4. Removed abstarct classes that exists in the parent class.
99
100 /**
101 * Child classes ovveride it for auto update / save options in main form
102 *
103 * @return void
104 */
105 public function maybe_update() {}
106
107
108 /**
109 * Child classes ovveride -- show vertical "Right Sidebar Content".
110 * // FixIn: 10.14.1.3.
111 *
112 * @return void
113 */
114 public function right_sidebar_content(){}
115
116
117
118 /**
119 * Child classes ovveride -- show vertical "Right Sidebar Content - Compact".
120 * // FixIn: 10.14.1.3.
121 *
122 * @return void
123 */
124 public function right_sidebar_compact_content(){}
125
126
127 // -----------------------------------------------------------------------------------------------------------------
128 // C O N T E N T
129 // -----------------------------------------------------------------------------------------------------------------
130
131 /**
132 * General Page Structure
133 *
134 * @param string $page_tag - its the same that return $this->in_page ().
135 */
136 public function content_structure( $page_tag ) {
137
138 // -------------------------------------------------------------------------------------------------------------
139 // Checking if this page - A C T I V E
140 // -------------------------------------------------------------------------------------------------------------
141 if ( ! $this->is_page_activated() ) {
142 return false;
143 }
144
145 $active_page_tab = $this->get_active__tab__tag();
146 $active_page_subtab = $this->get_active__subtab__tag();
147
148 // Fires Before showing settings Content page. Used in MultiUser version for blocking access to some pages.
149 $is_show_this_page = apply_filters( 'wpbc_before_showing_settings_page_is_show_page', true, $page_tag, $active_page_tab, $active_page_subtab );
150 if ( false === $is_show_this_page ) {
151 return false;
152 }
153
154 $this->update_nav_tabs_structure( $page_tag, $active_page_tab, $active_page_subtab );
155
156 // -------------------------------------------------------------------------------------------------------------
157 // -- U p d a t e --
158 // -------------------------------------------------------------------------------------------------------------
159 $this->maybe_update();
160
161 // -------------------------------------------------------------------------------------------------------------
162 // -- T e m p l a t e --
163 // -------------------------------------------------------------------------------------------------------------
164
165 // Hook: Fires Before showing settings Content page.
166 do_action( 'wpbc_before_settings_content', $page_tag, $active_page_tab, $active_page_subtab );
167
168
169 $template_params_arr = array(
170 'active_page' => $page_tag,
171 'active_tab' => $active_page_tab,
172 'active_subtab' => $active_page_subtab,
173 'page_structure_obj' => $this,
174 );
175 $settings_templates = new WPBC_Settings_Page_Parts( $template_params_arr );
176
177 // ---------------------------------------------------------------------------------------------------------
178 // Template Header
179 // ---------------------------------------------------------------------------------------------------------
180 $settings_templates->template_header();
181
182 wp_nonce_field( 'wpbc_ajax_admin_nonce', 'wpbc_admin_panel_nonce', true, true ); // Nonce.
183
184 // ---------------------------------------------------------------------------------------------------------
185 // Content.
186 // ---------------------------------------------------------------------------------------------------------
187 if ( ( isset( $this->current_page_params['subtab'] ) ) && ( isset( $this->current_page_params['subtab']['content'] ) ) ) {
188 call_user_func( array( $this, $this->current_page_params['subtab']['content'] ) );
189 } elseif ( ( isset( $this->current_page_params['tab'] ) ) && ( isset( $this->current_page_params['tab']['content'] ) ) ) {
190 call_user_func( array( $this, $this->current_page_params['tab']['content'] ) );
191 } else {
192 $this->content();
193 }
194
195 do_action( 'wpbc_show_settings_content', $page_tag, $active_page_tab, $active_page_subtab ); // Hook.
196
197 // ---------------------------------------------------------------------------------------------------------
198 // Template Footer
199 // ---------------------------------------------------------------------------------------------------------
200 $settings_templates->template_footer();
201
202 do_action( 'wpbc_after_settings_content', $page_tag, $active_page_tab, $active_page_subtab ); // Hook: Fires After showing settings Content page.
203 }
204
205
206 // -----------------------------------------------------------------------------------------------------------------
207 // == Support ==
208 // -----------------------------------------------------------------------------------------------------------------
209
210 /**
211 * Update structure of self::$nav_tabs with 'is_active' and 'url' parameters.
212 * We can do this here, because this function executed at step of showing content, and we know about all the structure of the menus, already.
213 *
214 * Based on URL: /admin.php?page=wpbc-settings&tab=email&subtab=new-visitor
215 *
216 * @param string $page_tag - 'wpbc-settings'.
217 * @param string $active_page_tab - 'email'.
218 * @param string $active_page_subtab - 'new-visitor'.
219 *
220 * @return bool
221 */
222 private function update_nav_tabs_structure( $page_tag, $active_page_tab, $active_page_subtab ) {
223
224 if ( empty( self::$nav_tabs ) ) {
225 return false;
226 }
227
228 // Menu Pages [Bookings, Resources, Prices, Settings ].
229 foreach ( self::$nav_tabs as $nav_page_tag => $nav_page_arr ) {
230
231 // Tabs [ General, Emails, ... ].
232 foreach ( self::$nav_tabs[ $nav_page_tag ] as $nav_tab_tag => $nav_tab_arr ) {
233
234 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['is_active'] = false;
235 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['url'] = ( ! empty( self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['link'] ) )
236 ? self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['link']
237 : $this->get_tab_url( $nav_page_tag, $nav_tab_tag );
238 // Inside of this page 'wpbc-settings' ?
239 if ( $nav_page_tag === $page_tag ) {
240
241 // Tab not selected -> clicked on Left menu only, but this is 'DEFAULT' TAB, so true.
242 if ( ( empty( $active_page_tab ) ) && ( ! empty( self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['default'] ) ) ) {
243 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['is_active'] = true;
244 }
245
246 // Page and Tab clicked !
247 if ( ( $nav_page_tag === $page_tag ) && ( $active_page_tab === $nav_tab_tag ) ) {
248 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['is_active'] = true;
249 }
250 }
251
252 if ( ! empty( self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'] ) ) {
253 // SubTabs e.g.: [ "New booking", "Approved", ... ].
254 foreach ( self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'] as $nav_subtab_tag => $nav_subtab_arr ) {
255
256 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['is_active'] = false;
257
258 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['url'] = ( ! empty( self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['link'] ) )
259 ? self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['link']
260 : $this->get_tab_url( $nav_page_tag, $nav_tab_tag, $nav_subtab_tag );
261 // We know that this TAB is active.
262 if ( ! empty( self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['is_active'] ) ) {
263
264 // SubTab not selected -> clicked on Left menu and Tab only, but not clicked on submenu (e.g. Stripe or "approved email") and if we have this is 'DEFAULT' TAB, so true.
265 if ( ( empty( $active_page_subtab ) ) && ( ! empty( self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['default'] ) ) ) {
266 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['is_active'] = true;
267 }
268
269 // Page and SubTab clicked !
270 if ( $active_page_subtab === $nav_subtab_tag ) {
271 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['is_active'] = true;
272 }
273 }
274 }
275 }
276 }
277 }
278 return true;
279 }
280
281 /**
282 * Get current active TAB 'Tag'
283 *
284 * @return mixed|string
285 */
286 protected function get_active__tab__tag() {
287
288 $active_page_tab = '';
289
290 if ( ( isset( $this->current_page_params['tab'] ) ) && ( ! empty( $this->current_page_params['tab']['tag'] ) ) ) {
291 $active_page_tab = $this->current_page_params['tab']['tag'];
292 }
293
294 return $active_page_tab;
295 }
296
297 /**
298 * Get current active SubTAB 'Tag'
299 *
300 * @return mixed|string
301 */
302 protected function get_active__subtab__tag() {
303
304 $active_page_subtab = '';
305
306 if ( ( isset( $this->current_page_params['subtab'] ) ) && ( ! empty( $this->current_page_params['subtab']['tag'] ) ) ) {
307 $active_page_subtab = $this->current_page_params['subtab']['tag'];
308 }
309
310 return $active_page_subtab;
311 }
312
313 /**
314 * Get Option. Check if this defined in Tabs or Subtabs array Otherwise return false.
315 *
316 * @param string $option_name - name of the option, like 'is_use_new_settings_skin'.
317 *
318 * @return false|mixed
319 *
320 * Example: $is_use_new_settings_skin = $this->is_use_option__in_subtabs( 'is_use_new_settings_skin' );
321 */
322 public function is_use_option__in_subtabs_or_tabs( $option_name ) {
323
324 // Check if this otion defined in tabs or 'subtabs' ?
325 $is_use_option = $this->is_use_option__in_subtabs( $option_name );
326
327 // If this option not defined in 'subtabs', then we check it in 'tab'.
328 if ( false === $is_use_option ) {
329 $is_use_option = ( $this->is_use_option__in_tabs( $option_name ) );
330 }
331
332 return $is_use_option;
333 }
334
335 /**
336 * Get Option. Check if this defined in subtabs array Otherwise return false.
337 *
338 * @param string $option_name - name of the option, like 'is_use_new_settings_skin'.
339 *
340 * @return false|mixed
341 *
342 * Example: $is_use_new_settings_skin = $this->is_use_option__in_subtabs( 'is_use_new_settings_skin' );
343 */
344 public function is_use_option__in_subtabs( $option_name ) {
345
346 // Check if this otion defined in subtabs ?
347 $is_use_option = ( ( isset( $this->current_page_params['subtab'] ) ) && ( ! empty( $this->current_page_params['subtab'][ $option_name ] ) ) )
348 ? $this->current_page_params['subtab'][ $option_name ]
349 : false;
350
351 return $is_use_option;
352 }
353
354 /**
355 * Get Option. Check if this defined in btabs array Otherwise return false.
356 *
357 * @param string $option_name - name of the option, like 'is_use_new_settings_skin'.
358 *
359 * @return false|mixed
360 *
361 * Example: $is_use_new_settings_skin = $this->is_use_option__in_subtabs( 'is_use_new_settings_skin' );
362 */
363 public function is_use_option__in_tabs( $option_name ) {
364
365 // Check if this otion defined in subtabs ?
366 $is_use_option = ( ( isset( $this->current_page_params['tab'] ) ) && ( ! empty( $this->current_page_params['tab'][ $option_name ] ) ) )
367 ? $this->current_page_params['tab'][ $option_name ]
368 : false;
369
370 return $is_use_option;
371 }
372
373 /**
374 * Get allowed left sidebar mode.
375 *
376 * @param string $mode Sidebar mode.
377 *
378 * @return string
379 */
380 private function get_valid_left_navigation_mode( $mode ) {
381
382 $mode = strval( $mode );
383 $allowed_modes = array( '', 'min', 'compact', 'max', 'none' );
384
385 return in_array( $mode, $allowed_modes, true ) ? $mode : '';
386 }
387
388 /**
389 * Get page-defined left sidebar mode before user preferences.
390 *
391 * @return string
392 */
393 private function get_page_left_navigation_default_mode() {
394
395 return $this->get_valid_left_navigation_mode( $this->is_use_option__in_subtabs_or_tabs( 'left_navigation__default_view_mode' ) );
396 }
397
398 /**
399 * Get forced left sidebar mode, if the current page must not use the user preference.
400 *
401 * @return string
402 */
403 private function get_forced_left_navigation_mode() {
404
405 return $this->get_valid_left_navigation_mode( $this->is_use_option__in_subtabs_or_tabs( 'left_navigation__force_view_mode' ) );
406 }
407
408 /**
409 * Check whether the current page should save and restore the user left sidebar preference.
410 *
411 * @return bool
412 */
413 public function is_left_navigation_user_mode_enabled() {
414
415 $forced_mode = $this->get_forced_left_navigation_mode();
416
417 if ( ! empty( $forced_mode ) ) {
418 return false;
419 }
420
421 if ( 'none' === $this->get_page_left_navigation_default_mode() ) {
422 return false;
423 }
424
425 return true;
426 }
427
428 /**
429 * Resolve the initial left sidebar mode.
430 *
431 * Forced page mode wins, then the saved user preference, then the page default.
432 *
433 * @return string
434 */
435 public function get_left_navigation_default_view_mode() {
436
437 $forced_mode = $this->get_forced_left_navigation_mode();
438
439 if ( ! empty( $forced_mode ) ) {
440 return $forced_mode;
441 }
442
443 $page_default_mode = $this->get_page_left_navigation_default_mode();
444
445 if ( 'none' === $page_default_mode ) {
446 return 'none';
447 }
448
449 $saved_user_mode = '';
450 if ( class_exists( 'WPBC_User_Custom_Data_Saver' ) ) {
451 $saved_user_mode = WPBC_User_Custom_Data_Saver::get_user_data_value( wpbc_get_current_user_id(), 'left_sidebar_view_mode' );
452 $saved_user_mode = $this->get_valid_left_navigation_mode( $saved_user_mode );
453 }
454
455 if ( ! empty( $saved_user_mode ) && ( 'none' !== $saved_user_mode ) ) {
456 return $saved_user_mode;
457 }
458
459 return $page_default_mode;
460 }
461
462 /**
463 * Check whether the current page should open in fullscreen.
464 *
465 * Forced page mode wins, then the saved user preference, then the page default.
466 *
467 * @return bool
468 */
469 public function is_full_screen_mode_enabled() {
470
471 if ( $this->is_use_option__in_subtabs_or_tabs( 'is_force_full_screen' ) ) {
472 return true;
473 }
474
475 if ( class_exists( 'WPBC_User_Custom_Data_Saver' ) ) {
476 $saved_full_screen = WPBC_User_Custom_Data_Saver::get_user_data_value( wpbc_get_current_user_id(), 'is_full_screen' );
477 $saved_full_screen = function_exists( 'wpbc_ui__get_full_screen_mode_from_cookie' )
478 ? wpbc_ui__get_full_screen_mode_from_cookie( $saved_full_screen )
479 : $saved_full_screen;
480
481 if ( 'On' === $saved_full_screen ) {
482 return true;
483 }
484
485 if ( 'Off' === $saved_full_screen ) {
486 return false;
487 }
488 }
489
490 return (bool) $this->is_use_option__in_subtabs_or_tabs( 'is_default_full_screen' );
491 }
492
493 /**
494 * Check whether the current page should save and restore the user fullscreen preference.
495 *
496 * @return bool
497 */
498 public function is_full_screen_user_mode_enabled() {
499
500 if ( $this->is_use_option__in_subtabs_or_tabs( 'is_force_full_screen' ) ) {
501 return false;
502 }
503
504 return true;
505 }
506
507 /**
508 * Get breadcrumb/status-line items for the top path.
509 *
510 * Pages usually only need 'is_show_top_path' => true. Optional 'top_path'
511 * settings in tabs/subtabs can override root title, root URL, version
512 * visibility, or provide custom items.
513 *
514 * @return array
515 */
516 public function get_top_path_items() {
517
518 $page_tag = $this->get_top_path_page_tag();
519 $top_path_config = $this->is_use_option__in_subtabs_or_tabs( 'top_path' );
520 $top_path_config = is_array( $top_path_config ) ? $top_path_config : array();
521
522 if ( ! empty( $top_path_config['items'] ) && is_array( $top_path_config['items'] ) ) {
523 $items = $this->normalize_top_path_items( $top_path_config['items'] );
524 return apply_filters( 'wpbc_ui_settings_top_path_items', $items, $this, $top_path_config );
525 }
526
527 $items = array();
528
529 if ( ! isset( $top_path_config['product_title'] ) || false !== $top_path_config['product_title'] ) {
530 $items[] = array(
531 'title' => isset( $top_path_config['product_title'] ) ? $top_path_config['product_title'] : __( 'WP Booking Calendar', 'booking' ),
532 'url' => isset( $top_path_config['product_url'] ) ? $top_path_config['product_url'] : $this->get_top_path_product_url(),
533 'active' => false,
534 );
535 }
536
537 if ( ! isset( $top_path_config['root_title'] ) || false !== $top_path_config['root_title'] ) {
538 $items[] = array(
539 'title' => isset( $top_path_config['root_title'] ) ? $top_path_config['root_title'] : $this->get_top_path_default_root_title( $page_tag ),
540 'url' => isset( $top_path_config['root_url'] ) ? $top_path_config['root_url'] : $this->get_top_path_default_root_url( $page_tag ),
541 'active' => false,
542 );
543 }
544
545 $tab_item = $this->get_top_path_tab_item( $page_tag );
546 if ( ! empty( $tab_item ) ) {
547 $items = $this->append_top_path_item( $items, $tab_item );
548 }
549
550 $subtab_item = $this->get_top_path_subtab_item( $page_tag );
551 if ( ! empty( $subtab_item ) ) {
552 $items = $this->append_top_path_item( $items, $subtab_item );
553 }
554
555 if ( ! empty( $items ) ) {
556 $last_item_index = count( $items ) - 1;
557 foreach ( $items as $item_index => $item ) {
558 $items[ $item_index ]['active'] = ( $item_index === $last_item_index );
559 }
560 }
561
562 $items = $this->normalize_top_path_items( $items );
563
564 return apply_filters( 'wpbc_ui_settings_top_path_items', $items, $this, $top_path_config );
565 }
566
567 /**
568 * Check whether the top path should be visible.
569 *
570 * The status line is visible by default. Pages can disable it explicitly
571 * with 'is_show_top_path' => false in tab or subtab definition.
572 *
573 * @return bool
574 */
575 public function is_top_path_enabled() {
576
577 if ( isset( $this->current_page_params['subtab'] ) && array_key_exists( 'is_show_top_path', $this->current_page_params['subtab'] ) ) {
578 return ( false !== $this->current_page_params['subtab']['is_show_top_path'] );
579 }
580
581 if ( isset( $this->current_page_params['tab'] ) && array_key_exists( 'is_show_top_path', $this->current_page_params['tab'] ) ) {
582 return ( false !== $this->current_page_params['tab']['is_show_top_path'] );
583 }
584
585 return true;
586 }
587
588 /**
589 * Check whether the top path should include the version/status block.
590 *
591 * @return bool
592 */
593 public function is_top_path_show_version() {
594
595 $top_path_config = $this->is_use_option__in_subtabs_or_tabs( 'top_path' );
596
597 if ( is_array( $top_path_config ) && array_key_exists( 'show_version', $top_path_config ) ) {
598 return (bool) $top_path_config['show_version'];
599 }
600
601 return true;
602 }
603
604 /**
605 * Get active page tag for top path generation.
606 *
607 * @return string
608 */
609 private function get_top_path_page_tag() {
610
611 $this_page = $this->in_page();
612 $this_page_arr = is_array( $this_page ) ? $this_page : array( $this_page );
613 $request_page = isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
614
615 if ( in_array( $request_page, $this_page_arr, true ) ) {
616 return $request_page;
617 }
618
619 return (string) reset( $this_page_arr );
620 }
621
622 /**
623 * Get default root title.
624 *
625 * @param string $page_tag Page tag.
626 *
627 * @return string
628 */
629 private function get_top_path_default_root_title( $page_tag ) {
630
631 $root_titles = array(
632 'wpbc' => __( 'Bookings', 'booking' ),
633 'wpbc-availability' => __( 'Availability', 'booking' ),
634 'wpbc-prices' => __( 'Prices', 'booking' ),
635 'wpbc-resources' => __( 'Resources', 'booking' ),
636 'wpbc-settings' => __( 'Settings', 'booking' ),
637 'wpbc-setup' => __( 'Setup', 'booking' ),
638 );
639 return isset( $root_titles[ $page_tag ] ) ? $root_titles[ $page_tag ] : __( 'Booking Calendar', 'booking' );
640 }
641
642 /**
643 * Get product root URL.
644 *
645 * @return string
646 */
647 private function get_top_path_product_url() {
648
649 if ( function_exists( 'wpbc_get_bookings_url' ) ) {
650 return wpbc_get_bookings_url();
651 }
652
653 return admin_url( 'admin.php?page=wpbc' );
654 }
655
656 /**
657 * Get default root URL.
658 *
659 * @param string $page_tag Page tag.
660 *
661 * @return string
662 */
663 private function get_top_path_default_root_url( $page_tag ) {
664
665 if ( 'wpbc' === $page_tag && function_exists( 'wpbc_get_bookings_url' ) ) {
666 return wpbc_get_bookings_url();
667 }
668
669 if ( 'wpbc-availability' === $page_tag && function_exists( 'wpbc_get_availability_url' ) ) {
670 return wpbc_get_availability_url();
671 }
672
673 if ( 'wpbc-prices' === $page_tag && function_exists( 'wpbc_get_price_url' ) ) {
674 return wpbc_get_price_url();
675 }
676
677 if ( 'wpbc-settings' === $page_tag && function_exists( 'wpbc_get_settings_url' ) ) {
678 return wpbc_get_settings_url();
679 }
680
681 if ( 'wpbc-resources' === $page_tag && function_exists( 'wpbc_get_resources_url' ) ) {
682 return wpbc_get_resources_url();
683 }
684
685 if ( 'wpbc-setup' === $page_tag && function_exists( 'wpbc_get_setup_wizard_page_url' ) ) {
686 return wpbc_get_setup_wizard_page_url();
687 }
688
689 return admin_url( add_query_arg( array( 'page' => $page_tag ), 'admin.php' ) );
690 }
691
692 /**
693 * Get top path item for the active tab.
694 *
695 * @param string $page_tag Page tag.
696 *
697 * @return array
698 */
699 private function get_top_path_tab_item( $page_tag ) {
700
701 $active_tab_tag = $this->get_active__tab__tag();
702 $nav_tabs = $this->get_nav_tabs();
703 $tab_arr = isset( $nav_tabs[ $page_tag ][ $active_tab_tag ] ) ? $nav_tabs[ $page_tag ][ $active_tab_tag ] : array();
704
705 if ( empty( $tab_arr ) && ! empty( $this->current_page_params['tab'] ) ) {
706 $tab_arr = $this->current_page_params['tab'];
707 }
708
709 if ( empty( $active_tab_tag ) || empty( $tab_arr ) ) {
710 return array();
711 }
712
713 return array(
714 'title' => isset( $tab_arr['top_path_title'] ) ? $tab_arr['top_path_title'] : ( isset( $tab_arr['title'] ) ? $tab_arr['title'] : '' ),
715 'url' => ! empty( $tab_arr['url'] ) ? $tab_arr['url'] : $this->get_tab_url( $page_tag, $active_tab_tag ),
716 'onclick' => ! empty( $tab_arr['onclick'] ) ? $tab_arr['onclick'] : '',
717 'active' => true,
718 );
719 }
720
721 /**
722 * Get top path item for the active subtab.
723 *
724 * @param string $page_tag Page tag.
725 *
726 * @return array
727 */
728 private function get_top_path_subtab_item( $page_tag ) {
729
730 $active_tab_tag = $this->get_active__tab__tag();
731 $active_subtab_tag = $this->get_active__subtab__tag();
732 $nav_tabs = $this->get_nav_tabs();
733 $subtab_arr = isset( $nav_tabs[ $page_tag ][ $active_tab_tag ]['subtabs'][ $active_subtab_tag ] ) ? $nav_tabs[ $page_tag ][ $active_tab_tag ]['subtabs'][ $active_subtab_tag ] : array();
734
735 if ( empty( $subtab_arr ) && ! empty( $this->current_page_params['subtab'] ) ) {
736 $subtab_arr = $this->current_page_params['subtab'];
737 }
738
739 if ( empty( $active_tab_tag ) || empty( $active_subtab_tag ) || empty( $subtab_arr ) || empty( $subtab_arr['type'] ) || 'subtab' !== $subtab_arr['type'] ) {
740 return array();
741 }
742
743 return array(
744 'title' => isset( $subtab_arr['top_path_title'] ) ? $subtab_arr['top_path_title'] : ( isset( $subtab_arr['title'] ) ? $subtab_arr['title'] : '' ),
745 'url' => ! empty( $subtab_arr['url'] ) ? $subtab_arr['url'] : $this->get_tab_url( $page_tag, $active_tab_tag, $active_subtab_tag ),
746 'onclick' => ! empty( $subtab_arr['onclick'] ) ? $subtab_arr['onclick'] : '',
747 'active' => true,
748 );
749 }
750
751 /**
752 * Normalize top path item values.
753 *
754 * @param array $items Top path items.
755 *
756 * @return array
757 */
758 private function normalize_top_path_items( $items ) {
759
760 $normalized_items = array();
761
762 foreach ( $items as $item ) {
763 if ( empty( $item['title'] ) ) {
764 continue;
765 }
766
767 $normalized_items[] = array(
768 'title' => wp_strip_all_tags( $item['title'] ),
769 'url' => isset( $item['url'] ) ? $item['url'] : '',
770 'onclick' => isset( $item['onclick'] ) ? $item['onclick'] : '',
771 'active' => ! empty( $item['active'] ),
772 );
773 }
774
775 return $normalized_items;
776 }
777
778 /**
779 * Append top path item, avoiding consecutive duplicate labels.
780 *
781 * @param array $items Top path items.
782 * @param array $item New top path item.
783 *
784 * @return array
785 */
786 private function append_top_path_item( $items, $item ) {
787
788 if ( empty( $items ) || empty( $item['title'] ) ) {
789 $items[] = $item;
790 return $items;
791 }
792
793 $last_item_index = count( $items ) - 1;
794 $last_title = isset( $items[ $last_item_index ]['title'] ) ? wp_strip_all_tags( $items[ $last_item_index ]['title'] ) : '';
795 $item_title = wp_strip_all_tags( $item['title'] );
796
797 if ( $last_title === $item_title ) {
798 if ( ! empty( $item['url'] ) ) {
799 $items[ $last_item_index ]['url'] = $item['url'];
800 }
801 if ( ! empty( $item['onclick'] ) ) {
802 $items[ $last_item_index ]['onclick'] = $item['onclick'];
803 }
804 return $items;
805 }
806
807 $items[] = $item;
808
809 return $items;
810 }
811
812 /**
813 * Get Navigation path for header, if applicable.
814 * Used in Setup Wizard page.
815 *
816 * @return false|array
817 */
818 protected function is_use_navigation_path_arr() {
819
820 // Use Top line as Path in Setup Wizard page // FixIn: 10.4.0.2.
821 $is_use_navigation_path_arr = $this->is_use_option__in_subtabs( 'is_use_navigation_path' );
822
823 return $is_use_navigation_path_arr;
824 }
825
826 /**
827 * Get URL of settings page, based on Page Slug and Tab Slug e.g. page=wpbc-settings&tab=email&subtab=approved
828 *
829 * @param string $page_tag - e.g. 'wpbc-settings'.
830 * @param string $tab_name - e.g. 'email'.
831 * @param string $subtab_name ( Optional ) - e.g. 'approved'.
832 *
833 * @return string - Escaped URL to plugin page.
834 */
835 private function get_tab_url( $page_tag, $tab_name, $subtab_name = false ) {
836 if ( false === $subtab_name ) {
837 return esc_url( admin_url( add_query_arg( array( 'page' => $page_tag, $this->tags['tab'] => $tab_name ), 'admin.php' ) ) );
838 } else {
839 return esc_url( admin_url( add_query_arg( array( 'page' => $page_tag, $this->tags['tab'] => $tab_name, $this->tags['subtab'] => $subtab_name ), 'admin.php' ) ) );
840 }
841 }
842 }
843