PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.6.7
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.6.7
1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 1.8.0 All 210 releases
charitable / includes / admin / settings / class-charitable-settings.php

class-charitable-settings.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.6.7, at includes/admin/settings/class-charitable-settings.php

609 lines 14.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Charitable Settings UI.
4 *
5 * @package Charitable/Classes/Charitable_Settings
6 * @author Eric Daams
7 * @copyright Copyright (c) 2018, Studio 164a
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.0.0
10 * @version 1.0.0
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Settings' ) ) :
19
20 /**
21 * Charitable_Settings
22 *
23 * @final
24 * @since 1.0.0
25 */
26 final class Charitable_Settings {
27
28 /**
29 * The single instance of this class.
30 *
31 * @var Charitable_Settings|null
32 */
33 private static $instance = null;
34
35 /**
36 * Dynamic groups.
37 *
38 * @since 1.5.7
39 *
40 * @var array
41 */
42 private $dynamic_groups;
43
44 /**
45 * List of static pages, used in some settings.
46 *
47 * @since 1.5.9
48 *
49 * @var array
50 */
51 private $pages;
52
53 /**
54 * Create object instance.
55 *
56 * @since 1.0.0
57 */
58 private function __construct() {
59 do_action( 'charitable_admin_settings_start', $this );
60 }
61
62 /**
63 * Returns and/or create the single instance of this class.
64 *
65 * @since 1.2.0
66 *
67 * @return Charitable_Settings
68 */
69 public static function get_instance() {
70 if ( is_null( self::$instance ) ) {
71 self::$instance = new self();
72 }
73
74 return self::$instance;
75 }
76
77 /**
78 * Return the array of tabs used on the settings page.
79 *
80 * @since 1.0.0
81 *
82 * @return string[]
83 */
84 public function get_sections() {
85 /**
86 * Filter the settings tabs.
87 *
88 * @since 1.0.0
89 *
90 * @param string[] $tabs List of tabs in key=>label format.
91 */
92 return apply_filters( 'charitable_settings_tabs', array(
93 'general' => __( 'General', 'charitable' ),
94 'gateways' => __( 'Payment Gateways', 'charitable' ),
95 'emails' => __( 'Emails', 'charitable' ),
96 'privacy' => __( 'Privacy', 'charitable' ),
97 'advanced' => __( 'Advanced', 'charitable' ),
98 ) );
99
100 }
101
102 /**
103 * Optionally add the extensions tab.
104 *
105 * @since 1.3.0
106 *
107 * @param string[] $tabs The existing set of tabs.
108 * @return string[]
109 */
110 public function maybe_add_extensions_tab( $tabs ) {
111 $actual_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'general';
112
113 /* Set the tab to 'extensions' */
114 $_GET['tab'] = 'extensions';
115
116 /**
117 * Filter the settings in the extensions tab.
118 *
119 * @since 1.3.0
120 *
121 * @param array $fields Array of fields. Empty by default.
122 */
123 $settings = apply_filters( 'charitable_settings_tab_fields_extensions', array() );
124
125 /* Set the tab back to whatever it actually is */
126 $_GET['tab'] = $actual_tab;
127
128 if ( ! empty( $settings ) ) {
129 $tabs = charitable_add_settings_tab(
130 $tabs,
131 'extensions',
132 __( 'Extensions', 'charitable' ),
133 array(
134 'index' => 4,
135 )
136 );
137 }
138
139 return $tabs;
140 }
141
142 /**
143 * Add the hidden "extensions" section field.
144 *
145 * @since 1.6.7
146 *
147 * @param array $fields All the settings fields.
148 * @return array
149 */
150 public function add_hidden_extensions_setting_field( $fields ) {
151 if ( ! array_key_exists( 'extensions', $fields ) ) {
152 return $fields;
153 }
154
155 $fields['extensions']['section'] = array(
156 'title' => '',
157 'type' => 'hidden',
158 'priority' => 10000,
159 'value' => 'extensions',
160 'save' => false,
161 );
162
163 return $fields;
164 }
165
166 /**
167 * Register setting.
168 *
169 * @since 1.0.0
170 *
171 * @return void
172 */
173 public function register_settings() {
174 if ( ! charitable_is_settings_view() ) {
175 return;
176 }
177
178 register_setting( 'charitable_settings', 'charitable_settings', array( $this, 'sanitize_settings' ) );
179
180 $fields = $this->get_fields();
181
182 if ( empty( $fields ) ) {
183 return;
184 }
185
186 $sections = array_merge( $this->get_sections(), $this->get_dynamic_groups() );
187
188 /* Register each section */
189 foreach ( $sections as $section_key => $section ) {
190 $section_id = 'charitable_settings_' . $section_key;
191
192 add_settings_section(
193 $section_id,
194 __return_null(),
195 '__return_false',
196 $section_id
197 );
198
199 if ( ! isset( $fields[ $section_key ] ) || empty( $fields[ $section_key ] ) ) {
200 continue;
201 }
202
203 /* Sort by priority */
204 $section_fields = $fields[ $section_key ];
205 uasort( $section_fields, 'charitable_priority_sort' );
206
207 /* Add the individual fields within the section */
208 foreach ( $section_fields as $key => $field ) {
209 $this->register_field( $field, array( $section_key, $key ) );
210 }
211 }
212 }
213
214 /**
215 * Sanitize submitted settings before saving to the database.
216 *
217 * @since 1.0.0
218 *
219 * @param array $values The submitted values.
220 * @return string
221 */
222 public function sanitize_settings( $values ) {
223 $old_values = get_option( 'charitable_settings', array() );
224 $new_values = array();
225
226 if ( ! is_array( $old_values ) ) {
227 $old_values = array();
228 }
229
230 if ( ! is_array( $values ) ) {
231 $values = array();
232 }
233
234 /* Loop through all fields, merging the submitted values into the master array */
235 foreach ( $values as $section => $submitted ) {
236 $new_values = array_merge( $new_values, $this->get_section_submitted_values( $section, $submitted ) );
237 }
238
239 $values = wp_parse_args( $new_values, $old_values );
240
241 /**
242 * Filter sanitized settings.
243 *
244 * @since 1.0.0
245 *
246 * @param array $values All values, merged.
247 * @param array $new_values Newly submitted values.
248 * @param array $old_values Old settings.
249 */
250 $values = apply_filters( 'charitable_save_settings', $values, $new_values, $old_values );
251
252 $this->add_update_message( __( 'Settings saved', 'charitable' ), 'success' );
253
254 return $values;
255 }
256
257 /**
258 * Checkbox settings should always be either 1 or 0.
259 *
260 * @since 1.0.0
261 *
262 * @param mixed $value Submitted value for field.
263 * @param array $field Field definition.
264 * @return int
265 */
266 public function sanitize_checkbox_value( $value, $field ) {
267 if ( isset( $field['type'] ) && 'checkbox' == $field['type'] ) {
268 $value = intval( $value && 'on' == $value );
269 }
270
271 return $value;
272 }
273
274 /**
275 * Render field. This is the default callback used for all fields, unless an alternative callback has been specified.
276 *
277 * @since 1.0.0
278 *
279 * @param array $args Field definition.
280 * @return void
281 */
282 public function render_field( $args ) {
283 $field_type = isset( $args['type'] ) ? $args['type'] : 'text';
284
285 charitable_admin_view( 'settings/' . $field_type, $args );
286 }
287
288 /**
289 * Returns an array of all pages in the id=>title format.
290 *
291 * @since 1.0.0
292 *
293 * @return string[]
294 */
295 public function get_pages() {
296 if ( ! isset( $this->pages ) ) {
297 $this->pages = charitable_get_pages_options();
298 }
299
300 return $this->pages;
301 }
302
303 /**
304 * Add an update message.
305 *
306 * @since 1.4.6
307 *
308 * @param string $message The message text.
309 * @param string $type The type of message. Options: 'error', 'success', 'warning', 'info'.
310 * @param boolean $dismissible Whether the message can be dismissed.
311 * @return void
312 */
313 public function add_update_message( $message, $type = 'error', $dismissible = true ) {
314 if ( ! in_array( $type, array( 'error', 'success', 'warning', 'info' ) ) ) {
315 $type = 'error';
316 }
317
318 charitable_get_admin_notices()->add_notice( $message, $type, false, $dismissible );
319 }
320
321 /**
322 * Recursively add settings fields, given an array.
323 *
324 * @since 1.0.0
325 *
326 * @param array $field The setting field.
327 * @param array $keys Array containing the section key and field key.
328 * @return void
329 */
330 private function register_field( $field, $keys ) {
331 $section_id = 'charitable_settings_' . $keys[0];
332
333 if ( isset( $field['render'] ) && ! $field['render'] ) {
334 return;
335 }
336
337 /* Drop the first key, which is the section identifier */
338 $field['name'] = implode( '][', $keys );
339
340 if ( ! $this->is_dynamic_group( $keys[0] ) ) {
341 array_shift( $keys );
342 }
343
344 $field['key'] = $keys;
345 $field['classes'] = $this->get_field_classes( $field );
346 $callback = isset( $field['callback'] ) ? $field['callback'] : array( $this, 'render_field' );
347 $label = $this->get_field_label( $field, end( $keys ) );
348
349 add_settings_field(
350 sprintf( 'charitable_settings_%s', implode( '_', $keys ) ),
351 $label,
352 $callback,
353 $section_id,
354 $section_id,
355 $field
356 );
357 }
358
359 /**
360 * Return the label for the given field.
361 *
362 * @since 1.0.0
363 *
364 * @param array $field The field definition.
365 * @param string $key The field key.
366 * @return string
367 */
368 private function get_field_label( $field, $key ) {
369 $label = '';
370
371 if ( isset( $field['label_for'] ) ) {
372 $label = $field['label_for'];
373 }
374
375 if ( isset( $field['title'] ) ) {
376 $label = $field['title'];
377 }
378
379 return $label;
380 }
381
382 /**
383 * Return a space separated string of classes for the given field.
384 *
385 * @since 1.0.0
386 *
387 * @param array $field Field definition.
388 * @return string
389 */
390 private function get_field_classes( $field ) {
391 $classes = array( 'charitable-settings-field' );
392
393 if ( isset( $field['class'] ) ) {
394 $classes[] = $field['class'];
395 }
396
397 /**
398 * Filter the list of classes to apply to settings fields.
399 *
400 * @since 1.0.0
401 *
402 * @param array $classes The list of classes.
403 * @param array $field The field definition.
404 */
405 $classes = apply_filters( 'charitable_settings_field_classes', $classes, $field );
406
407 return implode( ' ', $classes );
408 }
409
410 /**
411 * Return an array with all the fields & sections to be displayed.
412 *
413 * @uses charitable_settings_fields
414 * @see Charitable_Settings::register_setting()
415 * @since 1.0.0
416 *
417 * @return array
418 */
419 private function get_fields() {
420 /**
421 * Use the charitable_settings_tab_fields to include the fields for new tabs.
422 * DO NOT use it to add individual fields. That should be done with the
423 * filters within each of the methods.
424 */
425 $fields = array();
426
427 foreach ( $this->get_sections() as $section_key => $section ) {
428 /**
429 * Filter the array of fields to display in a particular tab.
430 *
431 * @since 1.0.0
432 *
433 * @param array $fields Array of fields.
434 */
435 $fields[ $section_key ] = apply_filters( 'charitable_settings_tab_fields_' . $section_key, array() );
436 }
437
438 /**
439 * Filter the array of settings fields.
440 *
441 * @since 1.0.0
442 *
443 * @param array $fields Array of fields.
444 */
445 return apply_filters( 'charitable_settings_tab_fields', $fields );
446 }
447
448 /**
449 * Get the submitted value for a particular setting.
450 *
451 * @since 1.0.0
452 *
453 * @param string $key The key of the setting being saved.
454 * @param array $field The setting field.
455 * @param array $submitted The submitted values.
456 * @param string $section The section being saved.
457 * @return mixed|null Returns null if the value was not submitted or is not applicable.
458 */
459 private function get_setting_submitted_value( $key, $field, $submitted, $section ) {
460 $value = null;
461
462 if ( isset( $field['save'] ) && ! $field['save'] ) {
463 return $value;
464 }
465
466 $field_type = isset( $field['type'] ) ? $field['type'] : '';
467
468 switch ( $field_type ) {
469
470 case 'checkbox':
471 $value = intval( array_key_exists( $key, $submitted ) && 'on' == $submitted[ $key ] );
472 break;
473
474 case 'multi-checkbox':
475 $value = isset( $submitted[ $key ] ) ? $submitted[ $key ] : array();
476 break;
477
478 case '':
479 case 'heading':
480 return $value;
481
482 default:
483 if ( ! array_key_exists( $key, $submitted ) ) {
484 return $value;
485 }
486
487 $value = $submitted[ $key ];
488
489 }//end switch
490
491 /**
492 * General way to sanitize values. If you only need to sanitize a
493 * specific setting, used the filter below instead.
494 *
495 * @since 1.0.0
496 *
497 * @param mixed $value The current setting value.
498 * @param array $field The field configuration.
499 * @param array $submitted All submitted data.
500 * @param string $key The setting key.
501 * @param string $section The section being saved.
502 */
503 $value = apply_filters( 'charitable_sanitize_value', $value, $field, $submitted, $key, $section );
504
505 /**
506 * Sanitize the setting value.
507 *
508 * The filter hook is formatted like this: charitable_sanitize_value_{$section}_{$key}.
509 *
510 * @since 1.5.0
511 *
512 * @param mixed $value The current setting value.
513 * @param array $field The field configuration.
514 * @param array $submitted All submitted data.
515 */
516 return apply_filters( 'charitable_sanitize_value_' . $section . '_' . $key, $value, $field, $submitted );
517 }
518
519 /**
520 * Return the submitted values for the given section.
521 *
522 * @since 1.0.0
523 *
524 * @param string $section The section being edited.
525 * @param array $submitted The submitted values.
526 * @return array
527 */
528 private function get_section_submitted_values( $section, $submitted ) {
529 $values = array();
530 $form_fields = $this->get_fields();
531
532 if ( ! isset( $form_fields[ $section ] ) ) {
533 return $values;
534 }
535
536 foreach ( $form_fields[ $section ] as $key => $field ) {
537 $value = $this->get_setting_submitted_value( $key, $field, $submitted, $section );
538
539 if ( is_null( $value ) ) {
540 continue;
541 }
542
543 if ( $this->is_dynamic_group( $section ) ) {
544 $values[ $section ][ $key ] = $value;
545 continue;
546 }
547
548 $values[ $key ] = $value;
549 }
550
551 return $values;
552 }
553
554 /**
555 * Return list of dynamic groups.
556 *
557 * @since 1.0.0
558 *
559 * @return string[]
560 */
561 private function get_dynamic_groups() {
562 if ( ! isset( $this->dynamic_groups ) ) {
563 /**
564 * Filter the list of dynamic groups.
565 *
566 * @since 1.0.0
567 *
568 * @param array $groups The dynamic groups.
569 */
570 $this->dynamic_groups = apply_filters( 'charitable_dynamic_groups', array() );
571 }
572
573 return $this->dynamic_groups;
574 }
575
576 /**
577 * Returns whether the given key indicates the start of a new section of the settings.
578 *
579 * @since 1.0.0
580 *
581 * @param string $composite_key The unique key for this group.
582 * @return boolean
583 */
584 private function is_dynamic_group( $composite_key ) {
585 return array_key_exists( $composite_key, $this->get_dynamic_groups() );
586 }
587
588 /* DEPRECATED FUNCTIONS */
589
590 /**
591 * Get the update messages.
592 *
593 * @deprecated 1.7.0
594 *
595 * @since 1.4.13 Deprecated.
596 */
597 public function get_update_messages() {
598 charitable_get_deprecated()->deprecated_function(
599 __METHOD__,
600 '1.4.13',
601 'Charitable_Admin_Notices::get_notices()'
602 );
603
604 return charitable_get_admin_notices()->get_notices();
605 }
606 }
607
608 endif;
609