PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.7.0.14
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.7.0.14
1.8.13.1 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 All 212 releases
charitable / includes / admin / class-charitable-admin.php

class-charitable-admin.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.7.0.14, at includes/admin/class-charitable-admin.php

719 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class that sets up the Charitable Admin functionality.
4 *
5 * @package Charitable/Classes/Charitable_Admin
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.6.44
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Admin' ) ) :
19
20 /**
21 * Charitable_Admin
22 *
23 * @final
24 * @since 1.0.0
25 */
26 final class Charitable_Admin {
27
28 /**
29 * The single instance of this class.
30 *
31 * @var Charitable_Admin|null
32 */
33 private static $instance = null;
34
35 /**
36 * Donation actions class.
37 *
38 * @var Charitable_Donation_Admin_Actions
39 */
40 private $donation_actions;
41
42 /**
43 * Set up the class.
44 *
45 * Note that the only way to instantiate an object is with the charitable_start method,
46 * which can only be called during the start phase. In other words, don't try
47 * to instantiate this object.
48 *
49 * @since 1.0.0
50 */
51 protected function __construct() {
52 $this->load_dependencies();
53
54 $this->donation_actions = new Charitable_Donation_Admin_Actions;
55
56 do_action( 'charitable_admin_loaded' );
57
58 add_action( 'wp_ajax_charitable_lite_settings_upgrade', array( $this, 'dismiss_lite_cta' ) );
59 }
60
61 /**
62 * Returns and/or create the single instance of this class.
63 *
64 * @since 1.2.0
65 *
66 * @return Charitable_Admin
67 */
68 public static function get_instance() {
69 if ( is_null( self::$instance ) ) {
70 self::$instance = new self();
71 }
72
73 return self::$instance;
74 }
75
76 /**
77 * Include admin-only files.
78 *
79 * @since 1.0.0
80 *
81 * @return void
82 */
83 private function load_dependencies() {
84 $admin_dir = charitable()->get_path( 'includes' ) . 'admin/';
85
86 require_once( $admin_dir . 'charitable-core-admin-functions.php' );
87 require_once( $admin_dir . 'campaigns/charitable-admin-campaign-hooks.php' );
88 require_once( $admin_dir . 'dashboard-widgets/charitable-dashboard-widgets-hooks.php' );
89 require_once( $admin_dir . 'donations/charitable-admin-donation-hooks.php' );
90 require_once( $admin_dir . 'settings/charitable-settings-admin-hooks.php' );
91 }
92
93 /**
94 * Get Charitable_Donation_Admin_Actions class.
95 *
96 * @since 1.5.0
97 *
98 * @return Charitable_Donation_Admin_Actions
99 */
100 public function get_donation_actions() {
101 return $this->donation_actions;
102 }
103
104 /**
105 * Do an admin action.
106 *
107 * @since 1.5.0
108 *
109 * @return boolean|WP_Error WP_Error in case of error. Mixed results if the action was performed.
110 */
111 public function maybe_do_admin_action() {
112 if ( ! array_key_exists( 'charitable_admin_action', $_GET ) ) {
113 return false;
114 }
115
116 if ( count( array_diff( array( 'action_type', '_nonce', 'object_id' ), array_keys( $_GET ) ) ) ) {
117 return new WP_Error( __( 'Action could not be executed.', 'charitable' ) );
118 }
119
120 if ( ! wp_verify_nonce( $_GET['_nonce'], 'donation_action' ) ) {
121 return new WP_Error( __( 'Action could not be executed. Nonce check failed.', 'charitable' ) );
122 }
123
124 if ( 'donation' != $_GET['action_type'] ) {
125 return new WP_Error( __( 'Action from an unknown action type executed.', 'charitable' ) );
126 }
127
128 return $this->donation_actions->do_action( $_GET['charitable_admin_action'], $_GET['object_id'] );
129 }
130
131 /**
132 * Loads admin-only scripts and stylesheets.
133 *
134 * @since 1.0.0
135 *
136 * @return void
137 */
138 public function admin_enqueue_scripts() {
139 if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
140 $suffix = '';
141 $version = '';
142 } else {
143 $suffix = '.min';
144 $version = charitable()->get_version();
145 }
146
147 $assets_dir = charitable()->get_path( 'assets', false );
148
149 /* Menu styles are loaded everywhere in the WordPress dashboard. */
150 wp_register_style(
151 'charitable-admin-menu',
152 $assets_dir . 'css/charitable-admin-menu' . $suffix . '.css',
153 array(),
154 $version
155 );
156
157 wp_enqueue_style( 'charitable-admin-menu' );
158
159 wp_register_script(
160 'charitable-admin-pages-all',
161 $assets_dir . 'js/charitable-admin-pages' . $suffix . '.js',
162 array( 'jquery' ),
163 $version,
164 false
165 );
166
167 wp_enqueue_script( 'charitable-admin-pages-all' );
168
169 /* Admin page styles are registered but only enqueued when necessary. */
170 wp_register_style(
171 'charitable-admin-pages',
172 $assets_dir . 'css/charitable-admin-pages' . $suffix . '.css',
173 array(),
174 $version
175 );
176
177 /* The following styles are only loaded on Charitable screens. */
178 $screen = get_current_screen();
179
180 /* This check covers the category and tags pages, only load the main admin css (upgrade banner, etc.) */
181 if ( ! is_null( $screen ) && in_array( $screen->base, array( 'edit-tags', 'edit-categories' ) ) ) {
182
183 wp_register_style(
184 'charitable-admin',
185 $assets_dir . 'css/charitable-admin' . $suffix . '.css',
186 array(),
187 $version
188 );
189
190 wp_enqueue_style( 'charitable-admin' );
191
192 wp_register_script(
193 'charitable-admin-notice',
194 $assets_dir . 'js/charitable-admin-notice' . $suffix . '.js',
195 array( 'jquery' ),
196 $version,
197 false
198 );
199
200 }
201
202 /* This check covers the category and tags pages, only load the main admin css (upgrade banner, etc.) */
203 if ( ! is_null( $screen ) && in_array( $screen->base, array( 'charitable_page_charitable-addons' ) ) ) {
204
205 }
206
207 if ( ! is_null( $screen ) && in_array( $screen->id, $this->get_charitable_screens() ) ) {
208
209 wp_register_style(
210 'charitable-admin',
211 $assets_dir . 'css/charitable-admin' . $suffix . '.css',
212 array(),
213 $version
214 );
215
216 wp_enqueue_style( 'charitable-admin' );
217
218 $dependencies = array( 'jquery-ui-datepicker', 'jquery-ui-tabs', 'jquery-ui-sortable' );
219 $localized_vars = array(
220 'suggested_amount_placeholder' => __( 'Amount', 'charitable' ),
221 'suggested_amount_description_placeholder' => __( 'Optional Description', 'charitable' ),
222 );
223
224 if ( 'donation' == $screen->id ) {
225 wp_register_script(
226 'accounting',
227 $assets_dir . 'js/libraries/accounting'. $suffix . '.js',
228 array( 'jquery' ),
229 $version,
230 true
231 );
232
233 $dependencies[] = 'accounting';
234 $localized_vars = array_merge(
235 $localized_vars,
236 array(
237 'currency_format_num_decimals' => esc_attr( charitable_get_currency_helper()->get_decimals() ),
238 'currency_format_decimal_sep' => esc_attr( charitable_get_currency_helper()->get_decimal_separator() ),
239 'currency_format_thousand_sep' => esc_attr( charitable_get_currency_helper()->get_thousands_separator() ),
240 'currency_format' => esc_attr( charitable_get_currency_helper()->get_accounting_js_format() ),
241 )
242 );
243 }
244
245 wp_register_script(
246 'charitable-admin',
247 $assets_dir . 'js/charitable-admin' . $suffix . '.js',
248 $dependencies,
249 $version,
250 false
251 );
252
253 wp_enqueue_script( 'charitable-admin' );
254
255 /**
256 * Filter the admin Javascript vars.
257 *
258 * @since 1.0.0
259 *
260 * @param array $localized_vars The vars.
261 */
262 $localized_vars = apply_filters( 'charitable_localized_javascript_vars', $localized_vars );
263
264 wp_localize_script( 'charitable-admin', 'CHARITABLE', $localized_vars );
265
266 /* color picker for admin settings */
267 wp_enqueue_script( 'wp-color-picker', false, false, false, true );
268 wp_enqueue_style( 'wp-color-picker' );
269
270 } // end if
271
272 wp_register_script(
273 'charitable-admin-notice',
274 $assets_dir . 'js/charitable-admin-notice' . $suffix . '.js',
275 array( 'jquery' ),
276 $version,
277 false
278 );
279
280 wp_register_script(
281 'charitable-admin-media',
282 $assets_dir . 'js/charitable-admin-media' . $suffix . '.js',
283 array( 'jquery' ),
284 $version,
285 false
286 );
287
288 wp_register_script(
289 'lean-modal',
290 $assets_dir . 'js/libraries/leanModal' . $suffix . '.js',
291 array( 'jquery' ),
292 $version,
293 true
294 );
295
296 wp_register_style(
297 'lean-modal-css',
298 $assets_dir . 'css/modal' . $suffix . '.css',
299 array(),
300 $version
301 );
302
303 wp_register_script(
304 'charitable-admin-tables',
305 $assets_dir . 'js/charitable-admin-tables' . $suffix . '.js',
306 array( 'jquery', 'lean-modal' ),
307 $version,
308 true
309 );
310
311 wp_register_script(
312 'select2',
313 $assets_dir . 'js/libraries/select2' . $suffix . '.js',
314 array( 'jquery' ),
315 '4.0.12',
316 true
317 );
318
319 wp_register_style(
320 'select2-css',
321 $assets_dir . 'css/libraries/select2' . $suffix . '.css',
322 array(),
323 '4.0.12'
324 );
325
326 do_action( 'after_charitable_admin_enqueue_scripts', $suffix, $version, $assets_dir );
327 }
328
329 /**
330 * Set admin body classes.
331 *
332 * @since 1.5.0
333 *
334 * @param string $classes Existing list of classes.
335 * @return string
336 */
337 public function set_body_class( $classes ) {
338 $screen = get_current_screen();
339
340 if ( 'donation' == $screen->post_type && ( 'add' == $screen->action || isset( $_GET['show_form'] ) ) ) {
341 $classes .= ' charitable-admin-donation-form';
342 }
343
344 return $classes;
345 }
346
347 /**
348 * Add notices to the dashboard.
349 *
350 * @since 1.4.0
351 *
352 * @return void
353 */
354 public function add_notices() {
355 /* Get any version update notices first. */
356 // $this->add_version_update_notices(); // depreciated
357
358 $this->add_third_party_notices();
359
360 /* Render notices. */
361 charitable_get_admin_notices()->render();
362 }
363
364 /**
365 * Add notices for potential third party warnings.
366 *
367 * @since 1.7.0.8
368 */
369 public function add_third_party_notices() {
370 if ( ! current_user_can( 'manage_options' ) ) {
371 return;
372 }
373
374 // Allow this feature to be disabled in case unforeseen problems come up.
375 if ( false === apply_filters( 'charitable_donations_export_args', true ) ) {
376 return;
377 }
378
379 $notices = array(
380 /* translators: %s: link */
381 'code-snippets/code-snippets.php' => sprintf( __( "You appear to be using a code snippet plugin. Please <a href='%s' target='_blank'>review best practices</a> when using snippets to avoid problems when upgrading or deactivating Charitable.", 'charitable' ),
382 'https://wpcharitable.com/code-snippet-best-practices/'
383 )
384 );
385
386 // Allow this list to be altered by a third party or charitable addon.
387 $notices = apply_filters( 'charitable_admin_third_party_notices', $notices );
388
389 $helper = charitable_get_admin_notices();
390
391 foreach ( $notices as $notice => $message ) {
392 if ( false === charitable_get_third_party_warning_option( 'code-snippets/code-snippets.php' ) || 'dismissed' === charitable_get_third_party_warning_option( 'code-snippets/code-snippets.php' ) ) {
393 continue;
394 }
395
396 $helper->add_third_party_warning( $message, $notice );
397 }
398
399 }
400
401 /**
402 * Add version update notices to the dashboard.
403 *
404 * @since 1.4.6
405 *
406 * @return void
407 */
408 public function add_version_update_notices() {
409 if ( ! current_user_can( 'manage_options' ) ) {
410 return;
411 }
412
413 $notices = array(
414 /* translators: %s: link */
415 'release-150' => sprintf( __( "Charitable 1.5 is packed with new features and improvements. <a href='%s' target='_blank'>Find out what's new</a>.", 'charitable' ),
416 'https://wpcharitable.com/charitable-1-5-release-notes/?utm_source=WordPress&utm_campaign=WP+Charitable&utm_medium=Admin+Notice&utm_content=Version+One+Five+Whats+New'
417 ),
418 /* translators: %s: link */
419 'release-160' => sprintf( __( 'Charitable 1.6 introduces important new user privacy features and other improvements. <a href="%s" target="_blank">Find out what\'s new</a>.', 'charitable' ),
420 'https://www.wpcharitable.com/charitable-1-6-user-privacy-gdpr-better-refunds-and-a-new-shortcode/?utm_source=WordPress&utm_campaign=WP+Charitable&utm_medium=Admin+Notice&utm_content=Version+One+Six+Whats+New'
421 ),
422 );
423
424 $helper = charitable_get_admin_notices();
425
426 foreach ( $notices as $notice => $message ) {
427 if ( ! get_transient( 'charitable_' . $notice . '_notice' ) ) {
428 continue;
429 }
430
431 $helper->add_version_update( $message, $notice );
432 }
433 }
434
435 /**
436 * Dismiss a notice.
437 *
438 * @since 1.4.0
439 *
440 * @return void
441 */
442 public function dismiss_notice() {
443 if ( ! isset( $_POST['notice'] ) ) {
444 wp_send_json_error();
445 }
446
447 $ret = ( 'noted' === charitable_get_third_party_warning_option( 'code-snippets/code-snippets.php' ) ) ? charitable_set_third_party_warning_option( 'code-snippets/code-snippets.php', 'dismissed' ) : delete_transient( 'charitable_' . filter_input( INPUT_POST, 'notice', FILTER_SANITIZE_STRING ) . '_notice', true );
448
449 do_action( 'charitable_dismiss_notice', $_POST );
450
451 if ( ! $ret ) {
452 wp_send_json_error( $ret );
453 }
454
455 wp_send_json_success();
456 }
457
458 /**
459 * Dismiss a banner.
460 *
461 * @since 1.7.0
462 *
463 * @return void
464 */
465 public function dismiss_banner() {
466 if ( ! isset( $_POST['banner_id'] ) ) {
467 wp_send_json_error();
468 }
469
470 $ret = set_transient( 'charitable_' . $_POST['banner_id'] . '_banner', 1, WEEK_IN_SECONDS );
471
472 if ( ! $ret ) {
473 wp_send_json_error( $ret );
474 }
475
476 wp_send_json_success();
477 }
478
479
480 /**
481 * Dismiss a five star rating.
482 *
483 * @since 1.7.0
484 *
485 * @return void
486 */
487 public function dismiss_five_star_rating() {
488 if ( ! isset( $_POST['banner_id'] ) ) {
489 wp_send_json_error();
490 }
491
492 $check = get_transient( 'charitable_' . $_POST['banner_id'] . '_banner' );
493
494 if ( ! $check ) {
495 $ret = set_transient( 'charitable_' . $_POST['banner_id'] . '_banner', true );
496 if ( ! $ret ) {
497 wp_send_json_error( $ret );
498 }
499 }
500
501 wp_send_json_success();
502 }
503
504 /**
505 * Dismiss a five star rating.
506 *
507 * @since 1.7.0
508 *
509 * @return void
510 */
511 public function dismiss_lite_cta() {
512 if ( ! isset( $_POST['chartiable_action'] ) ) {
513 wp_send_json_error();
514 }
515
516 $updated = update_option( 'charitable_lite_settings_upgrade', true );
517
518 if ( $updated ) {
519 wp_send_json_success();
520 } else {
521 wp_send_json_error();
522 }
523
524 }
525
526 /**
527 * Adds one or more classes to the body tag in the dashboard.
528 *
529 * @since 1.0.0
530 *
531 * @param string $classes Current body classes.
532 * @return string Altered body classes.
533 */
534 public function add_admin_body_class( $classes ) {
535 $screen = get_current_screen();
536
537 if ( in_array( $screen->post_type, array( Charitable::DONATION_POST_TYPE, Charitable::CAMPAIGN_POST_TYPE ) ) ) {
538 $classes .= ' post-type-charitable';
539 }
540
541 return $classes;
542 }
543
544 /**
545 * Add custom links to the plugin actions.
546 *
547 * @since 1.0.0
548 *
549 * @param string[] $links Plugin action links.
550 * @return string[]
551 */
552 public function add_plugin_action_links( $links ) {
553 $links[] = '<a href="' . admin_url( 'admin.php?page=charitable-settings' ) . '">' . __( 'Settings', 'charitable' ) . '</a>';
554 return $links;
555 }
556
557 /**
558 * Add Extensions link to the plugin row meta.
559 *
560 * @since 1.2.0
561 *
562 * @param string[] $links Plugin action links.
563 * @param string $file The plugin file.
564 * @return string[] $links
565 */
566 public function add_plugin_row_meta( $links, $file ) {
567 if ( plugin_basename( charitable()->get_path() ) != $file ) {
568 return $links;
569 }
570
571 // Use an updated UTM.
572 $extensions_link = charitable_ga_url(
573 'https://wpcharitable.com/extensions/',
574 urlencode( 'Admin Plugin Page'),
575 urlencode( 'Extensions' )
576 );
577
578 $links[] = '<a href="' . $extensions_link . '" target="_blank" rel="noopener">' . __( 'Extensions', 'charitable' ) . '</a>';
579
580 return $links;
581 }
582
583 /**
584 * Remove the jQuery UI styles added by Ninja Forms.
585 *
586 * @since 1.2.0
587 *
588 * @param string $context Media buttons context.
589 * @return string
590 */
591 public function remove_jquery_ui_styles_nf( $context ) {
592 wp_dequeue_style( 'jquery-smoothness' );
593 return $context;
594 }
595
596 /**
597 * Export donations.
598 *
599 * @since 1.3.0
600 *
601 * @return false|void Returns false if the export failed. Exits otherwise.
602 */
603 public function export_donations() {
604
605 if ( ! wp_verify_nonce( $_GET['_charitable_export_nonce'], 'charitable_export_donations' ) ) {
606 return false;
607 }
608
609 /**
610 * Filter the donation export arguments.
611 *
612 * @since 1.3.0
613 *
614 * @param array $args Export arguments.
615 */
616 $export_args = apply_filters(
617 'charitable_donations_export_args',
618 array(
619 'start_date' => $_GET['start_date'],
620 'end_date' => $_GET['end_date'],
621 'status' => $_GET['post_status'],
622 'campaign_id' => $_GET['campaign_id'],
623 'report_type' => $_GET['report_type'],
624 )
625 );
626
627 /**
628 * Filter the export class name.
629 *
630 * @since 1.3.0
631 *
632 * @param string $report_type The type of report.
633 * @param array $args Export arguments.
634 */
635 $export_class = apply_filters( 'charitable_donations_export_class', 'Charitable_Export_Donations', $_GET['report_type'], $export_args );
636
637 new $export_class( $export_args );
638
639 die();
640 }
641
642 /**
643 * Export campaigns.
644 *
645 * @since 1.6.0
646 *
647 * @return false|void Returns false if the export failed. Exits otherwise.
648 */
649 public function export_campaigns() {
650 if ( ! wp_verify_nonce( $_GET['_charitable_export_nonce'], 'charitable_export_campaigns' ) ) {
651 return false;
652 }
653
654 /**
655 * Filter the campaign export arguments.
656 *
657 * @since 1.6.0
658 *
659 * @param array $args Export arguments.
660 */
661 $export_args = apply_filters(
662 'charitable_campaigns_export_args',
663 array(
664 'start_date_from' => $_GET['start_date_from'],
665 'start_date_to' => $_GET['start_date_to'],
666 'end_date_from' => $_GET['end_date_from'],
667 'end_date_to' => $_GET['end_date_to'],
668 'status' => $_GET['status'],
669 'report_type' => $_GET['report_type'],
670 )
671 );
672
673 /**
674 * Filter the export class name.
675 *
676 * @since 1.6.0
677 *
678 * @param string $report_type The type of report.
679 * @param array $args Export arguments.
680 */
681 $export_class = apply_filters( 'charitable_campaigns_export_class', 'Charitable_Export_Campaigns', $_GET['report_type'], $export_args );
682
683 new $export_class( $export_args );
684
685 die();
686 }
687
688 /**
689 * Returns an array of screen IDs where the Charitable scripts should be loaded.
690 *
691 * @uses charitable_admin_screens
692 *
693 * @since 1.0.0
694 *
695 * @return array
696 */
697 public function get_charitable_screens() {
698 /**
699 * Filter admin screens where Charitable styles & scripts should be loaded.
700 *
701 * @since 1.0.0
702 *
703 * @param string[] $screens List of screen ids.
704 */
705 return apply_filters( 'charitable_admin_screens', array(
706 'campaign',
707 'donation',
708 'charitable_page_charitable-settings',
709 'edit-campaign',
710 'edit-donation',
711 'dashboard',
712 'toplevel_page_charitable',
713 'charitable_page_charitable-addons',
714 ) );
715 }
716 }
717
718 endif;
719