Passed
Push — master ( b7341c...97f9f4 )
by Dmitry
01:49
created

Request::handle_request_exception()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace UAPAY;
4
5
use UAPAY\Log as Log;
6
use UAPAY\Exception;
7
use Firebase\JWT\JWT;
8
9
abstract class Request
10
{
11
    /**
12
     *      @var object
13
     */
14
    protected $client;
15
16
    /**
17
     *      @var array
18
     */
19
    protected $jwt=array(
20
        'using'         => false,
21
        'UAPAY_pubkey'  => '',
22
        'our_privkey'   => '',
23
    );
24
25
    /**
26
     *      @var array
27
     */
28
    protected $data;
29
30
    /**
31
     *      Constructor
32
     *
33
     *      @param array $options array of options
34
     *      @throws Exception\Data
35
     */
36
    public function __construct($options)
37
    {
38
        // api_url
39
        if ( ! isset($options['api_uri']))
40
        {
41
            throw new Exception\Data('parameter api_uri is not specified');
42
        }
43
44
        $jo = new JWTOptions($options);
45
        $this->jwt = $jo->get();
46
47
        // http client
48
        $this->client = new \GuzzleHttp\Client([
49
            'base_uri'      => $options['api_uri'],
50
            'timeout'       => 2.0,
51
        ]);
52
    }
53
54
    /**
55
     *      get/set data
56
     *
57
     *      @param array $value
58
     *      @return array
59
     */
60
    public function data($value=null)
61
    {
62
        if ($value !== null)
63
        {
64
            $this->data = $this->as_array($value);
65
        }
66
67
        return $this->data;
68
    }
69
70
    /**
71
     *      Cast to string
72
     *
73
     *      @param mixed $value
74
     *      @return string
75
     */
76
    protected function as_string($value=null)
77
    {
78
        return (is_scalar($value))?((is_bool($value))?(($value)?'true':'false'):"$value"):null;
79
    }
80
81
    /**
82
     *      Cast to integer
83
     *
84
     *      @param mixed $value
85
     *      @return integer
86
     */
87
    protected function as_int($value=null)
88
    {
89
        return (is_int($value))?$value:null;
90
    }
91
92
    /**
93
     *      Cast to array
94
     *
95
     *      @param mixed $value
96
     *      @return array
97
     */
98
    protected function as_array($value=null)
99
    {
100
        return (is_array($value))?$value:null;
101
    }
102
103
    /**
104
     *      Returns params set
105
     *
106
     *      @return array
107
     */
108
    public function get_params()
109
    {
110
        return array();
111
    }
112
113
    /**
114
     *      Returns iat param
115
     *
116
     *      @return integer
117
     */
118
    public function get_param_iat()
119
    {
120
        return time();
121
    }
122
123
    /**
124
     *      Returns the JSON representation of class
125
     *
126
     *      @return string
127
     */
128
    public function get_json()
129
    {
130
        $ar = array(
131
            'params' => $this->get_params()
132
        );
133
        if (isset($this->data))
134
        {
135
            $ar['data'] = $this->data;
136
        }
137
        if ($this->jwt['using'] === true)
138
        {
139
            $payload = $ar;
140
            $payload['iat'] = $this->get_param_iat();
141
            $ar['token'] = $this->token_encode($payload);
142
143
            if (isset($ar['data'])) unset($ar['data']);
144
        }
145
        $json = json_encode($ar, JSON_UNESCAPED_SLASHES);
146
147
        Log::instance()->debug('build JSON:');
148
        Log::instance()->debug($json);
149
150
        return $json;
151
    }
152
153
    /**
154
     *      Get private key for encode payload
155
     *
156
     *      @return string
157
     */
158
    protected function own_private_key()
159
    {
160
        return (new Key())->get($this->jwt['our_privkey'], 'private');
161
    }
162
163
    /**
164
     *      Encode payload and return token
165
     *
166
     *      @param array $payload
167
     *      @throws Exception\JSON
168
     *      @return string Token
169
     */
170 View Code Duplication
    protected function token_encode($payload)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
    {
172
        Log::instance()->debug('encode payload:');
173
        Log::instance()->debug(print_r($payload, true));
174
        try
175
        {
176
            $token = JWT::encode($payload, $this->own_private_key(), 'RS512');
177
        }
178
        catch (\Exception $e)
179
        {
180
            Log::instance()->error($e->getMessage().PHP_EOL.$e->getTraceAsString());
181
            throw new Exception\JSON('unable to create JWT token', $e);
182
        }
183
184
        return $token;
185
    }
186
187
    /**
188
     *      Send request to UAPAY
189
     *
190
     *      @return object Response
191
     */
192
    public function send()
193
    {
194
        Log::instance()->add('send request to '.$this->api_path);
195
        try
196
        {
197
            $httpresponse = $this->client->request('POST', $this->api_path, [
198
                'headers' => [
199
                    'User-Agent'    => 'php_UAPAY/1.0',
200
                    'Content-Type'  => 'application/json'
201
                ],
202
                'body' => $this->get_json()
203
            ]);
204
            $body = $httpresponse->getBody()->getContents();
205
            Log::instance()->debug('got response:'.PHP_EOL.$body);
206
            return new $this->response_class($body, $this->jwt);
207
        }
208
        catch (\GuzzleHttp\Exception\RequestException $e)
209
        {
210
            $this->handle_request_exception($e);
211
        }
212
    }
213
214
    /**
215
     *      Handle request exception
216
     *
217
     *      @param \GuzzleHttp\Exception\RequestException $e
218
     *      @throws Exception\Transfer
219
     */
220
    protected function handle_request_exception($e)
221
    {
222
        Log::instance()->debug('request:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->getRequest()));
223
        if ($e->hasResponse()) {
224
            Log::instance()->debug('response:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->getResponse()));
225
        }
226
227
        throw new Exception\Transfer('an error occured during a transfer');
228
    }
229
}
230