Вход Регистрация
Файл: sngine-v2.8/Script/includes/libs/Stripe/lib/ApiRequestor.php
Строк: 446
<?php

namespace Stripe;

/**
 * Class ApiRequestor.
 */
class ApiRequestor
{
    
/**
     * @var null|string
     */
    
private $_apiKey;

    
/**
     * @var string
     */
    
private $_apiBase;

    
/**
     * @var HttpClientClientInterface
     */
    
private static $_httpClient;

    
/**
     * @var RequestTelemetry
     */
    
private static $requestTelemetry;

    
/**
     * ApiRequestor constructor.
     *
     * @param null|string $apiKey
     * @param null|string $apiBase
     */
    
public function __construct($apiKey null$apiBase null)
    {
        
$this->_apiKey $apiKey;
        if (!
$apiBase) {
            
$apiBase Stripe::$apiBase;
        }
        
$this->_apiBase $apiBase;
    }

    
/**
     * Creates a telemetry json blob for use in 'X-Stripe-Client-Telemetry' headers.
     *
     * @static
     *
     * @param RequestTelemetry $requestTelemetry
     *
     * @return string
     */
    
private static function _telemetryJson($requestTelemetry)
    {
        
$payload = [
            
'last_request_metrics' => [
                
'request_id' => $requestTelemetry->requestId,
                
'request_duration_ms' => $requestTelemetry->requestDuration,
            ],
        ];

        
$result json_encode($payload);
        if (
false !== $result) {
            return 
$result;
        }
        
Stripe::getLogger()->error('Serializing telemetry payload failed!');

        return 
'{}';
    }

    
/**
     * @static
     *
     * @param ApiResource|array|bool|mixed $d
     *
     * @return ApiResource|array|mixed|string
     */
    
private static function _encodeObjects($d)
    {
        if (
$d instanceof ApiResource) {
            return 
UtilUtil::utf8($d->id);
        }
        if (
true === $d) {
            return 
'true';
        }
        if (
false === $d) {
            return 
'false';
        }
        if (
is_array($d)) {
            
$res = [];
            foreach (
$d as $k => $v) {
                
$res[$k] = self::_encodeObjects($v);
            }

            return 
$res;
        }

        return 
UtilUtil::utf8($d);
    }

    
/**
     * @param string     $method
     * @param string     $url
     * @param null|array $params
     * @param null|array $headers
     *
     * @throws ExceptionApiErrorException
     *
     * @return array tuple containing (ApiReponse, API key)
     */
    
public function request($method$url$params null$headers null)
    {
        
$params $params ?: [];
        
$headers $headers ?: [];
        list(
$rbody$rcode$rheaders$myApiKey) =
        
$this->_requestRaw($method$url$params$headers);
        
$json $this->_interpretResponse($rbody$rcode$rheaders);
        
$resp = new ApiResponse($rbody$rcode$rheaders$json);

        return [
$resp$myApiKey];
    }

    
/**
     * @param string $rbody a JSON string
     * @param int $rcode
     * @param array $rheaders
     * @param array $resp
     *
     * @throws ExceptionUnexpectedValueException
     * @throws ExceptionApiErrorException
     */
    
public function handleErrorResponse($rbody$rcode$rheaders$resp)
    {
        if (!
is_array($resp) || !isset($resp['error'])) {
            
$msg "Invalid response object from API: {$rbody} "
              
"(HTTP response code was {$rcode})";

            throw new 
ExceptionUnexpectedValueException($msg);
        }

        
$errorData $resp['error'];

        
$error null;
        if (
is_string($errorData)) {
            
$error self::_specificOAuthError($rbody$rcode$rheaders$resp$errorData);
        }
        if (!
$error) {
            
$error self::_specificAPIError($rbody$rcode$rheaders$resp$errorData);
        }

        throw 
$error;
    }

    
/**
     * @static
     *
     * @param string $rbody
     * @param int    $rcode
     * @param array  $rheaders
     * @param array  $resp
     * @param array  $errorData
     *
     * @return ExceptionApiErrorException
     */
    
private static function _specificAPIError($rbody$rcode$rheaders$resp$errorData)
    {
        
$msg = isset($errorData['message']) ? $errorData['message'] : null;
        
$param = isset($errorData['param']) ? $errorData['param'] : null;
        
$code = isset($errorData['code']) ? $errorData['code'] : null;
        
$type = isset($errorData['type']) ? $errorData['type'] : null;
        
$declineCode = isset($errorData['decline_code']) ? $errorData['decline_code'] : null;

        switch (
$rcode) {
            case 
400:
                
// 'rate_limit' code is deprecated, but left here for backwards compatibility
                // for API versions earlier than 2015-09-08
                
if ('rate_limit' === $code) {
                    return 
ExceptionRateLimitException::factory($msg$rcode$rbody$resp$rheaders$code$param);
                }
                if (
'idempotency_error' === $type) {
                    return 
ExceptionIdempotencyException::factory($msg$rcode$rbody$resp$rheaders$code);
                }

                
// no break
            
case 404:
                return 
ExceptionInvalidRequestException::factory($msg$rcode$rbody$resp$rheaders$code$param);
            case 
401:
                return 
ExceptionAuthenticationException::factory($msg$rcode$rbody$resp$rheaders$code);
            case 
402:
                return 
ExceptionCardException::factory($msg$rcode$rbody$resp$rheaders$code$declineCode$param);
            case 
403:
                return 
ExceptionPermissionException::factory($msg$rcode$rbody$resp$rheaders$code);
            case 
429:
                return 
ExceptionRateLimitException::factory($msg$rcode$rbody$resp$rheaders$code$param);
            default:
                return 
ExceptionUnknownApiErrorException::factory($msg$rcode$rbody$resp$rheaders$code);
        }
    }

    
/**
     * @static
     *
     * @param bool|string $rbody
     * @param int         $rcode
     * @param array       $rheaders
     * @param array       $resp
     * @param string      $errorCode
     *
     * @return ExceptionOAuthOAuthErrorException
     */
    
private static function _specificOAuthError($rbody$rcode$rheaders$resp$errorCode)
    {
        
$description = isset($resp['error_description']) ? $resp['error_description'] : $errorCode;

        switch (
$errorCode) {
            case 
'invalid_client':
                return 
ExceptionOAuthInvalidClientException::factory($description$rcode$rbody$resp$rheaders$errorCode);
            case 
'invalid_grant':
                return 
ExceptionOAuthInvalidGrantException::factory($description$rcode$rbody$resp$rheaders$errorCode);
            case 
'invalid_request':
                return 
ExceptionOAuthInvalidRequestException::factory($description$rcode$rbody$resp$rheaders$errorCode);
            case 
'invalid_scope':
                return 
ExceptionOAuthInvalidScopeException::factory($description$rcode$rbody$resp$rheaders$errorCode);
            case 
'unsupported_grant_type':
                return 
ExceptionOAuthUnsupportedGrantTypeException::factory($description$rcode$rbody$resp$rheaders$errorCode);
            case 
'unsupported_response_type':
                return 
ExceptionOAuthUnsupportedResponseTypeException::factory($description$rcode$rbody$resp$rheaders$errorCode);
            default:
                return 
ExceptionOAuthUnknownOAuthErrorException::factory($description$rcode$rbody$resp$rheaders$errorCode);
        }
    }

    
/**
     * @static
     *
     * @param null|array $appInfo
     *
     * @return null|string
     */
    
private static function _formatAppInfo($appInfo)
    {
        if (
null !== $appInfo) {
            
$string $appInfo['name'];
            if (
null !== $appInfo['version']) {
                
$string .= '/' $appInfo['version'];
            }
            if (
null !== $appInfo['url']) {
                
$string .= ' (' $appInfo['url'] . ')';
            }

            return 
$string;
        }

        return 
null;
    }

    
/**
     * @static
     *
     * @param string $apiKey
     * @param null   $clientInfo
     *
     * @return array
     */
    
private static function _defaultHeaders($apiKey$clientInfo null)
    {
        
$uaString 'Stripe/v1 PhpBindings/' Stripe::VERSION;

        
$langVersion PHP_VERSION;
        
$uname_disabled in_array('php_uname'explode(','ini_get('disable_functions')), true);
        
$uname $uname_disabled '(disabled)' php_uname();

        
$appInfo Stripe::getAppInfo();
        
$ua = [
            
'bindings_version' => Stripe::VERSION,
            
'lang' => 'php',
            
'lang_version' => $langVersion,
            
'publisher' => 'stripe',
            
'uname' => $uname,
        ];
        if (
$clientInfo) {
            
$ua array_merge($clientInfo$ua);
        }
        if (
null !== $appInfo) {
            
$uaString .= ' ' self::_formatAppInfo($appInfo);
            
$ua['application'] = $appInfo;
        }

        return [
            
'X-Stripe-Client-User-Agent' => json_encode($ua),
            
'User-Agent' => $uaString,
            
'Authorization' => 'Bearer ' $apiKey,
        ];
    }

    
/**
     * @param string $method
     * @param string $url
     * @param array $params
     * @param array $headers
     *
     * @throws ExceptionAuthenticationException
     * @throws ExceptionApiConnectionException
     *
     * @return array
     */
    
private function _requestRaw($method$url$params$headers)
    {
        
$myApiKey $this->_apiKey;
        if (!
$myApiKey) {
            
$myApiKey Stripe::$apiKey;
        }

        if (!
$myApiKey) {
            
$msg 'No API key provided.  (HINT: set your API key using '
              
'"Stripe::setApiKey(<API-KEY>)".  You can generate API keys from '
              
'the Stripe web interface.  See https://stripe.com/api for '
              
'details, or email support@stripe.com if you have any questions.';

            throw new 
ExceptionAuthenticationException($msg);
        }

        
// Clients can supply arbitrary additional keys to be included in the
        // X-Stripe-Client-User-Agent header via the optional getUserAgentInfo()
        // method
        
$clientUAInfo null;
        if (
method_exists($this->httpClient(), 'getUserAgentInfo')) {
            
$clientUAInfo $this->httpClient()->getUserAgentInfo();
        }

        
$absUrl $this->_apiBase $url;
        
$params self::_encodeObjects($params);
        
$defaultHeaders $this->_defaultHeaders($myApiKey$clientUAInfo);
        if (
Stripe::$apiVersion) {
            
$defaultHeaders['Stripe-Version'] = Stripe::$apiVersion;
        }

        if (
Stripe::$accountId) {
            
$defaultHeaders['Stripe-Account'] = Stripe::$accountId;
        }

        if (
Stripe::$enableTelemetry && null !== self::$requestTelemetry) {
            
$defaultHeaders['X-Stripe-Client-Telemetry'] = self::_telemetryJson(self::$requestTelemetry);
        }

        
$hasFile false;
        foreach (
$params as $k => $v) {
            if (
is_resource($v)) {
                
$hasFile true;
                
$params[$k] = self::_processResourceParam($v);
            } elseif (
$v instanceof CURLFile) {
                
$hasFile true;
            }
        }

        if (
$hasFile) {
            
$defaultHeaders['Content-Type'] = 'multipart/form-data';
        } else {
            
$defaultHeaders['Content-Type'] = 'application/x-www-form-urlencoded';
        }

        
$combinedHeaders array_merge($defaultHeaders$headers);
        
$rawHeaders = [];

        foreach (
$combinedHeaders as $header => $value) {
            
$rawHeaders[] = $header ': ' $value;
        }

        
$requestStartMs UtilUtil::currentTimeMillis();

        list(
$rbody$rcode$rheaders) = $this->httpClient()->request(
            
$method,
            
$absUrl,
            
$rawHeaders,
            
$params,
            
$hasFile
        
);

        if (isset(
$rheaders['request-id'], $rheaders['request-id'][0])) {
            
self::$requestTelemetry = new RequestTelemetry(
                
$rheaders['request-id'][0],
                
UtilUtil::currentTimeMillis() - $requestStartMs
            
);
        }

        return [
$rbody$rcode$rheaders$myApiKey];
    }

    
/**
     * @param resource $resource
     *
     * @throws ExceptionInvalidArgumentException
     *
     * @return CURLFile|string
     */
    
private function _processResourceParam($resource)
    {
        if (
'stream' !== get_resource_type($resource)) {
            throw new 
ExceptionInvalidArgumentException(
                
'Attempted to upload a resource that is not a stream'
            
);
        }

        
$metaData stream_get_meta_data($resource);
        if (
'plainfile' !== $metaData['wrapper_type']) {
            throw new 
ExceptionInvalidArgumentException(
                
'Only plainfile resource streams are supported'
            
);
        }

        
// We don't have the filename or mimetype, but the API doesn't care
        
return new CURLFile($metaData['uri']);
    }

    
/**
     * @param string $rbody
     * @param int    $rcode
     * @param array  $rheaders
     *
     * @throws ExceptionUnexpectedValueException
     * @throws ExceptionApiErrorException
     *
     * @return array
     */
    
private function _interpretResponse($rbody$rcode$rheaders)
    {
        
$resp json_decode($rbodytrue);
        
$jsonError json_last_error();
        if (
null === $resp && JSON_ERROR_NONE !== $jsonError) {
            
$msg "Invalid response body from API: {$rbody} "
              
"(HTTP response code was {$rcode}, json_last_error() was {$jsonError})";

            throw new 
ExceptionUnexpectedValueException($msg$rcode);
        }

        if (
$rcode 200 || $rcode >= 300) {
            
$this->handleErrorResponse($rbody$rcode$rheaders$resp);
        }

        return 
$resp;
    }

    
/**
     * @static
     *
     * @param HttpClientClientInterface $client
     */
    
public static function setHttpClient($client)
    {
        
self::$_httpClient $client;
    }

    
/**
     * @static
     *
     * Resets any stateful telemetry data
     */
    
public static function resetTelemetry()
    {
        
self::$requestTelemetry null;
    }

    
/**
     * @return HttpClientClientInterface
     */
    
private function httpClient()
    {
        if (!
self::$_httpClient) {
            
self::$_httpClient HttpClientCurlClient::instance();
        }

        return 
self::$_httpClient;
    }
}
Онлайн: 0
Реклама