Completed
Push — master ( 8e0025...04518a )
by
05:55
created

Api::hydrateResponse()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0
cc 4
eloc 11
nc 4
nop 1
1
<?php
2
3
/*
4
 * This file is part of the PhpMob package.
5
 *
6
 * (c) Ishmael Doss <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace PhpMob\Omise;
13
14
use PhpMob\Omise\Client\HttpClientInterface;
15
use PhpMob\Omise\Exception\InvalidRequestArgumentException;
16
use PhpMob\Omise\Exception\InvalidResponseException;
17
use PhpMob\Omise\Domain\Error;
18
use PhpMob\Omise\Hydrator\Hydration;
19
use PhpMob\Omise\Hydrator\HydrationInterface;
20
use Psr\Http\Message\ResponseInterface;
21
use Symfony\Component\OptionsResolver\OptionsResolver;
22
23
/**
24
 * @author Ishmael Doss <[email protected]>
25
 */
26
abstract class Api
27
{
28
    /**
29
     * @var bool
30
     */
31
    protected $isSensitive = false;
32
33
    /**
34
     * @var HttpClientInterface
35
     */
36
    protected $httpClient;
37
38
    /**
39
     * @var array
40
     */
41
    protected $options;
42
43
    /**
44
     * @var HydrationInterface
45
     */
46
    private $hydration;
47
48
    /**
49
     * @param HttpClientInterface $httpClient
50
     * @param array $options
51
     * @param HydrationInterface $hydration
52
     */
53
    public function __construct(HttpClientInterface $httpClient, array $options, HydrationInterface $hydration = null)
54
    {
55
        $this->httpClient = $httpClient;
56
57
        $resolver = new OptionsResolver();
58
        $this->configureOptions($resolver);
59
60
        $this->options = $resolver->resolve($options);
61
        $this->hydration = $hydration ?: new Hydration();
62
        $this->isSensitive = $this->options['sensitive'];
63
    }
64
65
    /**
66
     * @param OptionsResolver $resolver
67
     */
68
    protected function configureOptions(OptionsResolver $resolver)
69
    {
70
        $resolver->setRequired(['secret_key', 'public_key', 'sandbox']);
71
72
        $resolver->setAllowedTypes('secret_key', 'string');
73
        $resolver->setAllowedTypes('public_key', 'string');
74
        $resolver->setAllowedTypes('sandbox', 'boolean');
75
76
        $resolver->setDefault('sensitive', $this->isSensitive);
77
    }
78
79
    /**
80
     * @return string
81
     */
82
    protected function getAuthorizationKey()
83
    {
84
        return 'Basic '.base64_encode($this->options[$this->isSensitive ? 'public_key' : 'secret_key'].':');
85
    }
86
87
    /**
88
     * @return string
89
     */
90
    protected function getApiServer()
91
    {
92
        return $this->isSensitive ? OmiseApi::OMISE_VAULT_ENDPOINT : OmiseApi::OMISE_ENDPOINT;
93
    }
94
95
    /**
96
     * @param string $method
97
     * @param string $path
98
     * @param array $data
99
     * @param array $headers
100
     *
101
     * @return mixed|Model
102
     * @throws InvalidResponseException
103
     */
104
    protected function doRequest($method, $path, array $data = [], array $headers = [])
105
    {
106
        $headers = array_merge(['Authorization' => $this->getAuthorizationKey()], $headers);
107
108
        if ('GET' !== strtoupper($method)) {
109
            $data = array_merge($data, ['livemode' => $this->options['sandbox']]);
110
            $headers = array_merge(['Content-Type' => 'application/json; charset=utf-8'], $headers);
111
        }
112
113
        $uri = preg_replace('/([^:])(\/{2,})/', '$1/', $this->getApiServer().$path);
114
        $response = $this->httpClient->send($method, $uri, $data, $headers);
115
116
        return $this->hydrateResponse($response);
117
    }
118
119
    /**
120
     * @param ResponseInterface $response
121
     *
122
     * @return mixed|Model
123
     * @throws InvalidResponseException
124
     */
125
    protected function hydrateResponse(ResponseInterface $response)
126
    {
127
        $content = $response->getBody()->getContents();
128
129
        // non api error, mock server error.
130
        if (empty($content) && $response->getStatusCode() >= 400) {
131
            $content = json_encode(
132
                [
133
                    'object' => 'error',
134
                    'code' => 'HTTP-'.$response->getStatusCode(),
135
                    'message' => $response->getReasonPhrase(),
136
                ]
137
            );
138
        }
139
140
        $result = $this->hydration->hydrate($content);
141
142
        if ($result instanceof Error) {
143
            throw new InvalidResponseException($result);
144
        }
145
146
        return $result;
147
    }
148
149
    /**
150
     * @param string $id
151
     * @param string $message
152
     *
153
     * @throws InvalidRequestArgumentException
154
     */
155
    protected static function assertNotEmpty($id, $message = 'Id can not be empty.')
156
    {
157
        if (empty($id)) {
158
            throw new InvalidRequestArgumentException($message);
159
        }
160
    }
161
}
162