Skip to content

Commit cb01966

Browse files
committed
refactor: Accessing response
1 parent 17573e9 commit cb01966

2 files changed

Lines changed: 161 additions & 33 deletions

File tree

src/Adapter/Formatter/Response.php

Lines changed: 120 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,160 @@
33
namespace Reactmore\SupportAdapter\Adapter\Formatter;
44

55
use JsonSerializable;
6+
use ArrayAccess;
67

78
/**
8-
* API Response Wrapper Class
9+
* Class Response
10+
*
11+
* API Response Wrapper Class.
12+
* Provides a default array-like response with the ability to convert
13+
* to object or JSON format. Implements ArrayAccess for convenient
14+
* array-like access to response properties.
15+
*
16+
* @package Reactmore\SupportAdapter\Adapter\Formatter
917
*/
10-
class Response implements JsonSerializable
18+
class Response implements JsonSerializable, ArrayAccess
1119
{
20+
/**
21+
* @var array The underlying response data.
22+
*/
1223
private array $response;
1324

1425
/**
15-
* Constructor.
26+
* Response constructor.
1627
*
17-
* @param bool $success Status keberhasilan request.
18-
* @param int $statusCode HTTP Status Code.
19-
* @param string $message Pesan response.
20-
* @param mixed $data Data response yang bisa dikustom.
28+
* @param bool $success Indicates whether the request was successful.
29+
* @param int $statusCode HTTP status code of the response.
30+
* @param string $message Human-readable message or description.
31+
* @param mixed $data The response payload/data.
2132
*/
22-
public function __construct(
23-
bool $success,
24-
int $statusCode,
25-
string $message,
26-
mixed $data
27-
) {
33+
public function __construct(bool $success, int $statusCode, string $message, mixed $data)
34+
{
2835
$this->response = [
29-
'success' => $success,
36+
'success' => $success,
3037
'status_code' => $statusCode,
31-
'message' => $message,
32-
'data' => $data
38+
'message' => $message,
39+
'data' => $data
3340
];
3441
}
3542

43+
// ---------------- Default array access ----------------
44+
45+
/**
46+
* Check if a response key exists (ArrayAccess implementation).
47+
*
48+
* @param mixed $offset
49+
* @return bool
50+
*/
51+
public function offsetExists($offset): bool
52+
{
53+
return isset($this->response[$offset]);
54+
}
55+
56+
/**
57+
* Get a response value by key (ArrayAccess implementation).
58+
*
59+
* @param mixed $offset
60+
* @return mixed
61+
*/
62+
public function offsetGet($offset): mixed
63+
{
64+
return $this->response[$offset] ?? null;
65+
}
66+
67+
/**
68+
* Set a response value by key (ArrayAccess implementation).
69+
*
70+
* @param mixed $offset
71+
* @param mixed $value
72+
* @return void
73+
*/
74+
public function offsetSet($offset, $value): void
75+
{
76+
$this->response[$offset] = $value;
77+
}
78+
79+
/**
80+
* Unset a response value by key (ArrayAccess implementation).
81+
*
82+
* @param mixed $offset
83+
* @return void
84+
*/
85+
public function offsetUnset($offset): void
86+
{
87+
unset($this->response[$offset]);
88+
}
89+
90+
// ---------------- Flexible output ----------------
91+
92+
/**
93+
* Get the entire response as an array (default format).
94+
*
95+
* @return array
96+
*/
3697
public function toArray(): array
3798
{
3899
return $this->response;
39100
}
40101

41-
public function jsonSerialize(): mixed
102+
/**
103+
* Get the entire response as an object.
104+
*
105+
* @return object
106+
*/
107+
public function toObject(): object
42108
{
43-
return $this->response;
109+
return (object) $this->response;
44110
}
45111

112+
/**
113+
* Get the entire response as a JSON string.
114+
*
115+
* @return string
116+
*/
46117
public function toJson(): string
47118
{
48119
return json_encode($this->response, JSON_PRETTY_PRINT);
49120
}
50121

122+
/**
123+
* Specify data for JSON serialization (JsonSerializable interface).
124+
*
125+
* @return mixed
126+
*/
127+
public function jsonSerialize(): mixed
128+
{
129+
return $this->response;
130+
}
131+
132+
/**
133+
* Magic getter for accessing response keys as properties.
134+
*
135+
* @param string $key
136+
* @return mixed|null
137+
*/
51138
public function __get(string $key): mixed
52139
{
53140
return $this->response[$key] ?? null;
54141
}
55142

143+
/**
144+
* Cast the response to a string (returns JSON string).
145+
*
146+
* @return string
147+
*/
56148
public function __toString(): string
57149
{
58150
return $this->toJson();
59151
}
152+
153+
/**
154+
* Get only the 'data' portion of the response.
155+
*
156+
* @return mixed
157+
*/
158+
public function getData(): mixed
159+
{
160+
return $this->response['data'];
161+
}
60162
}

src/Adapter/Formatter/ResponseFormatter.php

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,68 @@
22

33
namespace Reactmore\SupportAdapter\Adapter\Formatter;
44

5+
/**
6+
* Class ResponseFormatter
7+
*
8+
* Formats API responses into a consistent Response object.
9+
* Supports filtering data and provides standardized success/error responses.
10+
*
11+
* @package Reactmore\SupportAdapter\Adapter\Formatter
12+
*/
513
class ResponseFormatter
614
{
715
/**
8-
* Format response dari API dengan opsi custom data.
16+
* Format a successful API response into a Response object.
917
*
10-
* @param string $responseBody
11-
* @param string|null $message
12-
* @param callable|null $dataFilter Callback function untuk memfilter data API.
13-
* @return Response
18+
* This method parses the JSON response body, optionally applies a data filter,
19+
* and wraps it into a Response object with success status.
20+
*
21+
* @param string $responseBody The raw JSON response body from API.
22+
* @param string|null $message Optional custom message if not present in the response.
23+
* @param callable|null $dataFilter Optional callback to filter/transform the response data.
24+
*
25+
* Example of $dataFilter callback:
26+
* ```
27+
* $dataFilter = function(array $products) {
28+
* return array_filter($products, fn($item) => $item['price'] > 100);
29+
* };
30+
* $response = $productsService->getCategories([], 10, $dataFilter);
31+
* $categories = $response->getData();
32+
* ```
33+
*
34+
* @return Response The formatted Response object.
1435
*/
15-
public static function formatResponse($responseBody, $message = null, callable $dataFilter = null): Response
16-
{
36+
public static function formatResponse(
37+
string $responseBody,
38+
?string $message = null,
39+
?callable $dataFilter = null
40+
): Response {
1741
$response = json_decode($responseBody, true);
18-
$data = $response ?? null;
42+
$data = $response ?? null;
1943

20-
// Jika ada callback filter, gunakan filter tersebut untuk mengubah data
2144
if ($dataFilter && is_callable($dataFilter)) {
2245
$data = call_user_func($dataFilter, $data);
2346
}
2447

2548
return new Response(
2649
success: true,
2750
statusCode: $response['statusCode'] ?? 200,
28-
message: $response['messages'] ?? ($message ?? 'Request berhasil'),
51+
message: $response['messages'] ?? ($message ?? 'Request successful'),
2952
data: $data
3053
);
3154
}
3255

3356
/**
34-
* Format error response
57+
* Format an error API response into a Response object.
58+
*
59+
* This method standardizes error responses by wrapping the error message
60+
* and status code into a Response object.
3561
*
36-
* @param string $message
37-
* @param int $statusCode
38-
* @return Response
62+
* @param string $message The error message.
63+
* @param int $statusCode The HTTP status code for the error (default 500).
64+
* @return Response The formatted Response object.
3965
*/
40-
public static function formatErrorResponse($message, $statusCode = 500): Response
66+
public static function formatErrorResponse(string $message, int $statusCode = 500): Response
4167
{
4268
return new Response(
4369
success: false,

0 commit comments

Comments
 (0)