From 9c50ce0ef99a17e7c969ed8fc559c2d92ab5be04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=A4=80=ED=9D=A0?= Date: Wed, 4 Mar 2026 11:37:56 +0900 Subject: [PATCH] dbmsv4 init...5 --- app/Controllers/AbstractCRUDController.php | 5 +- app/Controllers/Ajax/AjaxController.php | 107 ++++++++++++++++++--- 2 files changed, 99 insertions(+), 13 deletions(-) diff --git a/app/Controllers/AbstractCRUDController.php b/app/Controllers/AbstractCRUDController.php index bb6da28..d462dc6 100644 --- a/app/Controllers/AbstractCRUDController.php +++ b/app/Controllers/AbstractCRUDController.php @@ -4,6 +4,7 @@ namespace App\Controllers; use App\Entities\CommonEntity; use CodeIgniter\HTTP\RedirectResponse; +use CodeIgniter\HTTP\ResponseInterface; use RuntimeException; /** @@ -53,7 +54,7 @@ abstract class AbstractCRUDController extends AbstractWebController ); } - public function create(): string|RedirectResponse + public function create(): string|RedirectResponse|ResponseInterface { try { $action = __FUNCTION__; @@ -111,7 +112,7 @@ abstract class AbstractCRUDController extends AbstractWebController $redirect_url ?? '/' . implode('/', [...$this->getActionPaths(), 'view']) . '/' . $entity->getPK() ); } - public function modify($uid): string|RedirectResponse + public function modify($uid): string|RedirectResponse|ResponseInterface { try { if (!$uid) { diff --git a/app/Controllers/Ajax/AjaxController.php b/app/Controllers/Ajax/AjaxController.php index ee7a82b..0e6c9f6 100644 --- a/app/Controllers/Ajax/AjaxController.php +++ b/app/Controllers/Ajax/AjaxController.php @@ -3,13 +3,14 @@ namespace App\Controllers\Ajax; use App\Controllers\AbstractCRUDController; +use App\Exceptions\FormValidationException; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Psr\Log\LoggerInterface; abstract class AjaxController extends AbstractCRUDController { - private $_layout = 'front'; + private $_layout = "front"; protected $layouts = []; public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { @@ -20,16 +21,100 @@ abstract class AjaxController extends AbstractCRUDController protected function action_init_process(string $action, array $formDatas = []): void { parent::action_init_process($action, $formDatas); - $this->addViewDatas('layout', $this->layouts); - $this->addViewDatas('title', $this->getTitle()); - $this->addViewDatas('helper', $this->service->getHelper()); + $this->addViewDatas("layout", $this->layouts); + $this->addViewDatas("title", $this->getTitle()); + $this->addViewDatas("helper", $this->service->getHelper()); $this->service->getActionForm()->form_init_process($action, $formDatas); - $this->addViewDatas('formFields', $this->service->getActionForm()->getFormFields()); - $this->addViewDatas('formRules', $this->service->getActionForm()->getFormRules()); - $this->addViewDatas('formFilters', $this->service->getActionForm()->getFormFilters()); - $this->addViewDatas('formOptions', $this->service->getActionForm()->getFormOptions()); - $this->addViewDatas('index_actionButtons', $this->service->getActionForm()->getActionButtons()); - $this->addViewDatas('index_batchjobFields', $this->service->getActionForm()->getBatchjobFilters()); - $this->addViewDatas('index_batchjobButtons', $this->service->getActionForm()->getBatchjobButtons()); + $this->addViewDatas("formFields", $this->service->getActionForm()->getFormFields()); + $this->addViewDatas("formRules", $this->service->getActionForm()->getFormRules()); + $this->addViewDatas("formFilters", $this->service->getActionForm()->getFormFilters()); + $this->addViewDatas("formOptions", $this->service->getActionForm()->getFormOptions()); + $this->addViewDatas("index_actionButtons", $this->service->getActionForm()->getActionButtons()); + $this->addViewDatas("index_batchjobFields", $this->service->getActionForm()->getBatchjobFilters()); + $this->addViewDatas("index_batchjobButtons", $this->service->getActionForm()->getBatchjobButtons()); + } + + protected function ok(array $data = [], int $status = 200): ResponseInterface + { + return $this->response->setStatusCode($status)->setJSON([ + "ok" => true, + ...$data, + ]); + } + + protected function fail(string $message, int $status = 400, array $extra = []): ResponseInterface + { + return $this->response->setStatusCode($status)->setJSON([ + "ok" => false, + "message" => $message, + ...$extra, + ]); + } + + protected function requireAjax() + { + // fetch + X-Requested-With 로 들어오는 경우 + if (!$this->request->isAJAX()) { + return $this->fail("Invalid request", 400); + } + return null; + } + + protected function handleException(\Throwable $e): ResponseInterface + { + if ($e instanceof FormValidationException) { + // ✅ 필드별 + 전역 메시지 + return $this->fail( + $e->getMessage() ?: "입력값을 확인해 주세요.", + 422, + ["errors" => $e->getErrors()] + ); + } + + log_message("error", "[AJAX] " . $e->getMessage()); + + return $this->fail("처리 중 오류가 발생했습니다.", 500); + } + + public function create(): ResponseInterface + { + if (!$this->request->isAJAX()) { + return $this->response->setStatusCode(400)->setJSON([ + "ok" => false, + "message" => static::class . "->" . __FUNCTION__ . "에서 오류발생: AJAX요청 형식이 아닙니다." + ]); + } + try { + $formDatas = $this->request->getPost(); + // log_message("error", "POST=" . json_encode($formDatas, JSON_UNESCAPED_UNICODE)); + $entity = $this->service->create($formDatas); + return $this->response->setStatusCode(201)->setJSON([ + "ok" => true, + "message" => "문의가 접수되었습니다.", + "data" => ["pk" => $entity->getPK()], + ]); + } catch (FormValidationException $e) { + // log_message("error", "CAUGHT FormValidationException: " . print_r($e->getErrors(), true)); + // ✅ 혹시 서비스에서 예외를 감싸버린 경우에도 에러를 최대한 복구 + $errors = service("validation")->getErrors(); + if (!empty($errors)) { + log_message("error", "FALLBACK validation errors: " . print_r($errors, true)); + return $this->response->setStatusCode(422)->setJSON([ + "ok" => false, + "message" => "입력값을 확인해 주세요.", + "errors" => $errors, + ]); + } + return $this->response->setStatusCode(422)->setJSON([ + "ok" => false, + "message" => "입력값을 확인해 주세요.", + "errors" => $e->getErrors(), + ]); + } catch (\Throwable $e) { + return $this->response->setStatusCode(500)->setJSON([ + "ok" => false, + "message" => "처리 중 오류가 발생했습니다.\n" . $e->getMessage(), + ]); + } } }