Passed
Push — master ( 5b937c...6d705d )
by Dmitry
01:38
created

Request::file_get_contents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
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 array
117
     */
118
    public function get_param_iat()
119
    {
120
        return time();
0 ignored issues
show
Bug Best Practice introduced by
The expression return time() returns the type integer which is incompatible with the documented return type array.
Loading history...
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
     *      @throws Exception\Runtime
157
     *      @return string
158
     */
159 View Code Duplication
    protected function own_private_key()
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...
160
    {
161
        try
162
        {
163
            $key = new Key();
164
            $private_key = $key->get($this->jwt['our_privkey']);
165
        }
166
        catch (\Exception $e)
167
        {
168
            throw new Exception\Runtime('The file with the private key was '.$e->getMessage().'!');
169
        }
170
171
        return $private_key;
172
    }
173
174
    /**
175
     *      Encode payload and return token
176
     *
177
     *      @param array $payload
178
     *      @throws Exception\JSON
179
     *      @return string Token
180
     */
181 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...
182
    {
183
        Log::instance()->debug('encode payload:');
184
        Log::instance()->debug(print_r($payload, true));
185
        try
186
        {
187
            $token = JWT::encode($payload, $this->own_private_key(), 'RS512');
188
        }
189
        catch (\Exception $e)
190
        {
191
            Log::instance()->error($e->getMessage().PHP_EOL.$e->getTraceAsString());
192
            throw new Exception\JSON('unable to create JWT token', $e);
193
        }
194
195
        return $token;
196
    }
197
198
    /**
199
     *      Send request to UAPAY
200
     *
201
     *      @throws Exception\Transfer
202
     *      @return object Response
203
     */
204
    public function send()
205
    {
206
        Log::instance()->add('send request to '.$this->api_path);
207
        try
208
        {
209
            $httpresponse = $this->client->request('POST', $this->api_path, [
210
                'headers' => [
211
                    'User-Agent'    => 'php_UAPAY/1.0',
212
                    'Content-Type'  => 'application/json'
213
                ],
214
                'body' => $this->get_json()
215
            ]);
216
            $body = $httpresponse->getBody()->getContents();
217
            Log::instance()->debug('got response:'.PHP_EOL.$body);
218
            $response = new $this->response_class($body, $this->jwt);
219
        }
220
        catch (\GuzzleHttp\Exception\TransferException $e)
221
        {
222
            Log::instance()->debug('request:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->getRequest()));
0 ignored issues
show
introduced by
The method getRequest() does not exist on GuzzleHttp\Exception\TransferException. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

222
            Log::instance()->debug('request:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->/** @scrutinizer ignore-call */ getRequest()));
Loading history...
223
            if ($e->hasResponse()) {
0 ignored issues
show
introduced by
The method hasResponse() does not exist on GuzzleHttp\Exception\TransferException. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

223
            if ($e->/** @scrutinizer ignore-call */ hasResponse()) {
Loading history...
224
                Log::instance()->debug('response:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->getResponse()));
0 ignored issues
show
introduced by
The method getResponse() does not exist on GuzzleHttp\Exception\TransferException. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
                Log::instance()->debug('response:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->/** @scrutinizer ignore-call */ getResponse()));
Loading history...
225
            }
226
227
            throw new Exception\Transfer('an error occured during a transfer');
228
        }
229
230
        return $response;
231
    }
232
}
233