PluginProbe
Code Snippets / 3.7.0
Code Snippets v3.7.0
3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 3.0.1 All 64 releases
code-snippets / php / settings / settings.php

settings.php in Code Snippets 3.7.0, at php/settings/settings.php

337 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This file registers the settings
4 *
5 * @package Code_Snippets
6 * @subpackage Settings
7 */
8
9 namespace Code_Snippets\Settings;
10
11 use Code_Snippets\Welcome_API;
12 use function Code_Snippets\clean_snippets_cache;
13 use function Code_Snippets\code_snippets;
14
15 const CACHE_KEY = 'code_snippets_settings';
16 const OPTION_GROUP = 'code-snippets';
17 const OPTION_NAME = 'code_snippets_settings';
18
19 /**
20 * Add a new option for either the current site or the current network
21 *
22 * @param bool $network Whether to add a network-wide option.
23 * @param string $option Name of option to add. Expected to not be SQL-escaped.
24 * @param mixed $value Option value, can be anything. Expected to not be SQL-escaped.
25 *
26 * @return bool False if the option was not added. True if the option was added.
27 */
28 function add_self_option( bool $network, string $option, $value ): bool {
29 return $network ? add_site_option( $option, $value ) : add_option( $option, $value );
30 }
31
32 /**
33 * Retrieves an option value based on an option name from either the current site or the current network
34 *
35 * @param bool $network Whether to get a network-wide option.
36 * @param string $option Name of option to retrieve. Expected to not be SQL-escaped.
37 * @param mixed $default_value Optional value to return if option doesn't exist. Default false.
38 *
39 * @return mixed Value set for the option.
40 */
41 function get_self_option( bool $network, string $option, $default_value = false ) {
42 return $network ? get_site_option( $option, $default_value ) : get_option( $option, $default_value );
43 }
44
45 /**
46 * Update the value of an option that was already added on the current site or the current network
47 *
48 * @param bool $network Whether to update a network-wide option.
49 * @param string $option Name of option. Expected to not be SQL-escaped.
50 * @param mixed $value Option value. Expected to not be SQL-escaped.
51 *
52 * @return bool False if value was not updated. True if value was updated.
53 */
54 function update_self_option( bool $network, string $option, $value ): bool {
55 return $network ? update_site_option( $option, $value ) : update_option( $option, $value );
56 }
57
58 /**
59 * Returns 'true' if plugin settings are unified on a multisite installation
60 * under the Network Admin settings menu
61 *
62 * This option is controlled by the "Enable administration menus" setting on the Network Settings menu
63 *
64 * @return bool
65 */
66 function are_settings_unified(): bool {
67 if ( ! is_multisite() ) {
68 return false;
69 }
70
71 $menu_perms = get_site_option( 'menu_items', array() );
72 return empty( $menu_perms['snippets_settings'] );
73 }
74
75 /**
76 * Retrieve the setting values from the database.
77 * If a setting does not exist in the database, the default value will be returned.
78 *
79 * @return array<string, array<string, mixed>>
80 */
81 function get_settings_values(): array {
82 $settings = wp_cache_get( CACHE_KEY );
83 if ( $settings ) {
84 return $settings;
85 }
86
87 $settings = get_default_settings();
88 $saved = get_self_option( are_settings_unified(), OPTION_NAME, array() );
89
90 foreach ( $settings as $section => $fields ) {
91 if ( isset( $saved[ $section ] ) ) {
92 $settings[ $section ] = array_replace( $fields, $saved[ $section ] );
93 }
94 }
95
96 wp_cache_set( CACHE_KEY, $settings );
97 return $settings;
98 }
99
100 /**
101 * Retrieve an individual setting field value
102 *
103 * @param string $section ID of the section the setting belongs to.
104 * @param string $field ID of the setting field.
105 *
106 * @return mixed
107 */
108 function get_setting( string $section, string $field ) {
109 $settings = get_settings_values();
110
111 return $settings[ $section ][ $field ] ?? null;
112 }
113
114 /**
115 * Update a single setting to a new value.
116 *
117 * @param string $section ID of the section the setting belongs to.
118 * @param string $field ID of the setting field.
119 * @param mixed $new_value Setting value. Expected to not be SQL-escaped.
120 *
121 * @return bool False if value was not updated. True if value was updated.
122 */
123 function update_setting( string $section, string $field, $new_value ): bool {
124 $settings = get_settings_values();
125
126 $settings[ $section ][ $field ] = $new_value;
127
128 wp_cache_set( CACHE_KEY, $settings );
129 return update_self_option( are_settings_unified(), OPTION_NAME, $settings );
130 }
131
132 /**
133 * Retrieve the settings sections
134 *
135 * @return array<string, string> Settings sections.
136 */
137 function get_settings_sections(): array {
138 $sections = array(
139 'general' => __( 'General', 'code-snippets' ),
140 'editor' => __( 'Code Editor', 'code-snippets' ),
141 'debug' => __( 'Debug', 'code-snippets' ),
142 );
143
144 return apply_filters( 'code_snippets_settings_sections', $sections );
145 }
146
147 /**
148 * Register settings sections, fields, etc
149 */
150 function register_plugin_settings() {
151 if ( are_settings_unified() ) {
152 if ( ! get_site_option( OPTION_NAME ) ) {
153 add_site_option( OPTION_NAME, get_default_settings() );
154 }
155 } elseif ( ! get_option( OPTION_NAME ) ) {
156 add_option( OPTION_NAME, get_default_settings() );
157 }
158
159 // Register the setting.
160 register_setting(
161 OPTION_GROUP,
162 OPTION_NAME,
163 [ 'sanitize_callback' => __NAMESPACE__ . '\\sanitize_settings' ]
164 );
165
166 // Register settings sections.
167 foreach ( get_settings_sections() as $section_id => $section_name ) {
168 add_settings_section( $section_id, $section_name, '__return_empty_string', 'code-snippets' );
169 }
170
171 // Register settings fields.
172 foreach ( get_settings_fields() as $section_id => $fields ) {
173 foreach ( $fields as $field_id => $field ) {
174 $field_object = new Setting_Field( $section_id, $field_id, $field );
175 add_settings_field( $field_id, $field['name'], [ $field_object, 'render' ], 'code-snippets', $section_id );
176 }
177 }
178
179 // Add editor preview as a field.
180 add_settings_field(
181 'editor_preview',
182 __( 'Editor Preview', 'code-snippets' ),
183 __NAMESPACE__ . '\\render_editor_preview',
184 'code-snippets',
185 'editor'
186 );
187 }
188
189 add_action( 'admin_init', __NAMESPACE__ . '\\register_plugin_settings' );
190
191 /**
192 * Sanitize a single setting value.
193 *
194 * @param array<string, mixed> $field Setting field information.
195 * @param mixed $input_value User input setting value, or null if missing.
196 *
197 * @return mixed Sanitized setting value, or null if unset.
198 */
199 function sanitize_setting_value( array $field, $input_value ) {
200 switch ( $field['type'] ) {
201
202 case 'checkbox':
203 return 'on' === $input_value;
204
205 case 'number':
206 return intval( $input_value );
207
208 case 'select':
209 $select_options = array_map( 'strval', array_keys( $field['options'] ) );
210 return in_array( strval( $input_value ), $select_options, true ) ? $input_value : null;
211
212 case 'checkboxes':
213 $results = [];
214
215 if ( ! empty( $input_value ) ) {
216 foreach ( $field['options'] as $option_id => $option_label ) {
217 if ( isset( $input_value[ $option_id ] ) && 'on' === $input_value[ $option_id ] ) {
218 $results[] = $option_id;
219 }
220 }
221 }
222
223 return $results;
224
225 case 'text':
226 case 'hidden':
227 return trim( sanitize_text_field( $input_value ) );
228
229 case 'callback':
230 return isset( $field['sanitize_callback'] ) && is_callable( $field['sanitize_callback'] ) ?
231 call_user_func( $field['sanitize_callback'], $input_value ) :
232 null;
233
234 default:
235 return null;
236 }
237 }
238
239 /**
240 * Process settings actions.
241 *
242 * @param array $input Provided settings input.
243 *
244 * @return array|null New $input value to return, or null to continue with settings update process.
245 */
246 function process_settings_actions( array $input ): ?array {
247
248 if ( isset( $input['reset_settings'] ) ) {
249 add_settings_error(
250 OPTION_NAME,
251 'settings_reset',
252 __( 'All settings have been reset to their defaults.', 'code-snippets' ),
253 'updated'
254 );
255
256 delete_option( 'code_snippets_cloud_settings' );
257 return [];
258 }
259
260 if ( isset( $input['debug']['database_update'] ) ) {
261 code_snippets()->db->create_or_upgrade_tables();
262
263 add_settings_error(
264 OPTION_NAME,
265 'database_update_done',
266 __( 'Successfully performed database table upgrade.', 'code-snippets' ),
267 'updated'
268 );
269 }
270
271 if ( isset( $input['debug']['reset_caches'] ) ) {
272 Welcome_API::clear_cache();
273 clean_snippets_cache( code_snippets()->db->get_table_name( false ) );
274
275 if ( is_multisite() ) {
276 clean_snippets_cache( code_snippets()->db->get_table_name( true ) );
277 }
278
279 add_settings_error(
280 OPTION_NAME,
281 'snippet_caches_reset',
282 __( 'Successfully reset snippets caches.', 'code-snippets' ),
283 'updated'
284 );
285 }
286
287 return null;
288 }
289
290 /**
291 * Validate the settings
292 *
293 * @param array<string, array<string, mixed>> $input The received settings.
294 *
295 * @return array<string, array<string, mixed>> The validated settings.
296 */
297 function sanitize_settings( array $input ): array {
298 wp_cache_delete( CACHE_KEY );
299 $result = process_settings_actions( $input );
300
301 if ( ! is_null( $result ) ) {
302 return $result;
303 }
304
305 $settings = get_settings_values();
306 $updated = false;
307
308 // Don't directly loop through $input as it does not include as deselected checkboxes.
309 foreach ( get_settings_fields() as $section_id => $fields ) {
310 foreach ( $fields as $field_id => $field ) {
311
312 // Fetch the corresponding input value from the posted data.
313 $input_value = $input[ $section_id ][ $field_id ] ?? null;
314
315 // Attempt to sanitize the setting value.
316 $sanitized_value = sanitize_setting_value( $field, $input_value );
317
318 if ( ! is_null( $sanitized_value ) && $settings[ $section_id ][ $field_id ] !== $sanitized_value ) {
319 $settings[ $section_id ][ $field_id ] = $sanitized_value;
320 $updated = true;
321 }
322 }
323 }
324
325 // Add an updated message.
326 if ( $updated ) {
327 add_settings_error(
328 OPTION_NAME,
329 'settings-saved',
330 __( 'Settings saved.', 'code-snippets' ),
331 'updated'
332 );
333 }
334
335 return $settings;
336 }
337