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 +464 -57 1.7.0.9 → 1.8.13 View file →
@@ -3,9 +3,9 @@
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 6 * @author David Bisset
7 - * @copyright Copyright (c) 2022, WP Charitable LLC
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,16 +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();
55 60
56 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' ) );
57 64 add_action( 'admin_notices', array( $this, 'render_five_star_rating' ) );
58 -
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 );
59 72 }
60 73
61 74 /**
62 75 * Adds a notice message.
@@ -62,11 +75,12 @@
62 75 * Adds a notice message.
63 76 *
64 77 * @since 1.4.6
65 78 *
66 - * @param string $message
67 - * @param string $type
68 - * @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.
69 83 * @return void
70 84 */
71 85 public function add_notice( $message, $type, $key = false, $dismissible = false ) {
72 86 if ( false === $key ) {
@@ -86,10 +100,11 @@
86 100 * Adds an error message.
87 101 *
88 102 * @since 1.4.6
89 103 *
90 - * @param string $message
91 - * @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.
92 107 * @return void
93 108 */
94 109 public function add_error( $message, $key = false, $dismissible = false ) {
95 110 $this->add_notice( $message, 'error', $key, $dismissible );
@@ -99,10 +114,11 @@
99 114 * Adds a warning message.
100 115 *
101 116 * @since 1.4.6
102 117 *
103 - * @param string $message
104 - * @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.
105 121 * @return void
106 122 */
107 123 public function add_warning( $message, $key = false, $dismissible = false ) {
108 124 $this->add_notice( $message, 'warning', $key, $dismissible );
@@ -112,10 +128,11 @@
112 128 * Adds a success message.
113 129 *
114 130 * @since 1.4.6
115 131 *
116 - * @param string $message
117 - * @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.
118 135 * @return void
119 136 */
120 137 public function add_success( $message, $key = false, $dismissible = false ) {
121 138 $this->add_notice( $message, 'success', $key, $dismissible );
@@ -125,10 +142,11 @@
125 142 * Adds an info message.
126 143 *
127 144 * @since 1.4.6
128 145 *
129 - * @param string $message
130 - * @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.
131 149 * @return void
132 150 */
133 151 public function add_info( $message, $key = false, $dismissible = false ) {
134 152 $this->add_notice( $message, 'info', $key, $dismissible );
@@ -138,9 +156,9 @@
138 156 * Adds a version update message.
139 157 *
140 158 * @since 1.4.6
141 159 *
142 - * @param string $message
160 + * @param string $message The message to display.
143 161 * @param string $key Optional. If not set, next numeric key is used.
144 162 * @param boolean $dismissible Optional. Set to true by default.
145 163 * @return void
146 164 */
@@ -152,9 +170,9 @@
152 170 * Adds a third party warning message.
153 171 *
154 172 * @since 1.7.0.8
155 173 *
156 - * @param string $message
174 + * @param string $message The message to display.
157 175 * @param string $key Optional. If not set, next numeric key is used.
158 176 * @param boolean $dismissible Optional. Set to true by default.
159 177 * @return void
160 178 */
@@ -171,9 +189,11 @@
171 189 */
172 190 public function render() {
173 191 foreach ( charitable_get_admin_notices()->get_notices() as $type => $notices ) {
174 192 foreach ( $notices as $key => $notice ) {
175 - $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 + }
176 196 }
177 197 }
178 198 }
179 199
@@ -181,12 +201,13 @@
181 201 * Render a notice.
182 202 *
183 203 * @since 1.4.6
184 204 *
185 - * @param string $notice
186 - * @param string $type
187 - * @param boolean $dismissible
188 - * @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.
189 210 * @return void
190 211 */
191 212 public function render_notice( $notice, $type, $dismissible = false, $notice_key = '', $paragraph_tags = true ) {
192 213 if ( ! isset( $this->script_enqueued ) ) {
@@ -228,15 +249,15 @@
228 249 if ( $dismissible ) {
229 250 $class .= ' is-dismissible';
230 251 }
231 252
232 - $body_text = ( $paragraph_tags ) ? '<p>%s</p>': '%s';
253 + $body_text = ( $paragraph_tags ) ? '<p>%s</p>' : '%s';
233 254
234 255 printf(
235 - '<div class="%s" %s>' . $body_text . '</div>',
256 + '<div class="%s" %s>' . wp_kses_post( $body_text ) . '</div>',
236 257 esc_attr( $class ),
237 258 strlen( $notice_key ) ? 'data-notice="' . esc_attr( $notice_key ) . '"' : '',
238 - $notice
259 + wp_kses_post( $notice )
239 260 );
240 261
241 262 if ( strlen( $notice_key ) ) {
242 263 unset( $this->notices[ $type ][ $notice_key ] );
@@ -242,14 +263,12 @@
242 263 unset( $this->notices[ $type ][ $notice_key ] );
243 264 }
244 265 }
245 266
246 -
247 267 /**
248 268 * Render a lite to pro banner
249 269 *
250 270 * @since 1.7.0
251 - *
252 271 */
253 272 public function render_upgrade_banner() {
254 273 if ( charitable_is_pro() ) {
255 274 return;
@@ -254,39 +273,168 @@
254 273 if ( charitable_is_pro() ) {
255 274 return;
256 275 }
257 276 $screen = get_current_screen();
258 - if ( ! is_null( $screen ) && ( in_array( $screen->id, $this->get_charitable_screens() ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
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 ) ) ) {
259 278 $banner = get_transient( 'charitable_charitablelitetopro_banner' );
260 279 if ( ! $banner ) {
261 280 $utm_link = charitable_pro_upgrade_url( 'Upgrade From Lite Top Banner Link', 'To unlock more features consider upgrading to Pro.' );
262 - $this->render_banner('You\'re using WP Charitable Lite. To unlock more features consider <a href="' . $utm_link . '" target="_blank" rel="noopener noreferrer">upgrading to Pro</a>.
263 - ','top-of-page', true);
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 + );
264 287 }
288 + }
289 + }
265 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;
266 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 + }
267 329 }
268 330
269 331 /**
270 - * Render a lite to pro banner
332 + * Render a license soon-to-be-expired banner.
271 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 + *
272 411 * @since 1.7.0
273 - *
274 412 */
275 413 public function render_five_star_rating() {
276 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 +
277 425 $screen = get_current_screen();
278 426
279 427 // determine if we are on the current screen.
280 - if ( ! is_null( $screen ) && ( in_array( $screen->id, $this->get_charitable_screens() ) || ( isset( $screen->taxonomy ) && 'campaign_category' === $screen->taxonomy ) || ( isset( $screen->taxonomy ) && 'campaign_tag' === $screen->taxonomy ) ) ) {
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 ) ) ) {
281 429
282 430 $slug = 'five-star-review';
283 431
284 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.
285 - $activated_datetime = ( false !== get_option( 'wpcharitable_activated_datetime' ) ) ? get_option( 'wpcharitable_activated_datetime' ) : false;
286 - $days = 0;
433 + $activated_datetime = ( false !== get_option( 'wpcharitable_activated_datetime' ) ) ? get_option( 'wpcharitable_activated_datetime' ) : false;
434 + $days = 0;
287 435 if ( $activated_datetime ) {
288 - $diff = current_time( 'timestamp' ) - $activated_datetime;
436 + $diff = current_time( 'timestamp' ) - $activated_datetime; // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested
289 437 $days = abs( round( $diff / 86400 ) );
290 438 }
291 439
292 440 $count_campaigns = wp_count_posts( 'campaign' );
@@ -294,30 +442,273 @@
294 442 $count_donations = wp_count_posts( 'donation' );
295 443 $total_donations = isset( $count_donations->{'charitable-completed'} ) ? $count_donations->{'charitable-completed'} : 0;
296 444
297 445 if ( $days >= apply_filters( 'charitable_days_since_activated', 14 ) && $total_campaigns >= 1 && $total_donations >= 1 ) {
298 - // check transient
446 + // check transient.
299 447 $star_review = get_transient( 'charitable_' . $slug . '_banner' );
300 448
301 - // render five star rating banner/notice
302 - if ( $star_review ) {
303 - $message = charitable_admin_view('notices/admin-notice-five-star-review', array(), true );
449 + // render five star rating banner/notice.
450 + if ( ! $star_review ) {
451 + $message = charitable_admin_view( 'notices/admin-notice-five-star-review', array(), true );
304 452 $key = 'five-star-review';
305 453 $this->render_notice( $message, 'five-star-review', true, $key, false );
306 454 }
455 + }
456 + }
457 + }
307 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 );
308 581 }
582 + }
583 + }
309 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;
310 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 + }
311 625 }
312 626
313 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 + /**
314 695 * Render a banner.
315 696 *
316 697 * @since 1.7.0
698 + * @version 1.8.1.12 Added css_class.
317 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
318 709 */
319 - public function render_banner( $message, $type = 'top-of-page', $dismissible = false, $data_nonce = 'charitablelitetopro', $data_id = 'charitablelitetopro', $data_lifespan = false ) {
710 + public function render_banner( $message, $type = 'top-of-page', $dismissible = false, $data_nonce = 'charitablelitetopro', $data_id = 'charitablelitetopro', $data_lifespan = false, $additional_css_class = '' ) {
320 711 if ( ! isset( $this->script_enqueued ) ) {
321 712 if ( ! wp_script_is( 'charitable-admin-notice' ) ) {
322 713 wp_enqueue_script( 'charitable-admin-notice' );
323 714 }
@@ -324,29 +715,28 @@
324 715
325 716 $this->script_enqueued = true;
326 717 }
327 718
328 - $class = 'charitable-banner';
719 + $css_class = trim( 'charitable-banner ' . $additional_css_class );
329 720
330 721 switch ( $type ) {
331 722 case 'top-of-page':
332 - $class .= ' charitable-admin-banner-top-of-page';
723 + $css_class .= ' charitable-admin-banner-top-of-page';
333 724 break;
334 725 }
335 726
336 - if ( $dismissible ) {
727 + if ( $dismissible ) { // phpcs:ignore
337 728 // $class .= ' is-dismissible';
338 729 }
339 730
340 731 printf(
341 732 '<div class="%s" %s %s %s>%s <button type="button" class="button-link charitable-banner-dismiss">x</button></div>',
342 - esc_attr( $class ),
733 + esc_attr( $css_class ),
343 734 strlen( $data_nonce ) ? 'data-notice="' . esc_attr( $data_nonce ) . '"' : '',
344 735 strlen( $data_id ) ? 'data-id="' . esc_attr( $data_id ) . '"' : '',
345 736 strlen( $data_lifespan ) ? 'data-lifespan="' . esc_attr( $data_lifespan ) . '"' : '',
346 - $message
737 + wp_kses_post( $message )
347 738 );
348 -
349 739 }
350 740
351 741
352 742 /**
@@ -356,8 +746,15 @@
356 746 *
357 747 * @return void
358 748 */
359 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 +
360 757 set_transient( 'charitable_notices', $this->notices );
361 758 }
362 759
363 760 /**
@@ -416,13 +813,16 @@
416 813 }
417 814
418 815 /**
419 816 * Returns an array of screen IDs where the Charitable notices should be displayed.
817 + * (Deprecated in 1.8.1.15)
420 818 *
421 819 * @uses charitable_admin_screens
422 820 *
423 821 * @since 1.7.0
424 - *
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.
425 825 * @return array
426 826 */
427 827 public function get_charitable_screens() {
428 828 /**
@@ -431,18 +831,25 @@
431 831 * @since 1.7.0
432 832 *
433 833 * @param string[] $screens List of screen ids.
434 834 */
435 - return apply_filters( 'charitable_admin_notice_screens', array(
436 - 'campaign',
437 - 'donation',
438 - 'charitable_page_charitable-settings',
439 - 'edit-campaign',
440 - 'edit-donation',
441 - 'toplevel_page_charitable',
442 - 'charitable_page_charitable-addons'
443 - ) );
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 + );
444 852 }
445 -
446 853 }
447 854
448 855 endif;