Issues (1282)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/payments/backward-compatibility.php (13 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Split _give_payment_meta to new Give core meta_keys.
4
 *
5
 * @since 2.0
6
 *
7
 * @param       $object_id
8
 * @param array $meta_value
9
 *
10
 * @return void
11
 */
12
function _give_20_bc_split_and_save_give_payment_meta( $object_id, $meta_value ) {
13
	// Bailout
14
	if ( empty( $meta_value ) ) {
15
		return;
16
	} elseif ( ! is_array( $meta_value ) ) {
17
		$meta_value = array();
18
	}
19
20
	remove_filter( 'get_post_metadata', '_give_20_bc_get_new_payment_meta', 10 );
21
22
	// Date payment meta.
23
	if ( ! empty( $meta_value['date'] ) ) {
24
		give_update_meta( $object_id, '_give_payment_date', $meta_value['date'] );
25
	}
26
27
	// Currency payment meta.
28
	if ( ! empty( $meta_value['currency'] ) ) {
29
		give_update_meta( $object_id, '_give_payment_currency', $meta_value['currency'] );
30
	}
31
32
	// User information.
33
	if ( ! empty( $meta_value['user_info'] ) ) {
34
		// Donor first name.
35
		if ( ! empty( $meta_value['user_info']['first_name'] ) ) {
36
			give_update_meta( $object_id, '_give_donor_billing_first_name', $meta_value['user_info']['first_name'] );
37
		}
38
39
		// Donor last name.
40
		if ( ! empty( $meta_value['user_info']['last_name'] ) ) {
41
			give_update_meta( $object_id, '_give_donor_billing_last_name', $meta_value['user_info']['last_name'] );
42
		}
43
44
		// Donor address payment meta.
45
		if ( ! empty( $meta_value['user_info']['address'] ) ) {
46
47
			// Address1.
48 View Code Duplication
			if ( ! empty( $meta_value['user_info']['address']['line1'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
				give_update_meta( $object_id, '_give_donor_billing_address1', $meta_value['user_info']['address']['line1'] );
50
			}
51
52
			// Address2.
53 View Code Duplication
			if ( ! empty( $meta_value['user_info']['address']['line2'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
54
				give_update_meta( $object_id, '_give_donor_billing_address2', $meta_value['user_info']['address']['line2'] );
55
			}
56
57
			// City.
58 View Code Duplication
			if ( ! empty( $meta_value['user_info']['address']['city'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
59
				give_update_meta( $object_id, '_give_donor_billing_city', $meta_value['user_info']['address']['city'] );
60
			}
61
62
			// Zip.
63 View Code Duplication
			if ( ! empty( $meta_value['user_info']['address']['zip'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
				give_update_meta( $object_id, '_give_donor_billing_zip', $meta_value['user_info']['address']['zip'] );
65
			}
66
67
			// State.
68 View Code Duplication
			if ( ! empty( $meta_value['user_info']['address']['state'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69
				give_update_meta( $object_id, '_give_donor_billing_state', $meta_value['user_info']['address']['state'] );
70
			}
71
72
			// Country.
73 View Code Duplication
			if ( ! empty( $meta_value['user_info']['address']['country'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
74
				give_update_meta( $object_id, '_give_donor_billing_country', $meta_value['user_info']['address']['country'] );
75
			}
76
		}
77
	}// End if().
78
79
	add_filter( 'get_post_metadata', '_give_20_bc_get_new_payment_meta', 10, 5 );
80
}
81
82
/**
83
 * Add backward compatibility to get meta value of _give_payment_meta meta key.
84
 *
85
 * @since 2.0
86
 *
87
 * @param       $object_id
88
 * @param array $meta_value
89
 *
90
 * @return array
91
 */
92
function _give_20_bc_give_payment_meta_value( $object_id, $meta_value ) {
93
	$cache_key = "_give_payment_meta_{$object_id}";
94
	$cache     = Give_Cache::get_db_query( $cache_key );
95
96
	if ( ! is_null( $cache ) ) {
97
		return $cache;
98
	}
99
100
	// Set default value to array.
101
	if ( ! is_array( $meta_value ) ) {
102
		$meta_value = array();
103
	}
104
105
	// Donation key.
106
	$meta_value['key'] = give_get_meta( $object_id, '_give_payment_purchase_key', true );
107
108
	// Donation form.
109
	$meta_value['form_title'] = give_get_meta( $object_id, '_give_payment_form_title', true );
110
111
	// Donor email.
112
	$meta_value['email'] = give_get_meta( $object_id, '_give_payment_donor_email', true );
113
	$meta_value['email'] = ! empty( $meta_value['email'] ) ?
114
		$meta_value['email'] :
115
		Give()->donors->get_column( 'email', give_get_payment_donor_id( $object_id ) );
116
117
	// Form id.
118
	$meta_value['form_id'] = give_get_meta( $object_id, '_give_payment_form_id', true );
119
120
	// Price id.
121
	$meta_value['price_id'] = give_get_meta( $object_id, '_give_payment_price_id', true );
122
123
	// Date.
124
	$meta_value['date'] = give_get_meta( $object_id, '_give_payment_date', true );
125
	$meta_value['date'] = ! empty( $meta_value['date'] ) ?
126
		$meta_value['date'] :
127
		get_post_field( 'post_date', $object_id );
128
129
	// Currency.
130
	$meta_value['currency'] = give_get_meta( $object_id, '_give_payment_currency', true );
131
132
	// Decode donor data.
133
	$donor_names = give_get_donor_name_by( give_get_meta( $object_id, '_give_payment_donor_id', true ), 'donor' );
134
	$donor_names = explode( ' ', $donor_names, 2 );
135
136
	// Donor first name.
137
	$donor_data['first_name'] = give_get_meta( $object_id, '_give_donor_billing_first_name', true );
138
	$donor_data['first_name'] = ! empty( $donor_data['first_name'] ) ?
139
		$donor_data['first_name'] :
140
		$donor_names[0];
141
142
	// Donor last name.
143
	$donor_data['last_name'] = give_get_meta( $object_id, '_give_donor_billing_last_name', true );
144
	$donor_data['last_name'] = ! empty( $donor_data['last_name'] ) ?
145
		$donor_data['last_name'] :
146
		( isset( $donor_names[1] ) ? $donor_names[1] : '' );
147
148
	// Donor email.
149
	$donor_data['email'] = $meta_value['email'];
150
151
	// User ID.
152
	$donor_data['id'] = give_get_payment_user_id( $object_id );
153
154
	$donor_data['address'] = false;
155
156
	// Address1.
157
	if ( $address1 = give_get_meta( $object_id, '_give_donor_billing_address1', true ) ) {
158
		$donor_data['address']['line1'] = $address1;
159
	}
160
161
	// Address2.
162
	if ( $address2 = give_get_meta( $object_id, '_give_donor_billing_address2', true ) ) {
163
		$donor_data['address']['line2'] = $address2;
164
	}
165
166
	// City.
167 View Code Duplication
	if ( $city = give_get_meta( $object_id, '_give_donor_billing_city', true ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
		$donor_data['address']['city'] = $city;
169
	}
170
171
	// Zip.
172 View Code Duplication
	if ( $zip = give_get_meta( $object_id, '_give_donor_billing_zip', true ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
173
		$donor_data['address']['zip'] = $zip;
174
	}
175
176
	// State.
177
	if ( $state = give_get_meta( $object_id, '_give_donor_billing_state', true ) ) {
178
		$donor_data['address']['state'] = $state;
179
	}
180
181
	// Country.
182
	if ( $country = give_get_meta( $object_id, '_give_donor_billing_country', true ) ) {
183
		$donor_data['address']['country'] = $country;
184
	}
185
186
	$meta_value['user_info'] = maybe_unserialize( $donor_data );
187
188
	Give_Cache::set_db_query( $cache_key, $meta_value );
189
190
	return $meta_value;
191
}
192
193
/**
194
 * Add backward compatibility old meta while saving.
195
 *  1. _give_payment_meta (split into multiple single meta keys)
196
 *  2. _give_payment_user_email (renamed to _give_payment_donor_email)
197
 *  3. _give_payment_customer_id (renamed to _give_payment_donor_id)
198
 *  4. give_payment_user_ip (renamed to give_payment_donor_ip)
199
 *
200
 * @since 2.0
201
 *
202
 * @param null|bool $check      Whether to allow updating metadata for the given type.
203
 * @param int       $object_id  Object ID.
204
 * @param string    $meta_key   Meta key.
205
 * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
206
 * @param mixed     $prev_value Optional. If specified, only update existing
207
 *                              metadata entries with the specified value.
208
 *                              Otherwise, update all entries.
209
 *
210
 * @return mixed
211
 */
212
function _give_20_bc_saving_old_payment_meta( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
0 ignored issues
show
The parameter $prev_value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
213
	// Bailout.
214
	if( 'give_payment' !== get_post_type( $object_id ) ) {
215
		return $check;
216
	}
217
218
	// Bailout.
219
	if (
220
		! in_array( $meta_key, array(
221
			'_give_payment_meta',
222
			'_give_payment_user_email',
223
			'_give_payment_customer_id',
224
			'give_payment_user_ip',
225
		) )
226
	) {
227
		return $check;
228
	}
229
230
	if ( '_give_payment_meta' === $meta_key ) {
231
		_give_20_bc_split_and_save_give_payment_meta( $object_id, $meta_value );
232
	} elseif ( '_give_payment_user_email' === $meta_key ) {
233
		give_update_meta( $object_id, '_give_payment_donor_email', $meta_value );
234
		$check = true;
235
	} elseif ( '_give_payment_customer_id' === $meta_key ) {
236
		give_update_meta( $object_id, '_give_payment_donor_id', $meta_value );
237
		$check = true;
238
	} elseif ( 'give_payment_user_ip' === $meta_key ) {
239
		give_update_meta( $object_id, '_give_payment_donor_ip', $meta_value );
240
		$check = true;
241
	}
242
243
	return $check;
244
}
245
246
add_filter( 'update_post_metadata', '_give_20_bc_saving_old_payment_meta', 10, 5 );
247
248
249
/**
250
 * Add backward compatibility to get old payment meta.
251
 *
252
 * @since 2.0
253
 *
254
 * @param $check
255
 * @param $object_id
256
 * @param $meta_key
257
 * @param $single
258
 *
259
 * @return mixed
260
 */
261
function _give_20_bc_get_old_payment_meta( $check, $object_id, $meta_key, $single ) {
262
	global $wpdb;
263
264
	// Early exit.
265
	if( 'give_payment' !== get_post_type( $object_id ) ) {
266
		return $check;
267
	}
268
	// Deprecated meta keys.
269
	$old_meta_keys = array(
270
		'_give_payment_customer_id',
271
		'_give_payment_user_email',
272
		'_give_payment_user_ip',
273
	);
274
275
	// Add _give_payment_meta to backward compatibility
276
	if ( ! give_has_upgrade_completed( 'v20_upgrades_payment_metadata' ) ) {
277
		$old_meta_keys[] = '_give_payment_meta';
278
	}
279
280
	// Bailout.
281
	if ( ! in_array( $meta_key, $old_meta_keys ) ) {
282
		return $check;
283
	}
284
285
	$cache_key = "{$meta_key}_{$object_id}";
286
	$check     = Give_Cache::get_db_query( $cache_key );
287
288
	if ( is_null( $check ) ) {
289
		switch ( $meta_key ) {
290
291
			// Handle old meta keys.
292
			case '_give_payment_meta':
293
				remove_filter( 'get_post_metadata', '_give_20_bc_get_old_payment_meta' );
294
295
				// if ( $meta_value = give_get_meta( $object_id, '_give_payment_meta' ) ) {
296
				$meta_value = ! empty( $meta_value ) ?
297
					current( $meta_value ) :
298
					(array) maybe_unserialize(
299
						$wpdb->get_var(
300
							$wpdb->prepare(
301
								"
302
								SELECT meta_value
303
								FROM $wpdb->postmeta
304
								WHERE post_id=%d
305
								AND meta_key=%s
306
								",
307
								$object_id,
308
								'_give_payment_meta'
309
							)
310
						)
311
					);
312
				$check      = _give_20_bc_give_payment_meta_value( $object_id, $meta_value );
313
				// }
314
315
				add_filter( 'get_post_metadata', '_give_20_bc_get_old_payment_meta', 10, 5 );
316
317
				break;
318
319
			case '_give_payment_customer_id':
320
				if ( $donor_id = give_get_meta( $object_id, '_give_payment_donor_id', $single ) ) {
321
					$check = $donor_id;
322
				}
323
				break;
324
325
			case '_give_payment_user_email':
326
				if ( $donor_email = give_get_meta( $object_id, '_give_payment_donor_email', $single ) ) {
327
					$check = $donor_email;
328
				}
329
				break;
330
331
			case '_give_payment_user_ip':
332
				if ( $donor_ip = give_get_meta( $object_id, '_give_payment_donor_ip', $single ) ) {
333
					$check = $donor_ip;
334
				}
335
				break;
336
		}// End switch().
337
338
		Give_Cache::set_db_query( $cache_key, $check );
339
	}
340
341
	// Put result in an array on zero index.
342
	if ( ! is_null( $check ) ) {
343
		$check = array( $check );
344
	}
345
346
	return $check;
347
}
348
349
add_filter( 'get_post_metadata', '_give_20_bc_get_old_payment_meta', 10, 5 );
350
351
352
/**
353
 * Add backward compatibility to get new payment meta.
354
 *
355
 * @since 2.0
356
 *
357
 * @param $check
358
 * @param $object_id
359
 * @param $meta_key
360
 * @param $single
361
 *
362
 * @return mixed
363
 */
364
function _give_20_bc_get_new_payment_meta( $check, $object_id, $meta_key, $single ) {
365
	global $wpdb;
366
367
	// Early exit.
368
	if( 'give_payment' !== get_post_type( $object_id ) ) {
369
		return $check;
370
	}
371
372
	$new_meta_keys = array(
373
		'_give_payment_donor_id',
374
		'_give_payment_donor_email',
375
		'_give_payment_donor_ip',
376
		'_give_donor_billing_first_name',
377
		'_give_donor_billing_last_name',
378
		'_give_donor_billing_address1',
379
		'_give_donor_billing_address2',
380
		'_give_donor_billing_city',
381
		'_give_donor_billing_zip',
382
		'_give_donor_billing_state',
383
		'_give_donor_billing_country',
384
		'_give_payment_date',
385
		'_give_payment_currency',
386
	);
387
388
	// metadata_exists fx will cause of firing get_post_metadata filter again so remove it to prevent infinite loop.
389
	remove_filter( 'get_post_metadata', '_give_20_bc_get_new_payment_meta' );
390
391
	// Bailout.
392
	if (
393
		! in_array( $meta_key, $new_meta_keys ) ||
394
		metadata_exists( 'post', $object_id, $meta_key )
395
	) {
396
		add_filter( 'get_post_metadata', '_give_20_bc_get_new_payment_meta', 10, 5 );
397
398
		return $check;
399
	}
400
401
	add_filter( 'get_post_metadata', '_give_20_bc_get_new_payment_meta', 10, 5 );
402
403
	$cache_key = "{$meta_key}_{$object_id}";
404
	$check    = Give_Cache::get_db_query( $cache_key );
405
406
	if ( is_null( $check ) ) {
407
		switch ( $meta_key ) {
408
409
			// Handle new meta keys.
410
			case '_give_payment_donor_id':
411
				$check = $wpdb->get_var(
412
					$wpdb->prepare(
413
						"SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id=%d AND meta_key=%s",
414
						$object_id,
415
						'_give_payment_customer_id'
416
					)
417
				);
418
				break;
419
420
			case '_give_payment_donor_email':
421
				$check = $wpdb->get_var(
422
					$wpdb->prepare(
423
						"SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id=%d AND meta_key=%s",
424
						$object_id,
425
						'_give_payment_user_email'
426
					)
427
				);
428
				break;
429
430
			case '_give_payment_donor_ip':
431
				$check = $wpdb->get_var(
432
					$wpdb->prepare(
433
						"SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id=%s AND meta_key=%s",
434
						$object_id,
435
						'_give_payment_user_ip'
436
					)
437
				);
438
				break;
439
440
			case '_give_donor_billing_first_name':
441
			case '_give_donor_billing_last_name':
442
			case '_give_donor_billing_address1':
443
			case '_give_donor_billing_address2':
444
			case '_give_donor_billing_city':
445
			case '_give_donor_billing_zip':
446
			case '_give_donor_billing_state':
447
			case '_give_donor_billing_country':
448
			case '_give_payment_date':
449
			case '_give_payment_currency':
450
				$donation_meta = Give_Cache::get_db_query( "_give_payment_meta_{$object_id}" );
451
452
				if ( is_null( $donation_meta ) ) {
453
					$donation_meta = $wpdb->get_var(
454
						$wpdb->prepare(
455
							"SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id=%d AND meta_key=%s",
456
							$object_id,
457
							'_give_payment_meta'
458
						)
459
					);
460
					$donation_meta = maybe_unserialize( $donation_meta );
461
					$donation_meta = ! is_array( $donation_meta ) ? array() : $donation_meta;
462
					Give_Cache::set_db_query( "_give_payment_meta_{$object_id}", $donation_meta );
463
				}
464
465
				// Get results.
466
				if ( empty( $donation_meta ) ) {
467
					$check = '';
468
				} elseif ( in_array( $meta_key, array( '_give_payment_date', '_give_payment_currency' ) ) ) {
469
					$payment_meta_key = str_replace( '_give_payment_', '', $meta_key );
470
471
					if ( isset( $donation_meta[ $payment_meta_key ] ) ) {
472
						$check = $donation_meta[ $payment_meta_key ];
473
					}
474
				} else {
475
					$payment_meta_key = str_replace( '_give_donor_billing_', '', $meta_key );
476
477
					switch ( $payment_meta_key ) {
478 View Code Duplication
						case 'address1':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
479
							if ( isset( $donation_meta['user_info']['address']['line1'] ) ) {
480
								$check = $donation_meta['user_info']['address']['line1'];
481
							}
482
							break;
483
484 View Code Duplication
						case 'address2':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
485
							if ( isset( $donation_meta['user_info']['address']['line2'] ) ) {
486
								$check = $donation_meta['user_info']['address']['line2'];
487
							}
488
							break;
489
490 View Code Duplication
						case 'first_name':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
491
							if ( isset( $donation_meta['user_info']['first_name'] ) ) {
492
								$check = $donation_meta['user_info']['first_name'];
493
							}
494
							break;
495
496 View Code Duplication
						case 'last_name':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
497
							if ( isset( $donation_meta['user_info']['last_name'] ) ) {
498
								$check = $donation_meta['user_info']['last_name'];
499
							}
500
							break;
501
502
						default:
503
							if ( isset( $donation_meta['user_info']['address'][ $payment_meta_key ] ) ) {
504
								$check = $donation_meta['user_info']['address'][ $payment_meta_key ];
505
							}
506
					}
507
				}
508
509
				break;
510
		}// End switch().
511
512
		// Set cache.
513
		Give_Cache::set_db_query( $cache_key, $check );
514
	}
515
516
	// Put result in an array on zero index.
517
	if ( ! $single ) {
518
		$check = array( $check );
519
	}
520
521
522
	return $check;
523
}
524
525
// Apply filter only if upgrade does not complete yet.
526
if ( ! give_has_upgrade_completed( 'v20_upgrades_payment_metadata' ) ) {
527
	add_filter( 'get_post_metadata', '_give_20_bc_get_new_payment_meta', 10, 5 );
528
}
529
530
531
/**
532
 * Add support for old payment meta keys.
533
 *
534
 * @since 2.0
535
 *
536
 * @param WP_Query $query
537
 *
538
 * @return void
539
 */
540
function _give_20_bc_support_deprecated_meta_key_query( $query ) {
541
	$new_meta_keys = array(
542
		'_give_payment_customer_id' => '_give_payment_donor_id',
543
		'_give_payment_user_email'  => '_give_payment_donor_email',
544
		// '_give_payment_user_ip'     => '_give_payment_donor_ip',
545
	);
546
547
	$deprecated_meta_keys = array_flip( $new_meta_keys );
548
549
	// Set meta keys.
550
	$meta_keys = array();
551
552
553
	// Bailout.
554
	if ( ! empty( $query->query_vars['meta_key'] ) ) {
555
		if ( in_array( $query->query_vars['meta_key'], $new_meta_keys ) ) {
556
			$meta_keys = $deprecated_meta_keys;
557
		} elseif ( in_array( $query->query_vars['meta_key'], $deprecated_meta_keys ) ) {
558
			$meta_keys = $new_meta_keys;
559
		}
560
561
		if ( ! empty( $meta_keys ) ) {
562
			// Set meta_query
563
			$query->set(
564
				'meta_query',
565
				array(
566
					'relation' => 'OR',
567
					array(
568
						'key'   => $query->query_vars['meta_key'],
569
						'value' => $query->query_vars['meta_value'],
570
					),
571
					array(
572
						'key'   => $meta_keys[ $query->query_vars['meta_key'] ],
573
						'value' => $query->query_vars['meta_value'],
574
					),
575
				)
576
			);
577
578
			// Unset single meta query.
579
			unset( $query->query_vars['meta_key'] );
580
			unset( $query->query_vars['meta_value'] );
581
		}
582
	} elseif (
583
		! empty( $query->query_vars['meta_query'] ) &&
584
		( 1 === count( $query->query_vars['meta_query'] ) )
585
	) {
586
		$meta_query = current( $query->query_vars['meta_query'] );
587
588
		if ( empty( $meta_query[0]['key'] ) ) {
589
			return;
590
		}
591
592
		if ( in_array( $meta_query[0]['key'], $new_meta_keys ) ) {
593
			$meta_keys = $deprecated_meta_keys;
594
		} elseif ( in_array( $meta_query[0]['key'], $deprecated_meta_keys ) ) {
595
			$meta_keys = $new_meta_keys;
596
		} else {
597
			return;
598
		}
599
600
		if ( ! empty( $meta_keys ) ) {
601
			// Set meta_query
602
			$query->set(
603
				'meta_query',
604
				array(
605
					'relation' => 'OR',
606
					array(
607
						'key'   => $query->query_vars['meta_query'][0]['key'],
608
						'value' => $query->query_vars['meta_query'][0]['value'],
609
					),
610
					array(
611
						'key'   => $meta_keys[ $query->query_vars['meta_query'][0]['key'] ],
612
						'value' => $query->query_vars['meta_query'][0]['value'],
613
					),
614
				)
615
			);
616
		}
617
	}
618
}
619
620
// Apply filter only if upgrade does not complete.
621
if ( ! give_has_upgrade_completed( 'v20_upgrades_payment_metadata' ) ) {
622
	add_action( 'pre_get_posts', '_give_20_bc_support_deprecated_meta_key_query' );
623
}
624
625
/**
626
 * Save payment backward compatibility.
627
 * Note: some addon still can use user_info in set payment meta
628
 *       we will use this info to set first name, last name and address of donor
629
 *
630
 * @since 2.0
631
 *
632
 * @param Give_Payment $payment
633
 * @param string       $key
634
 */
635
function _give_20_bc_payment_save( $payment, $key ) {
636
	switch ( $key ) {
637
		case 'user_info':
638
			if ( empty( $payment->user_info ) ) {
639
				// Bailout.
640
				break;
641
			} elseif ( is_string( $payment->user_info ) ) {
642
				// Check if value serialize.
643
				$payment->user_info = maybe_unserialize( $payment->user_info );
644
			}
645
646
647
			// Save first name.
648
			if ( isset( $payment->user_info['first_name'] ) ) {
649
				$payment->update_meta( '_give_donor_billing_first_name', $payment->user_info['first_name'] );
650
			}
651
652
653
			// Save last name.
654
			if ( isset( $payment->user_info['last_name'] ) ) {
655
				$payment->update_meta( '_give_donor_billing_last_name', $payment->user_info['last_name'] );
656
			}
657
658
659
			// Save address.
660
			if ( ! empty( $payment->user_info['address'] ) ) {
661
				foreach ( $payment->user_info['address'] as $address_name => $address ) {
662
					switch ( $address_name ) {
663
						case 'line1':
664
							$payment->update_meta( '_give_donor_billing_address1', $address );
665
							break;
666
667
						case 'line2':
668
							$payment->update_meta( '_give_donor_billing_address2', $address );
669
							break;
670
671
						default:
672
							$payment->update_meta( "_give_donor_billing_{$address_name}", $address );
673
					}
674
				}
675
			}
676
677
			break;
678
	}
679
}
680
681
682
// Apply filter only if upgrade complete.
683
if ( give_has_upgrade_completed( 'v20_upgrades_payment_metadata' ) ) {
684
	add_action( 'give_payment_save', '_give_20_bc_payment_save', 10, 2 );
685
}
686
687
688
/**
689
 * Delete pre upgrade cache for donations.
690
 *
691
 * @since 2.0
692
 *
693
 * @param $check
694
 * @param $object_id
695
 *
696
 * @return mixed
697
 */
698
function __give_20_bc_flush_cache( $check, $object_id ) {
699
	if ( 'give_payment' === get_post_type( $object_id ) ) {
700
		Give_Cache::delete_group( $object_id, 'give-donations' );
701
	}
702
703
	return $check;
704
}
705
706
// Apply only if upgrade does not complete.
707
if( ! give_has_upgrade_completed( 'v20_move_metadata_into_new_table' ) ) {
708
	add_action( 'update_post_metadata', '__give_20_bc_flush_cache', 9999, 2 );
709
	add_action( 'add_post_metadata', '__give_20_bc_flush_cache', 9999, 2 );
710
}
711