PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.20.0
GiveWP – Donation Plugin and Fundraising Platform v3.20.0
4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / admin / tools / data / class-give-tools-recount-all-stats.php
give / includes / admin / tools / data Last commit date
class-give-tools-delete-donations.php 6 years ago class-give-tools-delete-import-donors.php 6 years ago class-give-tools-delete-test-donors.php 6 years ago class-give-tools-delete-test-transactions.php 6 years ago class-give-tools-recount-all-stats.php 6 years ago class-give-tools-recount-donor-stats.php 6 years ago class-give-tools-recount-form-stats.php 5 years ago class-give-tools-recount-income.php 5 years ago class-give-tools-recount-single-donor-stats.php 6 years ago class-give-tools-reset-stats.php 5 years ago tools-actions.php 7 years ago
class-give-tools-recount-all-stats.php
493 lines
1 <?php
2 /**
3 * Recount all donation counts and income stats
4 *
5 * This class handles batch processing of recounting donations and income stat totals
6 *
7 * @subpackage Admin/Tools/Give_Tools_Recount_All_Stats
8 * @copyright Copyright (c) 2016, GiveWP
9 * @license https://opensource.org/licenses/gpl-license GNU Public License
10 * @since 1.5
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 /**
19 * Give_Tools_Recount_All_Stats Class
20 *
21 * @since 1.5
22 */
23 class Give_Tools_Recount_All_Stats extends Give_Batch_Export {
24
25 /**
26 * Our export type. Used for export-type specific filters/actions
27 *
28 * @since 1.5
29 * @var string
30 */
31 public $export_type = '';
32
33 /**
34 * Allows for a non-form batch processing to be run.
35 *
36 * @since 1.5
37 * @var bool
38 */
39 public $is_void = true;
40
41 /**
42 * Sets the number of items to pull on each step
43 *
44 * @since 1.5
45 * @var int
46 */
47 public $per_step = 30;
48
49 /**
50 * Display message on completing recount process
51 *
52 * @since 1.8.9
53 * @var string
54 */
55 public $message = '';
56
57 /**
58 * Sets donation form id for recalculation
59 *
60 * @since 1.8.9
61 * @var int
62 */
63 protected $form_id = 0;
64
65 /**
66 * Is Recount process completed
67 *
68 * @since 1.8.9
69 * @var bool
70 */
71 public $done = false;
72
73 /**
74 * Constructor.
75 */
76 public function __construct( $_step = 1 ) {
77 parent::__construct( $_step );
78
79 $this->is_writable = true;
80 }
81
82 /**
83 * Get the recount all stats data
84 *
85 * @access public
86 * @since 1.5
87 *
88 * @return bool
89 */
90 public function get_data() {
91
92 $totals = $this->get_stored_data( 'give_temp_recount_all_stats' );
93 $payment_items = $this->get_stored_data( 'give_temp_payment_items' );
94 $processed_payments = $this->get_stored_data( 'give_temp_processed_payments' );
95 $accepted_statuses = apply_filters( 'give_recount_accepted_statuses', array( 'publish' ) );
96
97 if ( false === $totals ) {
98 $totals = array();
99 }
100
101 if ( false === $payment_items ) {
102 $payment_items = array();
103 }
104
105 if ( false === $processed_payments ) {
106 $processed_payments = array();
107 }
108
109 $all_forms = $this->get_stored_data( 'give_temp_form_ids' );
110
111 $payments = $this->get_stored_data( 'give_temp_all_payments_data' );
112
113 if ( empty( $payments ) ) {
114 $args = apply_filters(
115 'give_recount_form_stats_args',
116 array(
117 'give_forms' => $all_forms,
118 'number' => $this->per_step,
119 'status' => $accepted_statuses,
120 'paged' => $this->step,
121 'output' => 'give_payments',
122 )
123 );
124
125 $payments_query = new Give_Payments_Query( $args );
126 $payments = $payments_query->get_payments();
127 }
128
129 if ( ! empty( $payments ) ) {
130
131 // Loop through payments
132 foreach ( $payments as $payment ) {
133
134 $payment_id = ( ! empty( $payment['ID'] ) ? absint( $payment['ID'] ) : ( ! empty( $payment->ID ) ? absint( $payment->ID ) : false ) );
135 $payment = new Give_Payment( $payment_id );
136
137 // Prevent payments that have all ready been retrieved from a previous sales log from counting again.
138 if ( in_array( $payment->ID, $processed_payments ) ) {
139 continue;
140 }
141
142 // Verify accepted status.
143 if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
144 $processed_payments[] = $payment->ID;
145 continue;
146 }
147
148 $payment_item = $payment_items[ $payment->ID ];
149
150 $form_id = isset( $payment_item['id'] ) ? $payment_item['id'] : '';
151
152 // Must have a form ID.
153 if ( empty( $form_id ) ) {
154 continue;
155 }
156
157 // Form ID must be within $all_forms array to be validated.
158 if ( ! in_array( $form_id, $all_forms ) ) {
159 continue;
160 }
161
162 // Set Sales count
163 $totals[ $form_id ]['sales'] = isset( $totals[ $form_id ]['sales'] ) ?
164 ++ $totals[ $form_id ]['sales'] :
165 1;
166
167 // Set Total Earnings
168 $totals[ $form_id ]['earnings'] = isset( $totals[ $form_id ]['earnings'] ) ?
169 ( $totals[ $form_id ]['earnings'] + $payment_item['price'] ) :
170 $payment_item['price'];
171
172 $processed_payments[] = $payment->ID;
173 }
174
175 // Get the list of form ids which does not contain any payment record.
176 $remaining_form_ids = array_diff( $all_forms, array_keys( $totals ) );
177 foreach ( $remaining_form_ids as $form_id ) {
178 // If array key doesn't exist, create it
179 if ( ! array_key_exists( $form_id, $totals ) ) {
180 $totals[ $form_id ] = array(
181 'sales' => (int) 0,
182 'earnings' => (float) 0,
183 );
184 }
185 }
186
187 $this->store_data( 'give_temp_processed_payments', $processed_payments );
188 $this->store_data( 'give_temp_recount_all_stats', $totals );
189
190 return true;
191 }
192
193 foreach ( $totals as $key => $stats ) {
194 give_update_meta( $key, '_give_form_sales', $stats['sales'] );
195 give_update_meta( $key, '_give_form_earnings', give_sanitize_amount_for_db( $stats['earnings'] ) );
196 }
197
198 return false;
199
200 }
201
202 /**
203 * Return the calculated completion percentage
204 *
205 * @since 1.5
206 * @return int
207 */
208 public function get_percentage_complete() {
209
210 $total = $this->get_stored_data( 'give_recount_all_total' );
211
212 if ( false === $total ) {
213 $this->pre_fetch();
214 $total = $this->get_stored_data( 'give_recount_all_total' );
215 }
216
217 $percentage = 100;
218
219 if ( $total > 0 ) {
220 $percentage = ( ( $this->per_step * $this->step ) / $total ) * 100;
221 }
222
223 if ( $percentage > 100 ) {
224 $percentage = 100;
225 }
226
227 return $percentage;
228 }
229
230 /**
231 * Set the properties specific to the payments export
232 *
233 * @since 1.5
234 *
235 * @param array $request The Form Data passed into the batch processing
236 */
237 public function set_properties( $request ) {
238 $this->form_id = isset( $request['form_id'] ) ? sanitize_text_field( $request['form_id'] ) : false;
239 }
240
241 /**
242 * Process a step
243 *
244 * @since 1.5
245 * @return bool
246 */
247 public function process_step() {
248
249 if ( ! $this->can_export() ) {
250 wp_die( esc_html__( 'You do not have permission to recount stats.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
251 }
252
253 $had_data = $this->get_data();
254
255 if ( $had_data ) {
256 $this->done = false;
257
258 return true;
259 } else {
260 $this->delete_data( 'give_recount_total_' . $this->form_id );
261 $this->delete_data( 'give_recount_all_total' );
262 $this->delete_data( 'give_temp_recount_all_stats' );
263 $this->delete_data( 'give_temp_payment_items' );
264 $this->delete_data( 'give_temp_form_ids' );
265 $this->delete_data( 'give_temp_processed_payments' );
266 $this->done = true;
267 $this->message = esc_html__( 'Donation form income amounts and donation counts stats successfully recounted.', 'give' );
268
269 return false;
270 }
271 }
272
273 /**
274 * Set headers.
275 */
276 public function headers() {
277 give_ignore_user_abort();
278 }
279
280 /**
281 * Perform the export
282 *
283 * @access public
284 * @since 1.5
285 * @return void
286 */
287 public function export() {
288
289 // Set headers
290 $this->headers();
291
292 give_die();
293 }
294
295 /**
296 * Pre Fetch Data
297 *
298 * @access public
299 * @since 1.5
300 */
301 public function pre_fetch() {
302
303 if ( 1 == $this->step ) {
304 $this->delete_data( 'give_temp_recount_all_total' );
305 $this->delete_data( 'give_temp_recount_all_stats' );
306 $this->delete_data( 'give_temp_payment_items' );
307 $this->delete_data( 'give_temp_processed_payments' );
308 $this->delete_data( 'give_temp_all_payments_data' );
309 }
310
311 $accepted_statuses = apply_filters( 'give_recount_accepted_statuses', array( 'publish' ) );
312 $total = $this->get_stored_data( 'give_temp_recount_all_total' );
313
314 if ( false === $total ) {
315
316 $payment_items = $this->get_stored_data( 'give_temp_payment_items' );
317
318 if ( false === $payment_items ) {
319 $payment_items = array();
320 $this->store_data( 'give_temp_payment_items', $payment_items );
321 }
322
323 $args = array(
324 'post_status' => 'publish',
325 'post_type' => 'give_forms',
326 'posts_per_page' => - 1,
327 'fields' => 'ids',
328 );
329
330 $all_forms = get_posts( $args );
331
332 $this->store_data( 'give_temp_form_ids', $all_forms );
333
334 $args = apply_filters(
335 'give_recount_form_stats_total_args',
336 array(
337 'give_forms' => $all_forms,
338 'number' => $this->per_step,
339 'status' => $accepted_statuses,
340 'page' => $this->step,
341 'output' => 'payments',
342 )
343 );
344
345 $payments_query = new Give_Payments_Query( $args );
346 $payments = $payments_query->get_payments();
347
348 $total = wp_count_posts( 'give_payment' )->publish;
349
350 $this->store_data( 'give_temp_all_payments_data', $payments );
351
352 if ( $payments ) {
353
354 foreach ( $payments as $payment ) {
355
356 $form_id = $payment->form_id;
357
358 // If for some reason somehow the form_ID isn't set check payment meta
359 if ( empty( $payment->form_id ) ) {
360 $payment_meta = $payment->get_meta();
361 $form_id = isset( $payment_meta['form_id'] ) ? $payment_meta['form_id'] : 0;
362 }
363
364 if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
365 continue;
366 }
367
368 $currency_code = give_get_payment_currency_code( $payment->ID );
369
370 if ( ! array_key_exists( $payment->ID, $payment_items ) ) {
371
372 /**
373 * Filter the payment amount.
374 *
375 * @since 2.1
376 */
377 $payment_total = apply_filters(
378 'give_donation_amount',
379 give_format_amount( $payment->total, array( 'donation_id' => $payment->ID ) ),
380 $payment->total,
381 $payment->ID,
382 array(
383 'type' => 'stats',
384 'currency' => false,
385 'amount' => false,
386 )
387 );
388
389 $payment_items[ $payment->ID ] = array(
390 'id' => $form_id,
391 'payment_id' => $payment->ID,
392 'price' => (float) give_maybe_sanitize_amount( $payment_total, array( 'currency' => $currency_code ) ),
393 );
394 }
395 }
396 }
397 $this->store_data( 'give_temp_payment_items', $payment_items );
398 $this->store_data( 'give_recount_all_total', $total );
399 }
400
401 }
402
403 /**
404 * Given a key, get the information from the Database Directly
405 *
406 * @since 1.5
407 *
408 * @param string $key The option_name
409 *
410 * @return mixed Returns the data from the database
411 */
412 private function get_stored_data( $key ) {
413 global $wpdb;
414 $value = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = '%s'", $key ) );
415 if ( empty( $value ) ) {
416 return false;
417 }
418
419 $maybe_json = json_decode( $value );
420
421 if ( ! is_null( $maybe_json ) ) {
422 $value = json_decode( $value, true );
423 }
424
425 return $value;
426 }
427
428 /**
429 * Give a key, store the value
430 *
431 * @since 1.5
432 *
433 * @param string $key The option_name
434 * @param mixed $value The value to store
435 *
436 * @return void
437 */
438 private function store_data( $key, $value ) {
439 global $wpdb;
440
441 $value = is_array( $value ) ? wp_json_encode( $value ) : esc_attr( $value );
442
443 $data = array(
444 'option_name' => $key,
445 'option_value' => $value,
446 'autoload' => 'no',
447 );
448
449 $formats = array(
450 '%s',
451 '%s',
452 '%s',
453 );
454
455 $wpdb->replace( $wpdb->options, $data, $formats );
456 }
457
458 /**
459 * Delete an option
460 *
461 * @since 1.5
462 *
463 * @param string $key The option_name to delete
464 *
465 * @return void
466 */
467 private function delete_data( $key ) {
468 global $wpdb;
469 $wpdb->delete( $wpdb->options, array( 'option_name' => $key ) );
470 }
471
472 /**
473 * Unset the properties specific to the donors export.
474 *
475 * @since 2.3.0
476 *
477 * @param array $request
478 * @param Give_Batch_Export $export
479 */
480 public function unset_properties( $request, $export ) {
481 if ( $export->done ) {
482 // Delete all the donation ids.
483 $this->delete_data( 'give_temp_all_payments_data' );
484 $this->delete_data( 'give_recount_total_' . $this->form_id );
485 $this->delete_data( 'give_recount_all_total' );
486 $this->delete_data( 'give_temp_recount_all_stats' );
487 $this->delete_data( 'give_temp_payment_items' );
488 $this->delete_data( 'give_temp_form_ids' );
489 $this->delete_data( 'give_temp_processed_payments' );
490 }
491 }
492 }
493