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
← All changes | includes/ui_settings/class-page-structure.php +520 -124 10.1111.8.4 View file →
@@ -1,4 +1,4 @@
1 1 <?php
2 2 /**
3 3 * Page Structure in Admin Panel
4 4 *
@@ -16,15 +16,51 @@
16 16 if ( ! defined( 'ABSPATH' ) ) {
17 17 exit; // Exit, if accessed directly.
18 18 }
19 19
20 -// FixIn: 11.0.0.1.
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() { ... }
21 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 +
22 56 /**
23 57 * Define Settings Page Structure
24 58 */
25 59 abstract class WPBC_Page_Structure extends WPBC_Menu_Structure {
26 60
61 + // FixIn: 11.0.0.1.
62 +
27 63 /**
28 64 * Constructor
29 65 */
30 66 public function __construct() {
@@ -32,140 +68,61 @@
32 68 parent::__construct();
33 69
34 70 // This Hook fire in the class WPBC_Admin_Menus for showing page content of specific menu.
35 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' ) );
36 74 }
37 75
38 - // -----------------------------------------------------------------------------------------------------------------
39 - // Abstract Methods
40 - // -----------------------------------------------------------------------------------------------------------------
41 76
42 77 /**
43 - * Define slug in what menu to show this page. // Parameter relative: $_GET['page'].
78 + * Set the wpbc_admin class to body.
44 79 *
45 - * @return string
80 + * @param bool $classes Body classes.
46 81 *
47 - * Example:
48 - *
49 - * return 'wpbc-settings';
82 + * @return array
50 83 */
51 - abstract public function in_page();
84 + public function wpbc_add_admin_body_class( $classes ) {
52 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 +
53 100 /**
54 - * Define Tabs and Subtabs of this Admin Page
101 + * Child classes ovveride it for auto update / save options in main form
55 102 *
56 - * @return array();
57 - *
58 - * Example:
59 - *
60 - * $tabs = array();
61 - * $tabs[ 'form' ] = array(
62 - * 'title' => __('Form','booking') // Title of TAB
63 - * , 'hint' => __('Customization of Form Fields', 'booking') // Hint
64 - * , 'page_title' =>ucwords( __('Form fields', 'booking') ) // Title of Page
65 - * //, 'link' => '' // Can be skiped, then generated link based on Page and Tab tags. Or can be extenral link
66 - * //, 'position' => '' // 'left' || 'right' || ''
67 - * //, 'css_classes' => '' // CSS class(es)
68 - * //, 'icon' => '' // Icon - link to the real PNG img
69 - * , 'font_icon' => 'wpbc_icn_draw' // CSS definition of forn Icon
70 - * , 'default' => false // Is this tab activated by default or not: true || false.
71 - * , 'disabled' => false // Is this tab disbaled: true || false.
72 - * , 'hided' => false // Is this tab hided: true || false.
73 - * , 'subtabs' => array()
74 - *
75 - * );
76 - * $tabs[ 'upgrade' ] = array(
77 - * 'title' => __('Upgrade','booking') // Title of TAB
78 - * , 'hint' => __('Upgrade to higher version', 'booking') // Hint
79 - * //, 'page_title' => __('Upgrade', 'booking') // Title of Page
80 - * , 'link' => 'http://server.com/' // Can be skiped, then generated link based on Page and Tab tags. Or can be extenral link
81 - * , 'position' => 'right' // 'left' || 'right' || ''
82 - * //, 'css_classes' => '' // CSS class(es)
83 - * //, 'icon' => '' // Icon - link to the real PNG img
84 - * , 'font_icon' => 'wpbc_icn_auto_graph'// CSS definition of forn Icon
85 - * //, 'default' => false // Is this tab activated by default or not: true || false.
86 - * //, 'subtabs' => array()
87 - *
88 - * );
89 - *
90 - * $subtabs = array();
91 - *
92 - * $subtabs['fields'] = array(
93 - * 'type' => 'subtab' // Required| Possible values: 'subtab' | 'separator' | 'button' | 'goto-link' | 'html'
94 - * , 'title' => __('Form','booking') // Title of TAB
95 - * , 'page_title' => __('Form Settings', 'booking') // Title of Page
96 - * , 'hint' => __('Customization of Form Settings', 'booking') // Hint
97 - * , 'link' => '' // link
98 - * , 'position' => '' // 'left' || 'right' || ''
99 - * , 'css_classes' => '' // CSS class(es)
100 - * //, 'icon' => 'https://www.paypalobjects.com/webstatic/icon/pp258.png' // Icon - link to the real PNG img
101 - * //, 'font_icon' => 'wpbc_icn_payment' // CSS definition of Font Icon
102 - * , 'default' => true // Is this sub tab activated by default or not: true || false.
103 - * , 'disabled' => false // Is this sub tab deactivated: true || false.
104 - * , 'checkbox' => false // or definition array for specific checkbox: array( 'checked' => true, 'name' => 'feature1_active_status' )
105 - * , 'content' => 'content' // Function to load as conten of this TAB
106 - * );
107 - *
108 - * $subtabs['form-separator'] = array(
109 - * 'type' => 'separator' // Required| Possible values: 'subtab' | 'separator' | 'button' | 'goto-link' | 'html'
110 - * );
111 - * $subtabs['form-goto'] = array(
112 - * 'type' => 'goto-link' // Required| Possible values: 'subtab' | 'separator' | 'button' | 'goto-link' | 'html'
113 - * , 'title' =>ucwords( __('Form fields', 'booking') ) // Title of TAB
114 - * , 'hint' => '' // Hint
115 - * , 'show_section' => 'id_of_show_section' // ID of HTML element, for scroll to.
116 - * );
117 - *
118 - * ob_start();
119 - * ...
120 - * $html_element_data = ob_get_clean();
121 - *
122 - * $subtabs['form-selection'] = array(
123 - * 'type' => 'html' // Required| Possible values: 'subtab' | 'separator' | 'button' | 'goto-link' | 'html'
124 - * , 'html' => $html_element_data
125 - * );
126 - *
127 - * $subtabs['form-save'] = array(
128 - * 'type' => 'button' // Required| Possible values: 'subtab' | 'separator' | 'button' | 'goto-link' | 'html'
129 - * , 'title' => __('Save Changes','booking') // Title of TAB
130 - * , 'form' => 'wpbc_form' // Required for 'button'! Name of Form to submit
131 - * );
132 - *
133 - * $tabs[ 'form' ][ 'subtabs' ] = $subtabs;
134 - *
135 - * return $tabs;
103 + * @return void
136 104 */
137 - abstract public function tabs();
105 + public function maybe_update() {}
138 106
107 +
139 108 /**
140 - * Show Content of this page - Main function.
109 + * Child classes ovveride -- show vertical "Right Sidebar Content".
110 + * // FixIn: 10.14.1.3.
141 111 *
142 - * In top of this function have to be checking ubout Update (saving POST request).
143 - *
144 - * Exmaple:
145 - *
146 - * // S u b m i t ///////////////////////////////////////////////////////
147 - *
148 - * $this_submit_form = 'wpbc_emails_toolbar'; // Define form name
149 - *
150 - * // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
151 - * if ( isset( $_POST['is_form_sbmitted_'. $this_submit_form ] ) ) {
152 - *
153 - * // Check N o n c e
154 - * check_admin_referer( 'wpbc_settings_page_' . $this_submit_form ); // Its stop show anything on submiting, if its not refear to the original page
155 - *
156 - * // Make Update of settings
157 - * $edit_field_data = $this->update_wpbc_emails_toolbar( $menu_slug );
158 - * }
112 + * @return void
159 113 */
160 - abstract public function content();
114 + public function right_sidebar_content(){}
161 115
116 +
117 +
162 118 /**
163 - * Child classes ovveride it for auto update / save options in main form
119 + * Child classes ovveride -- show vertical "Right Sidebar Content - Compact".
120 + * // FixIn: 10.14.1.3.
164 121 *
165 122 * @return void
166 123 */
167 - public function maybe_update() {}
124 + public function right_sidebar_compact_content(){}
168 125
169 126
170 127 // -----------------------------------------------------------------------------------------------------------------
171 128 // C O N T E N T
@@ -312,18 +269,18 @@
312 269 // Page and SubTab clicked !
313 270 if ( $active_page_subtab === $nav_subtab_tag ) {
314 271 self::$nav_tabs[ $nav_page_tag ][ $nav_tab_tag ]['subtabs'][ $nav_subtab_tag ]['is_active'] = true;
315 272 }
316 - }
317 - }
318 - }
319 - }
320 - }
321 - return true;
322 - }
323 -
324 - /**
325 - * Get current active TAB 'Tag'
273 + }
274 + }
275 + }
276 + }
277 + }
278 + return true;
279 + }
280 +
281 + /**
282 + * Get current active TAB 'Tag'
326 283 *
327 284 * @return mixed|string
328 285 */
329 286 protected function get_active__tab__tag() {
@@ -413,8 +370,447 @@
413 370 return $is_use_option;
414 371 }
415 372
416 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 + /**
417 813 * Get Navigation path for header, if applicable.
418 814 * Used in Setup Wizard page.
419 815 *
420 816 * @return false|array
@@ -442,5 +838,5 @@
442 838 } else {
443 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' ) ) );
444 840 }
445 841 }
446 -}
842 +}