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

696 lines 22.1 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 David Bisset
7 * @copyright Copyright (c) 2022, WP Charitable LLC
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 including "workaround".
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 $settings_keys = array_keys( $new_values );
243
244 if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) {
245 error_log( 'santiize_settings' );
246 error_log( 'values:' );
247 error_log( print_r( $values, true ) );
248 error_log( 'old_values:' );
249 error_log( print_r( $old_values, true ) );
250 error_log( 'new_values:' );
251 error_log( print_r( $new_values, true ) );
252 }
253
254 // determine if Charitable gateway "test mode" is being changed, and if so add a notice to the user.
255 if ( array_key_exists('test_mode', $new_values ) && array_key_exists('test_mode', $old_values ) && $old_values['test_mode'] !== $new_values['test_mode'] ) {
256 $old_settings_keys = array_keys( $old_values );
257 $dismissible = true;
258 if ( in_array( 'gateways_stripe', $old_settings_keys ) ) {
259 charitable_get_admin_notices()->add_notice( 'Some active payment gateways <strong>(including Stripe)</strong> might have reset their connections due to an update in the test mode. Please check your active payment gateways in ensure they are still connected.', 'warning', false, $dismissible );
260 } else {
261 charitable_get_admin_notices()->add_notice( 'Some active payment gateways might have reset their connections due to an update in the test mode. Please check your active payment gateways in ensure they are still connected.', 'warning', false, $dismissible );
262 }
263 }
264
265 if ( in_array( 'gateways_stripe', $settings_keys ) && charitable()->is_stripe_connect_addon() && false === charitable_using_stripe_connect() ) {
266 // non-existant array keys in the array for API keys might be a result of the "manual update key" feature which is based on ajax and might not load keys into form if the user doesn't click on the link in the settings to view/edit them.
267 if ( ! array_key_exists( 'live_secret_key', $values['gateways_stripe'] ) && isset( $old_values['gateways_stripe']['live_secret_key'] ) && ( false !== $old_values['gateways_stripe']['live_secret_key'] ) ) {
268 $values['gateways_stripe']['live_secret_key'] = $old_values['gateways_stripe']['live_secret_key'];
269 }
270 if ( ! array_key_exists( 'live_public_key', $values['gateways_stripe'] ) && isset( $old_values['gateways_stripe']['live_public_key'] ) && ( false !== $old_values['gateways_stripe']['live_public_key'] ) ) {
271 $values['gateways_stripe']['live_public_key'] = $old_values['gateways_stripe']['live_secret_key'];
272 }
273 if ( ! array_key_exists( 'test_secret_key', $values['gateways_stripe'] ) && isset( $old_values['gateways_stripe']['test_secret_key'] ) && ( false !== $old_values['gateways_stripe']['test_secret_key'] ) ) {
274 $values['gateways_stripe']['test_secret_key'] = $old_values['gateways_stripe']['test_secret_key'];
275 }
276 if ( ! array_key_exists( 'test_public_key', $values['gateways_stripe'] ) && isset( $old_values['gateways_stripe']['test_public_key'] ) && ( false !== $old_values['gateways_stripe']['test_public_key'] ) ) {
277 $values['gateways_stripe']['test_public_key'] = $old_values['gateways_stripe']['test_public_key'];
278 }
279 if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) {
280 error_log( 'update:' );
281 error_log( print_r( $values, true ) );
282 }
283 }
284
285 // determine if stripe is being returned as new values - if so, then perform the API key save workaround
286 if ( in_array( 'gateways_stripe', $settings_keys ) && charitable()->is_stripe_connect_addon() && false === charitable_using_stripe_connect() ) {
287 if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) {
288 error_log( 'there is a stripe connect addon but we are not using stripe connect' );
289 }
290 // the stripe connect addon is installed AND the AM Stripe Connect isn't being used... so it's possible the keys could be manual and the user could be updating them... therefore let's just make sure the new values match the values incoming.
291 $new_values['gateways_stripe']['live_secret_key'] = ( isset( $values['gateways_stripe']['live_secret_key'] ) && ( false !== $values['gateways_stripe']['live_secret_key'] ) ) ? $values['gateways_stripe']['live_secret_key'] : null;
292 $new_values['gateways_stripe']['live_public_key'] = ( isset( $values['gateways_stripe']['live_public_key'] ) && ( false !== $values['gateways_stripe']['live_public_key'] ) ) ? $values['gateways_stripe']['live_public_key'] : null;
293 $new_values['gateways_stripe']['test_secret_key'] = ( isset( $values['gateways_stripe']['test_secret_key'] ) && ( false !== $values['gateways_stripe']['test_secret_key'] ) ) ? $values['gateways_stripe']['test_secret_key'] : null;
294 $new_values['gateways_stripe']['test_public_key'] = ( isset( $values['gateways_stripe']['test_public_key'] ) && ( false !== $values['gateways_stripe']['test_public_key'] ) ) ? $values['gateways_stripe']['test_public_key'] : null;
295 } else if ( in_array( 'gateways_stripe', $settings_keys ) ) {
296 // otherwise we preserve the keys
297 if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) {
298 error_log( 'charitable debug, final with debug on:' );
299 $new_values['gateways_stripe']['live_secret_key'] = ( isset( $values['gateways_stripe']['live_secret_key'] ) && ( false !== $values['gateways_stripe']['live_secret_key'] ) ) ? $values['gateways_stripe']['live_secret_key'] : null;
300 $new_values['gateways_stripe']['live_public_key'] = ( isset( $values['gateways_stripe']['live_public_key'] ) && ( false !== $values['gateways_stripe']['live_public_key'] ) ) ? $values['gateways_stripe']['live_public_key'] : null;
301 $new_values['gateways_stripe']['test_secret_key'] = ( isset( $values['gateways_stripe']['test_secret_key'] ) && ( false !== $values['gateways_stripe']['test_secret_key'] ) ) ? $values['gateways_stripe']['test_secret_key'] : null;
302 $new_values['gateways_stripe']['test_public_key'] = ( isset( $values['gateways_stripe']['test_public_key'] ) && ( false !== $values['gateways_stripe']['test_public_key'] ) ) ? $values['gateways_stripe']['test_public_key'] : null;
303 } else {
304 $new_values['gateways_stripe']['live_secret_key'] = ( isset( $old_values['gateways_stripe']['live_secret_key'] ) && ( false !== $old_values['gateways_stripe']['live_secret_key'] ) ) ? $old_values['gateways_stripe']['live_secret_key'] : null;
305 $new_values['gateways_stripe']['live_public_key'] = ( isset( $old_values['gateways_stripe']['live_public_key'] ) && ( false !== $old_values['gateways_stripe']['live_public_key'] ) ) ? $old_values['gateways_stripe']['live_public_key'] : null;
306 $new_values['gateways_stripe']['test_secret_key'] = ( isset( $old_values['gateways_stripe']['test_secret_key'] ) && ( false !== $old_values['gateways_stripe']['test_secret_key'] ) ) ? $old_values['gateways_stripe']['test_secret_key'] : null;
307 $new_values['gateways_stripe']['test_public_key'] = ( isset( $old_values['gateways_stripe']['test_public_key'] ) && ( false !== $old_values['gateways_stripe']['test_public_key'] ) ) ? $old_values['gateways_stripe']['test_public_key'] : null;
308 }
309 }
310
311 // preserve any webhook keys, regardless if stripe connect addon is active or not.
312 if ( in_array( 'gateways_stripe', $settings_keys ) ) {
313 if ( array_key_exists( 'test_webhook_id', $old_values['gateways_stripe'] ) && isset( $old_values['gateways_stripe']['test_webhook_id'] ) ) {
314 $new_values['gateways_stripe']['test_webhook_id'] = $old_values['gateways_stripe']['test_webhook_id'];
315 }
316 if ( array_key_exists( 'live_webhook_id', $old_values['gateways_stripe'] ) && isset( $old_values['gateways_stripe']['live_webhook_id'] ) ) {
317 $new_values['gateways_stripe']['live_webhook_id'] = $old_values['gateways_stripe']['live_webhook_id'];
318 }
319 }
320
321 $values = wp_parse_args( $new_values, $old_values );
322
323 if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) {
324 error_log( 'santiize_settings values updated' );
325 error_log( print_r( $values, true ) );
326 }
327
328 /**
329 * Filter sanitized settings.
330 *
331 * @since 1.0.0
332 *
333 * @param array $values All values, merged.
334 * @param array $new_values Newly submitted values.
335 * @param array $old_values Old settings.
336 */
337 $values = apply_filters( 'charitable_save_settings', $values, $new_values, $old_values );
338
339 $this->add_update_message( __( 'Settings saved', 'charitable' ), 'success' );
340
341 return $values;
342 }
343
344 /**
345 * Checkbox settings should always be either 1 or 0.
346 *
347 * @since 1.0.0
348 *
349 * @param mixed $value Submitted value for field.
350 * @param array $field Field definition.
351 * @return int
352 */
353 public function sanitize_checkbox_value( $value, $field ) {
354 if ( isset( $field['type'] ) && 'checkbox' == $field['type'] ) {
355 $value = intval( $value && 'on' == $value );
356 }
357
358 return $value;
359 }
360
361 /**
362 * Render field. This is the default callback used for all fields, unless an alternative callback has been specified.
363 *
364 * @since 1.0.0
365 *
366 * @param array $args Field definition.
367 * @return void
368 */
369 public function render_field( $args ) {
370 $field_type = isset( $args['type'] ) ? $args['type'] : 'text';
371
372 charitable_admin_view( 'settings/' . $field_type, $args );
373 }
374
375 /**
376 * Returns an array of all pages in the id=>title format.
377 *
378 * @since 1.0.0
379 *
380 * @return string[]
381 */
382 public function get_pages() {
383 if ( ! isset( $this->pages ) ) {
384 $this->pages = charitable_get_pages_options();
385 }
386
387 return $this->pages;
388 }
389
390 /**
391 * Add an update message.
392 *
393 * @since 1.4.6
394 *
395 * @param string $message The message text.
396 * @param string $type The type of message. Options: 'error', 'success', 'warning', 'info'.
397 * @param boolean $dismissible Whether the message can be dismissed.
398 * @return void
399 */
400 public function add_update_message( $message, $type = 'error', $dismissible = true ) {
401 if ( ! in_array( $type, array( 'error', 'success', 'warning', 'info' ) ) ) {
402 $type = 'error';
403 }
404
405 charitable_get_admin_notices()->add_notice( $message, $type, false, $dismissible );
406 }
407
408 /**
409 * Recursively add settings fields, given an array.
410 *
411 * @since 1.0.0
412 *
413 * @param array $field The setting field.
414 * @param array $keys Array containing the section key and field key.
415 * @return void
416 */
417 private function register_field( $field, $keys ) {
418 $section_id = 'charitable_settings_' . $keys[0];
419
420 if ( isset( $field['render'] ) && ! $field['render'] ) {
421 return;
422 }
423
424 /* Drop the first key, which is the section identifier */
425 $field['name'] = implode( '][', $keys );
426
427 if ( ! $this->is_dynamic_group( $keys[0] ) ) {
428 array_shift( $keys );
429 }
430
431 $field['key'] = $keys;
432 $field['classes'] = $this->get_field_classes( $field );
433 $callback = isset( $field['callback'] ) ? $field['callback'] : array( $this, 'render_field' );
434 $label = $this->get_field_label( $field, end( $keys ) );
435
436 add_settings_field(
437 sprintf( 'charitable_settings_%s', implode( '_', $keys ) ),
438 $label,
439 $callback,
440 $section_id,
441 $section_id,
442 $field
443 );
444 }
445
446 /**
447 * Return the label for the given field.
448 *
449 * @since 1.0.0
450 *
451 * @param array $field The field definition.
452 * @param string $key The field key.
453 * @return string
454 */
455 private function get_field_label( $field, $key ) {
456 $label = '';
457
458 if ( isset( $field['label_for'] ) ) {
459 $label = $field['label_for'];
460 }
461
462 if ( isset( $field['title'] ) ) {
463 $label = $field['title'];
464 }
465
466 return $label;
467 }
468
469 /**
470 * Return a space separated string of classes for the given field.
471 *
472 * @since 1.0.0
473 *
474 * @param array $field Field definition.
475 * @return string
476 */
477 private function get_field_classes( $field ) {
478 $classes = array( 'charitable-settings-field' );
479
480 if ( isset( $field['class'] ) ) {
481 $classes[] = $field['class'];
482 }
483
484 /**
485 * Filter the list of classes to apply to settings fields.
486 *
487 * @since 1.0.0
488 *
489 * @param array $classes The list of classes.
490 * @param array $field The field definition.
491 */
492 $classes = apply_filters( 'charitable_settings_field_classes', $classes, $field );
493
494 return implode( ' ', $classes );
495 }
496
497 /**
498 * Return an array with all the fields & sections to be displayed.
499 *
500 * @uses charitable_settings_fields
501 * @see Charitable_Settings::register_setting()
502 * @since 1.0.0
503 *
504 * @return array
505 */
506 private function get_fields() {
507 /**
508 * Use the charitable_settings_tab_fields to include the fields for new tabs.
509 * DO NOT use it to add individual fields. That should be done with the
510 * filters within each of the methods.
511 */
512 $fields = array();
513
514 foreach ( $this->get_sections() as $section_key => $section ) {
515 /**
516 * Filter the array of fields to display in a particular tab.
517 *
518 * @since 1.0.0
519 *
520 * @param array $fields Array of fields.
521 */
522 $fields[ $section_key ] = apply_filters( 'charitable_settings_tab_fields_' . $section_key, array() );
523 }
524
525 /**
526 * Filter the array of settings fields.
527 *
528 * @since 1.0.0
529 *
530 * @param array $fields Array of fields.
531 */
532 return apply_filters( 'charitable_settings_tab_fields', $fields );
533 }
534
535 /**
536 * Get the submitted value for a particular setting.
537 *
538 * @since 1.0.0
539 *
540 * @param string $key The key of the setting being saved.
541 * @param array $field The setting field.
542 * @param array $submitted The submitted values.
543 * @param string $section The section being saved.
544 * @return mixed|null Returns null if the value was not submitted or is not applicable.
545 */
546 private function get_setting_submitted_value( $key, $field, $submitted, $section ) {
547 $value = null;
548
549 if ( isset( $field['save'] ) && ! $field['save'] ) {
550 return $value;
551 }
552
553 $field_type = isset( $field['type'] ) ? $field['type'] : '';
554
555 switch ( $field_type ) {
556
557 case 'checkbox':
558 $value = intval( array_key_exists( $key, $submitted ) && 'on' == $submitted[ $key ] );
559 break;
560
561 case 'multi-checkbox':
562 $value = isset( $submitted[ $key ] ) ? $submitted[ $key ] : array();
563 break;
564
565 case '':
566 case 'heading':
567 return $value;
568
569 default:
570 if ( ! array_key_exists( $key, $submitted ) ) {
571 return $value;
572 }
573
574 $value = $submitted[ $key ];
575
576 }//end switch
577
578 /**
579 * General way to sanitize values. If you only need to sanitize a
580 * specific setting, used the filter below instead.
581 *
582 * @since 1.0.0
583 *
584 * @param mixed $value The current setting value.
585 * @param array $field The field configuration.
586 * @param array $submitted All submitted data.
587 * @param string $key The setting key.
588 * @param string $section The section being saved.
589 */
590 $value = apply_filters( 'charitable_sanitize_value', $value, $field, $submitted, $key, $section );
591
592 /**
593 * Sanitize the setting value.
594 *
595 * The filter hook is formatted like this: charitable_sanitize_value_{$section}_{$key}.
596 *
597 * @since 1.5.0
598 *
599 * @param mixed $value The current setting value.
600 * @param array $field The field configuration.
601 * @param array $submitted All submitted data.
602 */
603 return apply_filters( 'charitable_sanitize_value_' . $section . '_' . $key, $value, $field, $submitted );
604 }
605
606 /**
607 * Return the submitted values for the given section.
608 *
609 * @since 1.0.0
610 *
611 * @param string $section The section being edited.
612 * @param array $submitted The submitted values.
613 * @return array
614 */
615 private function get_section_submitted_values( $section, $submitted ) {
616 $values = array();
617 $form_fields = $this->get_fields();
618
619 if ( ! isset( $form_fields[ $section ] ) ) {
620 return $values;
621 }
622
623 foreach ( $form_fields[ $section ] as $key => $field ) {
624 $value = $this->get_setting_submitted_value( $key, $field, $submitted, $section );
625
626 if ( is_null( $value ) ) {
627 continue;
628 }
629
630 if ( $this->is_dynamic_group( $section ) ) {
631 $values[ $section ][ $key ] = $value;
632 continue;
633 }
634
635 $values[ $key ] = $value;
636 }
637
638 return $values;
639 }
640
641 /**
642 * Return list of dynamic groups.
643 *
644 * @since 1.0.0
645 *
646 * @return string[]
647 */
648 private function get_dynamic_groups() {
649 if ( ! isset( $this->dynamic_groups ) ) {
650 /**
651 * Filter the list of dynamic groups.
652 *
653 * @since 1.0.0
654 *
655 * @param array $groups The dynamic groups.
656 */
657 $this->dynamic_groups = apply_filters( 'charitable_dynamic_groups', array() );
658 }
659
660 return $this->dynamic_groups;
661 }
662
663 /**
664 * Returns whether the given key indicates the start of a new section of the settings.
665 *
666 * @since 1.0.0
667 *
668 * @param string $composite_key The unique key for this group.
669 * @return boolean
670 */
671 private function is_dynamic_group( $composite_key ) {
672 return array_key_exists( $composite_key, $this->get_dynamic_groups() );
673 }
674
675 /* DEPRECATED FUNCTIONS */
676
677 /**
678 * Get the update messages.
679 *
680 * @deprecated 1.7.0
681 *
682 * @since 1.4.13 Deprecated.
683 */
684 public function get_update_messages() {
685 charitable_get_deprecated()->deprecated_function(
686 __METHOD__,
687 '1.4.13',
688 'Charitable_Admin_Notices::get_notices()'
689 );
690
691 return charitable_get_admin_notices()->get_notices();
692 }
693 }
694
695 endif;
696