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.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 1.7.0.9 All 211 releases
charitable / includes / admin / reports / class-charitable-reports-ajax.php

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

465 lines 16.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Charitable Reports Ajax.
4 *
5 * @package Charitable/Classes/Charitable_Reports_Ajax
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_Reports_Ajax' ) ) :
19
20 /**
21 * Charitable_Reports_Ajax
22 *
23 * @final
24 * @since 1.8.1
25 */
26 class Charitable_Reports_Ajax {
27
28 /**
29 * The single instance of this class.
30 *
31 * @var Charitable_Reports_Ajax|null
32 */
33 private static $instance = null;
34
35 /**
36 * Create object instance.
37 *
38 * @since 1.8.1
39 */
40 public function __construct() {
41 }
42
43 /**
44 * Run things upon init.
45 *
46 * @since 1.8.1
47 */
48 public function init() {
49 }
50
51 /**
52 * Generate and return data that overview report needs.
53 *
54 * @since 1.8.1
55 *
56 * @return void
57 */
58 public function get_overview_data() {
59
60 // security check.
61 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'charitable-reporting' ) ) { // phpcs:ignore
62 wp_send_json_error( 'Invalid nonce.' );
63 exit;
64 }
65
66 // Current user cannot handle this request.
67 if ( ! current_user_can( 'manage_options' ) ) {
68 return;
69 }
70
71 $start_date = ! empty( $_POST['start_date'] ) ? sanitize_text_field( $_POST['start_date'] ) : false; // phpcs:ignore
72 $end_date = ! empty( $_POST['end_date'] ) ? sanitize_text_field( $_POST['end_date'] ) : false; // phpcs:ignore
73 $campaign_id = ! empty( $_POST['campaign_id'] ) ? intval( $_POST['campaign_id'] ) : false; // phpcs:ignore
74 $category_id = ! empty( $_POST['campaign_category_id'] ) ? intval( $_POST['campaign_category_id'] ) : false; // phpcs:ignore
75 $filter = ! empty( $_POST['filter'] ) ? sanitize_text_field( $_POST['filter'] ) : false; // phpcs:ignore
76 $report_type = ! empty( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : 'overview'; // phpcs:ignore
77 $status = ! empty( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : false; // phpcs:ignore
78
79 $start_date = str_replace( '/', '-', $start_date );
80 $end_date = str_replace( '/', '-', $end_date );
81
82 $charitable_reports = Charitable_Reports::get_instance();
83
84 $args = array(
85 'start_date' => $start_date,
86 'end_date' => $end_date,
87 'status' => $status,
88 'campaign_id' => $campaign_id,
89 'category_id' => $category_id,
90 );
91
92 $charitable_reports->init_with_array( $report_type, $args );
93
94 $donations = $charitable_reports->get_donations();
95
96 $charitable_reports->init_axis_with_donations( $donations, $start_date, $end_date );
97
98 $donations = $charitable_reports->get_donations();
99 $total_count_donations = count( $donations );
100 $total_amount_donations = $charitable_reports->get_donations_total();
101 $donation_average = intval( $total_amount_donations ) > 0 && intval( $total_count_donations ) > 0 ? charitable_format_money( $total_amount_donations / $total_count_donations, 2, true ) : 0;
102 $donation_total = charitable_format_money( $total_amount_donations, 2, true );
103 $total_count_donors = $charitable_reports->get_donors_count();
104
105 // Called once. This used to be called twice, the first result being overwritten
106 // without ever being read, which doubled the cost of the whole request.
107 $donation_breakdown = $charitable_reports->get_donations_by_day();
108
109 $refunds_data = $charitable_reports->get_refunds();
110 $total_amount_refunds = charitable_format_money( $refunds_data['total_amount'], 2, true );
111 $total_count_refunds = $refunds_data['total_count'];
112
113 $payment_breakdown = $charitable_reports->get_donations_by_payment();
114
115 $top_donors = $charitable_reports->get_top_donors_overview();
116
117 // campaigns.
118 $top_campaigns_args = false;
119 $top_campaigns = Charitable_Campaigns::ordered_by_amount( $top_campaigns_args );
120
121 // main activity.
122 $report_activity = $charitable_reports->get_activity();
123
124 $report_html = array();
125
126 $report_html['html']['donation_breakdown'] = $charitable_reports->generate_donations_breakdown_rows( $donation_breakdown, $refunds_data );
127 $report_html['headline_chart_options']['donation_axis'] = (array) $charitable_reports->donation_axis;
128 $report_html['headline_chart_options']['date_axis'] = (array) $charitable_reports->date_axis;
129 $report_html['donation_amount'] = $donation_total;
130 $report_html['donation_count'] = $total_count_donations;
131 $report_html['donation_average'] = $donation_average;
132 $report_html['donors_count'] = $total_count_donors;
133 $report_html['refund_total_amount'] = $total_amount_refunds;
134 $report_html['refund_count'] = $total_count_refunds;
135 $report_html['payment_methods_chart']['payment_percentages'] = (array) array_reverse( $charitable_reports->payment_percentages );
136 $report_html['payment_methods_chart']['payment_labels'] = (array) array_reverse( $charitable_reports->payment_labels );
137 $report_html['html']['payment_methods_list'] = $charitable_reports->generate_payment_methods_list( $payment_breakdown );
138 $report_html['html']['activities'] = $charitable_reports->generate_activity_list( $report_activity );
139 $report_html['html']['top_donors_list'] = $charitable_reports->generate_top_donors( $top_donors );
140 $report_html['html']['top_campaigns_list'] = $charitable_reports->generate_top_campaigns( $top_campaigns );
141
142 // Cache via transients the 'charitable_report_overview_args' for 1 hour.
143 $charitable_report_overview_args = array(
144 'start_date' => $start_date,
145 'end_date' => $end_date,
146 'filter' => $filter,
147 'campaign_id' => $campaign_id,
148 );
149
150 $was_cached = set_transient( 'charitable-report-overview-args', $charitable_report_overview_args, 60 * 60 );
151
152 $report_html['was_cached'] = $was_cached;
153
154 wp_send_json_success( $report_html );
155
156 exit;
157 }
158
159 /**
160 * Generate and return data that activity report needs.
161 *
162 * @since 1.8.1
163 *
164 * @return void
165 */
166 public function get_activity_data() {
167
168 // security check.
169 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'charitable-reporting' ) ) { // phpcs:ignore
170 wp_send_json_error( 'Invalid nonce.' );
171 exit;
172 }
173
174 // Current user cannot handle this request.
175 if ( ! current_user_can( 'manage_options' ) ) {
176 return;
177 }
178
179 $report_html = array();
180
181 $types = array( 'campaign', 'donation' );
182 $action = ! empty( $_POST['activity_type'] ) ? esc_attr( $_POST['activity_type'] ) : ''; // phpcs:ignore
183 $campaign_id = ! empty( $_POST['campaign_id'] ) ? intval( $_POST['campaign_id'] ) : false; // phpcs:ignore
184 $category_id = ! empty( $_POST['category_id'] ) ? intval( $_POST['category_id'] ) : false; // phpcs:ignore
185 $activity_type = ! empty( $_POST['activity_type'] ) ? sanitize_text_field( $_POST['activity_type'] ) : ''; // phpcs:ignore
186 $start_date = ! empty( $_POST['start_date'] ) ? sanitize_text_field( $_POST['start_date'] ) : false; // phpcs:ignore
187 $end_date = ! empty( $_POST['end_date'] ) ? sanitize_text_field( $_POST['end_date'] ) : false; // phpcs:ignore
188 $limit = ! empty( $_POST['limit'] ) ? intval( $_POST['limit'] ) : false; // phpcs:ignore
189
190 $start_date = str_replace( '/', '-', $start_date );
191 $end_date = str_replace( '/', '-', $end_date );
192
193 $admin_activities = new Charitable_Admin_Activities();
194 $activities_args = $admin_activities->get_activity(
195 array(
196 'activity_filter_types' => array( $action ),
197 'campaign_id' => $campaign_id,
198 'category_id' => $category_id,
199 'activity_type' => $activity_type,
200 'start_date' => $start_date,
201 'end_date' => $end_date,
202 'limit' => $limit,
203 )
204 );
205 $report_activity = $admin_activities->get_activity_report_data( $activities_args );
206
207 $charitable_reports = Charitable_Reports::get_instance();
208
209 $report_html['html']['activities'] = $charitable_reports->generate_activity_list( $report_activity );
210
211 // Cache via transients the 'charitable_report_activity_args' for 1 hour.
212 $charitable_report_activity_args = array(
213 'start_date' => $start_date,
214 'end_date' => $end_date,
215 'activity_type' => $activity_type,
216 'campaign_id' => $campaign_id,
217 );
218
219 $was_cached = set_transient( 'charitable-report-activity-args', $charitable_report_activity_args, 60 * 60 );
220
221 $report_html['was_cached'] = $was_cached;
222
223 wp_send_json_success( $report_html );
224
225 exit;
226 }
227
228 /**
229 * Generate and return data that donor report needs.
230 *
231 * @since 1.8.1
232 *
233 * @return void
234 */
235 public function get_donor_data() {
236
237 // security check.
238 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'charitable-reporting' ) ) { // phpcs:ignore
239 wp_send_json_error( 'Invalid nonce.' );
240 exit;
241 }
242
243 // Current user cannot handle this request.
244 if ( ! current_user_can( 'manage_options' ) ) {
245 return;
246 }
247
248 $report_html = array();
249 $donor_breakdown = array();
250
251 $donor_report_type = isset( $_POST['report_type'] ) ? esc_attr( $_POST['report_type'] ) : 'donors-top'; // phpcs:ignore
252 $limit = isset( $_POST['limit'] ) ? intval( $_POST['limit'] ) : false;
253
254 $args = array();
255 $args['limit'] = ! $limit ? charitable_reports_get_pagination_per_page( $donor_report_type ) : $limit; // phpcs:ignore
256 $args['offset'] = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0; // phpcs:ignore
257 $args['ppage'] = isset( $_POST['ppage'] ) ? intval( $_POST['ppage'] ) : 1; // phpcs:ignore
258
259 $charitable_reports = Charitable_Reports::get_instance();
260 $charitable_reports->init_with_array( $donor_report_type, $args );
261
262 switch ( $donor_report_type ) {
263 case 'donors-top':
264 $donor_breakdown = $charitable_reports->get_top_donors();
265 break;
266 case 'donors-recurring':
267 $donor_breakdown = $charitable_reports->get_recurring_donors();
268 break;
269 case 'donors-first-time':
270 $donor_breakdown = $charitable_reports->get_first_time_donors();
271 break;
272
273 default:
274 // code...
275 break;
276 }
277
278 $report_html['html']['donors'] = $charitable_reports->generate_donor_breakdown_table_html( $donor_report_type, $donor_breakdown, $args['ppage'], $limit );
279 $report_html['html']['title_card'] = $charitable_reports->generate_title_card_html( $donor_report_type );
280
281 // Cache via transients the 'charitable_report_donor_args' for 1 hour.
282 $charitable_report_donor_args = array(
283 'donor_report_type' => $donor_report_type,
284 'limit' => $limit,
285 );
286
287 $was_cached = set_transient( 'charitable-report-donor-args', $charitable_report_donor_args, 60 * 60 );
288
289 $report_html['was_cached'] = $was_cached;
290
291 wp_send_json_success( $report_html );
292 }
293
294 /**
295 * Generate and return data that advanced screen (UI) needs.
296 * This allows addons and third parties to hook in and change the UI in the top of the advanced report page.
297 *
298 * @since 1.8.1
299 *
300 * @return void
301 */
302 public function get_advanced_report_ui() {
303
304 // security check.
305 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'charitable-reporting' ) ) { // phpcs:ignore
306 wp_send_json_error( 'Invalid nonce.' );
307 exit;
308 }
309
310 // Current user cannot handle this request.
311 if ( ! current_user_can( 'manage_options' ) ) {
312 return;
313 }
314
315 $args = array();
316 $args['start_date'] = isset( $_POST['start_date'] ) ? sanitize_text_field( $_POST['start_date'] ) : false; // phpcs:ignore
317 $args['end_date'] = isset( $_POST['end_date'] ) ? sanitize_text_field( $_POST['end_date'] ) : false; // phpcs:ignore
318 $args['selected_report_type'] = isset( $_POST['report_type'] ) ? esc_attr( $_POST['report_type'] ) : false; // phpcs:ignore
319 $args['datepickers'] = false;
320
321 $ui_html = apply_filters( 'charitable_report_advanced_ui', array(), $args );
322
323 wp_send_json_success( $ui_html );
324
325 exit;
326 }
327
328 /**
329 * Generate and return data that dashboard needs.
330 *
331 * @since 1.8.1
332 *
333 * @return void
334 */
335 public function get_dashboard_data() {
336
337 // security check.
338 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'charitable-reporting' ) ) { // phpcs:ignore
339 wp_send_json_error( 'Invalid nonce.' );
340 exit;
341 }
342
343 // Current user cannot handle this request.
344 if ( ! current_user_can( 'manage_options' ) ) {
345 return;
346 }
347
348 $report_html = array();
349
350 $start_date = isset( $_POST['start_date'] ) ? sanitize_text_field( $_POST['start_date'] ) : false; // phpcs:ignore
351 $end_date = isset( $_POST['end_date'] ) ? sanitize_text_field( $_POST['end_date'] ) : false; // phpcs:ignore
352 $days = isset( $_POST['days'] ) ? intval( $_POST['days'] ) : false;
353
354 $charitable_dashboard = Charitable_Dashboard_Legacy::get_instance();
355 $report_html['html'] = $charitable_dashboard->generate_dashboard_report_html( array( 'start_date' => $start_date, 'end_date' => $end_date, 'days' => $days ) ); // phpcs:ignore
356 $report_html['headline_chart_options']['donation_axis'] = (array) $charitable_dashboard->get_donation_axis();
357 $report_html['headline_chart_options']['date_axis'] = (array) $charitable_dashboard->get_date_axis();
358
359 // we go by days with dashbaord so adjust the start_date and end_date accordingly.
360 // Start date should be today's date and end date should be today's date plus the number of days.
361 // If days is 0, then we use the start_date and end_date.
362 if ( 0 === $days ) {
363 $start_date = $charitable_dashboard->get_start_date();
364 $end_date = $charitable_dashboard->get_end_date();
365 } else {
366 /*
367 * Site-local, not UTC: post_date is stored in site-local time, so a
368 * bound built from bare UTC "today" excludes part of today's
369 * donations on any site whose timezone is ahead of UTC.
370 *
371 * @since 1.8.13
372 */
373 $start_date = gmdate( 'Y-m-d', current_time( 'timestamp', 0 ) );
374 $end_date = gmdate( 'Y-m-d', current_time( 'timestamp', 0 ) + ( $days * 24 * 60 * 60 ) );
375 }
376 $report_html['start_date'] = $start_date;
377 $report_html['end_date'] = $end_date;
378 $report_html['days'] = $days;
379
380 // Cache via transients the 'charitable_report_donor_args' for 1 hour.
381 $charitable_dashboard_data_args = array(
382 'start_date' => $start_date,
383 'end_date' => $end_date,
384 'days' => $days,
385 'timestamp' => gmdate( 'Y/m/d h:i A', current_time( 'timestamp', 0 ) ),
386 );
387
388 $args_was_cached = set_transient( 'wpch_dashboard_data_args', $charitable_dashboard_data_args, DAY_IN_SECONDS );
389 // $html_was_cached = set_transient( 'wpch_dashboard_data_html', $report_html, 60 * 60 );
390
391 $report_html['args_was_cached'] = $args_was_cached;
392
393 wp_send_json_success( $report_html );
394 }
395
396 /**
397 * Generate and return data that the default advanced report "lybunt" needs.
398 *
399 * @since 1.8.1
400 *
401 * @return void
402 */
403 public function get_lybunt_report() {
404
405 // type check.
406 if ( ! isset( $_POST['report_type'] ) || 'lybunt' !== $_POST['report_type'] ) {
407 return;
408 }
409
410 // security check.
411 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'charitable-reporting' ) ) { // phpcs:ignore
412 wp_send_json_error( 'Invalid nonce.' );
413 exit;
414 }
415
416 // Current user cannot handle this request.
417 if ( ! current_user_can( 'manage_options' ) ) {
418 return;
419 }
420
421 $report_args = charitable_reports_get_advanced_report_args();
422
423 $charitable_reports = Charitable_Reports::get_instance();
424
425 if ( charitable_is_pro() ) :
426
427 $charitable_reports->init_with_array( 'lybunt' );
428
429 $advanced_report_data = $charitable_reports->get_advanced_data_by_report_type( $report_args );
430
431 else :
432
433 $advanced_report_data = $charitable_reports->get_data_sample( 'advanced' );
434
435 endif;
436
437 $start_date_compare_from = $report_args['start_date_compare_from'];
438 $end_date_compare_from = $report_args['end_date_compare_from'];
439 $start_date_compare_to = $report_args['start_date_compare_to'];
440 $end_date_compare_to = $report_args['end_date_compare_to'];
441
442 $report_html = array();
443 $report_html['html'] = $charitable_reports->generate_advanced_breakdown_report_html( 'lybunt', $advanced_report_data, $report_args );
444
445 wp_send_json_success( $report_html );
446 }
447
448 /**
449 * Returns and/or create the single instance of this class.
450 *
451 * @since 1.8.1
452 *
453 * @return Charitable_Reports_Ajax
454 */
455 public static function get_instance() {
456 if ( is_null( self::$instance ) ) {
457 self::$instance = new self();
458 }
459
460 return self::$instance;
461 }
462 }
463
464 endif;
465