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

545 lines 12.5 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 * @version 1.0.0
7 * @author Eric Daams
8 * @copyright Copyright (c) 2015, Studio 164a
9 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
13
14 if ( ! class_exists( 'Charitable_Settings' ) ) :
15
16 /**
17 * Charitable_Settings
18 *
19 * @final
20 * @since 1.0.0
21 */
22 final class Charitable_Settings {
23
24 /**
25 * The single instance of this class.
26 *
27 * @var Charitable_Settings|null
28 * @access private
29 * @static
30 */
31 private static $instance = null;
32
33 /**
34 * Current field. Used to access field args from the views.
35 *
36 * @var array
37 * @access private
38 */
39 private $current_field;
40
41 /**
42 * Create object instance.
43 *
44 * @access private
45 * @since 1.0.0
46 */
47 private function __construct() {
48 do_action( 'charitable_admin_settings_start', $this );
49 }
50
51 /**
52 * Returns and/or create the single instance of this class.
53 *
54 * @return Charitable_Settings
55 * @access public
56 * @since 1.2.0
57 */
58 public static function get_instance() {
59 if ( is_null( self::$instance ) ) {
60 self::$instance = new Charitable_Settings();
61 }
62
63 return self::$instance;
64 }
65
66 /**
67 * Return the array of tabs used on the settings page.
68 *
69 * @return string[]
70 * @access public
71 * @since 1.0.0
72 */
73 public function get_sections() {
74
75 return apply_filters( 'charitable_settings_tabs', array(
76 'general' => __( 'General', 'charitable' ),
77 'gateways' => __( 'Payment Gateways', 'charitable' ),
78 'emails' => __( 'Emails', 'charitable' ),
79 'advanced' => __( 'Advanced', 'charitable' ),
80 ) );
81
82 }
83
84 /**
85 * Optionally add the extensions tab.
86 *
87 * @param string[] $tabs
88 * @return string[]
89 * @access public
90 * @since 1.3.0
91 */
92 public function maybe_add_extensions_tab( $tabs ) {
93 $actual_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'general';
94
95 /* Set the tab to 'extensions' */
96 $_GET['tab'] = 'extensions';
97
98 $settings = apply_filters( 'charitable_settings_tab_fields_extensions', array() );
99
100 /* Set the tab back to whatever it actually is */
101 $_GET['tab'] = $actual_tab;
102
103 if ( ! empty( $settings ) ) {
104 $tabs = charitable_add_settings_tab(
105 $tabs,
106 'extensions',
107 __( 'Extensions', 'charitable' ),
108 array(
109 'index' => 3,
110 )
111 );
112 }
113
114 return $tabs;
115 }
116
117 /**
118 * Display notices.
119 *
120 * @return void
121 * @access public
122 * @since 1.4.6
123 */
124 public function add_notices() {
125 $messages = get_transient( 'charitable_settings_updated' );
126
127 if ( ! $messages ) {
128 return;
129 }
130
131 $helper = charitable_get_admin_notices();
132
133 foreach ( $messages as $notice ) {
134 $helper->render_notice( $notice['message'], $notice['type'], $notice['dismissible'] );
135 }
136
137 delete_transient( 'charitable_settings_updated' );
138 }
139
140 /**
141 * Register setting.
142 *
143 * @return void
144 * @access public
145 * @since 1.0.0
146 */
147 public function register_settings() {
148 if ( ! charitable_is_settings_view() ) {
149 return;
150 }
151
152 register_setting( 'charitable_settings', 'charitable_settings', array( $this, 'sanitize_settings' ) );
153
154 $fields = $this->get_fields();
155
156 if ( empty( $fields ) ) {
157 return;
158 }
159
160 $sections = array_merge( $this->get_sections(), $this->get_dynamic_groups() );
161
162 /* Register each section */
163 foreach ( $sections as $section_key => $section ) {
164 $section_id = 'charitable_settings_' . $section_key;
165
166 add_settings_section(
167 $section_id,
168 __return_null(),
169 '__return_false',
170 $section_id
171 );
172
173 if ( ! isset( $fields[ $section_key ] ) || empty( $fields[ $section_key ] ) ) {
174 continue;
175 }
176
177 /* Sort by priority */
178 $section_fields = $fields[ $section_key ];
179 uasort( $section_fields, 'charitable_priority_sort' );
180
181 /* Add the individual fields within the section */
182 foreach ( $section_fields as $key => $field ) {
183
184 $this->register_field( $field, array( $section_key, $key ) );
185
186 }
187 }
188 }
189
190 /**
191 * Sanitize submitted settings before saving to the database.
192 *
193 * @param array $values
194 * @return string
195 * @access public
196 * @since 1.0.0
197 */
198 public function sanitize_settings( $values ) {
199 $old_values = get_option( 'charitable_settings', array() );
200 $new_values = array();
201
202 if ( ! is_array( $values ) ) {
203 $values = array();
204 }
205
206 /* Loop through all fields, merging the submitted values into the master array */
207 foreach ( $values as $section => $submitted ) {
208 $new_values = array_merge( $new_values, $this->get_section_submitted_values( $section, $submitted ) );
209 }
210
211 $values = wp_parse_args( $new_values, $old_values );
212 $values = apply_filters( 'charitable_save_settings', $values, $new_values, $old_values );
213
214 /* Save the update messages to a transient. */
215 set_transient( 'charitable_settings_updated', $this->get_update_messages(), 30 );
216
217 return $values;
218 }
219
220 /**
221 * Checkbox settings should always be either 1 or 0.
222 *
223 * @param mixed $value
224 * @param array $field
225 * @return boolean
226 * @access public
227 * @since 1.0.0
228 */
229 public function sanitize_checkbox_value( $value, $field ) {
230 if ( isset( $field['type'] ) && 'checkbox' == $field['type'] ) {
231 $value = intval( $value && 'on' == $value );
232 }
233
234 return $value;
235 }
236
237 /**
238 * Render field. This is the default callback used for all fields, unless an alternative callback has been specified.
239 *
240 * @param array $args
241 * @return void
242 * @access public
243 * @since 1.0.0
244 */
245 public function render_field( $args ) {
246 $field_type = isset( $args['type'] ) ? $args['type'] : 'text';
247
248 charitable_admin_view( 'settings/' . $field_type, $args );
249 }
250
251
252 /**
253 * Returns an array of all pages in the id=>title format.
254 *
255 * @return string[]
256 * @access public
257 * @since 1.0.0
258 */
259 public function get_pages() {
260 $pages = wp_cache_get( 'filtered_static_pages', 'charitable' );
261
262 if ( false === $pages ) {
263
264 $all_pages = get_pages();
265
266 if ( ! $all_pages ) {
267 $all_pages = array();
268 }
269
270 $pages = array();
271
272 foreach ( $all_pages as $page ) {
273
274 $pages[ $page->ID ] = $page->post_title;
275
276 }
277
278 wp_cache_set( 'filtered_static_pages', $pages, 'charitable' );
279 }
280
281 return $pages;
282 }
283
284 /**
285 * Return the update messages.
286 *
287 * @return string[]
288 * @access public
289 * @since 1.4.6
290 */
291 public function get_update_messages() {
292 if ( empty( $this->messages ) ) {
293 $this->add_update_message( __( 'Settings saved', 'charitable' ), 'success' );
294 }
295
296 return $this->messages;
297 }
298
299 /**
300 * Add an update message.
301 *
302 * @param string $message
303 * @param string $type
304 * @param boolean $dismissible
305 * @return string[]
306 * @access public
307 * @since 1.4.6
308 */
309 public function add_update_message( $message, $type = 'error', $dismissible = true ) {
310 if ( ! in_array( $type, array( 'error', 'success', 'warning', 'info' ) ) ) {
311 $type = 'error';
312 }
313
314 $this->messages[] = array(
315 'message' => $message,
316 'type' => $type,
317 'dismissible' => $dismissible,
318 );
319 }
320
321 /**
322 * Recursively add settings fields, given an array.
323 *
324 * @param array $fields
325 * @param string $section_key
326 * @return void
327 * @access private
328 * @since 1.0.0
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 * @param array $field
363 * @param string $key
364 * @return string
365 * @access private
366 * @since 1.0.0
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 * @param array $field
386 * @return string
387 * @access private
388 * @since 1.0.0
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 $classes = apply_filters( 'charitable_settings_field_classes', $classes, $field );
398
399 return implode( ' ', $classes );
400 }
401
402 /**
403 * Return an array with all the fields & sections to be displayed.
404 *
405 * @uses charitable_settings_fields
406 * @see Charitable_Settings::register_setting()
407 * @return array
408 * @access private
409 * @since 1.0.0
410 */
411 private function get_fields() {
412 /**
413 * Use the charitable_settings_tab_fields to include the fields for new tabs.
414 * DO NOT use it to add individual fields. That should be done with the
415 * filters within each of the methods.
416 */
417 $fields = array();
418
419 foreach ( $this->get_sections() as $section_key => $section ) {
420 $fields[ $section_key ] = apply_filters( 'charitable_settings_tab_fields_' . $section_key, array() );
421 }
422
423 return apply_filters( 'charitable_settings_tab_fields', $fields );
424 }
425
426 /**
427 * Get the submitted value for a particular setting.
428 *
429 * @param string $key
430 * @param array $field
431 * @param array $submitted
432 * @return mixed|null Returns null if the value was not submitted or is not applicable.
433 * @access private
434 * @since 1.0.0
435 */
436 private function get_setting_submitted_value( $key, $field, $submitted ) {
437 $value = null;
438
439 if ( isset( $field['save'] ) && ! $field['save'] ) {
440 return $value;
441 }
442
443 $field_type = isset( $field['type'] ) ? $field['type'] : '';
444
445 switch ( $field_type ) {
446 case '' :
447 case 'heading' :
448 return $value;
449 break;
450
451 case 'checkbox' :
452 $value = isset( $submitted[ $key ] );
453 break;
454
455 case 'multi-checkbox' :
456 $value = isset( $submitted[ $key ] ) ? $submitted[ $key ] : array();
457 break;
458
459 default :
460 $value = $submitted[ $key ];
461 }
462
463 return apply_filters( 'charitable_sanitize_value', $value, $field, $submitted, $key );
464 }
465
466 /**
467 * Return the submitted values for the given section.
468 *
469 * @param string $section
470 * @param array $submitted
471 * @return array
472 * @access private
473 * @since 1.0.0
474 */
475 private function get_section_submitted_values( $section, $submitted ) {
476 $values = array();
477 $form_fields = $this->get_fields();
478
479 if ( ! isset( $form_fields[ $section ] ) ) {
480 return $values;
481 }
482
483 foreach ( $form_fields[ $section ] as $key => $field ) {
484
485 $value = $this->get_setting_submitted_value( $key, $field, $submitted );
486
487 if ( is_null( $value ) ) {
488 continue;
489 }
490
491 if ( $this->is_dynamic_group( $section ) ) {
492 $values[ $section ][ $key ] = $value;
493 continue;
494 }
495
496 $values[ $key ] = $value;
497 }
498
499 return $values;
500 }
501
502 /**
503 * Return list of dynamic groups.
504 *
505 * @return string[]
506 * @access private
507 * @since 1.0.0
508 */
509 private function get_dynamic_groups() {
510 return apply_filters( 'charitable_dynamic_groups', array() );
511 }
512
513 /**
514 * Returns a composite key, given a section and submitted values.
515 *
516 * @param string $section
517 * @param array $submitted
518 * @return string
519 * @access private
520 * @since 1.0.0
521 */
522 private function get_composite_key( $section, $submitted ) {
523 if ( ! is_array( current( $submitted ) ) ) {
524 return false;
525 }
526
527 return sprintf( '%s_%s', $section, key( $submitted ) );
528 }
529
530 /**
531 * Returns whether the given key indicates the start of a new section of the settings.
532 *
533 * @param string $section
534 * @param array $submitted
535 * @return boolean
536 * @access private
537 * @since 1.0.0
538 */
539 private function is_dynamic_group( $composite_key ) {
540 return array_key_exists( $composite_key, $this->get_dynamic_groups() );
541 }
542 }
543
544 endif; // End class_exists check
545