- 컨트롤러와 서비스에서 각각 래핑 후 결과 전달됨으로 이중 래핑되고 있음 -> 서비스에서 래핑하는 부분을 컨트롤러로 옮겨서 컨트롤러에서만 한번 래핑하는 걸로 수정
168 lines
5.4 KiB
PHP
168 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Helpers;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Http\JsonResponse;
|
|
|
|
class ApiResponse
|
|
{
|
|
|
|
function normalizeFiles(array $laravelFiles): array {
|
|
$files = ['name' => [], 'type' => [], 'tmp_name' => [], 'size' => [], 'fileType' => []];
|
|
foreach ($laravelFiles as $file) {
|
|
$files['name'][] = $file->getClientOriginalName();
|
|
$files['type'][] = $file->getClientMimeType();
|
|
$files['tmp_name'][] = $file->getPathname();
|
|
$files['size'][] = $file->getSize();
|
|
$files['fileType'][] = '';
|
|
}
|
|
return $files;
|
|
}
|
|
|
|
# DebugQuery Helper
|
|
public static function debugQueryLog(): array
|
|
{
|
|
$logs = DB::getQueryLog();
|
|
|
|
return collect($logs)
|
|
->skip(3)
|
|
->map(function ($log) {
|
|
$query = $log['query'];
|
|
foreach ($log['bindings'] as $binding) {
|
|
$binding = is_numeric($binding) ? $binding : "'" . addslashes($binding) . "'";
|
|
$query = preg_replace('/\\?/', $binding, $query, 1);
|
|
}
|
|
|
|
// \n 제거
|
|
$query = str_replace(["\n", "\r"], ' ', $query)." (time: {$log['time']})";
|
|
return trim($query);
|
|
})->toArray();
|
|
}
|
|
|
|
# ApiResponse Helper
|
|
public static function success(
|
|
$data = null,
|
|
string $message = '요청 성공',
|
|
array $debug = []
|
|
): JsonResponse {
|
|
$response = [
|
|
'success' => true,
|
|
'message' => $message,
|
|
'data' => $data,
|
|
];
|
|
if(!empty($debug)) $response['query'] = $debug;
|
|
return response()->json($response);
|
|
}
|
|
|
|
public static function error(
|
|
string $message = '요청 실패',
|
|
int $code = 400,
|
|
array $error = []
|
|
): JsonResponse {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => $message,
|
|
'error' => [
|
|
'code' => $code,
|
|
'details' => $error['details'] ?? null,
|
|
],
|
|
], $code);
|
|
}
|
|
|
|
public static function validate(
|
|
bool $condition,
|
|
string $message = 'Validation failed',
|
|
int $code = 422,
|
|
array $extra = []
|
|
): ?JsonResponse {
|
|
return $condition ? null : self::error($message, $code, $extra);
|
|
}
|
|
|
|
public static function response($type = '', $query = '', $key = ''): array
|
|
{
|
|
$debug = app()->environment('local') && request()->is('api/*');
|
|
|
|
$result = match ($type) {
|
|
'get' => $key ? $query->get()->keyBy($key) : $query->get(),
|
|
'getSub' => $query->get(),
|
|
'count' => $query->count(),
|
|
'first' => $query->first(),
|
|
'success' => 'Success',
|
|
'result' => $query,
|
|
default => null,
|
|
};
|
|
|
|
if($type=='getSub'){
|
|
$array = $result->map(function ($item) {
|
|
return (array) $item;
|
|
})->toArray();
|
|
foreach ($array as $row) {
|
|
$data[$row[$key]][] = $row;
|
|
}
|
|
$result = $data ?? [];
|
|
}
|
|
|
|
$response['data'] = $result;
|
|
$response['query'] = $debug ? self::debugQueryLog() : [];
|
|
|
|
// 다음 요청에 로그가 섞이지 않도록 비워준다 (로컬에서만 의미있음)
|
|
if ($debug) {
|
|
DB::flushQueryLog();
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
public static function handle(
|
|
callable $callback,
|
|
string $responseTitle = '요청'
|
|
): JsonResponse
|
|
{
|
|
try {
|
|
$result = $callback();
|
|
|
|
// 이미 JsonResponse면 그대로 반환
|
|
if ($result instanceof JsonResponse) {
|
|
return $result;
|
|
}
|
|
|
|
// [신규] 서비스가 에러 ‘신호 배열’을 반환한 경우 감지
|
|
// 허용 포맷 예:
|
|
// ['error' => 'NO_TENANT', 'code' => 400]
|
|
// ['code' => 404, 'message' => '데이터 없음']
|
|
if (is_array($result) && (
|
|
array_key_exists('error', $result) ||
|
|
(array_key_exists('code', $result) && is_numeric($result['code']) && (int)$result['code'] >= 400)
|
|
)
|
|
) {
|
|
$code = (int)($result['code'] ?? 400);
|
|
$message = (string)($result['message'] ?? ($result['error'] ?? ($responseTitle.' 실패')));
|
|
$details = $result['details'] ?? null;
|
|
|
|
// 에러에도 쿼리 로그 포함되도록 error()가 처리하게 맡김
|
|
return self::error($message, $code, ['details' => $details]);
|
|
}
|
|
|
|
// 표준 박스( ['data'=>..., 'query'=>...] ) 하위호환
|
|
if (is_array($result) && array_key_exists('data', $result)) {
|
|
$data = $result['data'];
|
|
$debug = $result['query'] ?? [];
|
|
} else {
|
|
// 그냥 도메인 결과만 반환한 경우
|
|
$data = $result;
|
|
$debug = (app()->environment('local') && request()->is('api/*'))
|
|
? self::debugQueryLog()
|
|
: [];
|
|
}
|
|
|
|
return self::success($data, $responseTitle.' 성공', $debug);
|
|
|
|
} catch (\Throwable $e) {
|
|
return self::error($responseTitle.' 실패', 500, [
|
|
'details' => $e->getMessage(),
|
|
]);
|
|
}
|
|
}
|
|
}
|