Test Failed
Push — master ( 339236...7fe983 )
by Devin
09:29 queued 04:18
created

misc-functions.php ➔ give_list_pluck()   C

Complexity

Conditions 10
Paths 10

Size

Total Lines 47
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
cc 10
eloc 24
nc 10
nop 3
dl 0
loc 47
rs 5.1578
c 0
b 0
f 0
ccs 0
cts 0
cp 0
crap 110

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Misc Functions
4
 *
5
 * @package     Give
6
 * @subpackage  Functions
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Is Test Mode Enabled.
19
 *
20
 * @since 1.0
21
 *
22
 * @return bool $ret True if return mode is enabled, false otherwise
23
 */
24
function give_is_test_mode() {
25 52
26
	$ret = give_is_setting_enabled( give_get_option( 'test_mode' ) );
27 52
28
	return (bool) apply_filters( 'give_is_test_mode', $ret );
29 52
30
}
31
32
/**
33
 * Get the set currency
34
 *
35
 * @since 1.0
36
 * @return string The currency code
37
 */
38
function give_get_currency() {
39 55
40 55
	$currency = give_get_option( 'currency', 'USD' );
41
42 55
	return apply_filters( 'give_currency', $currency );
43
}
44
45
/**
46
 * Get the set currency position
47
 *
48
 * @since 1.3.6
49
 *
50
 * @return string The currency code
51
 */
52
function give_get_currency_position() {
53 1
54 1
	$currency_pos = give_get_option( 'currency_position', 'before' );
55
56 1
	return apply_filters( 'give_currency_position', $currency_pos );
57
}
58
59
60
/**
61
 * Get Currencies
62
 *
63
 * @since 1.0
64
 * @return array $currencies A list of the available currencies
65
 */
66
67
function give_get_currencies() {
68
	$currencies = array(
69
		'USD'  => __( 'US Dollars ($)', 'give' ),
70
		'EUR'  => __( 'Euros (€)', 'give' ),
71
		'GBP'  => __( 'Pounds Sterling (£)', 'give' ),
72
		'AUD'  => __( 'Australian Dollars ($)', 'give' ),
73
		'BRL'  => __( 'Brazilian Real (R$)', 'give' ),
74
		'CAD'  => __( 'Canadian Dollars ($)', 'give' ),
75
		'CZK'  => __( 'Czech Koruna (Kč)', 'give' ),
76
		'DKK'  => __( 'Danish Krone (kr.)', 'give' ),
77
		'HKD'  => __( 'Hong Kong Dollar ($)', 'give' ),
78
		'HUF'  => __( 'Hungarian Forint (Ft)', 'give' ),
79
		'ILS'  => __( 'Israeli Shekel (₪)', 'give' ),
80
		'JPY'  => __( 'Japanese Yen (¥)', 'give' ),
81
		'MYR'  => __( 'Malaysian Ringgits (RM)', 'give' ),
82
		'MXN'  => __( 'Mexican Peso ($)', 'give' ),
83
		'MAD'  => __( 'Moroccan Dirham (&#x2e;&#x62f;&#x2e;&#x645;)', 'give' ),
84
		'NZD'  => __( 'New Zealand Dollar ($)', 'give' ),
85
		'NOK'  => __( 'Norwegian Krone (Kr.)', 'give' ),
86
		'PHP'  => __( 'Philippine Pesos (₱)', 'give' ),
87
		'PLN'  => __( 'Polish Zloty (zł)', 'give' ),
88
		'SGD'  => __( 'Singapore Dollar ($)', 'give' ),
89
		'KRW'  => __( 'South Korean Won (₩)', 'give' ),
90
		'ZAR'  => __( 'South African Rand (R)', 'give' ),
91
		'SEK'  => __( 'Swedish Krona (kr)', 'give' ),
92
		'CHF'  => __( 'Swiss Franc (CHF)', 'give' ),
93
		'TWD'  => __( 'Taiwan New Dollars (NT$)', 'give' ),
94
		'THB'  => __( 'Thai Baht (฿)', 'give' ),
95
		'INR'  => __( 'Indian Rupee (₹)', 'give' ),
96
		'TRY'  => __( 'Turkish Lira (₺)', 'give' ),
97
		'RIAL' => __( 'Iranian Rial (﷼)', 'give' ),
98
		'RUB'  => __( 'Russian Rubles (руб)', 'give' ),
99
	);
100
101
	return apply_filters( 'give_currencies', $currencies );
102
}
103
104
105
/**
106
 * Give Currency Symbol
107
 *
108
 * Given a currency determine the symbol to use. If no currency given, site default is used. If no symbol is determine,
109
 * the currency string is returned.
110
 *
111
 * @since      1.0
112
 *
113
 * @param  string $currency The currency string.
114
 * @param  bool $decode_currency Option to HTML decode the currency symbol.
115
 *
116
 * @return string           The symbol to use for the currency
117
 */
118 45
function give_currency_symbol( $currency = '', $decode_currency = false ) {
119
120
	if ( empty( $currency ) ) {
121
		$currency = give_get_currency();
122 45
	}
123
	switch ( $currency ) :
124
		case 'GBP' :
125 45
			$symbol = '&pound;';
126
			break;
127
		case 'BRL' :
128 45
			$symbol = '&#82;&#36;';
129
			break;
130
		case 'EUR' :
131 45
			$symbol = '&euro;';
132
			break;
133
		case 'NOK' :
134 45
			$symbol = '&#107;&#114;.';
135
			break;
136
		case 'INR' :
137 45
			$symbol = '&#8377;';
138 45
			break;
139 45
		case 'USD' :
140 45
		case 'AUD' :
141 45
		case 'CAD' :
142 45
		case 'HKD' :
143 45
		case 'MXN' :
144 45
		case 'SGD' :
145
			$symbol = '&#36;';
146
			break;
147
		case 'JPY' :
148
			$symbol = '&yen;';
149
			break;
150
		case 'THB' :
151
			$symbol = '&#3647;';
152
			break;
153
		case 'TRY' :
154
			$symbol = '&#8378;';
155
			break;
156
		case 'TWD' :
157
			$symbol = '&#78;&#84;&#36;';
158
			break;
159
		case 'ILS' :
160
			$symbol = '&#8362;';
161
			break;
162
		case 'RIAL' :
163
			$symbol = '&#xfdfc;';
164
			break;
165
		case 'RUB' :
166
			$symbol = '&#8381;';
167
			break;
168
		case 'DKK' :
169
		case 'SEK' :
170
			$symbol = '&nbsp;kr.&nbsp;';
171
			break;
172
		case 'PLN' :
173
			$symbol = '&#122;&#322;';
174
			break;
175
		case 'PHP' :
176
			$symbol = '&#8369;';
177
			break;
178
		case 'MYR' :
179
			$symbol = '&#82;&#77;';
180
			break;
181
		case 'HUF' :
182
			$symbol = '&#70;&#116;';
183
			break;
184
		case 'CZK' :
185
			$symbol = '&#75;&#269;';
186
			break;
187
		case 'KRW' :
188
			$symbol = '&#8361;';
189
			break;
190
		case 'ZAR' :
191
			$symbol = '&#82;';
192
			break;
193
		case 'MAD' :
194
			$symbol = '&#x2e;&#x62f;&#x2e;&#x645;';
195
			break;
196
		default :
197
			$symbol = $currency;
198
			break;
199
	endswitch;
200 45
201
	$symbol = ( ! $decode_currency ? $symbol : html_entity_decode( $symbol ) );
202
203
	return apply_filters( 'give_currency_symbol', $symbol, $currency );
204
}
205
206
207
/**
208
 * Get currency name.
209
 *
210
 * @since 1.8.8
211
 *
212 6
 * @param string $currency_code
213
 *
214
 * @return string
215 6
 */
216
function give_get_currency_name( $currency_code ) {
217
	$currency_name  = '';
218 6
	$currency_names = give_get_currencies();
219
220
	if ( $currency_code && array_key_exists( $currency_code, $currency_names ) ) {
221
		$currency_name = explode( '(', $currency_names[ $currency_code ] );
222
		$currency_name = trim( current( $currency_name ) );
223
	}
224
225
	return apply_filters( 'give_currency_name', $currency_name, $currency_code );
226
}
227
228
229
/**
230
 * Get the current page URL.
231
 *
232
 * @since 1.0
233
 * @return string $current_url Current page URL.
234
 */
235
function give_get_current_page_url() {
236
237
	global $wp;
238
239
	if ( get_option( 'permalink_structure' ) ) {
240
		$base = trailingslashit( home_url( $wp->request ) );
241
	} else {
242
		$base = add_query_arg( $wp->query_string, '', trailingslashit( home_url( $wp->request ) ) );
243
		$base = remove_query_arg( array( 'post_type', 'name' ), $base );
244
	}
245
246
	$scheme      = is_ssl() ? 'https' : 'http';
247
	$current_uri = set_url_scheme( $base, $scheme );
248
249
	if ( is_front_page() ) {
250
		$current_uri = home_url( '/' );
251
	}
252
253
	return apply_filters( 'give_get_current_page_url', $current_uri );
254
255
}
256
257
258
/**
259
 * Verify credit card numbers live?
260
 *
261
 * @since 1.0
262
 *
263
 * @return bool $ret True is verify credit cards is live
264
 */
265
function give_is_cc_verify_enabled() {
266
267
	$ret = true;
268
269
	/**
270
	 * Enable if use a single gateway other than PayPal or Manual. We have to assume it accepts credit cards.
271
	 * Enable if using more than one gateway if they are not both PayPal and manual, again assuming credit card usage.
272
	 */
273
	$gateways = give_get_enabled_payment_gateways();
274
275
	if ( count( $gateways ) == 1 && ! isset( $gateways['paypal'] ) && ! isset( $gateways['manual'] ) ) {
0 ignored issues
show
introduced by
Found "== 1". Use Yoda Condition checks, you must
Loading history...
276
		$ret = true;
277
	} elseif ( count( $gateways ) == 1 ) {
0 ignored issues
show
introduced by
Found "== 1". Use Yoda Condition checks, you must
Loading history...
278
		$ret = false;
279
	} elseif ( count( $gateways ) == 2 && isset( $gateways['paypal'] ) && isset( $gateways['manual'] ) ) {
0 ignored issues
show
introduced by
Found "== 2". Use Yoda Condition checks, you must
Loading history...
280
		$ret = false;
281
	}
282
283
	return (bool) apply_filters( 'give_verify_credit_cards', $ret );
284
}
285
286
/**
287
 * Retrieve timezone.
288
 *
289
 * @since 1.0
290
 * @return string $timezone The timezone ID.
291
 */
292
function give_get_timezone_id() {
293
294
	// if site timezone string exists, return it.
295
	if ( $timezone = get_option( 'timezone_string' ) ) {
296
		return $timezone;
297
	}
298
299
	// get UTC offset, if it isn't set return UTC.
300 52
	if ( ! ( $utc_offset = 3600 * get_option( 'gmt_offset', 0 ) ) ) {
301
		return 'UTC';
302 52
	}
303
304
	// attempt to guess the timezone string from the UTC offset.
305 52
	$timezone = timezone_name_from_abbr( '', $utc_offset );
306
307
	// last try, guess timezone string manually.
308 52
	if ( $timezone === false ) {
0 ignored issues
show
introduced by
Found "=== false". Use Yoda Condition checks, you must
Loading history...
309 52
310 52
		$is_dst = date( 'I' );
311
312 52
		foreach ( timezone_abbreviations_list() as $abbr ) {
313
			foreach ( $abbr as $city ) {
314
				if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
315
					return $city['timezone_id'];
316
				}
317
			}
318
		}
319
	}
320
321
	// Fallback.
322
	return 'UTC';
323
}
324
325
326
/**
327
 * Get User IP
328
 *
329
 * Returns the IP address of the current visitor
330
 *
331
 * @since 1.0
332
 * @return string $ip User's IP address
333
 */
334
function give_get_ip() {
335
336
	$ip = '127.0.0.1';
337
338
	if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
339
		// check ip from share internet
340
		$ip = $_SERVER['HTTP_CLIENT_IP'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
341
	} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
342
		// to check ip is pass from proxy
343
		$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
344
	} elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
0 ignored issues
show
introduced by
Due to using Batcache, server side based client related logic will not work, use JS instead.
Loading history...
345
		$ip = $_SERVER['REMOTE_ADDR'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
introduced by
Due to using Batcache, server side based client related logic will not work, use JS instead.
Loading history...
346
	}
347
348
	return apply_filters( 'give_get_ip', $ip );
349
}
350
351
352
/**
353
 * Store Donation Data in Sessions
354
 *
355
 * Used for storing info about donation
356
 *
357
 * @since 1.0
358
 *
359
 * @param $purchase_data
360
 *
361
 * @uses  Give()->session->set()
362
 */
363
function give_set_purchase_session( $purchase_data = array() ) {
364
	Give()->session->set( 'give_purchase', $purchase_data );
0 ignored issues
show
Documentation introduced by
$purchase_data is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
365
	Give()->session->set( 'give_email', $purchase_data['user_email'] );
366
}
367
368
/**
369
 * Retrieve Donation Data from Session
370
 *
371
 * Used for retrieving info about donation
372
 * after completing a donation
373
 *
374
 * @since 1.0
375
 * @uses  Give()->session->get()
376
 * @return mixed array | false
377
 */
378
function give_get_purchase_session() {
379
	return Give()->session->get( 'give_purchase' );
380
}
381
382
/**
383
 * Get Donation Summary
384
 *
385
 * Creates a donation summary for payment gateways from the donation data before the payment is created in the database.
386
 *
387
 * @since       1.8.12
388
 *
389
 * @param array $donation_data
390
 * @param bool $name_and_email
391
 * @param int $length
392
 *
393
 * @return string
394
 */
395
function give_payment_gateway_donation_summary( $donation_data, $name_and_email = true, $length = 255 ) {
396
397
	$summary = '';
398
399
	$form_id = isset( $donation_data['post_data']['give-form-id'] ) ? $donation_data['post_data']['give-form-id'] : '';
400
401
	// Form title.
402
	if ( isset( $donation_data['post_data']['give-form-title'] ) ) {
403
		$summary .= $donation_data['post_data']['give-form-title'];
404
	}
405
	// Form multilevel if applicable.
406
	if ( isset( $donation_data['post_data']['give-price-id'] ) ) {
407
		$summary .= ': ' . give_get_price_option_name( $form_id, $donation_data['post_data']['give-price-id'] );
408
	}
409
410
	// Add Donor's name + email if requested.
411
	if ( $name_and_email ) {
412
413
		// First name
414 View Code Duplication
		if ( isset( $donation_data['user_info']['first_name'] ) && ! empty( $donation_data['user_info']['first_name'] ) ) {
0 ignored issues
show
Duplication introduced by
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...
415
			$summary .= ' - ' . $donation_data['user_info']['first_name'];
416
		}
417
418 View Code Duplication
		if ( isset( $donation_data['user_info']['last_name'] ) && ! empty( $donation_data['user_info']['last_name'] ) ) {
0 ignored issues
show
Duplication introduced by
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...
419
			$summary .= ' ' . $donation_data['user_info']['last_name'];
420
		}
421
422
		$summary .= ' (' . $donation_data['user_email'] . ')';
423
	}
424
425
	// Cut the length
426
	$summary = substr( $summary, 0, $length );
427
428
	return apply_filters( 'give_payment_gateway_donation_summary', $summary );
429
}
430
431
432
/**
433
 * Get user host
434
 *
435
 * Returns the webhost this site is using if possible
436
 *
437
 * @since 1.0
438
 * @return string $host if detected, false otherwise
439
 */
440
function give_get_host() {
441
	$host = false;
0 ignored issues
show
Unused Code introduced by
$host is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
442
443
	if ( defined( 'WPE_APIKEY' ) ) {
444
		$host = 'WP Engine';
445
	} elseif ( defined( 'PAGELYBIN' ) ) {
446
		$host = 'Pagely';
447
	} elseif ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
448
		$host = 'ICDSoft';
449
	} elseif ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
450
		$host = 'NetworkSolutions';
451
	} elseif ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
452
		$host = 'iPage';
453
	} elseif ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
454
		$host = 'IPower';
455
	} elseif ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
456
		$host = 'MediaTemple Grid';
457
	} elseif ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
458
		$host = 'pair Networks';
459
	} elseif ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
460
		$host = 'Rackspace Cloud';
461
	} elseif ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
462
		$host = 'SysFix.eu Power Hosting';
463
	} elseif ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
464
		$host = 'Flywheel';
465
	} else {
466
		// Adding a general fallback for data gathering
467
		$host = 'DBH: ' . DB_HOST . ', SRV: ' . $_SERVER['SERVER_NAME'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
468
	}
469
470
	return $host;
471
}
472
473
474
/**
475
 * Check site host
476
 *
477
 * @since 1.0
478
 *
479
 * @param bool /string $host The host to check
480
 *
481
 * @return bool true if host matches, false if not
482
 */
483
function give_is_host( $host = false ) {
484
485
	$return = false;
486
487
	if ( $host ) {
488
		$host = str_replace( ' ', '', strtolower( $host ) );
489
490
		switch ( $host ) {
491
			case 'wpengine':
492
				if ( defined( 'WPE_APIKEY' ) ) {
493
					$return = true;
494
				}
495
				break;
496
			case 'pagely':
497
				if ( defined( 'PAGELYBIN' ) ) {
498
					$return = true;
499
				}
500
				break;
501
			case 'icdsoft':
502
				if ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
503
					$return = true;
504
				}
505
				break;
506
			case 'networksolutions':
507
				if ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
508
					$return = true;
509
				}
510
				break;
511
			case 'ipage':
512
				if ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
513
					$return = true;
514
				}
515
				break;
516 1
			case 'ipower':
517
				if ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
518 1
					$return = true;
519
				}
520
				break;
521 1
			case 'mediatemplegrid':
522
				if ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
523
					$return = true;
524
				}
525
				break;
526
			case 'pairnetworks':
527
				if ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
528
					$return = true;
529
				}
530
				break;
531
			case 'rackspacecloud':
532 1
				if ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
533
					$return = true;
534
				}
535
				break;
536
			case 'sysfix.eu':
537
			case 'sysfix.eupowerhosting':
538
				if ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
539
					$return = true;
540
				}
541
				break;
542
			case 'flywheel':
543
				if ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
544
					$return = true;
545
				}
546
				break;
547
			default:
548
				$return = false;
549
		}// End switch().
550
	}// End if().
551
552
	return $return;
553
}
554
555
/**
556
 * Marks a function as deprecated and informs when it has been used.
557
 *
558
 * There is a hook give_deprecated_function_run that will be called that can be used
559
 * to get the backtrace up to what file and function called the deprecated
560
 * function.
561
 *
562
 * The current behavior is to trigger a user error if WP_DEBUG is true.
563
 *
564
 * This function is to be used in every function that is deprecated.
565
 *
566
 * @uses do_action() Calls 'give_deprecated_function_run' and passes the function name, what to use instead,
567
 *   and the version the function was deprecated in.
568
 * @uses apply_filters() Calls 'give_deprecated_function_trigger_error' and expects boolean value of true to do
569
 *   trigger or false to not trigger error.
570
 *
571
 * @param string $function The function that was called.
572
 * @param string $version The plugin version that deprecated the function.
573
 * @param string $replacement Optional. The function that should have been called.
574
 * @param array $backtrace Optional. Contains stack backtrace of deprecated function.
575
 */
576
function _give_deprecated_function( $function, $version, $replacement = null, $backtrace = null ) {
577
578
	/**
579
	 * Fires while give deprecated function call occurs.
580
	 *
581
	 * Allow you to hook to deprecated function call.
582
	 *
583
	 * @since 1.0
584
	 *
585
	 * @param string $function The function that was called.
586
	 * @param string $replacement Optional. The function that should have been called.
587
	 * @param string $version The plugin version that deprecated the function.
588
	 */
589
	do_action( 'give_deprecated_function_run', $function, $replacement, $version );
590
591
	$show_errors = current_user_can( 'manage_options' );
592
593
	// Allow plugin to filter the output error trigger.
594
	if ( WP_DEBUG && apply_filters( 'give_deprecated_function_trigger_error', $show_errors ) ) {
595
		if ( ! is_null( $replacement ) ) {
596
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s! Use %3$s instead.', 'give' ), $function, $version, $replacement ) );
597
			trigger_error( print_r( $backtrace, 1 ) ); // Limited to previous 1028 characters, but since we only need to move back 1 in stack that should be fine.
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
598
			// Alternatively we could dump this to a file.
599
		} else {
600
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s with no alternative available.', 'give' ), $function, $version ) );
601
			trigger_error( print_r( $backtrace, 1 ) );// Limited to previous 1028 characters, but since we only need to move back 1 in stack that should be fine.
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
602
			// Alternatively we could dump this to a file.
603
		}
604
	}
605
}
606
607
/**
608
 * Give Get Admin ID
609
 *
610
 * Helper function to return the ID of the post for admin usage
611
 *
612
 * @return string $post_id
613
 */
614
function give_get_admin_post_id() {
615
	$post_id = isset( $_GET['post'] ) ? $_GET['post'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
616
	if ( ! $post_id && isset( $_POST['post_id'] ) ) {
617
		$post_id = $_POST['post_id'];
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
618
	}
619
620
	return $post_id;
621
}
622
623
/**
624
 * Get PHP Arg Separator Output
625
 *
626
 * @since 1.0
627
 * @return string Arg separator output
628
 */
629
function give_get_php_arg_separator_output() {
630
	return ini_get( 'arg_separator.output' );
631
}
632
633
634
/**
635
 * Month Num To Name
636
 *
637
 * Takes a month number and returns the name three letter name of it.
638
 *
639
 * @since 1.0
640
 *
641
 * @param int $n
642
 *
643
 * @return string Short month name
644
 */
645
function give_month_num_to_name( $n ) {
646
	$timestamp = mktime( 0, 0, 0, $n, 1, 2005 );
647
648
	return date_i18n( 'M', $timestamp );
649
}
650
651
652
/**
653
 * Checks whether function is disabled.
654
 *
655
 * @since 1.0
656
 *
657
 * @param string $function Name of the function.
658
 *
659
 * @return bool Whether or not function is disabled.
660
 */
661
function give_is_func_disabled( $function ) {
662
	$disabled = explode( ',', ini_get( 'disable_functions' ) );
663
664
	return in_array( $function, $disabled );
665
}
666
667
668
/**
669
 * Give Newsletter
670
 *
671
 * Returns the main Give newsletter form
672
 */
673
function give_get_newsletter() {
674
	?>
675
676
	<p class="newsletter-intro"><?php esc_html_e( 'Be sure to sign up for the Give newsletter below to stay informed of important updates and news.', 'give' ); ?></p>
677
678
	<div class="give-newsletter-form-wrap">
679
680
		<form action="//givewp.us3.list-manage.com/subscribe/post?u=3ccb75d68bda4381e2f45794c&amp;id=12a081aa13"
681
		      method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate"
682
		      target="_blank" novalidate>
683
			<div class="give-newsletter-confirmation">
684
				<p><?php esc_html_e( 'Thanks for Subscribing!', 'give' ); ?> :)</p>
685
			</div>
686
687
			<table class="form-table give-newsletter-form">
688
				<tr valign="middle">
689
					<td>
690
						<label for="mce-EMAIL"
691
						       class="screen-reader-text"><?php esc_html_e( 'Email Address (required)', 'give' ); ?></label>
692
						<input type="email" name="EMAIL" id="mce-EMAIL"
693
						       placeholder="<?php esc_attr_e( 'Email Address (required)', 'give' ); ?>"
694
						       class="required email" value="">
695
					</td>
696
					<td>
697
						<label for="mce-FNAME"
698
						       class="screen-reader-text"><?php esc_html_e( 'First Name', 'give' ); ?></label>
699
						<input type="text" name="FNAME" id="mce-FNAME"
700
						       placeholder="<?php esc_attr_e( 'First Name', 'give' ); ?>" class="" value="">
701
					</td>
702
					<td>
703
						<label for="mce-LNAME"
704
						       class="screen-reader-text"><?php esc_html_e( 'Last Name', 'give' ); ?></label>
705
						<input type="text" name="LNAME" id="mce-LNAME"
706
						       placeholder="<?php esc_attr_e( 'Last Name', 'give' ); ?>" class="" value="">
707
					</td>
708
					<td>
709
						<input type="submit" name="subscribe" id="mc-embedded-subscribe" class="button"
710
						       value="<?php esc_attr_e( 'Subscribe', 'give' ); ?>">
711
					</td>
712
				</tr>
713
			</table>
714
		</form>
715
716
		<div style="position: absolute; left: -5000px;">
717
			<input type="text" name="b_3ccb75d68bda4381e2f45794c_12a081aa13" tabindex="-1" value="">
718
		</div>
719
720
	</div>
721
722
	<script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script>
0 ignored issues
show
introduced by
Scripts must be registered/enqueued via wp_enqueue_script
Loading history...
723
	<script type='text/javascript'>(function ($) {
724
			window.fnames = new Array();
725
			window.ftypes = new Array();
726
			fnames[0] = 'EMAIL';
727
			ftypes[0] = 'email';
728
			fnames[1] = 'FNAME';
729
			ftypes[1] = 'text';
730
			fnames[2] = 'LNAME';
731
			ftypes[2] = 'text';
732
733
			//Successful submission
734
			$('form[name="mc-embedded-subscribe-form"]').on('submit', function () {
735
736
				var email_field = $(this).find('#mce-EMAIL').val();
737
				if (!email_field) {
738
					return false;
739
				}
740
				$(this).find('.give-newsletter-confirmation').show().delay(5000).slideUp();
741
				$(this).find('.give-newsletter-form').hide();
742
743
			});
744
745
		}(jQuery));
746
		var $mcj = jQuery.noConflict(true);
747
748
749
	</script>
750
	<!--End mc_embed_signup-->
751
752
<?php }
753
754
755
/**
756
 * Create SVG library function
757
 *
758
 * @param string $icon
759
 *
760
 * @return string
761
 */
762
function give_svg_icons( $icon ) {
763
764
	// Store your SVGs in an associative array
765
	$svgs = array(
766
		'microphone'    => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjY0cHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgLTIwIDY0IDEyMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNjQgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8Zz4NCgk8Zz4NCgkJPHBhdGggZD0iTTYyLDM2LjIxNWgtM2MtMS4xLDAtMiwwLjktMiwyVjUyYzAsNi42ODYtNS4yNjYsMTgtMjUsMThTNyw1OC42ODYsNyw1MlYzOC4yMTVjMC0xLjEtMC45LTItMi0ySDJjLTEuMSwwLTIsMC45LTIsMlY1Mg0KCQkJYzAsMTEuMTg0LDguMjE1LDIzLjE1MiwyNywyNC44MDFWOTBIMTRjLTEuMSwwLTIsMC44OTgtMiwydjZjMCwxLjEsMC45LDIsMiwyaDM2YzEuMSwwLDItMC45LDItMnYtNmMwLTEuMTAyLTAuOS0yLTItMkgzN1Y3Ni44MDENCgkJCUM1NS43ODUsNzUuMTUyLDY0LDYzLjE4NCw2NCw1MlYzOC4yMTVDNjQsMzcuMTE1LDYzLjEsMzYuMjE1LDYyLDM2LjIxNXoiLz4NCgkJPHBhdGggZD0iTTMyLDYwYzExLjczMiwwLDE1LTQuODE4LDE1LThWMzYuMjE1SDE3VjUyQzE3LDU1LjE4MiwyMC4yNjYsNjAsMzIsNjB6Ii8+DQoJCTxwYXRoIGQ9Ik00Nyw4YzAtMy4xODQtMy4yNjgtOC0xNS04QzIwLjI2NiwwLDE3LDQuODE2LDE3LDh2MjEuMjE1aDMwVjh6Ii8+DQoJPC9nPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPC9zdmc+DQo=',
767
		'alert'         => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjI4LjkzOHB4IiBoZWlnaHQ9IjI1LjAwNXB4IiB2aWV3Qm94PSIwIDAgMjguOTM4IDI1LjAwNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjguOTM4IDI1LjAwNTsiDQoJIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggc3R5bGU9ImZpbGw6IzAwMDAwMDsiIGQ9Ik0yOC44NTksMjQuMTU4TDE0Ljk1NywwLjI3OUMxNC44NTYsMC4xMDYsMTQuNjcsMCwxNC40NjgsMGMtMC4xOTgsMC0wLjM4MywwLjEwNi0wLjQ4MSwwLjI3OQ0KCUwwLjA3OSwyNC4xNThjLTAuMTAyLDAuMTc1LTAuMTA2LDAuMzg5LTAuMDA2LDAuNTY1YzAuMTAzLDAuMTc0LDAuMjg3LDAuMjgyLDAuNDg4LDAuMjgyaDI3LjgxNGMwLjIwMSwwLDAuMzg5LTAuMTA4LDAuNDg4LTAuMjgyDQoJYzAuMDQ3LTAuMDg4LDAuMDc0LTAuMTg2LDAuMDc0LTAuMjgxQzI4LjkzOCwyNC4zNDMsMjguOTExLDI0LjI0NSwyOC44NTksMjQuMTU4eiBNMTYuMzY5LDguNDc1bC0wLjQ2Miw5LjQ5M2gtMi4zODlsLTAuNDYxLTkuNDkzDQoJSDE2LjM2OXogTTE0LjcxMSwyMi44MjhoLTAuMDQyYy0xLjA4OSwwLTEuODQzLTAuODE3LTEuODQzLTEuOTA3YzAtMS4xMzEsMC43NzQtMS45MDcsMS44ODUtMS45MDdzMS44NDYsMC43NzUsMS44NjcsMS45MDcNCglDMTYuNTc5LDIyLjAxMSwxNS44NDQsMjIuODI4LDE0LjcxMSwyMi44Mjh6Ii8+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg==',
768
		'placemark'     => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMTAwcHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik01MC40MzQsMjAuMjcxYy0xMi40OTksMC0yMi42NjgsMTAuMTY5LTIyLjY2OCwyMi42NjhjMCwxMS44MTQsMTguODE1LDMyLjE1NSwyMC45NiwzNC40MzdsMS43MDgsMS44MTZsMS43MDgtMS44MTYNCgkJYzIuMTQ1LTIuMjgxLDIwLjk2LTIyLjYyMywyMC45Ni0zNC40MzdDNzMuMTAzLDMwLjQ0LDYyLjkzNCwyMC4yNzEsNTAuNDM0LDIwLjI3MXogTTUwLjQzNCw1Mi4zMmMtNS4xNzIsMC05LjM4LTQuMjA4LTkuMzgtOS4zOA0KCQlzNC4yMDgtOS4zOCw5LjM4LTkuMzhjNS4xNzMsMCw5LjM4LDQuMjA4LDkuMzgsOS4zOFM1NS42MDcsNTIuMzIsNTAuNDM0LDUyLjMyeiIvPg0KPC9nPg0KPC9zdmc+DQo=',
769
		'give_grey'     => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjEwMC4xIDAgNDAwIDQwMCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAxMDAuMSAwIDQwMCA0MDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnIGlkPSJMYXllcl8xXzFfIj48Y2lyY2xlIGZpbGw9IiM2NkJCNkEiIGN4PSItNDA3LjMiIGN5PSIzNDYuMyIgcj0iNDIuMiIvPjxnPjxnPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNzg2LjQsMTMzLjh2LTEyLjVoNC44YzMuOCwwLDYuNiwyLjUsNi42LDYuNHMtMi44LDYuNC02LjYsNi40aC00LjhWMTMzLjh6IE0tNzc3LjUsMTI3LjVjMC0yLjMtMS4zLTMuOC0zLjgtMy44aC0yLjN2Ny45aDIuM0MtNzc5LDEzMS42LTc3Ny41LDEyOS44LTc3Ny41LDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNzcxLjYsMTMzLjh2LTEyLjVoOC45djIuM2gtNi4xdjIuNWg2LjF2Mi4zaC02LjF2Mi44aDYuMXYyLjNoLTguOVYxMzMuOHoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTc0OC41LDEzMy44di04LjdsLTMuNiw4LjdoLTEuM2wtMy42LTguN3Y4LjdoLTIuNXYtMTIuNWgzLjhsMy4xLDcuNmwzLjEtNy42aDMuOHYxMi41SC03NDguNXoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTc0Mi40LDEyNy41YzAtMy44LDIuOC02LjQsNi42LTYuNHM2LjYsMi44LDYuNiw2LjRjMCwzLjgtMi44LDYuNC02LjYsNi40Qy03MzkuOCwxMzQuMS03NDIuNCwxMzEuMy03NDIuNCwxMjcuNXogTS03MzIuMiwxMjcuNWMwLTIuMy0xLjUtNC4xLTMuOC00LjFjLTIuMywwLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFDLTczMy43LDEzMS42LTczMi4yLDEyOS44LTczMi4yLDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNzI2LjgsMTI3LjVjMC0zLjgsMi44LTYuNCw2LjYtNi40YzIuOCwwLDQuMywxLjUsNS4zLDMuMWwtMi4zLDFjLTAuNS0xLTEuNS0xLjgtMy4xLTEuOGMtMi4zLDAtMy44LDEuOC0zLjgsNC4xYzAsMi4zLDEuNSw0LjEsMy44LDQuMWMxLjMsMCwyLjMtMC44LDMuMS0xLjhsMi4zLDFjLTEsMS41LTIuNSwzLjEtNS4zLDMuMUMtNzIzLjgsMTM0LjEtNzI2LjgsMTMxLjMtNzI2LjgsMTI3LjV6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS03MDQuNywxMzMuOGwtMi41LTQuM2gtMnY0LjNoLTIuNXYtMTIuNWg1LjljMi41LDAsNC4xLDEuOCw0LjEsNC4xYzAsMi4zLTEuMywzLjMtMi44LDMuOGwyLjgsNC44aC0yLjhWMTMzLjh6IE0tNzA0LjUsMTI1LjJjMC0xLTAuOC0xLjgtMS44LTEuOGgtMi44djMuM2gyLjhDLTcwNS41LDEyNy03MDQuNSwxMjYuNS03MDQuNSwxMjUuMnoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTY4OS43LDEzMy44bC0wLjgtMmgtNS4zbC0wLjgsMmgtMy4xbDQuOC0xMi41aDMuM2w0LjgsMTIuNUgtNjg5Ljd6IE0tNjkzLjMsMTIzLjlsLTIsNS4zaDMuOEwtNjkzLjMsMTIzLjl6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS02ODIuNiwxMzMuOHYtMTAuMmgtMy42di0yLjNoOS45djIuM2gtMy42djEwLjJILTY4Mi42eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjczLjIsMTMzLjh2LTEyLjVoMi41djEyLjVILTY3My4yeiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjY3LDEzMy44di0ybDUuOS03LjloLTUuOXYtMi4zaDkuNHYybC01LjksOC4xaDYuMXYyLjNoLTkuN1YxMzMuOHoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTY1NC4xLDEzMy44di0xMi41aDIuNXYxMi41SC02NTQuMXoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTYzOS4xLDEzMy44bC01LjktOC4xdjguMWgtMi41di0xMi41aDIuOGw1LjksNy45di03LjloMi41djEyLjVILTYzOS4xeiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjMzLjIsMTI3LjVjMC00LjEsMy4xLTYuNCw2LjYtNi40YzIuNSwwLDQuMywxLjMsNS4xLDIuOGwtMi4zLDEuM2MtMC41LTAuOC0xLjUtMS41LTMuMS0xLjVjLTIuMywwLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFjMSwwLDItMC41LDIuNS0xdi0xLjVoLTMuM1YxMjdoNS45djQuOGMtMS4zLDEuNS0zLjEsMi4zLTUuMywyLjNDLTYzMC4yLDEzNC4xLTYzMy4yLDEzMS42LTYzMy4yLDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjEyLjEsMTI3LjVjMC00LjEsMy4xLTYuNCw2LjYtNi40YzIuNSwwLDQuMywxLjMsNS4xLDIuOGwtMi4zLDEuM2MtMC41LTAuOC0xLjUtMS41LTMuMS0xLjVjLTIuMywwLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFjMSwwLDItMC41LDIuNS0xdi0xLjVoLTMuM1YxMjdoNS45djQuOGMtMS4zLDEuNS0zLjEsMi4zLTUuMywyLjNDLTYwOSwxMzQuMS02MTIuMSwxMzEuNi02MTIuMSwxMjcuNXoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTU5Ni42LDEzMy44di0xMi41aDguOXYyLjNoLTYuMXYyLjVoNi4xdjIuM2gtNi4xdjIuOGg2LjF2Mi4zaC04LjlWMTMzLjh6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01NzUuNywxMzMuOGwtNS45LTguMXY4LjFoLTIuNXYtMTIuNWgyLjhsNS45LDcuOXYtNy45aDIuNXYxMi41SC01NzUuN3oiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTU2OS4xLDEzMy44di0xMi41aDguOXYyLjNoLTYuMXYyLjVoNi4xdjIuM2gtNi4xdjIuOGg2LjF2Mi4zaC04LjlWMTMzLjh6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01NDkuNywxMzMuOGwtMi41LTQuM2gtMnY0LjNoLTIuNXYtMTIuNWg1LjljMi41LDAsNC4xLDEuOCw0LjEsNC4xYzAsMi4zLTEuMywzLjMtMi44LDMuOGwyLjgsNC44aC0yLjhWMTMzLjh6IE0tNTQ5LjUsMTI1LjJjMC0xLTAuOC0xLjgtMS44LTEuOGgtMi44djMuM2gyLjhDLTU1MC4zLDEyNy01NDkuNSwxMjYuNS01NDkuNSwxMjUuMnoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTU0My45LDEyNy41YzAtMy44LDIuOC02LjQsNi42LTYuNHM2LjYsMi44LDYuNiw2LjRjMCwzLjgtMi44LDYuNC02LjYsNi40Qy01NDEuMywxMzQuMS01NDMuOSwxMzEuMy01NDMuOSwxMjcuNXogTS01MzMuNywxMjcuNWMwLTIuMy0xLjUtNC4xLTMuOC00LjFzLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFDLTUzNS4yLDEzMS42LTUzMy43LDEyOS44LTUzMy43LDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNTI4LjYsMTMyLjFsMS41LTJjMC44LDEsMi4zLDEuOCw0LjEsMS44YzEuNSwwLDIuMy0wLjgsMi4zLTEuM2MwLTIuMy03LjEtMC44LTcuMS01LjNjMC0yLDEuOC0zLjgsNC44LTMuOGMyLDAsMy42LDAuNSw0LjgsMS44bC0xLjUsMmMtMS0xLTIuMy0xLjMtMy42LTEuM2MtMSwwLTEuOCwwLjUtMS44LDEuM2MwLDIsNy4xLDAuOCw3LjEsNS4zYzAsMi4zLTEuNSw0LjEtNS4xLDQuMUMtNTI1LjYsMTM0LjEtNTI3LjQsMTMzLjEtNTI4LjYsMTMyLjF6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01MTUuMSwxMzMuOHYtMTIuNWgyLjV2MTIuNUgtNTE1LjF6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01MDUuNywxMzMuOHYtMTAuMmgtMy42di0yLjNoOS45djIuM2gtMy42djEwLjJILTUwNS43eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNDkyLjcsMTMzLjh2LTUuMWwtNC44LTcuNGgzLjFsMy4xLDUuMWwzLjEtNS4xaDMuMWwtNC44LDcuNHY1LjFILTQ5Mi43eiIvPjwvZz48Zz48Zz48cGF0aCBmaWxsPSIjNjZCQjZBIiBkPSJNLTQ4NS45LDQ0LjNoLTEuM2wwLjMsMS4zYzIsOS45LDAuMywyNC43LTcuNCwzMy44Yy00LjMsNS4zLTkuOSw4LjEtMTYuOCw4LjFjLTEwLjksMC0xNS0xMy0xNS41LTI3LjdjMTcuOC00LjMsMjkuOC0xNS41LDI5LjgtMjguNWMwLTkuNC0yLjgtMjQuOS0yMS40LTI0LjljLTE3LjYsMC0yNi41LDI2LjItMjguMiw0NC41Yy04LjktMC4zLTE1LjUtNC4zLTE5LjYtOC4xYzEuNS02LjQsMi4zLTEyLjIsMi4zLTE3LjZjMC03LjQtNS4xLTEwLjctOS45LTEwLjdjLTYuOSwwLTE0LDYuNi0xNCwxOS4zYzAsNy42LDIuOCwxNCw4LjcsMTguNmMtNS4xLDEyLTEzLjcsMjIuMS0xNi41LDI1LjRjLTIuMy00LjgtOS43LTIyLjQtMTItNDEuNWMyLjgtNy42LDQuMy0xNCw0LjMtMTdjMC00LjgtMy4xLTcuNi04LjEtNy42Yy02LjksMC0xNy44LDQuMy0xOC4xLDQuNmwtMC41LDAuM3YwLjhjMCwwLjMsMy4zLDE1LjUsNi42LDMyLjNjLTYuNCwxMC40LTE3LjYsMjcuNy0yMy4yLDI3LjdjLTEwLjIsMCw2LjYtNTIuMi0wLjgtNTMuOWMtMC4zLDAtMC41LDAtMC44LDAuM2MtMy42LDIuMy00My41LDI0LjQtOTYuNywyNC40YzAsMCwwLDEsMC41LDJjMC4zLDAuOCwxLDEuNSwxLDEuNWMxNSwxLjgsMzYuNC0wLjMsNTIuNy0yLjVjLTkuNCwyMC4xLTI2LDMzLjMtNDEuMiwzMy4zYy0yOC44LDAtNTAuOS0zNC45LTUwLjktMzQuOWM4LjktNy45LDIzLjQtMzMuMyw0NC44LTMzLjNjMjEuMSwwLDMwLjMsMTEuNywzMC4zLDExLjdsMi4zLTMuOGMwLDAtOS45LTM0LjYtMzcuOS0zNC42cy01Ny44LDQ1LjgtNzUuMSw1Ni41YzAsMCwyMy45LDU2LjUsNzYuMSw1Ni41YzQzLjgsMCw1NS00Miw1Ny01Mi4yYzEwLjctMS41LDE4LjEtMy4xLDE4LjEtMy4xcy0yLjgsMjEuNC0yLjgsMzAuM3M5LjksMTguMywxOC4xLDE4LjNjNi45LDAsMjAuOS0xNC4yLDMxLTMxLjZsMC41LDJjNS4zLDE5LjYsMTIsMjkuOCwxOS44LDI5LjhjNy45LDAsMjAuOS0xNi4zLDI5LjMtMzYuOWM4LjQsMy42LDE4LjMsNC42LDI0LjIsNC44YzIuMywzNS40LDMxLjgsMzYuNCwzNS40LDM2LjRjMjEuOSwwLDQwLjUtMTUuOCw0MC41LTM0LjRDLTQ3MC42LDQ0LjUtNDg1LjYsNDQuMy00ODUuOSw0NC4zeiBNLTUxMi42LDI5LjVjMCwwLTAuMywxMS43LTEzLjUsMTcuNmMxLjMtMTUuNSw1LjEtMjkuNSw3LjYtMjkuNUMtNTE1LjYsMTcuOC01MTIuNiwyMi4xLTUxMi42LDI5LjV6Ii8+PHBhdGggZmlsbD0iIzY2QkI2QSIgZD0iTS02NjUsMTUuNWMwLDAuNSwwLjMsMC44LDAuOCwxYzEwLjQsMS41LDE3LjMtMS44LDE3LjMtMTguNmMwLTE1LjgtMTYuMy0zLjMtMTkuMy0xYy0wLjMsMC4zLTAuMywwLjUtMC4zLDFDLTY2My43LDQuMS02NjQuOCwxMy02NjUsMTUuNXoiLz48L2c+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMjg5LjU4NjQiIHkxPSIzNzMuMjM3OSIgeDI9Ii0yODIuODg0MiIgeTI9IjM3NS40NzE5IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xXykiIGQ9Ik0tNjIzLDQ5LjRjLTQuMSw2LjktMTAuMiwxNi4zLTE1LjUsMjIuMWMxLjMsMy4xLDIuOCw2LjksNC4zLDkuOWM0LjgtNS4zLDkuNy0xMi4yLDE0LTE5LjNMLTYyMyw0OS40eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMl8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI2OS4wNTc3IiB5MT0iMzcxLjU0NDEiIHgyPSItMjY1LjE3MDUiIHkyPSIzNzguMzgwMiIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfMl8pIiBkPSJNLTU3NC43LDU0LjdjLTItMS0zLjgtMi41LTMuOC0yLjVjLTMuNiw3LjktOC40LDE1LjMtMTIuMiwyMC4xYzEuOCwyLjUsNC44LDUuOSw3LjEsOC40YzQuNi02LjQsOS40LTE0LjgsMTMtMjMuN0MtNTcwLjQsNTYuNy01NzIuNiw1Ni01NzQuNyw1NC43eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfM18iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI0OC42NDE2IiB5MT0iMzY4LjM4MzUiIHgyPSItMjQ5LjQ0NTkiIHkyPSIzNzUuNTMyMyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfM18pIiBkPSJNLTUyNi4zLDU5LjhjMCwwLTUuMSwxLTEwLjIsMS41cy05LjksMC4zLTkuOSwwLjNjMC44LDEwLjIsMy42LDE3LjMsNy40LDIyLjZsMTguNi0xLjVDLTUyNC4zLDc3LjYtNTI2LjEsNjktNTI2LjMsNTkuOHoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzRfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yNDkuOCIgeTE9IjM4My41ODEiIHgyPSItMjQ5LjgiIHkyPSIzNzYuMzc2MyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfNF8pIiBkPSJNLTU0MS4xLDI4LjhMLTU0MS4xLDI4LjhjLTAuNSwxLjUtMS4zLDMuMy0xLjgsNS4xYzAsMC41LTAuMywwLjgtMC4zLDEuM2MtMSwzLjMtMS44LDYuNi0yLjMsOS45YzAsMC41LTAuMywwLjgtMC4zLDEuM2MtMC4zLDEuNS0wLjUsMy4xLTAuNSw0LjZjMTIsMCwyMC4xLTMuNiwyMC4xLTMuNmMwLTEuMywwLjMtMi4zLDAuMy0zLjZjMC0wLjMsMC0wLjUsMC0wLjhjMC0xLDAuMy0xLjgsMC4zLTIuOGMwLTAuMywwLTAuNSwwLTAuOGMwLjMtMi4zLDAuOC00LjYsMS02LjZMLTU0MS4xLDI4Ljh6IE0tNTQ2LjQsNTAuNkwtNTQ2LjQsNTAuNkwtNTQ2LjQsNTAuNkwtNTQ2LjQsNTAuNnoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzVfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zMTMiIHkxPSIzNzEuNzcyMiIgeDI9Ii0zMTMiIHkyPSIzODAuNzA4MyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfNV8pIiBkPSJNLTcwOC4zLDcyLjhsMTEuMiw0LjhjNS4zLTcuNiw4LjctMTUuNSwxMC43LTIxLjZsMi04LjFsLTUuMywwLjhDLTY5NC41LDU4LjgtNzAxLjEsNjYuOS03MDguMyw3Mi44eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfNl8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI3Ny41MjU1IiB5MT0iMzkwLjIxMyIgeDI9Ii0yNzguNjQ3OSIgeTI9IjM4OC40MjU0IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF82XykiIGQ9Ik0tNjA3LDM2LjFjMi44LTcuNiw0LjMtMTQsNC4zLTE3YzAtMC4zLDAtMC41LDAtMC44bC02LjYsMkMtNjA5LjMsMjAuNC02MDksMjQuNy02MDcsMzYuMXoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzdfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yNjIuNTgxMyIgeTE9IjM4Ni40ODI3IiB4Mj0iLTI2My4yMTUiIHkyPSIzODQuMDc0OSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfN18pIiBkPSJNLTU3MS40LDMwLjVjMCwwLTEuOCw1LjMsNS42LDEyYzEuMy01LjMsMi0xMC43LDIuMy0xNS4zTC01NzEuNCwzMC41eiIvPjwvZz48L2c+PGc+PGc+PHBhdGggZmlsbD0iIzY2QkI2QSIgZD0iTS04MDcuOCwzNDYuNmgtMC41djAuNWMwLjgsNC4zLDAsMTAuNC0zLjEsMTQuNWMtMS44LDIuMy00LjMsMy42LTcuMSwzLjZjLTQuNiwwLTYuNC01LjYtNi42LTExLjdjNy42LTEuOCwxMi43LTYuNiwxMi43LTEyLjJjMC00LjEtMS4zLTEwLjctOS4yLTEwLjdjLTcuNCwwLTExLjIsMTEuMi0xMiwxOC44Yy0zLjgsMC02LjYtMS44LTguNC0zLjZjMC44LTIuOCwxLTUuMSwxLTcuNGMwLTMuMS0yLjMtNC42LTQuMS00LjZjLTMuMSwwLTUuOSwyLjgtNS45LDguMWMwLDMuMywxLjMsNS45LDMuOCw3LjljLTIuMyw1LjEtNS45LDkuNC03LjEsMTAuN2MtMS0yLTQuMS05LjctNS4xLTE3LjZjMS4zLTMuMywxLjgtNS45LDEuOC03LjFjMC0yLTEuMy0zLjMtMy42LTMuM2MtMy4xLDAtNy42LDEuOC03LjYsMmwtMC4zLDAuM3YwLjNjMCwwLDEuMyw2LjYsMi44LDEzLjdjLTIuOCw0LjMtNy40LDExLjctOS45LDExLjdjLTQuMywwLDIuOC0yMi4xLTAuMy0yMi45aC0wLjNjLTEuNSwxLTE4LjYsMTAuNC00MSwxMC40YzAsMCwwLDAuNSwwLjMsMC44YzAuMywwLjMsMC41LDAuNSwwLjUsMC41YzYuNCwwLjgsMTUuNSwwLDIyLjQtMWMtNC4xLDguNC0xMC45LDE0LjItMTcuNiwxNC4yYy0xMi4yLDAtMjEuNi0xNC44LTIxLjYtMTQuOGMzLjgtMy4zLDkuOS0xNC4yLDE5LjEtMTQuMmM4LjksMCwxMyw0LjgsMTMsNC44bDEtMS41YzAsMC00LjMtMTQuOC0xNi0xNC44cy0yNC40LDE5LjYtMzEuOCwyMy45YzAsMCwxMC4yLDI0LjIsMzIuMywyNC4yYzE4LjYsMCwyMy40LTE3LjgsMjQuMi0yMi4xYzQuNi0wLjgsNy42LTEuMyw3LjYtMS4zcy0xLDkuMi0xLDEzYzAsMy44LDQuMSw3LjksNy42LDcuOWMzLjEsMCw4LjktNi4xLDEzLjItMTMuNWwwLjMsMC44YzIuMyw4LjQsNS4xLDEyLjcsOC40LDEyLjdzOC45LTYuOSwxMi41LTE1LjVjMy42LDEuNSw3LjksMiwxMC4yLDJjMSwxNSwxMy41LDE1LjUsMTUsMTUuNWM5LjQsMCwxNy4zLTYuNiwxNy4zLTE0LjVDLTgwMS40LDM0Ni44LTgwNy44LDM0Ni42LTgwNy44LDM0Ni42eiBNLTgxOSwzNDAuMmMwLDAsMCw1LjEtNS45LDcuNmMwLjUtNi42LDItMTIuNSwzLjMtMTIuNUMtODIwLjUsMzM1LjQtODE5LDMzNy4yLTgxOSwzNDAuMnoiLz48cGF0aCBmaWxsPSIjNjZCQjZBIiBkPSJNLTg4My44LDMzNC40YzAsMC4zLDAsMC4zLDAuMywwLjVjNC4zLDAuNSw3LjQtMC44LDcuNC03LjljMC02LjYtNi45LTEuNS04LjEtMC41YzAsMC0wLjMsMC4zLDAsMC41Qy04ODMuMywzMjkuNS04ODMuOCwzMzMuMS04ODMuOCwzMzQuNHoiLz48L2c+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF84XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzgyLjAwNzQiIHkxPSIyNTkuODQ3NSIgeDI9Ii0zNzkuMTU4NSIgeTI9IjI2MC43OTcyIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF84XykiIGQ9Ik0tODY2LDM0OC42Yy0xLjgsMi44LTQuMyw2LjktNi42LDkuNGMwLjUsMS4zLDEuMywyLjgsMS44LDQuM2MyLTIuMyw0LjEtNS4xLDYuMS04LjFMLTg2NiwzNDguNnoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzlfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zNzMuMTYyNiIgeTE9IjI1OS4wNDIzIiB4Mj0iLTM3MS41MTAyIiB5Mj0iMjYxLjk0ODIiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMi41NDQ1IDAgMCAtMi41NDQ1IDEwMC4xMjcyIDEwMTcuODExNykiPjxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz48c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+PC9saW5lYXJHcmFkaWVudD48cGF0aCBmaWxsPSJ1cmwoI1NWR0lEXzlfKSIgZD0iTS04NDUuNCwzNTAuOWMtMC44LTAuNS0xLjUtMS0xLjUtMWMtMS41LDMuMy0zLjYsNi40LTUuMSw4LjdjMC44LDEsMiwyLjUsMy4xLDMuNmMyLTIuOCw0LjEtNi4xLDUuNi0xMC4yQy04NDMuNiwzNTEuOS04NDQuNywzNTEuNC04NDUuNCwzNTAuOXoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEwXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzY0LjY5OTYiIHkxPSIyNTcuNzUwMyIgeDI9Ii0zNjUuMDQxNCIgeTI9IjI2MC43ODkyIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xMF8pIiBkPSJNLTgyNS4xLDM1My4yYzAsMC0yLDAuNS00LjMsMC44Yy0yLDAuMy00LjMsMC00LjMsMGMwLjMsNC4zLDEuNSw3LjQsMy4xLDkuN2w3LjktMC44Qy04MjQsMzYwLjgtODI0LjgsMzU3LTgyNS4xLDM1My4yeiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTFfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zNjUiIHkxPSIyNjQuMjIyMyIgeDI9Ii0zNjUiIHkyPSIyNjEuMTU5NyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfMTFfKSIgZD0iTS04MzEuMiwzMzkuOUwtODMxLjIsMzM5LjljLTAuMywwLjgtMC41LDEuNS0wLjgsMmMwLDAuMywwLDAuMy0wLjMsMC41Yy0wLjUsMS41LTAuOCwyLjgtMSw0LjNjMCwwLjMsMCwwLjMsMCwwLjVjMCwwLjgtMC4zLDEuMy0wLjMsMmM1LjEsMCw4LjctMS41LDguNy0xLjVjMC0wLjUsMC0xLDAuMy0xLjV2LTAuM2MwLTAuNSwwLTAuOCwwLjMtMXYtMC4zYzAuMy0xLDAuMy0yLDAuNS0yLjhMLTgzMS4yLDMzOS45eiBNLTgzMy41LDM0OS40TC04MzMuNSwzNDkuNEwtODMzLjUsMzQ5LjRMLTgzMy41LDM0OS40eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTJfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zOTIiIHkxPSIyNTkuMjAyNSIgeDI9Ii0zOTIiIHkyPSIyNjMuMDAxMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfMTJfKSIgZD0iTS05MDIuNCwzNTguOGw0LjgsMmMyLjMtMy4zLDMuNi02LjYsNC42LTkuMmwwLjgtMy42bC0yLjMsMC4zQy04OTYuNiwzNTIuNy04OTkuMSwzNTYuMi05MDIuNCwzNTguOHoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEzXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzc2Ljg2MzciIHkxPSIyNjcuMDM1NSIgeDI9Ii0zNzcuMzQwOSIgeTI9IjI2Ni4yNzU1IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xM18pIiBkPSJNLTg1OS4yLDM0M2MxLjMtMy4zLDEuOC01LjksMS44LTcuMXYtMC4zbC0yLjgsMC44Qy04NjAuMiwzMzYuNC04NjAuMiwzMzguMi04NTkuMiwzNDN6Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xNF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM3MC41NTQzIiB5MT0iMjY1LjQ2NDUiIHgyPSItMzcwLjgyMzYiIHkyPSIyNjQuNDQxIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xNF8pIiBkPSJNLTg0NC4xLDM0MC43YzAsMC0wLjgsMi4zLDIuMyw1LjFjMC41LTIuMywxLTQuNiwxLTYuNkwtODQ0LjEsMzQwLjd6Ii8+PC9nPjxnPjxyZWN0IHg9Ii02OTcuMyIgeT0iMjkyLjkiIGZpbGw9IiNGRkZGRkYiIHdpZHRoPSIxMDYuOSIgaGVpZ2h0PSIxMDYuOSIvPjxnPjxwYXRoIGZpbGw9IiM2NkJCNkEiIGQ9Ik0tNjQ0LjQsMzQ5LjljMC4zLDAuNSwwLjUsMC44LDAuNSwwLjhjOC43LDEsMjEuMSwwLDMwLjUtMS41Yy01LjMsMTEuNy0xNSwxOS4zLTIzLjksMTkuM2MtMTYuNSwwLTI5LjUtMjAuMS0yOS41LTIwLjFjNS4xLTQuNiwxMy43LTE5LjMsMjYtMTkuM2MxMi4yLDAsMTcuNiw2LjYsMTcuNiw2LjZsMS4zLTIuM2MwLDAtNS45LTIwLjEtMjEuOS0yMC4xYy0xNi4zLDAtMzMuMywyNi41LTQzLjUsMzIuNmMwLDAsMTMuNywzMi44LDQ0LDMyLjhjMjUuNCwwLDMxLjgtMjQuMiwzMy4xLTMwLjNjMy4zLTAuNSw2LjEtMSw4LjEtMS4zYzAuNS0xLjMsMS4zLTMuOCwwLjgtNy4xYy0xMC4yLDMuOC0yNS40LDguNC00My41LDguNEMtNjQ0LjcsMzQ4LjYtNjQ0LjcsMzQ5LjEtNjQ0LjQsMzQ5Ljl6Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xNV8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI4MS44NSIgeTE9IjI1Ny41MTg3IiB4Mj0iLTI4MS44NSIgeTI9IjI2Mi42NTExIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xNV8pIiBkPSJNLTYxMC4xLDM0OC45bC0zLjEsMC4zYzAsMC4zLTAuMywwLjUtMC41LDAuOGMtMC41LDEtMSwxLjgtMS41LDIuOGMtMC4zLDAuNS0wLjUsMC44LTAuOCwxLjNjLTAuNSwxLTEuMywyLTIsMi44Yy0wLjMsMC4zLTAuMywwLjMtMC41LDAuNWMtMS44LDIuMy0zLjYsNC4zLTUuNiw1LjlsNi40LDIuOEMtNjEyLjYsMzU5LjMtNjEwLjYsMzUxLjctNjEwLjEsMzQ4Ljl6Ii8+PC9nPjwvZz48Zz48Zz48ZGVmcz48Y2lyY2xlIGlkPSJTVkdJRF8xNl8iIGN4PSItNDA3LjMiIGN5PSIzNDYuMyIgcj0iNDIuMiIvPjwvZGVmcz48Y2xpcFBhdGggaWQ9IlNWR0lEXzE3XyI+PHVzZSB4bGluazpocmVmPSIjU1ZHSURfMTZfIiAgb3ZlcmZsb3c9InZpc2libGUiLz48L2NsaXBQYXRoPjxwYXRoIGNsaXAtcGF0aD0idXJsKCNTVkdJRF8xN18pIiBmaWxsPSIjRkZGRkZGIiBkPSJNLTQwMS4xLDM0OS40YzAuMywwLjMsMC41LDAuOCwwLjUsMC44YzcuNCwxLDE4LjEsMCwyNi4yLTEuM2MtNC42LDkuOS0xMywxNi41LTIwLjQsMTYuNWMtMTQuMiwwLTI1LjItMTcuMy0yNS4yLTE3LjNjNC4zLTMuOCwxMS43LTE2LjUsMjIuMS0xNi41czE1LDUuOSwxNSw1LjlsMS4zLTEuOGMwLDAtNC44LTE3LTE4LjgtMTdzLTI4LjUsMjIuNi0zNy4yLDI4YzAsMCwxMiwyOCwzNy43LDI4YzIxLjYsMCwyNy4yLTIwLjksMjguMi0yNmMyLjgtMC41LDUuMy0wLjgsNi45LTFjMC41LTEuMywxLTMuMywwLjgtNi4xYy04LjcsMy4zLTIxLjYsNy4xLTM3LjIsNy4xQy00MDEuNCwzNDguMy00MDEuNCwzNDguOS00MDEuMSwzNDkuNHoiLz48L2c+PC9nPjwvZz48ZyBpZD0iTGF5ZXJfMiI+PHBhdGggZmlsbD0iIzg4ODg4OCIgZD0iTTQ2Ny4zLDIwOS45Yy00LjgsMjQuNC0zMC44LDEyMi42LTEzMy42LDEyMi42Yy0xMjIuNiwwLTE3OC42LTEzMi44LTE3OC42LTEzMi44YzQxLTI0LjksMTEwLjQtMTMyLjMsMTc2LjEtMTMyLjNzODguOCw4MS4yLDg4LjgsODEuMmwtNS42LDguOWMwLDAtMjEuNi0yNy4yLTcxLjItMjcuMnMtODMuNyw1OS44LTEwNC42LDc4LjRjMCwwLDUyLjIsODEuNywxMTkuMyw4MS43YzM2LjEsMCw3NS4xLTMxLjMsOTYuOS03OC40Yy0zOC4yLDUuMy04OC4zLDEwLjItMTIzLjcsNS42YzAsMC0xLjgtMS41LTIuNS0zLjNjLTEtMi4zLTEuMy00LjYtMS4zLTQuNmM3MC4yLDAsMTMwLjUtMTYuNSwxNzEuNS0zMS44QzQ4Ny43LDc3LjYsNDAyLjksMCwzMDAuMSwwYy0xMTAuNCwwLTIwMCw4OS42LTIwMCwyMDBzODkuNiwyMDAsMjAwLDIwMGMxMDguOSwwLDE5Ny41LTg3LDIwMC0xOTUuNEM0OTIuNSwyMDUuOSw0ODEsMjA3LjksNDY3LjMsMjA5Ljl6Ii8+PC9nPjwvc3ZnPg==',
770
		'give_cpt_icon' => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAxNTcuMSAxNTcuMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTU3LjEgMTU3LjI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJLnN0MHtmaWxsOiM2NkJCNkE7fQ0KCS5zdDF7ZmlsbDojNTQ2RTdBO30NCgkuc3Qye2ZpbGw6dXJsKCNTVkdJRF8xXyk7fQ0KCS5zdDN7ZmlsbDp1cmwoI1NWR0lEXzJfKTt9DQoJLnN0NHtmaWxsOnVybCgjU1ZHSURfM18pO30NCgkuc3Q1e2ZpbGw6dXJsKCNTVkdJRF80Xyk7fQ0KCS5zdDZ7ZmlsbDp1cmwoI1NWR0lEXzVfKTt9DQoJLnN0N3tmaWxsOnVybCgjU1ZHSURfNl8pO30NCgkuc3Q4e2ZpbGw6dXJsKCNTVkdJRF83Xyk7fQ0KCS5zdDl7ZmlsbDp1cmwoI1NWR0lEXzhfKTt9DQoJLnN0MTB7ZmlsbDp1cmwoI1NWR0lEXzlfKTt9DQoJLnN0MTF7ZmlsbDp1cmwoI1NWR0lEXzEwXyk7fQ0KCS5zdDEye2ZpbGw6dXJsKCNTVkdJRF8xMV8pO30NCgkuc3QxM3tmaWxsOnVybCgjU1ZHSURfMTJfKTt9DQoJLnN0MTR7ZmlsbDp1cmwoI1NWR0lEXzEzXyk7fQ0KCS5zdDE1e2ZpbGw6dXJsKCNTVkdJRF8xNF8pO30NCgkuc3QxNntmaWxsOiNGRkZGRkY7fQ0KCS5zdDE3e2ZpbGw6dXJsKCNTVkdJRF8xNV8pO30NCgkuc3QxOHtjbGlwLXBhdGg6dXJsKCNTVkdJRF8xN18pO2ZpbGw6I0ZGRkZGRjt9DQoJLnN0MTl7ZmlsbDojRjFGMkYyO30NCjwvc3R5bGU+DQo8ZyBpZD0iTGF5ZXJfMSI+DQoJPGNpcmNsZSBjbGFzcz0ic3QwIiBjeD0iLTE5OS40IiBjeT0iMTM2LjEiIHI9IjE2LjYiLz4NCgk8Zz4NCgkJPGc+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTM0OC40LDUyLjZ2LTQuOWgxLjljMS41LDAsMi42LDEsMi42LDIuNWMwLDEuNS0xLjEsMi41LTIuNiwyLjVILTM0OC40eiBNLTM0NC45LDUwLjENCgkJCQljMC0wLjktMC41LTEuNS0xLjUtMS41aC0wLjl2My4xaDAuOUMtMzQ1LjUsNTEuNy0zNDQuOSw1MS0zNDQuOSw1MC4xeiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0zNDIuNiw1Mi42di00LjloMy41djAuOWgtMi40djFoMi40djAuOWgtMi40djEuMWgyLjR2MC45SC0zNDIuNnoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzMzLjUsNTIuNnYtMy40bC0xLjQsMy40aC0wLjVsLTEuNC0zLjR2My40aC0xdi00LjloMS41bDEuMiwzbDEuMi0zaDEuNXY0LjlILTMzMy41eiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0zMzEuMSw1MC4xYzAtMS41LDEuMS0yLjUsMi42LTIuNWMxLjUsMCwyLjYsMS4xLDIuNiwyLjVjMCwxLjUtMS4xLDIuNS0yLjYsMi41DQoJCQkJQy0zMzAuMSw1Mi43LTMzMS4xLDUxLjYtMzMxLjEsNTAuMXogTS0zMjcuMSw1MC4xYzAtMC45LTAuNi0xLjYtMS41LTEuNnMtMS41LDAuNy0xLjUsMS42YzAsMC45LDAuNiwxLjYsMS41LDEuNg0KCQkJCVMtMzI3LjEsNTEtMzI3LjEsNTAuMXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzI1LDUwLjFjMC0xLjUsMS4xLTIuNSwyLjYtMi41YzEuMSwwLDEuNywwLjYsMi4xLDEuMmwtMC45LDAuNGMtMC4yLTAuNC0wLjYtMC43LTEuMi0wLjcNCgkJCQljLTAuOSwwLTEuNSwwLjctMS41LDEuNmMwLDAuOSwwLjYsMS42LDEuNSwxLjZjMC41LDAsMC45LTAuMywxLjItMC43bDAuOSwwLjRjLTAuNCwwLjYtMSwxLjItMi4xLDEuMg0KCQkJCUMtMzIzLjgsNTIuNy0zMjUsNTEuNi0zMjUsNTAuMXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzE2LjMsNTIuNmwtMS0xLjdoLTAuOHYxLjdoLTF2LTQuOWgyLjNjMSwwLDEuNiwwLjcsMS42LDEuNmMwLDAuOS0wLjUsMS4zLTEuMSwxLjVsMS4xLDEuOUgtMzE2LjN6DQoJCQkJIE0tMzE2LjIsNDkuMmMwLTAuNC0wLjMtMC43LTAuNy0wLjdoLTEuMXYxLjNoMS4xQy0zMTYuNiw0OS45LTMxNi4yLDQ5LjctMzE2LjIsNDkuMnoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzEwLjQsNTIuNmwtMC4zLTAuOGgtMi4xbC0wLjMsMC44aC0xLjJsMS45LTQuOWgxLjNsMS45LDQuOUgtMzEwLjR6IE0tMzExLjgsNDguN2wtMC44LDIuMWgxLjUNCgkJCQlMLTMxMS44LDQ4Ljd6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTMwNy42LDUyLjZ2LTRoLTEuNHYtMC45aDMuOXYwLjloLTEuNHY0SC0zMDcuNnoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzAzLjksNTIuNnYtNC45aDF2NC45SC0zMDMuOXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzAxLjUsNTIuNnYtMC44bDIuMy0zLjFoLTIuM3YtMC45aDMuN3YwLjhsLTIuMywzLjJoMi40djAuOUgtMzAxLjV6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI5Ni40LDUyLjZ2LTQuOWgxdjQuOUgtMjk2LjR6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI5MC41LDUyLjZsLTIuMy0zLjJ2My4yaC0xdi00LjloMS4xbDIuMywzLjF2LTMuMWgxdjQuOUgtMjkwLjV6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI4OC4yLDUwLjFjMC0xLjYsMS4yLTIuNSwyLjYtMi41YzEsMCwxLjcsMC41LDIsMS4xbC0wLjksMC41Yy0wLjItMC4zLTAuNi0wLjYtMS4yLTAuNg0KCQkJCWMtMC45LDAtMS41LDAuNy0xLjUsMS42YzAsMC45LDAuNiwxLjYsMS41LDEuNmMwLjQsMCwwLjgtMC4yLDEtMC40di0wLjZoLTEuM3YtMC45aDIuM3YxLjljLTAuNSwwLjYtMS4yLDAuOS0yLjEsMC45DQoJCQkJQy0yODcsNTIuNy0yODguMiw1MS43LTI4OC4yLDUwLjF6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI3OS45LDUwLjFjMC0xLjYsMS4yLTIuNSwyLjYtMi41YzEsMCwxLjcsMC41LDIsMS4xbC0wLjksMC41Yy0wLjItMC4zLTAuNi0wLjYtMS4yLTAuNg0KCQkJCWMtMC45LDAtMS41LDAuNy0xLjUsMS42YzAsMC45LDAuNiwxLjYsMS41LDEuNmMwLjQsMCwwLjgtMC4yLDEtMC40di0wLjZoLTEuM3YtMC45aDIuM3YxLjljLTAuNSwwLjYtMS4yLDAuOS0yLjEsMC45DQoJCQkJQy0yNzguNyw1Mi43LTI3OS45LDUxLjctMjc5LjksNTAuMXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMjczLjgsNTIuNnYtNC45aDMuNXYwLjloLTIuNHYxaDIuNHYwLjloLTIuNHYxLjFoMi40djAuOUgtMjczLjh6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI2NS42LDUyLjZsLTIuMy0zLjJ2My4yaC0xdi00LjloMS4xbDIuMywzLjF2LTMuMWgxdjQuOUgtMjY1LjZ6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI2Myw1Mi42di00LjloMy41djAuOWgtMi40djFoMi40djAuOWgtMi40djEuMWgyLjR2MC45SC0yNjN6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI1NS40LDUyLjZsLTEtMS43aC0wLjh2MS43aC0xdi00LjloMi4zYzEsMCwxLjYsMC43LDEuNiwxLjZjMCwwLjktMC41LDEuMy0xLjEsMS41bDEuMSwxLjlILTI1NS40eg0KCQkJCSBNLTI1NS4zLDQ5LjJjMC0wLjQtMC4zLTAuNy0wLjctMC43aC0xLjF2MS4zaDEuMUMtMjU1LjYsNDkuOS0yNTUuMyw0OS43LTI1NS4zLDQ5LjJ6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI1My4xLDUwLjFjMC0xLjUsMS4xLTIuNSwyLjYtMi41YzEuNSwwLDIuNiwxLjEsMi42LDIuNWMwLDEuNS0xLjEsMi41LTIuNiwyLjUNCgkJCQlDLTI1Mi4xLDUyLjctMjUzLjEsNTEuNi0yNTMuMSw1MC4xeiBNLTI0OS4xLDUwLjFjMC0wLjktMC42LTEuNi0xLjUtMS42Yy0wLjksMC0xLjUsMC43LTEuNSwxLjZjMCwwLjksMC42LDEuNiwxLjUsMS42DQoJCQkJQy0yNDkuNyw1MS43LTI0OS4xLDUxLTI0OS4xLDUwLjF6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI0Ny4xLDUxLjlsMC42LTAuOGMwLjMsMC40LDAuOSwwLjcsMS42LDAuN2MwLjYsMCwwLjktMC4zLDAuOS0wLjVjMC0wLjktMi44LTAuMy0yLjgtMi4xDQoJCQkJYzAtMC44LDAuNy0xLjUsMS45LTEuNWMwLjgsMCwxLjQsMC4yLDEuOSwwLjdsLTAuNiwwLjhjLTAuNC0wLjQtMC45LTAuNS0xLjQtMC41Yy0wLjQsMC0wLjcsMC4yLTAuNywwLjVjMCwwLjgsMi44LDAuMywyLjgsMi4xDQoJCQkJYzAsMC45LTAuNiwxLjYtMiwxLjZDLTI0NS45LDUyLjctMjQ2LjYsNTIuMy0yNDcuMSw1MS45eiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0yNDEuOCw1Mi42di00LjloMXY0LjlILTI0MS44eiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0yMzguMSw1Mi42di00aC0xLjR2LTAuOWgzLjl2MC45aC0xLjR2NEgtMjM4LjF6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTIzMyw1Mi42di0ybC0xLjktMi45aDEuMmwxLjIsMmwxLjItMmgxLjJsLTEuOSwyLjl2MkgtMjMzeiIvPg0KCQk8L2c+DQoJCTxnPg0KCQkJPGc+DQoJCQkJPHBhdGggY2xhc3M9InN0MCIgZD0iTS0yMzAuMywxNy40bC0wLjUsMGwwLjEsMC41YzAuOCwzLjksMC4xLDkuNy0yLjksMTMuM2MtMS43LDIuMS0zLjksMy4yLTYuNiwzLjJjLTQuMywwLTUuOS01LjEtNi4xLTEwLjkNCgkJCQkJYzctMS43LDExLjctNi4xLDExLjctMTEuMmMwLTMuNy0xLjEtOS44LTguNC05LjhjLTYuOSwwLTEwLjQsMTAuMy0xMS4xLDE3LjVjLTMuNS0wLjEtNi4xLTEuNy03LjctMy4yYzAuNi0yLjUsMC45LTQuOCwwLjktNi45DQoJCQkJCWMwLTIuOS0yLTQuMi0zLjktNC4yYy0yLjcsMC01LjUsMi42LTUuNSw3LjZjMCwzLDEuMSw1LjUsMy40LDcuM2MtMiw0LjctNS40LDguNy02LjUsMTBjLTAuOS0xLjktMy44LTguOC00LjctMTYuMw0KCQkJCQljMS4xLTMsMS43LTUuNSwxLjctNi43YzAtMS45LTEuMi0zLTMuMi0zYy0yLjcsMC03LDEuNy03LjEsMS44bC0wLjIsMC4xbDAsMC4zYzAsMC4xLDEuMyw2LjEsMi42LDEyLjcNCgkJCQkJYy0yLjUsNC4xLTYuOSwxMC45LTkuMSwxMC45Yy00LDAsMi42LTIwLjUtMC4zLTIxLjJjLTAuMSwwLTAuMiwwLTAuMywwLjFjLTEuNCwwLjktMTcuMSw5LjYtMzgsOS42YzAsMCwwLDAuNCwwLjIsMC44DQoJCQkJCWMwLjEsMC4zLDAuNCwwLjYsMC40LDAuNmM1LjksMC43LDE0LjMtMC4xLDIwLjctMWMtMy43LDcuOS0xMC4yLDEzLjEtMTYuMiwxMy4xYy0xMS4zLDAtMjAtMTMuNy0yMC0xMy43DQoJCQkJCWMzLjUtMy4xLDkuMi0xMy4xLDE3LjYtMTMuMWM4LjMsMCwxMS45LDQuNiwxMS45LDQuNmwwLjktMS41YzAsMC0zLjktMTMuNi0xNC45LTEzLjZjLTExLDAtMjIuNywxOC0yOS41LDIyLjINCgkJCQkJYzAsMCw5LjQsMjIuMiwyOS45LDIyLjJjMTcuMiwwLDIxLjYtMTYuNSwyMi40LTIwLjVjNC4yLTAuNiw3LjEtMS4yLDcuMS0xLjJzLTEuMSw4LjQtMS4xLDExLjljMCwzLjUsMy45LDcuMiw3LjEsNy4yDQoJCQkJCWMyLjcsMCw4LjItNS42LDEyLjItMTIuNGwwLjIsMC44YzIuMSw3LjcsNC43LDExLjcsNy44LDExLjdjMy4xLDAsOC4yLTYuNCwxMS41LTE0LjVjMy4zLDEuNCw3LjIsMS44LDkuNSwxLjkNCgkJCQkJYzAuOSwxMy45LDEyLjUsMTQuMywxMy45LDE0LjNjOC42LDAsMTUuOS02LjIsMTUuOS0xMy41Qy0yMjQuMywxNy41LTIzMC4yLDE3LjQtMjMwLjMsMTcuNHogTS0yNDAuOCwxMS42YzAsMC0wLjEsNC42LTUuMyw2LjkNCgkJCQkJYzAuNS02LjEsMi0xMS42LDMtMTEuNkMtMjQyLDctMjQwLjgsOC43LTI0MC44LDExLjZ6Ii8+DQoJCQkJPHBhdGggY2xhc3M9InN0MCIgZD0iTS0zMDAuNyw2LjFjMCwwLjIsMC4xLDAuMywwLjMsMC40YzQuMSwwLjYsNi44LTAuNyw2LjgtNy4zYzAtNi4yLTYuNC0xLjMtNy42LTAuNA0KCQkJCQljLTAuMSwwLjEtMC4xLDAuMi0wLjEsMC40Qy0zMDAuMiwxLjYtMzAwLjYsNS4xLTMwMC43LDYuMXoiLz4NCgkJCTwvZz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMV8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI4OS41ODQ0IiB5MT0iMjYuNzY4IiB4Mj0iLTI4Mi44ODIzIiB5Mj0iMjQuNTM0Ij4NCgkJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQkJPHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPg0KCQkJPC9saW5lYXJHcmFkaWVudD4NCgkJCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0tMjg0LjIsMTkuNGMtMS42LDIuNy00LDYuNC02LjEsOC43YzAuNSwxLjIsMS4xLDIuNywxLjcsMy45YzEuOS0yLjEsMy44LTQuOCw1LjUtNy42TC0yODQuMiwxOS40eiIvPg0KCQkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8yXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMjY5LjAxOTQiIHkxPSIyOC40Nzc3IiB4Mj0iLTI2NS4xMzIyIiB5Mj0iMjEuNjQxNiI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3QzIiBkPSJNLTI2NS4yLDIxLjVjLTAuOC0wLjQtMS41LTEtMS41LTFjLTEuNCwzLjEtMy4zLDYtNC44LDcuOWMwLjcsMSwxLjksMi4zLDIuOCwzLjNjMS44LTIuNSwzLjctNS44LDUuMS05LjMNCgkJCQlDLTI2My41LDIyLjMtMjY0LjQsMjItMjY1LjIsMjEuNXoiLz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfM18iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI0OC42MjU0IiB5MT0iMzEuNjE0NyIgeDI9Ii0yNDkuNDI5NyIgeTI9IjI0LjQ2NTkiPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCQk8L2xpbmVhckdyYWRpZW50Pg0KCQkJPHBhdGggY2xhc3M9InN0NCIgZD0iTS0yNDYuMiwyMy41YzAsMC0yLDAuNC00LDAuNmMtMiwwLjItMy45LDAuMS0zLjksMC4xYzAuMyw0LDEuNCw2LjgsMi45LDguOWw3LjMtMC42DQoJCQkJQy0yNDUuNCwzMC41LTI0Ni4xLDI3LjEtMjQ2LjIsMjMuNXoiLz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfNF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI0OS43MjY3IiB5MT0iMTYuNDE5IiB4Mj0iLTI0OS43MjY3IiB5Mj0iMjMuNjIzNyI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q1IiBkPSJNLTI1MiwxMS4zTC0yNTIsMTEuM2MtMC4yLDAuNi0wLjUsMS4zLTAuNywyYzAsMC4yLTAuMSwwLjMtMC4xLDAuNWMtMC40LDEuMy0wLjcsMi42LTAuOSwzLjkNCgkJCQljMCwwLjItMC4xLDAuMy0wLjEsMC41Yy0wLjEsMC42LTAuMiwxLjItMC4yLDEuOGM0LjcsMCw3LjktMS40LDcuOS0xLjRjMC0wLjUsMC4xLTAuOSwwLjEtMS40YzAtMC4xLDAtMC4yLDAtMC4zDQoJCQkJYzAtMC40LDAuMS0wLjcsMC4xLTEuMWMwLTAuMSwwLTAuMiwwLTAuM2MwLjEtMC45LDAuMy0xLjgsMC40LTIuNkwtMjUyLDExLjN6IE0tMjU0LjEsMTkuOUMtMjU0LjEsMTkuOS0yNTQuMSwxOS45LTI1NC4xLDE5LjkNCgkJCQlMLTI1NC4xLDE5LjlDLTI1NC4xLDE5LjktMjU0LjEsMTkuOS0yNTQuMSwxOS45eiIvPg0KCQkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF81XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzEzLjAyNzIiIHkxPSIyOC4yMjc4IiB4Mj0iLTMxMy4wMjcyIiB5Mj0iMTkuMjkxNyI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q2IiBkPSJNLTMxNy43LDI4LjZsNC40LDEuOWMyLjEtMywzLjQtNi4xLDQuMi04LjVsMC44LTMuMmwtMi4xLDAuM0MtMzEyLjMsMjMuMS0zMTQuOSwyNi4zLTMxNy43LDI4LjZ6Ii8+DQoJCQk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzZfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yNzcuNTIzOSIgeTE9IjkuNzg4IiB4Mj0iLTI3OC42NDYzIiB5Mj0iMTEuNTc1NiI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q3IiBkPSJNLTI3Ny45LDE0LjJjMS4xLTMsMS43LTUuNSwxLjctNi43YzAtMC4xLDAtMC4yLDAtMC4zbC0yLjYsMC44Qy0yNzguOCw4LTI3OC43LDkuNy0yNzcuOSwxNC4yeiIvPg0KCQkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF83XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMjYyLjU1MjkiIHkxPSIxMy41MjQ4IiB4Mj0iLTI2My4xODY2IiB5Mj0iMTUuOTMyNiI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q4IiBkPSJNLTI2My45LDEyYzAsMC0wLjcsMi4xLDIuMiw0LjdjMC41LTIuMSwwLjgtNC4yLDAuOS02TC0yNjMuOSwxMnoiLz4NCgkJPC9nPg0KCTwvZz4NCgk8Zz4NCgkJPGc+DQoJCQk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNLTM1Ni44LDEzNi4ybC0wLjIsMGwwLDAuMmMwLjMsMS43LDAsNC4xLTEuMiw1LjdjLTAuNywwLjktMS43LDEuNC0yLjgsMS40Yy0xLjgsMC0yLjUtMi4yLTIuNi00LjYNCgkJCQljMy0wLjcsNS0yLjYsNS00LjhjMC0xLjYtMC41LTQuMi0zLjYtNC4yYy0yLjksMC00LjQsNC40LTQuNyw3LjRjLTEuNSwwLTIuNi0wLjctMy4zLTEuNGMwLjMtMS4xLDAuNC0yLDAuNC0yLjkNCgkJCQljMC0xLjItMC45LTEuOC0xLjYtMS44Yy0xLjIsMC0yLjMsMS4xLTIuMywzLjJjMCwxLjMsMC41LDIuMywxLjUsMy4xYy0wLjksMi0yLjMsMy43LTIuOCw0LjJjLTAuNC0wLjgtMS42LTMuOC0yLTYuOQ0KCQkJCWMwLjUtMS4zLDAuNy0yLjMsMC43LTIuOGMwLTAuOC0wLjUtMS4zLTEuNC0xLjNjLTEuMiwwLTMsMC43LTMsMC44bC0wLjEsMC4xbDAsMC4xYzAsMCwwLjUsMi42LDEuMSw1LjQNCgkJCQljLTEuMSwxLjctMi45LDQuNi0zLjksNC42Yy0xLjcsMCwxLjEtOC43LTAuMS05YzAsMC0wLjEsMC0wLjEsMGMtMC42LDAuNC03LjMsNC4xLTE2LjEsNC4xYzAsMCwwLDAuMiwwLjEsMC4zDQoJCQkJYzAuMSwwLjEsMC4yLDAuMiwwLjIsMC4yYzIuNSwwLjMsNi4xLDAsOC44LTAuNGMtMS42LDMuMy00LjMsNS42LTYuOSw1LjZjLTQuOCwwLTguNS01LjgtOC41LTUuOGMxLjUtMS4zLDMuOS01LjYsNy41LTUuNg0KCQkJCWMzLjUsMCw1LjEsMS45LDUuMSwxLjlsMC40LTAuNmMwLDAtMS43LTUuOC02LjMtNS44cy05LjYsNy43LTEyLjUsOS40YzAsMCw0LDkuNSwxMi43LDkuNWM3LjMsMCw5LjItNyw5LjUtOC43DQoJCQkJYzEuOC0wLjMsMy0wLjUsMy0wLjVzLTAuNCwzLjYtMC40LDUuMXMxLjYsMy4xLDMsMy4xYzEuMiwwLDMuNS0yLjQsNS4yLTUuM2wwLjEsMC4zYzAuOSwzLjMsMiw1LDMuMyw1YzEuMywwLDMuNS0yLjcsNC45LTYuMQ0KCQkJCWMxLjQsMC42LDMuMSwwLjgsNCwwLjhjMC40LDUuOSw1LjMsNi4xLDUuOSw2LjFjMy43LDAsNi44LTIuNiw2LjgtNS43Qy0zNTQuMywxMzYuMy0zNTYuOCwxMzYuMi0zNTYuOCwxMzYuMnogTS0zNjEuMiwxMzMuNw0KCQkJCWMwLDAsMCwyLTIuMywzYzAuMi0yLjYsMC44LTQuOSwxLjMtNC45Qy0zNjEuOCwxMzEuOC0zNjEuMiwxMzIuNS0zNjEuMiwxMzMuN3oiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0tMzg2LjcsMTMxLjRjMCwwLjEsMCwwLjEsMC4xLDAuMmMxLjcsMC4yLDIuOS0wLjMsMi45LTMuMWMwLTIuNi0yLjctMC42LTMuMi0wLjJjMCwwLTAuMSwwLjEsMCwwLjINCgkJCQlDLTM4Ni41LDEyOS41LTM4Ni43LDEzMC45LTM4Ni43LDEzMS40eiIvPg0KCQk8L2c+DQoJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfOF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM4MS45OTkzIiB5MT0iMTQwLjE3NjkiIHgyPSItMzc5LjE1MDQiIHkyPSIxMzkuMjI3MiI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDkiIGQ9Ik0tMzc5LjcsMTM3Yy0wLjcsMS4xLTEuNywyLjctMi42LDMuN2MwLjIsMC41LDAuNSwxLjEsMC43LDEuN2MwLjgtMC45LDEuNi0yLDIuNC0zLjJMLTM3OS43LDEzN3oiLz4NCgkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF85XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzczLjI1NzUiIHkxPSIxNDAuOTAzNyIgeDI9Ii0zNzEuNjA1MSIgeTI9IjEzNy45OTc4Ij4NCgkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJPC9saW5lYXJHcmFkaWVudD4NCgkJPHBhdGggY2xhc3M9InN0MTAiIGQ9Ik0tMzcxLjYsMTM3LjljLTAuMy0wLjItMC42LTAuNC0wLjYtMC40Yy0wLjYsMS4zLTEuNCwyLjUtMiwzLjRjMC4zLDAuNCwwLjgsMSwxLjIsMS40DQoJCQljMC44LTEuMSwxLjYtMi40LDIuMi00Qy0zNzAuOSwxMzguMy0zNzEuMywxMzguMS0zNzEuNiwxMzcuOXoiLz4NCgkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xMF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM2NC41ODg0IiB5MT0iMTQyLjIzNzIiIHgyPSItMzY0LjkzMDMiIHkyPSIxMzkuMTk4MyI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDExIiBkPSJNLTM2My42LDEzOC44YzAsMC0wLjgsMC4yLTEuNywwLjNjLTAuOCwwLjEtMS43LDAtMS43LDBjMC4xLDEuNywwLjYsMi45LDEuMiwzLjhsMy4xLTAuMw0KCQkJQy0zNjMuMiwxNDEuOC0zNjMuNSwxNDAuMy0zNjMuNiwxMzguOHoiLz4NCgkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xMV8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM2NS4wNTY2IiB5MT0iMTM1Ljc3NzciIHgyPSItMzY1LjA1NjYiIHkyPSIxMzguODQwMyI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDEyIiBkPSJNLTM2NiwxMzMuNkwtMzY2LDEzMy42Yy0wLjEsMC4zLTAuMiwwLjYtMC4zLDAuOGMwLDAuMSwwLDAuMS0wLjEsMC4yYy0wLjIsMC42LTAuMywxLjEtMC40LDEuNw0KCQkJYzAsMC4xLDAsMC4xLDAsMC4yYzAsMC4zLTAuMSwwLjUtMC4xLDAuOGMyLDAsMy40LTAuNiwzLjQtMC42YzAtMC4yLDAtMC40LDAuMS0wLjZjMCwwLDAtMC4xLDAtMC4xYzAtMC4yLDAtMC4zLDAuMS0wLjQNCgkJCWMwLDAsMC0wLjEsMC0wLjFjMC4xLTAuNCwwLjEtMC44LDAuMi0xLjFMLTM2NiwxMzMuNnogTS0zNjYuOSwxMzcuM0MtMzY2LjksMTM3LjMtMzY2LjksMTM3LjMtMzY2LjksMTM3LjNMLTM2Ni45LDEzNy4zDQoJCQlDLTM2Ni45LDEzNy4zLTM2Ni45LDEzNy4zLTM2Ni45LDEzNy4zeiIvPg0KCQk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEyXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzkxLjk2NDQiIHkxPSIxNDAuNzk3NSIgeDI9Ii0zOTEuOTY0NCIgeTI9IjEzNi45OTg5Ij4NCgkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJPC9saW5lYXJHcmFkaWVudD4NCgkJPHBhdGggY2xhc3M9InN0MTMiIGQ9Ik0tMzk0LDE0MWwxLjksMC44YzAuOS0xLjMsMS40LTIuNiwxLjgtMy42bDAuMy0xLjRsLTAuOSwwLjFDLTM5MS43LDEzOC42LTM5Mi43LDE0MC0zOTQsMTQxeiIvPg0KCQk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEzXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzc2Ljg3MjYiIHkxPSIxMzIuOTU5IiB4Mj0iLTM3Ny4zNDk4IiB5Mj0iMTMzLjcxODkiPg0KCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJPHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPg0KCQk8L2xpbmVhckdyYWRpZW50Pg0KCQk8cGF0aCBjbGFzcz0ic3QxNCIgZD0iTS0zNzcsMTM0LjhjMC41LTEuMywwLjctMi4zLDAuNy0yLjhjMCwwLDAtMC4xLDAtMC4xbC0xLjEsMC4zQy0zNzcuNCwxMzIuMi0zNzcuNCwxMzIuOS0zNzcsMTM0Ljh6Ii8+DQoJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTRfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zNzAuNTA4OCIgeTE9IjEzNC41NDc1IiB4Mj0iLTM3MC43NzgxIiB5Mj0iMTM1LjU3MSI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDE1IiBkPSJNLTM3MS4xLDEzMy45YzAsMC0wLjMsMC45LDAuOSwyYzAuMi0wLjksMC40LTEuOCwwLjQtMi42TC0zNzEuMSwxMzMuOXoiLz4NCgk8L2c+DQoJPGc+DQoJCTxyZWN0IHg9Ii0zMTMuNCIgeT0iMTE1LjEiIGNsYXNzPSJzdDE2IiB3aWR0aD0iNDIiIGhlaWdodD0iNDIiLz4NCgkJPGc+DQoJCQk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNLTI5Mi42LDEzNy41YzAuMSwwLjIsMC4yLDAuMywwLjIsMC4zYzMuNCwwLjQsOC4zLDAsMTItMC42Yy0yLjEsNC42LTUuOSw3LjYtOS40LDcuNg0KCQkJCWMtNi41LDAtMTEuNi03LjktMTEuNi03LjljMi0xLjgsNS40LTcuNiwxMC4yLTcuNnM2LjksMi42LDYuOSwyLjZsMC41LTAuOWMwLDAtMi4zLTcuOS04LjYtNy45Yy02LjQsMC0xMy4xLDEwLjQtMTcuMSwxMi44DQoJCQkJYzAsMCw1LjQsMTIuOSwxNy4zLDEyLjljMTAsMCwxMi41LTkuNSwxMy0xMS45YzEuMy0wLjIsMi40LTAuNCwzLjItMC41YzAuMi0wLjUsMC41LTEuNSwwLjMtMi44Yy00LDEuNS0xMCwzLjMtMTcuMSwzLjMNCgkJCQlDLTI5Mi43LDEzNy0yOTIuNywxMzcuMi0yOTIuNiwxMzcuNXoiLz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTVfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yODEuNzk2MiIgeTE9IjE0Mi40ODEzIiB4Mj0iLTI4MS43OTYyIiB5Mj0iMTM3LjM0ODkiPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCQk8L2xpbmVhckdyYWRpZW50Pg0KCQkJPHBhdGggY2xhc3M9InN0MTciIGQ9Ik0tMjc5LjEsMTM3LjFsLTEuMiwwLjFjMCwwLjEtMC4xLDAuMi0wLjIsMC4zYy0wLjIsMC40LTAuNCwwLjctMC42LDEuMWMtMC4xLDAuMi0wLjIsMC4zLTAuMywwLjUNCgkJCQljLTAuMiwwLjQtMC41LDAuOC0wLjgsMS4xYy0wLjEsMC4xLTAuMSwwLjEtMC4yLDAuMmMtMC43LDAuOS0xLjQsMS43LTIuMiwyLjNsMi41LDEuMUMtMjgwLjEsMTQxLjItMjc5LjMsMTM4LjItMjc5LjEsMTM3LjF6Ii8+DQoJCTwvZz4NCgk8L2c+DQoJPGc+DQoJCTxkZWZzPg0KCQkJPGNpcmNsZSBpZD0iU1ZHSURfMTZfIiBjeD0iLTE5OS40IiBjeT0iMTM2LjEiIHI9IjE2LjYiLz4NCgkJPC9kZWZzPg0KCQk8Y2xpcFBhdGggaWQ9IlNWR0lEXzE3XyI+DQoJCQk8dXNlIHhsaW5rOmhyZWY9IiNTVkdJRF8xNl8iICBzdHlsZT0ib3ZlcmZsb3c6dmlzaWJsZTsiLz4NCgkJPC9jbGlwUGF0aD4NCgkJPHBhdGggY2xhc3M9InN0MTgiIGQ9Ik0tMTk3LDEzNy4zYzAuMSwwLjEsMC4yLDAuMywwLjIsMC4zYzIuOSwwLjQsNy4xLDAsMTAuMy0wLjVjLTEuOCwzLjktNS4xLDYuNS04LDYuNWMtNS42LDAtOS45LTYuOC05LjktNi44DQoJCQljMS43LTEuNSw0LjYtNi41LDguNy02LjVzNS45LDIuMyw1LjksMi4zbDAuNS0wLjdjMCwwLTEuOS02LjctNy40LTYuN3MtMTEuMiw4LjktMTQuNiwxMWMwLDAsNC43LDExLDE0LjgsMTENCgkJCWM4LjUsMCwxMC43LTguMiwxMS4xLTEwLjJjMS4xLTAuMiwyLjEtMC4zLDIuNy0wLjRjMC4yLTAuNSwwLjQtMS4zLDAuMy0yLjRjLTMuNCwxLjMtOC41LDIuOC0xNC42LDIuOA0KCQkJQy0xOTcuMSwxMzYuOS0xOTcuMSwxMzcuMS0xOTcsMTM3LjN6Ii8+DQoJPC9nPg0KPC9nPg0KPGcgaWQ9IkxheWVyXzIiPg0KCTxwYXRoIGNsYXNzPSJzdDE5IiBkPSJNMTQ0LjMsODIuNWMtMS45LDkuNi0xMi4xLDQ4LjItNTIuNSw0OC4yYy00OC4yLDAtNzAuMi01Mi4yLTcwLjItNTIuMmMxNi4xLTkuOCw0My40LTUyLDY5LjItNTINCgkJczM0LjksMzEuOSwzNC45LDMxLjlsLTIuMiwzLjVjMCwwLTguNS0xMC43LTI4LTEwLjdTNjIuNiw3NC43LDU0LjQsODJjMCwwLDIwLjUsMzIuMSw0Ni45LDMyLjFjMTQuMiwwLDI5LjUtMTIuMywzOC4xLTMwLjgNCgkJYy0xNSwyLjEtMzQuNyw0LTQ4LjYsMi4yYzAsMC0wLjctMC42LTEtMS4zYy0wLjQtMC45LTAuNS0xLjgtMC41LTEuOGMyNy42LDAsNTEuMy02LjUsNjcuNC0xMi41QzE1Mi4zLDMwLjUsMTE5LDAsNzguNiwwDQoJCUMzNS4yLDAsMCwzNS4yLDAsNzguNmMwLDQzLjQsMzUuMiw3OC42LDc4LjYsNzguNmM0Mi44LDAsNzcuNi0zNC4yLDc4LjYtNzYuOEMxNTQuMiw4MC45LDE0OS43LDgxLjcsMTQ0LjMsODIuNXoiLz4NCjwvZz4NCjwvc3ZnPg0K',
771
	);
772
773
	// Return the chosen icon's SVG string
774
	return $svgs[ $icon ];
775
}
776
777
/**
778
 * Modify Admin Nav Menu Label
779
 *
780
 * @since 1.3
781
 *
782
 * @param object $post_type The current object to add a menu items meta box for.
783
 *
784
 * @return mixed
785
 */
786
function modify_nav_menu_meta_box_object( $post_type ) {
787
	if ( isset( $post_type->name ) && $post_type->name == 'give_forms' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
788
		$post_type->labels->name = esc_html__( 'Donation Forms', 'give' );
789
	}
790
791
	return $post_type;
792
}
793
794
add_filter( 'nav_menu_meta_box_object', 'modify_nav_menu_meta_box_object' );
795
796
/**
797
 * Enable 'Donation Form' meta enabled by default on Menu page.
798
 *
799
 * @since 1.8.9
800
 */
801
function give_nav_donation_metabox_enabled() {
802
803
	// Return false, if it fails to retrieve hidden meta box list and is not admin.
804
	if ( ( ! $hidden_meta_boxes = get_user_option( 'metaboxhidden_nav-menus' ) ) || ! is_admin() ) {
805
		return false;
806
	}
807
808
	// Return false, In case, we don't find 'Donation Form' in hidden meta box list.
809
	if ( ! in_array( 'add-post-type-give_forms', $hidden_meta_boxes, true ) ) {
810
		return false;
811
	}
812
813
	// Exclude 'Donation Form' value from hidden meta box's list.
814
	$hidden_meta_boxes = array_diff( $hidden_meta_boxes, array( 'add-post-type-give_forms' ) );
815
816
	// Get current user ID.
817
	$user = wp_get_current_user();
818
819
	update_user_option( $user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true );
820
}
821
822
/**
823
 * Array_column backup usage
824
 *
825
 * This file is part of the array_column library.
826
 *
827
 * @since      : 1.3.0.1
828
 *
829
 * @copyright  Copyright (c) Ben Ramsey (http://benramsey.com)
830
 * @license    https://opensource.org/licenses/MIT MIT
831
 */
832
833
if ( ! function_exists( 'array_column' ) ) {
834
	/**
835
	 * Returns the values from a single column of the input array, identified by
836
	 * the $columnKey.
837
	 *
838
	 * Optionally, you may provide an $indexKey to index the values in the returned
839
	 * array by the values from the $indexKey column in the input array.
840
	 *
841
	 * @param array $input A multi-dimensional array (record set) from which to pull
842
	 *                              a column of values.
843
	 * @param int|string $columnKey The column of values to return. This value may be the
844
	 *                              integer key of the column you wish to retrieve, or it
845
	 *                              may be the string key name for an associative array.
846
	 * @param mixed $indexKey (Optional.) The column to use as the index/keys for
847
	 *                              the returned array. This value may be the integer key
848
	 *                              of the column, or it may be the string key name.
849
	 *
850
	 * @return array
851
	 */
852
	function array_column( $input = null, $columnKey = null, $indexKey = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $input 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...
Unused Code introduced by
The parameter $columnKey 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...
Unused Code introduced by
The parameter $indexKey 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...
853
		// Using func_get_args() in order to check for proper number of
854
		// parameters and trigger errors exactly as the built-in array_column()
855
		// does in PHP 5.5.
856
		$argc   = func_num_args();
857
		$params = func_get_args();
858
859
		if ( $argc < 2 ) {
860
			trigger_error( sprintf( esc_html__( 'array_column() expects at least 2 parameters, %s given.', 'give' ), $argc ), E_USER_WARNING );
861
862
			return null;
863
		}
864
865
		if ( ! is_array( $params[0] ) ) {
866
			trigger_error( sprintf( esc_html__( 'array_column() expects parameter 1 to be array, %s given.', 'give' ), gettype( $params[0] ) ), E_USER_WARNING );
867
868
			return null;
869
		}
870
871 View Code Duplication
		if ( ! is_int( $params[1] )
0 ignored issues
show
Duplication introduced by
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...
872
		     && ! is_float( $params[1] )
873
		     && ! is_string( $params[1] )
874
		     && $params[1] !== null
875
		     && ! ( is_object( $params[1] ) && method_exists( $params[1], '__toString' ) )
876
		) {
877
			trigger_error( esc_html__( 'array_column(): The column key should be either a string or an integer.', 'give' ), E_USER_WARNING );
878
879
			return false;
880
		}
881
882 View Code Duplication
		if ( isset( $params[2] )
0 ignored issues
show
Duplication introduced by
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...
883
		     && ! is_int( $params[2] )
884
		     && ! is_float( $params[2] )
885
		     && ! is_string( $params[2] )
886
		     && ! ( is_object( $params[2] ) && method_exists( $params[2], '__toString' ) )
887
		) {
888
			trigger_error( esc_html__( 'array_column(): The index key should be either a string or an integer.', 'give' ), E_USER_WARNING );
889
890
			return false;
891
		}
892
893
		$paramsInput     = $params[0];
894
		$paramsColumnKey = ( $params[1] !== null ) ? (string) $params[1] : null;
895
896
		$paramsIndexKey = null;
897
		if ( isset( $params[2] ) ) {
898
			if ( is_float( $params[2] ) || is_int( $params[2] ) ) {
899
				$paramsIndexKey = (int) $params[2];
900
			} else {
901
				$paramsIndexKey = (string) $params[2];
902
			}
903
		}
904
905
		$resultArray = array();
906
907
		foreach ( $paramsInput as $row ) {
908
			$key    = $value = null;
909
			$keySet = $valueSet = false;
910
911
			if ( $paramsIndexKey !== null && array_key_exists( $paramsIndexKey, $row ) ) {
912
				$keySet = true;
913
				$key    = (string) $row[ $paramsIndexKey ];
914
			}
915
916
			if ( $paramsColumnKey === null ) {
917
				$valueSet = true;
918
				$value    = $row;
919
			} elseif ( is_array( $row ) && array_key_exists( $paramsColumnKey, $row ) ) {
920
				$valueSet = true;
921
				$value    = $row[ $paramsColumnKey ];
922
			}
923
924
			if ( $valueSet ) {
925
				if ( $keySet ) {
926
					$resultArray[ $key ] = $value;
927
				} else {
928
					$resultArray[] = $value;
929
				}
930
			}
931
		}
932
933
		return $resultArray;
934
	}
935
}// End if().
936
937
/**
938
 * Determines the receipt visibility status.
939
 *
940
 * @since 1.3.2
941
 *
942
 * @param string $payment_key
943
 *
944
 * @return bool Whether the receipt is visible or not.
945
 */
946
function give_can_view_receipt( $payment_key = '' ) {
947
948
	$return = false;
949
950
	if ( empty( $payment_key ) ) {
951
		return $return;
952
	}
953
954
	global $give_receipt_args;
955
956
	$give_receipt_args['id'] = give_get_purchase_id_by_key( $payment_key );
957
958
	$user_id = (int) give_get_payment_user_id( $give_receipt_args['id'] );
959
960
	$payment_meta = give_get_payment_meta( $give_receipt_args['id'] );
961
962
	if ( is_user_logged_in() ) {
963
		if ( $user_id === (int) get_current_user_id() ) {
964
			$return = true;
965
		} elseif ( wp_get_current_user()->user_email === give_get_payment_user_email( $give_receipt_args['id'] ) ) {
966
			$return = true;
967
		} elseif ( current_user_can( 'view_give_sensitive_data' ) ) {
968
			$return = true;
969
		}
970
	}
971
972
	$session = give_get_purchase_session();
973
	if ( ! empty( $session ) && ! is_user_logged_in() ) {
974
		if ( $session['purchase_key'] === $payment_meta['key'] ) {
975
			$return = true;
976
		}
977
	}
978
979
	return (bool) apply_filters( 'give_can_view_receipt', $return, $payment_key );
980
981
}
982
983
/**
984
 * Fallback for cal_days_in_month
985
 *
986
 * Fallback in case the calendar extension is not loaded in PHP; Only supports Gregorian calendar
987
 */
988
if ( ! function_exists( 'cal_days_in_month' ) ) {
989
	/**
990
	 * cal_days_in_month
991
	 *
992
	 * @param int $calendar
993
	 * @param int $month
994
	 * @param int $year
995
	 *
996
	 * @return bool|string
997
	 */
998
	function cal_days_in_month( $calendar, $month, $year ) {
0 ignored issues
show
Unused Code introduced by
The parameter $calendar 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...
999
		return date( 't', mktime( 0, 0, 0, $month, 1, $year ) );
1000
	}
1001
}
1002
1003
/**
1004
 * Get plugin info including status, type, and license validation.
1005
 *
1006
 * This is an enhanced version of get_plugins() that returns the status
1007
 * (`active` or `inactive`) of all plugins, type of plugin (`add-on` or `other`
1008
 * and license validation for Give add-ons (`true` or `false`). Does not include
1009
 * MU plugins.
1010
 *
1011
 * @since 1.8.0
1012
 *
1013
 * @return array Plugin info plus status, type, and license validation if
1014
 *               available.
1015
 */
1016
function give_get_plugins() {
1017
	$plugins             = get_plugins();
1018
	$active_plugin_paths = (array) get_option( 'active_plugins', array() );
1019
1020
	if ( is_multisite() ) {
1021
		$network_activated_plugin_paths = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
1022
		$active_plugin_paths            = array_merge( $active_plugin_paths, $network_activated_plugin_paths );
1023
	}
1024
1025
	foreach ( $plugins as $plugin_path => $plugin_data ) {
1026
		// Is plugin active?
1027
		if ( in_array( $plugin_path, $active_plugin_paths ) ) {
1028
			$plugins[ $plugin_path ]['Status'] = 'active';
1029
		} else {
1030
			$plugins[ $plugin_path ]['Status'] = 'inactive';
1031
		}
1032
1033
		$dirname = strtolower( dirname( $plugin_path ) );
1034
1035
		// Is plugin a Give add-on by WordImpress?
1036
		if ( strstr( $dirname, 'give-' ) && strstr( $plugin_data['AuthorURI'], 'wordimpress.com' ) ) {
1037
			// Plugin is a Give-addon.
1038
			$plugins[ $plugin_path ]['Type'] = 'add-on';
1039
1040
			// Get license info from database.
1041
			$plugin_name    = str_replace( 'Give - ', '', $plugin_data['Name'] );
1042
			$db_option      = 'give_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $plugin_name ) ) ) . '_license_active';
1043
			$license_active = get_option( $db_option );
1044
1045
			// Does a valid license exist?
1046
			if ( ! empty( $license_active ) && 'valid' === $license_active->license ) {
1047
				$plugins[ $plugin_path ]['License'] = true;
1048
			} else {
1049
				$plugins[ $plugin_path ]['License'] = false;
1050
			}
1051
		} else {
1052
			// Plugin is not a Give add-on.
1053
			$plugins[ $plugin_path ]['Type'] = 'other';
1054
		}
1055
	}
1056
1057
	return $plugins;
1058
}
1059
1060
1061
/**
1062
 * Check if terms enabled or not for form.
1063
 *
1064
 * @since 1.8
1065
 *
1066
 * @param $form_id
1067
 *
1068
 * @return bool
1069
 */
1070
function give_is_terms_enabled( $form_id ) {
1071
	$form_option = give_get_meta( $form_id, '_give_terms_option', true );
1072
1073
	if (
1074
		give_is_setting_enabled( $form_option, 'global' )
1075
		&& give_is_setting_enabled( give_get_option( 'terms' ) )
1076
	) {
1077
		return true;
1078
1079
	} elseif ( give_is_setting_enabled( $form_option ) ) {
1080
		return true;
1081
1082
	} else {
1083
		return false;
1084
	}
1085
}
1086
1087
1088
/**
1089
 * Delete donation stats cache.
1090
 *
1091
 * @todo  Resolve stats cache key naming issue. Currently it is difficult to regenerate cache key.
1092
 *
1093
 * @since 1.8.7
1094
 *
1095
 * @param string|array $date_range Date for stats.
1096
 *                                 Date value should be in today, yesterday, this_week, last_week, this_month, last_month, this_quarter, last_quarter, this_year, last_year.
1097
 *                                 For date value other, all cache will be removed.
1098
 *
1099
 * @param array $args
1100
 *
1101
 * @return WP_Error|bool
1102
 */
1103
function give_delete_donation_stats( $date_range = '', $args = array() ) {
1104
	// Delete all cache.
1105
	$status = Give_Cache::delete( Give_Cache::get_options_like( 'give_stats' ) );
1106
1107
	/**
1108
	 * Fire the action when donation stats delete.
1109
	 *
1110
	 * @since 1.8.7
1111
	 *
1112
	 * @param string|array $date_range
1113
	 * @param array $args
1114
	 */
1115
	do_action( 'give_delete_donation_stats', $status, $date_range, $args );
1116
1117
	return $status;
1118
}
1119
1120
1121
/**
1122
 * Get Form/Payment meta.
1123
 *
1124
 * @since 1.8.8
1125
 *
1126
 * @param int $id
1127
 * @param string $meta_key
1128
 * @param bool $single
1129
 * @param bool $default
1130
 *
1131
 * @return mixed
1132
 */
1133
function give_get_meta( $id, $meta_key, $single = false, $default = false ) {
1134
	/**
1135
	 * Filter the meta value
1136
	 *
1137
	 * @since 1.8.8
1138
	 */
1139
	$meta_value = apply_filters(
1140
		'give_get_meta',
1141
		get_post_meta( $id, $meta_key, $single ),
1142
		$id,
1143
		$meta_key,
1144
		$default
1145
	);
1146
1147
	if (
1148
		( empty( $meta_key ) || empty( $meta_value ) )
1149
		&& $default
1150
	) {
1151
		$meta_value = $default;
1152
	}
1153
1154
	return $meta_value;
1155
}
1156
1157
/**
1158
 * Update Form/Payment meta.
1159
 *
1160
 * @since 1.8.8
1161
 *
1162
 * @param int $id
1163
 * @param string $meta_key
1164
 * @param string $meta_value
1165
 * @param string $prev_value
1166
 *
1167
 * @return mixed
1168
 */
1169
function give_update_meta( $id, $meta_key, $meta_value, $prev_value = '' ) {
1170
	$status = update_post_meta( $id, $meta_key, $meta_value, $prev_value );
1171
1172
	/**
1173
	 * Filter the meta value update status
1174
	 *
1175
	 * @since 1.8.8
1176
	 */
1177
	return apply_filters( 'give_update_meta', $status, $id, $meta_key, $meta_value );
1178
}
1179
1180
/**
1181
 * Delete Form/Payment meta.
1182
 *
1183
 * @since 1.8.8
1184
 *
1185
 * @param int $id
1186
 * @param string $meta_key
1187
 * @param string $meta_value
1188
 *
1189
 * @return mixed
1190
 */
1191
function give_delete_meta( $id, $meta_key, $meta_value = '' ) {
1192
	$status = delete_post_meta( $id, $meta_key, $meta_value );
1193
1194
	/**
1195
	 * Filter the meta value delete status
1196
	 *
1197
	 * @since 1.8.8
1198
	 */
1199
	return apply_filters( 'give_delete_meta', $status, $id, $meta_key, $meta_value );
1200
}
1201
1202
/**
1203
 * Check if the upgrade routine has been run for a specific action
1204
 *
1205
 * @since  1.0
1206
 *
1207
 * @param  string $upgrade_action The upgrade action to check completion for
1208
 *
1209
 * @return bool                   If the action has been added to the completed actions array
1210
 */
1211
function give_has_upgrade_completed( $upgrade_action = '' ) {
1212
1213
	if ( empty( $upgrade_action ) ) {
1214
		return false;
1215
	}
1216
1217
	$completed_upgrades = give_get_completed_upgrades();
1218
1219
	return in_array( $upgrade_action, $completed_upgrades );
1220
1221
}
1222
1223
/**
1224
 * For use when doing 'stepped' upgrade routines, to see if we need to start somewhere in the middle
1225
 *
1226
 * @since 1.8
1227
 *
1228
 * @return mixed   When nothing to resume returns false, otherwise starts the upgrade where it left off
1229
 */
1230
function give_maybe_resume_upgrade() {
1231
	$doing_upgrade = get_option( 'give_doing_upgrade', false );
1232
	if ( empty( $doing_upgrade ) ) {
1233
		return false;
1234
	}
1235
1236
	return $doing_upgrade;
1237
}
1238
1239
/**
1240
 * Adds an upgrade action to the completed upgrades array
1241
 *
1242
 * @since  1.0
1243
 *
1244
 * @param  string $upgrade_action The action to add to the completed upgrades array
1245
 *
1246
 * @return bool                   If the function was successfully added
1247
 */
1248
function give_set_upgrade_complete( $upgrade_action = '' ) {
1249
1250
	if ( empty( $upgrade_action ) ) {
1251
		return false;
1252
	}
1253
1254
	$completed_upgrades   = give_get_completed_upgrades();
1255
	$completed_upgrades[] = $upgrade_action;
1256
1257
	// Remove any blanks, and only show uniques.
1258
	$completed_upgrades = array_unique( array_values( $completed_upgrades ) );
1259
1260
	/**
1261
	 * Fire the action when any upgrade set to complete.
1262
	 *
1263
	 * @since 1.8.12
1264
	 */
1265
	do_action( 'give_set_upgrade_completed', $upgrade_action, $completed_upgrades );
1266
1267
	return update_option( 'give_completed_upgrades', $completed_upgrades );
1268
}
1269
1270
/**
1271
 * Get's the array of completed upgrade actions
1272
 *
1273
 * @since  1.0
1274
 * @return array The array of completed upgrades
1275
 */
1276
function give_get_completed_upgrades() {
1277
	return (array) get_option( 'give_completed_upgrades' );
1278
}
1279
1280
1281
/**
1282
 * Return Import Page URL
1283
 *
1284
 * @since 1.8.13
1285
 *
1286
 * @param array $parameter
1287
 *
1288
 * @return string URL
1289
 */
1290
function give_import_page_url( $parameter = array() ) {
1291
	$defalut_query_arg = array(
1292
		'post_type' => 'give_forms',
1293
		'page'      => 'give-tools',
1294
		'tab'       => 'import',
1295
	);
1296
	$import_query_arg  = wp_parse_args( $parameter, $defalut_query_arg );
1297
1298
	return add_query_arg( $import_query_arg, admin_url( 'edit.php' ) );
1299
}
1300
1301
/**
1302
 * Add import Donation forms, donations , donor from CSV to database
1303
 *
1304
 * @since 1.8.13
1305
 *
1306
 * @param array $raw_key Setup bu user at step 2.
1307
 * @param array $row_data Feilds that are being imported from CSV
1308
 * @param array $main_key First row from the CSV
1309
 * @param array $import_setting Contain the global variable.
1310
 */
1311
function give_save_import_donation_to_db( $raw_key, $row_data, $main_key = array(), $import_setting = array() ) {
1312
	$data                          = array_combine( $raw_key, $row_data );
1313
	$price_id                      = false;
0 ignored issues
show
Unused Code introduced by
$price_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1314
	$customer_id                   = 0;
1315
	$import_setting['create_user'] = ( isset( $import_setting['create_user'] ) ? $import_setting['create_user'] : 1 );
1316
1317
	$data = (array) apply_filters( 'give_save_import_donation_to_db', $data );
1318
1319
	if ( ! strpos( $data['amount'], '.' ) ) {
1320
		$data['amount'] = $data['amount'] . '.00';
1321
	}
1322
1323
	// Here come the login function.
1324
	$donor_data = give_import_get_user_from_csv( $data, $import_setting );
1325
	if ( ! empty( $donor_data->id ) ) {
1326
		if ( ! empty( $donor_data->user_id ) ) {
1327
			$customer_id = $donor_data->user_id;
1328
		} elseif ( ! empty( $data['user_id'] ) ) {
1329
			$customer_id = $data['user_id'];
1330
		}
1331
	} else {
1332
		return false;
1333
	}
1334
1335
	// get form data or register a form data.
1336
	$form = give_import_get_form_data_from_csv( $data, $import_setting );
1337
	if ( false == $form ) {
1338
		return false;
1339
	} else {
1340
		$price_id = ( ! empty( $form->price_id ) ) ? $form->price_id : false;
1341
	}
1342
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1343
1344
	$address = array(
1345
		'line1'   => ( ! empty( $data['line1'] ) ? give_clean( $data['line1'] ) : '' ),
1346
		'line2'   => ( ! empty( $data['line1'] ) ? give_clean( $data['line2'] ) : '' ),
1347
		'city'    => ( ! empty( $data['line1'] ) ? give_clean( $data['city'] ) : '' ),
1348
		'zip'     => ( ! empty( $data['zip'] ) ? give_clean( $data['zip'] ) : '' ),
1349
		'state'   => ( ! empty( $data['state'] ) ? give_clean( $data['state'] ) : '' ),
1350
		'country' => ( ! empty( $data['country'] ) ? ( ( $country_code = array_search( $data['country'], give_get_country_list() ) ) ? $country_code : $data['country'] ) : '' ),
1351
	);
1352
1353
	//Create payment_data array
1354
	$payment_data = array(
1355
		'donor_id'        => $donor_data->id,
1356
		'price'           => $data['amount'],
1357
		'status'          => ( ! empty( $data['post_status'] ) ? $data['post_status'] : 'publish' ),
1358
		'currency'        => give_get_currency(),
1359
		'user_info'       => array(
1360
			'id'         => $customer_id,
1361
			'email'      => ( ! empty( $data['email'] ) ? $data['email'] : ( isset( $donor_data->email ) ? $donor_data->email : false ) ),
1362
			'first_name' => ( ! empty( $data['first_name'] ) ? $data['first_name'] : ( ! empty( $customer_id ) && ( $first_name = get_user_meta( $customer_id, 'first_name', true ) ) ? $first_name : $donor_data->name ) ),
0 ignored issues
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1363
			'last_name'  => ( ! empty( $data['last_name'] ) ? $data['last_name'] : ( ! empty( $customer_id ) && ( $last_name = get_user_meta( $customer_id, 'last_name', true ) ) ? $last_name : $donor_data->name ) ),
0 ignored issues
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1364
			'address'    => $address,
1365
		),
1366
		'gateway'         => ( ! empty( $data['gateway'] ) && 'offline' != strtolower( $data['gateway'] ) ? strtolower( $data['gateway'] ) : 'manual' ),
1367
		'give_form_title' => ( ! empty( $data['form_title'] ) ? $data['form_title'] : $form->get_name() ),
1368
		'give_form_id'    => (string) $form->get_ID(),
1369
		'give_price_id'   => $price_id,
1370
		'purchase_key'    => strtolower( md5( uniqid() ) ),
1371
		'user_email'      => $data['email'],
1372
		'post_date'       => ( ! empty( $data['post_date'] ) ? mysql2date( 'Y-m-d H:i:s', $data['post_date'] ) : current_time( 'mysql' ) ),
1373
		'mode'            => ( ! empty( $data['mode'] ) ? ( 'true' == (string) $data['mode'] || 'TRUE' == (string) $data['mode'] ? 'test' : 'live' ) : ( isset( $import_setting['mode'] ) ? ( true == (bool) $import_setting['mode'] ? 'test' : 'live' ) : ( give_is_test_mode() ? 'test' : 'live' ) ) ),
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1374
	);
1375
1376
	$payment_data = apply_filters( 'give_import_before_import_payment', $payment_data, $data, $donor_data, $form );
1377
1378
	// Get the report
1379
	$report = give_import_donation_report();
1380
1381
	// Check for duplicate code.
1382
	if ( true === give_check_import_donation_duplicate( $payment_data, $data, $form, $donor_data ) ) {
1383
		$report['duplicate_donation'] = ( ! empty( $report['duplicate_donation'] ) ? ( absint( $report['duplicate_donation'] ) + 1 ) : 1 );
1384
	} else {
1385
		add_action( 'give_update_payment_status', 'give_donation_import_insert_default_payment_note', 1, 1 );
1386
		add_filter( 'give_insert_payment_args', 'give_donation_import_give_insert_payment_args', 11, 2 );
1387
		add_filter( 'give_update_donor_information', 'give_donation_import_update_donor_information', 11, 3 );
1388
		add_action( 'give_insert_payment', 'give_import_donation_insert_payment', 11, 2 );
1389
		$payment = give_insert_payment( $payment_data );
1390
		remove_action( 'give_update_payment_status', 'give_donation_import_insert_default_payment_note', 1 );
1391
		remove_filter( 'give_insert_payment_args', 'give_donation_import_give_insert_payment_args', 11 );
1392
		remove_filter( 'give_update_donor_information', 'give_donation_import_update_donor_information', 11 );
1393
		remove_action( 'give_insert_payment', 'give_import_donation_insert_payment', 11 );
1394
1395
		if ( $payment ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1396
1397
			$report['create_donation'] = ( ! empty( $report['create_donation'] ) ? ( absint( $report['create_donation'] ) + 1 ) : 1 );
1398
1399
			update_post_meta( $payment, '_give_payment_import', true );
1400
1401
			if ( ! empty( $import_setting['csv'] ) ) {
1402
				update_post_meta( $payment, '_give_payment_import_id', $import_setting['csv'] );
1403
			}
1404
1405
			// Insert Notes.
1406
			if ( ! empty( $data['notes'] ) ) {
1407
				give_insert_payment_note( $payment, $data['notes'] );
1408
			}
1409
1410
			$meta_exists = array_keys( $raw_key, 'post_meta' );
1411
			if ( ! empty( $main_key ) && ! empty( $meta_exists ) ) {
1412
				foreach ( $meta_exists as $meta_exist ) {
1413
					if ( ! empty( $main_key[ $meta_exist ] ) && ! empty( $row_data[ $meta_exist ] ) ) {
1414
						update_post_meta( $payment, $main_key[ $meta_exist ], $row_data[ $meta_exist ] );
1415
					}
1416
				}
1417
			}
1418
		} else {
1419
			$report['failed_donation'] = ( ! empty( $report['failed_donation'] ) ? ( absint( $report['failed_donation'] ) + 1 ) : 1 );
1420
		}
1421
	}
1422
1423
	// update the report
1424
	give_import_donation_report_update( $report );
1425
}
1426
1427
/**
1428
 * Alter donor information when importing donations from CSV
1429
 *
1430
 * @since 1.8.13
1431
 *
1432
 * @param $donor
1433
 * @param $payment_id
1434
 * @param $payment_data
1435
 *
1436
 * @return Give_Donor
1437
 */
1438
function give_donation_import_update_donor_information( $donor, $payment_id, $payment_data ) {
0 ignored issues
show
Unused Code introduced by
The parameter $payment_id 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...
1439
	$old_donor = $donor;
1440
	if ( ! empty( $payment_data['donor_id'] ) ) {
1441
		$donor_id = absint( $payment_data['donor_id'] );
1442
		$donor    = new Give_Donor( $donor_id );
1443
		if ( ! empty( $donor->id ) ) {
1444
			return $donor;
1445
		}
1446
	}
1447
1448
	return $old_donor;
1449
}
1450
1451
/*
1452
 * Give update purchase_count of give customer.
1453
 *
1454
 * @since 1.8.13
1455
 */
1456
function give_import_donation_insert_payment( $payment_id, $payment_data ) {
1457
	// Update Give Customers purchase_count
1458
	if ( ! empty( $payment_data['status'] ) && ( 'complete' === (string) $payment_data['status'] || 'publish' === (string) $payment_data['status'] ) ) {
1459
		$donor_id = (int) get_post_meta( $payment_id, '_give_payment_customer_id', true );
1460
		if ( ! empty( $donor_id ) ) {
1461
			$donor = new Give_Donor( $donor_id );
0 ignored issues
show
Documentation introduced by
$donor_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1462
			$donor->increase_purchase_count();
1463
		}
1464
	}
1465
}
1466
1467
/**
1468
 * Add author id in in donation post
1469
 *
1470
 * @since 8.1.13
1471
 */
1472
function give_donation_import_give_insert_payment_args( $args, $payment_data ) {
1473
	if ( ! empty( $payment_data['user_info']['id'] ) ) {
1474
		$args['post_author'] = (int) $payment_data['user_info']['id'];
1475
	}
1476
1477
	return $args;
1478
}
1479
1480
/**
1481
 * Check if Import donation is duplicate
1482
 *
1483
 * @since 1.8.13
1484
 */
1485
function give_check_import_donation_duplicate( $payment_data, $data, $form, $donor_data ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form 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...
Unused Code introduced by
The parameter $donor_data 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...
1486
	$return = false;
1487
	if ( ! empty( $data['post_date'] ) ) {
1488
		$post_date = mysql2date( 'Y-m-d-H-i-s', $data['post_date'] );
1489
		$post_date = explode( '-', $post_date );
1490
		$args      = array(
1491
			'post_type'              => 'give_payment',
1492
			'cache_results'          => false,
1493
			'no_found_rows'          => true,
1494
			'update_post_meta_cache' => false,
1495
			'update_post_term_cache' => false,
1496
			'fields'                 => 'ids',
1497
			'date_query'             => array(
1498
				array(
1499
					'year'   => $post_date[0],
1500
					'month'  => $post_date[1],
1501
					'day'    => $post_date[2],
1502
					'hour'   => $post_date[3],
1503
					'minute' => $post_date[4],
1504
					'second' => $post_date[5],
1505
				),
1506
			),
1507
			'meta_query'             => array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
1508
				array(
1509
					'key'     => '_give_payment_total',
1510
					'value'   => preg_replace( '/[\$,]/', '', $payment_data['price'] ),
1511
					'compare' => 'LIKE',
1512
				),
1513
				array(
1514
					'key'     => '_give_payment_form_id',
1515
					'value'   => $payment_data['give_form_id'],
1516
					'type'    => 'numeric',
1517
					'compare' => '=',
1518
				),
1519
				array(
1520
					'key'     => '_give_payment_gateway',
1521
					'value'   => $payment_data['gateway'],
1522
					'compare' => '=',
1523
				),
1524
			),
1525
		);
1526
1527
		$payments  = new Give_Payments_Query( $args );
1528
		$donations = $payments->get_payments();
1529
		if ( ! empty( $donations ) ) {
1530
			return true;
1531
		}
1532
	}
1533
1534
	return $return;
1535
}
1536
1537
/**
1538
 * Record payment notes that is being imported from CSV.
1539
 *
1540
 * @since  1.8.13
1541
 *
1542
 * @param  int $payment_id The ID number of the payment.
1543
 *
1544
 * @return void
1545
 */
1546
function give_donation_import_insert_default_payment_note( $payment_id ) {
1547
	$current_user = wp_get_current_user();
1548
	give_insert_payment_note( $payment_id, esc_html( wp_sprintf( __( 'This donation was imported by %s', 'give' ), $current_user->user_email ) ) );
1549
}
1550
1551
1552
/**
1553
 * Remove login when user register with give functions.
1554
 *
1555
 * @since 1.8.13
1556
 *
1557
 * @param $value
1558
 *
1559
 * @return bool
1560
 */
1561
function give_log_user_in_on_register_callback( $value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $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...
1562
	return false;
1563
}
1564
1565
/**
1566
 * Import CSV in DB
1567
 *
1568
 * @param int $file_id CSV id
1569
 * @param array $mapto Map csv to meta key.
0 ignored issues
show
Bug introduced by
There is no parameter named $mapto. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1570
 * @param int $start Start from which csv line.
1571
 * @param int $end End from which csv line.
1572
 */
1573
function give_get_donation_data_from_csv( $file_id, $start, $end, $delimiter = ',' ) {
1574
	$raw_data = array();
1575
	$file_dir = get_attached_file( $file_id );
1576
	$count    = 0;
1577
	if ( false !== ( $handle = fopen( $file_dir, 'r' ) ) ) {
1578
		while ( false !== ( $row = fgetcsv( $handle, 0, $delimiter ) ) ) {
1579
			if ( $count >= $start && $count <= $end ) {
1580
				$raw_data[] = $row;
1581
			}
1582
			$count ++;
1583
		}
1584
		fclose( $handle );
1585
	}
1586
1587
	return $raw_data;
1588
}
1589
1590
1591
/**
1592
 * Return the option that are default options.
1593
 *
1594
 * @since 1.8.13
1595
 */
1596
function give_import_default_options() {
1597
	/**
1598
	 * Filter to modify defalut option in the import dropdown
1599
	 *
1600
	 * @since 1.8.13
1601
	 *
1602
	 * @return array
1603
	 */
1604
	return (array) apply_filters( 'give_import_default_options', array(
1605
		'' => __( 'Do not import', 'give' ),
1606
	) );
1607
}
1608
1609
/**
1610
 * Return the option that are related to donations.
1611
 *
1612
 * @since 1.8.13
1613
 */
1614
function give_import_donations_options() {
1615
	/**
1616
	 * Filter to modify donations option in the import dropdown
1617
	 *
1618
	 * @since 1.8.13
1619
	 *
1620
	 * @return array
1621
	 */
1622
	return (array) apply_filters( 'give_import_donations_options', array(
1623
		''            => __( 'Do not import', 'give' ),
1624
		'id'          => __( 'Donation ID', 'give' ),
1625
		'amount'      => __( 'Donation Amount', 'give' ),
1626
		'post_date'   => __( 'Donation Date', 'give' ),
1627
		'first_name'  => __( 'Donor First Name', 'give' ),
1628
		'last_name'   => __( 'Donor Last Name', 'give' ),
1629
		'line1'       => __( 'Address 1', 'give' ),
1630
		'line2'       => __( 'Address 2', 'give' ),
1631
		'city'        => __( 'City', 'give' ),
1632
		'state'       => __( 'State', 'give' ),
1633
		'country'     => __( 'Country', 'give' ),
1634
		'zip'         => __( 'Zip', 'give' ),
1635
		'email'       => __( 'Donor Email', 'give' ),
1636
		'post_status' => __( 'Donation Status', 'give' ),
1637
		'gateway'     => __( 'Payment Method', 'give' ),
1638
		'notes'       => __( 'Notes', 'give' ),
1639
		'mode'        => __( 'Test Mode', 'give' ),
1640
		'post_meta'   => __( 'Import as Meta', 'give' ),
1641
	) );
1642
}
1643
1644
/**
1645
 * Return the option that are related to donations.
1646
 *
1647
 * @since 1.8.13
1648
 */
1649
function give_import_donor_options() {
1650
	/**
1651
	 * Filter to modify donors option in the import dropdown
1652
	 *
1653
	 * @since 1.8.13
1654
	 *
1655
	 * @return array
1656
	 */
1657
	return (array) apply_filters( 'give_import_donor_options', array(
1658
		'donor_id' => __( 'Donor ID', 'give' ),
1659
		'user_id'  => __( 'User ID', 'give' ),
1660
	) );
1661
}
1662
1663
/**
1664
 * Return the option that are related to donations.
1665
 *
1666
 * @since 1.8.13
1667
 */
1668
function give_import_donation_form_options() {
1669
	/**
1670
	 * Filter to modify form option in the import dropdown
1671
	 *
1672
	 * @since 1.8.13
1673
	 *
1674
	 * @return array
1675
	 */
1676
	return (array) apply_filters( 'give_import_donation_form_options', array(
1677
		'form_id'    => __( 'Donation Form ID', 'give' ),
1678
		'form_title' => __( 'Donation Form', 'give' ),
1679
		'form_level' => __( 'Donation Level', 'give' ),
1680
		'form_custom_amount_text' => __( 'Custom Amount Text', 'give' ),
1681
	) );
1682
}
1683
1684
/**
1685
 * Give get user details.
1686
 *
1687
 * @since 1.8.13
1688
 *
1689
 * @param $data
1690
 *
1691
 * @return bool|false|WP_User
1692
 */
1693
function give_import_get_user_from_csv( $data, $import_setting = array() ) {
1694
	$report      = give_import_donation_report();
1695
	$donor_data  = false;
1696
	$customer_id = false;
0 ignored issues
show
Unused Code introduced by
$customer_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1697
1698
	// check if donor id is not empty
1699
	if ( ! empty( $data['donor_id'] ) ) {
1700
		$donor_data = new Give_Donor( (int) $data['donor_id'] );
0 ignored issues
show
Documentation introduced by
(int) $data['donor_id'] is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1701 View Code Duplication
		if ( ! empty( $donor_data->id ) ) {
0 ignored issues
show
Duplication introduced by
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...
1702
			$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1703
		}
1704
	}
1705
1706
	if ( empty( $donor_data->id ) && ! empty( $data['user_id'] ) ) {
1707
		$user_id    = (int) $data['user_id'];
1708
		$donor_data = new Give_Donor( $user_id, true );
0 ignored issues
show
Documentation introduced by
$user_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1709
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1710
1711
		if ( empty( $donor_data->id ) ) {
1712
			$donor_data = get_user_by( 'id', $user_id );
1713
			if ( ! empty( $donor_data->ID ) ) {
1714
				$first_name = ( ! empty( $data['first_name'] ) ? $data['first_name'] : $donor_data->user_nicename );
1715
				$last_name  = ( ! empty( $data['last_name'] ) ? $data['last_name'] : ( ( $lastname = get_user_meta( $donor_data->ID, 'last_name', true ) ) ? $lastname : '' ) );
0 ignored issues
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1716
				$name       = $first_name . ' ' . $last_name;
1717
				$user_email = $donor_data->user_email;
1718
				$donor_args = array(
1719
					'name'    => $name,
1720
					'email'   => $user_email,
1721
					'user_id' => $user_id,
1722
				);
1723
1724
				$donor_data = new Give_Donor();
1725
				$donor_data->create( $donor_args );
1726
1727
				// Adding notes that donor is being imported from CSV.
1728
				$current_user = wp_get_current_user();
1729
				$donor_data->add_note( esc_html( wp_sprintf( __( 'This donor was imported by %s', 'give' ), $current_user->user_email ) ) );
1730
1731
				// Add is used to ensure duplicate emails are not added
1732 View Code Duplication
				if ( $user_email != $data['email'] && ! empty( $data['email'] ) ) {
0 ignored issues
show
Duplication introduced by
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...
1733
					$donor_data->add_meta( 'additional_email', $data['email'] );
1734
				}
1735
1736
				$report['create_donor'] = ( ! empty( $report['create_donor'] ) ? ( absint( $report['create_donor'] ) + 1 ) : 1 );
1737
			} else {
1738
			}
1739
		} else {
1740
			// Add is used to ensure duplicate emails are not added
1741 View Code Duplication
			if ( $donor_data->email != $data['email'] ) {
0 ignored issues
show
Duplication introduced by
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...
1742
				$donor_data->add_meta( 'additional_email', ( ! empty( $data['email'] ) ? $data['email'] : $donor_data->email ) );
1743
			}
1744
			$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1745
		}
1746
	}
1747
1748
	if ( empty( $donor_data->id ) && ! empty( $data['email'] ) ) {
1749
1750
		$donor_data = new Give_Donor( $data['email'] );
1751
		if ( empty( $donor_data->id ) ) {
1752
			$donor_data = get_user_by( 'email', $data['email'] );
1753
1754
			if ( empty( $donor_data->ID ) && ! empty( $data['first_name'] ) && ! empty( $data['last_name'] ) && isset( $import_setting['create_user'] ) && 1 === absint( $import_setting['create_user'] ) ) {
1755
				$give_role  = (array) give_get_option( 'donor_default_user_role', get_option( 'default_role', ( ( $give_donor = wp_roles()->is_role( 'give_donor' ) ) && ! empty( $give_donor ) ? 'give_donor' : 'subscriber' ) ) );
1756
				$donor_args = array(
1757
					'user_login'      => $data['email'],
1758
					'user_email'      => $data['email'],
1759
					'user_registered' => date( 'Y-m-d H:i:s' ),
1760
					'user_first'      => $data['first_name'],
1761
					'user_last'       => $data['last_name'],
1762
					'user_pass'       => wp_generate_password( 8, true ),
1763
					'role'            => $give_role,
1764
				);
1765
1766
				/**
1767
				 * Filter to modify user data before new user id register.
1768
				 *
1769
				 * @since 1.8.13
1770
				 */
1771
				$donor_args = (array) apply_filters( 'give_import_insert_user_args', $donor_args, $data, $import_setting );
1772
1773
				// This action was added to remove the login when using the give register function.
1774
				add_filter( 'give_log_user_in_on_register', 'give_log_user_in_on_register_callback', 11 );
1775
				$customer_id = give_register_and_login_new_user( $donor_args );
1776
				remove_filter( 'give_log_user_in_on_register', 'give_log_user_in_on_register_callback', 11 );
1777
1778
				update_user_meta( $customer_id, '_give_payment_import', true );
0 ignored issues
show
introduced by
update_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1779
				$donor_data = new Give_Donor( $customer_id, true );
0 ignored issues
show
Documentation introduced by
$customer_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1780
			} else {
1781
				$customer_id = ( ! empty( $donor_data->ID ) ? $donor_data->ID : false );
1782
			}
1783
1784
			if ( ! empty( $customer_id ) || ( isset( $import_setting['create_user'] ) && 0 === absint( $import_setting['create_user'] ) ) ) {
1785
				$donor_data = new Give_Donor( $customer_id, true );
1786
1787
				if ( empty( $donor_data->id ) ) {
1788
1789
					if ( ! empty( $data['form_id'] ) ) {
1790
						$form = new Give_Donate_Form( $data['form_id'] );
1791
					}
1792
1793
					$payment_title = ( isset( $data['form_title'] ) ? $data['form_title'] : ( isset( $form ) ? $form->get_name() : esc_html__( 'New Form', 'give' ) ) );
1794
					$donor_args    = array(
1795
						'name'  => ! is_email( $payment_title ) ? $data['first_name'] . ' ' . $data['last_name'] : '',
1796
						'email' => $data['email'],
1797
					);
1798
1799
					if ( ! empty( $customer_id ) ) {
1800
						$donor_args['user_id'] = $customer_id;
1801
					}
1802
1803
					$donor_data->create( $donor_args );
1804
1805
					// Adding notes that donor is being imported from CSV.
1806
					$current_user = wp_get_current_user();
1807
					$donor_data->add_note( esc_html( wp_sprintf( __( 'This donor was imported by %s', 'give' ), $current_user->user_email ) ) );
1808
1809
					$report['create_donor'] = ( ! empty( $report['create_donor'] ) ? ( absint( $report['create_donor'] ) + 1 ) : 1 );
1810 View Code Duplication
				} else {
0 ignored issues
show
Duplication introduced by
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...
1811
					$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1812
				}
1813
			}
1814 View Code Duplication
		} else {
0 ignored issues
show
Duplication introduced by
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...
1815
			$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1816
		}
1817
	}
1818
1819
// update the report
1820
	give_import_donation_report_update( $report );
1821
1822
	return $donor_data;
1823
}
1824
1825
/**
1826
 * Give get form data from csv if not then create and form and return the form value.
1827
 *
1828
 * @since 1.8.13.
1829
 *
1830
 * @param $data .
1831
 *
1832
 * @return array|bool|Give_Donate_Form|int|null|WP_Post
1833
 */
1834
function give_import_get_form_data_from_csv( $data, $import_setting = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $import_setting 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...
1835
	$new_form = false;
1836
1837
	// Get the import report
1838
	$report = give_import_donation_report();
1839
1840
	$form = false;
1841
	$meta = array();
1842
1843
	if ( ! empty( $data['form_id'] ) ) {
1844
		$form = new Give_Donate_Form( $data['form_id'] );
1845
		// Add support to older php version.
1846
		$form_id = $form->get_ID();
1847 View Code Duplication
		if ( empty( $form_id ) ) {
0 ignored issues
show
Duplication introduced by
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...
1848
			$report['duplicate_form'] = ( ! empty( $report['duplicate_form'] ) ? ( absint( $report['duplicate_form'] ) + 1 ) : 1 );
1849
			$form = false;
1850
		}
1851
	}
1852
1853
	if ( false === $form && ! empty( $data['form_title'] ) ) {
1854
		$form = get_page_by_title( $data['form_title'], OBJECT, 'give_forms' );
1855
1856
		if ( ! empty( $form->ID ) ) {
1857
1858
			$report['duplicate_form'] = ( ! empty( $report['duplicate_form'] ) ? ( absint( $report['duplicate_form'] ) + 1 ) : 1 );
1859
1860
			$form = new Give_Donate_Form( $form->ID );
0 ignored issues
show
Unused Code introduced by
$form is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1861
		} else {
1862
			$form                  = new Give_Donate_Form();
1863
			$args                  = array(
1864
				'post_title'  => $data['form_title'],
1865
				'post_status' => 'publish',
1866
			);
1867
			$form                  = $form->create( $args );
0 ignored issues
show
Unused Code introduced by
$form is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1868
			$report['create_form'] = ( ! empty( $report['create_form'] ) ? ( absint( $report['create_form'] ) + 1 ) : 1 );
1869
			$new_form              = true;
1870
1871
		}
1872
1873
		$form = get_page_by_title( $data['form_title'], OBJECT, 'give_forms' );
1874
		$form = new Give_Donate_Form( $form->ID );
1875
	}
1876
1877
	if ( ! empty( $form ) && $form->get_ID() ) {
1878
		if ( ! empty( $data['form_level'] ) && 'custom' != (string) strtolower( $data['form_level'] ) ) {
1879
			$prices     = (array) $form->get_prices();
1880
			$price_text = array();
1881 View Code Duplication
			foreach ( $prices as $key => $price ) {
0 ignored issues
show
Duplication introduced by
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...
1882
				if ( isset( $price['_give_id']['level_id'] ) ) {
1883
					$price_text[ $price['_give_id']['level_id'] ] = ( ! empty( $price['_give_text'] ) ? $price['_give_text'] : '' );
1884
				}
1885
			}
1886
1887
			if ( ! in_array( $data['form_level'], $price_text ) ) {
1888
1889
				// For generating unquiet level id.
1890
				$count     = 1;
1891
				$new_level = count( $prices ) + $count;
1892
				while ( array_key_exists( $new_level, $price_text ) ) {
1893
					$count ++;
1894
					$new_level = count( $prices ) + $count;
1895
				}
1896
1897
				$multi_level_donations = array(
1898
					array(
1899
						'_give_id'      => array(
1900
							'level_id' => $new_level,
1901
						),
1902
						'_give_amount'  => give_sanitize_amount_for_db( $data['amount'] ),
1903
						'_give_text'    => $data['form_level'],
1904
					),
1905
				);
1906
1907
				$price_text[ $new_level ] = $data['form_level'];
1908
1909
				if ( ! empty( $prices ) && is_array( $prices ) && ! empty( $prices[0] ) ) {
1910
					$prices = wp_parse_args( $multi_level_donations, $prices );
1911
				} else {
1912
					$multi_level_donations[0]['_give_default'] = 'default';
1913
					$prices = $multi_level_donations;
1914
				}
1915
			}
1916
			$form->price_id = array_search( $data['form_level'], $price_text );
1917
1918
			$donation_levels_amounts = wp_list_pluck( $prices, '_give_amount' );
1919
			$min_amount              = min( $donation_levels_amounts );
1920
			$max_amount              = max( $donation_levels_amounts );
1921
1922
			$meta = array(
1923
				'_give_levels_minimum_amount' => $min_amount,
1924
				'_give_levels_maximum_amount' => $max_amount,
1925
				'_give_price_option'          => 'multi',
1926
				'_give_donation_levels'       => array_values( $prices ),
1927
			);
1928
		} else {
1929
			$form->price_id = 'custom';
1930
		}
1931
1932
		$defaults = array(
1933
			'_give_set_price'    => give_sanitize_amount_for_db( $data['amount'] ),
1934
			'_give_price_option' => 'set',
1935
		);
1936
1937
		// If new form is created.
1938
		if ( ! empty( $new_form ) ) {
1939
			$new_form = array(
1940
				'_give_custom_amount_text' => ( ! empty( $data['form_custom_amount_text'] ) ? $data['form_custom_amount_text'] : 'Custom' ),
1941
				'_give_logged_in_only'     => 'enabled',
1942
				'_give_custom_amount'      => 'enabled',
1943
				'_give_payment_import'     => true,
1944
				'_give_display_style'      => 'radios',
1945
				'_give_payment_display'    => 'onpage',
1946
				'give_product_notes'       => 'Donation Notes',
1947
				'_give_product_type'       => 'default',
1948
				'_give_default_gateway'    => 'global',
1949
				'_give_show_register_form' => 'both',
1950
			);
1951
			$defaults = wp_parse_args( $defaults, $new_form );
1952
		}
1953
1954
		$meta = wp_parse_args( $meta, $defaults );
1955
1956
		foreach ( $meta as $key => $value ) {
1957
			give_update_meta( $form->get_ID(), $key, $value );
1958
		}
1959
	}
1960
1961
	// update the report
1962
	give_import_donation_report_update( $report );
1963
1964
	return $form;
1965
}
1966
1967
/**
1968
 * Remove the Give transaction pages from WP search results.
1969
 *
1970
 * @since 1.8.13
1971
 *
1972
 * @param \WP_Query
1973
 *
1974
 */
1975
function give_remove_pages_from_search( $query ) {
1976
	if ( ! $query->is_admin && $query->is_search && $query->is_main_query() ) {
1977
		$transaction_failed = give_get_option( 'failure_page', 0 );
1978
		$success_page       = give_get_option( 'success_page', 0 );
1979
		$args               = apply_filters( 'give_remove_pages_from_search', array(
1980
			$transaction_failed,
1981
			$success_page
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1982
		), $query );
1983
		$query->set( 'post__not_in', $args );
1984
	}
1985
}
1986
1987
add_action( 'pre_get_posts', 'give_remove_pages_from_search', 10, 1 );
1988
1989
/**
1990
 * Inserts a new key/value before a key in the array.
1991
 *
1992
 * @since 1.8.13
1993
 *
1994
 * @param string $key The key to insert before.
1995
 * @param array $array An array to insert in to.
1996
 * @param string $new_key The key to insert.
1997
 * @param array|string $new_value An value to insert.
1998
 *
1999
 * @return array The new array if the key exists, the passed array otherwise.
2000
 *
2001
 * @see   array_insert_before()
2002
 */
2003 View Code Duplication
function give_array_insert_before( $key, array &$array, $new_key, $new_value ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in 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...
2004
	if ( array_key_exists( $key, $array ) ) {
2005
		$new = array();
2006
		foreach ( $array as $k => $value ) {
2007
			if ( $k === $key ) {
2008
				$new[ $new_key ] = $new_value;
2009
			}
2010
			$new[ $k ] = $value;
2011
		}
2012
2013
		return $new;
2014
	}
2015
2016
	return $array;
2017
}
2018
2019
/**
2020
 * Inserts a new key/value after a key in the array.
2021
 *
2022
 * @since 1.8.13
2023
 *
2024
 * @param string $key The key to insert after.
2025
 * @param array $array An array to insert in to.
2026
 * @param string $new_key The key to insert.
2027
 * @param array|string $new_value An value to insert.
2028
 *
2029
 * @return array The new array if the key exists, the passed array otherwise.
2030
 *
2031
 * @see   array_insert_before()
2032
 */
2033 View Code Duplication
function give_array_insert_after( $key, array &$array, $new_key, $new_value ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in 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...
2034
	if ( array_key_exists( $key, $array ) ) {
2035
		$new = array();
2036
		foreach ( $array as $k => $value ) {
2037
			$new[ $k ] = $value;
2038
			if ( $k === $key ) {
2039
				$new[ $new_key ] = $new_value;
2040
			}
2041
		}
2042
2043
		return $new;
2044
	}
2045
2046
	return $array;
2047
}
2048
2049
/**
2050
 * Pluck a certain field out of each object in a list.
2051
 *
2052
 * This has the same functionality and prototype of
2053
 * array_column() (PHP 5.5) but also supports objects.
2054
 *
2055
 * @since 1.8.13
2056
 *
2057
 * @param array $list List of objects or arrays
2058
 * @param int|string $field Field from the object to place instead of the entire object
2059
 * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
2060
 *                              Default null.
2061
 *
2062
 * @return array Array of found values. If `$index_key` is set, an array of found values with keys
2063
 *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
2064
 *               `$list` will be preserved in the results.
2065
 */
2066
function give_list_pluck( $list, $field, $index_key = null ) {
2067
2068
	if ( ! $index_key ) {
2069
		/*
2070
		 * This is simple. Could at some point wrap array_column()
2071
		 * if we knew we had an array of arrays.
2072
		 */
2073
		foreach ( $list as $key => $value ) {
2074
			if ( is_object( $value ) ) {
2075
				if ( isset( $value->$field ) ) {
2076
					$list[ $key ] = $value->$field;
2077
				}
2078
			} else {
2079
				if ( isset( $value[ $field ] ) ) {
2080
					$list[ $key ] = $value[ $field ];
2081
				}
2082
			}
2083
		}
2084
2085
		return $list;
2086
	}
2087
2088
	/*
2089
	 * When index_key is not set for a particular item, push the value
2090
	 * to the end of the stack. This is how array_column() behaves.
2091
	 */
2092
	$newlist = array();
2093
	foreach ( $list as $value ) {
2094
		if ( is_object( $value ) ) {
2095
			if ( isset( $value->$index_key ) ) {
2096
				$newlist[ $value->$index_key ] = $value->$field;
2097
			} else {
2098
				$newlist[] = $value->$field;
2099
			}
2100
		} else {
2101
			if ( isset( $value[ $index_key ] ) ) {
2102
				$newlist[ $value[ $index_key ] ] = $value[ $field ];
2103
			} else {
2104
				$newlist[] = $value[ $field ];
2105
			}
2106
		}
2107
	}
2108
2109
	$list = $newlist;
2110
2111
	return $list;
2112
}
2113
2114
/**
2115
 * Get the Import report of the donations
2116
 *
2117
 * @since 1.8.13
2118
 */
2119
function give_import_donation_report() {
2120
	return get_option( 'give_import_donation_report', array() );
2121
}
2122
2123
2124
/**
2125
 * Update the Import report of the donations
2126
 *
2127
 * @since 1.8.13
2128
 */
2129
function give_import_donation_report_update( $value = array() ) {
2130
	update_option( 'give_import_donation_report', $value );
2131
}
2132
2133
2134
/**
2135
 * Delete the Import report of the donations
2136
 *
2137
 * @since 1.8.13
2138
 */
2139
function give_import_donation_report_reset() {
2140
	update_option( 'give_import_donation_report', array() );
2141
}
2142
2143
2144
/**
2145
 * Add meta data field to a donor.
2146
 *
2147
 * @since 1.8.13
2148
 *
2149
 * @param int $donor_id Donor ID.
2150
 * @param string $meta_key Metadata name.
2151
 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
2152
 * @param bool $unique Optional. Whether the same key should not be added.
2153
 *                           Default false.
2154
 *
2155
 * @return int|false Meta ID on success, false on failure.
2156
 */
2157
function add_donor_meta( $donor_id, $meta_key, $meta_value, $unique = false ) {
2158
	return add_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $unique );
2159
}
2160
2161
/**
2162
 * Remove metadata matching criteria from a Donor meta.
2163
 *
2164
 * You can match based on the key, or key and value. Removing based on key and
2165
 * value, will keep from removing duplicate metadata with the same key. It also
2166
 * allows removing all metadata matching key, if needed.
2167
 *
2168
 * @since 1.8.13
2169
 *
2170
 * @param int $donor_id Donor ID
2171
 * @param string $meta_key Metadata name.
2172
 * @param mixed $meta_value Optional. Metadata value.
2173
 *
2174
 * @return bool True on success, false on failure.
2175
 */
2176
function delete_donor_meta( $donor_id, $meta_key, $meta_value = '' ) {
2177
	return delete_metadata( 'give_customer', $donor_id, $meta_key, $meta_value );
2178
}
2179
2180
/**
2181
 * Retrieve donor meta field for a donor meta table.
2182
 *
2183
 * @since 1.8.13
2184
 *
2185
 * @param int $donor_id Donor ID.
2186
 * @param string $key Optional. The meta key to retrieve. By default, returns data for all keys.
2187
 * @param bool $single Whether to return a single value.
2188
 *
2189
 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
2190
 *  is true.
2191
 */
2192
function get_donor_meta( $donor_id, $key = '', $single = false ) {
2193
	return get_metadata( 'give_customer', $donor_id, $key, $single );
2194
}
2195
2196
/**
2197
 * Update customer meta field based on Donor ID.
2198
 *
2199
 * If the meta field for the donor does not exist, it will be added.
2200
 *
2201
 * @since 1.8.13
2202
 *
2203
 * @param int $donor_id Donor ID.
2204
 * @param string $meta_key Metadata key.
2205
 * @param mixed $meta_value Metadata value.
2206
 * @param mixed $prev_value Optional. Previous value to check before removing.
2207
 *
2208
 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
2209
 */
2210
function update_donor_meta( $donor_id, $meta_key, $meta_value, $prev_value = '' ) {
2211
	return update_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $prev_value );
2212
}
2213
2214
/*
2215
 * Give recalculate income and donation of the donation from ID
2216
 *
2217
 * @since 1.8.13
2218
 *
2219
 * @param int $form_id Form id of which recalculation needs to be done.
2220
 */
2221
function give_recount_form_income_donation( $form_id = false ) {
2222
	// Check if form id is not empty.
2223
	if ( ! empty( $form_id ) ) {
2224
		/**
2225
		 * Filter to modify payment status.
2226
		 *
2227
		 * @since 1.8.13
2228
		 */
2229
		$accepted_statuses = apply_filters( 'give_recount_accepted_statuses', array( 'publish' ) );
2230
2231
		/**
2232
		 * Filter to modify args of payment query before recalculating the form total
2233
		 *
2234
		 * @since 1.8.13
2235
		 */
2236
		$args = apply_filters( 'give_recount_form_stats_args', array(
2237
			'give_forms'     => $form_id,
2238
			'status'         => $accepted_statuses,
2239
			'posts_per_page' => - 1,
2240
			'fields'         => 'ids',
2241
		) );
2242
2243
		$totals = array(
2244
			'sales'    => 0,
2245
			'earnings' => 0,
2246
		);
2247
2248
		$payments = new Give_Payments_Query( $args );
2249
		$payments = $payments->get_payments();
2250
2251
		if ( $payments ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
2252 View Code Duplication
			foreach ( $payments as $payment ) {
0 ignored issues
show
Duplication introduced by
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...
2253
				//Ensure acceptible status only
2254
				if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
2255
					continue;
2256
				}
2257
2258
				//Ensure only payments for this form are counted
2259
				if ( $payment->form_id != $form_id ) {
2260
					continue;
2261
				}
2262
2263
				$totals['sales'] ++;
2264
				$totals['earnings'] += $payment->total;
2265
2266
			}
2267
		}
2268
		give_update_meta( $form_id, '_give_form_sales', $totals['sales'] );
2269
		give_update_meta( $form_id, '_give_form_earnings', give_sanitize_amount_for_db( $totals['earnings'] ) );
2270
	}
2271
}