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

544 lines 12.6 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 return apply_filters( 'charitable_settings_tabs', array(
75 'general' => __( 'General', 'charitable' ),
76 'gateways' => __( 'Payment Gateways', 'charitable' ),
77 'emails' => __( 'Emails', 'charitable' ),
78 'licenses' => __( 'Licenses', 'charitable' ),
79 'advanced' => __( 'Advanced', 'charitable' ),
80 ) );
81 }
82
83 /**
84 * Optionally add the extensions tab.
85 *
86 * @param string[] $tabs
87 * @return string[]
88 * @access public
89 * @since 1.3.0
90 */
91 public function maybe_add_extensions_tab( $tabs ) {
92 $actual_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'general';
93
94 /* Set the tab to 'extensions' */
95 $_GET['tab'] = 'extensions';
96
97 $settings = apply_filters( 'charitable_settings_tab_fields_extensions', array() );
98
99 /* Set the tab back to whatever it actually is */
100 $_GET['tab'] = $actual_tab;
101
102 if ( ! empty( $settings ) ) {
103 $tabs = charitable_add_settings_tab(
104 $tabs,
105 'extensions',
106 __( 'Extensions', 'charitable' ),
107 array(
108 'index' => 3,
109 )
110 );
111 }
112
113 return $tabs;
114 }
115
116 /**
117 * Display notices.
118 *
119 * @return void
120 * @access public
121 * @since 1.4.6
122 */
123 public function add_notices() {
124 $messages = get_transient( 'charitable_settings_updated' );
125
126 if ( ! $messages ) {
127 return;
128 }
129
130 $helper = charitable_get_admin_notices();
131
132 foreach ( $messages as $notice ) {
133 $helper->render_notice( $notice['message'], $notice['type'], $notice['dismissible'] );
134 }
135
136 delete_transient( 'charitable_settings_updated' );
137 }
138
139 /**
140 * Register setting.
141 *
142 * @return void
143 * @access public
144 * @since 1.0.0
145 */
146 public function register_settings() {
147 if ( ! charitable_is_settings_view() ) {
148 return;
149 }
150
151 register_setting( 'charitable_settings', 'charitable_settings', array( $this, 'sanitize_settings' ) );
152
153 $fields = $this->get_fields();
154
155 if ( empty( $fields ) ) {
156 return;
157 }
158
159 $sections = array_merge( $this->get_sections(), $this->get_dynamic_groups() );
160
161 /* Register each section */
162 foreach ( $sections as $section_key => $section ) {
163 $section_id = 'charitable_settings_' . $section_key;
164
165 add_settings_section(
166 $section_id,
167 __return_null(),
168 '__return_false',
169 $section_id
170 );
171
172 if ( ! isset( $fields[ $section_key ] ) || empty( $fields[ $section_key ] ) ) {
173 continue;
174 }
175
176 /* Sort by priority */
177 $section_fields = $fields[ $section_key ];
178 uasort( $section_fields, 'charitable_priority_sort' );
179
180 /* Add the individual fields within the section */
181 foreach ( $section_fields as $key => $field ) {
182
183 $this->register_field( $field, array( $section_key, $key ) );
184
185 }
186 }
187 }
188
189 /**
190 * Sanitize submitted settings before saving to the database.
191 *
192 * @param array $values
193 * @return string
194 * @access public
195 * @since 1.0.0
196 */
197 public function sanitize_settings( $values ) {
198 $old_values = get_option( 'charitable_settings', array() );
199 $new_values = array();
200
201 if ( ! is_array( $values ) ) {
202 $values = array();
203 }
204
205 /* Loop through all fields, merging the submitted values into the master array */
206 foreach ( $values as $section => $submitted ) {
207 $new_values = array_merge( $new_values, $this->get_section_submitted_values( $section, $submitted ) );
208 }
209
210 $values = wp_parse_args( $new_values, $old_values );
211 $values = apply_filters( 'charitable_save_settings', $values, $new_values, $old_values );
212
213 /* Save the update messages to a transient. */
214 set_transient( 'charitable_settings_updated', $this->get_update_messages(), 30 );
215
216 return $values;
217 }
218
219 /**
220 * Checkbox settings should always be either 1 or 0.
221 *
222 * @param mixed $value
223 * @param array $field
224 * @return boolean
225 * @access public
226 * @since 1.0.0
227 */
228 public function sanitize_checkbox_value( $value, $field ) {
229 if ( isset( $field['type'] ) && 'checkbox' == $field['type'] ) {
230 $value = intval( $value && 'on' == $value );
231 }
232
233 return $value;
234 }
235
236 /**
237 * Render field. This is the default callback used for all fields, unless an alternative callback has been specified.
238 *
239 * @param array $args
240 * @return void
241 * @access public
242 * @since 1.0.0
243 */
244 public function render_field( $args ) {
245 $field_type = isset( $args['type'] ) ? $args['type'] : 'text';
246
247 charitable_admin_view( 'settings/' . $field_type, $args );
248 }
249
250
251 /**
252 * Returns an array of all pages in the id=>title format.
253 *
254 * @return string[]
255 * @access public
256 * @since 1.0.0
257 */
258 public function get_pages() {
259 $pages = wp_cache_get( 'filtered_static_pages', 'charitable' );
260
261 if ( false === $pages ) {
262
263 $all_pages = get_pages();
264
265 if ( ! $all_pages ) {
266 $all_pages = array();
267 }
268
269 $pages = array();
270
271 foreach ( $all_pages as $page ) {
272
273 $pages[ $page->ID ] = $page->post_title;
274
275 }
276
277 wp_cache_set( 'filtered_static_pages', $pages, 'charitable' );
278 }
279
280 return $pages;
281 }
282
283 /**
284 * Return the update messages.
285 *
286 * @return string[]
287 * @access public
288 * @since 1.4.6
289 */
290 public function get_update_messages() {
291 if ( empty( $this->messages ) ) {
292 $this->add_update_message( __( 'Settings saved', 'charitable' ), 'success' );
293 }
294
295 return $this->messages;
296 }
297
298 /**
299 * Add an update message.
300 *
301 * @param string $message
302 * @param string $type
303 * @param boolean $dismissible
304 * @return string[]
305 * @access public
306 * @since 1.4.6
307 */
308 public function add_update_message( $message, $type = 'error', $dismissible = true ) {
309 if ( ! in_array( $type, array( 'error', 'success', 'warning', 'info' ) ) ) {
310 $type = 'error';
311 }
312
313 $this->messages[] = array(
314 'message' => $message,
315 'type' => $type,
316 'dismissible' => $dismissible,
317 );
318 }
319
320 /**
321 * Recursively add settings fields, given an array.
322 *
323 * @param array $fields
324 * @param string $section_key
325 * @return void
326 * @access private
327 * @since 1.0.0
328 */
329 private function register_field( $field, $keys ) {
330 $section_id = 'charitable_settings_' . $keys[0];
331
332 if ( isset( $field['render'] ) && ! $field['render'] ) {
333 return;
334 }
335
336 /* Drop the first key, which is the section identifier */
337 $field['name'] = implode( '][', $keys );
338
339 if ( ! $this->is_dynamic_group( $keys[0] ) ) {
340 array_shift( $keys );
341 }
342
343 $field['key'] = $keys;
344 $field['classes'] = $this->get_field_classes( $field );
345 $callback = isset( $field['callback'] ) ? $field['callback'] : array( $this, 'render_field' );
346 $label = $this->get_field_label( $field, end( $keys ) );
347
348 add_settings_field(
349 sprintf( 'charitable_settings_%s', implode( '_', $keys ) ),
350 $label,
351 $callback,
352 $section_id,
353 $section_id,
354 $field
355 );
356 }
357
358 /**
359 * Return the label for the given field.
360 *
361 * @param array $field
362 * @param string $key
363 * @return string
364 * @access private
365 * @since 1.0.0
366 */
367 private function get_field_label( $field, $key ) {
368 $label = '';
369
370 if ( isset( $field['label_for'] ) ) {
371 $label = $field['label_for'];
372 }
373
374 if ( isset( $field['title'] ) ) {
375 $label = $field['title'];
376 }
377
378 return $label;
379 }
380
381 /**
382 * Return a space separated string of classes for the given field.
383 *
384 * @param array $field
385 * @return string
386 * @access private
387 * @since 1.0.0
388 */
389 private function get_field_classes( $field ) {
390 $classes = array( 'charitable-settings-field' );
391
392 if ( isset( $field['class'] ) ) {
393 $classes[] = $field['class'];
394 }
395
396 $classes = apply_filters( 'charitable_settings_field_classes', $classes, $field );
397
398 return implode( ' ', $classes );
399 }
400
401 /**
402 * Return an array with all the fields & sections to be displayed.
403 *
404 * @uses charitable_settings_fields
405 * @see Charitable_Settings::register_setting()
406 * @return array
407 * @access private
408 * @since 1.0.0
409 */
410 private function get_fields() {
411 /**
412 * Use the charitable_settings_tab_fields to include the fields for new tabs.
413 * DO NOT use it to add individual fields. That should be done with the
414 * filters within each of the methods.
415 */
416 $fields = array();
417
418 foreach ( $this->get_sections() as $section_key => $section ) {
419 $fields[ $section_key ] = apply_filters( 'charitable_settings_tab_fields_' . $section_key, array() );
420 }
421
422 return apply_filters( 'charitable_settings_tab_fields', $fields );
423 }
424
425 /**
426 * Get the submitted value for a particular setting.
427 *
428 * @param string $key
429 * @param array $field
430 * @param array $submitted
431 * @return mixed|null Returns null if the value was not submitted or is not applicable.
432 * @access private
433 * @since 1.0.0
434 */
435 private function get_setting_submitted_value( $key, $field, $submitted ) {
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 case '' :
446 case 'heading' :
447 return $value;
448 break;
449
450 case 'checkbox' :
451 $value = isset( $submitted[ $key ] );
452 break;
453
454 case 'multi-checkbox' :
455 $value = isset( $submitted[ $key ] ) ? $submitted[ $key ] : array();
456 break;
457
458 default :
459 $value = $submitted[ $key ];
460 }
461
462 return apply_filters( 'charitable_sanitize_value', $value, $field, $submitted, $key );
463 }
464
465 /**
466 * Return the submitted values for the given section.
467 *
468 * @param string $section
469 * @param array $submitted
470 * @return array
471 * @access private
472 * @since 1.0.0
473 */
474 private function get_section_submitted_values( $section, $submitted ) {
475 $values = array();
476 $form_fields = $this->get_fields();
477
478 if ( ! isset( $form_fields[ $section ] ) ) {
479 return $values;
480 }
481
482 foreach ( $form_fields[ $section ] as $key => $field ) {
483
484 $value = $this->get_setting_submitted_value( $key, $field, $submitted );
485
486 if ( is_null( $value ) ) {
487 continue;
488 }
489
490 if ( $this->is_dynamic_group( $section ) ) {
491 $values[ $section ][ $key ] = $value;
492 continue;
493 }
494
495 $values[ $key ] = $value;
496 }
497
498 return $values;
499 }
500
501 /**
502 * Return list of dynamic groups.
503 *
504 * @return string[]
505 * @access private
506 * @since 1.0.0
507 */
508 private function get_dynamic_groups() {
509 return apply_filters( 'charitable_dynamic_groups', array() );
510 }
511
512 /**
513 * Returns a composite key, given a section and submitted values.
514 *
515 * @param string $section
516 * @param array $submitted
517 * @return string
518 * @access private
519 * @since 1.0.0
520 */
521 private function get_composite_key( $section, $submitted ) {
522 if ( ! is_array( current( $submitted ) ) ) {
523 return false;
524 }
525
526 return sprintf( '%s_%s', $section, key( $submitted ) );
527 }
528
529 /**
530 * Returns whether the given key indicates the start of a new section of the settings.
531 *
532 * @param string $section
533 * @param array $submitted
534 * @return boolean
535 * @access private
536 * @since 1.0.0
537 */
538 private function is_dynamic_group( $composite_key ) {
539 return array_key_exists( $composite_key, $this->get_dynamic_groups() );
540 }
541 }
542
543 endif; // End class_exists check
544