PlaceOrder::run()   F
last analyzed

Complexity

Conditions 18
Paths 6144

Size

Total Lines 110
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 342

Importance

Changes 0
Metric Value
cc 18
eloc 53
nc 6144
nop 0
dl 0
loc 110
ccs 0
cts 66
cp 0
crap 342
rs 0.7
c 0
b 0
f 0

How to fix   Long Method    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
namespace Never5\DownloadMonitor\Shop\Ajax;
4
5
use Never5\DownloadMonitor\Shop\Order;
6
use Never5\DownloadMonitor\Shop\Services\Services;
7
8
class PlaceOrder extends Ajax {
9
10
	/**
11
	 * Constructor
12
	 */
13
	public function __construct() {
14
		parent::__construct( 'place_order' );
15
	}
16
17
	/**
18
	 * Calling this method will return a negative success to the browser
19
	 *
20
	 * @param string $error_message
21
	 */
22
	private function failed( $error_message ) {
23
		wp_send_json( array( 'success' => false, 'error' => $error_message ) );
0 ignored issues
show
Bug introduced by
The function wp_send_json was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

23
		/** @scrutinizer ignore-call */ 
24
  wp_send_json( array( 'success' => false, 'error' => $error_message ) );
Loading history...
24
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
25
	}
26
27
	/**
28
	 * Parse and complete raw customer post data
29
	 *
30
	 * @return array
31
	 */
32
	private function parse_customer_post_data() {
33
		return array(
34
			'first_name' => isset( $_POST['customer']['first_name'] ) ? $_POST['customer']['first_name'] : '',
35
			'last_name'  => isset( $_POST['customer']['last_name'] ) ? $_POST['customer']['last_name'] : '',
36
			'company'    => isset( $_POST['customer']['company'] ) ? $_POST['customer']['company'] : '',
37
			'email'      => isset( $_POST['customer']['email'] ) ? $_POST['customer']['email'] : '',
38
			'address_1'  => isset( $_POST['customer']['address_1'] ) ? $_POST['customer']['address_1'] : '',
39
			'address_2'  => isset( $_POST['customer']['address_2'] ) ? $_POST['customer']['address_2'] : '',
40
			'postcode'   => isset( $_POST['customer']['postcode'] ) ? $_POST['customer']['postcode'] : '',
41
			'city'       => isset( $_POST['customer']['city'] ) ? $_POST['customer']['city'] : '',
42
			'state'      => isset( $_POST['customer']['state'] ) ? $_POST['customer']['state'] : '',
43
			'country'    => isset( $_POST['customer']['country'] ) ? $_POST['customer']['country'] : '',
44
			'phone'      => isset( $_POST['customer']['phone'] ) ? $_POST['customer']['phone'] : '',
45
			'ip_address' => isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : ''
46
		);
47
	}
48
49
	/**
50
	 * @param bool $success
51
	 * @param string $redirect
52
	 * @param string $error
53
	 */
54
	private function response( $success, $redirect, $error ) {
55
		wp_send_json( array( 'success' => $success, 'redirect' => $redirect, 'error' => $error ) );
0 ignored issues
show
Bug introduced by
The function wp_send_json was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

55
		/** @scrutinizer ignore-call */ 
56
  wp_send_json( array( 'success' => $success, 'redirect' => $redirect, 'error' => $error ) );
Loading history...
56
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
57
	}
58
59
	/**
60
	 * AJAX callback method
61
	 *
62
	 * @return void
63
	 */
64
	public function run() {
65
66
		// check nonce
67
		$this->check_nonce();
68
69
		//
70
		$customer_post = $this->parse_customer_post_data();
71
72
		// get gateway
73
		$enabled_gateways = Services::get()->service( 'payment_gateway' )->get_enabled_gateways();
74
75
		/** @var \Never5\DownloadMonitor\Shop\Checkout\PaymentGateway\PaymentGateway $gateway */
76
		$gateway = ( isset( $_POST['payment_gateway'] ) && isset( $enabled_gateways[ $_POST['payment_gateway'] ] ) ? $enabled_gateways[ $_POST['payment_gateway'] ] : null );
77
78
		/**
79
		 * Check if all required fields are set
80
		 */
81
		$required_fields = Services::get()->service( 'checkout_field' )->get_required_fields();
82
		foreach ( $required_fields as $required_field ) {
83
			if ( ! isset( $customer_post[ $required_field ] ) || $customer_post[ $required_field ] === "" ) {
84
				$this->failed( __( 'Not all required fields are set', 'download-monitor' ) );
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

84
				$this->failed( /** @scrutinizer ignore-call */ __( 'Not all required fields are set', 'download-monitor' ) );
Loading history...
85
			}
86
		}
87
88
		// check if gateway is valid
89
		if ( is_null( $gateway ) ) {
90
			$this->failed( __( 'Invalid Payment Gateway', 'download-monitor' ) );
91
		}
92
93
		// check if we need to create an order or fetch one based on id and hash
94
		$order_id     = absint( ( isset( $_POST['order_id'] ) ) ? $_POST['order_id'] : 0 );
0 ignored issues
show
Bug introduced by
The function absint was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

94
		$order_id     = /** @scrutinizer ignore-call */ absint( ( isset( $_POST['order_id'] ) ) ? $_POST['order_id'] : 0 );
Loading history...
95
		$order_hash   = ( isset( $_POST['order_hash'] ) ? $_POST['order_hash'] : '' );
96
		$order        = null;
97
		$is_new_order = true;
98
99
		if ( $order_id > 0 && ! empty( $order_hash ) ) {
100
			/** @var \Never5\DownloadMonitor\Shop\Order\WordPressRepository $op */
101
			try {
102
				$op        = Services::get()->service( 'order_repository' );
103
				$tmp_order = $op->retrieve_single( $order_id );
104
105
				// check order hashes
106
				if ( $order_hash !== $tmp_order->get_hash() ) {
107
					throw new \Exception( 'Order hash incorrect' );
108
				}
109
110
				if ( $tmp_order->get_status()->get_key() !== 'pending-payment' ) {
111
					throw new \Exception( 'Order status not pending payment' );
112
				}
113
114
				$order        = $tmp_order;
115
				$is_new_order = false;
116
117
			} catch ( \Exception $e ) {
118
				$order = null;
119
			}
120
		}
121
122
		// create order if no order is set at this point
123
		if ( null === $order ) {
124
			/** @var Order\Order $order */
125
			$order = Services::get()->service( 'order_factory' )->make();
126
		}
127
128
		/**
129
		 * Create OrderCustomer
130
		 */
131
		$order->set_customer( new Order\OrderCustomer(
132
			$customer_post['first_name'],
133
			$customer_post['last_name'],
134
			$customer_post['company'],
135
			$customer_post['address_1'],
136
			$customer_post['address_2'],
137
			$customer_post['city'],
138
			$customer_post['state'],
139
			$customer_post['postcode'],
140
			$customer_post['country'],
141
			$customer_post['email'],
142
			$customer_post['phone'],
143
			$customer_post['ip_address']
144
		) );
145
146
		// build array with order items based on current cart if this is a new order
147
		if ( $is_new_order ) {
148
			$order->set_items( Services::get()->service( 'order' )->build_order_items_from_cart() );
149
		}
150
151
		// persist order
152
		try {
153
			Services::get()->service( 'order_repository' )->persist( $order );
154
		} catch ( \Exception $exception ) {
155
			$this->response( false, '', $exception->getMessage() );
156
		}
157
158
		// run gateway
159
		$gateway_result = $gateway->process( $order );
160
161
		// exit if gateway was not successful
162
		if ( ! $gateway_result->is_success() ) {
163
			$this->response( false, '', sprintf( __( 'Payment gateway error: %s', 'download-monitor' ), $gateway_result->get_error_message() ) );
164
		}
165
166
		// order is in DB, gateway did what it had to do -> clear the cart
167
		Services::get()->service( 'cart' )->destroy_cart();
168
169
		// we good, send response with redirect
170
		$this->response( true, $gateway_result->get_redirect(), '' );
171
172
		// bye
173
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
174
	}
175
176
}