initial commit
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
// api/helpers/response.php
|
||||
|
||||
function setCORSHeaders(): void {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Vary: Origin');
|
||||
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-API-Token');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
|
||||
$allowed = false;
|
||||
if ($origin !== '') {
|
||||
$origin = trim($origin);
|
||||
$allowedOrigins = parseAllowedOrigins(getenv('CORS_ALLOWED_ORIGINS') ?: '');
|
||||
if (!empty($allowedOrigins)) {
|
||||
$allowed = in_array($origin, $allowedOrigins, true);
|
||||
} else {
|
||||
$allowed = (bool)preg_match('/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/', $origin);
|
||||
}
|
||||
if ($allowed) {
|
||||
header('Access-Control-Allow-Origin: ' . $origin);
|
||||
}
|
||||
}
|
||||
|
||||
if (getMethod() === 'OPTIONS') {
|
||||
http_response_code(($origin !== '' && !$allowed) ? 403 : 204);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function parseAllowedOrigins(string $raw): array {
|
||||
$parts = array_map('trim', explode(',', $raw));
|
||||
return array_values(array_filter($parts, static fn ($v) => $v !== ''));
|
||||
}
|
||||
|
||||
function sendJSON(mixed $data, int $code = 200): void {
|
||||
http_response_code($code);
|
||||
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
|
||||
function sendSuccess(mixed $data = null, string $message = 'OK', int $code = 200): void {
|
||||
sendJSON(['status' => 'success', 'message' => $message, 'data' => $data], $code);
|
||||
}
|
||||
|
||||
function sendError(string $message, int $code = 400): void {
|
||||
sendJSON(['status' => 'error', 'message' => $message], $code);
|
||||
}
|
||||
|
||||
function requireWriteAuth(string $method): void {
|
||||
if (!in_array($method, ['POST', 'PUT', 'DELETE'], true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$expected = (string)(getenv('API_WRITE_TOKEN') ?: '');
|
||||
if ($expected === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$provided = (string)($_SERVER['HTTP_X_API_TOKEN'] ?? '');
|
||||
if ($provided === '') {
|
||||
$auth = (string)($_SERVER['HTTP_AUTHORIZATION'] ?? '');
|
||||
if (preg_match('/Bearer\s+(.+)/i', $auth, $m)) {
|
||||
$provided = trim($m[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($provided === '' || !hash_equals($expected, $provided)) {
|
||||
sendError('Unauthorized', 401);
|
||||
}
|
||||
}
|
||||
|
||||
function executeOrFail(mysqli_stmt $stmt, string $defaultMessage = 'Operasi database gagal'): void {
|
||||
if ($stmt->execute()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$errno = $stmt->errno;
|
||||
$error = $stmt->error;
|
||||
error_log('DB stmt error [' . $errno . ']: ' . $error);
|
||||
|
||||
if ($errno === 1062) {
|
||||
sendError('Data duplikat terdeteksi', 409);
|
||||
}
|
||||
if ($errno === 1451 || $errno === 1452) {
|
||||
sendError('Relasi data tidak valid', 422);
|
||||
}
|
||||
sendError($defaultMessage, 500);
|
||||
}
|
||||
|
||||
function getBody(): array {
|
||||
$raw = file_get_contents('php://input');
|
||||
$data = json_decode($raw, true);
|
||||
return is_array($data) ? $data : [];
|
||||
}
|
||||
|
||||
function getMethod(): string {
|
||||
return strtoupper($_SERVER['REQUEST_METHOD']);
|
||||
}
|
||||
Reference in New Issue
Block a user