PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
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
← All changes | includes/admin/class-charitable-admin-notices.php +589 -23 1.6.60 → 1.8.13 View file →
@@ -2,10 +2,10 @@
2 2 /**
3 3 * Contains the class that is used to register and retrieve notices in the admin like errors, warnings, success messages, etc.
4 4 *
5 5 * @package Charitable/Classes/Charitable_Admin_Notices
6 - * @author Eric Daams
7 - * @copyright Copyright (c) 2022, Studio 164a
6 + * @author David Bisset
7 + * @copyright Copyright (c) 2023, WP Charitable LLC
8 8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 9 * @since 1.4.6
10 10 * @version 1.6.24
11 11 */
@@ -47,12 +47,29 @@
47 47 /**
48 48 * Create class object. A private constructor, so this is used in a singleton context.
49 49 *
50 50 * @since 1.4.6
51 - * @since 1.5.4 Access changed to public.
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
52 57 */
53 58 public function __construct() {
54 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 );
55 72 }
56 73
57 74 /**
58 75 * Adds a notice message.
@@ -58,11 +75,12 @@
58 75 * Adds a notice message.
59 76 *
60 77 * @since 1.4.6
61 78 *
62 - * @param string $message
63 - * @param string $type
64 - * @param string $key Optional. If not set, next numeric key is used.
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.
65 83 * @return void
66 84 */
67 85 public function add_notice( $message, $type, $key = false, $dismissible = false ) {
68 86 if ( false === $key ) {
@@ -82,10 +100,11 @@
82 100 * Adds an error message.
83 101 *
84 102 * @since 1.4.6
85 103 *
86 - * @param string $message
87 - * @param string $key Optional. If not set, next numeric key is used.
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.
88 107 * @return void
89 108 */
90 109 public function add_error( $message, $key = false, $dismissible = false ) {
91 110 $this->add_notice( $message, 'error', $key, $dismissible );
@@ -95,10 +114,11 @@
95 114 * Adds a warning message.
96 115 *
97 116 * @since 1.4.6
98 117 *
99 - * @param string $message
100 - * @param string $key Optional. If not set, next numeric key is used.
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.
101 121 * @return void
102 122 */
103 123 public function add_warning( $message, $key = false, $dismissible = false ) {
104 124 $this->add_notice( $message, 'warning', $key, $dismissible );
@@ -108,10 +128,11 @@
108 128 * Adds a success message.
109 129 *
110 130 * @since 1.4.6
111 131 *
112 - * @param string $message
113 - * @param string $key Optional. If not set, next numeric key is used.
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.
114 135 * @return void
115 136 */
116 137 public function add_success( $message, $key = false, $dismissible = false ) {
117 138 $this->add_notice( $message, 'success', $key, $dismissible );
@@ -121,10 +142,11 @@
121 142 * Adds an info message.
122 143 *
123 144 * @since 1.4.6
124 145 *
125 - * @param string $message
126 - * @param string $key Optional. If not set, next numeric key is used.
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.
127 149 * @return void
128 150 */
129 151 public function add_info( $message, $key = false, $dismissible = false ) {
130 152 $this->add_notice( $message, 'info', $key, $dismissible );
@@ -134,9 +156,9 @@
134 156 * Adds a version update message.
135 157 *
136 158 * @since 1.4.6
137 159 *
138 - * @param string $message
160 + * @param string $message The message to display.
139 161 * @param string $key Optional. If not set, next numeric key is used.
140 162 * @param boolean $dismissible Optional. Set to true by default.
141 163 * @return void
142 164 */
@@ -144,8 +166,22 @@
144 166 $this->add_notice( $message, 'version', $key, $dismissible );
145 167 }
146 168
147 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 + /**
148 184 * Render notices.
149 185 *
150 186 * @since 1.4.6
151 187 *
@@ -153,9 +189,11 @@
153 189 */
154 190 public function render() {
155 191 foreach ( charitable_get_admin_notices()->get_notices() as $type => $notices ) {
156 192 foreach ( $notices as $key => $notice ) {
157 - $this->render_notice( $notice['message'], $type, $notice['dismissible'], $key );
193 + if ( ! empty( $notice['message'] ) ) {
194 + $this->render_notice( $notice['message'], $type, $notice['dismissible'], $key );
195 + }
158 196 }
159 197 }
160 198 }
161 199
@@ -163,15 +201,16 @@
163 201 * Render a notice.
164 202 *
165 203 * @since 1.4.6
166 204 *
167 - * @param string $notice
168 - * @param string $type
169 - * @param boolean $dismissible
170 - * @param string $notice_key
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.
171 210 * @return void
172 211 */
173 - public function render_notice( $notice, $type, $dismissible = false, $notice_key = '' ) {
212 + public function render_notice( $notice, $type, $dismissible = false, $notice_key = '', $paragraph_tags = true ) {
174 213 if ( ! isset( $this->script_enqueued ) ) {
175 214 if ( ! wp_script_is( 'charitable-admin-notice' ) ) {
176 215 wp_enqueue_script( 'charitable-admin-notice' );
177 216 }
@@ -197,8 +236,12 @@
197 236 case 'info':
198 237 $class .= ' notice-info';
199 238 break;
200 239
240 + case 'five-star-review':
241 + $class .= ' notice-info notice-five-star-review';
242 + break;
243 +
201 244 case 'version':
202 245 $class .= ' charitable-upgrade-notice';
203 246 break;
204 247 }
@@ -206,13 +249,15 @@
206 249 if ( $dismissible ) {
207 250 $class .= ' is-dismissible';
208 251 }
209 252
253 + $body_text = ( $paragraph_tags ) ? '<p>%s</p>' : '%s';
254 +
210 255 printf(
211 - '<div class="%s" %s><p>%s</p></div>',
256 + '<div class="%s" %s>' . wp_kses_post( $body_text ) . '</div>',
212 257 esc_attr( $class ),
213 258 strlen( $notice_key ) ? 'data-notice="' . esc_attr( $notice_key ) . '"' : '',
214 - $notice
259 + wp_kses_post( $notice )
215 260 );
216 261
217 262 if ( strlen( $notice_key ) ) {
218 263 unset( $this->notices[ $type ][ $notice_key ] );
@@ -219,8 +264,483 @@
219 264 }
220 265 }
221 266
222 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 + /**
223 743 * When PHP finishes executing, stash any notices that haven't been rendered yet.
224 744 *
225 745 * @since 1.4.13
226 746 *
@@ -226,8 +746,15 @@
226 746 *
227 747 * @return void
228 748 */
229 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 +
230 757 set_transient( 'charitable_notices', $this->notices );
231 758 }
232 759
233 760 /**
@@ -282,8 +809,47 @@
282 809 'version' => array(),
283 810 );
284 811
285 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 + );
286 852 }
287 853 }
288 854
289 855 endif;