PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 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 All 205 releases
booking / includes / ui_settings / class-page-structure.php

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

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