trafficmonitor init...2
This commit is contained in:
parent
d86c64b28e
commit
a632153947
@ -32,7 +32,11 @@ class UserController extends AdminController
|
||||
}
|
||||
return parent::getFormRule($action, $field, $rule);
|
||||
}
|
||||
//Index,FieldForm관련.
|
||||
//Action작업관련
|
||||
protected function create_form_process(): void
|
||||
{
|
||||
new UserDTO($this->request->getPost());
|
||||
}
|
||||
protected function create_process(): RedirectResponse
|
||||
{
|
||||
//요청 데이터를 DTO 객체로 변환
|
||||
@ -63,7 +67,7 @@ class UserController extends AdminController
|
||||
}
|
||||
//요청 데이터를 DTO 객체로 변환
|
||||
$dto = new UserDTO($this->request->getPost());
|
||||
$entity = $this->service->modify($dto);
|
||||
$entity = $this->service->modify($entity, $dto);
|
||||
$redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths());
|
||||
return redirect()->to($redirect_url)->with('success', "{$entity->getTitle()} 계정 수정이 완료되었습니다.");
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ use CodeIgniter\Entity\Entity;
|
||||
|
||||
abstract class CommonEntity extends Entity
|
||||
{
|
||||
const DEFAULT_STATUS = "";
|
||||
protected $datamap = [];
|
||||
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
|
||||
//사용법 : $client->created_at->format('Y-m-d')
|
||||
|
||||
@ -8,7 +8,6 @@ class TrafficEntity extends CommonEntity
|
||||
{
|
||||
const PK = TrafficModel::PK;
|
||||
const TITLE = TrafficModel::TITLE;
|
||||
const DEFAULT_STATUS = STATUS['AVAILABLE'];
|
||||
final public function getUserUID(): int|null
|
||||
{
|
||||
return $this->attributes['user_uid'] ?? null;
|
||||
|
||||
@ -4,23 +4,20 @@ namespace App\Entities;
|
||||
|
||||
use App\Entities\CommonEntity;
|
||||
use App\Models\UserModel as Model;
|
||||
use CodeIgniter\Entity\Entity; // Entity 클래스를 명시적으로 use 하는 것이 좋습니다.
|
||||
|
||||
class UserEntity extends CommonEntity
|
||||
{
|
||||
const PK = Model::PK;
|
||||
const TITLE = Model::TITLE;
|
||||
const DEFAULT_STATUS = STATUS['AVAILABLE'];
|
||||
|
||||
/**
|
||||
* @var array Entity 속성을 DB에 저장하거나 DB에서 로드할 때의 형 변환 규칙
|
||||
* @var array DB 컬럼 타입이 VARCHAR(255)이고 CSV 형식으로 통일하기 위해 json-array 캐스팅을 제거합니다.
|
||||
*/
|
||||
protected $casts = [
|
||||
// 'role' 컬럼에 배열을 할당하면 DB에 JSON 문자열로 저장되며,
|
||||
// DB에서 로드할 때 JSON 문자열이 자동으로 PHP 배열로 변환됩니다.
|
||||
'role' => 'json-array',
|
||||
// 'role' => 'json-array', // 🚫 CSV 형식 저장을 위해 제거
|
||||
];
|
||||
|
||||
// --- Getter Methods ---
|
||||
|
||||
public function getID(): string
|
||||
{
|
||||
return (string) $this->attributes['id'];
|
||||
@ -31,8 +28,41 @@ class UserEntity extends CommonEntity
|
||||
return $this->attributes['passwd'];
|
||||
}
|
||||
|
||||
// $formDatas['passwd']에 평문 비밀번호가 들어있으면,
|
||||
// Model->insert시 Entity 생성자($formDatas)가 setPasswd()를 자동으로 호출합니다.
|
||||
/**
|
||||
* 사용자의 역할을 배열 형태로 반환합니다.
|
||||
* DB의 JSON 또는 CSV 형식 데이터를 모두 배열로 복구할 수 있는 로직을 포함합니다.
|
||||
* @return array
|
||||
*/
|
||||
public function getRole(): array
|
||||
{
|
||||
$role = $this->attributes['role'] ?? null;
|
||||
|
||||
// 1. 이미 배열인 경우 (방어적 코딩)
|
||||
if (is_array($role)) {
|
||||
return array_filter($role);
|
||||
}
|
||||
|
||||
// 2. 문자열 데이터인 경우 처리
|
||||
if (is_string($role) && !empty($role)) {
|
||||
// 2-a. JSON 디코딩 시도 (기존 DB의 JSON 형식 처리)
|
||||
$decodedRole = json_decode($role, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE && is_array($decodedRole)) {
|
||||
return $decodedRole;
|
||||
}
|
||||
|
||||
// 2-b. JSON이 아니면 CSV로 가정하고 변환
|
||||
$parts = explode(',', $role);
|
||||
// 각 요소의 불필요한 공백과 따옴표 제거
|
||||
$cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $parts);
|
||||
return array_filter($cleanedRoles);
|
||||
}
|
||||
|
||||
// 3. 변환에 실패했거나 데이터가 없는 경우 빈 배열 반환
|
||||
return [];
|
||||
}
|
||||
|
||||
// --- Setter Methods ---
|
||||
|
||||
public function setPasswd(string $password)
|
||||
{
|
||||
// 비밀번호를 암호화하여 저장합니다.
|
||||
@ -40,35 +70,31 @@ class UserEntity extends CommonEntity
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용자의 역할을 배열 형태로 반환합니다.
|
||||
* $casts에 의해 DB에서 읽어올 때 이미 배열로 변환될 것을 기대합니다.
|
||||
* @return array
|
||||
* Role 데이터가 Entity에 설정될 때 호출되어, 입력된 CSV/JSON 문자열을 정리 후
|
||||
* DB에 적합한 CSV 문자열로 최종 저장합니다.
|
||||
* @param mixed $role 입력 데이터 (문자열 또는 배열)
|
||||
*/
|
||||
public function getRole(): array
|
||||
public function setRole(mixed $role)
|
||||
{
|
||||
$role = $this->attributes['role'] ?? [];
|
||||
$roleArray = [];
|
||||
|
||||
// 1. $casts가 성공적으로 작동했거나, 이미 배열인 경우 바로 반환합니다.
|
||||
if (is_array($role)) {
|
||||
return $role;
|
||||
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);
|
||||
}
|
||||
} else if (is_array($role)) {
|
||||
// 이미 배열인 경우에도 데이터 정리를 한 번 거칩니다.
|
||||
$cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $role);
|
||||
$roleArray = array_filter($cleanedRoles);
|
||||
}
|
||||
|
||||
// 2. 캐스팅에 실패했으나 원본이 문자열로 남아있는 경우 (JSON 또는 CSV)
|
||||
if (is_string($role) && !empty($role)) {
|
||||
// 2-a. JSON 디코딩을 시도합니다.
|
||||
$decodedRole = json_decode($role, true);
|
||||
|
||||
if (json_last_error() === JSON_ERROR_NONE && is_array($decodedRole)) {
|
||||
return $decodedRole; // 유효한 JSON 배열인 경우
|
||||
}
|
||||
|
||||
// 2-b. JSON이 아니면 레거시 CSV 형식이라고 가정하고 explode로 변환합니다.
|
||||
if (defined('DEFAULTS') && isset(DEFAULTS['DELIMITER_ROLE'])) {
|
||||
return explode(DEFAULTS['DELIMITER_ROLE'], $role);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 변환에 실패했거나 데이터가 없는 경우 빈 배열 반환
|
||||
return [];
|
||||
// 💡 핵심: 최종적으로 DB에 삽입될 단일 CSV 문자열로 변환하여 저장합니다.
|
||||
$this->attributes['role'] = implode(',', $roleArray);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@ class UserHelper extends CommonHelper
|
||||
if (($viewDatas['control']['entity'] ?? null) instanceof UserEntity) {
|
||||
$value = $viewDatas['control']['entity']->getRole();
|
||||
}
|
||||
dd($value);
|
||||
$currentRoles = is_array($value)
|
||||
? array_map('strtolower', array_map('trim', $value))
|
||||
: [];
|
||||
@ -30,11 +29,6 @@ class UserHelper extends CommonHelper
|
||||
//체크박스를 순회하며 생성
|
||||
foreach ($viewDatas['control']['formOptions']['role'] as $key => $label) {
|
||||
$checked = in_array(strtolower(trim($key)), $currentRoles);
|
||||
var_dump($currentRoles);
|
||||
echo '<HR>';
|
||||
echo $key;
|
||||
echo $checked ? "{$key}TRUE" : "FALSE";
|
||||
dd($viewDatas['control']['formOptions']['role']);
|
||||
$form .= '<label class="me-3">';
|
||||
// form_checkbox에 들어가는 값($key)은 원본 값을 유지(저장용).
|
||||
$form .= form_checkbox('role[]', $key, $checked, array_merge(['id' => "role_{$key}"], $extras));
|
||||
|
||||
@ -101,24 +101,23 @@ abstract class CommonService
|
||||
}
|
||||
//CURD 결과처리용
|
||||
//DB 결과 처리 로직 통합 및 개선
|
||||
protected function handle_save_result(mixed $result, $entity): CommonEntity
|
||||
protected function handle_save_result(mixed $result, CommonEntity $entity): CommonEntity
|
||||
{
|
||||
if (!$result) {
|
||||
// static::class는 현재 호출된 자식 클래스 이름 반환
|
||||
throw new RuntimeException(static::class . "에서 {$entity->getTitle()} 등록/수정 중 DB 오류가 발생하였습니다.");
|
||||
throw new RuntimeException(static::class . "에서 " . __FUNCTION__ . "오류발생:" . $this->model->getLastQuery());
|
||||
}
|
||||
// 2. 최종 PK 값 결정 (insert/update 공통)
|
||||
$pkValue = $this->model->useAutoIncrement() && is_numeric($result) && (int)$result > 0
|
||||
$pk = $this->model->useAutoIncrement() && is_numeric($result) && (int)$result > 0
|
||||
? (int)$result
|
||||
: $entity->{$this->model->primaryKey};
|
||||
|
||||
if (empty($pkValue)) {
|
||||
if (empty($pk)) {
|
||||
throw new RuntimeException("{$entity->getTitle()} 저장 후 Primary Key를 확인할 수 없습니다.");
|
||||
}
|
||||
// 3. Entity 재조회 (수정 및 생성 모두 최신 DB 상태 반영)
|
||||
$savedEntity = $this->model->find($pkValue);
|
||||
$savedEntity = $this->model->find($pk);
|
||||
if (!$savedEntity) {
|
||||
throw new RuntimeException("등록/수정된 데이터를 찾을 수 없습니다. (PK: {$pkValue})");
|
||||
throw new RuntimeException("등록/수정된 데이터를 찾을 수 없습니다. (PK: {$pk})");
|
||||
}
|
||||
return $savedEntity;
|
||||
}
|
||||
@ -137,8 +136,8 @@ abstract class CommonService
|
||||
return $this->handle_save_result($result, $entity);
|
||||
}
|
||||
//수정용
|
||||
abstract protected function modify_process(array $formDatas): array;
|
||||
public function modify(object $dto): CommonEntity
|
||||
abstract protected function modify_process(CommonEntity $entity, array $formDatas): CommonEntity;
|
||||
public function modify(CommonEntity $entity, object $dto): CommonEntity
|
||||
{
|
||||
$formDatas = (array) $dto;
|
||||
//입력값 검증
|
||||
@ -146,10 +145,15 @@ abstract class CommonService
|
||||
if (!$validation->run($formDatas)) {
|
||||
throw new ValidationException(implode("\n", $validation->getErrors()));
|
||||
}
|
||||
list($pk, $updateData) = $this->modify_process($formDatas);
|
||||
$entity = new ($this->model->returnType)($updateData); // 재조회에 필요한 PK를 얻기 위함
|
||||
$result = $this->model->update($pk, $updateData);
|
||||
return $this->handle_save_result($result, $entity);
|
||||
$updatedEntity = $this->modify_process($entity, $formDatas);
|
||||
// 2. 💡 model->save() 사용: Primary Key가 있으므로 UPDATE를 수행하며,
|
||||
// Dirty Tracking에 의해 변경된 필드만 업데이트합니다.
|
||||
$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
|
||||
{
|
||||
|
||||
@ -49,6 +49,10 @@ class UserService extends CommonService
|
||||
//기본 기능부분
|
||||
protected function create_process(array $formDatas): UserEntity
|
||||
{
|
||||
if (isset($formDatas['confirmpassword'])) {
|
||||
unset($formDatas['confirmpassword']);
|
||||
}
|
||||
//UserEntity를 생성하면 Setter가 자동 호출됩니다.
|
||||
return new UserEntity($formDatas);
|
||||
}
|
||||
public function create(object $dto): UserEntity
|
||||
@ -58,20 +62,24 @@ class UserService extends CommonService
|
||||
}
|
||||
return parent::create($dto);
|
||||
}
|
||||
protected function modify_process(array $formDatas): array
|
||||
protected function modify_process(CommonEntity $entity, array $formDatas): UserEntity
|
||||
{
|
||||
// DTO에 PK가 포함되어 있다고 가정. 필요 시 데이터 가공
|
||||
return [
|
||||
$formDatas[$this->model->primaryKey], // PK
|
||||
$formDatas // Update Data
|
||||
];
|
||||
// CommonEntity 타입을 UserEntity로 형 변환합니다. (타입 힌트가 CommonEntity지만 실제로는 UserEntity 객체입니다.)
|
||||
$userEntity = $entity;
|
||||
if (isset($formDatas['confirmpassword'])) {
|
||||
unset($formDatas['confirmpassword']);
|
||||
}
|
||||
// 변경 사항을 Entity에 적용합니다. (Dirty Tracking 활성화)
|
||||
$userEntity->fill($formDatas);
|
||||
// 💡 부모 호출 제거: 변경된 Entity 객체를 반환합니다.
|
||||
return $userEntity;
|
||||
}
|
||||
public function modify(object $dto): UserEntity
|
||||
public function modify($entity, object $dto): UserEntity
|
||||
{
|
||||
if (!$dto instanceof UserDTO) {
|
||||
throw new RuntimeException(__METHOD__ . "에서 오류발생:" . get_class($dto) . "는 사용할수 없습니다.");
|
||||
}
|
||||
return parent::modify($dto);
|
||||
return parent::modify($entity, $dto);
|
||||
}
|
||||
//List 검색용
|
||||
//FormFilter 조건절 처리
|
||||
|
||||
Loading…
Reference in New Issue
Block a user