Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.48% covered (success)
93.48%
43 / 46
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Request
93.48% covered (success)
93.48%
43 / 46
71.43% covered (warning)
71.43%
5 / 7
12.04
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 __get
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 makeRequest
90.91% covered (success)
90.91%
20 / 22
0.00% covered (danger)
0.00%
0 / 1
5.02
 setEndpoint
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 call
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 addHeaders
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace LDC\LDCCRM\Transport;
4
5use GuzzleHttp\Client;
6use GuzzleHttp\Psr7\Request as Psr7Request;
7use GuzzleHttp\Psr7\Utils as Psr7Utils;
8use GuzzleHttp\RequestOptions;
9use GuzzleHttp\Utils as GuzzleHttpUtils;
10use LDC\LDCCRM\Enums\HttpMethods;
11use LDC\LDCCRM\Utils;
12use Psr\Http\Message\ResponseInterface;
13
14/**
15 * The UWIL Flucollector request
16 * Contains the http method, the requested url and data to pass
17 *
18 * @property \LDC\LDCCRM\Enums\HttpMethods $method readonly method
19 * @property string $uri readonly uri
20 * @property array $headers headers
21 * @property array $data readonly data
22 *
23 * @package LDCCrmClient
24 * @subpackage transport
25 */
26class Request
27{
28    /**
29     * GuzzleHttp client
30     *
31     * @var \GuzzleHttp\Client
32     */
33    private Client $client;
34
35    /**
36     * The http method
37     *
38     * @var \LDC\LDCCRM\Enums\HttpMethods
39     */
40    protected HttpMethods $method;
41
42    /**
43     * The http url
44     *
45     * @var string
46     */
47    protected string $uri;
48
49    /**
50     * Data to pass to the http headers
51     *
52     * @var array
53     */
54    protected array $headers = [];
55
56    /**
57     * Data to pass to the http body
58     *
59     * @var array
60     */
61    protected array $data = [];
62
63    /**
64     * Guzzle request
65     *
66     * @var callable the returns \GuzzleHttp\Psr7\Request
67     */
68    private \Closure $request;
69
70    /**
71     * The Api endpoint
72     *
73     * @var string
74     */
75    private string $endpoint;
76
77    /**
78     * Request
79     *
80     * @param \LDC\LDCCRM\Enums\HttpMethods $method
81     * @param string                        $uri
82     * @param array                         $headers
83     * @param array                         $data
84     */
85    public function __construct(
86        HttpMethods $method,
87        string $uri,
88        array $headers = [],
89        #[\SensitiveParameter] array $data = []
90    ) {
91        $this->method  = $method;
92        $this->uri     = $uri;
93        $this->data    = $data;
94        $this->headers = $headers;
95        $this->client  = new Client([
96            RequestOptions::HEADERS => [
97                'User-Agent' => sprintf(
98                    'LDC CRM Client v%s',
99                    Utils::getPackageInfo()['version']
100                )
101            ]
102        ]);
103    }
104
105    /**
106     * Generic accessor
107     *
108     * @param string $field
109     * @return mixed|null
110     */
111    public function __get(string $field)
112    {
113        if (\in_array($field, ['method', 'uri', 'data'])) {
114            return $this->{$field};
115        }
116        return null;
117    }
118
119    /**
120     * make the guzzle request
121     *
122     * @return void
123     */
124    private function makeRequest(): void
125    {
126        $this->request = function () {
127            $uri = $this->uri;
128            // * If query merge query and data, set data to empty.
129            if ($this->method->equals(HttpMethods::get)) {
130                // * Merge query in url with Data
131                $q     = \parse_url($uri, \PHP_URL_QUERY) ?? '';
132                $q     = \strpos($q, '&') !== false ? explode('&', $q) : ($q ? [$q] : []);
133                $query = [];
134                foreach ($q as $qParam) {
135                    $qParam = explode('=', $qParam, 2);
136
137                    $query[$qParam[0]] = $qParam[1];
138                }
139                // * Remove query part.
140                $uri = strtok($uri, '?');
141                // * Append build query
142                $uri = sprintf("%s?%s", $uri, http_build_query(array_merge($query, $this->data)));
143
144                $this->data = [];
145            }
146            $request = new Psr7Request(
147                \strtoupper($this->method->name()),
148                sprintf('%s/%s', $this->endpoint, $uri),
149                $this->headers
150            );
151            $request = Psr7Utils::modifyRequest($request, [
152                'body' => GuzzleHttpUtils::jsonEncode($this->data)
153            ]);
154            return $request;
155        };
156    }
157
158    /**
159     * Set the api endpoint to the request
160     *
161     * @param string $endpoint
162     * @return void
163     */
164    public function setEndpoint(string $endpoint): void
165    {
166        $this->endpoint = $endpoint;
167    }
168
169    /**
170     * Make the Http request
171     *
172     * @return ResponseInterface
173     */
174    public function call(): ResponseInterface
175    {
176        $this->makeRequest();
177        /** @var \GuzzleHttp\Psr7\Request */
178        $request = ($this->request)();
179        return $this->client->send($request, [
180            // ! Do not throw HTTP Exceptions.
181            'http_errors' => false,
182            'allow_redirects' => false
183        ]);
184    }
185
186    /**
187     * Add headers to the request
188     *
189     * @param array $headers
190     * @return void
191     */
192    public function addHeaders(#[\SensitiveParameter] array $headers)
193    {
194        $this->headers = \array_merge($this->headers, $headers);
195    }
196
197    /**
198     * Add data to the request
199     *
200     * @param array $data
201     * @return void
202     */
203    public function addData(#[\SensitiveParameter] array $data)
204    {
205        $this->data = \array_merge($this->data, $data);
206    }
207}