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