Completed
Push — master ( e76da6...3c4e89 )
by Aleksandr
01:31
created

Client.php (2 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace carono\rest;
4
5
use function GuzzleHttp\Psr7\build_query;
6
use GuzzleHttp\Client as GuzzleClient;
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\StreamInterface;
9
10
class Client
11
{
12
    public $login;
13
    public $password;
14
    public $proxy;
15
    public $method = 'GET';
16
    public $postDataInBody = false;
17
    public $useAuth = true;
18
19
    /**
20
     * @var ResponseInterface
21
     */
22
    public $request;
23
24
    const TYPE_JSON = 'json';
25
    const TYPE_XML = 'xml';
26
    const TYPE_FORM = 'form';
27
28
    protected $protocol = 'https';
29
    protected $url = '';
30
    protected $type = 'json';
31
    protected $output_type;
32
    protected $_guzzleOptions = [];
33
    protected $_custom_guzzle_options = [];
34
    protected $_guzzle;
35
    protected $_errors;
36
37
    /**
38
     * Client constructor.
39
     *
40
     * @param array $config
41
     */
42
    public function __construct(array $config = [])
43
    {
44
        $this->_guzzle = new GuzzleClient();
45
        foreach ($config as $prop => $value) {
46
            $this->$prop = $value;
47
        }
48
        $this->init();
49
    }
50
51
    public function init()
52
    {
53
        $this->method = strtoupper($this->method);
54
        if (!in_array($this->method, ['GET', 'POST'])) {
55
            $this->method = 'GET';
56
        }
57
    }
58
59
    /**
60
     * @param bool $asString
61
     * @return string
62
     */
63
    public function getError($asString = true)
64
    {
65
        if (!$asString) {
66
            return $this->_errors;
67
        }
68
        $error = ['Ошибка валидации параметров'];
69
        foreach ($this->_errors as $param => $errors) {
70
            $error[] = $param . ' - ' . join('; ', $errors);
71
        }
72
        return join("\n", $error);
73
    }
74
75
    public function validate(array $data)
76
    {
77
        foreach ($data as $param => $value) {
78
            $this->validateParam($param, $value);
79
        }
80
        return !count($this->_errors);
81
    }
82
83
    /**
84
     * @param array $data
85
     * @return array
86
     */
87
    public function filter(array $data)
88
    {
89
        $result = [];
90
        foreach ($data as $param => $value) {
91
            if (!is_null($filtered = $this->filterParam($param, $value))) {
92
                $result[$param] = $filtered;
93
            }
94
        }
95
        return $result;
96
    }
97
98
    /**
99
     * @param $param
100
     * @param $value
101
     * @return mixed
102
     */
103
    public function filterParam($param, $value)
104
    {
105
        return $value;
106
    }
107
108
    /**
109
     * @param $param
110
     * @param $value
111
     * @return bool
112
     */
113
    public function validateParam($param, $value)
114
    {
115
        return true;
116
    }
117
118
    public function setGuzzleOptions($array)
119
    {
120
        $this->_custom_guzzle_options = $array;
121
    }
122
123
    /**
124
     * @param $url
125
     * @return string
126
     */
127
    protected function buildUrl($url)
128
    {
129
        if (strpos($this->url, '://')) {
130
            return $this->url . ($url ? '/' . $url : '');
131
        } else {
132
            return $this->protocol . '://' . $this->url . ($url ? '/' . $url : '');
133
        }
134
    }
135
136
    /**
137
     * @return GuzzleClient
138
     */
139
    public function getGuzzle()
140
    {
141
        return $this->_guzzle;
142
    }
143
144
    /**
145
     * @param $urlRequest
146
     * @param array $data
147
     * @return string|\stdClass|\SimpleXMLElement
148
     */
149
    public function getContent($urlRequest, $data = [])
150
    {
151
        $options = [];
152
        $this->guzzleOptions();
153
        $url = $this->buildUrl($urlRequest);
154
        $client = $this->getGuzzle();
155
        $data = $this->prepareData($data);
156
        if ($this->method == 'GET') {
157
            $url = $url . (strpos($url, '?') ? '&' : '?') . build_query($data);
158
        } elseif ($this->postDataInBody) {
159
            $options = ['body' => $data];
160
        } else {
161
            $options = ['form_params' => $data];
162
        }
163
        $request = $client->request($this->method, $url, array_merge($options, $this->_guzzleOptions));
164
        $this->request = $request;
165
        return $this->unSerialize($request->getBody()->getContents());
166
    }
167
168
    /**
169
     * @param $data
170
     * @return mixed
171
     */
172
    protected function unSerializeJson($data)
173
    {
174
        return \GuzzleHttp\json_decode($data);
175
    }
176
177
    /**
178
     * @param $data
179
     * @return \SimpleXMLElement
180
     */
181
    protected function unSerializeXml($data)
182
    {
183
        return simplexml_load_string($data);
184
    }
185
186
    /**
187
     * @param $data
188
     * @return mixed|null|\SimpleXMLElement
189
     */
190
    public function unSerialize($data)
191
    {
192
        $type = $this->output_type ? $this->output_type : $this->type;
193
194
        switch ($type) {
195
            case self::TYPE_JSON:
196
                return $this->unSerializeJson($data);
197
                break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
198
            case self::TYPE_XML:
199
                return $this->unSerializeXml($data);
200
                break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
201
        }
202
        return $data;
203
    }
204
205
    /**
206
     * @param $param
207
     * @param $message
208
     */
209
    public function addError($param, $message)
210
    {
211
        $this->_errors[$param][] = $message;
212
    }
213
214
    /**
215
     * @param array $data
216
     * @return array
217
     */
218
    protected function beforePrepareData(array $data)
219
    {
220
        return $data;
221
    }
222
223
    /**
224
     * @param $data
225
     * @return string|array
226
     * @throws \Exception
227
     */
228
    protected function prepareData(array $data)
229
    {
230
        $data = $this->beforePrepareData($data);
231
        $data = $this->filter($data);
232
233
        if (!$this->validate($data)) {
234
            throw new \Exception($this->getError());
235
        }
236
        if ($this->method == 'GET') {
237
            return $data;
238
        }
239
        switch ($this->type) {
240
            case self::TYPE_JSON:
241
                $data = \GuzzleHttp\json_encode($data);
242
                break;
243
            case self::TYPE_XML:
244
                throw new \Exception('Xml type is not implemented yet');
245
                break;
246
            case self::TYPE_FORM:
247
                break;
248
            default:
249
                throw new \Exception('Type is not supported');
250
                break;
251
        }
252
        return $data;
253
    }
254
255
    /**
256
     * @throws \Exception
257
     */
258
    public function guzzleOptions()
259
    {
260
        $options = [
261
            'headers' => []
262
        ];
263
        if ($this->proxy) {
264
            $options['proxy'] = $this->proxy;
265
        }
266
        switch ($this->type) {
267
            case self::TYPE_JSON:
268
                $options['headers']['content-type'] = 'application/json';
269
                break;
270
            case self::TYPE_XML:
271
                $options['headers']['content-type'] = 'application/xml';
272
                break;
273
            case self::TYPE_FORM:
274
                $options['headers']['content-type'] = 'application/x-www-form-urlencoded';
275
                break;
276
277
            default:
278
                throw new \Exception('Type is not supported');
279
        }
280
        if (($this->login || $this->password) && $this->useAuth) {
281
            $options['auth'] = [$this->login, $this->password];
282
        }
283
        $this->_guzzleOptions = array_merge($options, $this->_custom_guzzle_options);
284
    }
285
}