Skip to content

Commit 58defd3

Browse files
committed
Update
1 parent 9fec6c5 commit 58defd3

3 files changed

Lines changed: 64 additions & 167 deletions

File tree

includes/options.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
class Options {
1010
public static function defaults() : array {
1111
return array(
12-
'example_text' => '',
13-
'enable_feature' => false,
14-
// Dark mode settings
1512
'enabled' => true,
1613
'default_mode' => 'system',
1714
'show_toggle' => true,

includes/rest.php

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ public function register_routes() : void {
3030
'callback' => array( $this, 'update_settings' ),
3131
'permission_callback' => array( Permissions::class, 'can_manage' ),
3232
'args' => array(
33-
'example_text' => array(
34-
'type' => 'string',
35-
),
36-
'enable_feature' => array(
37-
'type' => 'boolean',
38-
),
3933
'enabled' => array(
4034
'type' => 'boolean',
4135
),
@@ -57,7 +51,8 @@ public function register_routes() : void {
5751
'toggle_size' => array(
5852
'type' => 'string',
5953
'enum' => array( 'xs', 's', 'm', 'l', 'xl' ),
60-
), 'exclude_selectors' => array(
54+
),
55+
'exclude_selectors' => array(
6156
'type' => 'string',
6257
),
6358
'brightness' => array(
@@ -120,33 +115,12 @@ public function get_settings() : WP_REST_Response {
120115
}
121116

122117
public function update_settings( WP_REST_Request $request ) {
123-
$data = array(
124-
'example_text' => $request->get_param( 'example_text' ),
125-
'enable_feature' => $request->get_param( 'enable_feature' ),
126-
'enabled' => $request->get_param( 'enabled' ),
127-
'default_mode' => $request->get_param( 'default_mode' ),
128-
'show_toggle' => $request->get_param( 'show_toggle' ),
129-
'toggle_position' => $request->get_param( 'toggle_position' ),
130-
'toggle_style' => $request->get_param( 'toggle_style' ),
131-
'toggle_size' => $request->get_param( 'toggle_size' ),
132-
'exclude_selectors' => $request->get_param( 'exclude_selectors' ),
133-
'brightness' => $request->get_param( 'brightness' ),
134-
'contrast' => $request->get_param( 'contrast' ),
135-
'sepia' => $request->get_param( 'sepia' ),
136-
'grayscale' => $request->get_param( 'grayscale' ),
137-
'transition_enabled' => $request->get_param( 'transition_enabled' ),
138-
'transition_duration' => $request->get_param( 'transition_duration' ),
139-
'schedule_enabled' => $request->get_param( 'schedule_enabled' ),
140-
'schedule_start' => $request->get_param( 'schedule_start' ),
141-
'schedule_end' => $request->get_param( 'schedule_end' ),
142-
'keyboard_enabled' => $request->get_param( 'keyboard_enabled' ),
143-
'keyboard_shortcut' => $request->get_param( 'keyboard_shortcut' ),
144-
'image_brightness' => $request->get_param( 'image_brightness' ),
145-
'video_brightness' => $request->get_param( 'video_brightness' ),
146-
'background_brightness' => $request->get_param( 'background_brightness' ),
147-
'theme' => $request->get_param( 'theme' ),
148-
'custom_colors' => $request->get_param( 'custom_colors' ),
149-
);
118+
$defaults = Options::defaults();
119+
$data = array();
120+
121+
foreach ( array_keys( $defaults ) as $key ) {
122+
$data[ $key ] = $request->get_param( $key );
123+
}
150124

151125
$sanitized = Sanitize::options( $data );
152126
if ( is_wp_error( $sanitized ) ) {

includes/sanitize.php

Lines changed: 56 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -9,163 +9,89 @@
99
}
1010

1111
class Sanitize {
12+
1213
public static function options( array $values ) {
14+
$defaults = Options::defaults();
1315
$sanitized = array();
1416

15-
// Existing fields
16-
$sanitized['example_text'] = isset( $values['example_text'] ) ? sanitize_text_field( $values['example_text'] ) : '';
17-
$sanitized['enable_feature'] = isset( $values['enable_feature'] ) ? (bool) $values['enable_feature'] : false;
18-
19-
// Dark mode fields
20-
$sanitized['enabled'] = isset( $values['enabled'] ) ? (bool) $values['enabled'] : false;
21-
22-
$sanitized['default_mode'] = isset( $values['default_mode'] )
23-
&& in_array( $values['default_mode'], array( 'system', 'dark', 'light' ), true )
24-
? $values['default_mode']
25-
: 'system';
26-
27-
$sanitized['show_toggle'] = isset( $values['show_toggle'] ) ? (bool) $values['show_toggle'] : true;
28-
29-
$sanitized['toggle_position'] = isset( $values['toggle_position'] )
30-
&& in_array( $values['toggle_position'], array( 'bottom-right', 'bottom-left' ), true )
31-
? $values['toggle_position']
32-
: 'bottom-right';
33-
34-
35-
$sanitized['toggle_style'] = isset( $values['toggle_style'] )
36-
&& in_array( $values['toggle_style'], array( 'classic', 'pill', 'minimal' ), true )
37-
? $values['toggle_style']
38-
: 'classic';
17+
// Booleans
18+
foreach ( array( 'enabled', 'show_toggle', 'transition_enabled', 'schedule_enabled', 'keyboard_enabled' ) as $key ) {
19+
$sanitized[ $key ] = isset( $values[ $key ] ) ? (bool) $values[ $key ] : $defaults[ $key ];
20+
}
3921

40-
$sanitized['toggle_size'] = isset( $values['toggle_size'] )
41-
&& in_array( $values['toggle_size'], array( 'xs', 's', 'm', 'l', 'xl' ), true )
42-
? $values['toggle_size']
43-
: 'm';
44-
// Filter settings (relative values: -50 to +50 for brightness/contrast, 0-100 for sepia/grayscale)
45-
$sanitized['brightness'] = isset( $values['brightness'] )
46-
? max( -50, min( 50, (int) $values['brightness'] ) )
47-
: 0;
22+
// Enums
23+
$enums = array(
24+
'default_mode' => array( 'system', 'dark', 'light' ),
25+
'toggle_position' => array( 'bottom-right', 'bottom-left' ),
26+
'toggle_style' => array( 'classic', 'pill', 'minimal' ),
27+
'toggle_size' => array( 'xs', 's', 'm', 'l', 'xl' ),
28+
'theme' => array( 'classic', 'cool', 'warm', 'high-contrast', 'pure-black', 'custom' ),
29+
);
4830

49-
$sanitized['contrast'] = isset( $values['contrast'] )
50-
? max( -50, min( 50, (int) $values['contrast'] ) )
51-
: 0;
31+
foreach ( $enums as $key => $allowed ) {
32+
$sanitized[ $key ] = isset( $values[ $key ] ) && in_array( $values[ $key ], $allowed, true )
33+
? $values[ $key ]
34+
: $defaults[ $key ];
35+
}
5236

53-
$sanitized['sepia'] = isset( $values['sepia'] )
54-
? max( 0, min( 100, (int) $values['sepia'] ) )
55-
: 0;
37+
// Clamped integers
38+
$ranges = array(
39+
'brightness' => array( -50, 50 ),
40+
'contrast' => array( -50, 50 ),
41+
'sepia' => array( 0, 100 ),
42+
'grayscale' => array( 0, 100 ),
43+
'transition_duration' => array( 0, 1000 ),
44+
'image_brightness' => array( 50, 150 ),
45+
'video_brightness' => array( 50, 150 ),
46+
'background_brightness' => array( 50, 150 ),
47+
);
5648

57-
$sanitized['grayscale'] = isset( $values['grayscale'] )
58-
? max( 0, min( 100, (int) $values['grayscale'] ) )
59-
: 0;
49+
foreach ( $ranges as $key => $range ) {
50+
$sanitized[ $key ] = isset( $values[ $key ] )
51+
? max( $range[0], min( $range[1], (int) $values[ $key ] ) )
52+
: $defaults[ $key ];
53+
}
6054

61-
// Sanitize exclude_selectors with strict pattern
55+
// Exclude selectors (CSS whitelist pattern)
6256
$exclude = isset( $values['exclude_selectors'] ) ? trim( $values['exclude_selectors'] ) : '';
6357
if ( ! empty( $exclude ) ) {
64-
// Match frontend pattern: /^[a-zA-Z0-9#.\-_\s,:>\[\]\(\)="'~+*\\/]*$/
65-
if ( preg_match( '/^[a-zA-Z0-9#.\-_\s,:>\[\]\(\)="\'~+*\\/]*$/', $exclude ) ) {
66-
$sanitized['exclude_selectors'] = $exclude;
67-
} else {
58+
if ( ! preg_match( '/^[a-zA-Z0-9#.\-_\s,:>\[\]\(\)="\'~+*\\/]*$/', $exclude ) ) {
6859
return new WP_Error(
6960
'nightly_invalid_selectors',
7061
__( 'Invalid CSS selectors provided.', 'nightly' ),
7162
array( 'status' => 400 )
7263
);
7364
}
65+
$sanitized['exclude_selectors'] = $exclude;
7466
} else {
7567
$sanitized['exclude_selectors'] = '';
7668
}
7769

78-
// Transition settings
79-
$sanitized['transition_enabled'] = isset( $values['transition_enabled'] ) ? (bool) $values['transition_enabled'] : true;
80-
81-
$sanitized['transition_duration'] = isset( $values['transition_duration'] )
82-
? max( 0, min( 1000, (int) $values['transition_duration'] ) )
83-
: 300;
84-
85-
// Schedule settings
86-
$sanitized['schedule_enabled'] = isset( $values['schedule_enabled'] ) ? (bool) $values['schedule_enabled'] : false;
87-
88-
// Validate time format HH:MM
89-
$schedule_start = isset( $values['schedule_start'] ) ? trim( $values['schedule_start'] ) : '20:00';
90-
if ( preg_match( '/^([01][0-9]|2[0-3]):([0-5][0-9])$/', $schedule_start ) ) {
91-
$sanitized['schedule_start'] = $schedule_start;
92-
} else {
93-
$sanitized['schedule_start'] = '20:00';
94-
}
95-
96-
$schedule_end = isset( $values['schedule_end'] ) ? trim( $values['schedule_end'] ) : '06:00';
97-
if ( preg_match( '/^([01][0-9]|2[0-3]):([0-5][0-9])$/', $schedule_end ) ) {
98-
$sanitized['schedule_end'] = $schedule_end;
99-
} else {
100-
$sanitized['schedule_end'] = '06:00';
101-
}
102-
103-
// Keyboard shortcut settings
104-
$sanitized['keyboard_enabled'] = isset( $values['keyboard_enabled'] ) ? (bool) $values['keyboard_enabled'] : true;
105-
106-
// Validate keyboard shortcut format (e.g., "Ctrl+Shift+D", "Meta+K", "Alt+D")
107-
$keyboard_shortcut = isset( $values['keyboard_shortcut'] ) ? trim( $values['keyboard_shortcut'] ) : 'Ctrl+Shift+D';
108-
if ( preg_match( '/^(Ctrl|Meta|Cmd|Alt|Shift)(\+(Ctrl|Meta|Cmd|Alt|Shift))*\+[A-Za-z0-9]$/', $keyboard_shortcut ) ) {
109-
$sanitized['keyboard_shortcut'] = $keyboard_shortcut;
110-
} else {
111-
$sanitized['keyboard_shortcut'] = 'Ctrl+Shift+D';
70+
// Time fields (HH:MM format)
71+
$time_fields = array( 'schedule_start', 'schedule_end' );
72+
foreach ( $time_fields as $key ) {
73+
$time = isset( $values[ $key ] ) ? trim( $values[ $key ] ) : $defaults[ $key ];
74+
$sanitized[ $key ] = preg_match( '/^([01][0-9]|2[0-3]):[0-5][0-9]$/', $time )
75+
? $time
76+
: $defaults[ $key ];
11277
}
11378

114-
// Media brightness settings
115-
$sanitized['image_brightness'] = isset( $values['image_brightness'] )
116-
? max( 50, min( 150, (int) $values['image_brightness'] ) )
117-
: 100;
118-
119-
$sanitized['video_brightness'] = isset( $values['video_brightness'] )
120-
? max( 50, min( 150, (int) $values['video_brightness'] ) )
121-
: 100;
79+
// Keyboard shortcut (e.g., "Ctrl+Shift+D")
80+
$shortcut = isset( $values['keyboard_shortcut'] ) ? trim( $values['keyboard_shortcut'] ) : $defaults['keyboard_shortcut'];
81+
$sanitized['keyboard_shortcut'] = preg_match( '/^(Ctrl|Meta|Cmd|Alt|Shift)(\+(Ctrl|Meta|Cmd|Alt|Shift))*\+[A-Za-z0-9]$/', $shortcut )
82+
? $shortcut
83+
: $defaults['keyboard_shortcut'];
12284

123-
$sanitized['background_brightness'] = isset( $values['background_brightness'] )
124-
? max( 50, min( 150, (int) $values['background_brightness'] ) )
125-
: 100;
126-
127-
// Theme settings
128-
$sanitized['theme'] = isset( $values['theme'] )
129-
&& in_array( $values['theme'], array( 'classic', 'cool', 'warm', 'high-contrast', 'pure-black', 'custom' ), true )
130-
? $values['theme']
131-
: 'classic';
132-
133-
// Custom colors (only for custom theme)
85+
// Custom colors (hex values with fallback)
86+
$color_defaults = $defaults['custom_colors'];
13487
$custom_colors = isset( $values['custom_colors'] ) && is_array( $values['custom_colors'] )
13588
? $values['custom_colors']
13689
: array();
13790

138-
$sanitized['custom_colors'] = array(
139-
'bg_primary' => isset( $custom_colors['bg_primary'] ) ? sanitize_hex_color( $custom_colors['bg_primary'] ) : '#000000',
140-
'bg_secondary' => isset( $custom_colors['bg_secondary'] ) ? sanitize_hex_color( $custom_colors['bg_secondary'] ) : '#0a0a0a',
141-
'text_primary' => isset( $custom_colors['text_primary'] ) ? sanitize_hex_color( $custom_colors['text_primary'] ) : '#ffffff',
142-
'text_secondary' => isset( $custom_colors['text_secondary'] ) ? sanitize_hex_color( $custom_colors['text_secondary'] ) : '#a0a0a0',
143-
'border' => isset( $custom_colors['border'] ) ? sanitize_hex_color( $custom_colors['border'] ) : '#1a1a1a',
144-
'accent' => isset( $custom_colors['accent'] ) ? sanitize_hex_color( $custom_colors['accent'] ) : '#4a9eff',
145-
);
146-
147-
// Fallback to defaults if sanitize_hex_color returns null
148-
foreach ( $sanitized['custom_colors'] as $key => $color ) {
149-
if ( $color === null ) {
150-
$defaults = array(
151-
'bg_primary' => '#000000',
152-
'bg_secondary' => '#0a0a0a',
153-
'text_primary' => '#ffffff',
154-
'text_secondary' => '#a0a0a0',
155-
'border' => '#1a1a1a',
156-
'accent' => '#4a9eff',
157-
);
158-
$sanitized['custom_colors'][ $key ] = $defaults[ $key ];
159-
}
160-
}
161-
162-
// Existing validation
163-
if ( strlen( $sanitized['example_text'] ) > 200 ) {
164-
return new WP_Error(
165-
'nightly_invalid_text',
166-
__( 'Example text is too long.', 'nightly' ),
167-
array( 'status' => 400 )
168-
);
91+
$sanitized['custom_colors'] = array();
92+
foreach ( $color_defaults as $key => $default ) {
93+
$color = isset( $custom_colors[ $key ] ) ? sanitize_hex_color( $custom_colors[ $key ] ) : null;
94+
$sanitized['custom_colors'][ $key ] = $color ?? $default;
16995
}
17096

17197
return $sanitized;

0 commit comments

Comments
 (0)