1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* GetPaid_Customers_Query class |
4
|
|
|
* |
5
|
|
|
* Contains core class used to query for customers. |
6
|
|
|
* |
7
|
|
|
* @since 1.0.19 |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Main class used for querying customers. |
12
|
|
|
* |
13
|
|
|
* @since 1.0.19 |
14
|
|
|
* |
15
|
|
|
* @see GetPaid_Subscriptions_Query::prepare_query() for information on accepted arguments. |
16
|
|
|
*/ |
17
|
|
|
class GetPaid_Customers_Query { |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Query vars, after parsing |
21
|
|
|
* |
22
|
|
|
* @since 1.0.19 |
23
|
|
|
* @var array |
24
|
|
|
*/ |
25
|
|
|
public $query_vars = array(); |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* List of found customers. |
29
|
|
|
* |
30
|
|
|
* @since 1.0.19 |
31
|
|
|
* @var array |
32
|
|
|
*/ |
33
|
|
|
private $results; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Total number of found customers for the current query |
37
|
|
|
* |
38
|
|
|
* @since 1.0.19 |
39
|
|
|
* @var int |
40
|
|
|
*/ |
41
|
|
|
private $total_customers = 0; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* The SQL query used to fetch matching customers. |
45
|
|
|
* |
46
|
|
|
* @since 1.0.19 |
47
|
|
|
* @var string |
48
|
|
|
*/ |
49
|
|
|
public $request; |
50
|
|
|
|
51
|
|
|
// SQL clauses |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Contains the 'FIELDS' sql clause |
55
|
|
|
* |
56
|
|
|
* @since 1.0.19 |
57
|
|
|
* @var string |
58
|
|
|
*/ |
59
|
|
|
public $query_fields; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Contains the 'FROM' sql clause |
63
|
|
|
* |
64
|
|
|
* @since 1.0.19 |
65
|
|
|
* @var string |
66
|
|
|
*/ |
67
|
|
|
public $query_from; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Contains the 'WHERE' sql clause |
71
|
|
|
* |
72
|
|
|
* @since 1.0.19 |
73
|
|
|
* @var string |
74
|
|
|
*/ |
75
|
|
|
public $query_where; |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Contains the 'ORDER BY' sql clause |
79
|
|
|
* |
80
|
|
|
* @since 1.0.19 |
81
|
|
|
* @var string |
82
|
|
|
*/ |
83
|
|
|
public $query_orderby; |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Contains the 'LIMIT' sql clause |
87
|
|
|
* |
88
|
|
|
* @since 1.0.19 |
89
|
|
|
* @var string |
90
|
|
|
*/ |
91
|
|
|
public $query_limit; |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Class constructor. |
95
|
|
|
* |
96
|
|
|
* @since 1.0.19 |
97
|
|
|
* |
98
|
|
|
* @param null|string|array $query Optional. The query variables. |
99
|
|
|
*/ |
100
|
|
|
public function __construct( $query = null ) { |
101
|
|
|
if ( ! is_null( $query ) ) { |
102
|
|
|
$this->prepare_query( $query ); |
103
|
|
|
$this->query(); |
104
|
|
|
} |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Fills in missing query variables with default values. |
109
|
|
|
* |
110
|
|
|
* @since 1.0.19 |
111
|
|
|
* |
112
|
|
|
* @param string|array $args Query vars, as passed to `GetPaid_Subscriptions_Query`. |
113
|
|
|
* @return array Complete query variables with undefined ones filled in with defaults. |
114
|
|
|
*/ |
115
|
|
|
public static function fill_query_vars( $args ) { |
116
|
|
|
$defaults = array( |
117
|
|
|
'include' => array(), |
118
|
|
|
'exclude' => array(), |
119
|
|
|
'orderby' => 'id', |
120
|
|
|
'order' => 'DESC', |
121
|
|
|
'offset' => '', |
122
|
|
|
'number' => 10, |
123
|
|
|
'paged' => 1, |
124
|
|
|
'count_total' => true, |
125
|
|
|
'fields' => 'all', |
126
|
|
|
); |
127
|
|
|
|
128
|
|
|
foreach ( GetPaid_Customer_Data_Store::get_database_fields() as $field => $type ) { |
129
|
|
|
$defaults[ $field ] = 'any'; |
130
|
|
|
|
131
|
|
|
if ( '%f' === $type || '%d' === $type ) { |
132
|
|
|
$defaults[ $field . '_min' ] = ''; |
133
|
|
|
$defaults[ $field . '_max' ] = ''; |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
return wp_parse_args( $args, $defaults ); |
|
|
|
|
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Prepare the query variables. |
142
|
|
|
* |
143
|
|
|
* @since 1.0.19 |
144
|
|
|
* |
145
|
|
|
* @see self::fill_query_vars() For allowede args and their defaults. |
146
|
|
|
*/ |
147
|
|
|
public function prepare_query( $query = array() ) { |
148
|
|
|
global $wpdb; |
149
|
|
|
|
150
|
|
|
if ( empty( $this->query_vars ) || ! empty( $query ) ) { |
151
|
|
|
$this->query_limit = null; |
152
|
|
|
$this->query_vars = $this->fill_query_vars( $query ); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
if ( ! empty( $this->query_vars['fields'] ) && 'all' !== $this->query_vars['fields'] ) { |
156
|
|
|
$this->query_vars['fields'] = wpinv_parse_list( $this->query_vars['fields'] ); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
do_action( 'getpaid_pre_get_customers', array( &$this ) ); |
160
|
|
|
|
161
|
|
|
// Ensure that query vars are filled after 'getpaid_pre_get_customers'. |
162
|
|
|
$qv = & $this->query_vars; |
163
|
|
|
$qv = $this->fill_query_vars( $qv ); |
164
|
|
|
$table = $wpdb->prefix . 'getpaid_customers'; |
165
|
|
|
$this->query_from = "FROM $table"; |
166
|
|
|
|
167
|
|
|
// Prepare query fields. |
168
|
|
|
$this->prepare_query_fields( $qv, $table ); |
169
|
|
|
|
170
|
|
|
// Prepare query where. |
171
|
|
|
$this->prepare_query_where( $qv, $table ); |
172
|
|
|
|
173
|
|
|
// Prepare query order. |
174
|
|
|
$this->prepare_query_order( $qv, $table ); |
175
|
|
|
|
176
|
|
|
// limit |
177
|
|
|
if ( isset( $qv['number'] ) && $qv['number'] > 0 ) { |
178
|
|
|
if ( $qv['offset'] ) { |
179
|
|
|
$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $qv['number'] ); |
180
|
|
|
} else { |
181
|
|
|
$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $qv['number'] ); |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
do_action_ref_array( 'getpaid_after_customers_query', array( &$this ) ); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Prepares the query fields. |
190
|
|
|
* |
191
|
|
|
* @since 1.0.19 |
192
|
|
|
* |
193
|
|
|
* @param array $qv Query vars. |
194
|
|
|
* @param string $table Table name. |
195
|
|
|
*/ |
196
|
|
|
protected function prepare_query_fields( &$qv, $table ) { |
197
|
|
|
|
198
|
|
|
if ( is_array( $qv['fields'] ) ) { |
199
|
|
|
$qv['fields'] = array_unique( $qv['fields'] ); |
200
|
|
|
$allowed_fields = array_keys( GetPaid_Customer_Data_Store::get_database_fields() ); |
201
|
|
|
|
202
|
|
|
$query_fields = array(); |
203
|
|
|
foreach ( $qv['fields'] as $field ) { |
204
|
|
|
if ( ! in_array( $field, $allowed_fields ) ) { |
205
|
|
|
continue; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
$field = sanitize_key( $field ); |
209
|
|
|
$query_fields[] = "$table.`$field`"; |
210
|
|
|
} |
211
|
|
|
$this->query_fields = implode( ',', $query_fields ); |
212
|
|
|
} else { |
213
|
|
|
$this->query_fields = "$table.*"; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
if ( isset( $qv['count_total'] ) && $qv['count_total'] ) { |
217
|
|
|
$this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Prepares the query where. |
224
|
|
|
* |
225
|
|
|
* @since 1.0.19 |
226
|
|
|
* |
227
|
|
|
* @param array $qv Query vars. |
228
|
|
|
* @param string $table Table name. |
229
|
|
|
*/ |
230
|
|
|
protected function prepare_query_where( &$qv, $table ) { |
231
|
|
|
global $wpdb; |
232
|
|
|
$this->query_where = 'WHERE 1=1'; |
233
|
|
|
|
234
|
|
|
// Fields. |
235
|
|
|
foreach ( GetPaid_Customer_Data_Store::get_database_fields() as $field => $type ) { |
236
|
|
|
if ( 'any' !== $qv[ $field ] ) { |
237
|
|
|
|
238
|
|
|
// In. |
239
|
|
|
if ( is_array( $qv[ $field ] ) ) { |
240
|
|
|
$in = join( ',', array_fill( 0, count( $qv[ $field ] ), $type ) ); |
241
|
|
|
$this->query_where .= $wpdb->prepare( " AND $table.`status` IN ( $in )", $qv[ $field ] ); |
242
|
|
|
} elseif ( ! empty( $qv[ $field ] ) ) { |
243
|
|
|
$this->query_where .= $wpdb->prepare( " AND $table.`$field` = $type", $qv[ $field ] ); |
244
|
|
|
} |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
// Min/Max. |
248
|
|
|
if ( '%f' === $type || '%d' === $type ) { |
249
|
|
|
|
250
|
|
|
// Min. |
251
|
|
|
if ( is_numeric( $qv[ $field . '_min' ] ) ) { |
252
|
|
|
$this->query_where .= $wpdb->prepare( " AND $table.`$field` >= $type", $qv[ $field . '_min' ] ); |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
// Max. |
256
|
|
|
if ( is_numeric( $qv[ $field . '_max' ] ) ) { |
257
|
|
|
$this->query_where .= $wpdb->prepare( " AND $table.`$field` <= $type", $qv[ $field . '_max' ] ); |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
if ( ! empty( $qv['include'] ) ) { |
263
|
|
|
$include = implode( ',', wp_parse_id_list( $qv['include'] ) ); |
264
|
|
|
$this->query_where .= " AND $table.`id` IN ($include)"; |
265
|
|
|
} elseif ( ! empty( $qv['exclude'] ) ) { |
266
|
|
|
$exclude = implode( ',', wp_parse_id_list( $qv['exclude'] ) ); |
267
|
|
|
$this->query_where .= " AND $table.`id` NOT IN ($exclude)"; |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
// Date queries are allowed for the customer creation date. |
271
|
|
|
if ( ! empty( $qv['date_created_query'] ) && is_array( $qv['date_created_query'] ) ) { |
272
|
|
|
$date_created_query = new WP_Date_Query( $qv['date_created_query'], "$table.date_created" ); |
273
|
|
|
$this->query_where .= $date_created_query->get_sql(); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Prepares the query order. |
280
|
|
|
* |
281
|
|
|
* @since 1.0.19 |
282
|
|
|
* |
283
|
|
|
* @param array $qv Query vars. |
284
|
|
|
* @param string $table Table name. |
285
|
|
|
*/ |
286
|
|
|
protected function prepare_query_order( &$qv, $table ) { |
287
|
|
|
|
288
|
|
|
// sorting. |
289
|
|
|
$qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : ''; |
290
|
|
|
$order = $this->parse_order( $qv['order'] ); |
291
|
|
|
|
292
|
|
|
// Default order is by 'id' (latest customers). |
293
|
|
|
if ( empty( $qv['orderby'] ) ) { |
294
|
|
|
$qv['orderby'] = array( 'id' ); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
// 'orderby' values may be an array, comma- or space-separated list. |
298
|
|
|
$ordersby = array_filter( wpinv_parse_list( $qv['orderby'] ) ); |
299
|
|
|
|
300
|
|
|
$orderby_array = array(); |
301
|
|
|
foreach ( $ordersby as $_key => $_value ) { |
302
|
|
|
|
303
|
|
|
if ( is_int( $_key ) ) { |
304
|
|
|
// Integer key means this is a flat array of 'orderby' fields. |
305
|
|
|
$_orderby = $_value; |
306
|
|
|
$_order = $order; |
307
|
|
|
} else { |
308
|
|
|
// Non-integer key means that the key is the field and the value is ASC/DESC. |
309
|
|
|
$_orderby = $_key; |
310
|
|
|
$_order = $_value; |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
$parsed = $this->parse_orderby( $_orderby, $table ); |
314
|
|
|
|
315
|
|
|
if ( $parsed ) { |
316
|
|
|
$orderby_array[] = $parsed . ' ' . $this->parse_order( $_order ); |
317
|
|
|
} |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
// If no valid clauses were found, order by id. |
321
|
|
|
if ( empty( $orderby_array ) ) { |
322
|
|
|
$orderby_array[] = "id $order"; |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
$this->query_orderby = 'ORDER BY ' . implode( ', ', $orderby_array ); |
326
|
|
|
|
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
/** |
330
|
|
|
* Execute the query, with the current variables. |
331
|
|
|
* |
332
|
|
|
* @since 1.0.19 |
333
|
|
|
* |
334
|
|
|
* @global wpdb $wpdb WordPress database abstraction object. |
335
|
|
|
*/ |
336
|
|
|
public function query() { |
337
|
|
|
global $wpdb; |
338
|
|
|
|
339
|
|
|
$qv =& $this->query_vars; |
340
|
|
|
|
341
|
|
|
// Return a non-null value to bypass the default GetPaid customers query and remember to set the |
342
|
|
|
// total_customers property. |
343
|
|
|
$this->results = apply_filters_ref_array( 'getpaid_customers_pre_query', array( null, &$this ) ); |
344
|
|
|
|
345
|
|
|
if ( null === $this->results ) { |
346
|
|
|
$this->request = "SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"; |
347
|
|
|
|
348
|
|
|
if ( ( is_array( $qv['fields'] ) && 1 !== count( $qv['fields'] ) ) || 'all' === $qv['fields'] ) { |
349
|
|
|
$this->results = $wpdb->get_results( $this->request ); |
350
|
|
|
} else { |
351
|
|
|
$this->results = $wpdb->get_col( $this->request ); |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
if ( isset( $qv['count_total'] ) && $qv['count_total'] ) { |
355
|
|
|
$found_customers_query = apply_filters( 'getpaid_found_customers_query', 'SELECT FOUND_ROWS()', $this ); |
356
|
|
|
$this->total_customers = (int) $wpdb->get_var( $found_customers_query ); |
357
|
|
|
} |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
if ( 'all' === $qv['fields'] ) { |
361
|
|
|
foreach ( $this->results as $key => $customer ) { |
362
|
|
|
$this->set_cache( $customer->id, $customer, 'getpaid_customers' ); |
363
|
|
|
$this->set_cache( $customer->user_id, $customer->id, 'getpaid_customer_ids_by_user_id' ); |
364
|
|
|
$this->set_cache( $customer->email, $customer->id, 'getpaid_customer_ids_by_email' ); |
365
|
|
|
$this->results[ $key ] = new GetPaid_Customer( $customer ); |
366
|
|
|
} |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* Set cache |
373
|
|
|
* |
374
|
|
|
* @param string $id |
375
|
|
|
* @param mixed $data |
376
|
|
|
* @param string $group |
377
|
|
|
* @param integer $expire |
378
|
|
|
* @return boolean |
379
|
|
|
*/ |
380
|
|
|
public function set_cache( $key, $data, $group = '', $expire = 0 ) { |
381
|
|
|
|
382
|
|
|
if ( empty( $key ) ) { |
383
|
|
|
return false; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
wp_cache_set( $key, $data, $group, $expire ); |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
/** |
390
|
|
|
* Retrieve query variable. |
391
|
|
|
* |
392
|
|
|
* @since 1.0.19 |
393
|
|
|
* |
394
|
|
|
* @param string $query_var Query variable key. |
395
|
|
|
* @return mixed |
396
|
|
|
*/ |
397
|
|
|
public function get( $query_var ) { |
398
|
|
|
if ( isset( $this->query_vars[ $query_var ] ) ) { |
399
|
|
|
return $this->query_vars[ $query_var ]; |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
return null; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* Set query variable. |
407
|
|
|
* |
408
|
|
|
* @since 1.0.19 |
409
|
|
|
* |
410
|
|
|
* @param string $query_var Query variable key. |
411
|
|
|
* @param mixed $value Query variable value. |
412
|
|
|
*/ |
413
|
|
|
public function set( $query_var, $value ) { |
414
|
|
|
$this->query_vars[ $query_var ] = $value; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* Return the list of customers. |
419
|
|
|
* |
420
|
|
|
* @since 1.0.19 |
421
|
|
|
* |
422
|
|
|
* @return GetPaid_Customer[]|array Found customers. |
423
|
|
|
*/ |
424
|
|
|
public function get_results() { |
425
|
|
|
return $this->results; |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
/** |
429
|
|
|
* Return the total number of customers for the current query. |
430
|
|
|
* |
431
|
|
|
* @since 1.0.19 |
432
|
|
|
* |
433
|
|
|
* @return int Number of total customers. |
434
|
|
|
*/ |
435
|
|
|
public function get_total() { |
436
|
|
|
return $this->total_customers; |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* Parse and sanitize 'orderby' keys passed to the customers query. |
441
|
|
|
* |
442
|
|
|
* @since 1.0.19 |
443
|
|
|
* |
444
|
|
|
* @param string $orderby Alias for the field to order by. |
445
|
|
|
* @param string $table The current table. |
446
|
|
|
* @return string Value to use in the ORDER clause, if `$orderby` is valid. |
447
|
|
|
*/ |
448
|
|
|
protected function parse_orderby( $orderby, $table ) { |
449
|
|
|
|
450
|
|
|
$_orderby = ''; |
451
|
|
|
if ( in_array( $orderby, array_keys( GetPaid_Customer_Data_Store::get_database_fields() ), true ) ) { |
452
|
|
|
$_orderby = "$table.`$orderby`"; |
453
|
|
|
} elseif ( 'id' === strtolower( $orderby ) ) { |
454
|
|
|
$_orderby = "$table.id"; |
455
|
|
|
} elseif ( 'include' === $orderby && ! empty( $this->query_vars['include'] ) ) { |
456
|
|
|
$include = wp_parse_id_list( $this->query_vars['include'] ); |
457
|
|
|
$include_sql = implode( ',', $include ); |
458
|
|
|
$_orderby = "FIELD( $table.id, $include_sql )"; |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
return $_orderby; |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
/** |
465
|
|
|
* Parse an 'order' query variable and cast it to ASC or DESC as necessary. |
466
|
|
|
* |
467
|
|
|
* @since 1.0.19 |
468
|
|
|
* |
469
|
|
|
* @param string $order The 'order' query variable. |
470
|
|
|
* @return string The sanitized 'order' query variable. |
471
|
|
|
*/ |
472
|
|
|
protected function parse_order( $order ) { |
473
|
|
|
if ( ! is_string( $order ) || empty( $order ) ) { |
|
|
|
|
474
|
|
|
return 'DESC'; |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
if ( 'ASC' === strtoupper( $order ) ) { |
478
|
|
|
return 'ASC'; |
479
|
|
|
} else { |
480
|
|
|
return 'DESC'; |
481
|
|
|
} |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
} |
485
|
|
|
|
$args
can contain request data and is used in variable name context(s) leading to a potential security vulnerability.2 paths for user data to reach this point
$_GET,
and Data is passed throughrawurlencode_deep()
, and Data is passed throughwpinv_clean()
, andwpinv_clean(rawurlencode_deep($_GET[$field]))
is assigned to$query
in includes/admin/class-wpinv-customers-table.php on line 232$_GET,
and Data is passed throughrawurlencode_deep()
, and Data is passed throughwpinv_clean()
, andwpinv_clean(rawurlencode_deep($_GET[$field]))
is assigned to$query
in includes/admin/class-wpinv-customers-table.php on line 232
getpaid_get_customers()
is calledin includes/admin/class-wpinv-customers-table.php on line 256
$args
in includes/user-functions.php on line 20
in includes/user-functions.php on line 33
$query
in includes/class-getpaid-customers-query.php on line 100
in includes/class-getpaid-customers-query.php on line 102
$query
in includes/class-getpaid-customers-query.php on line 147
in includes/class-getpaid-customers-query.php on line 152
$args
in includes/class-getpaid-customers-query.php on line 115
$_GET,
and Data is passed throughrawurlencode_deep()
, and Data is passed throughwpinv_clean()
, andwpinv_clean(rawurlencode_deep($_GET[$field]))
is assigned to$query
in includes/admin/class-wpinv-customers-table.php on line 239$_GET,
and Data is passed throughrawurlencode_deep()
, and Data is passed throughwpinv_clean()
, andwpinv_clean(rawurlencode_deep($_GET[$field]))
is assigned to$query
in includes/admin/class-wpinv-customers-table.php on line 239
getpaid_get_customers()
is calledin includes/admin/class-wpinv-customers-table.php on line 256
$args
in includes/user-functions.php on line 20
in includes/user-functions.php on line 33
$query
in includes/class-getpaid-customers-query.php on line 100
in includes/class-getpaid-customers-query.php on line 102
$query
in includes/class-getpaid-customers-query.php on line 147
in includes/class-getpaid-customers-query.php on line 152
$args
in includes/class-getpaid-customers-query.php on line 115
Used in variable context
wp_parse_args()
is calledin includes/class-getpaid-customers-query.php on line 137
$args
in wordpress/wp-includes/functions.php on line 4821
wp_parse_str()
is calledin wordpress/wp-includes/functions.php on line 4827
$input_string
in wordpress/wp-includes/formatting.php on line 5148
parse_str()
is calledin wordpress/wp-includes/formatting.php on line 5149
General Strategies to prevent injection
In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:
For numeric data, we recommend to explicitly cast the data: