PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.4.5
GiveWP – Donation Plugin and Fundraising Platform v2.4.5
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 7 years ago class-give-tools-delete-import-donors.php 7 years ago class-give-tools-delete-test-donors.php 7 years ago class-give-tools-delete-test-transactions.php 7 years ago class-give-tools-recount-all-stats.php 7 years ago class-give-tools-recount-donor-stats.php 8 years ago class-give-tools-recount-form-stats.php 7 years ago class-give-tools-recount-income.php 7 years ago class-give-tools-recount-single-donor-stats.php 7 years ago class-give-tools-reset-stats.php 7 years ago tools-actions.php 7 years ago
class-give-tools-recount-all-stats.php
482 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( 'give_recount_form_stats_args', array(
115 'give_forms' => $all_forms,
116 'number' => $this->per_step,
117 'status' => $accepted_statuses,
118 'paged' => $this->step,
119 'output' => 'give_payments',
120 ) );
121
122 $payments_query = new Give_Payments_Query( $args );
123 $payments = $payments_query->get_payments();
124 }
125
126 if ( ! empty( $payments ) ) {
127
128 //Loop through payments
129 foreach ( $payments as $payment ) {
130
131 $payment_id = ( ! empty( $payment['ID'] ) ? absint( $payment['ID'] ) : ( ! empty( $payment->ID ) ? absint( $payment->ID ) : false ) );
132 $payment = new Give_Payment( $payment_id );
133
134 // Prevent payments that have all ready been retrieved from a previous sales log from counting again.
135 if ( in_array( $payment->ID, $processed_payments ) ) {
136 continue;
137 }
138
139 // Verify accepted status.
140 if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
141 $processed_payments[] = $payment->ID;
142 continue;
143 }
144
145 $payment_item = $payment_items[ $payment->ID ];
146
147 $form_id = isset( $payment_item['id'] ) ? $payment_item['id'] : '';
148
149 // Must have a form ID.
150 if ( empty( $form_id ) ) {
151 continue;
152 }
153
154 // Form ID must be within $all_forms array to be validated.
155 if ( ! in_array( $form_id, $all_forms ) ) {
156 continue;
157 }
158
159 // Set Sales count
160 $totals[ $form_id ]['sales'] = isset( $totals[ $form_id ]['sales'] ) ?
161 ++ $totals[ $form_id ]['sales'] :
162 1;
163
164 // Set Total Earnings
165 $totals[ $form_id ]['earnings'] = isset( $totals[ $form_id ]['earnings'] ) ?
166 ( $totals[ $form_id ]['earnings'] + $payment_item['price'] ) :
167 $payment_item['price'];
168
169 $processed_payments[] = $payment->ID;
170 }
171
172 // Get the list of form ids which does not contain any payment record.
173 $remaining_form_ids = array_diff( $all_forms, array_keys( $totals ) );
174 foreach ( $remaining_form_ids as $form_id ) {
175 //If array key doesn't exist, create it
176 if ( ! array_key_exists( $form_id, $totals ) ) {
177 $totals[ $form_id ] = array(
178 'sales' => (int) 0,
179 'earnings' => (float) 0,
180 );
181 }
182 }
183
184 $this->store_data( 'give_temp_processed_payments', $processed_payments );
185 $this->store_data( 'give_temp_recount_all_stats', $totals );
186
187 return true;
188 }
189
190
191 foreach ( $totals as $key => $stats ) {
192 give_update_meta( $key, '_give_form_sales', $stats['sales'] );
193 give_update_meta( $key, '_give_form_earnings', give_sanitize_amount_for_db( $stats['earnings'] ) );
194 }
195
196 return false;
197
198 }
199
200 /**
201 * Return the calculated completion percentage
202 *
203 * @since 1.5
204 * @return int
205 */
206 public function get_percentage_complete() {
207
208 $total = $this->get_stored_data( 'give_recount_all_total' );
209
210 if ( false === $total ) {
211 $this->pre_fetch();
212 $total = $this->get_stored_data( 'give_recount_all_total' );
213 }
214
215 $percentage = 100;
216
217 if ( $total > 0 ) {
218 $percentage = ( ( $this->per_step * $this->step ) / $total ) * 100;
219 }
220
221 if ( $percentage > 100 ) {
222 $percentage = 100;
223 }
224
225 return $percentage;
226 }
227
228 /**
229 * Set the properties specific to the payments export
230 *
231 * @since 1.5
232 *
233 * @param array $request The Form Data passed into the batch processing
234 */
235 public function set_properties( $request ) {
236 $this->form_id = isset( $request['form_id'] ) ? sanitize_text_field( $request['form_id'] ) : false;
237 }
238
239 /**
240 * Process a step
241 *
242 * @since 1.5
243 * @return bool
244 */
245 public function process_step() {
246
247 if ( ! $this->can_export() ) {
248 wp_die( esc_html__( 'You do not have permission to recount stats.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
249 }
250
251 $had_data = $this->get_data();
252
253 if ( $had_data ) {
254 $this->done = false;
255
256 return true;
257 } else {
258 $this->delete_data( 'give_recount_total_' . $this->form_id );
259 $this->delete_data( 'give_recount_all_total' );
260 $this->delete_data( 'give_temp_recount_all_stats' );
261 $this->delete_data( 'give_temp_payment_items' );
262 $this->delete_data( 'give_temp_form_ids' );
263 $this->delete_data( 'give_temp_processed_payments' );
264 $this->done = true;
265 $this->message = esc_html__( 'Donation form income amounts and donation counts stats successfully recounted.', 'give' );
266
267 return false;
268 }
269 }
270
271 /**
272 * Set headers.
273 */
274 public function headers() {
275 give_ignore_user_abort();
276 }
277
278 /**
279 * Perform the export
280 *
281 * @access public
282 * @since 1.5
283 * @return void
284 */
285 public function export() {
286
287 // Set headers
288 $this->headers();
289
290 give_die();
291 }
292
293 /**
294 * Pre Fetch Data
295 *
296 * @access public
297 * @since 1.5
298 */
299 public function pre_fetch() {
300
301 if ( 1 == $this->step ) {
302 $this->delete_data( 'give_temp_recount_all_total' );
303 $this->delete_data( 'give_temp_recount_all_stats' );
304 $this->delete_data( 'give_temp_payment_items' );
305 $this->delete_data( 'give_temp_processed_payments' );
306 $this->delete_data( 'give_temp_all_payments_data' );
307 }
308
309 $accepted_statuses = apply_filters( 'give_recount_accepted_statuses', array( 'publish' ) );
310 $total = $this->get_stored_data( 'give_temp_recount_all_total' );
311
312 if ( false === $total ) {
313
314 $payment_items = $this->get_stored_data( 'give_temp_payment_items' );
315
316 if ( false === $payment_items ) {
317 $payment_items = array();
318 $this->store_data( 'give_temp_payment_items', $payment_items );
319 }
320
321 $args = array(
322 'post_status' => 'publish',
323 'post_type' => 'give_forms',
324 'posts_per_page' => - 1,
325 'fields' => 'ids',
326 );
327
328 $all_forms = get_posts( $args );
329
330 $this->store_data( 'give_temp_form_ids', $all_forms );
331
332 $args = apply_filters( 'give_recount_form_stats_total_args', array(
333 'give_forms' => $all_forms,
334 'number' => $this->per_step,
335 'status' => $accepted_statuses,
336 'page' => $this->step,
337 'output' => 'payments',
338 ) );
339
340 $payments_query = new Give_Payments_Query( $args );
341 $payments = $payments_query->get_payments();
342
343 $total = wp_count_posts( 'give_payment' )->publish;
344
345 $this->store_data( 'give_temp_all_payments_data', $payments );
346
347 if ( $payments ) {
348
349 foreach ( $payments as $payment ) {
350
351 $form_id = $payment->form_id;
352
353 //If for some reason somehow the form_ID isn't set check payment meta
354 if ( empty( $payment->form_id ) ) {
355 $payment_meta = $payment->get_meta();
356 $form_id = isset( $payment_meta['form_id'] ) ? $payment_meta['form_id'] : 0;
357 }
358
359 if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
360 continue;
361 }
362
363 if ( ! array_key_exists( $payment->ID, $payment_items ) ) {
364
365 /**
366 * Filter the payment amount.
367 *
368 * @since 2.1
369 */
370 $payment_total = apply_filters(
371 'give_donation_amount',
372 give_format_amount( $payment->total, array( 'donation_id' => $payment->ID ) ),
373 $payment->total,
374 $payment->ID,
375 array( 'type' => 'stats', 'currency' => false, 'amount' => false )
376 );
377
378 $payment_items[ $payment->ID ] = array(
379 'id' => $form_id,
380 'payment_id' => $payment->ID,
381 'price' => (float) give_maybe_sanitize_amount( $payment_total ),
382 );
383 }
384 }
385 }
386 $this->store_data( 'give_temp_payment_items', $payment_items );
387 $this->store_data( 'give_recount_all_total', $total );
388 }
389
390 }
391
392 /**
393 * Given a key, get the information from the Database Directly
394 *
395 * @since 1.5
396 *
397 * @param string $key The option_name
398 *
399 * @return mixed Returns the data from the database
400 */
401 private function get_stored_data( $key ) {
402 global $wpdb;
403 $value = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = '%s'", $key ) );
404 if ( empty( $value ) ) {
405 return false;
406 }
407
408 $maybe_json = json_decode( $value );
409
410 if ( ! is_null( $maybe_json ) ) {
411 $value = json_decode( $value, true );
412 }
413
414 return $value;
415 }
416
417 /**
418 * Give a key, store the value
419 *
420 * @since 1.5
421 *
422 * @param string $key The option_name
423 * @param mixed $value The value to store
424 *
425 * @return void
426 */
427 private function store_data( $key, $value ) {
428 global $wpdb;
429
430 $value = is_array( $value ) ? wp_json_encode( $value ) : esc_attr( $value );
431
432 $data = array(
433 'option_name' => $key,
434 'option_value' => $value,
435 'autoload' => 'no',
436 );
437
438 $formats = array(
439 '%s',
440 '%s',
441 '%s',
442 );
443
444 $wpdb->replace( $wpdb->options, $data, $formats );
445 }
446
447 /**
448 * Delete an option
449 *
450 * @since 1.5
451 *
452 * @param string $key The option_name to delete
453 *
454 * @return void
455 */
456 private function delete_data( $key ) {
457 global $wpdb;
458 $wpdb->delete( $wpdb->options, array( 'option_name' => $key ) );
459 }
460
461 /**
462 * Unset the properties specific to the donors export.
463 *
464 * @since 2.3.0
465 *
466 * @param array $request
467 * @param Give_Batch_Export $export
468 */
469 public function unset_properties( $request, $export ) {
470 if ( $export->done ) {
471 // Delete all the donation ids.
472 $this->delete_data( 'give_temp_all_payments_data' );
473 $this->delete_data( 'give_recount_total_' . $this->form_id );
474 $this->delete_data( 'give_recount_all_total' );
475 $this->delete_data( 'give_temp_recount_all_stats' );
476 $this->delete_data( 'give_temp_payment_items' );
477 $this->delete_data( 'give_temp_form_ids' );
478 $this->delete_data( 'give_temp_processed_payments' );
479 }
480 }
481 }
482