daemon-idc/app/Controllers/Ajax/AjaxController.php
2026-03-03 15:44:35 +09:00

121 lines
4.9 KiB
PHP

<?php
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';
protected $layouts = [];
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
$this->addActionPaths($this->_layout);
$this->layouts = LAYOUTS[$this->_layout];
}
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->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());
}
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));
return $this->response->setStatusCode(422)->setJSON([
'ok' => false,
'message' => '입력값을 확인해 주세요.',
'errors' => $e->getErrors(),
]);
} catch (\Throwable $e) {
// ✅ 혹시 서비스에서 예외를 감싸버린 경우에도 에러를 최대한 복구
$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(500)->setJSON([
'ok' => false,
'message' => '처리 중 오류가 발생했습니다.',
]);
}
}
}