|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* Recount all customer stats |
|
4
|
|
|
* |
|
5
|
|
|
* This class handles batch processing of recounting all customer stats |
|
6
|
|
|
* |
|
7
|
|
|
* @subpackage Admin/Tools/Give_Tools_Recount_Customer_Stats |
|
8
|
|
|
* @copyright Copyright (c) 2016, Chris Klosowski |
|
9
|
|
|
* @license http://opensource.org/licenses/gpl-2.0.php 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_Customer_Stats Class |
|
20
|
|
|
* |
|
21
|
|
|
* @since 1.5 |
|
22
|
|
|
*/ |
|
23
|
|
|
class Give_Tools_Recount_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 = 5; |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* Get the Export Data |
|
48
|
|
|
* |
|
49
|
|
|
* @access public |
|
50
|
|
|
* @since 1.5 |
|
51
|
|
|
* @global object $wpdb Used to query the database using the WordPress |
|
52
|
|
|
* Database API |
|
53
|
|
|
* @return array $data The data for the CSV file |
|
54
|
|
|
*/ |
|
55
|
|
|
public function get_data() { |
|
56
|
|
|
|
|
57
|
|
|
$args = array( |
|
58
|
|
|
'number' => $this->per_step, |
|
59
|
|
|
'offset' => $this->per_step * ( $this->step - 1 ), |
|
60
|
|
|
'orderby' => 'id', |
|
61
|
|
|
'order' => 'DESC', |
|
62
|
|
|
); |
|
63
|
|
|
|
|
64
|
|
|
$customers = Give()->customers->get_customers( $args ); |
|
65
|
|
|
|
|
66
|
|
|
if ( $customers ) { |
|
67
|
|
|
|
|
68
|
|
|
$allowed_payment_status = apply_filters( 'give_recount_customer_payment_statuses', give_get_payment_status_keys() ); |
|
69
|
|
|
|
|
70
|
|
|
foreach ( $customers as $customer ) { |
|
71
|
|
|
|
|
72
|
|
|
$attached_payment_ids = explode( ',', $customer->payment_ids ); |
|
73
|
|
|
|
|
74
|
|
|
$attached_args = array( |
|
75
|
|
|
'post__in' => $attached_payment_ids, |
|
76
|
|
|
'number' => - 1, |
|
77
|
|
|
'status' => $allowed_payment_status, |
|
78
|
|
|
); |
|
79
|
|
|
|
|
80
|
|
|
$attached_payments = (array) give_get_payments( $attached_args ); |
|
81
|
|
|
|
|
82
|
|
|
$unattached_args = array( |
|
83
|
|
|
'post__not_in' => $attached_payment_ids, |
|
84
|
|
|
'number' => - 1, |
|
85
|
|
|
'status' => $allowed_payment_status, |
|
86
|
|
|
'meta_query' => array( |
|
87
|
|
|
array( |
|
88
|
|
|
'key' => '_give_payment_user_email', |
|
89
|
|
|
'value' => $customer->email, |
|
90
|
|
|
'compare' => '=', |
|
91
|
|
|
) |
|
92
|
|
|
), |
|
93
|
|
|
); |
|
94
|
|
|
|
|
95
|
|
|
$unattached_payments = give_get_payments( $unattached_args ); |
|
96
|
|
|
|
|
97
|
|
|
$payments = array_merge( $attached_payments, $unattached_payments ); |
|
98
|
|
|
|
|
99
|
|
|
$purchase_value = 0.00; |
|
100
|
|
|
$purchase_count = 0; |
|
101
|
|
|
$payment_ids = array(); |
|
102
|
|
|
|
|
103
|
|
|
if ( $payments ) { |
|
|
|
|
|
|
104
|
|
|
|
|
105
|
|
|
foreach ( $payments as $payment ) { |
|
106
|
|
|
|
|
107
|
|
|
$should_process_payment = 'publish' == $payment->post_status || 'revoked' == $payment->post_status ? true : false; |
|
108
|
|
|
$should_process_payment = apply_filters( 'give_customer_recount_should_process_payment', $should_process_payment, $payment ); |
|
109
|
|
|
|
|
110
|
|
|
if ( true === $should_process_payment ) { |
|
111
|
|
|
|
|
112
|
|
|
if ( apply_filters( 'give_customer_recount_should_increase_value', true, $payment ) ) { |
|
113
|
|
|
$purchase_value += give_get_payment_amount( $payment->ID ); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
if ( apply_filters( 'give_customer_recount_should_increase_count', true, $payment ) ) { |
|
117
|
|
|
$purchase_count ++; |
|
118
|
|
|
} |
|
119
|
|
|
|
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
$payment_ids[] = $payment->ID; |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
$payment_ids = implode( ',', $payment_ids ); |
|
128
|
|
|
|
|
129
|
|
|
$customer_update_data = array( |
|
130
|
|
|
'purchase_count' => $purchase_count, |
|
131
|
|
|
'purchase_value' => $purchase_value, |
|
132
|
|
|
'payment_ids' => $payment_ids, |
|
133
|
|
|
); |
|
134
|
|
|
|
|
135
|
|
|
$customer_instance = new Give_Customer( $customer->id ); |
|
136
|
|
|
$customer_instance->update( $customer_update_data ); |
|
137
|
|
|
|
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
return true; |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
return false; |
|
144
|
|
|
|
|
145
|
|
|
} |
|
146
|
|
|
|
|
147
|
|
|
/** |
|
148
|
|
|
* Return the calculated completion percentage |
|
149
|
|
|
* |
|
150
|
|
|
* @since 1.5 |
|
151
|
|
|
* @return int |
|
152
|
|
|
*/ |
|
153
|
|
|
public function get_percentage_complete() { |
|
154
|
|
|
|
|
155
|
|
|
$args = array( |
|
156
|
|
|
'number' => - 1, |
|
157
|
|
|
'orderby' => 'id', |
|
158
|
|
|
'order' => 'DESC', |
|
159
|
|
|
); |
|
160
|
|
|
|
|
161
|
|
|
$customers = Give()->customers->get_customers( $args ); |
|
162
|
|
|
$total = count( $customers ); |
|
163
|
|
|
|
|
164
|
|
|
$percentage = 100; |
|
165
|
|
|
|
|
166
|
|
|
if ( $total > 0 ) { |
|
167
|
|
|
$percentage = ( ( $this->per_step * $this->step ) / $total ) * 100; |
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
|
if ( $percentage > 100 ) { |
|
171
|
|
|
$percentage = 100; |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
return $percentage; |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Set the properties specific to the payments export |
|
179
|
|
|
* |
|
180
|
|
|
* @since 1.5 |
|
181
|
|
|
* |
|
182
|
|
|
* @param array $request The Form Data passed into the batch processing |
|
183
|
|
|
*/ |
|
184
|
|
|
public function set_properties( $request ) { |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
/** |
|
188
|
|
|
* Process a step |
|
189
|
|
|
* |
|
190
|
|
|
* @since 1.5 |
|
191
|
|
|
* @return bool |
|
192
|
|
|
*/ |
|
193
|
|
|
public function process_step() { |
|
194
|
|
|
|
|
195
|
|
|
if ( ! $this->can_export() ) { |
|
196
|
|
|
wp_die( __( 'You do not have permission to export data.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) ); |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
$had_data = $this->get_data(); |
|
200
|
|
|
|
|
201
|
|
|
if ( $had_data ) { |
|
202
|
|
|
$this->done = false; |
|
|
|
|
|
|
203
|
|
|
|
|
204
|
|
|
return true; |
|
205
|
|
|
} else { |
|
206
|
|
|
$this->done = true; |
|
207
|
|
|
$this->message = __( 'Donor stats successfully recounted.', 'give' ); |
|
|
|
|
|
|
208
|
|
|
|
|
209
|
|
|
return false; |
|
210
|
|
|
} |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
/** |
|
214
|
|
|
* Headers |
|
215
|
|
|
*/ |
|
216
|
|
|
public function headers() { |
|
217
|
|
|
ignore_user_abort( true ); |
|
218
|
|
|
|
|
219
|
|
|
if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { |
|
220
|
|
|
set_time_limit( 0 ); |
|
221
|
|
|
} |
|
222
|
|
|
} |
|
223
|
|
|
|
|
224
|
|
|
/** |
|
225
|
|
|
* Perform the export |
|
226
|
|
|
* |
|
227
|
|
|
* @access public |
|
228
|
|
|
* @since 1.5 |
|
229
|
|
|
* @return void |
|
230
|
|
|
*/ |
|
231
|
|
|
public function export() { |
|
232
|
|
|
|
|
233
|
|
|
// Set headers |
|
234
|
|
|
$this->headers(); |
|
235
|
|
|
|
|
236
|
|
|
give_die(); |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
} |
|
240
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.