Open Monograph Press  3.3.0
paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php
1 <?php
2 namespace GuzzleHttp;
3 
5 use GuzzleHttp\Exception\GuzzleException;
11 
26 class Client implements ClientInterface
27 {
29  private $config;
30 
62  public function __construct(array $config = [])
63  {
64  if (!isset($config['handler'])) {
65  $config['handler'] = HandlerStack::create();
66  } elseif (!is_callable($config['handler'])) {
67  throw new \InvalidArgumentException('handler must be a callable');
68  }
69 
70  // Convert the base_uri to a UriInterface
71  if (isset($config['base_uri'])) {
72  $config['base_uri'] = Psr7\uri_for($config['base_uri']);
73  }
74 
75  $this->configureDefaults($config);
76  }
77 
84  public function __call($method, $args)
85  {
86  if (count($args) < 1) {
87  throw new \InvalidArgumentException('Magic request methods require a URI and optional options array');
88  }
89 
90  $uri = $args[0];
91  $opts = isset($args[1]) ? $args[1] : [];
92 
93  return substr($method, -5) === 'Async'
94  ? $this->requestAsync(substr($method, 0, -5), $uri, $opts)
95  : $this->request($method, $uri, $opts);
96  }
97 
106  public function sendAsync(RequestInterface $request, array $options = [])
107  {
108  // Merge the base URI into the request URI if needed.
109  $options = $this->prepareDefaults($options);
110 
111  return $this->transfer(
112  $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
113  $options
114  );
115  }
116 
126  public function send(RequestInterface $request, array $options = [])
127  {
128  $options[RequestOptions::SYNCHRONOUS] = true;
129  return $this->sendAsync($request, $options)->wait();
130  }
131 
146  public function requestAsync($method, $uri = '', array $options = [])
147  {
148  $options = $this->prepareDefaults($options);
149  // Remove request modifying parameter because it can be done up-front.
150  $headers = isset($options['headers']) ? $options['headers'] : [];
151  $body = isset($options['body']) ? $options['body'] : null;
152  $version = isset($options['version']) ? $options['version'] : '1.1';
153  // Merge the URI into the base URI.
154  $uri = $this->buildUri($uri, $options);
155  if (is_array($body)) {
156  $this->invalidBody();
157  }
158  $request = new Psr7\Request($method, $uri, $headers, $body, $version);
159  // Remove the option so that they are not doubly-applied.
160  unset($options['headers'], $options['body'], $options['version']);
161 
162  return $this->transfer($request, $options);
163  }
164 
179  public function request($method, $uri = '', array $options = [])
180  {
181  $options[RequestOptions::SYNCHRONOUS] = true;
182  return $this->requestAsync($method, $uri, $options)->wait();
183  }
184 
196  public function getConfig($option = null)
197  {
198  return $option === null
199  ? $this->config
200  : (isset($this->config[$option]) ? $this->config[$option] : null);
201  }
202 
208  private function buildUri($uri, array $config)
209  {
210  // for BC we accept null which would otherwise fail in uri_for
211  $uri = Psr7\uri_for($uri === null ? '' : $uri);
212 
213  if (isset($config['base_uri'])) {
214  $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
215  }
216 
217  if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
218  $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion'];
219  $uri = Utils::idnUriConvert($uri, $idnOptions);
220  }
221 
222  return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
223  }
224 
231  private function configureDefaults(array $config)
232  {
233  $defaults = [
234  'allow_redirects' => RedirectMiddleware::$defaultSettings,
235  'http_errors' => true,
236  'decode_content' => true,
237  'verify' => true,
238  'cookies' => false,
239  'idn_conversion' => true,
240  ];
241 
242  // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
243 
244  // We can only trust the HTTP_PROXY environment variable in a CLI
245  // process due to the fact that PHP has no reliable mechanism to
246  // get environment variables that start with "HTTP_".
247  if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) {
248  $defaults['proxy']['http'] = getenv('HTTP_PROXY');
249  }
250 
251  if ($proxy = getenv('HTTPS_PROXY')) {
252  $defaults['proxy']['https'] = $proxy;
253  }
254 
255  if ($noProxy = getenv('NO_PROXY')) {
256  $cleanedNoProxy = str_replace(' ', '', $noProxy);
257  $defaults['proxy']['no'] = explode(',', $cleanedNoProxy);
258  }
259 
260  $this->config = $config + $defaults;
261 
262  if (!empty($config['cookies']) && $config['cookies'] === true) {
263  $this->config['cookies'] = new CookieJar();
264  }
265 
266  // Add the default user-agent header.
267  if (!isset($this->config['headers'])) {
268  $this->config['headers'] = ['User-Agent' => default_user_agent()];
269  } else {
270  // Add the User-Agent header if one was not already set.
271  foreach (array_keys($this->config['headers']) as $name) {
272  if (strtolower($name) === 'user-agent') {
273  return;
274  }
275  }
276  $this->config['headers']['User-Agent'] = default_user_agent();
277  }
278  }
279 
287  private function prepareDefaults(array $options)
288  {
289  $defaults = $this->config;
290 
291  if (!empty($defaults['headers'])) {
292  // Default headers are only added if they are not present.
293  $defaults['_conditional'] = $defaults['headers'];
294  unset($defaults['headers']);
295  }
296 
297  // Special handling for headers is required as they are added as
298  // conditional headers and as headers passed to a request ctor.
299  if (array_key_exists('headers', $options)) {
300  // Allows default headers to be unset.
301  if ($options['headers'] === null) {
302  $defaults['_conditional'] = [];
303  unset($options['headers']);
304  } elseif (!is_array($options['headers'])) {
305  throw new \InvalidArgumentException('headers must be an array');
306  }
307  }
308 
309  // Shallow merge defaults underneath options.
310  $result = $options + $defaults;
311 
312  // Remove null values.
313  foreach ($result as $k => $v) {
314  if ($v === null) {
315  unset($result[$k]);
316  }
317  }
318 
319  return $result;
320  }
321 
332  private function transfer(RequestInterface $request, array $options)
333  {
334  // save_to -> sink
335  if (isset($options['save_to'])) {
336  $options['sink'] = $options['save_to'];
337  unset($options['save_to']);
338  }
339 
340  // exceptions -> http_errors
341  if (isset($options['exceptions'])) {
342  $options['http_errors'] = $options['exceptions'];
343  unset($options['exceptions']);
344  }
345 
346  $request = $this->applyOptions($request, $options);
348  $handler = $options['handler'];
349 
350  try {
351  return Promise\promise_for($handler($request, $options));
352  } catch (\Exception $e) {
353  return Promise\rejection_for($e);
354  }
355  }
356 
365  private function applyOptions(RequestInterface $request, array &$options)
366  {
367  $modify = [
368  'set_headers' => [],
369  ];
370 
371  if (isset($options['headers'])) {
372  $modify['set_headers'] = $options['headers'];
373  unset($options['headers']);
374  }
375 
376  if (isset($options['form_params'])) {
377  if (isset($options['multipart'])) {
378  throw new \InvalidArgumentException('You cannot use '
379  . 'form_params and multipart at the same time. Use the '
380  . 'form_params option if you want to send application/'
381  . 'x-www-form-urlencoded requests, and the multipart '
382  . 'option to send multipart/form-data requests.');
383  }
384  $options['body'] = http_build_query($options['form_params'], '', '&');
385  unset($options['form_params']);
386  // Ensure that we don't have the header in different case and set the new value.
387  $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
388  $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
389  }
390 
391  if (isset($options['multipart'])) {
392  $options['body'] = new Psr7\MultipartStream($options['multipart']);
393  unset($options['multipart']);
394  }
395 
396  if (isset($options['json'])) {
397  $options['body'] = \GuzzleHttp\json_encode($options['json']);
398  unset($options['json']);
399  // Ensure that we don't have the header in different case and set the new value.
400  $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
401  $options['_conditional']['Content-Type'] = 'application/json';
402  }
403 
404  if (!empty($options['decode_content'])
405  && $options['decode_content'] !== true
406  ) {
407  // Ensure that we don't have the header in different case and set the new value.
408  $options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']);
409  $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
410  }
411 
412  if (isset($options['body'])) {
413  if (is_array($options['body'])) {
414  $this->invalidBody();
415  }
416  $modify['body'] = Psr7\stream_for($options['body']);
417  unset($options['body']);
418  }
419 
420  if (!empty($options['auth']) && is_array($options['auth'])) {
421  $value = $options['auth'];
422  $type = isset($value[2]) ? strtolower($value[2]) : 'basic';
423  switch ($type) {
424  case 'basic':
425  // Ensure that we don't have the header in different case and set the new value.
426  $modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']);
427  $modify['set_headers']['Authorization'] = 'Basic '
428  . base64_encode("$value[0]:$value[1]");
429  break;
430  case 'digest':
431  // @todo: Do not rely on curl
432  $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
433  $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
434  break;
435  case 'ntlm':
436  $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM;
437  $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
438  break;
439  }
440  }
441 
442  if (isset($options['query'])) {
443  $value = $options['query'];
444  if (is_array($value)) {
445  $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
446  }
447  if (!is_string($value)) {
448  throw new \InvalidArgumentException('query must be a string or array');
449  }
450  $modify['query'] = $value;
451  unset($options['query']);
452  }
453 
454  // Ensure that sink is not an invalid value.
455  if (isset($options['sink'])) {
456  // TODO: Add more sink validation?
457  if (is_bool($options['sink'])) {
458  throw new \InvalidArgumentException('sink must not be a boolean');
459  }
460  }
461 
462  $request = Psr7\modify_request($request, $modify);
463  if ($request->getBody() instanceof Psr7\MultipartStream) {
464  // Use a multipart/form-data POST if a Content-Type is not set.
465  // Ensure that we don't have the header in different case and set the new value.
466  $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
467  $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
468  . $request->getBody()->getBoundary();
469  }
470 
471  // Merge in conditional headers if they are not present.
472  if (isset($options['_conditional'])) {
473  // Build up the changes so it's in a single clone of the message.
474  $modify = [];
475  foreach ($options['_conditional'] as $k => $v) {
476  if (!$request->hasHeader($k)) {
477  $modify['set_headers'][$k] = $v;
478  }
479  }
480  $request = Psr7\modify_request($request, $modify);
481  // Don't pass this internal value along to middleware/handlers.
482  unset($options['_conditional']);
483  }
484 
485  return $request;
486  }
487 
493  private function invalidBody()
494  {
495  throw new \InvalidArgumentException('Passing in the "body" request '
496  . 'option as an array to send a POST request has been deprecated. '
497  . 'Please use the "form_params" request option to send a '
498  . 'application/x-www-form-urlencoded request, or the "multipart" '
499  . 'request option to send a multipart/form-data request.');
500  }
501 }
GuzzleHttp
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:2
GuzzleHttp\Client\getConfig
getConfig($option=null)
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:199
GuzzleHttp\Client\sendAsync
sendAsync(RequestInterface $request, array $options=[])
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:109
Psr\Http\Message\RequestInterface
Definition: vendor/psr/http-message/src/RequestInterface.php:24
GuzzleHttp\Client\__construct
__construct(array $config=[])
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:65
GuzzleHttp\Client\__call
__call($method, $args)
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:87
GuzzleHttp\ClientInterface
Definition: vendor/guzzlehttp/guzzle/src/ClientInterface.php:13
GuzzleHttp\Client\request
request($method, $uri='', array $options=[])
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:182
GuzzleHttp\Psr7
Definition: AppendStream.php:2
Psr\Http\Message\UriInterface
Definition: UriInterface.php:24
Psr\Http\Message\ResponseInterface
Definition: vendor/psr/http-message/src/ResponseInterface.php:20
GuzzleHttp\Psr7\Request
Definition: paymethod/paypal/vendor/guzzlehttp/psr7/src/Request.php:12
GuzzleHttp\default_user_agent
default_user_agent()
Definition: guzzlehttp/guzzle/src/functions.php:131
GuzzleHttp\Psr7\uri_for
uri_for($uri)
Definition: guzzlehttp/psr7/src/functions.php:54
GuzzleHttp\Client\requestAsync
requestAsync($method, $uri='', array $options=[])
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:149
GuzzleHttp\Client
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:26
GuzzleHttp\Client\send
send(RequestInterface $request, array $options=[])
Definition: paymethod/paypal/vendor/guzzlehttp/guzzle/src/Client.php:129
GuzzleHttp\Promise
Definition: AggregateException.php:2
GuzzleHttp\Cookie\CookieJar
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:10