Passed
Push — master ( 505d49...e3b573 )
by Dmitry
01:50
created

Request::__construct()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 1
nop 1
dl 0
loc 15
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 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:');
0 ignored issues
show
Bug introduced by
The method debug() does not exist on UAPAY\Log. ( Ignorable by Annotation )

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

147
        Log::instance()->/** @scrutinizer ignore-call */ debug('build JSON:');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
148
        Log::instance()->debug($json);
149
150
        return $json;
151
    }
152
153
    /**
154
     *      Get file contents
155
     *
156
     *      @param string $fname
157
     *      @return string
158
     */
159
    protected function file_get_contents($fname)
160
    {
161
        return file_get_contents($fname);
162
    }
163
164
    /**
165
     *      Get private key for encode payload
166
     *
167
     *      @throws Exception\Runtime
168
     *      @return string
169
     */
170 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...
171
    {
172
        // check private key file
173
        if ( ! file_exists($this->jwt['our_privkey']))
174
        {
175
            throw new Exception\Runtime('The file with the private key was not find!');
176
        }
177
178
        // load private key file
179
        $private_key = $this->file_get_contents($this->jwt['our_privkey']);
180
        if ($private_key === FALSE)
181
        {
182
            throw new Exception\Runtime('The file with the private key was not read!');
183
        }
184
185
        return $private_key;
186
    }
187
188
    /**
189
     *      Encode payload and return token
190
     *
191
     *      @param array $payload
192
     *      @throws Exception\JSON
193
     *      @return string Token
194
     */
195 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...
196
    {
197
        Log::instance()->debug('encode payload:');
198
        Log::instance()->debug(print_r($payload, true));
199
        try
200
        {
201
            $token = JWT::encode($payload, $this->own_private_key(), 'RS512');
202
        }
203
        catch (\Exception $e)
204
        {
205
            Log::instance()->error($e->getMessage().PHP_EOL.$e->getTraceAsString());
0 ignored issues
show
Bug introduced by
The method error() does not exist on UAPAY\Log. ( Ignorable by Annotation )

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

205
            Log::instance()->/** @scrutinizer ignore-call */ error($e->getMessage().PHP_EOL.$e->getTraceAsString());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
206
            throw new Exception\JSON('unable to create JWT token', $e);
207
        }
208
209
        return $token;
210
    }
211
212
    /**
213
     *      Send request to UAPAY
214
     *
215
     *      @throws Exception\Transfer
216
     *      @return object Response
217
     */
218
    public function send()
219
    {
220
        Log::instance()->add('send request to '.$this->api_path);
0 ignored issues
show
Bug introduced by
The method add() does not exist on UAPAY\Log. ( Ignorable by Annotation )

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

220
        Log::instance()->/** @scrutinizer ignore-call */ add('send request to '.$this->api_path);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
221
        try
222
        {
223
            $httpresponse = $this->client->request('POST', $this->api_path, [
224
                'headers' => [
225
                    'User-Agent'    => 'php_UAPAY/1.0',
226
                    'Content-Type'  => 'application/json'
227
                ],
228
                'body' => $this->get_json()
229
            ]);
230
            $body = $httpresponse->getBody()->getContents();
231
            Log::instance()->debug('got response:'.PHP_EOL.$body);
232
            $response = new $this->response_class($body, $this->jwt);
233
        }
234
        catch (\GuzzleHttp\Exception\TransferException $e)
235
        {
236
            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

236
            Log::instance()->debug('request:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->/** @scrutinizer ignore-call */ getRequest()));
Loading history...
237
            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

237
            if ($e->/** @scrutinizer ignore-call */ hasResponse()) {
Loading history...
238
                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

238
                Log::instance()->debug('response:'.PHP_EOL.\GuzzleHttp\Psr7\str($e->/** @scrutinizer ignore-call */ getResponse()));
Loading history...
239
            }
240
241
            throw new Exception\Transfer('an error occured during a transfer');
242
        }
243
244
        return $response;
245
    }
246
}
247