Test Failed
Push — release/1.8.12 ( b58a2f...d255b1 )
by Ravinder
375:09 queued 372:17
created

includes/admin/payments/actions.php (34 issues)

Upgrade to new PHP Analysis Engine

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

1
<?php
2
/**
3
 * Admin Payment Actions
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Payments
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
 *
19
 * Process the payment details edit
20
 *
21
 * @since  1.0
22
 * @access private
23
 *
24
 * @param array $data Donation data.
25
 *
26
 * @return      void
27
 */
28
function give_update_payment_details( $data ) {
29
30 View Code Duplication
	if ( ! current_user_can( 'edit_give_payments', $data['give_payment_id'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
31
		wp_die( esc_html__( 'You do not have permission to edit payments.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
32
	}
33
34
	check_admin_referer( 'give_update_payment_details_nonce' );
35
36
	// Retrieve the payment ID.
37
	$payment_id = absint( $data['give_payment_id'] );
38
39
	/* @var Give_Payment $payment */
40
	$payment = new Give_Payment( $payment_id );
41
42
	// Retrieve existing payment meta.
43
	$meta      = $payment->get_meta();
0 ignored issues
show
$meta 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...
44
	$user_info = $payment->user_info;
0 ignored issues
show
$user_info 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...
45
46
	$status = $data['give-payment-status'];
47
	$date   = sanitize_text_field( $data['give-payment-date'] );
48
	$hour   = sanitize_text_field( $data['give-payment-time-hour'] );
49
50
	// Restrict to our high and low.
51
	if ( $hour > 23 ) {
52
		$hour = 23;
53
	} elseif ( $hour < 0 ) {
54
		$hour = 00;
55
	}
56
57
	$minute = sanitize_text_field( $data['give-payment-time-min'] );
58
59
	// Restrict to our high and low.
60
	if ( $minute > 59 ) {
61
		$minute = 59;
62
	} elseif ( $minute < 0 ) {
63
		$minute = 00;
64
	}
65
66
	$address = array_map( 'trim', $data['give-payment-address'][0] );
67
68
	$curr_total = $payment->total;
69
	$new_total  = give_maybe_sanitize_amount( $data['give-payment-total'] );
70
	$date       = date( 'Y-m-d', strtotime( $date ) ) . ' ' . $hour . ':' . $minute . ':00';
71
72
	$curr_donor_id = sanitize_text_field( $data['give-current-donor'] );
73
	$new_donor_id  = sanitize_text_field( $data['donor-id'] );
74
75
	/**
76
	 * Fires before updating edited donation.
77
	 *
78
	 * @since 1.0
79
	 * @since 1.8.9 Changes hook name give_update_edited_purchase -> give_update_edited_donation
80
	 *
81
	 * @param int $payment_id The ID of the payment.
82
	 */
83
	do_action( 'give_update_edited_donation', $payment_id );
84
85
	$payment->date = $date;
86
	$updated       = $payment->save();
87
88
	if ( 0 === $updated ) {
89
		wp_die( esc_html__( 'Error Updating Donation.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 400 ) );
90
	}
91
92
	$donor_changed = false;
93
94
	if ( isset( $data['give-new-donor'] ) && $data['give-new-donor'] == '1' ) {
0 ignored issues
show
Found "== '". Use Yoda Condition checks, you must
Loading history...
95
96
		$email = isset( $data['give-new-donor-email'] ) ? sanitize_text_field( $data['give-new-donor-email'] ) : '';
97
		$names = isset( $data['give-new-donor-name'] ) ? sanitize_text_field( $data['give-new-donor-name'] ) : '';
98
99
		if ( empty( $email ) || empty( $names ) ) {
100
			wp_die( esc_html__( 'New donors require a name and email address.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 400 ) );
101
		}
102
103
		$donor = new Give_Donor( $email );
104
		if ( empty( $donor->id ) ) {
105
			$donor_data = array( 'name' => $names, 'email' => $email );
106
			$user_id       = email_exists( $email );
107
			if ( false !== $user_id ) {
108
				$donor_data['user_id'] = $user_id;
109
			}
110
111
			if ( ! $donor->create( $donor_data ) ) {
112
				// Failed to crete the new donor, assume the previous donor.
113
				$donor_changed = false;
0 ignored issues
show
$donor_changed 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...
114
				$donor         = new Give_Donor( $curr_donor_id );
115
				give_set_error( 'give-payment-new-donor-fail', __( 'Error creating new donor.', 'give' ) );
116
			}
117
		}
118
119
		$new_donor_id = $donor->id;
0 ignored issues
show
$new_donor_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...
120
121
		$previous_donor = new Give_Donor( $curr_donor_id );
122
123
		$donor_changed = true;
124
125
	} elseif ( $curr_donor_id !== $new_donor_id ) {
126
127
		$donor = new Give_Donor( $new_donor_id );
128
		$email    = $donor->email;
0 ignored issues
show
$email 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...
129
		$names    = $donor->name;
130
131
		$previous_donor = new Give_Donor( $curr_donor_id );
132
133
		$donor_changed = true;
134
135
	} else {
136
137
		$donor = new Give_Donor( $curr_donor_id );
138
		$email    = $donor->email;
0 ignored issues
show
$email 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...
139
		$names    = $donor->name;
140
141
	}
142
143
	// Setup first and last name from input values.
144
	$names      = explode( ' ', $names );
145
	$first_name = ! empty( $names[0] ) ? $names[0] : '';
146
	$last_name  = '';
147 View Code Duplication
	if ( ! empty( $names[1] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
148
		unset( $names[0] );
149
		$last_name = implode( ' ', $names );
150
	}
151
152
	if ( $donor_changed ) {
153
154
		// Remove the stats and payment from the previous donor and attach it to the new donor.
155
		$previous_donor->remove_payment( $payment_id, false );
156
		$donor->attach_payment( $payment_id, false );
157
158
		if ( 'publish' == $status ) {
159
160
			// Reduce previous user donation count and amount.
161
			$previous_donor->decrease_donation_count();
162
			$previous_donor->decrease_value( $curr_total );
163
164
			// If donation was completed adjust stats of new donors.
165
			$donor->increase_purchase_count();
166
			$donor->increase_value( $new_total );
167
		}
168
169
		$payment->customer_id = $donor->id;
170
	} else {
171
172
		if ( 'publish' === $status ) {
173
			// Update user donation stat.
174
			$donor->update_donation_value( $curr_total, $new_total );
175
		}
176
	}
177
178
	// Set new meta values.
179
	$payment->user_id    = $donor->user_id;
180
	$payment->email      = $donor->email;
181
	$payment->first_name = $first_name;
182
	$payment->last_name  = $last_name;
183
	$payment->address    = $address;
184
	$payment->total      = $new_total;
0 ignored issues
show
Documentation Bug introduced by
It seems like $new_total can also be of type integer or string. However, the property $total is declared as type double. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
185
186
	// Check for payment notes.
187
	if ( ! empty( $data['give-payment-note'] ) ) {
188
189
		$note = wp_kses( $data['give-payment-note'], array() );
190
		give_insert_payment_note( $payment_id, $note );
191
192
	}
193
194
	// Set new status.
195
	$payment->status = $status;
196
197
	// Adjust total store earnings if the payment total has been changed.
198
	if ( $new_total !== $curr_total && 'publish' == $status ) {
199
200
		if ( $new_total > $curr_total ) {
201
			// Increase if our new total is higher.
202
			$difference = $new_total - $curr_total;
203
			give_increase_total_earnings( $difference );
204
205
		} elseif ( $curr_total > $new_total ) {
206
			// Decrease if our new total is lower.
207
			$difference = $curr_total - $new_total;
208
			give_decrease_total_earnings( $difference );
209
210
		}
211
	}
212
213
	$payment->save();
214
215
	// Get new give form ID.
216
	$new_form_id     = absint( $data['give-payment-form-select'] );
217
	$current_form_id = absint( $payment->get_meta( '_give_payment_form_id' ) );
218
219
	// We are adding payment transfer code in last to remove any conflict with above functionality.
220
	// For example: above code will automatically handle form stat (increase/decrease) when payment status changes.
221
	// Check if user want to transfer current payment to new give form id.
222
	if ( $new_form_id != $current_form_id ) {
223
224
		// Get new give form title.
225
		$new_form_title = get_the_title( $new_form_id );
226
227
		// Update new give form data in payment data.
228
		$payment_meta               = $payment->get_meta();
229
		$payment_meta['form_title'] = $new_form_title;
230
		$payment_meta['form_id']    = $new_form_id;
231
232
		// Update price id post meta data for set donation form.
233
		if ( ! give_has_variable_prices( $new_form_id ) ) {
234
			$payment_meta['price_id'] = '';
235
		}
236
237
		// Update payment give form meta data.
238
		$payment->update_meta( '_give_payment_form_id', $new_form_id );
239
		$payment->update_meta( '_give_payment_form_title', $new_form_title );
240
		$payment->update_meta( '_give_payment_meta', $payment_meta );
241
242
		// Update price id payment metadata.
243
		if ( ! give_has_variable_prices( $new_form_id ) ) {
244
			$payment->update_meta( '_give_payment_price_id', '' );
245
		}
246
247
		// If donation was completed, adjust stats of forms.
248
		if ( 'publish' == $status ) {
249
250
			// Decrease sale of old give form. For other payment status.
251
			$current_form = new Give_Donate_Form( $current_form_id );
252
			$current_form->decrease_sales();
253
			$current_form->decrease_earnings( $curr_total );
254
255
			// Increase sale of new give form.
256
			$new_form = new Give_Donate_Form( $new_form_id );
257
			$new_form->increase_sales();
258
			$new_form->increase_earnings( $new_total );
259
		}
260
261
		// Re setup payment to update new meta value in object.
262
		$payment->update_payment_setup( $payment->ID );
263
	}
264
265
	// Update price id if current form is variable form.
266
	/* @var Give_Donate_Form $form */
267
	$form = new Give_Donate_Form( $payment->form_id );
0 ignored issues
show
$payment->form_id is of type string, 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...
268
269
	if ( isset( $data['give-variable-price'] ) && $form->has_variable_prices() ) {
270
271
		// Get payment meta data.
272
		$payment_meta = $payment->get_meta();
273
274
		$price_info = array();
275
		$price_id = '';
276
277
		// Get price info
278
		if( 0 <= $data['give-variable-price'] ) {
0 ignored issues
show
Space after opening control structure is required
Loading history...
No space before opening parenthesis is prohibited
Loading history...
279
			foreach ( $form->prices as $variable_price ) {
280
				if( $new_total === give_maybe_sanitize_amount( $variable_price['_give_amount'] ) ) {
0 ignored issues
show
Space after opening control structure is required
Loading history...
No space before opening parenthesis is prohibited
Loading history...
281
					$price_info = $variable_price;
282
					break;
283
				}
284
			}
285
		}
286
287
		// Set price id.
288
		if( ! empty( $price_info ) ) {
0 ignored issues
show
Space after opening control structure is required
Loading history...
No space before opening parenthesis is prohibited
Loading history...
289
			$price_id = $data['give-variable-price'];
290
291
			if( $data['give-variable-price'] !== $price_info['_give_id']['level_id'] ) {
0 ignored issues
show
Space after opening control structure is required
Loading history...
No space before opening parenthesis is prohibited
Loading history...
292
				// Set price id to amount match.
293
				$price_id = $price_info['_give_id']['level_id'];
294
			}
0 ignored issues
show
Blank line found after control structure
Loading history...
295
296
		} elseif( $form->is_custom_price_mode() ){
0 ignored issues
show
Space after opening control structure is required
Loading history...
No space before opening parenthesis is prohibited
Loading history...
297
			$price_id = 'custom';
298
		}
299
300
		// Update payment meta data.
301
		$payment_meta['price_id'] = $price_id;
302
303
		// Update payment give form meta data.
304
		$payment->update_meta( '_give_payment_price_id', $price_id );
305
		$payment->update_meta( '_give_payment_meta', $payment_meta );
306
307
		// Re setup payment to update new meta value in object.
308
		$payment->update_payment_setup( $payment->ID );
309
	}
310
311
	/**
312
	 * Fires after updating edited donation.
313
	 *
314
	 * @since 1.0
315
	 * @since 1.8.9 Changes hook name give_updated_edited_purchase -> give_updated_edited_donation
316
	 *
317
	 * @param int $payment_id The ID of the payment.
318
	 */
319
	do_action( 'give_updated_edited_donation', $payment_id );
320
321
	wp_safe_redirect( admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&view=view-payment-details&give-message=payment-updated&id=' . $payment_id ) );
322
	exit;
323
}
324
325
add_action( 'give_update_payment_details', 'give_update_payment_details' );
326
327
/**
328
 * Trigger a Donation Deletion.
329
 *
330
 * @since 1.0
331
 *
332
 * @param array $data Arguments passed.
333
 *
334
 * @return void
335
 */
336
function give_trigger_donation_delete( $data ) {
337
	if ( wp_verify_nonce( $data['_wpnonce'], 'give_donation_nonce' ) ) {
338
339
		$payment_id = absint( $data['purchase_id'] );
340
341
		if ( ! current_user_can( 'edit_give_payments', $payment_id ) ) {
342
			wp_die( __( 'You do not have permission to edit payments.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
343
		}
344
345
		give_delete_donation( $payment_id );
346
		wp_redirect( admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&give-message=donation_deleted' ) );
347
		give_die();
348
	}
349
}
350
351
add_action( 'give_delete_payment', 'give_trigger_donation_delete' );
352
353
/**
354
 * AJAX Store Donation Note
355
 */
356
function give_ajax_store_payment_note() {
357
358
	$payment_id = absint( $_POST['payment_id'] );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
359
	$note       = wp_kses( $_POST['note'], array() );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
360
361
	if ( ! current_user_can( 'edit_give_payments', $payment_id ) ) {
362
		wp_die( __( 'You do not have permission to edit payments.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
363
	}
364
365
	if ( empty( $payment_id ) ) {
366
		die( '-1' );
367
	}
368
369
	if ( empty( $note ) ) {
370
		die( '-1' );
371
	}
372
373
	$note_id = give_insert_payment_note( $payment_id, $note );
374
	die( give_get_payment_note_html( $note_id ) );
375
}
376
377
add_action( 'wp_ajax_give_insert_payment_note', 'give_ajax_store_payment_note' );
378
379
/**
380
 * Triggers a donation note deletion without ajax
381
 *
382
 * @since 1.0
383
 *
384
 * @param array $data Arguments passed
385
 *
386
 * @return void
387
 */
388
function give_trigger_payment_note_deletion( $data ) {
389
390
	if ( ! wp_verify_nonce( $data['_wpnonce'], 'give_delete_payment_note_' . $data['note_id'] ) ) {
391
		return;
392
	}
393
394 View Code Duplication
	if ( ! current_user_can( 'edit_give_payments', $data['payment_id'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
395
		wp_die( esc_html__( 'You do not have permission to edit payments.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
396
	}
397
398
	$edit_order_url = admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&view=view-payment-details&give-message=donation-note-deleted&id=' . absint( $data['payment_id'] ) );
399
400
	give_delete_payment_note( $data['note_id'], $data['payment_id'] );
401
402
	wp_redirect( $edit_order_url );
403
}
404
405
add_action( 'give_delete_payment_note', 'give_trigger_payment_note_deletion' );
406
407
/**
408
 * Delete a payment note deletion with ajax
409
 *
410
 * @since 1.0
411
 *
412
 * @return void
413
 */
414
function give_ajax_delete_payment_note() {
415
416 View Code Duplication
	if ( ! current_user_can( 'edit_give_payments', $_POST['payment_id'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
417
		wp_die( esc_html__( 'You do not have permission to edit payments.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
418
	}
419
420
	if ( give_delete_payment_note( $_POST['note_id'], $_POST['payment_id'] ) ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
421
		die( '1' );
422
	} else {
423
		die( '-1' );
424
	}
425
426
}
427
428
add_action( 'wp_ajax_give_delete_payment_note', 'give_ajax_delete_payment_note' );
429