Completed
Push — master ( 260ce8...60cf75 )
by Brian
21s queued 16s
created

GetPaid_Checkout::get_submission_items()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 10
rs 10
cc 3
nc 2
nop 0
1
<?php
2
/**
3
 * Contains the Main Checkout Class.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Main Checkout Class.
11
 *
12
 */
13
class GetPaid_Checkout {
14
15
	/**
16
	 * @var GetPaid_Payment_Form_Submission
17
	 */
18
	protected $payment_form_submission;
19
20
	/**
21
	 * Class constructor.
22
	 * 
23
	 * @param GetPaid_Payment_Form_Submission $submission
24
	 */
25
	public function __construct( $submission ) {
26
		$this->payment_form_submission = $submission;
27
	}
28
29
	/**
30
	 * Processes the checkout.
31
	 *
32
	 */
33
	public function process_checkout() {
34
35
		// Validate the submission.
36
		$this->validate_submission();
37
38
		// Get the items and invoice.
39
		$items      = $this->get_submission_items();
40
		$invoice    = $this->get_submission_invoice();
41
		$invoice    = $this->process_submission_invoice( $invoice, $items );
42
		$prepared   = $this->prepare_submission_data_for_saving( $invoice );
43
44
		// Save the invoice.
45
		$invoice->recalculate_total();
46
        $invoice->save();
47
48
		// Send to the gateway.
49
		$this->post_process_submission( $invoice, $prepared );
50
	}
51
52
	/**
53
	 * Validates the submission.
54
	 *
55
	 */
56
	protected function validate_submission() {
57
58
		$submission = $this->payment_form_submission;
59
		$data       = $submission->get_data();
60
61
		// Do we have an error?
62
        if ( ! empty( $submission->last_error ) ) {
63
			wp_send_json_error( $submission->last_error );
64
        }
65
66
		// We need a billing email.
67
        if ( ! $submission->has_billing_email() || ! is_email( $submission->get_billing_email() ) ) {
68
            wp_send_json_error( __( 'Provide a valid billing email.', 'invoicing' ) );
69
		}
70
71
		// Non-recurring gateways should not be allowed to process recurring invoices.
72
		if ( $submission->has_recurring && ! wpinv_gateway_support_subscription( $data['wpi-gateway'] ) ) {
73
			wp_send_json_error( __( 'The selected payment gateway does not support subscription payment.', 'invoicing' ) );
74
		}
75
	
76
		// Ensure the gateway is active.
77
		if ( ! wpinv_is_gateway_active( $data['wpi-gateway'] ) ) {
78
			wpinv_set_error( 'invalid_gateway', __( 'The selected payment gateway is not active', 'invoicing' ) );
79
		}
80
81
		// Clear any existing errors.
82
		wpinv_clear_errors();
83
		
84
		// Allow themes and plugins to hook to errors
85
		do_action( 'getpaid_checkout_error_checks', $submission );
86
		
87
		// Do we have any errors?
88
        if ( wpinv_get_errors() ) {
89
            wp_send_json_error( getpaid_get_errors_html() );
90
		}
91
92
	}
93
94
	/**
95
	 * Retrieves submission items.
96
	 *
97
	 * @return GetPaid_Form_Item[]
98
	 */
99
	protected function get_submission_items() {
100
101
		$items = $this->payment_form_submission->get_items();
102
103
        // Ensure that we have items.
104
        if ( empty( $items ) && 0 == count( $this->payment_form_submission->get_fees() ) ) {
105
            wp_send_json_error( __( 'Please select at least one item.', 'invoicing' ) );
106
		}
107
108
		return $items;
109
	}
110
111
	/**
112
	 * Retrieves submission invoice.
113
	 *
114
	 * @return WPInv_Invoice
115
	 */
116
	protected function get_submission_invoice() {
117
		$submission = $this->payment_form_submission;
118
119
		if ( ! $submission->has_invoice() ) {
120
			return new WPInv_Invoice();
121
        }
122
123
		$invoice = $submission->get_invoice();
124
125
		// Make sure that it is neither paid or refunded.
126
		if ( $invoice->is_paid() || $invoice->is_refunded() ) {
127
			wp_send_json_error( __( 'This invoice has already been paid for.', 'invoicing' ) );
128
		}
129
130
		return $invoice;
131
	}
132
133
	/**
134
	 * Processes the submission invoice.
135
	 *
136
	 * @param WPInv_Invoice $invoice
137
	 * @param GetPaid_Form_Item[] $items
138
	 * @return WPInv_Invoice
139
	 */
140
	protected function process_submission_invoice( $invoice, $items ) {
141
142
		$submission = $this->payment_form_submission;
143
		$data       = $submission->get_data();
144
145
		// Set-up the invoice details.
146
		$invoice->set_email( sanitize_email( $submission->get_billing_email() ) );
147
		$invoice->set_user_id( $this->get_submission_customer() );
148
		$invoice->set_payment_form( absint( $submission->get_payment_form()->get_id() ) );
149
        $invoice->set_items( $items );
150
        $invoice->set_fees( $submission->get_fees() );
151
        $invoice->set_taxes( $submission->get_taxes() );
152
		$invoice->set_discounts( $submission->get_discounts() );
153
		$invoice->set_gateway( $data['wpi-gateway'] );
154
155
		if ( $submission->has_discount_code() ) {
156
            $invoice->set_discount_code( $submission->get_discount_code() );
157
		}
158
159
		getpaid_maybe_add_default_address( $invoice );
160
		return $invoice;
161
	}
162
163
	/**
164
	 * Retrieves the submission's customer.
165
	 *
166
	 * @return int The customer id.
167
	 */
168
	protected function get_submission_customer() {
169
		$submission = $this->payment_form_submission;
170
171
		// If this is an existing invoice...
172
		if ( $submission->has_invoice() ) {
173
			return $submission->get_invoice()->get_user_id();
174
		}
175
176
		// (Maybe) create the user.
177
        $user = get_current_user_id();
178
179
        if ( empty( $user ) ) {
180
            $user = get_user_by( 'email', $submission->get_billing_email() );
181
        }
182
183
        if ( empty( $user ) ) {
184
            $user = wpinv_create_user( $submission->get_billing_email() );
185
        }
186
187
        if ( is_wp_error( $user ) ) {
188
            wp_send_json_error( $user->get_error_message() );
189
        }
190
191
        if ( is_numeric( $user ) ) {
192
            return $user;
193
		}
194
195
		return $user->ID;
0 ignored issues
show
Bug introduced by
The property ID does not seem to exist on WP_Error.
Loading history...
196
197
	}
198
199
	/**
200
     * Prepares submission data for saving to the database.
201
     *
202
	 * @param WPInv_Invoice $invoice
203
     */
204
    public function prepare_submission_data_for_saving( &$invoice ) {
205
206
		$submission = $this->payment_form_submission;
207
208
		// Prepared submission details.
209
        $prepared = array();
210
211
        // Raw submission details.
212
		$data = $submission->get_data();
213
		
214
		// Loop throught the submitted details.
215
        foreach ( $submission->get_payment_form()->get_elements() as $field ) {
216
217
			// Skip premade fields.
218
            if ( ! empty( $field['premade'] ) ) {
219
                continue;
220
            }
221
222
            // If it is required and not set, abort.
223
            if ( ! $submission->is_required_field_set( $field ) ) {
224
                wp_send_json_error( __( 'Some required fields are not set.', 'invoicing' ) );
225
            }
226
227
            // Handle address fields.
228
            if ( $field['type'] == 'address' ) {
229
230
                foreach ( $field['fields'] as $address_field ) {
231
232
                    // skip if it is not visible.
233
                    if ( empty( $address_field['visible'] ) ) {
234
                        continue;
235
                    }
236
237
                    // If it is required and not set, abort
238
                    if ( ! empty( $address_field['required'] ) && empty( $data[ $address_field['name'] ] ) ) {
239
                        wp_send_json_error( __( 'Some required fields are not set.', 'invoicing' ) );
240
                    }
241
242
                    if ( isset( $data[ $address_field['name'] ] ) ) {
243
                        $name   = str_replace( 'wpinv_', '', $address_field['name'] );
244
                        $method = "set_$name";
245
                        $invoice->$method( wpinv_clean( $data[ $address_field['name'] ] ) );
246
                    }
247
248
                }
249
250
            } else if ( isset( $data[ $field['id'] ] ) ) {
251
                $label = $field['id'];
252
253
                if ( isset( $field['label'] ) ) {
254
                    $label = $field['label'];
255
                }
256
257
                $prepared[ wpinv_clean( $label ) ] = wpinv_clean( $data[ $field['id'] ] );
258
            }
259
260
		}
261
		
262
		return $prepared;
263
264
	}
265
266
	/**
267
	 * Confirms the submission is valid and send users to the gateway.
268
	 *
269
	 * @param WPInv_Invoice $invoice
270
	 * @param array $prepared_payment_form_data
271
	 */
272
	protected function post_process_submission( $invoice, $prepared_payment_form_data ) {
273
274
		// Ensure the invoice exists.
275
        if ( $invoice->get_id() == 0 ) {
276
            wp_send_json_error( __( 'An error occured while saving your invoice.', 'invoicing' ) );
277
        }
278
279
		// Was this invoice created via the payment form?
280
        if ( ! $this->payment_form_submission->has_invoice() ) {
281
            update_post_meta( $invoice->get_id(), 'wpinv_created_via', 'payment_form' );
282
        }
283
284
        // Save payment form data.
285
        if ( ! empty( $prepared_payment_form_data ) ) {
286
            update_post_meta( $invoice->get_id(), 'payment_form_data', $prepared_payment_form_data );
287
		}
288
289
		// Backwards compatibility.
290
        add_filter( 'wp_redirect', array( $this, 'send_redirect_response' ) );
291
		add_action( 'wpinv_pre_send_back_to_checkout', array( $this, 'checkout_error' ) );
292
293
		$this->process_payment( $invoice );
294
295
        // If we are here, there was an error.
296
		$this->checkout_error();
297
298
	}
299
300
	/**
301
	 * Processes the actual payment.
302
	 *
303
	 * @param WPInv_Invoice $invoice
304
	 */
305
	protected function process_payment( $invoice ) {
306
307
		$submission = $this->payment_form_submission;
308
309
		// No need to send free invoices to the gateway.
310
		if ( $invoice->is_free() ) {
311
			$invoice->set_gateway( 'none' );
312
			$invoice->add_note( __( "This is a free invoice and won't be sent to the payment gateway", 'invoicing' ), false, false, true );
313
			$invoice->mark_paid();
314
			wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) );
315
		}
316
317
		// Clear any checkout errors.
318
		wpinv_clear_errors();
319
320
		// Fires before sending to the gateway.
321
		do_action( 'getpaid_checkout_before_gateway', $invoice, $submission );
322
323
		// Allow the sumission data to be modified before it is sent to the gateway.
324
		$submission_data    = $submission->get_data();
325
		$submission_gateway = apply_filters( 'getpaid_gateway_submission_gateway', $invoice->get_gateway(), $submission, $invoice );
326
		$submission_data    = apply_filters( 'getpaid_gateway_submission_data', $submission_data, $submission, $invoice );
327
328
		// Validate the currency.
329
		if ( ! apply_filters( "getpaid_gateway_{$submission_gateway}_is_valid_for_currency", true, $invoice->get_currency() ) ) {
330
			wpinv_set_error( 'invalid_currency', __( 'The chosen payment gateway does not support the invoice currency', 'invoicing' ) );
331
		}
332
333
		// Check to see if we have any errors.
334
		if ( wpinv_get_errors() ) {
335
			wpinv_send_back_to_checkout();
336
		}
337
338
		// Send info to the gateway for payment processing
339
		do_action( "getpaid_gateway_$submission_gateway", $invoice, $submission_data, $submission );
340
341
		// Backwards compatibility.
342
		wpinv_send_to_gateway( $submission_gateway, $invoice );
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_send_to_gateway() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

342
		/** @scrutinizer ignore-deprecated */ wpinv_send_to_gateway( $submission_gateway, $invoice );
Loading history...
343
344
	}
345
346
	/**
347
     * Sends a redrect response to payment details.
348
     *
349
     */
350
    public function send_redirect_response( $url ) {
351
        $url = urlencode( $url );
352
        wp_send_json_success( $url );
353
    }
354
355
    /**
356
     * Fired when a checkout error occurs
357
     *
358
     */
359
    public function checkout_error() {
360
361
        // Do we have any errors?
362
        if ( wpinv_get_errors() ) {
363
            wp_send_json_error( getpaid_get_errors_html() );
364
		}
365
366
        wp_send_json_error( __( 'An error occured while processing your payment. Please try again.', 'invoicing' ) );
367
368
	}
369
370
}
371