Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
30.00% covered (danger)
30.00%
3 / 10
CRAP
55.06% covered (warning)
55.06%
49 / 89
Request
0.00% covered (danger)
0.00%
0 / 1
30.00% covered (danger)
30.00%
3 / 10
219.76
55.06% covered (warning)
55.06%
49 / 89
 __call
100.00% covered (success)
100.00%
1 / 1
7
100.00% covered (success)
100.00%
15 / 15
 getParameters
0.00% covered (danger)
0.00%
0 / 1
3.01
88.89% covered (success)
88.89%
8 / 9
 setQueryContent
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 setOutputTypeContent
0.00% covered (danger)
0.00%
0 / 1
5.39
75.00% covered (success)
75.00%
6 / 8
 checkFile
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 6
 convertDataForMultipart
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 13
 getOutputType
0.00% covered (danger)
0.00%
0 / 1
5.07
85.71% covered (success)
85.71%
6 / 7
 getHeaders
0.00% covered (danger)
0.00%
0 / 1
6.22
81.82% covered (success)
81.82%
9 / 11
 setHeaders
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 createObject
0.00% covered (danger)
0.00%
0 / 1
132
0.00% covered (danger)
0.00%
0 / 15
1<?php
2
3namespace Qmp\Laravel\MicroService\Client\Tools;
4
5use Illuminate\Http\UploadedFile;
6use Illuminate\Support\Collection;
7use Illuminate\Support\Facades\Log;
8use Qmp\Laravel\MicroService\Client\Client;
9use Qmp\Laravel\MicroService\Client\Exceptions\ClientException;
10
11class Request
12{
13    /**
14     * DEFAULT OPTIONS
15     */
16    const HEADERS = [
17        'Accept'        => 'application/json',
18    ];
19
20    /**
21     * METHODS
22     */
23    const METHOD_GET = 'GET';
24    const METHOD_POST = 'POST';
25    const METHOD_PUT = 'PUT';
26    const METHOD_DELETE = 'DELETE';
27
28
29    /**
30     * @var array request options
31     */
32    private $request = [
33        'url' => null,
34        'token' => null,
35        'userid' => null,
36        'systemtoken' => null,
37        'authtype' => null,
38
39        // Query info
40        'method' => self::METHOD_GET,
41        'path' => '',
42        'callback' => null,
43
44        // Parameters
45        'headers' => self::HEADERS,
46        'jsonbody' => true,
47        'query' => null,
48        'body' => null,
49        'multipart' => null,
50        'timeout' => 60,
51    ];
52
53    /**
54     * @param $method
55     * @param array $arguments
56     * @return mixed|bool|Request
57     * @throws ClientException
58     */
59    public function __call($method, array $arguments)
60    {
61        $prefix = substr($method, 0, 3);
62        $field = strtolower(substr($method, 3));
63
64        if (!in_array($field, array_keys($this->request))) {
65            throw new ClientException('Field ' . $field . ' not exist', 31);
66        }
67
68        switch ($prefix) {
69            case 'get':
70                return $this->request[$field];
71            case 'set':
72                if (count($arguments) < 1) {
73                    throw new ClientException('The call of ' . $method . ' must have an argument', 33);
74                }
75
76                $this->request[$field] = reset($arguments);
77                return $this;
78            case 'has':
79                return $this->request[$field] !== null;
80
81            default:
82                throw new ClientException('Method ' . $prefix  . ' is not allowed', 32);
83        }
84    }
85
86    /**
87     * @return array all needed parameters formatted to guzzle send
88     */
89    public function getParameters()
90    {
91        $parameters =  [
92            'base_uri' => $this->getUrl(),
93            'http_errors' => false,
94            'headers' => $this->getHeaders()
95        ];
96
97        if ($this->getMethod() === self::METHOD_PUT) {
98            $parameters['_method'] = 'PUT';
99        }
100
101        $parameters = $this->setQueryContent($parameters);
102        $parameters = $this->setOutputTypeContent($parameters);
103
104        if ($this->hasTimeout()) {
105            $parameters['timeout'] = $this->getTimeout();
106        }
107
108        return $parameters;
109    }
110
111    /**
112     * @param array $parameters
113     * @return array
114     */
115    private function setQueryContent(array $parameters)
116    {
117        if ($this->hasQuery()) {
118            $parameters['query'] = $this->getQuery();
119        }
120
121        return $parameters;
122    }
123
124    /**
125     * @param array $parameters
126     * @return array
127     */
128    private function setOutputTypeContent(array $parameters)
129    {
130        $outputType = $this->getOutputType();
131        if ($this->hasBody()) {
132            $data = $outputType === 'multipart' ? $this->convertDataForMultipart($this->getBody()) : $this->getBody();
133            $parameters[$outputType] = $data;
134        } else {
135            if ($this->hasMultipart()) {
136                $data = $outputType === 'multipart' ? $this->convertDataForMultipart($this->getMultipart()) : $this->getMultipart();
137                $parameters[$outputType] = $data;
138            }
139        }
140
141        return $parameters;
142    }
143
144    /**
145     * @param Collection $collection
146     * @param string $key
147     * @return \lluminate\Support\Collection;
148     */
149    private function checkFile(Collection $collection)
150    {
151        $file = $collection->get('contents');
152        if (is_a($file, UploadedFile::class)) {
153            return $collection->merge([
154                'contents' => fopen($file->getRealPath(), 'r'),
155                'filename' => $file->getClientOriginalName()
156            ]);
157        };
158        return $collection;
159    }
160
161    /**
162     * @return \Illuminate\Support\Collection
163     */
164    private function  convertDataForMultipart(array $data)
165    {
166        $return = collect();
167
168        collect($data)->each(function ($value, $key) use ($return) {
169            if (is_array($value)) {
170                collect($value)->each(function ($value, $valueKey) use ($key, $return) {
171                    $temp = $this->checkFile(collect([
172                        'name' => $key . '[' . $valueKey . ']',
173                        'contents' => $value
174                    ]));
175
176                    $return->push($temp->toArray());
177                });
178            } else {
179                $temp = $this->checkFile(collect(['name' => $key, 'contents' => $value]));
180                $return->push($temp->toArray());
181            }
182        });
183
184        return $return->toArray();
185    }
186    
187    /**
188     * @return string get format of body
189     */
190    public function getOutputType()
191    {
192        if ($this->hasJsonBody()) {
193            return 'json';
194        } elseif ($this->getMethod() === self::METHOD_POST || $this->getMethod() === self::METHOD_PUT) {
195            if ($this->hasMultipart()) {
196                return 'multipart';
197            }
198
199            return 'form_params';
200        }
201
202        return 'body';
203    }
204
205    /**
206     * @return array Get request headers
207     */
208    public function getHeaders()
209    {
210        $headers = $this->request['headers'];
211        $headers[Client::KEYWORD_HEADER_REQUEST_ORIGIN] = request()->header('origin');
212
213        if ($this->getToken() !== null) {
214            $headers['Authorization'] = $this->getToken();
215        }
216
217        if ($this->getUserId() !== null) {
218            $headers[Client::KEYWORD_HEADER_REQUEST] = $this->getUserId();
219        }
220
221        if ($this->getSystemToken() !== null && env('TOKEN_SYSTEM_CALL')) {
222            $headers[Client::KEYWORD_HEADER_REQUEST_SYSTEM_CALL] = env('TOKEN_SYSTEM_CALL');
223        }
224
225        if ($this->getAuthType() !== null) {
226            $headers[Client::KEYWORD_HEADER_REQUEST_AUTH_TYPE] = $this->getAuthType();
227        }
228
229        return $headers;
230    }
231
232    public function setHeaders(array $headers)
233    {
234        $this->request['headers'] = array_merge($this->request['headers'], $headers);
235    }
236
237
238    /**
239     * @return array Create Request Object
240     */
241    public static function createObject(string $dockerServiceHostname, string $path, array $parameters = []): Request
242    {
243        $request = new Request();
244        $request->setUrl('http://' . $dockerServiceHostname)
245            ->setPath('api/' . $path);
246
247        if (!empty($parameters['query']) && is_array($parameters['query'])) {
248            $request->setQuery($parameters['query']);
249        }
250        if (!empty($parameters['body']) && is_array($parameters['body'])) {
251            $request->setBody($parameters['body']);
252        }
253        if (!empty($parameters['multipart']) && is_array($parameters['multipart'])) {
254            $request->setJsonBody(null);
255            $request->setMultipart($parameters['multipart']);
256        }
257        if (!empty($parameters['timeout']) && is_int($parameters['timeout'])) {
258            $request->setTimeout($parameters['timeout']);
259        }
260        if (!empty($parameters['headers']) && is_array($parameters['headers'])) {
261            $request->setHeaders($parameters['headers']);
262        }
263
264        return $request;
265    }
266}