Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 84
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
FontSettings
0.00% covered (danger)
0.00%
0 / 84
0.00% covered (danger)
0.00%
0 / 6
380
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 register_settings
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
2
 initialize_settings
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 sanitize_settings
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 maybe_refresh_with_capabilities
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
90
 is_cloudflare_fonts_enabled
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace NewfoldLabs\WP\Module\Performance\Fonts;
4
5/**
6 * Manages the registration and sanitization of font optimization settings.
7 */
8class FontSettings {
9
10    /**
11     * The setting key for font optimization.
12     */
13    private const SETTING_KEY = 'nfd_fonts_optimization';
14
15    /**
16     * The default setting.
17     *
18     * @var array
19     */
20    private $default_settings = array(
21        'cloudflare' => array(
22            'fonts'        => array(
23                'value'    => false,
24                'user_set' => false,
25            ),
26            'last_updated' => 0,
27        ),
28    );
29
30    /**
31     * Constructor to initialize defaults and register setting.
32     *
33     * @param \NewfoldLabs\WP\Container\Container|null $container Optional DI container.
34     */
35    public function __construct( $container = null ) {
36        if ( $container && $container->has( 'capabilities' ) ) {
37            $capabilities = $container->get( 'capabilities' );
38            $this->default_settings['cloudflare']['fonts']['value'] = (bool) $capabilities->get( 'hasCloudflareFonts' );
39        }
40
41        $this->default_settings['cloudflare']['last_updated'] = time();
42
43        $this->register_settings();
44        $this->initialize_settings();
45    }
46
47    /**
48     * Registers the `nfd_fonts_optimization` setting.
49     */
50    private function register_settings() {
51        register_setting(
52            'general',
53            self::SETTING_KEY,
54            array(
55                'type'              => 'object',
56                'description'       => __( 'Settings for NFD Font Optimization.', 'wp-module-performance' ),
57                'sanitize_callback' => array( $this, 'sanitize_settings' ),
58                'default'           => $this->default_settings,
59                'show_in_rest'      => array(
60                    'schema' => array(
61                        'type'                 => 'object',
62                        'properties'           => array(
63                            'cloudflare' => array(
64                                'type'        => 'object',
65                                'description' => __( 'Cloudflare-related font optimization settings.', 'wp-module-performance' ),
66                                'properties'  => array(
67                                    'fonts'        => array(
68                                        'type'        => 'object',
69                                        'description' => __( 'Enable Cloudflare Font Optimization.', 'wp-module-performance' ),
70                                        'properties'  => array(
71                                            'value'    => array(
72                                                'type'    => 'boolean',
73                                                'default' => $this->default_settings['cloudflare']['fonts']['value'],
74                                            ),
75                                            'user_set' => array(
76                                                'type'    => 'boolean',
77                                                'default' => $this->default_settings['cloudflare']['fonts']['user_set'],
78                                            ),
79                                        ),
80                                    ),
81                                    'last_updated' => array(
82                                        'type'        => 'integer',
83                                        'description' => __( 'Timestamp of last update.', 'wp-module-performance' ),
84                                        'default'     => $this->default_settings['cloudflare']['last_updated'],
85                                    ),
86                                ),
87                            ),
88                        ),
89                        'additionalProperties' => false,
90                    ),
91                ),
92            )
93        );
94    }
95
96    /**
97     * Initializes the setting if it doesn't exist.
98     */
99    private function initialize_settings() {
100        if ( get_option( self::SETTING_KEY, false ) === false ) {
101            add_option( self::SETTING_KEY, $this->default_settings );
102        }
103    }
104
105    /**
106     * Sanitizes the font optimization settings before saving.
107     *
108     * @param array $settings The input settings from the request.
109     * @return array Sanitized settings array with a timestamp.
110     */
111    public function sanitize_settings( $settings ) {
112        $existing = get_option( self::SETTING_KEY, array() );
113
114        $fonts_value    = isset( $settings['cloudflare']['fonts']['value'] )
115        ? ! empty( $settings['cloudflare']['fonts']['value'] )
116        : ( ! empty( $existing['cloudflare']['fonts']['value'] ) );
117        $fonts_user_set = isset( $settings['cloudflare']['fonts']['user_set'] )
118        ? ! empty( $settings['cloudflare']['fonts']['user_set'] )
119        : ( ! empty( $existing['cloudflare']['fonts']['user_set'] ) );
120
121        return array(
122            'cloudflare' => array(
123                'fonts'        => array(
124                    'value'    => $fonts_value,
125                    'user_set' => $fonts_user_set,
126                ),
127                'last_updated' => time(),
128            ),
129        );
130    }
131
132    /**
133     * Refreshes legacy font settings based on Cloudflare capabilities.
134     *
135     * @param object|null $capabilities Optional capabilities object.
136     */
137    public static function maybe_refresh_with_capabilities( $capabilities ) {
138        $settings = get_option( self::SETTING_KEY, array() );
139
140        if ( ! isset( $settings['cloudflare']['fonts'] ) ) {
141            $settings['cloudflare']['fonts'] = array(
142                'value'    => false,
143                'user_set' => false,
144            );
145        }
146
147        if ( is_array( $capabilities ) ) {
148            $has_fonts = isset( $capabilities['hasCloudflareFonts'] ) ? (bool) $capabilities['hasCloudflareFonts'] : false;
149
150            if ( $settings['cloudflare']['fonts']['user_set'] ) {
151                if ( $settings['cloudflare']['fonts']['value'] && ! $has_fonts ) {
152                    $settings['cloudflare']['fonts']['value'] = false;
153                }
154            } elseif ( ! $settings['cloudflare']['fonts']['value'] && $has_fonts ) {
155                $settings['cloudflare']['fonts']['value'] = true;
156            }
157        }
158
159        $settings['cloudflare']['last_updated'] = time();
160        update_option( self::SETTING_KEY, $settings );
161    }
162
163    /**
164     * Checks if Cloudflare font optimization is enabled.
165     *
166     * @return bool
167     */
168    public static function is_cloudflare_fonts_enabled() {
169        $settings = get_option( self::SETTING_KEY, array( 'cloudflare' => array( 'fonts' => array( 'value' => false ) ) ) );
170        return ! empty( $settings['cloudflare']['fonts']['value'] );
171    }
172}