PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.12.2
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.12.2
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-notices.php

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

856 lines 28.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Contains the class that is used to register and retrieve notices in the admin like errors, warnings, success messages, etc.
4 *
5 * @package Charitable/Classes/Charitable_Admin_Notices
6 * @author David Bisset
7 * @copyright Copyright (c) 2023, WP Charitable LLC
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.4.6
10 * @version 1.6.24
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Admin_Notices' ) ) :
19
20 /**
21 * Charitable_Admin_Notices
22 *
23 * @since 1.4.6
24 */
25 class Charitable_Admin_Notices extends Charitable_Notices {
26
27 /**
28 * Whether the script has been enqueued.
29 *
30 * @since 1.4.6
31 *
32 * @var boolean
33 */
34 private $script_enqueued;
35
36 /**
37 * Returns and/or create the single instance of this class.
38 *
39 * @since 1.4.6
40 *
41 * @return Charitable_Admin_Notices
42 */
43 public static function get_instance() {
44 return charitable()->registry()->get( 'admin_notices' );
45 }
46
47 /**
48 * Create class object. A private constructor, so this is used in a singleton context.
49 *
50 * @since 1.4.6
51 * @version 1.5.4 Access changed to public.
52 * @version 1.8.0 Added the 'render_campaign_builder_notice' notice.
53 * @version 1.8.1 Added 'render_dashboard_reporting_notice' and 'dismiss_dashboard_reporting_notice'. Removed 'render_campaign_builder_notice' notice.
54 * @version 1.8.1.12 Added 'render_license_expiring_banner'.
55 *
56 * @return void
57 */
58 public function __construct() {
59 $this->load_notices();
60
61 add_action( 'admin_notices', array( $this, 'render_upgrade_banner' ) );
62 add_action( 'admin_notices', array( $this, 'render_license_expiring_banner' ) );
63 add_action( 'admin_notices', array( $this, 'render_license_expired_banner' ) );
64 add_action( 'admin_notices', array( $this, 'render_five_star_rating' ) );
65 add_action( 'admin_notices', array( $this, 'render_square_connection_error' ) );
66 add_action( 'admin_notices', array( $this, 'render_paypal_account_type_required_notice' ) );
67 add_action( 'charitable_dismiss_notice', array( $this, 'dismiss_five_star_notice' ), 10, 1 );
68 add_action( 'charitable_dismiss_notice', array( $this, 'dismiss_campaign_builder_notice' ), 10, 1 );
69 add_action( 'charitable_dismiss_notice', array( $this, 'dismiss_dashboard_reporting_notice' ), 10, 1 );
70 add_action( 'charitable_dismiss_notice', array( $this, 'dismiss_square_connection_error_notice' ), 10, 1 );
71 add_filter( 'charitable_localized_javascript_vars', array( $this, 'render_campaign_upgrade_banner_html' ), 10, 1 );
72 }
73
74 /**
75 * Adds a notice message.
76 *
77 * @since 1.4.6
78 *
79 * @param string $message The message to display.
80 * @param string $type The type of notice. Accepts 'error', 'warning', 'success', 'info', 'version'.
81 * @param string $key Optional. If not set, next numeric key is used.
82 * @param boolean $dismissible Optional. Whether the notice can be dismissed. Defaults to false.
83 * @return void
84 */
85 public function add_notice( $message, $type, $key = false, $dismissible = false ) {
86 if ( false === $key ) {
87 $this->notices[ $type ][] = array(
88 'message' => $message,
89 'dismissible' => $dismissible,
90 );
91 } else {
92 $this->notices[ $type ][ $key ] = array(
93 'message' => $message,
94 'dismissible' => $dismissible,
95 );
96 }
97 }
98
99 /**
100 * Adds an error message.
101 *
102 * @since 1.4.6
103 *
104 * @param string $message The message to display.
105 * @param string $key Optional. If not set, next numeric key is used.
106 * @param boolean $dismissible Optional. Set to true by default.
107 * @return void
108 */
109 public function add_error( $message, $key = false, $dismissible = false ) {
110 $this->add_notice( $message, 'error', $key, $dismissible );
111 }
112
113 /**
114 * Adds a warning message.
115 *
116 * @since 1.4.6
117 *
118 * @param string $message The message to display.
119 * @param string $key Optional. If not set, next numeric key is used.
120 * @param boolean $dismissible Optional. Set to true by default.
121 * @return void
122 */
123 public function add_warning( $message, $key = false, $dismissible = false ) {
124 $this->add_notice( $message, 'warning', $key, $dismissible );
125 }
126
127 /**
128 * Adds a success message.
129 *
130 * @since 1.4.6
131 *
132 * @param string $message The message to display.
133 * @param string $key Optional. If not set, next numeric key is used.
134 * @param boolean $dismissible Optional. Set to true by default.
135 * @return void
136 */
137 public function add_success( $message, $key = false, $dismissible = false ) {
138 $this->add_notice( $message, 'success', $key, $dismissible );
139 }
140
141 /**
142 * Adds an info message.
143 *
144 * @since 1.4.6
145 *
146 * @param string $message The message to display.
147 * @param string $key Optional. If not set, next numeric key is used.
148 * @param boolean $dismissible Optional. Set to true by default.
149 * @return void
150 */
151 public function add_info( $message, $key = false, $dismissible = false ) {
152 $this->add_notice( $message, 'info', $key, $dismissible );
153 }
154
155 /**
156 * Adds a version update message.
157 *
158 * @since 1.4.6
159 *
160 * @param string $message The message to display.
161 * @param string $key Optional. If not set, next numeric key is used.
162 * @param boolean $dismissible Optional. Set to true by default.
163 * @return void
164 */
165 public function add_version_update( $message, $key = false, $dismissible = true ) {
166 $this->add_notice( $message, 'version', $key, $dismissible );
167 }
168
169 /**
170 * Adds a third party warning message.
171 *
172 * @since 1.7.0.8
173 *
174 * @param string $message The message to display.
175 * @param string $key Optional. If not set, next numeric key is used.
176 * @param boolean $dismissible Optional. Set to true by default.
177 * @return void
178 */
179 public function add_third_party_warning( $message, $key = false, $dismissible = true ) {
180 $this->add_notice( $message, 'warning', $key, $dismissible );
181 }
182
183 /**
184 * Render notices.
185 *
186 * @since 1.4.6
187 *
188 * @return void
189 */
190 public function render() {
191 foreach ( charitable_get_admin_notices()->get_notices() as $type => $notices ) {
192 foreach ( $notices as $key => $notice ) {
193 if ( ! empty( $notice['message'] ) ) {
194 $this->render_notice( $notice['message'], $type, $notice['dismissible'], $key );
195 }
196 }
197 }
198 }
199
200 /**
201 * Render a notice.
202 *
203 * @since 1.4.6
204 *
205 * @param string $notice The notice message.
206 * @param string $type The type of notice. Accepts 'error', 'warning', 'success', 'info', 'version'.
207 * @param boolean $dismissible Optional. Whether the notice can be dismissed. Defaults to false.
208 * @param string $notice_key Optional. If set, the notice will be dismissed when the user dismisses the notice.
209 * @param boolean $paragraph_tags Optional. Whether to wrap the notice in paragraph tags. Defaults to true.
210 * @return void
211 */
212 public function render_notice( $notice, $type, $dismissible = false, $notice_key = '', $paragraph_tags = true ) {
213 if ( ! isset( $this->script_enqueued ) ) {
214 if ( ! wp_script_is( 'charitable-admin-notice' ) ) {
215 wp_enqueue_script( 'charitable-admin-notice' );
216 }
217
218 $this->script_enqueued = true;
219 }
220
221 $class = 'notice charitable-notice';
222
223 switch ( $type ) {
224 case 'error':
225 $class .= ' notice-error';
226 break;
227
228 case 'warning':
229 $class .= ' notice-warning';
230 break;
231
232 case 'success':
233 $class .= ' updated';
234 break;
235
236 case 'info':
237 $class .= ' notice-info';
238 break;
239
240 case 'five-star-review':
241 $class .= ' notice-info notice-five-star-review';
242 break;
243
244 case 'version':
245 $class .= ' charitable-upgrade-notice';
246 break;
247 }
248
249 if ( $dismissible ) {
250 $class .= ' is-dismissible';
251 }
252
253 $body_text = ( $paragraph_tags ) ? '<p>%s</p>' : '%s';
254
255 printf(
256 '<div class="%s" %s>' . wp_kses_post( $body_text ) . '</div>',
257 esc_attr( $class ),
258 strlen( $notice_key ) ? 'data-notice="' . esc_attr( $notice_key ) . '"' : '',
259 wp_kses_post( $notice )
260 );
261
262 if ( strlen( $notice_key ) ) {
263 unset( $this->notices[ $type ][ $notice_key ] );
264 }
265 }
266
267 /**
268 * Render a lite to pro banner
269 *
270 * @since 1.7.0
271 */
272 public function render_upgrade_banner() {
273 if ( charitable_is_pro() ) {
274 return;
275 }
276 $screen = get_current_screen();
277 if ( ! is_null( $screen ) && ( in_array( $screen->id, charitable_get_charitable_screens() ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
278 $banner = get_transient( 'charitable_charitablelitetopro_banner' );
279 if ( ! $banner ) {
280 $utm_link = charitable_pro_upgrade_url( 'Upgrade From Lite Top Banner Link', 'To unlock more features consider upgrading to Pro.' );
281 $this->render_banner(
282 'You\'re using Charitable Lite! To unlock more features consider <a href="' . $utm_link . '" target="_blank" rel="noopener noreferrer">upgrading to Pro</a>.
283 ',
284 'top-of-page',
285 true
286 );
287 }
288 }
289 }
290
291 /**
292 * Render a license soon-to-be-expired banner.
293 *
294 * @since 1.8.1.12
295 */
296 public function render_license_expiring_banner() {
297
298 if ( ! charitable_is_pro() || ! class_exists( 'Charitable_Licenses_Settings' ) || ! class_exists( 'Charitable_Addons_Directory' ) ) {
299 // This should only show if the user has a license already entered.
300 return;
301 }
302
303 $is_legacy = Charitable_Addons_Directory::is_current_plan_legacy();
304 if ( $is_legacy ) {
305 return;
306 }
307
308 // Is the license expiring within 14 days?
309 $is_license_expiring = Charitable_Licenses_Settings::get_instance()->is_license_expiring( 1209600 );
310
311 if ( $is_license_expiring ) {
312 $screen = get_current_screen();
313 if ( ! is_null( $screen ) && ( in_array( $screen->id, charitable_get_charitable_screens(), true ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
314 $banner = get_transient( 'charitable_expiringlicense_banner' );
315 if ( ! $banner ) {
316 $this->render_banner(
317 'Your Charitable license may be expiring soon. <a href="' . admin_url( 'admin.php?page=charitable-settings&tab=general&warning=license-expire' ) . '" target="_blank" rel="noopener noreferrer">View license settings</a> to ensure support and updates are not interrupted.
318 ',
319 'top-of-page',
320 true,
321 'expiringlicense',
322 'expiringlicense',
323 false,
324 'charitable-license-expiring-banner'
325 );
326 }
327 }
328 }
329 }
330
331 /**
332 * Render a license soon-to-be-expired banner.
333 *
334 * @since 1.8.1.12
335 */
336 public function render_license_expired_banner() {
337 if ( ! charitable_is_pro() || ! class_exists( 'Charitable_Licenses_Settings' ) || ! class_exists( 'Charitable_Addons_Directory' ) ) {
338 // This should only show if the user has a license already entered.
339 return;
340 }
341
342 $is_legacy = Charitable_Addons_Directory::is_current_plan_legacy();
343 if ( $is_legacy ) {
344 return;
345 }
346
347 // Is the license expiring within 14 days?
348 $is_license_expired = Charitable_Licenses_Settings::get_instance()->is_license_expired();
349
350 if ( $is_license_expired ) {
351 $screen = get_current_screen();
352 if ( ! is_null( $screen ) && ( in_array( $screen->id, charitable_get_charitable_screens(), true ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
353 $banner = get_transient( 'charitable_expiredlicense_banner' );
354 if ( ! $banner ) {
355 $this->render_banner(
356 'Your Charitable license may have expired. <a href="' . admin_url( 'admin.php?page=charitable-settings&tab=general&warning=license-expire' ) . '" target="_blank" rel="noopener noreferrer">View license settings</a> to ensure support and updates are not interrupted.
357 ',
358 'top-of-page',
359 true,
360 'expiredlicense',
361 'expiredlicense',
362 false,
363 'charitable-license-expiring-banner'
364 );
365 }
366 }
367 }
368 }
369
370 /**
371 * Render a lite to pro banner in campaign lists, add it to the charitable admin vars so it can be injected via JS.
372 *
373 * @param array $strings The localized strings.
374 *
375 * @since 1.8.0
376 */
377 public function render_campaign_upgrade_banner_html( $strings = false ) {
378 if ( charitable_is_pro() ) {
379 return $strings;
380 }
381 $screen = get_current_screen();
382 if ( ! is_null( $screen ) && isset( $screen->base ) && 'edit' === $screen->base && isset( $screen->id ) && 'edit-campaign' === $screen->id ) {
383 $banner = get_transient( 'charitable_charitable_ltp_lb_list_banner' );
384 if ( ! $banner ) {
385 $nonce = wp_create_nonce( 'charitable_dismiss_list_banner' );
386 $banner_text = '<p><strong>Unlock More Donations with Peer-to-Peer Fundraising!</strong><br/>Harness the power of supporter networks and friends to reach more people and raise more money for your cause.</p>';
387 $strings['banner'] = sprintf(
388 '<div data-id="charitable_ltp_lb" data-nonce="%1$s" class="charitable-campaign-list-banner">' .
389 '<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>' .
390 '<div class="charitable-campaign-list-banner-icon-text">' .
391 '<div class="charitable-campaign-list-banner-icon"><img src="%2$s" /></div>' .
392 '<div class="charitable-campaign-list-banner-text">%3$s</div>' .
393 '</div>' .
394 '<div class="charitable-campaign-list-banner-button"><a class="button-link" href="#">Learn More</a></div>' .
395 '</div>',
396 $nonce,
397 charitable()->get_path( 'assets', false ) . 'images/icons/ambassador.png',
398 $banner_text
399 );
400 } else {
401 $strings['banner'] = '';
402 }
403 }
404
405 return $strings;
406 }
407
408 /**
409 * Render a prompt to ask for a five star rating.
410 *
411 * @since 1.7.0
412 */
413 public function render_five_star_rating() {
414
415 if ( ! function_exists( 'get_current_screen' ) ) {
416 return;
417 }
418
419 // Dashboard has its own inline version of this notice — skip the top-bar one.
420 $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
421 if ( 'charitable-dashboard' === $page ) {
422 return;
423 }
424
425 $screen = get_current_screen();
426
427 // determine if we are on the current screen.
428 if ( ! is_null( $screen ) && ( in_array( $screen->id, charitable_get_charitable_screens() ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
429
430 $slug = 'five-star-review';
431
432 // determine when to display this message. for now, there should be some sensible boundaries before showing the notification: a minimum of 14 days of use, created one donation form and received at least one donation.
433 $activated_datetime = ( false !== get_option( 'wpcharitable_activated_datetime' ) ) ? get_option( 'wpcharitable_activated_datetime' ) : false;
434 $days = 0;
435 if ( $activated_datetime ) {
436 $diff = current_time( 'timestamp' ) - $activated_datetime; // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested
437 $days = abs( round( $diff / 86400 ) );
438 }
439
440 $count_campaigns = wp_count_posts( 'campaign' );
441 $total_campaigns = isset( $count_campaigns->publish ) ? $count_campaigns->publish : 0;
442 $count_donations = wp_count_posts( 'donation' );
443 $total_donations = isset( $count_donations->{'charitable-completed'} ) ? $count_donations->{'charitable-completed'} : 0;
444
445 if ( $days >= apply_filters( 'charitable_days_since_activated', 14 ) && $total_campaigns >= 1 && $total_donations >= 1 ) {
446 // check transient.
447 $star_review = get_transient( 'charitable_' . $slug . '_banner' );
448
449 // render five star rating banner/notice.
450 if ( ! $star_review ) {
451 $message = charitable_admin_view( 'notices/admin-notice-five-star-review', array(), true );
452 $key = 'five-star-review';
453 $this->render_notice( $message, 'five-star-review', true, $key, false );
454 }
455 }
456 }
457 }
458
459 /**
460 * Render a notice when the Square connection fails.
461 *
462 * @since 1.8.7
463 */
464 public function render_square_connection_error() {
465
466 $admin_notice = get_option( 'charitable_square_connection_error_notice' );
467
468 if ( false === $admin_notice ) {
469 return;
470 }
471
472 $message = charitable_admin_view( 'notices/admin-notice-square-connection-error', array( 'message' => $admin_notice['message'], 'status_code' => $admin_notice['status_code'] ), true ); // phpcs:ignore
473 $key = 'square-connection-error';
474 $this->render_notice( $message, 'error', true, $key, false );
475 }
476
477 /**
478 * Render a persistent banner across all Charitable admin screens when
479 * the PayPal Commerce gateway is connected but the merchant has not
480 * yet chosen an Account Type (Nonprofit vs Business).
481 *
482 * Per the 1.8.12 spec (B-strict default-handling) this banner is
483 * intentionally NOT dismissible — the underlying state blocks
484 * donations at validate_donation(), so dismissing the banner without
485 * resolving the setting would mask broken donation processing from
486 * the merchant. The banner persists until the setting is saved.
487 *
488 * @since 1.8.12
489 *
490 * @return void
491 */
492 public function render_paypal_account_type_required_notice() {
493 // Gate behind manage_options. The notice exposes gateway
494 // configuration state and links to the settings page; only users
495 // who can actually fix it should see it.
496 if ( ! current_user_can( 'manage_options' ) ) {
497 return;
498 }
499
500 // Only fire on Charitable admin screens to avoid leaking into
501 // unrelated plugins' admin contexts.
502 $screen = get_current_screen();
503 if ( is_null( $screen ) || ! in_array( $screen->id, charitable_get_charitable_screens(), true ) ) {
504 return;
505 }
506
507 if ( ! class_exists( 'Charitable_Gateway_Paypal_Commerce' ) ) {
508 return;
509 }
510
511 // Only fire when PayPal Commerce is actually an enabled gateway.
512 // Stale merchant ID meta can survive from a prior connected session
513 // even after the gateway is disabled in Settings > Payment Gateways;
514 // without this check the notice would scold merchants who are not
515 // using the gateway at all, and the deep-link target (the
516 // gateways_paypal_commerce settings group) is not even registered
517 // when the gateway is off, so clicking the notice's CTA would
518 // bounce them to the gateway list page instead.
519 $gateways = charitable_get_helper( 'gateways' );
520 if ( ! $gateways || ! $gateways->is_active_gateway( Charitable_Gateway_Paypal_Commerce::ID ) ) {
521 return;
522 }
523
524 $gateway = new Charitable_Gateway_Paypal_Commerce();
525
526 // Only relevant for sites that have actually connected PayPal
527 // Commerce. A disconnected gateway has nothing to gate.
528 if ( ! $gateway->is_seller_connected() ) {
529 return;
530 }
531
532 if ( $gateway->is_account_type_configured() ) {
533 return;
534 }
535
536 $settings_url = admin_url( 'admin.php?page=charitable-settings&tab=gateways&group=gateways_paypal_commerce' );
537 $message = sprintf(
538 /* translators: %s: settings URL */
539 __( '<strong>PayPal Commerce: Action Required.</strong> Donations are currently blocked because your Account Type has not been set. <a href="%s">Choose Nonprofit or Business</a> on the PayPal Commerce settings page to resume accepting donations.', 'charitable' ),
540 esc_url( $settings_url )
541 );
542
543 echo '<div class="notice notice-error" style="border-left-width:4px;"><p>' . wp_kses(
544 $message,
545 array(
546 'strong' => array(),
547 'a' => array(
548 'href' => array(),
549 ),
550 )
551 ) . '</p></div>';
552 }
553
554 /**
555 * Render a banner to promote the new campaign builder in version 1.8.0.
556 * This was removed in 1.8.1 in favor of the updated notice render_dashboard_reporting_notice.
557 *
558 * @since 1.8.0
559 */
560 public function render_campaign_builder_notice() {
561
562 if ( ! function_exists( 'get_current_screen' ) ) {
563 return;
564 }
565
566 $screen = get_current_screen();
567
568 // determine if we are on the current screen.
569 if ( ! is_null( $screen ) && ( in_array( $screen->id, charitable_get_charitable_screens() ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
570
571 $slug = 'campaign-builder';
572
573 // check transient.
574 $builder_notice = get_transient( 'charitable_' . $slug . '_banner' );
575
576 // render banner/notice.
577 if ( ! $builder_notice ) {
578 $message = charitable_admin_view( 'notices/admin-notice-campaign-builder', array(), true );
579 $key = 'campaign-builder';
580 $this->render_notice( $message, 'campaign-builder', true, $key, false );
581 }
582 }
583 }
584
585 /**
586 * Render a banner to promote
587 *
588 * @since 1.8.1
589 * @version 1.8.1.10
590 * @version 1.8.2 deprecated.
591 */
592 public function render_dashboard_reporting_notice() {
593
594 if ( ! function_exists( 'get_current_screen' ) ) {
595 return;
596 }
597
598 $screen = get_current_screen();
599
600 // determine if we are on the current screen.
601 if ( ! is_null( $screen ) && ( in_array( $screen->id, charitable_get_charitable_screens() ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
602
603 $slug = 'dashboard-reporting';
604
605 // determine when to display this message. for now, there should be some sensible boundaries before showing the notification: a minimum of 10 days of use.
606 $activated_datetime = ( false !== get_option( 'wpcharitable_activated_datetime' ) ) ? get_option( 'wpcharitable_activated_datetime' ) : false;
607 $days = 0;
608 if ( $activated_datetime ) {
609 $diff = current_time( 'timestamp' ) - $activated_datetime; // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested
610 $days = abs( round( $diff / 86400 ) );
611 }
612
613 if ( $days >= apply_filters( 'charitable_days_since_activated', 10, $slug ) ) {
614 // check transient.
615 $builder_notice = get_transient( 'charitable_' . $slug . '_banner' );
616
617 // render banner/notice.
618 if ( ! $builder_notice ) {
619 $message = charitable_admin_view( 'notices/admin-notice-dashboard-reporting', array(), true );
620 $key = 'dashboard-reporting';
621 $this->render_notice( $message, 'dashboard-reporting', true, $key, false );
622 }
623 }
624 }
625 }
626
627 /**
628 * Dismiss review request.
629 *
630 * @since 1.8.0
631 * @param array $postdata $_POST data.
632 */
633 public function dismiss_five_star_notice( $postdata ) {
634
635 if ( empty( $postdata['notice'] ) || 'five-star-review' !== $postdata['notice'] ) {
636 return;
637 }
638
639 $slug = 'five-star-review';
640
641 set_transient( 'charitable_' . $slug . '_banner', 1, 0 );
642 }
643
644 /**
645 * Dismiss the new campaign builder notice. Deprecated in 1.8.1.
646 *
647 * @since 1.8.0
648 * @param array $postdata $_POST data.
649 */
650 public function dismiss_campaign_builder_notice( $postdata ) {
651
652 if ( empty( $postdata['notice'] ) || 'campaign-builder' !== $postdata['notice'] ) {
653 return;
654 }
655
656 $slug = 'campaign-builder';
657
658 set_transient( 'charitable_' . $slug . '_banner', 1, 0 );
659 }
660
661 /**
662 * Dismiss the new campaign builder notice.
663 *
664 * @since 1.8.1
665 * @param array $postdata $_POST data.
666 */
667 public function dismiss_dashboard_reporting_notice( $postdata ) {
668
669 if ( empty( $postdata['notice'] ) || 'dashboard-reporting' !== $postdata['notice'] ) {
670 return;
671 }
672
673 $slug = 'dashboard-reporting';
674
675 set_transient( 'charitable_' . $slug . '_banner', 1, 0 );
676 }
677
678 /**
679 * Dismiss the Square connection error notice.
680 *
681 * @since 1.8.7
682 * @param array $postdata $_POST data.
683 */
684 public function dismiss_square_connection_error_notice( $postdata ) {
685 if ( empty( $postdata['notice'] ) || 'square-connection-error' !== $postdata['notice'] ) {
686 return;
687 }
688
689 delete_option( 'charitable_square_connection_error_notice' );
690 wp_send_json_success();
691 exit;
692 }
693
694 /**
695 * Render a banner.
696 *
697 * @since 1.7.0
698 * @version 1.8.1.12 Added css_class.
699 *
700 * @param string $message The message to display.
701 * @param string $type The type of notice. Accepts 'top-of-page'.
702 * @param boolean $dismissible Optional. Whether the notice can be dismissed. Defaults to false.
703 * @param mixed $data_nonce Optional. The nonce to use for the notice.
704 * @param mixed $data_id Optional. The id to use for the notice.
705 * @param string $data_lifespan Optional. The lifespan of the notice.
706 * @param string $additional_css_class Optional. The CSS class to use for the notice.
707 *
708 * @return void
709 */
710 public function render_banner( $message, $type = 'top-of-page', $dismissible = false, $data_nonce = 'charitablelitetopro', $data_id = 'charitablelitetopro', $data_lifespan = false, $additional_css_class = '' ) {
711 if ( ! isset( $this->script_enqueued ) ) {
712 if ( ! wp_script_is( 'charitable-admin-notice' ) ) {
713 wp_enqueue_script( 'charitable-admin-notice' );
714 }
715
716 $this->script_enqueued = true;
717 }
718
719 $css_class = trim( 'charitable-banner ' . $additional_css_class );
720
721 switch ( $type ) {
722 case 'top-of-page':
723 $css_class .= ' charitable-admin-banner-top-of-page';
724 break;
725 }
726
727 if ( $dismissible ) { // phpcs:ignore
728 // $class .= ' is-dismissible';
729 }
730
731 printf(
732 '<div class="%s" %s %s %s>%s <button type="button" class="button-link charitable-banner-dismiss">x</button></div>',
733 esc_attr( $css_class ),
734 strlen( $data_nonce ) ? 'data-notice="' . esc_attr( $data_nonce ) . '"' : '',
735 strlen( $data_id ) ? 'data-id="' . esc_attr( $data_id ) . '"' : '',
736 strlen( $data_lifespan ) ? 'data-lifespan="' . esc_attr( $data_lifespan ) . '"' : '',
737 wp_kses_post( $message )
738 );
739 }
740
741
742 /**
743 * When PHP finishes executing, stash any notices that haven't been rendered yet.
744 *
745 * @since 1.4.13
746 *
747 * @return void
748 */
749 public function shutdown() {
750 if ( charitable_is_debug( 'square' ) ) {
751 // phpcs:disable
752 error_log( 'Saving admin notices to transient' );
753 error_log( 'Notices to save: ' . print_r( $this->notices, true ) );
754 // phpcs:enable
755 }
756
757 set_transient( 'charitable_notices', $this->notices );
758 }
759
760 /**
761 * Load the notices array.
762 *
763 * If there are any stuffed in a transient, pull those out. Otherwise, reset a clear array.
764 *
765 * @since 1.4.13
766 *
767 * @return void
768 */
769 public function load_notices() {
770 $this->notices = get_transient( 'charitable_notices' );
771
772 if ( ! is_array( $this->notices ) ) {
773 $this->clear();
774 }
775 }
776
777 /**
778 * Fill admin notices from the front-end notices array.
779 *
780 * @since 1.6.24
781 *
782 * @return void
783 */
784 public function fill_notices_from_frontend() {
785 $notices = charitable_get_notices();
786
787 foreach ( $notices->get_notices() as $type => $type_notices ) {
788 foreach ( $type_notices as $notice ) {
789 $this->add_notice( $notice, $type );
790 }
791 }
792
793 $notices->clear();
794 }
795
796 /**
797 * Clear out all existing notices.
798 *
799 * @since 1.4.6
800 *
801 * @return void
802 */
803 public function clear() {
804 $clear = array(
805 'error' => array(),
806 'warning' => array(),
807 'success' => array(),
808 'info' => array(),
809 'version' => array(),
810 );
811
812 $this->notices = $clear;
813 }
814
815 /**
816 * Returns an array of screen IDs where the Charitable notices should be displayed.
817 * (Deprecated in 1.8.1.15)
818 *
819 * @uses charitable_admin_screens
820 *
821 * @since 1.7.0
822 * @since 1.8.1 Added the Charitable reports page.
823 * @since 1.8.1.6 Added the Charitable tools and guide tools page.
824 * @since 1.8.5 Added the Charitable donors page.
825 * @return array
826 */
827 public function get_charitable_screens() {
828 /**
829 * Filter admin screens where Charitable styles & scripts should be loaded.
830 *
831 * @since 1.7.0
832 *
833 * @param string[] $screens List of screen ids.
834 */
835 return apply_filters(
836 'charitable_admin_notice_screens',
837 array(
838 'campaign',
839 'donation',
840 'charitable_page_charitable-settings',
841 'charitable_page_charitable-tools',
842 'charitable_page_charitable-growth-tools',
843 'charitable_page_charitable-reports',
844 'charitable_page_charitable-dashboard',
845 'edit-campaign',
846 'edit-donation',
847 'toplevel_page_charitable',
848 'charitable_page_charitable-addons',
849 'charitable_page_charitable-donors',
850 )
851 );
852 }
853 }
854
855 endif;
856