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

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