PluginProbe ʕ •ᴥ•ʔ
Gallery : FooGallery / 3.2.6
Gallery : FooGallery v3.2.6
3.3.2 3.3.3 3.3.0 3.1.31 3.1.32 3.1.34 3.1.36 3.2.0 3.2.6 trunk 1.10.3 2.0.24 2.1.34 2.2.44 2.3.3 2.4.32 3.0.6 3.1.11 3.1.12 3.1.13 3.1.20 3.1.25 3.1.26 3.1.26.1 3.1.26.2
foogallery / includes / foopluginbase / classes / class-foo-plugin-settings.php
foogallery / includes / foopluginbase / classes Last commit date
class-foo-friendly-dates.php 4 weeks ago class-foo-plugin-base.php 4 weeks ago class-foo-plugin-file-locator.php 4 weeks ago class-foo-plugin-metabox-sanity.php 4 weeks ago class-foo-plugin-options.php 4 weeks ago class-foo-plugin-settings.php 4 weeks ago class-foo-plugin-textdomain.php 4 weeks ago index.php 4 weeks ago
class-foo-plugin-settings.php
510 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 /*
8 * Foo Plugin Settings
9 *
10 * A helpful class to handle settings for a plugin
11 *
12 * Version: 2.1
13 * Author: Brad Vincent
14 * Author URI: http://fooplugins.com
15 * License: GPL2
16 */
17
18 if ( !class_exists( 'Foo_Plugin_Settings_v2_2' ) ) {
19 class Foo_Plugin_Settings_v2_2 {
20
21 protected $plugin_slug;
22
23 protected $_settings = array(); //the plugin settings array
24 protected $_settings_sections = array(); //the plugin sections array
25 protected $_settings_tabs = array(); //the plugin tabs array
26 protected $_admin_errors = false; //store of admin errors
27
28 /**
29 * Constructor for the Foo_Plugin_Settings_v2_2 class
30 *
31 * @param string $plugin_slug The slug of the plugin.
32 */
33 public function __construct( $plugin_slug ) {
34 $this->plugin_slug = $plugin_slug;
35
36 $this->register_settings();
37 }
38
39 /**
40 * Get the tabs of the plugin settings
41 *
42 * @return array
43 */
44 public function get_tabs() {
45 return $this->_settings_tabs;
46 }
47
48 /**
49 * Check if there is any setting of a certain type
50 *
51 * @param string $type The type of setting to check.
52 * @return bool
53 */
54 public function has_setting_of_type( $type ) {
55 foreach ( $this->_settings as $setting ) {
56 if ( $setting['type'] == $type ) {
57 return true;
58 }
59 }
60
61 return false;
62 }
63
64 /**
65 * Check if a tab with a specific ID exists
66 *
67 * @param string $tab_id The ID of the tab to check.
68 * @return bool
69 */
70 public function has_tab( $tab_id ) {
71 return array_key_exists( $tab_id, $this->_settings_tabs );
72 }
73
74 /**
75 * Add a setting tab
76 *
77 * @param string $tab_id The ID of the tab.
78 * @param string $title The title of the tab.
79 */
80 function add_tab( $tab_id, $title ) {
81 if ( !$this->has_tab( $tab_id ) ) {
82
83 //pre action
84 do_action( $this->plugin_slug . '_admin_settings_before_tab', $tab_id, $title );
85
86 $tab = array(
87 'id' => $tab_id,
88 'title' => $title
89 );
90
91 $this->_settings_tabs[$tab_id] = $tab;
92
93 //post action
94 do_action( $this->plugin_slug . '_admin_settings_after_tab', $tab_id, $title );
95 }
96 }
97
98 /**
99 * Check if a section with a specific ID exists
100 *
101 * @param string $section_id The ID of the section.
102 * @return bool
103 */
104 function has_section( $section_id ) {
105 return array_key_exists( $section_id, $this->_settings_sections );
106 }
107
108 /**
109 * Add a setting section
110 *
111 * @param string $section_id The ID of the section.
112 * @param string $title The title of the section.
113 * @param string $desc The description of the section (default is an empty string).
114 */
115 function add_section( $section_id, $title, $desc = '' ) {
116
117 //check we have the section
118 if ( !$this->has_section( $section_id ) ) {
119
120 //pre action
121 do_action( $this->plugin_slug . '_admin_settings_before_section', $section_id, $title, $desc );
122
123 $section = array(
124 'id' => $section_id,
125 'title' => $title,
126 'desc' => $desc
127 );
128
129 $this->_settings_sections[$section_id] = $section;
130
131 add_settings_section( $section_id, $title, array( $this, 'echo_section_desc' ), $this->plugin_slug );
132
133 //post action
134 do_action( $this->plugin_slug . '_admin_settings_after_section', $section_id, $title, $desc );
135 }
136 }
137
138 /**
139 * Echo the description of a section
140 *
141 * @param array $arg An array of arguments passed to the callback.
142 */
143 function echo_section_desc( $arg ) {
144 $section = $this->_settings_sections[ $arg['id'] ];
145 echo wp_kses_post( $section['desc'] );
146 }
147
148 /**
149 * Add a section to a tab
150 *
151 * @param string $tab_id The ID of the tab.
152 * @param string $section_id The ID of the section.
153 * @param string $title The title of the section.
154 * @param string $desc The description of the section (default is an empty string).
155 * @return string The ID of the section.
156 */
157 function add_section_to_tab( $tab_id, $section_id, $title, $desc = '' ) {
158 if ( array_key_exists( $tab_id, $this->_settings_tabs ) ) {
159
160 //get the correct section id for the tab
161 $section_id = $tab_id . '-' . $section_id;
162
163 //add the section to the tab
164 if ( !array_key_exists( $section_id, $this->_settings_sections ) ) {
165 $this->_settings_tabs[$tab_id]['sections'][$section_id] = $section_id;
166 }
167
168 //add the section
169 $this->add_section( $section_id, $title, $desc );
170
171 }
172
173 return $section_id;
174 }
175
176 /**
177 * Add settings based on the provided configuration.
178 *
179 * @param array|bool $settings The settings configuration.
180 */
181 function add_settings( $settings = false ) {
182 if ( !is_array( $settings ) || ( !array_key_exists( 'settings', $settings ) ) ) return;
183
184 foreach( $settings['settings'] as $setting ) {
185 //add a tab if needed
186 $tab_id = foo_safe_get( $setting, 'tab', false );
187
188 if ( $tab_id !== false && !$this->has_tab( $tab_id ) && array_key_exists( 'tabs', $settings ) && array_key_exists( $tab_id, $settings['tabs'] ) ) {
189 $tab = $settings['tabs'][$tab_id];
190 $this->add_tab( $tab_id, $tab );
191 }
192
193 //add a section if needed
194 $section_id = foo_safe_get( $setting, 'section', false );
195 if ( $section_id !== false && !$this->has_section( $section_id ) && array_key_exists( 'sections', $settings ) && array_key_exists( $section_id, $settings['sections'] ) ) {
196 $section = $settings['sections'][$section_id];
197 $this->add_section_to_tab( $tab_id, $section_id, $section['name'] );
198 }
199
200 $this->add_setting( $setting );
201 }
202 }
203
204 /**
205 * Register settings for the plugin.
206 */
207 function register_settings() {
208 register_setting( $this->plugin_slug, $this->plugin_slug, array( 'sanitize_callback' => array( $this, 'validate' ) ) );
209 }
210
211 /**
212 * Add a settings field.
213 *
214 * @param array $args The arguments for the setting.
215 */
216 function add_setting( $args = array() ) {
217
218 $defaults = array(
219 'id' => 'default_field',
220 'title' => 'Default Field',
221 'desc' => '',
222 'default' => '',
223 'placeholder' => '',
224 'type' => 'text',
225 'section' => '',
226 'choices' => array(),
227 'class' => '',
228 'tab' => ''
229 );
230
231 //only declare up front so no debug warnings are shown
232 $title = $type = $id = $desc = $default = $placeholder = $choices = $class = $section = $tab = null;
233
234 extract( wp_parse_args( $args, $defaults ) );
235
236 $field_args = array(
237 'type' => $type,
238 'id' => $id,
239 'desc' => $desc,
240 'default' => $default,
241 'placeholder' => $placeholder,
242 'choices' => $choices,
243 'label_for' => $id,
244 'class' => $class
245 );
246
247 $this->_settings[] = $args;
248
249 $section_id = foo_convert_to_key( $section );
250
251 //check we have the tab
252 if ( !empty( $tab ) ) {
253 $tab_id = foo_convert_to_key( $tab );
254
255 //add the tab
256 $this->add_tab( $tab_id, foo_title_case( $tab ) );
257
258 //add the section
259 $section_id = $this->add_section_to_tab( $tab_id, $section_id, foo_title_case( $section ) );
260 } else {
261 //just add the section
262 $this->add_section( $section_id, foo_title_case( $section ) );
263 }
264
265 do_action( $this->plugin_slug . '_admin_settings_before_setting', $args );
266
267 //add the setting!
268 add_settings_field( $id, $title, array( $this, 'render' ), $this->plugin_slug, $section_id, $field_args );
269
270 do_action( $this->plugin_slug . '_admin_settings_after_setting', $args );
271 }
272
273 /**
274 * Render HTML for individual settings.
275 *
276 * @param array $args The arguments for rendering the setting.
277 */
278 function render( $args = array() ) {
279
280 //only declare up front so no debug warnings are shown
281 $type = $id = $desc = $default = $placeholder = $choices = $class = $section = $tab = null;
282
283 extract( $args );
284
285 $options = get_option( $this->plugin_slug );
286
287 $has_options = $options !== false;
288
289 if ( function_exists( 'is_multisite' ) && is_multisite() ) {
290 // If we are in the network settings, use site options directly.
291 if ( is_network_admin() ) {
292 $options = get_site_option( $this->plugin_slug );
293 } else {
294 $site_options = get_site_option( $this->plugin_slug );
295 $options = is_array( $options ) ? wp_parse_args( $options, $site_options ) : (array) $site_options;
296 }
297 } else {
298 $options = is_array( $options ) ? $options : array();
299 }
300
301 if ( $options === '' ) {
302 $options = array();
303 }
304
305 if ( !isset( $options[$id]) && $type != 'checkbox' ) {
306 $options[$id] = $default;
307 }
308
309 $field_class = '';
310 if ( $class != '' ) {
311 $field_class = ' class="' . $class . '"';
312 }
313
314 $errors = get_settings_errors( $id );
315
316 do_action( $this->plugin_slug . '_admin_settings_before_render_setting', $args );
317
318 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Form field generation with internal settings
319 switch ( $type ) {
320
321 case 'heading':
322 echo '</td></tr><tr valign="top"><td colspan="2">' . $desc;
323 break;
324
325 case 'html':
326 echo $desc;
327 break;
328
329 case 'checkbox':
330 $checked = '';
331 if ( isset( $options[$id] ) && $options[$id] == 'on' ) {
332 $checked = ' checked="checked"';
333 } else if ( $options === false && $default == 'on' ) {
334 $checked = ' checked="checked"';
335 } else if ( $has_options === false && $default == 'on' ) {
336 $checked = ' checked="checked"';
337 }
338
339 //echo '<input type="hidden" name="'.$this->plugin_slug.'[' . $id . '_default]" value="' . $default . '" />';
340 echo '<input' . $field_class . ' type="checkbox" id="' . $id . '" name="' . $this->plugin_slug . '[' . $id . ']" value="on"' . $checked . ' /> <label for="' . $id . '"><small>' . $desc . '</small></label>';
341
342 break;
343
344 case 'select':
345 echo '<select' . $field_class . ' name="' . $this->plugin_slug . '[' . $id . ']">';
346
347 foreach ( $choices as $value => $label ) {
348 $selected = '';
349 if ( $options[$id] == $value ) {
350 $selected = ' selected="selected"';
351 }
352 echo '<option ' . $selected . ' value="' . $value . '">' . $label . '</option>';
353 }
354
355 echo '</select>';
356
357 break;
358
359 case 'radio':
360 $i = 0;
361 $saved_value = $options[$id];
362 if ( empty( $saved_value ) ) {
363 $saved_value = $default;
364 }
365 foreach ( $choices as $value => $label ) {
366 $selected = '';
367 if ( $saved_value == $value ) {
368 $selected = ' checked="checked"';
369 }
370 echo '<input' . $field_class . $selected . ' type="radio" name="' . $this->plugin_slug . '[' . $id . ']" id="' . $id . $i . '" value="' . $value . '"> <label for="' . $id . $i . '">' . $label . '</label>';
371 if ( $i < count( $choices ) - 1 ) {
372 echo '<br />';
373 }
374 $i++;
375 }
376
377 break;
378
379 case 'textarea':
380 echo '<textarea' . $field_class . ' id="' . $id . '" name="' . $this->plugin_slug . '[' . $id . ']" placeholder="' . $placeholder . '">' . esc_textarea( $options[$id] ) . '</textarea>';
381
382 break;
383
384 case 'password':
385 echo '<input' . $field_class . ' type="password" id="' . $id . '" name="' . $this->plugin_slug . '[' . $id . ']" value="' . esc_attr( $options[$id] ) . '" />';
386
387 break;
388
389 case 'text':
390 echo '<input class="regular-text ' . esc_attr( $class ) . '" type="text" id="' . esc_attr( $id ) . '" name="' . esc_attr( $this->plugin_slug ) . '[' . esc_attr( $id ) . ']" placeholder="' . esc_attr( $placeholder ) . '" value="' . esc_attr( foogallery_sanitize_javascript( $options[$id], array() ) ) . '" />';
391
392 break;
393
394 case 'checkboxlist':
395 $i = 0;
396 foreach ( $choices as $value => $label ) {
397
398 $checked = '';
399 if ( isset( $options[$id][$value] ) && $options[$id][$value] == 'true' ) {
400 $checked = 'checked="checked"';
401 }
402
403 echo '<input' . $field_class . ' ' . $checked . ' type="checkbox" name="' . $this->plugin_slug . '[' . $id . '|' . $value . ']" id="' . $id . $i . '" value="on"> <label for="' . $id . $i . '">' . $label . '</label>';
404 if ( $i < count( $choices ) - 1 ) {
405 echo '<br />';
406 }
407 $i++;
408 }
409
410 break;
411 case 'image':
412 echo '<input class="regular-text image-upload-url" type="text" id="' . $id . '" name="' . $this->plugin_slug . '[' . $id . ']" placeholder="' . $placeholder . '" value="' . esc_attr( $options[$id] ) . '" />';
413 echo '<input data-uploader-title="' . __('Select An Image', $this->plugin_slug) . '" data-link="' . $id . '" class="image-upload-button" type="button" name="upload_button" value="' . __( 'Select Image', $this->plugin_slug ) . '" />';
414 break;
415
416 default:
417 do_action( $this->plugin_slug . '_admin_settings_custom_type_render_setting', $args );
418 break;
419 }
420
421 do_action( $this->plugin_slug . '_admin_settings_after_render_setting', $args );
422
423 if ( is_array( $errors ) ) {
424 foreach ( $errors as $error ) {
425 echo "<span class='error'>{$error['message']}</span>";
426 }
427 }
428
429 if ( $type != 'checkbox' && $type != 'heading' && $type != 'html' && $desc != '' ) {
430 echo '<br /><small>' . $desc . '</small>';
431 }
432 // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
433 }
434
435 /**
436 * Validate the input settings.
437 *
438 * @param array $input The input settings to validate.
439 *
440 * @return array The validated settings.
441 */
442 function validate( $input ) {
443
444 //check to see if the options were reset
445 if ( isset ( $input['reset-defaults']) ) {
446 delete_option( $this->plugin_slug );
447 add_settings_error(
448 'reset',
449 'reset_error',
450 __( 'Settings restored to default values', $this->plugin_slug ),
451 'updated'
452 );
453
454 return false;
455 }
456
457 if ( empty( $this->_settings ) ) {
458 $settings = apply_filters( $this->plugin_slug . '_admin_settings', false );
459 $this->add_settings( $settings );
460 }
461
462 foreach ( $this->_settings as $setting ) {
463 $this->validate_setting( $setting, $input );
464 }
465
466 return $input;
467 }
468
469 /**
470 * Validate a single setting.
471 *
472 * @param array $setting The setting configuration.
473 * @param array $input The input settings to validate.
474 */
475 function validate_setting( $setting, &$input ) {
476 //validate a single setting
477
478 if ( $setting['type'] == 'checkbox' ) {
479 if ( isset( $input[ $setting['id'] ] ) && 'off' === $input[ $setting['id'] ] ) {
480 // Keep normalized unchecked values stable if the option is sanitized again.
481 $input[ $setting['id'] ] = 'off';
482 } else if ( ! empty( $input[ $setting['id'] ] ) ) {
483 $input[ $setting['id'] ] = 'on';
484 } else if ( isset( $setting['default'] ) && 'on' === $setting['default'] ) {
485 $input[ $setting['id'] ] = 'off';
486 }
487 }
488
489 if ( $setting['type'] == 'checkboxlist' ) {
490
491 unset( $checkboxarray);
492
493 foreach ( $setting['choices'] as $value => $label ) {
494 if ( !empty( $input[$setting['id'] . '|' . $value]) ) {
495 // If it's not null, make sure it's true, add it to an array
496 $checkboxarray[$value] = 'true';
497 } else {
498 $checkboxarray[$value] = 'false';
499 }
500 }
501
502 if ( !empty( $checkboxarray) ) {
503 $input[$setting['id']] = $checkboxarray;
504 }
505
506 }
507 }
508 }
509 }
510