Initial commit BIJ CI4
This commit is contained in:
219
app/Services/ApiClient.php
Normal file
219
app/Services/ApiClient.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use CodeIgniter\HTTP\CURLRequest;
|
||||
use Config\Services;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Klien HTTP ke API internal (`/api/mobile/*` dan `/api/admin/*`).
|
||||
* Controller admin web tidak mengakses DB; hanya memanggil API lewat kelas ini.
|
||||
*/
|
||||
class ApiClient
|
||||
{
|
||||
private CURLRequest $client;
|
||||
|
||||
public function __construct(?CURLRequest $client = null)
|
||||
{
|
||||
$this->client = $client ?? Services::curlrequest([
|
||||
'timeout' => 30,
|
||||
'http_errors' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, scalar|null> $formData
|
||||
*
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
public function postMobile(string $method, array $formData = []): array
|
||||
{
|
||||
helper(['url']);
|
||||
|
||||
return $this->post('api/mobile/' . ltrim($method, '/'), $formData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, scalar|null> $formData
|
||||
*
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
public function postMobileWithToken(string $method, string $token, array $formData = []): array
|
||||
{
|
||||
$formData['token'] = $token;
|
||||
|
||||
return $this->postMobile($method, $formData);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET ke `/api/admin/{path}` — token ditambahkan ke query string.
|
||||
*
|
||||
* @param array<string, scalar|null> $query
|
||||
*
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
public function getAdmin(string $path, ?string $token, array $query = []): array
|
||||
{
|
||||
helper(['url']);
|
||||
if ($token !== null && $token !== '') {
|
||||
$query['token'] = $token;
|
||||
}
|
||||
|
||||
$forward = $this->adminInternalHeaders();
|
||||
if (($forward['Cookie'] ?? '') !== '' && session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
return $this->get('api/admin/' . ltrim($path, '/'), $query, $forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST form ke `/api/admin/{path}`.
|
||||
*
|
||||
* @param array<string, scalar|null> $formData
|
||||
*
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
public function postAdmin(string $path, ?string $token, array $formData = []): array
|
||||
{
|
||||
helper(['url']);
|
||||
if ($token !== null && $token !== '') {
|
||||
$formData['token'] = $token;
|
||||
}
|
||||
|
||||
$forward = $this->adminInternalHeaders();
|
||||
if (($forward['Cookie'] ?? '') !== '' && session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
return $this->post('api/admin/' . ltrim($path, '/'), $formData, $forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET generik (relatif terhadap root site, mis. `api/admin/pegawai`).
|
||||
*
|
||||
* @param array<string, scalar|null> $query
|
||||
* @param array<string, string> $extraHeaders
|
||||
*
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
public function get(string $path, array $query = [], array $extraHeaders = []): array
|
||||
{
|
||||
helper(['url']);
|
||||
$url = base_url(ltrim($path, '/'));
|
||||
|
||||
$base = $this->emptyResult();
|
||||
|
||||
$headers = array_merge(
|
||||
['Accept' => 'application/json'],
|
||||
$extraHeaders
|
||||
);
|
||||
|
||||
try {
|
||||
$response = $this->client->get($url, [
|
||||
'query' => $query,
|
||||
'headers' => $headers,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
$base['error'] = $e->getMessage();
|
||||
|
||||
return $base;
|
||||
}
|
||||
|
||||
return $this->fillFromResponse($base, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* POST `application/x-www-form-urlencoded`.
|
||||
*
|
||||
* @param array<string, scalar|null> $formData
|
||||
* @param array<string, string> $extraHeaders
|
||||
*
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
public function post(string $path, array $formData = [], array $extraHeaders = []): array
|
||||
{
|
||||
helper(['url']);
|
||||
$url = base_url(ltrim($path, '/'));
|
||||
|
||||
$base = $this->emptyResult();
|
||||
|
||||
$headers = array_merge(
|
||||
['Accept' => 'application/json'],
|
||||
$extraHeaders
|
||||
);
|
||||
|
||||
try {
|
||||
$response = $this->client->post($url, [
|
||||
'form_params' => $formData,
|
||||
'headers' => $headers,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
$base['error'] = $e->getMessage();
|
||||
|
||||
return $base;
|
||||
}
|
||||
|
||||
return $this->fillFromResponse($base, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Teruskan cookie browser ke hit internal `/api/admin/*` agar sesi panel sama.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function adminInternalHeaders(): array
|
||||
{
|
||||
$cookie = Services::request()->getHeaderLine('Cookie');
|
||||
|
||||
return $cookie !== '' ? ['Cookie' => $cookie] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed>|null $json
|
||||
*/
|
||||
public static function isSuccess(?array $json): bool
|
||||
{
|
||||
return is_array($json) && (int) ($json['status'] ?? 0) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
private function emptyResult(): array
|
||||
{
|
||||
return [
|
||||
'transport_ok' => false,
|
||||
'http_code' => 0,
|
||||
'json' => null,
|
||||
'error' => null,
|
||||
'raw' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string} $base
|
||||
*
|
||||
* @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
|
||||
*/
|
||||
private function fillFromResponse(array $base, int $statusCode, string $body): array
|
||||
{
|
||||
$base['http_code'] = $statusCode;
|
||||
$base['raw'] = $body;
|
||||
$base['transport_ok'] = $statusCode === 200;
|
||||
|
||||
$decoded = json_decode($body, true);
|
||||
if (! is_array($decoded)) {
|
||||
$base['error'] = 'Respons bukan JSON objek';
|
||||
|
||||
return $base;
|
||||
}
|
||||
|
||||
$base['json'] = $decoded;
|
||||
|
||||
return $base;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user