Skip to content

Commit d7333b8

Browse files
authored
Merge pull request #33 from spotlibs/feature/exploration
Client and ClientExternal Library
2 parents b50f423 + aa923c0 commit d7333b8

File tree

6 files changed

+315
-227
lines changed

6 files changed

+315
-227
lines changed

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<php>
2121
<env name="APP_NAME" value="SPOTLIBS_MICROSERVICE"/>
2222
<env name="APP_ENV" value="local"/>
23+
<env name="APP_DEBUG" value="TRUE"/>
2324
</php>
2425

2526
<coverage cacheDirectory=".phpunit.cache/code-coverage"

src/Libraries/Client.php

Lines changed: 3 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,9 @@
1515

1616
namespace Spotlibs\PhpLib\Libraries;
1717

18-
use Carbon\Exceptions\InvalidTypeException;
19-
use Exception;
2018
use GuzzleHttp\Client as BaseClient;
21-
use GuzzleHttp\Exception\GuzzleException;
2219
use GuzzleHttp\Psr7\Request;
23-
use GuzzleHttp\RequestOptions;
2420
use Psr\Http\Message\ResponseInterface;
25-
use Spotlibs\PhpLib\Libraries\ClientHelpers\Multipart;
26-
use Symfony\Component\HttpKernel\Exception\HttpException;
2721

2822
/**
2923
* ClientTimeoutUnit
@@ -111,42 +105,6 @@ public function setVerify(bool $verify): self
111105
return $this;
112106
}
113107

114-
/**
115-
* Set request body
116-
*
117-
* @param array $body number of desired timeout
118-
*
119-
* @return self
120-
*/
121-
public function setRequestBody(array $body): self
122-
{
123-
$this->body = $body;
124-
return $this;
125-
}
126-
127-
/**
128-
* Set request body in associative array
129-
*
130-
* @param string $form_type RequestOptions::FORM_PARAMS|JSON|MULTIPART|QUERY|...
131-
*
132-
* @return self
133-
*/
134-
public function setFormType(string $form_type): self
135-
{
136-
$allowed = [
137-
RequestOptions::FORM_PARAMS,
138-
RequestOptions::JSON,
139-
RequestOptions::MULTIPART,
140-
RequestOptions::QUERY,
141-
RequestOptions::BODY
142-
];
143-
if (!in_array($form_type, $allowed)) {
144-
throw new Exception('form type not allowed. supporting ' . implode(", ", $allowed));
145-
}
146-
$this->request_body_type = $form_type;
147-
return $this;
148-
}
149-
150108
/**
151109
* Set request headers in associative array
152110
*
@@ -182,90 +140,14 @@ public function injectResponseHeader(array $headers): self
182140
*/
183141
public function call(Request $request): ResponseInterface
184142
{
185-
$body = [];
186-
if (!empty($this->body)) {
187-
$this->checkMultipartBody();
188-
$body = [
189-
$this->request_body_type => $this->body
190-
];
191-
}
192-
$options = ['timeout' => $this->timeout];
193-
$options = array_merge($options, $body);
143+
$options = ['timeout' => $this->timeout, 'verify' => $this->verify];
194144
foreach ($this->requestHeaders as $key => $header) {
195-
$request->withHeader($key, $header);
145+
$request = $request->withHeader($key, $header);
196146
}
197147
$response = $this->send($request, $options);
198148
foreach ($this->responseHeaders as $key => $header) {
199-
$response->withHeader($key, $header);
149+
$response = $response->withHeader($key, $header);
200150
}
201151
return $response;
202152
}
203-
204-
/**
205-
* Check and setup multipart request body if form type is multipart
206-
*
207-
* @return void
208-
*/
209-
private function checkMultipartBody(): void
210-
{
211-
if ($this->request_body_type == RequestOptions::MULTIPART) {
212-
$temp = [];
213-
$key_of_contents = [];
214-
foreach ($this->body as $key => $b) {
215-
if (! $b instanceof Multipart) {
216-
throw new InvalidTypeException('Request body does not comply multipart form-data structure');
217-
}
218-
if (is_array($b->contents)) {
219-
$key_of_contents[] = $key;
220-
/**
221-
* Check if contents is array of files
222-
*
223-
* @var array $b->contents
224-
*/
225-
if (isset($b->contents[0]) && $b->contents[0] instanceof \Illuminate\Http\UploadedFile) {
226-
$z = $b->contents;
227-
/**
228-
* Array $b->contents
229-
*
230-
* @var \Illuminate\Http\UploadedFile[] $z
231-
*/
232-
foreach ($z as $v) {
233-
/**
234-
* Multipart
235-
*
236-
* @var \Illuminate\Http\UploadedFile $v multipart
237-
*/
238-
$y = new Multipart(['name' => $b->name . '[]', 'headers' => ['Content-Type' => $v->getMimeType()]]);
239-
$y->contents = fopen($v->getRealPath(), 'r');
240-
array_push($temp, $y->toArray());
241-
}
242-
}
243-
} else {
244-
$x = $this->body[$key];
245-
/**
246-
* Multipart
247-
*
248-
* @var Multipart $x multipart
249-
*/
250-
if ($x->contents instanceof \Illuminate\Http\UploadedFile) {
251-
$z = $x->contents;
252-
/**
253-
* Uploaded file
254-
*
255-
* @var \Illuminate\Http\UploadedFile $z uploaded file
256-
*/
257-
$x->contents = fopen($z->getRealPath(), 'r');
258-
}
259-
$this->body[$key] = $x->toArray();
260-
}
261-
}
262-
if (count($temp) > 0) {
263-
foreach ($key_of_contents as $key) {
264-
unset($this->body[$key]);
265-
}
266-
$this->body = array_values($this->body);
267-
$this->body = array_merge($this->body, $temp);
268-
}
269-
}
270-
}
271153
}

src/Libraries/ClientExternal.php

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
<?php
2+
3+
/**
4+
* PHP version 8
5+
*
6+
* @category Library
7+
* @package Libraries
8+
* @author Made Mas Adi Winata <m45adiwinata@gmail.com>
9+
* @license https://mit-license.org/ MIT License
10+
* @version GIT: 0.3.7
11+
* @link https://github.com/spotlibs
12+
*/
13+
14+
declare(strict_types=1);
15+
16+
namespace Spotlibs\PhpLib\Libraries;
17+
18+
use GuzzleHttp\Client as BaseClient;
19+
use GuzzleHttp\Psr7\MultipartStream;
20+
use GuzzleHttp\Psr7\Request;
21+
use Psr\Http\Message\ResponseInterface;
22+
use Spotlibs\PhpLib\Logs\Log;
23+
24+
/**
25+
* ClientTimeoutUnit
26+
*
27+
* Name for HTTP Client timeout unit
28+
*
29+
* @category HttpClient
30+
* @package Client
31+
* @author Made Mas Adi Winata <m45adiwinata@gmail.com>
32+
* @license https://mit-license.org/ MIT License
33+
* @link https://github.com/spotlibs
34+
*/
35+
class ClientExternal extends BaseClient
36+
{
37+
/**
38+
* Timeout in seconds, default is 10 seconds
39+
*
40+
* @var float $timeout
41+
*/
42+
public float $timeout = 10;
43+
/**
44+
* Set to true to enable SSL certificate verification and use the default CA bundle provided by operating system
45+
*
46+
* @var bool $verify
47+
*/
48+
public bool $verify = false;
49+
/**
50+
* Request body, set according to the request
51+
*
52+
* @var array $body
53+
*/
54+
protected array $body = [];
55+
/**
56+
* Request header if only headers are not set in the request. Will be appended on call method
57+
*
58+
* @var array $requestHeaders
59+
*/
60+
protected array $requestHeaders = [];
61+
/**
62+
* Customize response header
63+
*
64+
* @var array $responseHeaders
65+
*/
66+
protected array $responseHeaders = [];
67+
/**
68+
* Body type of the
69+
*
70+
* @var array $responseHeaders
71+
*/
72+
protected string $request_body_type = 'json';
73+
74+
/**
75+
* Create a new Client instance.
76+
*
77+
* @return void
78+
*/
79+
public function __construct()
80+
{
81+
parent::__construct();
82+
}
83+
84+
/**
85+
* Set the timeout for Http Client
86+
*
87+
* @param float $timeout number of desired timeout
88+
*
89+
* @return self
90+
*/
91+
public function setTimeout(float $timeout): self
92+
{
93+
$this->timeout = $timeout;
94+
return $this;
95+
}
96+
97+
/**
98+
* Set verify
99+
*
100+
* @param bool $verify number of desired timeout
101+
*
102+
* @return self
103+
*/
104+
public function setVerify(bool $verify): self
105+
{
106+
$this->verify = $verify;
107+
return $this;
108+
}
109+
110+
/**
111+
* Set request headers in associative array
112+
*
113+
* @param array<string[]> $headers example: ['Content-Type' => ['application/json']]
114+
*
115+
* @return self
116+
*/
117+
public function injectRequestHeader(array $headers): self
118+
{
119+
$this->requestHeaders = $headers;
120+
return $this;
121+
}
122+
123+
/**
124+
* Set response headers in associative array
125+
*
126+
* @param array<string[]> $headers example: ['Content-Type' => ['application/json']]
127+
*
128+
* @return self
129+
*/
130+
public function injectResponseHeader(array $headers): self
131+
{
132+
$this->responseHeaders = $headers;
133+
return $this;
134+
}
135+
136+
/**
137+
* Set the timeout for Http Client
138+
*
139+
* @param Request $request HTTP Request instance
140+
*
141+
* @return ResponseInterface
142+
*/
143+
public function call(Request $request): ResponseInterface
144+
{
145+
$startime = microtime(true);
146+
$options = ['timeout' => $this->timeout, 'verify' => $this->verify];
147+
foreach ($this->requestHeaders as $key => $header) {
148+
$request = $request->withHeader($key, $header);
149+
}
150+
if (!$request->hasHeader('Content-Type')) {
151+
$request = $request->withHeader('Content-Type', 'application/json');
152+
}
153+
$response = $this->send($request, $options);
154+
foreach ($this->responseHeaders as $key => $header) {
155+
$response = $response->withHeader($key, $header);
156+
}
157+
$elapsed = microtime(true) - $startime;
158+
if (env('APP_DEBUG', false)) {
159+
$request->getBody()->rewind();
160+
if (strlen($reqbody = $request->getBody()->getContents()) > 5000) {
161+
$reqbody = "more than 5000 characters";
162+
}
163+
if (strlen($respbody = $response->getBody()->getContents()) > 5000) {
164+
$respbody = "more than 5000 characters";
165+
}
166+
$logData = [
167+
'host' => $request->getUri()->getHost(),
168+
'url' => $request->getUri()->getPath(),
169+
'request' => [
170+
'headers' => $request->getHeaders(),
171+
'body' => json_decode($reqbody, true)
172+
],
173+
'response' => [
174+
'headers' => $response->getHeaders(),
175+
'body' => json_decode($respbody, true)
176+
],
177+
'responseTime' => round($elapsed * 1000),
178+
'memoryUsage' => memory_get_usage()
179+
];
180+
$response->getBody()->rewind();
181+
Log::activity()->info($logData);
182+
}
183+
return $response;
184+
}
185+
}

src/Libraries/ClientHelpers/Multipart.php

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)