Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.83% covered (success)
97.83%
45 / 46
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Tabs
97.83% covered (success)
97.83%
45 / 46
80.00% covered (warning)
80.00%
4 / 5
14
0.00% covered (danger)
0.00%
0 / 1
 init
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 register_sections
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
 get_visible_tabs
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 get_active_tab
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
5.12
 get_active_page_and_group
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2/**
3 * BeyondWords settings tabs: slugs, settings groups and section IDs per tab.
4 *
5 * Field registration lives in `Fields` and `Preselect`.
6 *
7 * @package BeyondWords\Settings
8 *
9 * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
10 */
11
12declare( strict_types = 1 );
13
14namespace BeyondWords\Settings;
15
16defined( 'ABSPATH' ) || exit;
17
18/**
19 * Settings tabs.
20 *
21 * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
22 */
23class Tabs {
24
25    const TAB_AUTHENTICATION = 'authentication';
26    const TAB_INTEGRATION    = 'integration';
27    const TAB_PREFERENCES    = 'preferences';
28
29    const PAGE_AUTHENTICATION = 'beyondwords_authentication';
30    const PAGE_INTEGRATION    = 'beyondwords_integration';
31    const PAGE_PREFERENCES    = 'beyondwords_preferences';
32
33    const SETTINGS_GROUP_AUTHENTICATION = 'beyondwords_authentication_settings';
34    const SETTINGS_GROUP_INTEGRATION    = 'beyondwords_integration_settings';
35    const SETTINGS_GROUP_PREFERENCES    = 'beyondwords_preferences_settings';
36
37    const SECTION_AUTHENTICATION = 'authentication';
38    const SECTION_INTEGRATION    = 'integration';
39    const SECTION_PREFERENCES    = 'preferences';
40
41    /**
42     * Register WordPress hooks.
43     */
44    public static function init(): void {
45        add_action( 'admin_init', [ self::class, 'register_sections' ] );
46    }
47
48    /**
49     * Register a settings section per tab.
50     */
51    public static function register_sections(): void {
52        add_settings_section(
53            self::SECTION_AUTHENTICATION,
54            '',
55            '__return_false',
56            self::PAGE_AUTHENTICATION
57        );
58
59        add_settings_section(
60            self::SECTION_INTEGRATION,
61            '',
62            '__return_false',
63            self::PAGE_INTEGRATION
64        );
65
66        add_settings_section(
67            self::SECTION_PREFERENCES,
68            '',
69            '__return_false',
70            self::PAGE_PREFERENCES
71        );
72    }
73
74    /**
75     * Tabs visible on the settings page.
76     *
77     * Until valid API credentials are present we only show Authentication —
78     * the other tabs need an API connection to be useful.
79     *
80     * @return array<string,string> Map of tab slug to display label.
81     */
82    public static function get_visible_tabs(): array {
83        $tabs = [
84            self::TAB_AUTHENTICATION => __( 'Authentication', 'speechkit' ),
85            self::TAB_INTEGRATION    => __( 'Integration', 'speechkit' ),
86            self::TAB_PREFERENCES    => __( 'Preferences', 'speechkit' ),
87        ];
88
89        if ( ! Utils::has_valid_api_connection() ) {
90            return [ self::TAB_AUTHENTICATION => $tabs[ self::TAB_AUTHENTICATION ] ];
91        }
92
93        return $tabs;
94    }
95
96    /**
97     * Resolve the active tab slug from `$_GET`, falling back to the first.
98     */
99    public static function get_active_tab(): string {
100        $tabs = self::get_visible_tabs();
101
102        if ( empty( $tabs ) ) {
103            return '';
104        }
105
106        $default = (string) array_key_first( $tabs );
107
108        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
109        $requested = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
110
111        return ( '' !== $requested && array_key_exists( $requested, $tabs ) ) ? $requested : $default;
112    }
113
114    /**
115     * Resolve the page slug + settings group for the active tab.
116     *
117     * @return array{page:string,group:string}
118     */
119    public static function get_active_page_and_group(): array {
120        switch ( self::get_active_tab() ) {
121            case self::TAB_INTEGRATION:
122                return [
123                    'page'  => self::PAGE_INTEGRATION,
124                    'group' => self::SETTINGS_GROUP_INTEGRATION,
125                ];
126            case self::TAB_PREFERENCES:
127                return [
128                    'page'  => self::PAGE_PREFERENCES,
129                    'group' => self::SETTINGS_GROUP_PREFERENCES,
130                ];
131            case self::TAB_AUTHENTICATION:
132            default:
133                return [
134                    'page'  => self::PAGE_AUTHENTICATION,
135                    'group' => self::SETTINGS_GROUP_AUTHENTICATION,
136                ];
137        }
138    }
139}