Test Failed
Push — issues/2397 ( f367c1...92dbfa )
by Ravinder
04:29
created

ajax-functions.php ➔ give_confirm_email_for_donation_access()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 50
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 31
nc 5
nop 0
dl 0
loc 50
rs 8.6315
c 0
b 0
f 0
1
<?php
2
/**
3
 * AJAX Functions
4
 *
5
 * Process the front-end AJAX actions.
6
 *
7
 * @package     Give
8
 * @subpackage  Functions/AJAX
9
 * @copyright   Copyright (c) 2016, WordImpress
10
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
11
 * @since       1.0
12
 */
13
14
// Exit if accessed directly.
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
/**
20
 * Check if AJAX works as expected
21
 *
22
 * @since  1.0
23
 *
24
 * @return bool True if AJAX works, false otherwise
25
 */
26
function give_test_ajax_works() {
27
28
	// Check if the Airplane Mode plugin is installed.
29
	if ( class_exists( 'Airplane_Mode_Core' ) ) {
30
31
		$airplane = Airplane_Mode_Core::getInstance();
32
33
		if ( method_exists( $airplane, 'enabled' ) ) {
34
35
			if ( $airplane->enabled() ) {
36
				return true;
37
			}
38
		} else {
39
40
			if ( 'on' === $airplane->check_status() ) {
41
				return true;
42
			}
43
		}
44
	}
45
46
	add_filter( 'block_local_requests', '__return_false' );
47
48
	if ( Give_Cache::get( '_give_ajax_works', true ) ) {
49
		return true;
50
	}
51
52
	$params = array(
53
		'sslverify' => false,
54
		'timeout'   => 30,
55
		'body'      => array(
56
			'action' => 'give_test_ajax',
57
		),
58
	);
59
60
	$ajax = wp_remote_post( give_get_ajax_url(), $params );
61
62
	$works = true;
63
64
	if ( is_wp_error( $ajax ) ) {
65
66
		$works = false;
67
68
	} else {
69
70
		if ( empty( $ajax['response'] ) ) {
71
			$works = false;
72
		}
73
74
		if ( empty( $ajax['response']['code'] ) || 200 !== (int) $ajax['response']['code'] ) {
75
			$works = false;
76
		}
77
78
		if ( empty( $ajax['response']['message'] ) || 'OK' !== $ajax['response']['message'] ) {
79
			$works = false;
80
		}
81
82
		if ( ! isset( $ajax['body'] ) || 0 !== (int) $ajax['body'] ) {
83
			$works = false;
84
		}
85
	}
86
87
	if ( $works ) {
88
		Give_Cache::set( '_give_ajax_works', '1', DAY_IN_SECONDS, true );
89
	}
90
91
	return $works;
92
}
93
94
95
/**
96
 * Get AJAX URL
97
 *
98
 * @since  1.0
99
 *
100
 * @return string
101
 */
102
function give_get_ajax_url() {
103
	$scheme = defined( 'FORCE_SSL_ADMIN' ) && FORCE_SSL_ADMIN ? 'https' : 'admin';
104
105
	$current_url = give_get_current_page_url();
106
	$ajax_url    = admin_url( 'admin-ajax.php', $scheme );
107
108
	if ( preg_match( '/^https/', $current_url ) && ! preg_match( '/^https/', $ajax_url ) ) {
109
		$ajax_url = preg_replace( '/^http/', 'https', $ajax_url );
110
	}
111
112
	return apply_filters( 'give_ajax_url', $ajax_url );
113
}
114
115
/**
116
 * Loads Checkout Login Fields via AJAX
117
 *
118
 * @since  1.0
119
 *
120
 * @return void
121
 */
122
function give_load_checkout_login_fields() {
123
	/**
124
	 * Fire when render login fields via ajax.
125
	 *
126
	 * @since 1.7
127
	 */
128
	do_action( 'give_donation_form_login_fields' );
129
130
	give_die();
131
}
132
133
add_action( 'wp_ajax_nopriv_give_checkout_login', 'give_load_checkout_login_fields' );
134
135
/**
136
 * Load Checkout Fields
137
 *
138
 * @since  1.3.6
139
 *
140
 * @return void
141
 */
142
function give_load_checkout_fields() {
143
	$form_id = isset( $_POST['form_id'] ) ? $_POST['form_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...
144
145
	ob_start();
146
147
	/**
148
	 * Fire to render registration/login form.
149
	 *
150
	 * @since 1.7
151
	 */
152
	do_action( 'give_donation_form_register_login_fields', $form_id );
153
154
	$fields = ob_get_clean();
155
156
	wp_send_json( array(
157
		'fields' => wp_json_encode( $fields ),
158
		'submit' => wp_json_encode( give_get_donation_form_submit_button( $form_id ) ),
159
	) );
160
}
161
162
add_action( 'wp_ajax_nopriv_give_cancel_login', 'give_load_checkout_fields' );
163
add_action( 'wp_ajax_nopriv_give_checkout_register', 'give_load_checkout_fields' );
164
165
/**
166
 * Get Form Title via AJAX (used only in WordPress Admin)
167
 *
168
 * @since  1.0
169
 *
170
 * @return void
171
 */
172
function give_ajax_get_form_title() {
173
	if ( isset( $_POST['form_id'] ) ) {
174
		$title = get_the_title( $_POST['form_id'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
175
		if ( $title ) {
176
			echo $title;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$title'
Loading history...
177
		} else {
178
			echo 'fail';
179
		}
180
	}
181
	give_die();
182
}
183
184
add_action( 'wp_ajax_give_get_form_title', 'give_ajax_get_form_title' );
185
add_action( 'wp_ajax_nopriv_give_get_form_title', 'give_ajax_get_form_title' );
186
187
/**
188
 * Retrieve a states drop down
189
 *
190
 * @since  1.0
191
 *
192
 * @return void
193
 */
194
function give_ajax_get_states_field() {
195
	$states_found   = false;
196
	$show_field     = true;
197
	$states_require = true;
198
	// Get the Country code from the $_POST.
199
	$country = sanitize_text_field( $_POST['country'] );
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-validated input variable: $_POST
Loading history...
200
201
	// Get the field name from the $_POST.
202
	$field_name = sanitize_text_field( $_POST['field_name'] );
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-validated input variable: $_POST
Loading history...
203
204
	$label        = __( 'State', 'give' );
205
	$states_label = give_get_states_label();
206
207
	$default_state = '';
208
	if ( $country === give_get_country() ) {
209
		$default_state = give_get_state();
210
	}
211
212
	// Check if $country code exists in the array key for states label.
213
	if ( array_key_exists( $country, $states_label ) ) {
214
		$label = $states_label[ $country ];
215
	}
216
217
	if ( empty( $country ) ) {
218
		$country = give_get_country();
219
	}
220
221
	$states = give_get_states( $country );
222
	if ( ! empty( $states ) ) {
223
		$args         = array(
224
			'name'             => $field_name,
225
			'id'               => $field_name,
226
			'class'            => $field_name . '  give-select',
227
			'options'          => $states,
228
			'show_option_all'  => false,
229
			'show_option_none' => false,
230
			'placeholder'      => $label,
231
			'selected'         => $default_state,
232
		);
233
		$data         = Give()->html->select( $args );
234
		$states_found = true;
235
	} else {
236
		$data = 'nostates';
237
238
		// Get the country list that does not have any states init.
239
		$no_states_country = give_no_states_country_list();
240
241
		// Check if $country code exists in the array key.
242
		if ( array_key_exists( $country, $no_states_country ) ) {
243
			$show_field = false;
244
		}
245
246
		// Get the country list that does not require states.
247
		$states_not_required_country_list = give_states_not_required_country_list();
248
249
		// Check if $country code exists in the array key.
250
		if ( array_key_exists( $country, $states_not_required_country_list ) ) {
251
			$states_require = false;
252
		}
253
	}
254
	$response = array(
255
		'success'        => true,
256
		'states_found'   => $states_found,
257
		'show_field'     => $show_field,
258
		'states_label'   => $label,
259
		'states_require' => $states_require,
260
		'data'           => $data,
261
		'default_state'  => $default_state,
262
	);
263
	wp_send_json( $response );
264
}
265
266
add_action( 'wp_ajax_give_get_states', 'give_ajax_get_states_field' );
267
add_action( 'wp_ajax_nopriv_give_get_states', 'give_ajax_get_states_field' );
268
269
/**
270
 * Retrieve donation forms via AJAX for chosen dropdown search field.
271
 *
272
 * @since  1.0
273
 *
274
 * @return void
275
 */
276
function give_ajax_form_search() {
277
	global $wpdb;
278
279
	$search   = esc_sql( sanitize_text_field( $_GET['s'] ) );
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-validated input variable: $_GET
Loading history...
280
	$excludes = ( isset( $_GET['current_id'] ) ? (array) $_GET['current_id'] : array() );
0 ignored issues
show
Unused Code introduced by
$excludes 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...
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...
281
282
	$results = array();
283
	if ( current_user_can( 'edit_give_forms' ) ) {
284
		$items = $wpdb->get_results( "SELECT ID,post_title FROM $wpdb->posts WHERE `post_type` = 'give_forms' AND `post_title` LIKE '%$search%' LIMIT 50" );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
285
	} else {
286
		$items = $wpdb->get_results( "SELECT ID,post_title FROM $wpdb->posts WHERE `post_type` = 'give_forms' AND `post_status` = 'publish' AND `post_title` LIKE '%$search%' LIMIT 50" );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
287
	}
288
289
	if ( $items ) {
290
291
		foreach ( $items as $item ) {
292
293
			$results[] = array(
294
				'id'   => $item->ID,
295
				'name' => $item->post_title,
296
			);
297
		}
298
	} else {
299
300
		$items[] = array(
301
			'id'   => 0,
302
			'name' => __( 'No forms found.', 'give' ),
303
		);
304
305
	}
306
307
	echo json_encode( $results );
308
309
	give_die();
310
}
311
312
add_action( 'wp_ajax_give_form_search', 'give_ajax_form_search' );
313
add_action( 'wp_ajax_nopriv_give_form_search', 'give_ajax_form_search' );
314
315
/**
316
 * Search the donors database via Ajax
317
 *
318
 * @since  1.0
319
 *
320
 * @return void
321
 */
322
function give_ajax_donor_search() {
323
	global $wpdb;
324
325
	$search  = esc_sql( sanitize_text_field( $_GET['s'] ) );
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-validated input variable: $_GET
Loading history...
326
	$results = array();
327
	if ( ! current_user_can( 'view_give_reports' ) ) {
328
		$donors = array();
329
	} else {
330
		$donors = $wpdb->get_results( "SELECT id,name,email FROM {$wpdb->prefix}give_customers WHERE `name` LIKE '%$search%' OR `email` LIKE '%$search%' LIMIT 50" );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
331
	}
332
333
	if ( $donors ) {
334
335
		foreach ( $donors as $donor ) {
336
337
			$results[] = array(
338
				'id'   => $donor->id,
339
				'name' => $donor->name . ' (' . $donor->email . ')',
340
			);
341
		}
342
	} else {
343
344
		$donors[] = array(
345
			'id'   => 0,
346
			'name' => __( 'No donors found.', 'give' ),
347
		);
348
349
	}
350
351
	echo json_encode( $results );
352
353
	give_die();
354
}
355
356
add_action( 'wp_ajax_give_donor_search', 'give_ajax_donor_search' );
357
358
359
/**
360
 * Searches for users via ajax and returns a list of results
361
 *
362
 * @since  1.0
363
 *
364
 * @return void
365
 */
366
function give_ajax_search_users() {
367
368
	if ( current_user_can( 'manage_give_settings' ) ) {
369
370
		$search = esc_sql( sanitize_text_field( $_GET['s'] ) );
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-validated input variable: $_GET
Loading history...
371
372
		$get_users_args = array(
373
			'number' => 9999,
374
			'search' => $search . '*',
375
		);
376
377
		$get_users_args = apply_filters( 'give_search_users_args', $get_users_args );
378
379
		$found_users = apply_filters( 'give_ajax_found_users', get_users( $get_users_args ), $search );
380
		$results     = array();
381
382
		if ( $found_users ) {
383
384
			foreach ( $found_users as $user ) {
385
386
				$results[] = array(
387
					'id'   => $user->ID,
388
					'name' => esc_html( $user->user_login . ' (' . $user->user_email . ')' ),
389
				);
390
			}
391
		} else {
392
393
			$results[] = array(
394
				'id'   => 0,
395
				'name' => __( 'No users found.', 'give' ),
396
			);
397
398
		}
399
400
		echo json_encode( $results );
401
402
	}// End if().
403
404
	give_die();
405
406
}
407
408
add_action( 'wp_ajax_give_user_search', 'give_ajax_search_users' );
409
410
411
/**
412
 * Check for Price Variations (Multi-level donation forms)
413
 *
414
 * @since  1.5
415
 *
416
 * @return void
417
 */
418
function give_check_for_form_price_variations() {
419
420
	if ( ! current_user_can( 'edit_give_forms', get_current_user_id() ) ) {
421
		die( '-1' );
422
	}
423
424
	$form_id = intval( $_POST['form_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-validated input variable: $_POST
Loading history...
425
	$form    = get_post( $form_id );
426
427
	if ( 'give_forms' != $form->post_type ) {
428
		die( '-2' );
429
	}
430
431
	if ( give_has_variable_prices( $form_id ) ) {
432
		$variable_prices = give_get_variable_prices( $form_id );
433
434
		if ( $variable_prices ) {
435
			$ajax_response = '<select class="give_price_options_select give-select give-select" name="give_price_option">';
436
437
			if ( isset( $_POST['all_prices'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
438
				$ajax_response .= '<option value="all">' . esc_html__( 'All Levels', 'give' ) . '</option>';
439
			}
440
441
			foreach ( $variable_prices as $key => $price ) {
442
443
				$level_text = ! empty( $price['_give_text'] ) ? esc_html( $price['_give_text'] ) : give_currency_filter( give_format_amount( $price['_give_amount'], array( 'sanitize' => false ) ) );
444
445
				$ajax_response .= '<option value="' . esc_attr( $price['_give_id']['level_id'] ) . '">' . $level_text . '</option>';
446
			}
447
			$ajax_response .= '</select>';
448
			echo $ajax_response;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$ajax_response'
Loading history...
449
		}
450
	}
451
452
	give_die();
453
}
454
455
add_action( 'wp_ajax_give_check_for_form_price_variations', 'give_check_for_form_price_variations' );
456
457
458
/**
459
 * Check for Variation Prices HTML  (Multi-level donation forms)
460
 *
461
 * @since  1.6
462
 *
463
 * @return void
464
 */
465
function give_check_for_form_price_variations_html() {
466
	if ( ! current_user_can( 'edit_give_payments', get_current_user_id() ) ) {
467
		wp_die();
468
	}
469
470
	$form_id    = ! empty( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
471
	$payment_id = ! empty( $_POST['payment_id'] ) ? intval( $_POST['payment_id'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
472
	if ( empty( $form_id ) || empty( $payment_id ) ) {
473
		wp_die();
474
	}
475
476
	$form = get_post( $form_id );
477
	if ( ! empty( $form->post_type ) && 'give_forms' != $form->post_type ) {
478
		wp_die();
479
	}
480
481
	if ( ! give_has_variable_prices( $form_id ) || ! $form_id ) {
0 ignored issues
show
Security Bug introduced by
It seems like $form_id defined by !empty($_POST['form_id']...OST['form_id']) : false on line 470 can also be of type false; however, give_has_variable_prices() does only seem to accept integer, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
Bug Best Practice introduced by
The expression $form_id of type integer|false is loosely compared to false; 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...
482
		esc_html_e( 'n/a', 'give' );
483
	} else {
484
		$prices_atts = array();
485 View Code Duplication
		if ( $variable_prices = give_get_variable_prices( $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...
486
			foreach ( $variable_prices as $variable_price ) {
487
				$prices_atts[ $variable_price['_give_id']['level_id'] ] = give_format_amount( $variable_price['_give_amount'], array( 'sanitize' => false ) );
488
			}
489
		}
490
491
		// Variable price dropdown options.
492
		$variable_price_dropdown_option = array(
493
			'id'               => $form_id,
494
			'name'             => 'give-variable-price',
495
			'chosen'           => true,
496
			'show_option_all'  => '',
497
			'show_option_none' => '',
498
			'select_atts'      => 'data-prices=' . esc_attr( json_encode( $prices_atts ) ),
499
		);
500
501
		if ( $payment_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment_id of type integer|false 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...
502
			// Payment object.
503
			$payment = new Give_Payment( $payment_id );
504
505
			// Payment meta.
506
			$payment_meta                               = $payment->get_meta();
507
			$variable_price_dropdown_option['selected'] = $payment_meta['price_id'];
508
		}
509
510
		// Render variable prices select tag html.
511
		give_get_form_variable_price_dropdown( $variable_price_dropdown_option, true );
512
	}
513
514
	give_die();
515
}
516
517
add_action( 'wp_ajax_give_check_for_form_price_variations_html', 'give_check_for_form_price_variations_html' );
518
519
/**
520
 * Send Confirmation Email For Complete Donation History Access.
521
 *
522
 * @since 1.8.17
523
 *
524
 * @return bool
525
 */
526
function give_confirm_email_for_donation_access() {
527
528
	// Verify Security using Nonce.
529
	if ( ! check_ajax_referer( 'give_ajax_nonce', 'nonce' ) ) {
530
		return false;
531
	}
532
533
	// Bail Out, if email is empty.
534
	if ( empty( $_POST['email'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
535
		return false;
536
	}
537
538
	$donor = Give()->donors->get_donor_by( 'email', $_POST['email'] );
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...
539
	if ( Give()->email_access->can_send_email( $donor->id ) ) {
540
		$return     = array();
541
		$email_sent = Give()->email_access->send_email( $donor->id, $donor->email );
542
543
		if ( ! $email_sent ) {
544
			$return['status']  = 'error';
545
			$return['message'] = Give()->notices->print_frontend_notice(
546
				__( 'Unable to send email. Please try again.', 'give' ),
547
				false,
548
				'error'
549
			);
550
		}
551
552
		$return['status']  = 'success';
553
		$return['message'] = Give()->notices->print_frontend_notice(
554
			__( 'Please check your email and click on the link to access your complete donation history.', 'give' ),
555
			false,
556
			'success'
557
		);
558
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
559
560
	} else {
561
		$value             = Give()->email_access->verify_throttle / 60;
562
		$return['status']  = 'error';
563
		$return['message'] = Give()->notices->print_frontend_notice(
564
			sprintf(
565
				__( 'Too many access email requests detected. Please wait %s before requesting a new donation history access link.', 'give' ),
566
				sprintf( _n( '%s minute', '%s minutes', $value, 'give' ), $value )
567
			),
568
			false,
569
			'error'
570
		);
571
	}
572
573
	echo json_encode( $return );
574
	give_die();
575
}
576
577
add_action( 'wp_ajax_nopriv_give_confirm_email_for_donations_access', 'give_confirm_email_for_donation_access' );