Completed
Push — release/2.0 ( 4d845f...d9fa8a )
by Ravinder
18:24
created

actions.php ➔ give_trigger_donation_delete()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 28 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
	if ( ! current_user_can( 'edit_give_payments', $data['give_payment_id'] ) ) {
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();
44
	$user_info = $payment->user_info;
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 = give_sanitize_amount( $payment->total );
69
	$new_total  = give_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
	 *
80
	 * @param int $payment_id The ID of the payment.
81
	 */
82
	do_action( 'give_update_edited_donation', $payment_id );
83
84
	$payment->date = $date;
85
	$updated       = $payment->save();
86
87
	if ( 0 === $updated ) {
88
		wp_die( esc_html__( 'Error Updating Donation.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 400 ) );
89
	}
90
91
	$donor_changed = false;
92
93
	if ( isset( $data['give-new-donor'] ) && $data['give-new-donor'] == '1' ) {
94
95
		$email = isset( $data['give-new-donor-email'] ) ? sanitize_text_field( $data['give-new-donor-email'] ) : '';
96
		$names = isset( $data['give-new-donor-name'] ) ? sanitize_text_field( $data['give-new-donor-name'] ) : '';
97
98
		if ( empty( $email ) || empty( $names ) ) {
99
			wp_die( esc_html__( 'New donors require a name and email address.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 400 ) );
100
		}
101
102
		$donor = new Give_Donor( $email );
103
		if ( empty( $donor->id ) ) {
104
			$donor_data = array( 'name' => $names, 'email' => $email );
105
			$user_id       = email_exists( $email );
106
			if ( false !== $user_id ) {
107
				$donor_data['user_id'] = $user_id;
108
			}
109
110
			if ( ! $donor->create( $donor_data ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $donor->create($donor_data) of type false|integer 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...
111
				// Failed to crete the new donor, assume the previous donor.
112
				$donor_changed = false;
113
				$donor         = new Give_Donor( $curr_donor_id );
114
				give_set_error( 'give-payment-new-donor-fail', __( 'Error creating new donor.', 'give' ) );
115
			}
116
		}
117
118
		$new_donor_id = $donor->id;
119
120
		$previous_donor = new Give_Donor( $curr_donor_id );
121
122
		$donor_changed = true;
123
124
	} elseif ( $curr_donor_id !== $new_donor_id ) {
125
126
		$donor = new Give_Donor( $new_donor_id );
127
		$email    = $donor->email;
128
		$names    = $donor->name;
129
130
		$previous_donor = new Give_Donor( $curr_donor_id );
131
132
		$donor_changed = true;
133
134
	} else {
135
136
		$donor = new Give_Donor( $curr_donor_id );
137
		$email    = $donor->email;
138
		$names    = $donor->name;
139
140
	}
141
142
	// Setup first and last name from input values.
143
	$names      = explode( ' ', $names );
144
	$first_name = ! empty( $names[0] ) ? $names[0] : '';
145
	$last_name  = '';
146
	if ( ! empty( $names[1] ) ) {
147
		unset( $names[0] );
148
		$last_name = implode( ' ', $names );
149
	}
150
151
	if ( $donor_changed ) {
152
153
		// Remove the stats and payment from the previous donor and attach it to the new donor.
154
		$previous_donor->remove_payment( $payment_id, false );
0 ignored issues
show
Bug introduced by
The variable $previous_donor does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
155
		$donor->attach_payment( $payment_id, false );
156
157
		if ( 'publish' == $status ) {
158
159
			// Reduce previous user donation count and amount.
160
			$previous_donor->decrease_donation_count();
161
			$previous_donor->decrease_value( $curr_total );
162
163
			// If donation was completed adjust stats of new donors.
164
			$donor->increase_purchase_count();
165
			$donor->increase_value( $new_total );
166
		}
167
168
		$payment->customer_id = $donor->id;
169
	} else {
170
171
		if ( 'publish' === $status ) {
172
			// Update user donation stat.
173
			$donor->update_donation_value( $curr_total, $new_total );
174
		}
175
	}
176
177
	// Set new meta values.
178
	$payment->user_id    = $donor->user_id;
179
	$payment->email      = $donor->email;
180
	$payment->first_name = $first_name;
181
	$payment->last_name  = $last_name;
182
	$payment->address    = $address;
0 ignored issues
show
Documentation introduced by
The property $address is declared protected in Give_Payment. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
183
	$payment->total      = $new_total;
184
185
	// Check for payment notes.
186
	if ( ! empty( $data['give-payment-note'] ) ) {
187
188
		$note = wp_kses( $data['give-payment-note'], array() );
189
		give_insert_payment_note( $payment_id, $note );
190
191
	}
192
193
	// Set new status.
194
	$payment->status = $status;
195
196
	// Adjust total store earnings if the payment total has been changed.
197
	if ( $new_total !== $curr_total && 'publish' == $status ) {
198
199
		if ( $new_total > $curr_total ) {
200
			// Increase if our new total is higher.
201
			$difference = $new_total - $curr_total;
202
			give_increase_total_earnings( $difference );
203
204
		} elseif ( $curr_total > $new_total ) {
205
			// Decrease if our new total is lower.
206
			$difference = $curr_total - $new_total;
207
			give_decrease_total_earnings( $difference );
208
209
		}
210
	}
211
212
	$payment->save();
213
214
	// Get new give form ID.
215
	$new_form_id     = absint( $data['give-payment-form-select'] );
216
	$current_form_id = absint( $payment->get_meta( '_give_payment_form_id' ) );
217
218
	// We are adding payment transfer code in last to remove any conflict with above functionality.
219
	// For example: above code will automatically handle form stat (increase/decrease) when payment status changes.
220
	// Check if user want to transfer current payment to new give form id.
221
	if ( $new_form_id != $current_form_id ) {
222
223
		// Get new give form title.
224
		$new_form_title = get_the_title( $new_form_id );
225
226
		// Update new give form data in payment data.
227
		$payment_meta               = $payment->get_meta();
228
		$payment_meta['form_title'] = $new_form_title;
229
		$payment_meta['form_id']    = $new_form_id;
230
231
		// Update price id post meta data for set donation form.
232
		if ( ! give_has_variable_prices( $new_form_id ) ) {
233
			$payment_meta['price_id'] = '';
234
		}
235
236
		// Update payment give form meta data.
237
		$payment->update_meta( '_give_payment_form_id', $new_form_id );
238
		$payment->update_meta( '_give_payment_form_title', $new_form_title );
239
		$payment->update_meta( '_give_payment_meta', $payment_meta );
240
241
		// Update price id payment metadata.
242
		if ( ! give_has_variable_prices( $new_form_id ) ) {
243
			$payment->update_meta( '_give_payment_price_id', '' );
244
		}
245
246
		// If donation was completed, adjust stats of forms.
247
		if ( 'publish' == $status ) {
248
249
			// Decrease sale of old give form. For other payment status.
250
			$current_form = new Give_Donate_Form( $current_form_id );
251
			$current_form->decrease_sales();
252
			$current_form->decrease_earnings( $curr_total );
253
254
			// Increase sale of new give form.
255
			$new_form = new Give_Donate_Form( $new_form_id );
256
			$new_form->increase_sales();
257
			$new_form->increase_earnings( $new_total );
258
		}
259
260
		// Re setup payment to update new meta value in object.
261
		$payment->update_payment_setup( $payment->ID );
262
	}
263
264
	// Update price id if current form is variable form.
265
	if ( ! empty( $data['give-variable-price'] ) && give_has_variable_prices( $payment->form_id ) ) {
266
267
		// Get payment meta data.
268
		$payment_meta = $payment->get_meta();
269
270
		// Set payment id to empty string if variable price id is negative ( i.e. custom amount feature enabled ).
271
		$data['give-variable-price'] = ( 'custom' === $data['give-variable-price'] ) ? 'custom' : ( 0 < $data['give-variable-price'] ) ? $data['give-variable-price'] : '';
272
273
		// Update payment meta data.
274
		$payment_meta['price_id'] = $data['give-variable-price'];
275
276
		// Update payment give form meta data.
277
		$payment->update_meta( '_give_payment_price_id', $data['give-variable-price'] );
278
		$payment->update_meta( '_give_payment_meta', $payment_meta );
279
280
		// Re setup payment to update new meta value in object.
281
		$payment->update_payment_setup( $payment->ID );
282
	}
283
284
	/**
285
	 * Fires after updating edited donation.
286
	 *
287
	 * @since 1.0
288
	 *
289
	 * @param int $payment_id The ID of the payment.
290
	 */
291
	do_action( 'give_update_edited_donation', $payment_id );
292
293
	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 ) );
294
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_update_payment_details() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
295
}
296
297
add_action( 'give_update_payment_details', 'give_update_payment_details' );
298
299
/**
300
 * Trigger a Donation Deletion.
301
 *
302
 * @since 1.0
303
 *
304
 * @param array $data Arguments passed.
305
 *
306
 * @return void
307
 */
308
function give_trigger_donation_delete( $data ) {
309
	if ( wp_verify_nonce( $data['_wpnonce'], 'give_donation_nonce' ) ) {
310
311
		$payment_id = absint( $data['purchase_id'] );
312
313
		if ( ! current_user_can( 'edit_give_payments', $payment_id ) ) {
314
			wp_die( __( 'You do not have permission to edit payments.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
315
		}
316
317
		give_delete_donation( $payment_id );
318
		wp_redirect( admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&give-message=donation_deleted' ) );
319
		give_die();
320
	}
321
}
322
323
add_action( 'give_delete_payment', 'give_trigger_donation_delete' );
324
325
/**
326
 * AJAX Store Donation Note
327
 */
328
function give_ajax_store_payment_note() {
329
330
	$payment_id = absint( $_POST['payment_id'] );
331
	$note       = wp_kses( $_POST['note'], array() );
332
333
	if ( ! current_user_can( 'edit_give_payments', $payment_id ) ) {
334
		wp_die( __( 'You do not have permission to edit payments.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
335
	}
336
337
	if ( empty( $payment_id ) ) {
338
		die( '-1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_ajax_store_payment_note() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
339
	}
340
341
	if ( empty( $note ) ) {
342
		die( '-1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_ajax_store_payment_note() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
343
	}
344
345
	$note_id = give_insert_payment_note( $payment_id, $note );
346
	die( give_get_payment_note_html( $note_id ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_ajax_store_payment_note() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
347
}
348
349
add_action( 'wp_ajax_give_insert_payment_note', 'give_ajax_store_payment_note' );
350
351
/**
352
 * Triggers a donation note deletion without ajax
353
 *
354
 * @since 1.0
355
 *
356
 * @param array $data Arguments passed
357
 *
358
 * @return void
359
 */
360
function give_trigger_payment_note_deletion( $data ) {
361
362
	if ( ! wp_verify_nonce( $data['_wpnonce'], 'give_delete_payment_note_' . $data['note_id'] ) ) {
363
		return;
364
	}
365
366
	if ( ! current_user_can( 'edit_give_payments', $data['payment_id'] ) ) {
367
		wp_die( esc_html__( 'You do not have permission to edit payments.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
368
	}
369
370
	$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'] ) );
371
372
	give_delete_payment_note( $data['note_id'], $data['payment_id'] );
373
374
	wp_redirect( $edit_order_url );
375
}
376
377
add_action( 'give_delete_payment_note', 'give_trigger_payment_note_deletion' );
378
379
/**
380
 * Delete a payment note deletion with ajax
381
 *
382
 * @since 1.0
383
 *
384
 * @return void
385
 */
386
function give_ajax_delete_payment_note() {
387
388
	if ( ! current_user_can( 'edit_give_payments', $_POST['payment_id'] ) ) {
389
		wp_die( esc_html__( 'You do not have permission to edit payments.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
390
	}
391
392
	if ( give_delete_payment_note( $_POST['note_id'], $_POST['payment_id'] ) ) {
393
		die( '1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_ajax_delete_payment_note() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
394
	} else {
395
		die( '-1' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_ajax_delete_payment_note() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
396
	}
397
398
}
399
400
add_action( 'wp_ajax_give_delete_payment_note', 'give_ajax_delete_payment_note' );
401