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

WC_Stripe_Connect_API::request_headers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
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
		 * Send request to Connect Server to deauthorize account
86
		 *
87
		 * @return array
88
		 */
89
		public function deauthorize_stripe_account() {
90
91
			return $this->request( 'POST', '/stripe/account/deauthorize' );
92
		}
93
94
		/**
95
		 * General OAuth request method.
96
		 *
97
		 * @param string $method request method.
98
		 * @param string $path   path for request.
99
		 * @param array  $body   request body.
100
		 *
101
		 * @return array|WP_Error
102
		 */
103
		protected function request( $method, $path, $body = array() ) {
104
105
			if ( ! is_array( $body ) ) {
106
				return new WP_Error(
107
					'request_body_should_be_array',
108
					__( 'Unable to send request to WooCommerce Connect server. Body must be an array.', 'woocommerce-gateway-stripe' )
109
				);
110
			}
111
112
			$url = trailingslashit( WOOCOMMERCE_CONNECT_SERVER_URL );
113
			$url = apply_filters( 'wc_connect_server_url', $url );
114
			$url = trailingslashit( $url ) . ltrim( $path, '/' );
115
116
			// Add useful system information to requests that contain bodies.
117
			if ( in_array( $method, array( 'POST', 'PUT' ), true ) ) {
118
				$body = $this->request_body( $body );
119
				$body = wp_json_encode( apply_filters( 'wc_connect_api_client_body', $body ) );
120
121
				if ( ! $body ) {
122
					return new WP_Error(
123
						'unable_to_json_encode_body',
124
						__( 'Unable to encode body for request to WooCommerce Connect server.', 'woocommerce-gateway-stripe' )
125
					);
126
				}
127
			}
128
129
			$headers = $this->request_headers();
130
			if ( is_wp_error( $headers ) ) {
131
				return $headers;
132
			}
133
134
			$http_timeout = 60; // 1 minute
135
			if ( function_exists( 'wc_set_time_limit' ) ) {
136
				wc_set_time_limit( $http_timeout + 10 );
137
			}
138
			$args = array(
139
				'headers'     => $headers,
140
				'method'      => $method,
141
				'body'        => $body,
142
				'redirection' => 0,
143
				'compress'    => true,
144
				'timeout'     => $http_timeout,
145
			);
146
147
			$args          = apply_filters( 'wc_connect_request_args', $args );
148
			$response      = wp_remote_request( $url, $args );
149
			$response_code = wp_remote_retrieve_response_code( $response );
150
			$content_type  = wp_remote_retrieve_header( $response, 'content-type' );
151
152
			if ( false === strpos( $content_type, 'application/json' ) ) {
153
				if ( 200 !== $response_code ) {
154
					return new WP_Error(
155
						'wcc_server_error',
156
						sprintf(
157
							// Translators: HTTP error code.
158
							__( 'Error: The WooCommerce Connect server returned HTTP code: %d', 'woocommerce-gateway-stripe' ),
159
							$response_code
160
						)
161
					);
162
				}
163
				return $response;
164
			}
165
166
			$response_body = wp_remote_retrieve_body( $response );
167
			if ( ! empty( $response_body ) ) {
168
				$response_body = json_decode( $response_body );
169
			}
170
171
			if ( 200 !== $response_code ) {
172
				if ( empty( $response_body ) ) {
173
					return new WP_Error(
174
						'wcc_server_empty_response',
175
						sprintf(
176
							// Translators: HTTP error code.
177
							__( 'Error: The WooCommerce Connect server returned ( %d ) and an empty response body.', 'woocommerce-gateway-stripe' ),
178
							$response_code
179
						)
180
					);
181
				}
182
183
				$error   = property_exists( $response_body, 'error' ) ? $response_body->error : '';
184
				$message = property_exists( $response_body, 'message' ) ? $response_body->message : '';
185
				$data    = property_exists( $response_body, 'data' ) ? $response_body->data : '';
186
187
				return new WP_Error(
188
					'wcc_server_error_response',
189
					sprintf(
190
						/* translators: %1$s: error code, %2$s: error message, %3$d: HTTP response code */
191
						__( 'Error: The WooCommerce Connect server returned: %1$s %2$s ( %3$d )', 'woocommerce-gateway-stripe' ),
192
						$error,
193
						$message,
194
						$response_code
195
					),
196
					$data
197
				);
198
			}
199
200
			return $response_body;
201
		}
202
203
		/**
204
		 * Adds useful WP/WC/WCC information to request bodies.
205
		 *
206
		 * @param array $initial_body body of initial request.
207
		 *
208
		 * @return array
209
		 */
210
		protected function request_body( $initial_body = array() ) {
211
212
			$default_body = array(
213
				'settings' => array(),
214
			);
215
216
			$body = array_merge( $default_body, $initial_body );
217
218
			// Add interesting fields to the body of each request.
219
			$body['settings'] = wp_parse_args(
220
				$body['settings'],
221
				array(
222
					'base_city'      => WC()->countries->get_base_city(),
223
					'base_country'   => WC()->countries->get_base_country(),
224
					'base_state'     => WC()->countries->get_base_state(),
225
					'base_postcode'  => WC()->countries->get_base_postcode(),
226
					'currency'       => get_woocommerce_currency(),
227
					'stripe_version' => WC_STRIPE_VERSION,
228
					'wc_version'     => WC()->version,
229
					'wp_version'     => get_bloginfo( 'version' ),
230
				)
231
			);
232
233
			return $body;
234
		}
235
236
		/**
237
		 * Generates headers for request to the WooCommerce Connect Server.
238
		 *
239
		 * @return array|WP_Error
240
		 */
241
		protected function request_headers() {
242
243
			$headers                    = array();
244
			$locale                     = strtolower( str_replace( '_', '-', get_locale() ) );
245
			$locale_elements            = explode( '-', $locale );
246
			$lang                       = $locale_elements[0];
247
			$headers['Accept-Language'] = $locale . ',' . $lang;
248
			$headers['Content-Type']    = 'application/json; charset=utf-8';
249
			$headers['Accept']          = 'application/vnd.woocommerce-connect.v' . self::WOOCOMMERCE_CONNECT_SERVER_API_VERSION;
250
251
			return $headers;
252
		}
253
	}
254
}
255