PluginProbe
Code Snippets / 3.6.3
Code Snippets v3.6.3
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.6.3, at php/settings/settings.php

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