PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.6.22
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.6.22
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.22, at includes/admin/settings/class-charitable-settings.php

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