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

480 lines 13.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 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 * Register setting.
118 *
119 * @return void
120 * @access public
121 * @since 1.0.0
122 */
123 public function register_settings() {
124 if ( ! charitable_is_settings_view() ) {
125 return;
126 }
127
128 register_setting( 'charitable_settings', 'charitable_settings', array( $this, 'sanitize_settings' ) );
129
130 $fields = $this->get_fields();
131
132 if ( empty( $fields ) ) {
133 return;
134 }
135
136 $sections = array_merge( $this->get_sections(), $this->get_dynamic_groups() );
137
138 /* Register each section */
139 foreach ( $sections as $section_key => $section ) {
140 $section_id = 'charitable_settings_' . $section_key;
141
142 add_settings_section(
143 $section_id,
144 __return_null(),
145 '__return_false',
146 $section_id
147 );
148
149 if ( ! isset( $fields[ $section_key ] ) || empty( $fields[ $section_key ] ) ) {
150 continue;
151 }
152
153 /* Sort by priority */
154 $section_fields = $fields[ $section_key ];
155 uasort( $section_fields, 'charitable_priority_sort' );
156
157 /* Add the individual fields within the section */
158 foreach ( $section_fields as $key => $field ) {
159
160 $this->register_field( $field, array( $section_key, $key ) );
161
162 }
163 }
164 }
165
166 /**
167 * Sanitize submitted settings before saving to the database.
168 *
169 * @param array $values
170 * @return string
171 * @access public
172 * @since 1.0.0
173 */
174 public function sanitize_settings( $values ) {
175 $old_values = get_option( 'charitable_settings', array() );
176 $new_values = array();
177
178 if ( ! is_array( $values ) ) {
179 $values = array();
180 }
181
182 /* Loop through all fields, merging the submitted values into the master array */
183 foreach ( $values as $section => $submitted ) {
184 $new_values = array_merge( $new_values, $this->get_section_submitted_values( $section, $submitted ) );
185 }
186
187 $values = wp_parse_args( $new_values, $old_values );
188
189 return apply_filters( 'charitable_save_settings', $values, $new_values, $old_values );
190 }
191
192 /**
193 * Checkbox settings should always be either 1 or 0.
194 *
195 * @param mixed $value
196 * @param array $field
197 * @return boolean
198 * @access public
199 * @since 1.0.0
200 */
201 public function sanitize_checkbox_value( $value, $field ) {
202 if ( isset( $field[ 'type' ] ) && 'checkbox' == $field[ 'type' ] ) {
203 $value = intval( $value && 'on' == $value );
204 }
205
206 return $value;
207 }
208
209 /**
210 * Render field. This is the default callback used for all fields, unless an alternative callback has been specified.
211 *
212 * @param array $args
213 * @return void
214 * @access public
215 * @since 1.0.0
216 */
217 public function render_field( $args ) {
218 $field_type = isset( $args[ 'type' ] ) ? $args[ 'type' ] : 'text';
219
220 charitable_admin_view( 'settings/' . $field_type, $args );
221 }
222
223
224 /**
225 * Returns an array of all pages in the id=>title format.
226 *
227 * @return string[]
228 * @access public
229 * @since 1.0.0
230 */
231 public function get_pages() {
232 $pages = wp_cache_get( 'filtered_static_pages', 'charitable' );
233
234 if ( false === $pages ) {
235
236 $all_pages = get_pages();
237
238 if ( ! $all_pages ) {
239 $all_pages = array();
240 }
241
242 $pages = array();
243
244 foreach ( $all_pages as $page ) {
245
246 $pages[ $page->ID ] = $page->post_title;
247
248 }
249
250 wp_cache_set( 'filtered_static_pages', $pages, 'charitable' );
251 }
252
253 return $pages;
254 }
255
256 /**
257 * Recursively add settings fields, given an array.
258 *
259 * @param array $fields
260 * @param string $section_key
261 * @return void
262 * @access private
263 * @since 1.0.0
264 */
265 private function register_field( $field, $keys ) {
266 $section_id = 'charitable_settings_' . $keys[ 0 ];
267
268 if ( isset( $field[ 'render' ] ) && ! $field[ 'render' ] ) {
269 return;
270 }
271
272 /* Drop the first key, which is the section identifier */
273 $field[ 'name' ] = implode( '][', $keys );
274
275 if ( ! $this->is_dynamic_group( $keys[ 0 ] ) ) {
276 array_shift( $keys );
277 }
278
279 $field[ 'key' ] = $keys;
280 $field[ 'classes' ] = $this->get_field_classes( $field );
281
282 $callback = isset( $field[ 'callback' ] ) ? $field[ 'callback' ] : array( $this, 'render_field' );
283 $label = $this->get_field_label( $field, end( $keys ) );
284
285 add_settings_field(
286 sprintf( 'charitable_settings_%s', implode( '_', $keys ) ),
287 $label,
288 $callback,
289 $section_id,
290 $section_id,
291 $field
292 );
293 }
294
295 /**
296 * Return the label for the given field.
297 *
298 * @param array $field
299 * @param string $key
300 * @return string
301 * @access private
302 * @since 1.0.0
303 */
304 private function get_field_label( $field, $key ) {
305 $label = "";
306
307 if ( isset( $field[ 'label_for' ] ) ) {
308 $label = $field[ 'label_for' ];
309 }
310
311 if ( isset( $field[ 'title' ] ) ) {
312 $label = $field[ 'title' ];
313 }
314
315 return $label;
316 }
317
318 /**
319 * Return a space separated string of classes for the given field.
320 *
321 * @param array $field
322 * @return string
323 * @access private
324 * @since 1.0.0
325 */
326 private function get_field_classes( $field ) {
327 $classes = array( 'charitable-settings-field' );
328
329 if ( isset( $field[ 'class' ] ) ) {
330 $classes[] = $field[ 'class' ];
331 }
332
333 $classes = apply_filters( 'charitable_settings_field_classes', $classes, $field );
334
335 return implode( ' ', $classes );
336 }
337
338 /**
339 * Return an array with all the fields & sections to be displayed.
340 *
341 * @uses charitable_settings_fields
342 * @see Charitable_Settings::register_setting()
343 * @return array
344 * @access private
345 * @since 1.0.0
346 */
347 private function get_fields() {
348 /**
349 * Use the charitable_settings_tab_fields to include the fields for new tabs.
350 * DO NOT use it to add individual fields. That should be done with the
351 * filters within each of the methods.
352 */
353 $fields = array();
354
355 foreach ( $this->get_sections() as $section_key => $section ) {
356 $fields[ $section_key ] = apply_filters( 'charitable_settings_tab_fields_' . $section_key, array() );
357 }
358
359 return apply_filters( 'charitable_settings_tab_fields', $fields );
360 }
361
362 /**
363 * Get the submitted value for a particular setting.
364 *
365 * @param string $key
366 * @param array $field
367 * @param array $submitted
368 * @return mixed|null Returns null if the value was not submitted or is not applicable.
369 * @access private
370 * @since 1.0.0
371 */
372 private function get_setting_submitted_value( $key, $field, $submitted ) {
373 $value = null;
374
375 if ( isset( $field[ 'save' ] ) && ! $field[ 'save' ] ) {
376 return $value;
377 }
378
379 $field_type = isset( $field[ 'type' ] ) ? $field[ 'type' ] : '';
380
381 switch( $field_type ) {
382 case '' :
383 case 'heading' :
384 return $value;
385 break;
386
387 case 'checkbox' :
388 $value = isset( $submitted[ $key ] );
389 break;
390
391 case 'multi-checkbox' :
392 $value = isset( $submitted[ $key ] ) ? $submitted[ $key ] : array();
393 break;
394
395 default :
396 $value = $submitted[ $key ];
397 }
398
399 return apply_filters( 'charitable_sanitize_value', $value, $field, $submitted, $key );
400 }
401
402 /**
403 * Return the submitted values for the given section.
404 *
405 * @param string $section
406 * @param array $submitted
407 * @return array
408 * @access private
409 * @since 1.0.0
410 */
411 private function get_section_submitted_values( $section, $submitted ) {
412 $values = array();
413 $form_fields = $this->get_fields();
414
415 if ( ! isset( $form_fields[ $section ] ) ) {
416 return $values;
417 }
418
419 foreach ( $form_fields[ $section ] as $key => $field ) {
420
421 $value = $this->get_setting_submitted_value( $key, $field, $submitted );
422
423 if ( is_null( $value ) ) {
424 continue;
425 }
426
427 if ( $this->is_dynamic_group( $section ) ) {
428 $values[ $section ][ $key ] = $value;
429 continue;
430 }
431
432 $values[ $key ] = $value;
433 }
434
435 return $values;
436 }
437
438 /**
439 * Return list of dynamic groups.
440 *
441 * @return string[]
442 * @access private
443 * @since 1.0.0
444 */
445 private function get_dynamic_groups() {
446 return apply_filters( 'charitable_dynamic_groups', array() );
447 }
448
449 /**
450 * Returns a composite key, given a section and submitted values.
451 *
452 * @param string $section
453 * @param array $submitted
454 * @return string
455 * @access private
456 * @since 1.0.0
457 */
458 private function get_composite_key( $section, $submitted ) {
459 if ( ! is_array( current( $submitted ) ) ) {
460 return false;
461 }
462
463 return sprintf( '%s_%s', $section, key( $submitted ) );
464 }
465
466 /**
467 * Returns whether the given key indicates the start of a new section of the settings.
468 *
469 * @param string $section
470 * @param array $submitted
471 * @return boolean
472 * @access private
473 * @since 1.0.0
474 */
475 private function is_dynamic_group( $composite_key ) {
476 return array_key_exists( $composite_key, $this->get_dynamic_groups() );
477 }
478 }
479
480 endif; // End class_exists check