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|null|\SimpleXMLElement
171
     */
172
    public function unSerialize($data)
173
    {
174
        $type = $this->output_type ? $this->output_type : $this->type;
175
176
        switch ($type) {
177
            case self::TYPE_JSON:
178
                return \GuzzleHttp\json_decode($data);
179
                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...
180
            case self::TYPE_XML:
181
                return simplexml_load_string($data);
182
                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...
183
        }
184
        return $data;
185
    }
186
187
    /**
188
     * @param $param
189
     * @param $message
190
     */
191
    public function addError($param, $message)
192
    {
193
        $this->_errors[$param][] = $message;
194
    }
195
196
    /**
197
     * @param array $data
198
     * @return array
199
     */
200
    protected function beforePrepareData(array $data)
201
    {
202
        return $data;
203
    }
204
205
    /**
206
     * @param $data
207
     * @return string|array
208
     * @throws \Exception
209
     */
210
    protected function prepareData(array $data)
211
    {
212
        $data = $this->beforePrepareData($data);
213
        $data = $this->filter($data);
214
215
        if (!$this->validate($data)) {
216
            throw new \Exception($this->getError());
217
        }
218
        if ($this->method == 'GET') {
219
            return $data;
220
        }
221
        switch ($this->type) {
222
            case self::TYPE_JSON:
223
                $data = \GuzzleHttp\json_encode($data);
224
                break;
225
            case self::TYPE_XML:
226
                throw new \Exception('Xml type is not implemented yet');
227
                break;
228
            case self::TYPE_FORM:
229
                break;
230
            default:
231
                throw new \Exception('Type is not supported');
232
                break;
233
        }
234
        return $data;
235
    }
236
237
    /**
238
     * @throws \Exception
239
     */
240
    public function guzzleOptions()
241
    {
242
        $options = [
243
            'headers' => []
244
        ];
245
        if ($this->proxy) {
246
            $options['proxy'] = $this->proxy;
247
        }
248
        switch ($this->type) {
249
            case self::TYPE_JSON:
250
                $options['headers']['content-type'] = 'application/json';
251
                break;
252
            case self::TYPE_XML:
253
                $options['headers']['content-type'] = 'application/xml';
254
                break;
255
            case self::TYPE_FORM:
256
                $options['headers']['content-type'] = 'application/x-www-form-urlencoded';
257
                break;
258
259
            default:
260
                throw new \Exception('Type is not supported');
261
        }
262
        if (($this->login || $this->password) && $this->useAuth) {
263
            $options['auth'] = [$this->login, $this->password];
264
        }
265
        $this->_guzzleOptions = array_merge($options, $this->_custom_guzzle_options);
266
    }
267
}