Completed
Pull Request — master (#1267)
by
unknown
01:47
created

WC_Stripe_Connect_API::request()   C

Complexity

Conditions 13
Paths 48

Size

Total Lines 105

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
nc 48
nop 3
dl 0
loc 105
rs 5.2933
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
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
if ( ! defined( 'WOOCOMMERCE_CONNECT_SERVER_URL' ) ) {
7
	define( 'WOOCOMMERCE_CONNECT_SERVER_URL', 'https://api.woocommerce.com/' );
8
}
9
10
if ( ! class_exists( 'WC_Stripe_Connect_API' ) ) {
11
	/**
12
	 * Stripe Connect API class.
13
	 */
14
	class WC_Stripe_Connect_API {
15
16
		const WOOCOMMERCE_CONNECT_SERVER_API_VERSION = '3';
17
18
		/**
19
		 * Send request to Connect Server to initiate Stripe OAuth
20
		 *
21
		 * @param  string $return_url return address.
22
		 *
23
		 * @return array
24
		 */
25
		public function get_stripe_oauth_init( $return_url ) {
26
27
			$current_user                   = wp_get_current_user();
28
			$business_data                  = array();
29
			$business_data['url']           = get_site_url();
30
			$business_data['business_name'] = html_entity_decode( get_bloginfo( 'name' ), ENT_QUOTES );
31
			$business_data['first_name']    = $current_user->user_firstname;
32
			$business_data['last_name']     = $current_user->user_lastname;
33
			$business_data['phone']         = '';
34
			$business_data['currency']      = get_woocommerce_currency();
35
36
			$wc_countries = WC()->countries;
37
38
			if ( method_exists( $wc_countries, 'get_base_address' ) ) {
39
				$business_data['country']        = $wc_countries->get_base_country();
40
				$business_data['street_address'] = $wc_countries->get_base_address();
41
				$business_data['city']           = $wc_countries->get_base_city();
42
				$business_data['state']          = $wc_countries->get_base_state();
43
				$business_data['zip']            = $wc_countries->get_base_postcode();
44
			} else {
45
				$base_location                   = wc_get_base_location();
46
				$business_data['country']        = $base_location['country'];
47
				$business_data['street_address'] = '';
48
				$business_data['city']           = '';
49
				$business_data['state']          = $base_location['state'];
50
				$business_data['zip']            = '';
51
			}
52
53
			$request = array(
54
				'returnUrl'    => $return_url,
55
				'businessData' => $business_data,
56
			);
57
58
			return $this->request( 'POST', '/stripe/oauth-init', $request );
59
		}
60
61
		/**
62
		 * Send request to Connect Server for Stripe keys
63
		 *
64
		 * @param  string $code OAuth server code.
65
		 *
66
		 * @return array
67
		 */
68
		public function get_stripe_oauth_keys( $code ) {
69
70
			$request = array( 'code' => $code );
71
72
			return $this->request( 'POST', '/stripe/oauth-keys', $request );
73
		}
74
75
		/**
76
		 * General OAuth request method.
77
		 *
78
		 * @param string $method request method.
79
		 * @param string $path   path for request.
80
		 * @param array  $body   request body.
81
		 *
82
		 * @return array|WP_Error
83
		 */
84
		protected function request( $method, $path, $body = array() ) {
85
86
			if ( ! is_array( $body ) ) {
87
				return new WP_Error(
88
					'request_body_should_be_array',
89
					__( 'Unable to send request to WooCommerce Connect server. Body must be an array.', 'woocommerce-gateway-stripe' )
90
				);
91
			}
92
93
			$url = trailingslashit( WOOCOMMERCE_CONNECT_SERVER_URL );
94
			$url = apply_filters( 'wc_connect_server_url', $url );
95
			$url = trailingslashit( $url ) . ltrim( $path, '/' );
96
97
			// Add useful system information to requests that contain bodies.
98
			if ( in_array( $method, array( 'POST', 'PUT' ), true ) ) {
99
				$body = $this->request_body( $body );
100
				$body = wp_json_encode( apply_filters( 'wc_connect_api_client_body', $body ) );
101
102
				if ( ! $body ) {
103
					return new WP_Error(
104
						'unable_to_json_encode_body',
105
						__( 'Unable to encode body for request to WooCommerce Connect server.', 'woocommerce-gateway-stripe' )
106
					);
107
				}
108
			}
109
110
			$headers = $this->request_headers();
111
			if ( is_wp_error( $headers ) ) {
112
				return $headers;
113
			}
114
115
			$http_timeout = 60; // 1 minute
116
			wc_set_time_limit( $http_timeout + 10 );
117
			$args = array(
118
				'headers'     => $headers,
119
				'method'      => $method,
120
				'body'        => $body,
121
				'redirection' => 0,
122
				'compress'    => true,
123
				'timeout'     => $http_timeout,
124
			);
125
126
			$args          = apply_filters( 'wc_connect_request_args', $args );
127
			$response      = wp_remote_request( $url, $args );
128
			$response_code = wp_remote_retrieve_response_code( $response );
129
			$content_type  = wp_remote_retrieve_header( $response, 'content-type' );
130
131
			if ( false === strpos( $content_type, 'application/json' ) ) {
132
				if ( 200 !== $response_code ) {
133
					return new WP_Error(
134
						'wcc_server_error',
135
						sprintf(
136
							// Translators: HTTP error code.
137
							__( 'Error: The WooCommerce Connect server returned HTTP code: %d', 'woocommerce-gateway-stripe' ),
138
							$response_code
139
						)
140
					);
141
				} else {
142
					return new WP_Error(
143
						'wcc_server_error_content_type',
144
						sprintf(
145
							// Translators: content-type error code.
146
							__( 'Error: The WooCommerce Connect server returned an invalid content-type: %s.', 'woocommerce-gateway-stripe' ),
147
							$content_type
148
						)
149
					);
150
				}
151
			}
152
153
			$response_body = wp_remote_retrieve_body( $response );
154
			if ( ! empty( $response_body ) ) {
155
				$response_body = json_decode( $response_body );
156
			}
157
158
			if ( 200 !== $response_code ) {
159
				if ( empty( $response_body ) ) {
160
					return new WP_Error(
161
						'wcc_server_empty_response',
162
						sprintf(
163
							// Translators: HTTP error code.
164
							__( 'Error: The WooCommerce Connect server returned ( %d ) and an empty response body.', 'woocommerce-gateway-stripe' ),
165
							$response_code
166
						)
167
					);
168
				}
169
170
				$error   = property_exists( $response_body, 'error' ) ? $response_body->error : '';
171
				$message = property_exists( $response_body, 'message' ) ? $response_body->message : '';
172
				$data    = property_exists( $response_body, 'data' ) ? $response_body->data : '';
173
174
				return new WP_Error(
175
					'wcc_server_error_response',
176
					sprintf(
177
						/* translators: %1$s: error code, %2$s: error message, %3$d: HTTP response code */
178
						__( 'Error: The WooCommerce Connect server returned: %1$s %2$s ( %3$d )', 'woocommerce-gateway-stripe' ),
179
						$error,
180
						$message,
181
						$response_code
182
					),
183
					$data
184
				);
185
			}
186
187
			return $response_body;
188
		}
189
190
		/**
191
		 * Adds useful WP/WC/WCC information to request bodies.
192
		 *
193
		 * @param array $initial_body body of initial request.
194
		 *
195
		 * @return array
196
		 */
197
		protected function request_body( $initial_body = array() ) {
198
199
			$default_body = array(
200
				'settings' => array(),
201
			);
202
203
			$body = array_merge( $default_body, $initial_body );
204
205
			// Add interesting fields to the body of each request.
206
			$body['settings'] = wp_parse_args(
207
				$body['settings'],
208
				array(
209
					'base_city'      => WC()->countries->get_base_city(),
210
					'base_country'   => WC()->countries->get_base_country(),
211
					'base_state'     => WC()->countries->get_base_state(),
212
					'base_postcode'  => WC()->countries->get_base_postcode(),
213
					'currency'       => get_woocommerce_currency(),
214
					'stripe_version' => WC_STRIPE_VERSION,
215
					'wc_version'     => WC()->version,
216
					'wp_version'     => get_bloginfo( 'version' ),
217
				)
218
			);
219
220
			return $body;
221
		}
222
223
		/**
224
		 * Generates headers for request to the WooCommerce Connect Server.
225
		 *
226
		 * @return array|WP_Error
227
		 */
228
		protected function request_headers() {
229
230
			$headers                    = array();
231
			$locale                     = strtolower( str_replace( '_', '-', get_locale() ) );
232
			$locale_elements            = explode( '-', $locale );
233
			$lang                       = $locale_elements[0];
234
			$headers['Accept-Language'] = $locale . ',' . $lang;
235
			$headers['Content-Type']    = 'application/json; charset=utf-8';
236
			$headers['Accept']          = 'application/vnd.woocommerce-connect.v' . self::WOOCOMMERCE_CONNECT_SERVER_API_VERSION;
237
238
			return $headers;
239
		}
240
	}
241
}
242