PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.3
GiveWP – Donation Plugin and Fundraising Platform v4.16.3
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-single-donor-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 8 months 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 9 months ago tools-actions.php 7 years ago
class-give-tools-recount-single-donor-stats.php
352 lines
1 <?php
2 /**
3 * Recount single donor stats.
4 *
5 * This class handles batch processing of recounting a single donor's stats.
6 *
7 * @subpackage Admin/Tools/Give_Tools_Recount_Single_Customer_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_Single_Customer_Stats Class
20 *
21 * @since 1.5
22 */
23 class Give_Tools_Recount_Single_Customer_Stats extends Give_Batch_Export {
24
25 /**
26 * Our export type. Used for export-type specific filters/actions
27 *
28 * @var string
29 * @since 1.5
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 boolean
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 integer
46 */
47 public $per_step = 10;
48
49 /**
50 * Constructor.
51 */
52 public function __construct( $_step = 1 ) {
53 parent::__construct( $_step );
54
55 $this->is_writable = true;
56 }
57
58 /**
59 * Get the Export Data
60 *
61 * @access public
62 * @since 1.5
63 * @global object $wpdb Used to query the database using the WordPress Database API
64 * @return bool
65 */
66 public function get_data() {
67
68 $donor = new Give_Donor( $this->customer_id );
69 $payments = $this->get_stored_data( 'give_recount_donor_payments_' . $donor->id );
70
71 $offset = ( $this->step - 1 ) * $this->per_step;
72 $step_items = array_slice( $payments, $offset, $this->per_step );
73
74 if ( count( $step_items ) > 0 ) {
75 $pending_total = (float) $this->get_stored_data( 'give_stats_donor_pending_total' . $donor->id );
76 $step_total = 0;
77
78 $found_payment_ids = $this->get_stored_data( 'give_stats_found_payments_' . $donor->id );
79
80 foreach ( $step_items as $payment ) {
81 $payment = get_post( $payment->ID );
82
83 if ( is_null( $payment ) || is_wp_error( $payment ) || 'give_payment' !== $payment->post_type ) {
84
85 $missing_payments = $this->get_stored_data( 'give_stats_missing_payments' . $donor->id );
86 $missing_payments[] = $payment->ID;
87 $this->store_data( 'give_stats_missing_payments' . $donor->id, $missing_payments );
88
89 continue;
90 }
91
92 $should_process_payment = 'publish' == $payment->post_status ? true : false;
93 $should_process_payment = apply_filters( 'give_donor_recount_should_process_donation', $should_process_payment, $payment );
94
95 if ( true === $should_process_payment ) {
96
97 $found_payment_ids[] = $payment->ID;
98
99 if ( apply_filters( 'give_donor_recount_should_increase_value', true, $payment ) ) {
100 $payment_amount = (float) give_donation_amount( $payment->ID, array( 'type' => 'stats' ) );
101 $step_total += $payment_amount;
102 }
103 }
104 }
105
106 $updated_total = $pending_total + $step_total;
107 $this->store_data( 'give_stats_donor_pending_total' . $donor->id, $updated_total );
108 $this->store_data( 'give_stats_found_payments_' . $donor->id, $found_payment_ids );
109
110 return true;
111 }
112
113 return false;
114
115 }
116
117 /**
118 * Return the calculated completion percentage
119 *
120 * @since 1.5
121 * @return int
122 */
123 public function get_percentage_complete() {
124
125 $payments = $this->get_stored_data( 'give_recount_donor_payments_' . $this->customer_id );
126 $total = count( $payments );
127
128 $percentage = 100;
129
130 if ( $total > 0 ) {
131 $percentage = ( ( $this->per_step * $this->step ) / $total ) * 100;
132 }
133
134 if ( $percentage > 100 ) {
135 $percentage = 100;
136 }
137
138 return $percentage;
139 }
140
141 /**
142 * Set the properties specific to the payments export
143 *
144 * @since 1.5
145 *
146 * @param array $request The Form Data passed into the batch processing
147 */
148 public function set_properties( $request ) {
149 $this->customer_id = isset( $request['customer_id'] ) ? sanitize_text_field( $request['customer_id'] ) : false;
150 }
151
152 /**
153 * Process a step
154 *
155 * @since 1.5
156 * @return bool
157 */
158 public function process_step() {
159
160 if ( ! $this->can_export() ) {
161 wp_die( esc_html__( 'You do not have permission to recount stats.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
162 }
163
164 $had_data = $this->get_data();
165
166 if ( $had_data ) {
167 $this->done = false;
168
169 return true;
170 } else {
171 $donor = new Give_Donor( $this->customer_id );
172 $payment_ids = get_option( 'give_stats_found_payments_' . $donor->id, array() );
173 $this->delete_data( 'give_stats_found_payments_' . $donor->id );
174
175 $removed_payments = array_unique( get_option( 'give_stats_missing_payments' . $donor->id, array() ) );
176
177 // Find non-existing payments (deleted) and total up the donation count
178 $purchase_count = 0;
179 foreach ( $payment_ids as $key => $payment_id ) {
180 if ( in_array( $payment_id, $removed_payments ) ) {
181 unset( $payment_ids[ $key ] );
182 continue;
183 }
184
185 $payment = get_post( $payment_id );
186 if ( apply_filters( 'give_donor_recount_should_increase_count', true, $payment ) ) {
187 $purchase_count ++;
188 }
189 }
190
191 $this->delete_data( 'give_stats_missing_payments' . $donor->id );
192
193 $pending_total = $this->get_stored_data( 'give_stats_donor_pending_total' . $donor->id );
194 $this->delete_data( 'give_stats_donor_pending_total' . $donor->id );
195 $this->delete_data( 'give_recount_donor_stats_' . $donor->id );
196 $this->delete_data( 'give_recount_donor_payments_' . $this->customer_id );
197
198 $payment_ids = implode( ',', $payment_ids );
199 $donor->update(
200 array(
201 'payment_ids' => $payment_ids,
202 'purchase_count' => $purchase_count,
203 'purchase_value' => $pending_total,
204 )
205 );
206
207 $this->done = true;
208 $this->message = esc_html__( 'Donor stats have been successfully recounted.', 'give' );
209
210 return false;
211 }
212 }
213
214 public function headers() {
215 give_ignore_user_abort();
216 }
217
218 /**
219 * Perform the export
220 *
221 * @access public
222 * @since 1.5
223 * @return void
224 */
225 public function export() {
226
227 // Set headers
228 $this->headers();
229
230 give_die();
231 }
232
233 /**
234 * Zero out the data on step one
235 *
236 * @access public
237 * @since 1.5
238 * @return void
239 */
240 public function pre_fetch() {
241 if ( $this->step === 1 ) {
242 $allowed_payment_status = apply_filters( 'give_recount_donors_donation_statuses', give_get_payment_status_keys() );
243
244 // Before we start, let's zero out the customer's data
245 $donor = new Give_Donor( $this->customer_id );
246 $donor->update(
247 array(
248 'purchase_value' => give_format_amount( 0, array( 'sanitize' => false ) ),
249 'purchase_count' => 0,
250 )
251 );
252
253 $attached_payment_ids = explode( ',', $donor->payment_ids );
254
255 $attached_args = array(
256 'post__in' => $attached_payment_ids,
257 'number' => - 1,
258 'status' => $allowed_payment_status,
259 );
260
261 $attached_payments = give_get_payments( $attached_args );
262
263 $unattached_args = array(
264 'post__not_in' => $attached_payment_ids,
265 'number' => - 1,
266 'status' => $allowed_payment_status,
267 'meta_query' => array(
268 array(
269 'key' => '_give_payment_donor_email',
270 'value' => $donor->email,
271 ),
272 ),
273 );
274
275 $unattached_payments = give_get_payments( $unattached_args );
276
277 $payments = array_merge( $attached_payments, $unattached_payments );
278
279 $this->store_data( 'give_recount_donor_payments_' . $donor->id, $payments );
280 }
281 }
282
283 /**
284 * Given a key, get the information from the Database Directly
285 *
286 * @since 1.5
287 *
288 * @param string $key The option_name
289 *
290 * @return mixed Returns the data from the database
291 */
292 private function get_stored_data( $key ) {
293 global $wpdb;
294 $value = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = '%s'", $key ) );
295
296 if ( empty( $value ) ) {
297 return false;
298 }
299
300 $maybe_json = json_decode( $value );
301 if ( ! is_null( $maybe_json ) ) {
302 $value = json_decode( $value, true );
303 }
304
305 return $value;
306 }
307
308 /**
309 * Give a key, store the value
310 *
311 * @since 1.5
312 *
313 * @param string $key The option_name
314 * @param mixed $value The value to store
315 *
316 * @return void
317 */
318 private function store_data( $key, $value ) {
319 global $wpdb;
320
321 $value = is_array( $value ) ? wp_json_encode( $value ) : esc_attr( $value );
322
323 $data = array(
324 'option_name' => $key,
325 'option_value' => $value,
326 'autoload' => 'no',
327 );
328
329 $formats = array(
330 '%s',
331 '%s',
332 '%s',
333 );
334
335 $wpdb->replace( $wpdb->options, $data, $formats );
336 }
337
338 /**
339 * Delete an option
340 *
341 * @since 1.5
342 *
343 * @param string $key The option_name to delete
344 *
345 * @return void
346 */
347 private function delete_data( $key ) {
348 global $wpdb;
349 $wpdb->delete( $wpdb->options, array( 'option_name' => $key ) );
350 }
351 }
352