Skip to content

Commit ab0e4e4

Browse files
authored
Merge pull request #28 from spotlibs/feature/exploration
runtime exception still write to runtime error log
2 parents d95e078 + 5eef5ee commit ab0e4e4

File tree

20 files changed

+648
-566
lines changed

20 files changed

+648
-566
lines changed

phpunit.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
processUncoveredFiles="true">
2727
<include>
2828
<directory suffix=".php">src</directory>
29+
<file>src/Libraries/Client.php</file>
2930
</include>
3031
<exclude>
3132
<file>src/Exceptions/Handler.php</file>
33+
<file>src/Libraries/Kafka.php</file>
34+
<file>src/Libraries/KafkaCallable.php</file>
3235
<directory suffix=".php">src/Commands</directory>
3336
<directory suffix=".php">src/Facades</directory>
34-
<directory suffix=".php">src/Libraries</directory>
3537
<directory suffix=".php">src/Middlewares</directory>
3638
<directory suffix=".php">src/Providers</directory>
3739
<directory suffix=".php">src/Validations</directory>

public/docs/.gitkeep

Whitespace-only changes.

public/docs/hello.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello world

public/docs/hello2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
spotlibs the php library

src/Dtos/TraitDtos.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
namespace Spotlibs\PhpLib\Dtos;
1717

18+
use ReflectionClass;
19+
1820
/**
1921
* TraitDtos
2022
*
@@ -35,7 +37,16 @@ trait TraitDtos
3537
*/
3638
public function __construct(array $data = [])
3739
{
40+
$reflector = new ReflectionClass(static::class);
3841
foreach ($data as $key => $value) {
42+
if (is_array($value)) {
43+
$prop = $reflector->getProperty($key);
44+
$type = $prop->getType()->getName();
45+
//construct object if type is not array
46+
if ($type != 'array') {
47+
$value = new $type($value);
48+
}
49+
}
3950
$this->{$key} = $value;
4051
}
4152
}

src/Exceptions/Handler.php

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,14 @@ class Handler extends ExceptionHandler
6565
*/
6666
public function report(Throwable $exception)
6767
{
68-
$logData = [
69-
'exception_code' => $exception->getCode(),
70-
'message' => $exception->getMessage(),
71-
'line' => $exception->getLine(),
72-
'file' => $exception->getFile(),
73-
'requestID' => app()->request->header('X-Request-ID') ?? null
74-
];
75-
if (!$exception instanceof ExceptionInterface && !$exception instanceof NotFoundHttpException && !$exception instanceof ValidationException) {
76-
if (!config('app.debug')) {
77-
Log::runtime()->error($logData);
78-
} else {
79-
parent::report($exception);
80-
}
68+
if ((!$exception instanceof ExceptionInterface && !$exception instanceof NotFoundHttpException && !$exception instanceof ValidationException) || $exception instanceof RuntimeException) {
69+
Log::runtime()->error(
70+
[
71+
'code' => $exception->getCode(),
72+
'message' => $exception->getMessage() . 'on line ' . $exception->getLine() . ' of file ' . $exception->getFile(),
73+
'requestID' => app()->request->header('X-Request-ID') ?? null
74+
]
75+
);
8176
}
8277
}
8378

src/Exceptions/StdException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class StdException
5656
* @param mixed $responseData response data
5757
* @param array $validationErrors additional validation error
5858
*
59-
* @return void
59+
* @return ExceptionInterface
6060
*/
6161
public static function create(
6262
string $responseCode,

src/Facades/Queue.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
namespace Spotlibs\PhpLib\Facades;
1717

18+
use DateTime;
1819
use Illuminate\Support\Facades\Queue as BaseQueue;
1920
use Spotlibs\PhpLib\Services\Context;
2021
use Spotlibs\PhpLib\Services\Metadata;
@@ -58,4 +59,32 @@ public static function pushOn(string $queue, object|string $job, mixed $data = '
5859

5960
return parent::pushOn($queue, $job, $data);
6061
}
62+
63+
/**
64+
* Push job to queue
65+
*
66+
* @param string $queue queue name
67+
* @param \DateTimeInterface|\DateInterval|int $delay delay for the job to run
68+
* @param object|string $job instance of a job
69+
* @param mixed $data additional data (optional)
70+
*
71+
* @return mixed
72+
*/
73+
public static function laterOn(string $queue, \DateTimeInterface|\DateInterval|int $delay, object|string $job, mixed $data = ''): mixed
74+
{
75+
$context = app(Context::class);
76+
if ($context) {
77+
$meta = $context->get(Metadata::class);
78+
if ($meta instanceof Metadata) {
79+
if (isset($meta->req_id)) {
80+
$job->taskID = $meta->req_id;
81+
} elseif (isset($meta->task_id)) {
82+
$job->taskID = $meta->task_id;
83+
}
84+
$job->identifier = $meta->identifier;
85+
}
86+
}
87+
88+
return parent::laterOn($queue, $delay, $job, $data);
89+
}
6190
}

src/Libraries/Client.php

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
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 Carbon\Exceptions\InvalidTypeException;
19+
use Exception;
20+
use GuzzleHttp\Client as BaseClient;
21+
use GuzzleHttp\Exception\GuzzleException;
22+
use GuzzleHttp\Psr7\Request;
23+
use GuzzleHttp\RequestOptions;
24+
use Psr\Http\Message\ResponseInterface;
25+
use Spotlibs\PhpLib\Libraries\ClientHelpers\Multipart;
26+
use Symfony\Component\HttpKernel\Exception\HttpException;
27+
28+
/**
29+
* ClientTimeoutUnit
30+
*
31+
* Name for HTTP Client timeout unit
32+
*
33+
* @category HttpClient
34+
* @package Client
35+
* @author Made Mas Adi Winata <m45adiwinata@gmail.com>
36+
* @license https://mit-license.org/ MIT License
37+
* @link https://github.com/spotlibs
38+
*/
39+
class Client extends BaseClient
40+
{
41+
/**
42+
* Timeout in seconds, default is 10 seconds
43+
*
44+
* @var float $timeout
45+
*/
46+
public float $timeout = 10;
47+
/**
48+
* Set to true to enable SSL certificate verification and use the default CA bundle provided by operating system
49+
*
50+
* @var bool $verify
51+
*/
52+
public bool $verify = false;
53+
/**
54+
* Request body, set according to the request
55+
*
56+
* @var array $body
57+
*/
58+
protected array $body = [];
59+
/**
60+
* Request header if only headers are not set in the request. Will be appended on call method
61+
*
62+
* @var array $requestHeaders
63+
*/
64+
protected array $requestHeaders = [];
65+
/**
66+
* Customize response header
67+
*
68+
* @var array $responseHeaders
69+
*/
70+
protected array $responseHeaders = [];
71+
/**
72+
* Body type of the
73+
*
74+
* @var array $responseHeaders
75+
*/
76+
protected string $request_body_type = 'json';
77+
78+
/**
79+
* Create a new Client instance.
80+
*
81+
* @return void
82+
*/
83+
public function __construct()
84+
{
85+
parent::__construct();
86+
}
87+
88+
/**
89+
* Set the timeout for Http Client
90+
*
91+
* @param int $timeout number of desired timeout
92+
*
93+
* @return self
94+
*/
95+
public function setTimeout(float $timeout): self
96+
{
97+
$this->timeout = $timeout;
98+
return $this;
99+
}
100+
101+
/**
102+
* Set verify
103+
*
104+
* @param bool $verify number of desired timeout
105+
*
106+
* @return self
107+
*/
108+
public function setVerify(bool $verify): self
109+
{
110+
$this->verify = $verify;
111+
return $this;
112+
}
113+
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+
150+
/**
151+
* Set request headers in associative array
152+
*
153+
* @param array<string[]> $headers example: ['Content-Type' => ['application/json']]
154+
*
155+
* @return self
156+
*/
157+
public function injectRequestHeader(array $headers): self
158+
{
159+
$this->requestHeaders = $headers;
160+
return $this;
161+
}
162+
163+
/**
164+
* Set response headers in associative array
165+
*
166+
* @param array<string[]> $headers example: ['Content-Type' => ['application/json']]
167+
*
168+
* @return self
169+
*/
170+
public function injectResponseHeader(array $headers): self
171+
{
172+
$this->responseHeaders = $headers;
173+
return $this;
174+
}
175+
176+
/**
177+
* Set the timeout for Http Client
178+
*
179+
* @param Request $request HTTP Request instance
180+
*
181+
* @return ResponseInterface
182+
*/
183+
public function call(Request $request): ResponseInterface
184+
{
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);
194+
foreach ($this->requestHeaders as $key => $header) {
195+
$request->withHeader($key, $header);
196+
}
197+
$response = $this->send($request, $options);
198+
foreach ($this->responseHeaders as $key => $header) {
199+
$response->withHeader($key, $header);
200+
}
201+
return $response;
202+
}
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+
}
271+
}

0 commit comments

Comments
 (0)