From 155b7d513779d84b035a25b008d948461745c936 Mon Sep 17 00:00:00 2001 From: "choi.jh" Date: Mon, 10 Nov 2025 11:29:00 +0900 Subject: [PATCH] trafficmonitor init...2 --- app/Controllers/Admin/AdminController.php | 69 +++++++++++------- app/Controllers/Admin/UserController.php | 26 ++++--- app/Controllers/CommonController.php | 7 +- app/Database/user.sql | 4 +- app/Entities/UserEntity.php | 15 ++-- app/Helpers/CommonHelper.php | 88 +++++------------------ app/Helpers/UserHelper.php | 6 +- app/Services/Auth/AuthService.php | 2 +- app/Services/CommonService.php | 15 ++-- app/Services/UserService.php | 19 +++-- app/Views/admin/user/create_form.php | 6 +- app/Views/admin/user/index.php | 6 +- app/Views/admin/user/modify_form.php | 6 +- app/Views/admin/user/view.php | 3 +- 14 files changed, 122 insertions(+), 150 deletions(-) diff --git a/app/Controllers/Admin/AdminController.php b/app/Controllers/Admin/AdminController.php index 4f7c400..e53ae8c 100644 --- a/app/Controllers/Admin/AdminController.php +++ b/app/Controllers/Admin/AdminController.php @@ -39,31 +39,28 @@ abstract class AdminController extends CommonController $this->addViewDatas('formRules', $this->service->getFormService()->getFormRules($action, array_keys($formFields))); $this->addViewDatas('formOptions', $this->service->getFormService()->getFormOptions($action, $formFilters)); } - protected function create_form_process(array $formDatas = []): array - { - return $formDatas; - } + abstract protected function create_form_process(string $action): void; final public function create_form(): string { $action = __FUNCTION__; try { //초기화 $this->action_init_process($action); - $this->addViewDatas('formDatas', $this->create_form_process()); + $this->create_form_process($action); } catch (\Exception $e) { log_message('error', $e->getMessage()); session()->setFlashdata('message', $e->getMessage()); } return $this->action_render_process($this->getActionPaths(), $action, $this->getViewDatas()); } - abstract protected function create_process(): RedirectResponse; - final public function create(): RedirectResponse + abstract protected function create_process(string $action): string|RedirectResponse; + final public function create(): string|RedirectResponse { $action = __FUNCTION__; try { //초기화 $this->action_init_process($action); - return $this->create_process(); + return $this->create_process($action); } catch (ValidationException $e) { // 검증 실패 시 폼으로 돌아가서 오류 메시지 표시 log_message('error', $e->getMessage()); @@ -73,7 +70,38 @@ abstract class AdminController extends CommonController return redirect()->back()->withInput()->with('message', $e->getMessage()); } } - protected function modify_form_process($uid): CommonEntity + abstract protected function modify_form_process(string $action, $uid): void; + final public function modify_form($uid): string + { + $action = __FUNCTION__; + try { + //초기화 + $this->action_init_process($action); + $this->modify_form_process($action, $uid); + } catch (\Exception $e) { + log_message('error', $e->getMessage()); + session()->setFlashdata('message', $e->getMessage()); + } + return $this->action_render_process($this->getActionPaths(), $action, $this->getViewDatas()); + } + abstract protected function modify_process(string $action, $uid): string|RedirectResponse; + final public function modify($uid): string|RedirectResponse + { + $action = __FUNCTION__; + try { + //초기화 + $this->action_init_process($action); + return $this->modify_process($action, $uid); + } catch (ValidationException $e) { + // 검증 실패 시 폼으로 돌아가서 오류 메시지 표시 + log_message('error', $e->getMessage()); + return redirect()->back()->withInput()->with('message', $e->getMessage()); + } catch (\Exception $e) { + log_message('error', $e->getMessage()); + return redirect()->back()->withInput()->with('message', $e->getMessage()); + } + } + protected function delete_process($uid): RedirectResponse { if (!$uid) { throw new \Exception("계정 번호가 정의 되지 않았습니다."); @@ -82,30 +110,17 @@ abstract class AdminController extends CommonController if (!$entity instanceof CommonEntity) { throw new \Exception("{$uid}에 해당하는 계정을 찾을수 없습니다."); } - return $entity; + $this->service->delete($uid); + $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); + return redirect()->to($redirect_url)->with('message', "{$entity->getTitle()} 계정 생성이 완료되었습니다."); } - final public function modify_form($uid): string + final public function delete($uid): RedirectResponse { $action = __FUNCTION__; try { //초기화 $this->action_init_process($action); - $entity = $this->modify_form_process($uid); - $this->addViewDatas('entity', $entity); - } catch (\Exception $e) { - log_message('error', $e->getMessage()); - session()->setFlashdata('message', $e->getMessage()); - } - return $this->action_render_process($this->getActionPaths(), $action, $this->getViewDatas()); - } - abstract protected function modify_process($uid): RedirectResponse; - final public function modify($uid): RedirectResponse - { - $action = __FUNCTION__; - try { - //초기화 - $this->action_init_process($action); - return $this->modify_process($uid); + return $this->delete_process($uid); } catch (ValidationException $e) { // 검증 실패 시 폼으로 돌아가서 오류 메시지 표시 log_message('error', $e->getMessage()); diff --git a/app/Controllers/Admin/UserController.php b/app/Controllers/Admin/UserController.php index 3dd75e7..093270b 100644 --- a/app/Controllers/Admin/UserController.php +++ b/app/Controllers/Admin/UserController.php @@ -30,19 +30,21 @@ class UserController extends AdminController return parent::getFormRule($action, $field, $rule); } //Action작업관련 - protected function create_process(): RedirectResponse + protected function create_form_process(string $action): void + { + //Form Default값 설정 + $formDatas = ['role' => [ROLE['USER']['MANAGER']]]; + $this->addViewDatas('formDatas', $formDatas); + } + protected function create_process(string $action): string|RedirectResponse { //요청 데이터를 DTO 객체로 변환 - $dto = new UserDTO($this->request->getPost()); - $entity = $this->service->create($dto); + $dto = new UserDTO($this->request->getPost()); + $entity = $this->service->create($dto); $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); return redirect()->to($redirect_url)->with('message', "{$entity->getTitle()} 계정 생성이 완료되었습니다."); } - protected function modify_form_process($uid): UserEntity - { - return parent::modify_form_process($uid); - } - protected function modify_process($uid): RedirectResponse + protected function modify_form_process(string $action, $uid): void { if (!$uid) { throw new \Exception("계정 번호가 정의 되지 않았습니다."); @@ -51,13 +53,17 @@ class UserController extends AdminController if (!$entity instanceof UserEntity) { throw new \Exception("{$uid}에 해당하는 계정을 찾을수 없습니다."); } + $this->addViewDatas('entity', $entity); + } + protected function modify_process(string $action, $uid): string|RedirectResponse + { + //요청 데이터를 DTO 객체로 변환 $dto = new UserDTO($this->request->getPost()); - $entity = $this->service->modify($entity, $dto); + $entity = $this->service->modify($uid, $dto); $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); return redirect()->to($redirect_url)->with('message', "{$entity->getTitle()} 계정 수정이 완료되었습니다."); } - protected function view_process($uid): UserEntity { return parent::view_process($uid); diff --git a/app/Controllers/CommonController.php b/app/Controllers/CommonController.php index 8d839e7..742958d 100644 --- a/app/Controllers/CommonController.php +++ b/app/Controllers/CommonController.php @@ -3,9 +3,9 @@ namespace App\Controllers; use App\Controllers\BaseController; -use App\DTOs\CertificationDTO; use App\Libraries\AuthContext; use App\Traits\LogTrait; +use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Psr\Log\LoggerInterface; @@ -74,6 +74,11 @@ abstract class CommonController extends BaseController $this->addViewDatas('authContext', $this->getAuthContext()); $this->addViewDatas('classPath', $this->service->getClassPaths(false)); } + protected function action_rediect_process(string $message): RedirectResponse + { + $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); + return redirect()->to($redirect_url)->with('message', $message); + } protected function action_render_process(array $view_paths, string $view_file, array $viewDatas): string { $lastest_path = array_pop($view_paths); //paths는 마지막을 뺀 앞단까지만 남음 diff --git a/app/Database/user.sql b/app/Database/user.sql index e926a06..b468b53 100644 --- a/app/Database/user.sql +++ b/app/Database/user.sql @@ -37,7 +37,7 @@ CREATE TABLE `user` ( PRIMARY KEY (`uid`), UNIQUE KEY `UQ_id` (`id`), UNIQUE KEY `UQ_email` (`email`) -) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8 COMMENT='관리자정보'; +) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8 COMMENT='관리자정보'; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -59,4 +59,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2025-11-05 21:33:38 +-- Dump completed on 2025-11-10 8:58:23 diff --git a/app/Entities/UserEntity.php b/app/Entities/UserEntity.php index 25bde51..8f0b440 100644 --- a/app/Entities/UserEntity.php +++ b/app/Entities/UserEntity.php @@ -77,24 +77,19 @@ class UserEntity extends CommonEntity public function setRole(mixed $role) { $roleArray = []; - if (is_string($role)) { // 1. 양쪽의 불필요한 따옴표와 공백을 제거하여 깨끗한 문자열 확보 $cleanRoleString = trim($role, " \t\n\r\0\x0B\""); - if (!empty($cleanRoleString)) { - // 2. 쉼표를 기준으로 분리 후, 각 요소의 공백/따옴표를 다시 제거 - $parts = explode(',', $cleanRoleString); - $cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $parts); - $roleArray = array_filter($cleanedRoles); + $role = explode(DEFAULTS["DELIMITER_ROLE"], $cleanRoleString); } - } else if (is_array($role)) { - // 이미 배열인 경우에도 데이터 정리를 한 번 거칩니다. + } + if (is_array($role)) { + //배열에도 불필요한 따옴표와 공백을 제거 $cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $role); $roleArray = array_filter($cleanedRoles); } - // 💡 핵심: 최종적으로 DB에 삽입될 단일 CSV 문자열로 변환하여 저장합니다. - $this->attributes['role'] = implode(',', $roleArray); + $this->attributes['role'] = implode(DEFAULTS["DELIMITER_ROLE"], $roleArray); } } diff --git a/app/Helpers/CommonHelper.php b/app/Helpers/CommonHelper.php index ae9df40..35a796f 100644 --- a/app/Helpers/CommonHelper.php +++ b/app/Helpers/CommonHelper.php @@ -22,51 +22,6 @@ class CommonHelper } return $this->_attributes[$key]; } - // final public function form_dropdown_common(string $field, mixed $value, array $viewDatas, array $extras = [], array $attributes = [], bool $isAll = false): string - // { - // // 필터 옵션이 없으면 빈 배열로 초기화 - // if (!array_key_exists($field, $viewDatas['formOptions'])) { - // return ""; // 필터 옵션이 없으면 빈 문자열 반환 - // } - // $extra = ""; - // foreach ($extras as $extra_tag => $extra_value) { - // $extra .= sprintf(" %s=\"%s\"", $extra_tag, $extra_value); - // } - // // $formOptions는 필터 옵션 배열로, key는 필터 엔티티의 PK, value는 필터 엔티티 객체 - // $html = sprintf("'; - // return $html; - // } - // //필수함수 - // protected function form_dropdown_common_process(string $field, mixed $value, array $viewDatas, array $extras = [], array $attributes = [], bool $isAll = false): string - // { - // $html = ""; - // switch ($field) { - // default: - // foreach ($viewDatas['formOptions'][$field]['options'] as $option_key => $option_value) { - // $isSelected = $option_key == $value ? ' selected' : ''; - // $isDisabled = ""; - // $attribute = ""; - // $label = ""; - // if ($option_value instanceof CommonEntity) { - // if ($option_key != $value && $option_value->getStatus() != DEFAULTS['STATUS'] && !$isAll) { - // continue; - // } - // foreach ($attributes as $attribute_name => $attribute_value) { - // $attribute .= sprintf(" %s=\"%s\"", $attribute_name, $option_value->$attribute_value); - // } - // $label = $option_value->getCustomTitle(); - // } else { - // $label = $option_value; - // } - // $html .= sprintf("", $option_key, $isSelected, $isDisabled, $attribute, $label); - // } - // break; - // } - // return $html; - // } public function getFieldLabel(string $field, string $label, array $viewDatas, array $extras = []): string { switch ($field) { @@ -81,21 +36,17 @@ class CommonHelper { switch ($field) { case 'email': - $form = form_input($field, $value ?? "", [ - "class" => "form-control", - 'style' => 'width:100%;', - "placeholder" => "예)test@example.com", - ...$extras - ]); + $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' form-control' : 'form-control'; + $extras['style'] = 'width:100%;'; + $extras['placeholder'] = '예)test@example.co.kr'; + $form = form_input($field, $value ?? "", $extras); break; case 'mobile': case 'phone': - $form = form_input($field, $value ?? "", [ - "class" => "form-control", - 'style' => 'width:100%;', - "placeholder" => "예)010-0010-0010", - ...$extras - ]); + $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' form-control' : 'form-control'; + $extras['style'] = 'width:100%;'; + $extras['placeholder'] = '예)010-0010-0010'; + $form = form_input($field, $value ?? "", $extras); break; case 'issue_at': case 'expired_at': @@ -105,30 +56,25 @@ class CommonHelper case 'updated_at': case 'created_at': case 'deleted_at': - $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' calender' : 'calender'; + $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' form-control calender' : 'form-control calender'; + $extras['style'] = 'width:100%;'; $form = form_input($field, $value ?? "", $extras); break; case 'description': case 'content': case 'detail': case 'history': - $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' tinymce' : 'tinymce'; - $form = form_textarea($field, html_entity_decode($value ?? "", ENT_QUOTES, 'UTF-8'), [ - "class" => "form-control", - 'style' => 'width:100%;', - ...$extras - ]); + $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' form-control tinymce' : 'form-control tinymce'; + $extras['style'] = 'width:100%;'; + $form = form_textarea($field, html_entity_decode($value ?? "", ENT_QUOTES, 'UTF-8'), $extras); break; default: + $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' form-control' : 'form-control'; if (in_array($field, $viewDatas['formFilters'])) { - $form = form_dropdown($field, $viewDatas['formOptions'][$field]['options'], $value, $viewDatas['formOptions'][$field]['extras']); - // $form = $this->form_dropdown_common($field, $value, $viewDatas, $extras); + $form = form_dropdown($field, $viewDatas['formOptions'][$field]['options'], $value, [...$extras, ...$viewDatas['formOptions'][$field]['extras']]); } else { - $form = form_input($field, $value ?? "", [ - "class" => "form-control", - 'style' => 'width:100%;', - ...$extras - ]); + $extras['style'] = 'width:100%;'; + $form = form_input($field, $value ?? "", $extras); } break; } diff --git a/app/Helpers/UserHelper.php b/app/Helpers/UserHelper.php index 841b21c..e51600a 100644 --- a/app/Helpers/UserHelper.php +++ b/app/Helpers/UserHelper.php @@ -15,7 +15,9 @@ class UserHelper extends CommonHelper switch ($field) { case 'passwd': case 'confirmpassword': - $form = form_password($field, "", [...$extras]); + $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' form-control' : 'form-control'; + $extras['style'] = 'width:100%;'; + $form = form_password($field, "", $extras); break; case 'role': $currentRoles = is_array($value) @@ -27,7 +29,7 @@ class UserHelper extends CommonHelper foreach ($viewDatas['formOptions'][$field]['options'] as $key => $label) { $checked = in_array(strtolower(trim($key)), $currentRoles); $form .= ''; } diff --git a/app/Services/Auth/AuthService.php b/app/Services/Auth/AuthService.php index 51e3149..79e656f 100644 --- a/app/Services/Auth/AuthService.php +++ b/app/Services/Auth/AuthService.php @@ -85,7 +85,7 @@ abstract class AuthService } final protected function getValidationRules(string $action, array $allRules = []): array { - foreach ($this->getFormService()->getFormFields($action) as $field) { + foreach ($this->getFormService()->getFormFields($action) as $field => $label) { $allRules = array_merge($allRules, $this->getValidationRule($action, $field, $allRules)); } return $allRules; diff --git a/app/Services/CommonService.php b/app/Services/CommonService.php index 7deafd7..b7b503b 100644 --- a/app/Services/CommonService.php +++ b/app/Services/CommonService.php @@ -91,7 +91,7 @@ abstract class CommonService //Validation용 final protected function getValidationRules(string $action, array $allRules = []): array { - foreach ($this->getFormService()->getFormFields($action) as $field) { + foreach ($this->getFormService()->getFormFields($action) as $field => $label) { $allRules = array_merge($allRules, $this->getValidationRule($action, $field, $allRules)); } return $allRules; @@ -131,7 +131,7 @@ abstract class CommonService abstract protected function create_process(array $formDatas): CommonEntity; public function create(object $dto): CommonEntity { - $formDatas = (array) $dto; + $formDatas = (array)$dto; //입력값 검증 $validation = service('validation')->setRules($this->getValidationRules(__FUNCTION__)); if (!$validation->run($formDatas)) { @@ -142,23 +142,20 @@ abstract class CommonService return $this->handle_save_result($result, $entity); } //수정용 - abstract protected function modify_process(CommonEntity $entity, array $formDatas): CommonEntity; - public function modify(CommonEntity $entity, object $dto): CommonEntity + abstract protected function modify_process($uid, array $formDatas): CommonEntity; + public function modify($uid, object $dto): CommonEntity { - $formDatas = (array) $dto; + $formDatas = (array)$dto; //입력값 검증 $validation = service('validation')->setRules($this->getValidationRules(__FUNCTION__)); if (!$validation->run($formDatas)) { throw new ValidationException(implode("\n", $validation->getErrors())); } - $updatedEntity = $this->modify_process($entity, $formDatas); - // 2. 💡 model->save() 사용: Primary Key가 있으므로 UPDATE를 수행하며, - // Dirty Tracking에 의해 변경된 필드만 업데이트합니다. + $updatedEntity = $this->modify_process($uid, $formDatas); $result = $this->model->save($updatedEntity); if (!$result) { throw new RuntimeException(static::class . "에서 " . __FUNCTION__ . "오류발생:" . $this->model->getLastQuery()); } - // 3. handle_save_result에 Entity 객체 전달 return $this->handle_save_result($result, $updatedEntity); } protected function delete_process($uid): bool diff --git a/app/Services/UserService.php b/app/Services/UserService.php index 0d245e8..61718cd 100644 --- a/app/Services/UserService.php +++ b/app/Services/UserService.php @@ -61,24 +61,29 @@ class UserService extends CommonService } return parent::create($dto); } - protected function modify_process(CommonEntity $entity, array $formDatas): UserEntity + protected function modify_process($uid, array $formDatas): UserEntity { - // CommonEntity 타입을 UserEntity로 형 변환합니다. (타입 힌트가 CommonEntity지만 실제로는 UserEntity 객체입니다.) - $userEntity = $entity; + if (!$uid) { + throw new \Exception("계정 번호가 정의 되지 않았습니다."); + } + $entity = $this->getEntity($uid); + if (!$entity instanceof UserEntity) { + throw new \Exception("{$uid}에 해당하는 계정을 찾을수 없습니다."); + } if (isset($formDatas['confirmpassword'])) { unset($formDatas['confirmpassword']); } // 변경 사항을 Entity에 적용합니다. (Dirty Tracking 활성화) - $userEntity->fill($formDatas); + $entity->fill($formDatas); // 💡 부모 호출 제거: 변경된 Entity 객체를 반환합니다. - return $userEntity; + return $entity; } - public function modify($entity, object $dto): UserEntity + public function modify($uid, object $dto): UserEntity { if (!$dto instanceof UserDTO) { throw new RuntimeException(__METHOD__ . "에서 오류발생:" . get_class($dto) . "는 사용할수 없습니다."); } - return parent::modify($entity, $dto); + return parent::modify($uid, $dto); } //List 검색용 //FormFilter 조건절 처리 diff --git a/app/Views/admin/user/create_form.php b/app/Views/admin/user/create_form.php index 5ae7388..82d4599 100644 --- a/app/Views/admin/user/create_form.php +++ b/app/Views/admin/user/create_form.php @@ -1,4 +1,5 @@ extend(LAYOUTS[$viewDatas['layout']]['path']) ?> +alertTrait(session('message')) : "" ?> section('content') ?>
include("templates/{$viewDatas['layout']}/form_content_top"); ?>
@@ -6,17 +7,16 @@ $label): ?> - +
getFieldLabel($field, $label, $viewDatas) ?>getFieldLabel($field, $label, $viewDatas) ?> getFieldForm($field, old($field) ?? ($viewDatas['formDatas'][$field] ?? null), $viewDatas) ?> - +
"btn btn-outline btn-primary")); ?>
-
include("templates/{$viewDatas['layout']}/form_content_bottom"); ?>
endSection() ?> \ No newline at end of file diff --git a/app/Views/admin/user/index.php b/app/Views/admin/user/index.php index 3096cf3..80d0a62 100644 --- a/app/Views/admin/user/index.php +++ b/app/Views/admin/user/index.php @@ -19,11 +19,11 @@ $template = "templates" . DIRECTORY_SEPARATOR . "{$viewDatas['layout']}"; - + $label): ?> - + - + diff --git a/app/Views/admin/user/modify_form.php b/app/Views/admin/user/modify_form.php index b70a549..040274f 100644 --- a/app/Views/admin/user/modify_form.php +++ b/app/Views/admin/user/modify_form.php @@ -1,4 +1,5 @@ extend(LAYOUTS[$viewDatas['layout']]['path']) ?> +alertTrait(session('message')) : "" ?> section('content') ?>
include("templates/{$viewDatas['layout']}/form_content_top"); ?>
@@ -6,17 +7,16 @@
번호번호 getListLabel($field, $label, $viewDatas) ?>getListLabel($field, $label, $viewDatas) ?> 작업작업
$label): ?> - +
getFieldLabel($field, $label, $viewDatas) ?>getFieldLabel($field, $label, $viewDatas) ?> getFieldForm($field, old($field) ?? ($viewDatas['entity']->$field ?? null), $viewDatas) ?> - +
"btn btn-outline btn-primary")); ?>
-
include("templates/{$viewDatas['layout']}/form_content_bottom"); ?>
endSection() ?> \ No newline at end of file diff --git a/app/Views/admin/user/view.php b/app/Views/admin/user/view.php index db4650e..80061d8 100644 --- a/app/Views/admin/user/view.php +++ b/app/Views/admin/user/view.php @@ -1,11 +1,12 @@ extend(LAYOUTS[$viewDatas['layout']]['path']) ?> +alertTrait(session('message')) : "" ?> section('content') ?>
include("templates/{$viewDatas['layout']}/form_content_top"); ?>
$label): ?> - +
getFieldLabel($field, $label, $viewDatas) ?>getFieldLabel($field, $label, $viewDatas) ?> getFieldView($field, old($field) ?? ($viewDatas['entity']->$field ?? null), $viewDatas) ?>