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
charitable / includes / admin / dashboard / class-charitable-dashboard-legacy.php

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

1,529 lines 49.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Charitable Dashboard UI.
4 *
5 * @package Charitable/Classes/Charitable_Dashboard
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.8.1
10 * @version 1.8.1
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Dashboard_Legacy' ) ) :
19
20 /**
21 * Charitable_Dashboard_Legacy
22 *
23 * @final
24 * @since 1.8.1
25 */
26 final class Charitable_Dashboard_Legacy {
27
28 /**
29 * The single instance of this class.
30 *
31 * @var Charitable_Dashboard_Legacy|null
32 */
33 private static $instance = null;
34
35 /**
36 * The dashboard data that holds start date, end date, and filter.
37 *
38 * @since 1.8.1
39 *
40 * @var array
41 */
42 public $dashboard_data = array();
43
44 /**
45 * The date filter values.
46 *
47 * @since 1.8.1
48 *
49 * @var array
50 */
51 public $date_range_filter_values = array();
52
53 /**
54 * The start date.
55 *
56 * @since 1.8.1
57 *
58 * @var string
59 */
60 public $start_date = false;
61
62 /**
63 * The end date.
64 *
65 * @since 1.8.1
66 *
67 * @var string
68 */
69 public $end_date = false;
70
71 /**
72 * The number of days.
73 *
74 * @since 1.8.1
75 *
76 * @var int
77 */
78 public $days = false;
79
80 /**
81 * The donation axis of the highlight chart.
82 *
83 * @since 1.8.1
84 *
85 * @var array
86 */
87 public $donation_axis = array();
88
89 /**
90 * The date axis of the highlight chart.
91 *
92 * @since 1.8.1
93 *
94 * @var array
95 */
96 public $date_axis = array();
97
98 /**
99 * The default number of days to show in the filter.
100 *
101 * @since 1.8.1
102 *
103 * @var int
104 */
105 private $filter_days_default = 7;
106
107 /**
108 * Stores the last date/time of cache, false if there is no active or valid cache.
109 *
110 * @since 1.8.1
111 *
112 * @var int
113 */
114 public $is_data_cached = false;
115
116 /**
117 * Create object instance.
118 *
119 * @param array $args The arguments.
120 *
121 * @since 1.8.1
122 */
123 public function __construct( $args = array() ) {
124
125 do_action( 'charitable_admin_reports_start', $this );
126
127 add_action( 'charitable_after_admin_dashboard', array( $this, 'dashboard_cta' ) );
128
129 add_action( 'charitable_admin_dashboard_notifications', array( $this, 'display_notifications' ) );
130
131 $this->init( $args );
132 }
133
134 /**
135 * Run things upon init.
136 *
137 * @since 1.8.1
138 *
139 * @param array $args The arguments.
140 *
141 * @return void
142 */
143 private function init( $args = array() ) {
144
145 /*
146 * Site-local, not UTC: post_date is stored in site-local time, so a
147 * bound built from bare UTC excludes part of today's donations on any
148 * site whose timezone is ahead of UTC.
149 *
150 * @since 1.8.13
151 */
152 $defaults = apply_filters(
153 'charitable_dashboard_data_arg_defaults',
154 array(
155 'start_date' => gmdate( 'Y/m/d', current_time( 'timestamp', 0 ) - ( 7 * DAY_IN_SECONDS ) ),
156 'end_date' => gmdate( 'Y/m/d', current_time( 'timestamp', 0 ) ),
157 'days' => 7,
158 )
159 );
160
161 $cached_dashboard_data_args = $this->get_cached_dashboard_data_args();
162
163 if ( ! empty( $cached_dashboard_data_args ) && ! empty( $cached_dashboard_data_args['start_date'] ) && ! empty( $cached_dashboard_data_args['end_date'] ) && ! empty( $cached_dashboard_data_args['days'] ) ) {
164
165 $dashboard_data_args['start_date'] = esc_html( $cached_dashboard_data_args['start_date'] );
166 $dashboard_data_args['end_date'] = esc_html( $cached_dashboard_data_args['end_date'] );
167 $dashboard_data_args['days'] = intval( $cached_dashboard_data_args['days'] );
168
169 $this->is_data_cached = $cached_dashboard_data_args['timestamp'];
170
171 } else {
172
173 $this->is_data_cached = false;
174 $dashboard_data_args = wp_parse_args( $args, $defaults );
175 }
176
177 do_action( 'charitable_admin_dashboard_init_start', $this );
178
179 // Get the date filter values.
180 $this->date_range_filter_values = apply_filters(
181 'charitable_dashboard_date_range_filter_values',
182 array(
183 '7' => __( 'Last 7 Days', 'charitable' ),
184 '14' => __( 'Last 14 Days', 'charitable' ),
185 '30' => __( 'Last 30 Days', 'charitable' ),
186 )
187 );
188
189 $this->start_date = $dashboard_data_args['start_date'];
190 $this->end_date = $dashboard_data_args['end_date'];
191 $this->days = $dashboard_data_args['days'];
192
193 $this->dashboard_data = (array) $dashboard_data_args;
194
195 $this->maybe_load_scripts();
196
197 // Allow Charitable and third-party plugins to hook into the dashboard.
198 do_action( 'charitable_admin_dashboard_init_end', $this );
199 }
200
201 /**
202 * Get the cached dashboard notifications.
203 *
204 * @since 1.8.2
205 *
206 * @return array
207 */
208 public function display_notifications() {
209
210 // Grab the array of notifications, which includes the title, some meta, and the message.
211 $notifications = get_option( 'charitable_dashboard_notifications', array() );
212
213 if ( empty( $notifications ) ) {
214 return false;
215 }
216
217 // remove any notifications that don't have a 'type' key.
218 $notifications = array_filter(
219 $notifications,
220 function ( $notification ) {
221 return isset( $notification['type'] );
222 }
223 );
224
225 // remove any notifications that have a 'dismissed' key.
226 $notifications = array_filter(
227 $notifications,
228 function ( $notification ) {
229 return ! isset( $notification['dismissed'] );
230 }
231 );
232
233 if ( empty( $notifications ) ) {
234 return false;
235 }
236
237 // sort notifications by type = 'error' first, then 'warning', followed by 'notice'.
238 uasort(
239 $notifications,
240 function ( $a, $b ) {
241 $types = array( 'error', 'warning', 'notice' );
242 $pos_a = array_search( $a['type'], $types ); // phpcs:ignore
243 $pos_b = array_search( $b['type'], $types ); // phpcs:ignore
244
245 return $pos_a - $pos_b;
246 }
247 );
248
249 include charitable()->get_path( 'includes' ) . 'admin/templates/dashboard-notifications.php';
250 }
251
252
253 /**
254 * Remove a dashboard notification.
255 *
256 * @since 1.8.2
257 *
258 * @param string $notification_id The notification ID.
259 *
260 * @return boolean
261 */
262 public function charitable_remove_dashboard_notification( $notification_id = false ) {
263
264 // check nonce.
265 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'charitable_dashboard_notification_nonce' ) ) {
266 wp_send_json_error( array( 'message' => esc_html__( 'Invalid nonce.', 'charitable' ) ) );
267 }
268
269 if ( false === $notification_id ) {
270 return false;
271 }
272
273 $notification_id = sanitize_text_field( wp_unslash( $notification_id ) );
274
275 $notifications = (array) get_option( 'charitable_dashboard_notifications', array() );
276
277 if ( empty( $notifications ) ) {
278 return false;
279 }
280
281 if ( ! empty( $notifications[ $notification_id ] ) ) {
282 unset( $notifications[ $notification_id ] );
283 update_option( 'charitable_dashboard_notifications', $notifications );
284 return true;
285 } else {
286 return false;
287 }
288 }
289
290 /**
291 * Get the donation axis information for the highlight chart.
292 *
293 * @since 1.8.1.6
294 *
295 * @return array
296 */
297 public function enable_tooltips() {
298
299 $donation_axis = $this->get_donation_axis();
300
301 if ( empty( $donation_axis ) ) {
302 return false;
303 }
304
305 // remove any '0' and ',' from the string.
306 $donation_axis = array_map(
307 function ( $value ) {
308 return str_replace( array( '0', ',' ), '', $value );
309 },
310 $donation_axis
311 );
312
313 // if the trimmed length is 0, return false.
314 $enable_tooltips = array_filter(
315 $donation_axis,
316 function ( $value ) {
317 return strlen( trim( $value ) ) > 0;
318 }
319 );
320
321 return $enable_tooltips;
322 }
323
324 /**
325 * Get the donation axis information for the highlight chart.
326 *
327 * @since 1.8.1
328 *
329 * @return array
330 */
331 public function get_donation_axis() {
332
333 $donation_axis = $this->maybe_cache_dashboard() ? get_transient( 'wpch_dashboard_report_html_donation_axis' ) : false;
334 $date_axis = $this->maybe_cache_dashboard() ? get_transient( 'wpch_dashboard_report_html_date_axis' ) : false;
335
336 if ( $donation_axis && $date_axis ) {
337 return $donation_axis;
338 }
339
340 if ( empty( $this->donation_axis ) ) {
341 return array( 0, 0, 0, 0, 0, 0 );
342 }
343
344 return (array) $this->donation_axis;
345 }
346
347 /**
348 * Get the date axis information for the highlight chart.
349 *
350 * @since 1.8.1
351 *
352 * @return array
353 */
354 public function get_date_axis() {
355
356 $donation_axis = $this->maybe_cache_dashboard() ? get_transient( 'wpch_dashboard_report_html_donation_axis' ) : false;
357 $date_axis = $this->maybe_cache_dashboard() ? get_transient( 'wpch_dashboard_report_html_date_axis' ) : false;
358
359 if ( $donation_axis && $date_axis ) {
360 return $date_axis;
361 }
362
363 if ( empty( $this->date_axis ) ) {
364 /*
365 * Site-local, not UTC: matches the convention used everywhere else
366 * this class builds a date bound.
367 *
368 * @since 1.8.13
369 */
370 return $this->get_days_between_dates( gmdate( 'Y/m/d', current_time( 'timestamp', 0 ) - ( 7 * DAY_IN_SECONDS ) ), gmdate( 'Y/m/d', current_time( 'timestamp', 0 ) ) );
371 }
372
373 return (array) $this->date_axis;
374 }
375
376 /**
377 * Generate the dashboard HTML.
378 *
379 * @since 1.8.1
380 *
381 * @param array $args The arguments.
382 *
383 * @return array
384 */
385 public function generate_dashboard_report_html( $args = array() ) {
386
387 if ( ! is_array( $args ) ) {
388 $args = array();
389 }
390
391 $defaults = array(
392 'start_date' => false,
393 'end_date' => false,
394 'days' => false,
395 'show_support_box' => true,
396 'include_icons' => true,
397 'action' => false,
398 'show_recommended_addons' => true,
399 'show_recommended_snippets' => true,
400 'show_notifications' => true,
401 'use_cache' => 'no', // 'yes' or 'no' or 'maybe'.
402 );
403
404 $args = apply_filters( 'charitable_dashboard_report_html_args', wp_parse_args( $args, $defaults ) );
405
406 // Extract individual variables from args array.
407 $start_date = $args['start_date'] ?? false;
408 $end_date = $args['end_date'] ?? false;
409 $days = $args['days'] ?? false;
410 $show_support_box = $args['show_support_box'] ?? true;
411 $include_icons = $args['include_icons'] ?? true;
412 $action = $args['action'] ?? false;
413 $show_recommended_addons = $args['show_recommended_addons'] ?? true;
414 $show_recommended_snippets = $args['show_recommended_snippets'] ?? true;
415 $show_notifications = $args['show_notifications'] ?? true;
416 $use_cache = $args['use_cache'] ?? 'no';
417
418 if ( false === $days ) {
419 $args = $this->get_cached_dashboard_data_args();
420 if ( empty( $args ) || false === $args ) {
421 /*
422 * NOTE (1.8.13): $days is still `false` here - it isn't set to 7
423 * until the line below - so `'-' . $days . ' days'` resolves to
424 * '- days' and strtotime() returns an epoch-adjacent date. This
425 * is a separate, pre-existing defect (not the UTC-vs-site-local
426 * bug fixed elsewhere in this file this release) and is left
427 * untouched here; fixing it needs its own review since the
428 * $days ordering is the actual problem, not the timezone.
429 */
430 $start_date = gmdate( 'Y/m/d', strtotime( '-' . $days . ' days' ) );
431 $end_date = gmdate( 'Y/m/d' );
432 $days = 7;
433 } else {
434 $start_date = $args['start_date'];
435 $end_date = $args['end_date'];
436 $days = $args['days'];
437 }
438 }
439
440 $html = $this->maybe_cache_dashboard( $use_cache ) ? get_transient( 'wpch_dashboard_report_html_' . intval( $days ) ) : false;
441 $this->donation_axis = $this->maybe_cache_dashboard( $use_cache ) ? get_transient( 'wpch_dashboard_report_html_donation_axis_' . intval( $days ) ) : false;
442 $this->date_axis = $this->maybe_cache_dashboard( $use_cache ) ? get_transient( 'wpch_dashboard_report_html_date_axis_' . intval( $days ) ) : false;
443
444 $show_snippets_on_dashboard = apply_filters( 'charitable_show_snippets_on_dashboard', true );
445
446 // if WPCode isn't activated, then don't show the WPCode snippets on the dashboard.
447 if ( $show_snippets_on_dashboard ) {
448 // is WPCode WordPress plugin activated?
449 $is_activated = Charitable_Admin_Plugins_Third_Party::get_instance()->is_plugin_activated( 'wpcode' );
450
451 // if WPCode is not activated, then don't show the WPCode snippets on the dashboard.
452 if ( ! $is_activated ) {
453 $show_recommended_snippets = false;
454 }
455 } else {
456 $show_recommended_snippets = false;
457 }
458
459 if ( false === $html || false === $this->donation_axis || false === $this->date_axis || ! $this->maybe_cache_dashboard( $use_cache ) ) {
460
461 if ( $days ) {
462 /*
463 * Site-local, not UTC: this feeds Charitable_Reports::get_data(),
464 * which filters on p.post_date (site-local time), so a bound
465 * built from bare UTC excludes part of today's donations on any
466 * site whose timezone is ahead of UTC.
467 *
468 * @since 1.8.13
469 */
470 $start_date = gmdate( 'Y/m/d', strtotime( '-' . $days . ' days', current_time( 'timestamp', 0 ) ) );
471 $end_date = gmdate( 'Y/m/d', current_time( 'timestamp', 0 ) );
472 } else {
473 $start_date = ( false === $start_date ) ? $this->start_date : $start_date;
474 $end_date = ( false === $end_date ) ? $this->end_date : $end_date;
475 }
476
477 $charitable_reports = Charitable_Reports::get_instance();
478
479 $args = array(
480 'start_date' => $start_date,
481 'end_date' => $end_date,
482 'days' => $days,
483 );
484
485 $charitable_reports->init_with_array( 'dashboard', $args );
486
487 // donations.
488 $donations = $charitable_reports->get_donations();
489 $total_count_donations = count( $donations );
490 $total_amount_donations = $charitable_reports->get_donations_total();
491 $donation_average = ( $total_amount_donations > 0 && $total_amount_donations > 0 ) ? ( charitable_format_money( $total_amount_donations / $total_count_donations, 2, true ) ) : charitable_format_money( 0 );
492 $donation_total = charitable_format_money( $total_amount_donations );
493
494 // donors.
495 $total_count_donors = $charitable_reports->get_donors_count();
496
497 // refunds.
498 $refunds_data = $charitable_reports->get_refunds();
499
500 $total_amount_refunds = $refunds_data['total_amount'];
501 $total_count_refunds = $refunds_data['total_count'];
502
503 // campaigns.
504 $args = array( 'posts_per_page' => apply_filters( 'charitable_dashboard_top_campaigns_amount', 5 ) );
505 $top_campaigns = Charitable_Campaigns::ordered_by_amount( $args );
506
507 $this->donation_axis = ! empty( $charitable_reports->donation_axis ) ? (array) $charitable_reports->donation_axis : false;
508 $this->date_axis = ! empty( $charitable_reports->date_axis ) ? (array) $charitable_reports->date_axis : false;
509
510 $html = array();
511
512 ob_start();
513
514 ?>
515
516 <div class="charitable-cards">
517 <div class="charitable-container charitable-report-ui charitable-card"
518 <?php
519 if ( $action === 'download' ) :
520 ?>
521 style="width: 24.5%; display:inline-block;"<?php endif; ?>>
522 <strong><span id="charitable-top-donation-total-amount"><?php echo esc_html( $donation_total ); ?></span></strong>
523 <p><span id="charitable-top-donation-total-count"><?php echo count( $donations ); ?></span> <?php echo esc_html__( 'Total Donations', 'charitable' ); ?></p>
524 </div>
525 <div class="charitable-container charitable-report-ui charitable-card"
526 <?php
527 if ( $action === 'download' ) :
528 ?>
529 style="width: 24.5%; display:inline-block;"<?php endif; ?>>
530 <strong><span id="charitable-top-donation-average"><?php echo esc_html( $donation_average ); ?></span></strong>
531 <p><?php echo esc_html__( 'Average Donation', 'charitable' ); ?></p>
532 </div>
533 <div class="charitable-container charitable-report-ui charitable-card"
534 <?php
535 if ( $action === 'download' ) :
536 ?>
537 style="width: 24.5%; display:inline-block;"<?php endif; ?>>
538 <strong><span id="charitable-top-donor-count"><?php echo intval( $total_count_donors ); ?></span></strong>
539 <p><?php echo esc_html__( 'Donors', 'charitable' ); ?></p>
540 </div>
541 <div class="charitable-container charitable-report-ui charitable-card"
542 <?php
543 if ( $action === 'download' ) :
544 ?>
545 style="width: 24.5%; display:inline-block;"<?php endif; ?>>
546 <strong><span id="charitable-top-refund-total-amount"><?php echo charitable_format_money( $total_amount_refunds ); // phpcs:ignore ?></span></strong>
547 <p><span id="charitable-top-refund-count"><?php echo intval( $total_count_refunds ); ?></span> <?php echo esc_html__( 'Refunds', 'charitable' ); ?></p>
548 </div>
549 </div>
550 <?php
551
552 $html['charitable_cards'] = ob_get_clean();
553
554 $no_items_text = ( $days > 0 ) ? esc_html__( 'There are no donations in the last ', 'charitable' ) . $days . ' ' . esc_html__( 'days.', 'charitable' ) : esc_html__( 'There are no donations for the selected date range.', 'charitable' );
555
556 ob_start();
557 ?>
558 <div class="charitable-container charitable-report-card charitable-recent-donations-report">
559 <div class="header">
560 <h4><?php echo esc_html__( 'Recent Donations', 'charitable' ); ?></h4>
561 <a href="#" class="charitable-toggle"><i class="fa fa-angle-down charitable-angle-down"></i></a>
562 </div>
563 <div class="charitable-toggle-container charitable-report-ui">
564 <?php
565
566 $list = $charitable_reports->generate_recent_donations_list( $donations, 10, $include_icons );
567
568 if ( ! empty( $list ) ) :
569 ?>
570 <div class="the-list">
571 <ul id="charitable-recent-donations-list">
572 <?php echo $list; // phpcs:ignore ?>
573 </ul>
574 </div>
575 <?php else : ?>
576 <div class="no-items">
577 <p><strong><?php echo esc_html( $no_items_text ); ?></strong></p>
578 <p class="link"><a href="<?php echo admin_url( 'post-new.php?post_type=donation' ); // phpcs:ignore ?>"><?php echo esc_html__( 'Add Donation', 'charitable' ); ?>
579 <?php
580 if ( $include_icons ) :
581 ?>
582 <img src="<?php echo esc_url( charitable()->get_path( 'assets', false ) ) . 'images/icons/east.svg'; // phpcs:ignore ?>" /><?php endif; ?></a></p>
583 </div>
584 <?php endif; ?>
585 </div>
586 <div class="more">
587 <?php if ( false === $action ) : ?>
588 <a href="<?php echo admin_url( 'edit.php?post_type=donation' ); // phpcs:ignore ?>"><?php echo esc_html__( 'View All Donations', 'charitable' ); ?>
589 <?php
590 if ( $include_icons ) :
591 ?>
592 <img src="<?php echo esc_url( charitable()->get_path( 'assets', false ) ) . 'images/icons/east.svg'; // phpcs:ignore ?>" /><?php endif; ?></a>
593 <?php endif; ?>
594 </div>
595 </div>
596
597 <div class="charitable-container charitable-report-card charitable-top-campaigns-report">
598 <div class="header">
599 <h4><?php echo esc_html__( 'Top Campaigns', 'charitable' ); ?></h4>
600 <a href="#" class="charitable-toggle"><i class="fa fa-angle-down charitable-angle-down"></i></a>
601 </div>
602 <div class="charitable-toggle-container charitable-report-ui">
603 <?php if ( ! empty( $top_campaigns->posts ) ) : ?>
604 <div class="the-list">
605 <ul id="charitable-top-campaigns-list">
606 <?php echo $charitable_reports->generate_top_campaigns( $top_campaigns ); // phpcs:ignore ?>
607 </ul>
608 </div>
609 <?php else : ?>
610 <div class="no-items">
611 <p><strong><?php echo esc_html__( 'There are no campaigns at the moment.', 'charitable' ); ?></strong></p>
612 <?php if ( false === $action ) : ?>
613 <?php if ( charitable_disable_legacy_campaigns() ) : ?>
614 <p class="link"><a href="<?php echo admin_url( 'admin.php?page=charitable-campaign-builder&view=template' ); // phpcs:ignore ?>"><?php echo esc_html__( 'Add New Campaign', 'charitable' ); ?>
615 <?php else : ?>
616 <p class="link"><a href="<?php echo admin_url( 'post-new.php?post_type=campaign' ); // phpcs:ignore ?>"><?php echo esc_html__( 'Add New Campaign', 'charitable' ); ?>
617 <?php endif; ?>
618
619
620 <?php
621 if ( $include_icons ) :
622 ?>
623 <img src="<?php echo esc_url( charitable()->get_path( 'assets', false ) ) . 'images/icons/east.svg'; // phpcs:ignore ?>" /><?php endif; ?></a></p>
624 <?php endif; ?>
625 </div>
626 <?php endif; ?>
627 </div>
628 <div class="more">
629 <?php if ( ! empty( $top_campaigns->posts ) && false === $action ) : ?>
630 <?php if ( charitable_disable_legacy_campaigns() ) : ?>
631 <a href="<?php echo admin_url( 'admin.php?page=charitable-campaign-builder&view=template' ); // phpcs:ignore ?>"><?php echo esc_html__( 'Add New Campaign', 'charitable' ); ?> <img src="<?php echo esc_url( charitable()->get_path( 'assets', false ) ) . 'images/icons/east.svg'; // phpcs:ignore ?>" /></a>
632 <?php else : ?>
633 <a href="<?php echo admin_url( 'post-new.php?post_type=campaign' ); // phpcs:ignore ?>"><?php echo esc_html__( 'Add New Campaign', 'charitable' ); ?> <img src="<?php echo esc_url( charitable()->get_path( 'assets', false ) ) . 'images/icons/east.svg'; // phpcs:ignore ?>" /></a>
634 <?php endif; ?>
635 <?php endif; ?>
636 </div>
637 </div>
638
639 <?php
640 if ( $show_recommended_snippets ) :
641
642 $recommended_snippets = $this->get_dashboard_recommended_snippets( 2 );
643
644 if ( ! empty( $recommended_snippets ) ) :
645
646 ?>
647 <div class="charitable-container charitable-report-card charitable-recommended-snippets">
648 <div class="header">
649 <h4><?php echo esc_html__( 'Recommended Snippets', 'charitable' ); ?></h4>
650 <a href="#" class="charitable-toggle"><i class="fa fa-angle-down charitable-angle-down"></i></a>
651 </div>
652 <div class="charitable-toggle-container charitable-report-ui">
653 <div id="charitable-wpcode-snippets-list">
654 <div class="charitable-wpcode-snippets-list">
655
656 <?php
657 foreach ( $recommended_snippets as $snippet ) :
658 $button_text = $snippet['installed'] ? __( 'Edit Snippet', 'charitable' ) : __( 'Install Snippet', 'charitable' );
659 $button_type_class = $snippet['installed'] ? 'button-primary' : 'button-secondary';
660 $button_action = $snippet['installed'] ? 'edit' : 'install';
661 $library_id = ! empty( $snippet['library_id'] ) ? ( $snippet['library_id'] ) : false;
662 ?>
663 <div class="charitable-wpcode-snippet">
664 <div class="charitable-wpcode-snippet-header">
665 <h3 class="charitable-wpcode-snippet-title"><?php echo esc_html( $snippet['title'] ); ?></h3>
666 <div class="charitable-wpcode-snippet-note"><?php echo esc_html( $snippet['note'] ); ?></div>
667 </div>
668 <div class="charitable-wpcode-snippet-footer">
669 <a
670 href="<?php echo esc_url( $snippet['install'] ); ?>"
671 class="button charitable-wpcode-snippet-button <?php echo sanitize_html_class( $button_type_class ); ?>"
672 data-action="<?php echo esc_attr( $button_action ); ?>"><?php echo esc_html( $button_text ); ?> </a>
673 <?php if ( $library_id ) : ?>
674 <a class="charitable-wpcode-snippet-external-link" title="<?php esc_html_e( 'View this snippet on WPCode.com', 'charitable' ); ?>" href="https://library.wpcode.com/profile/wpcharitable/?code_type=all&order=popular&view=all&search=<?php echo urlencode( $snippet['title'] ); ?>" target="_blank"><span class="dashicons dashicons-external"></span></a>
675 <?php endif; ?>
676 </div>
677 </div>
678 <?php endforeach; ?>
679 </div>
680 <div class="no-items">
681 <p class="link"><a href="<?php echo esc_url( admin_url( 'admin.php?page=charitable-tools&tab=snippets' ) ); ?>"><?php esc_html_e( 'View All Snippets', 'charitable' ); ?> <img src="<?php echo esc_url( charitable()->get_path( 'assets', false ) ) . 'images/icons/east.svg'; ?>" /> </a></p>
682 </div>
683 </div>
684 </div>
685 </div>
686 <?php
687
688 endif; // snippets links not empty.
689
690 endif;
691
692 if ( $show_support_box ) :
693
694 $dashboard_support_links = $this->get_dashboard_support_links();
695
696 if ( ! empty( $dashboard_support_links ) ) :
697 ?>
698 <div class="charitable-container charitable-report-card charitable-support">
699 <div class="header">
700 <h4><?php echo esc_html__( 'Support', 'charitable' ); ?></h4>
701 <a href="#" class="charitable-toggle"><i class="fa fa-angle-down charitable-angle-down"></i></a>
702 </div>
703 <div class="charitable-toggle-container charitable-report-ui">
704 <div class="the-list">
705 <ul>
706 <?php foreach ( $dashboard_support_links as $dashboard_support_link ) : ?>
707 <?php
708 if ( ! empty( $dashboard_support_link['lite_pro'] )
709 && ( ( $dashboard_support_link['lite_pro'] === 'lite' && charitable_is_pro() ) || ( $dashboard_support_link['lite_pro'] === 'pro' && ! charitable_is_pro() ) ) ) {
710 continue;
711 }
712 ?>
713 <li>
714 <?php if ( ! empty( $dashboard_support_link['icon'] ) ) : ?>
715 <div class="icon">
716 <img src="<?php echo esc_url( $dashboard_support_link['icon'] ); ?>" alt="">
717 </div>
718 <?php endif; ?>
719 <div class="info">
720 <a target="_blank" href="<?php echo esc_url( $dashboard_support_link['url'] ); ?>"><?php echo esc_html( $dashboard_support_link['title'] ); ?></a>
721 </div>
722 </li>
723 <?php endforeach; ?>
724 </ul>
725 </div>
726 </div>
727 </div>
728 <?php
729
730 endif; // support links not empty.
731
732 endif; // show support box.
733
734 if ( $show_notifications ) :
735
736 Charitable_Notifications::get_instance()->output( 'dashboard' );
737
738 endif; // show support box.
739
740 if ( $show_recommended_addons ) :
741
742 $recommended_addons = $this->get_dashboard_recommended_addons();
743
744 if ( ! empty( $recommended_addons ) ) :
745
746 ?>
747 <div class="charitable-container charitable-report-card charitable-recommended-addons">
748 <div class="header">
749 <h4><?php echo esc_html__( 'Recommended Addons', 'charitable' ); ?></h4>
750 <a href="#" class="charitable-toggle"><i class="fa fa-angle-down charitable-angle-down"></i></a>
751 </div>
752 <div class="charitable-toggle-container charitable-report-ui">
753 <div class="the-list">
754 <ul>
755 <?php
756 foreach ( $recommended_addons as $addon_slug => $addon_info ) :
757
758 $extension_url = charitable_ga_url(
759 'https://wpcharitable.com/extensions/charitable-' . $addon_slug,
760 urlencode( 'Recommended Extensions' ), // phpcs:ignore
761 $addon_slug
762 );
763
764 ?>
765 <li class="<?php echo esc_attr( $addon_slug ); ?>">
766 <?php if ( ! empty( $addon_info['recommended'] ) ) : ?>
767 <span class="popular"><?php echo esc_html__( 'Popular', 'charitable' ); ?></span>
768 <?php endif; ?>
769 <a href="<?php echo esc_url( $extension_url ); ?>" target="_blank" rel="noopener">
770 <?php /* translators: %s: extension title */ ?>
771 <img src="<?php echo esc_url( charitable()->get_path( 'assets', false ) ); ?>images/extensions/<?php echo esc_attr( $addon_slug ); ?>.png" alt="<?php echo esc_attr( sprintf( _x( '%s banner', 'extension banner', 'charitable' ), $addon_slug ) ); ?>" />
772 <h4><?php echo esc_html( $addon_info['title'] ); ?></h4>
773 <?php echo esc_html( $addon_info['description'] ); ?>
774 </a>
775 </li><?php endforeach; ?>
776 </ul>
777 </div>
778 </div>
779 </div>
780 <?php
781
782 endif; // support links not empty.
783
784 endif; // show recommended addons box.
785
786 $html['charitable_reports'] = ob_get_clean();
787
788 if ( $this->maybe_cache_dashboard( $use_cache ) ) :
789
790 set_transient( 'wpch_dashboard_report_html_' . intval( $days ), $html, MINUTE_IN_SECONDS );
791 set_transient( 'wpch_dashboard_report_html_donation_axis_' . intval( $days ), $this->donation_axis, MINUTE_IN_SECONDS );
792 set_transient( 'wpch_dashboard_report_html_date_axis_' . intval( $days ), $this->date_axis, MINUTE_IN_SECONDS );
793
794 endif;
795
796 } // End if().
797
798 return $html;
799 }
800
801 /**
802 * Get the cached dashboard data args.
803 *
804 * @since 1.8.1
805 *
806 * @return array
807 */
808 public function get_cached_dashboard_data_args() {
809
810 if ( ! $this->maybe_cache_dashboard() ) {
811 return false;
812 }
813
814 $dashboard_data_args = get_transient( 'wpch_dashboard_data_args' );
815
816 return $dashboard_data_args;
817 }
818
819 /**
820 * Set the cached dashboard data args.
821 *
822 * @since 1.8.1
823 *
824 * @param array $dashboard_data_args The dashboard data args.
825 *
826 * @return bool False if not set, otherwise the date/time of cache.
827 */
828 public function set_cached_dashboard_data_args( $dashboard_data_args = array() ) {
829
830 if ( empty( $dashboard_data_args ) || ! $this->maybe_cache_dashboard() ) {
831 return false;
832 }
833
834 // Set the timestamp.
835 $dashboard_data_args['timestamp'] = gmdate( 'Y/m/d h:i A', current_time( 'timestamp', 0 ) );
836
837 $transient_set = set_transient( 'wpch_dashboard_data_args', $dashboard_data_args, DAY_IN_SECONDS );
838
839 return ( $transient_set ) ? $dashboard_data_args['timestamp'] : false; // phpcs:ignore
840 }
841
842 /**
843 * A check to see if the dashboard data is cached, and if so the timestamp of when it was cached.
844 *
845 * @since 1.8.1
846 *
847 * @return string
848 */
849 public function is_dashboard_data_cached() {
850
851 if ( ! $this->maybe_cache_dashboard() ) {
852 return false;
853 }
854
855 $dashboard_data_args = get_transient( 'wpch_dashboard_data_args' );
856
857 if ( $dashboard_data_args && ! empty( $dashboard_data_args['timestamp'] ) ) {
858 // return format of the date/time to something like March 31, 1970 12:00 AM.
859 return gmdate( 'F j, Y h:i A', strtotime( $dashboard_data_args['timestamp'] ) );
860 }
861
862 return false;
863 }
864
865 /**
866 * Get the start date.
867 *
868 * @since 1.8.1
869 *
870 * @return string
871 */
872 public function get_start_date() {
873
874 $start_date = ! empty( $this->dashboard_data['start_date'] ) ? $this->dashboard_data['start_date'] : false;
875
876 return $start_date;
877 }
878
879 /**
880 * Get the end date.
881 *
882 * @since 1.8.1
883 *
884 * @return string
885 */
886 public function get_end_date() {
887
888 $end_date = ! empty( $this->dashboard_data['end_date'] ) ? $this->dashboard_data['end_date'] : false;
889
890 return $end_date;
891 }
892
893 /**
894 * Get the filter value.
895 *
896 * @since 1.8.1
897 *
898 * @return string
899 */
900 public function get_filter_value() {
901
902 $filter = ! empty( $this->dashboard_data['filter'] ) ? $this->dashboard_data['filter'] : false;
903
904 return $filter;
905 }
906
907 /**
908 * Check if the report should be cached.
909 *
910 * @since 1.8.1
911 *
912 * @param bool $force_cache Force cache. Default is 'maybe'. Accepts 'yes', 'no', 'maybe'. :-).
913 *
914 * @return bool
915 */
916 public function maybe_cache_dashboard( $force_cache = 'maybe' ) {
917
918 if ( $force_cache === 'yes' ) {
919 return true;
920 }
921 if ( $force_cache === 'no' ) {
922 return false;
923 }
924 if ( charitable_is_debug() ) {
925 return false;
926 }
927 if ( defined( 'CHARITABLE_REPORTS_NO_CACHE' ) && CHARITABLE_REPORTS_NO_CACHE ) {
928 return false;
929 }
930
931 return true;
932 }
933
934 /**
935 * Is the data cached?
936 *
937 * @since 1.8.1
938 *
939 * @return boolean
940 */
941 public function is_data_cached() {
942
943 return $this->is_data_cached;
944 }
945
946 /**
947 * Return the HTML of the filter select dropdown.
948 *
949 * @since 1.8.1
950 *
951 * @param string $selected_value The selected value.
952 *
953 * @return string
954 */
955 public function get_filter_dropdown( $selected_value = false ) {
956
957 $options_values = $this->date_range_filter_values;
958
959 $selected_value = false === $selected_value && $this->days ? $this->days : $selected_value;
960 $selected_value = false === $selected_value && $this->filter_days_default ? $this->filter_days_default : $selected_value;
961
962 ob_start();
963
964 ?>
965
966 <select name="action" id="report-date-range-filter">
967 <?php foreach ( $options_values as $value => $label ) : ?>
968 <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $selected_value, $value ); ?>><?php echo esc_html( $label ); ?></option>
969 <?php endforeach; ?>
970 </select>
971
972 <?php
973
974 return ob_get_clean();
975 }
976
977 /**
978 * Return the default number of days for the dashboard filter.
979 *
980 * @since 1.8.1
981 *
982 * @return string
983 */
984 public function get_days() {
985
986 $selected_value = $this->days ? $this->days : false;
987 $selected_value = false === $selected_value && $this->filter_days_default ? $this->filter_days_default : $selected_value;
988
989 return $selected_value;
990 }
991
992 /**
993 * Util function that gets dates between two given dates.
994 *
995 * @param string $start_date The start date.
996 * @param string $end_date The end date.
997 * @param string $format The date format.
998 *
999 * @since 1.8.1
1000 *
1001 * @return mixed
1002 */
1003 public function get_days_between_dates( $start_date, $end_date, $format = 'M d' ) { // phpcs:ignore
1004 $days = array();
1005
1006 $current_date = new DateTime( $start_date );
1007 $end_date = new DateTime( $end_date );
1008
1009 while ( $current_date <= $end_date ) {
1010 $days[] = $current_date->format( 'M d' ); // 'Y-m-d
1011 $current_date->modify( '+1 day' );
1012 }
1013
1014 return $days;
1015 }
1016
1017
1018 /**
1019 * Load scripts and styles.
1020 *
1021 * @since 1.8.1
1022 *
1023 * @return void
1024 */
1025 public function maybe_load_scripts() {
1026
1027 if ( ! function_exists( 'get_current_screen' ) ) {
1028 return;
1029 }
1030
1031 $screen = get_current_screen();
1032
1033 // Add Javascript vars at the footer of the WordPress admin, at the dashboard and the overview tab of reporting.
1034 if ( ! is_null( $screen ) && $screen->id === 'charitable_page_charitable-dashboard' ) {
1035 // Specific styles for the "dashboard".
1036 add_action( 'admin_footer', array( $this, 'report_vars' ), 100 );
1037 }
1038 }
1039
1040 /**
1041 * Enqueue assets and write JS vars for the report.
1042 *
1043 * @since 1.8.1
1044 *
1045 * @return void
1046 */
1047 public function report_vars() {
1048
1049 ?>
1050 <script id="charitable-report-data-js">
1051 var charitable_reporting = <?php echo wp_json_encode( $this->get_localized_strings() ); ?>;
1052 </script>
1053
1054 <?php
1055 }
1056
1057 /**
1058 * Get localized strings.
1059 *
1060 * @since 1.8.1
1061 *
1062 * @return array
1063 */
1064 private function get_localized_strings() {
1065
1066 $currency_helper = charitable_get_currency_helper();
1067
1068 $strings = array(
1069 'version' => Charitable::VERSION,
1070 'nonce' => wp_create_nonce( 'charitable-reporting' ),
1071 'admin_nonce' => wp_create_nonce( 'charitable-admin' ),
1072 'currency_symbol' => $currency_helper->get_currency_symbol(),
1073 'ajax_url' => admin_url( 'admin-ajax.php' ),
1074 'date_select_day' => 'DD',
1075 'date_select_month' => 'MM',
1076 'headline_chart_options' => array(
1077 'donation_axis' => (array) $this->get_donation_axis(),
1078 'date_axis' => (array) $this->get_date_axis(),
1079 'enable_tooltips' => (bool) $this->enable_tooltips(),
1080 ),
1081 'payment_methods_chart_options' => array(
1082 'payment_percentages' => array(),
1083 'payment_labels' => array(),
1084 ),
1085 );
1086
1087 $strings = apply_filters( 'charitable_admin_dashboard_strings', $strings );
1088
1089 return $strings;
1090 }
1091
1092 /**
1093 * Get recommended addons, which can be based on the locale or currency.
1094 *
1095 * @since 1.8.1
1096 * @since 1.8.1.5 Added recommended and $limit.
1097 *
1098 * @param string $currency The currency code.
1099 * @param string $locale The locale.
1100 * @param int $limit The number of recommended addons to return.
1101 *
1102 * @return array
1103 */
1104 public function get_dashboard_recommended_addons( $currency = false, $locale = false, $limit = 6 ) {
1105
1106 $currency = ( false === $currency && function_exists( 'charitable_get_default_currency' ) ? charitable_get_default_currency() : $currency );
1107 $currencies = charitable_get_currency_helper()->get_all_currencies();
1108 $locale = $locale ? $locale : get_locale();
1109
1110 $all_extensions = array(
1111 'payfast' => array(
1112 'title' => esc_html__( 'Refunds', 'charitable' ),
1113 'description' => esc_html__( 'Accept donations in South African Rand', 'charitable' ),
1114 ),
1115 'payu-money' => array(
1116 'title' => esc_html__( 'PayUmoney', 'charitable' ),
1117 'description' => esc_html__( 'Accept donations in Indian Rupees with PayUmoney', 'charitable' ),
1118 ),
1119 'easy-digital-downloads-connect' => array(
1120 'title' => esc_html__( 'Easy Digital Downloads', 'charitable' ),
1121 'description' => esc_html__( 'Collect donations with Easy Digital Downloads', 'charitable' ),
1122 ),
1123 'recurring-donations' => array(
1124 'title' => esc_html__( 'Recurring Donations', 'charitable' ),
1125 'description' => esc_html__( 'Accept recurring donations', 'charitable' ),
1126 ),
1127 'fee-relief' => array(
1128 'title' => esc_html__( 'Fee Relief', 'charitable' ),
1129 'description' => esc_html__( 'Let donors cover the gateway fees', 'charitable' ),
1130 ),
1131 'authorize-net' => array(
1132 'title' => esc_html__( 'Authorize.NET', 'charitable' ),
1133 'description' => esc_html__( 'Collect donations with Authorize.Net', 'charitable' ),
1134 ),
1135 'ambassadors' => array(
1136 'title' => esc_html__( 'Ambassadors', 'charitable' ),
1137 'description' => esc_html__( 'Peer to peer fundraising or crowdfunding', 'charitable' ),
1138 ),
1139 'windcave' => array(
1140 'title' => esc_html__( 'Windcave', 'charitable' ),
1141 'description' => sprintf(
1142 /* translators: %s: currency code */
1143 __( 'Collect donations in %s', 'charitable' ),
1144 $currencies[ $currency ]
1145 ),
1146 ),
1147 'anonymous-donations' => array(
1148 'title' => esc_html__( 'Anonymous Donations', 'charitable' ),
1149 'description' => esc_html__( 'Let donors give anonymously', 'charitable' ),
1150 ),
1151 'user-avatar' => array(
1152 'title' => esc_html__( 'User Avatar', 'charitable' ),
1153 'description' => esc_html__( 'Let your donors upload their own profile photo', 'charitable' ),
1154 ),
1155 'video' => array(
1156 'title' => esc_html__( 'Video', 'charitable' ),
1157 'description' => esc_html__( 'Boost campaigns by adding videos', 'charitable' ),
1158 ),
1159 'annual-receipts' => array(
1160 'title' => esc_html__( 'Annual Receipts', 'charitable' ),
1161 'description' => esc_html__( 'Provide downloadable annual receipts', 'charitable' ),
1162 ),
1163 'pdf-receipts' => array(
1164 'title' => esc_html__( 'PDF Receipts', 'charitable' ),
1165 'description' => esc_html__( 'Make life easy for your donors by providing them with a PDF receipt for their donation', 'charitable' ),
1166 ),
1167 );
1168
1169 if ( 'en_ZA' === $locale || 'ZAR' === $currency ) {
1170 $extensions = array_intersect_key(
1171 $all_extensions,
1172 array(
1173 'payfast' => '',
1174 'recurring-donations' => '',
1175 'ambassadors' => '',
1176 'fee-relief' => '',
1177 )
1178 );
1179 } elseif ( 'hi_IN' === $locale || 'INR' === $currency ) {
1180 $extensions = array_intersect_key(
1181 $all_extensions,
1182 array(
1183 'payu-money' => '',
1184 'ambassadors' => '',
1185 'fee-relief' => '',
1186 'windcave' => '',
1187 )
1188 );
1189 } elseif ( in_array( $locale, array( 'en_NZ', 'ms_MY', 'ja', 'zh_HK' ) ) || in_array( $currency, array( 'NZD', 'MYR', 'JPY', 'HKD' ), true ) ) {
1190 $extensions = array_intersect_key(
1191 $all_extensions,
1192 array(
1193 'recurring-donations' => '',
1194 'windcave' => '',
1195 'fee-relief' => '',
1196 )
1197 );
1198 } elseif ( in_array( $locale, array( 'th' ) ) || in_array( $currency, array( 'BND', 'FJD', 'KWD', 'PGK', 'SBD', 'THB', 'TOP', 'VUV', 'WST' ), true ) ) {
1199 $extensions = array_intersect_key(
1200 $all_extensions,
1201 array(
1202 'windcave' => '',
1203 'fee-relief' => '',
1204 'ambassadors' => '',
1205 'anonymous-donations' => '',
1206 )
1207 );
1208 } elseif ( class_exists( 'EDD' ) ) {
1209 $extensions = array_intersect_key(
1210 $all_extensions,
1211 array(
1212 'ambassadors' => '',
1213 'easy-digital-downloads-connect' => '',
1214 'anonymous-donations' => '',
1215 'user-avatar' => '',
1216 )
1217 );
1218 } else {
1219 $extensions = array_intersect_key(
1220 $all_extensions,
1221 array(
1222 'recurring-donations' => '',
1223 'authorize-net' => '',
1224 'fee-relief' => '',
1225 'ambassadors' => '',
1226 'video' => '',
1227 'annual-receipts' => '',
1228 )
1229 );
1230 }
1231
1232 $recommended_addons = $this->get_recommended_dashboard_addons();
1233
1234 // Recommended addons.
1235 if ( ! empty( $recommended_addons ) ) {
1236
1237 foreach ( $extensions as $key => $value ) {
1238 // go through extensions and remove any that are already recommended.
1239 if ( array_key_exists( $key, $recommended_addons ) ) {
1240 unset( $extensions[ $key ] );
1241 }
1242 // add recommended addons to the front of the extensions array.
1243 $extensions = array_merge( $recommended_addons, $extensions );
1244
1245 }
1246 }
1247
1248 // Chop off array to the limit.
1249 $extensions = array_slice( $extensions, 0, $limit );
1250
1251 return $extensions;
1252 }
1253
1254 /**
1255 * Get the recommended dashboard addons.
1256 *
1257 * @since 1.8.1.5
1258 * @version 1.8.3
1259 * @version 1.8.8.2
1260 *
1261 * @return array
1262 */
1263 public function get_recommended_dashboard_addons() {
1264
1265 $recommended_addons = get_transient( '_charitable_addons' ); // @codingStandardsIgnoreLine - testing.
1266
1267 // Get addons data from transient or perform API query if no transient.
1268 if ( false === $recommended_addons ) {
1269 $recommended_addons = charitable_get_addons_data_from_server();
1270 }
1271
1272 $recommended_to_return = array();
1273
1274 if ( $recommended_addons ) {
1275
1276 foreach ( (array) $recommended_addons as $i => $addon ) {
1277
1278 if ( ! isset( $addon['slug'] ) || $addon['slug'] === '' || strtolower( $addon['slug'] ) === 'auto draft' ) {
1279 continue;
1280 }
1281
1282 if ( ! is_array( $addon ) ) {
1283 $addon = array();
1284 }
1285
1286 if ( isset( $addon['featured'] ) && ! empty( $addon['sections'] ) && in_array( 'recommended', $addon['featured'], true ) ) {
1287
1288 // Check if sections is already an array or needs to be unserialized (added in 1.8.8.2)
1289 $sections = is_array( $addon['sections'] ) ? $addon['sections'] : unserialize( $addon['sections'] );
1290 $description = isset( $sections['description'] ) ? $sections['description'] : '';
1291
1292 // subsutite test for translations, trying in 1.8.3.
1293 $addon['name'] = ! empty( $addon['name'] ) && strtolower( $addon['name'] ) === 'charitable recurring donations' ? __( 'Charitable Recurring Donations', 'charitable' ) : $addon['name'];
1294 $addon['name'] = ! empty( $addon['name'] ) && strtolower( $addon['name'] ) === 'charitable pdf receipts' ? __( 'Charitable PDF Receipts', 'charitable' ) : $addon['name'];
1295 $description = ! empty( $description ) && strpos( $description, 'with recurring donations' ) !== false ? __( 'Grow your organization\'s revenue with recurring donations.', 'charitable' ) : $description;
1296 $description = ! empty( $description ) && strpos( $description, 'PDF receipt' ) !== false ? __( 'Make life easy for your donors by providing them with a PDF receipt for their donation.', 'charitable' ) : $description;
1297
1298 $recommended_to_return[ str_replace( 'charitable-', '', $addon['slug'] ) ] = array(
1299 'title' => $addon['name'],
1300 'description' => wp_strip_all_tags( $description ),
1301 'recommended' => true,
1302 );
1303
1304 }
1305 }
1306 }
1307
1308 return $recommended_to_return;
1309 }
1310
1311 /**
1312 * Get recommended snippets.
1313 *
1314 * @since 1.8.1.6
1315 *
1316 * @param int $limit The number of recommended addons to return.
1317 * @param bool $show_installed Show installed snippets.
1318 *
1319 * @return array
1320 */
1321 public function get_dashboard_recommended_snippets( $limit = 3, $show_installed = true ) { // phpcs:ignore
1322
1323 $snippets = charitable_get_intergration_wpcode()->load_charitable_snippets( $limit, $show_installed );
1324
1325 return $snippets;
1326 }
1327
1328 /**
1329 * Get the dashboard support links, which are displayed in a "card" on the dashboard.
1330 *
1331 * @since 1.8.1
1332 *
1333 * @return array
1334 */
1335 public function get_dashboard_support_links() {
1336
1337 $dashboard_support_links = apply_filters(
1338 'charitable_dashboard_support_links',
1339 array(
1340 array(
1341 'title' => __( 'Getting started? Read the Beginners Guide', 'charitable' ),
1342 'url' => 'https://wpcharitable.com/start-here/?referrer=chariable-dashboard',
1343 'icon' => charitable()->get_path( 'assets', false ) . 'images/icons/stories.svg',
1344 'lite_pro' => false,
1345 ),
1346 array(
1347 'title' => __( 'View Our Documentation', 'charitable' ),
1348 'url' => 'https://wpcharitable.com/documentation?referrer=chariable-dashboard',
1349 'icon' => charitable()->get_path( 'assets', false ) . 'images/icons/menu_book.svg',
1350 'lite_pro' => false,
1351 ),
1352 array(
1353 'title' => __( 'Contact Our Expert Support Team For Help', 'charitable' ),
1354 'url' => 'https://wpcharitable.com/support?referrer=chariable-dashboard',
1355 'icon' => charitable()->get_path( 'assets', false ) . 'images/icons/sms.svg',
1356 'lite_pro' => false,
1357 ),
1358 array(
1359 'title' => __( 'Upgrade From Lite to Unlock More Powerful Features', 'charitable' ),
1360 'url' => 'https://wpcharitable.com/lite-vs-pro?referrer=chariable-dashboard',
1361 'icon' => charitable()->get_path( 'assets', false ) . 'images/icons/bullet_check.svg',
1362 'lite_pro' => 'lite',
1363 ),
1364 array(
1365 'title' => __( 'Upgrade Your Plan to Unlock More Powerful Features', 'charitable' ),
1366 'url' => 'https://wpcharitable.com/pricing?referrer=chariable-dashboard',
1367 'icon' => charitable()->get_path( 'assets', false ) . 'images/icons/bullet_check.svg',
1368 'lite_pro' => 'pro',
1369 ),
1370 )
1371 );
1372
1373 return $dashboard_support_links;
1374 }
1375
1376 /**
1377 * Get the notices to display on the dashboard. Get any stored notices/notifications from the database.
1378 *
1379 * @since 1.8.3
1380 *
1381 * @return array
1382 */
1383 public function get_notifications() {
1384
1385 $notifications_html = Charitable_Notifications::get_instance()->output( 'dashboard' );
1386
1387 return $notifications_html;
1388 }
1389
1390 /**
1391 * Get the notices to display on the dashboard. Get any stored notices/notifications from the database.
1392 *
1393 * @since 1.8.1.6
1394 * @version 1.8.2
1395 *
1396 * @return array
1397 */
1398 public function get_notices() {
1399
1400 return (array) apply_filters( 'charitable_dashboard_notices', get_option( 'charitable_dashboard_notifications', array() ) );
1401 }
1402
1403 /**
1404 * Get the dashboard guide tool notices.
1405 *
1406 * @since 1.8.1.6
1407 * @since 1.8.1.10
1408 *
1409 * @return bool
1410 */
1411 public function maybe_show_dashboard_growth_tool_chart_notice() {
1412
1413 $charitable_growth_tool_notices = get_option( 'charitable_growth_tool_notices', false );
1414
1415 $ret = true;
1416
1417 if ( ! $charitable_growth_tool_notices ) {
1418 $ret = true;
1419 }
1420
1421 if ( ! empty( $charitable_growth_tool_notices['dismiss']['dashboard'] ) ) {
1422 $ret = false;
1423 }
1424
1425 // Don't show this immediately for new users.
1426 $slug = 'dashboard-growth-tool-chart';
1427
1428 // 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 campaign.
1429 $activated_datetime = ( false !== get_option( 'wpcharitable_activated_datetime' ) ) ? get_option( 'wpcharitable_activated_datetime' ) : false;
1430 $days = 0;
1431 if ( $activated_datetime ) {
1432 $diff = current_time( 'timestamp' ) - $activated_datetime;
1433 $days = abs( round( $diff / 86400 ) );
1434 }
1435
1436 $count_campaigns = wp_count_posts( 'campaign' );
1437 $total_campaigns = isset( $count_campaigns->publish ) ? $count_campaigns->publish : 0;
1438
1439 if ( $days >= apply_filters( 'charitable_days_since_activated', 14 ) && $total_campaigns >= 1 ) {
1440 // check transient.
1441 $help_pointers = get_transient( 'charitable_' . $slug . '_banner' );
1442
1443 // render five star rating banner/notice.
1444 if ( ! $help_pointers ) {
1445 return apply_filters( 'charitable_show_dashboard_growth_tool_chart_notice', $ret );
1446 }
1447 }
1448
1449 return false;
1450 }
1451
1452 /* DEPRECATED FUNCTIONS */
1453
1454 /**
1455 * Display upgrade notice at the bottom on the plugin settings pages.
1456 *
1457 * @since 1.8.1
1458 * @version 1.8.8
1459 *
1460 * @param string $view Current view inside the plugin settings page.
1461 * @param string $css_class CSS class for the cta.
1462 * @param bool $show_close_button Whether to show the close button.
1463 */
1464 public function dashboard_cta( $view = false, $css_class = 'reports-lite-cta', $show_close_button = false ) { // phpcs:ignore
1465
1466 if ( charitable_is_pro() ) {
1467 // no need to display this cta since they have a valid license.
1468 return;
1469 }
1470
1471 if ( get_option( 'charitable_lite_reports_upgrade', false ) || apply_filters( 'charitable_lite_reports_upgrade', false ) ) {
1472 return;
1473 }
1474 ?>
1475 <?php if ( $show_close_button ) : ?>
1476 <div class="charitable-cta-dismiss-container">
1477 <button type="button" class="button-link charitable-banner-dismiss dismiss">x</button>
1478 </div>
1479 <?php endif; ?>
1480 <?php charitable_render_global_upgrade_cta( $css_class ); ?>
1481 <script type="text/javascript">
1482 jQuery( function ( $ ) {
1483 $( document ).on( 'click', '.reports-lite-cta .dismiss', function ( event ) {
1484 event.preventDefault();
1485 $.post( ajaxurl, {
1486 action: 'charitable_lite_reports_upgrade',
1487 charitable_action: 'remove_lite_cta'
1488 } );
1489 $( '.reports-lite-cta' ).remove();
1490 } );
1491 } );
1492 </script>
1493 <?php
1494 }
1495
1496 /**
1497 * Dismiss upgrade notice at the bottom on the plugin settings pages.
1498 *
1499 * @since 1.7.0.4
1500 */
1501 public function reports_cta_dismiss() {
1502
1503 if ( ! charitable_current_user_can() ) {
1504 wp_send_json_error();
1505 }
1506
1507 update_option( 'charitable_lite_reports_upgrade', time() );
1508
1509 wp_send_json_success();
1510 }
1511
1512 /**
1513 * Returns and/or create the single instance of this class.
1514 *
1515 * @since 1.8.1
1516 *
1517 * @return Charitable_Dashboard_Legacy
1518 */
1519 public static function get_instance() {
1520 if ( is_null( self::$instance ) ) {
1521 self::$instance = new self();
1522 }
1523
1524 return self::$instance;
1525 }
1526 }
1527
1528 endif;
1529