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

WC_Stripe_Connect_API::request()   C

Complexity

Conditions 14
Paths 92

Size

Total Lines 99

Duplication

Lines 0
Ratio 0 %

Importance

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