diff --git a/app/Controllers/Admin/SearchController.php b/app/Controllers/Admin/SearchController.php index 376cc2b..9cf5c25 100644 --- a/app/Controllers/Admin/SearchController.php +++ b/app/Controllers/Admin/SearchController.php @@ -2,7 +2,6 @@ namespace App\Controllers\Admin; -use App\Entities\Customer\ServiceEntity; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Psr\Log\LoggerInterface; @@ -33,6 +32,9 @@ class SearchController extends AdminController foreach ($rows as $row) { $uids[] = "'{$row->serviceinfo_uid}'"; } + if (count($uids) === 0) { + return $entities; + } //서비스별 서버리스트 // $childServers = []; foreach ($this->service->getEntities([sprintf("uid IN (%s)", implode(",", $uids)) => null]) as $entity) { diff --git a/app/DTOs/CommonDTO.php b/app/DTOs/CommonDTO.php index 48745da..2b16cd4 100644 --- a/app/DTOs/CommonDTO.php +++ b/app/DTOs/CommonDTO.php @@ -9,64 +9,61 @@ abstract class CommonDTO { protected function __construct(array $datas = []) { - if (empty($datas)) return; + if (empty($datas)) + return; $reflection = new ReflectionClass($this); foreach ($datas as $key => $value) { - if (!$reflection->hasProperty($key)) continue; + if (!$reflection->hasProperty($key)) + continue; $property = $reflection->getProperty($key); $type = $property->getType(); $assignValue = $value; - // 1. 빈 문자열('') 처리 로직 개선 + // *_uid 규칙 처리 + if ($value === '' && preg_match('/_uid$/', $key)) { + if ($type instanceof ReflectionNamedType && $type->allowsNull()) { + $this->{$key} = null; + continue; + } + } + + // 1) 기존: 빈 문자열('') 처리 if ($value === '') { - // 프로퍼티가 null을 허용하는 경우에만 null 할당 if ($type instanceof ReflectionNamedType && $type->allowsNull()) { $assignValue = null; } else { - // null을 허용하지 않는 경우, 타입별 기본값 지정 $typeName = ($type instanceof ReflectionNamedType) ? $type->getName() : ''; $assignValue = ($typeName === 'int' || $typeName === 'float') ? 0 : ''; } } - // 2. 값이 존재할 때의 타입별 캐스팅 로직 + // 2) 기존: 타입별 캐스팅 elseif ($type instanceof ReflectionNamedType) { $typeName = $type->getName(); - // 타입이 array이고 입력값이 문자열인 경우 (CSV -> Array) if ($typeName === 'array' && is_string($value)) { $assignValue = explode(DEFAULTS["DELIMITER_ROLE"], $value); - } - // 타입이 int이고 입력값이 숫자형인 경우 - elseif ($typeName === 'int' && is_numeric($value)) { + } elseif ($typeName === 'int' && is_numeric($value)) { $assignValue = (int) $value; - } - // 타입이 float이고 입력값이 숫자형인 경우 - elseif ($typeName === 'float' && is_numeric($value)) { + } elseif ($typeName === 'float' && is_numeric($value)) { $assignValue = (float) $value; } } - // 최종 값 할당 $this->{$key} = $assignValue; } } - // [중요] final 해제 또는 로직 변경 public function toArray(): array { - // get_object_vars는 protected를 가져오지 못하므로 - // Reflection을 사용하여 모든 프로퍼티를 가져오되, - // 값을 가져올 때는 $this->{$name}을 통해 Getter나 매직메서드가 작동하게 합니다. $reflection = new ReflectionClass($this); $properties = $reflection->getProperties(); $result = []; foreach ($properties as $property) { $name = $property->getName(); - // $this->$name 처리를 통해 자식의 __get()이 호출되도록 유도 $result[$name] = $this->{$name}; } diff --git a/app/DTOs/Customer/Wallet/AccountDTO.php b/app/DTOs/Customer/Wallet/AccountDTO.php index d2558c7..b60ba3e 100644 --- a/app/DTOs/Customer/Wallet/AccountDTO.php +++ b/app/DTOs/Customer/Wallet/AccountDTO.php @@ -4,6 +4,8 @@ namespace App\DTOs\Customer\Wallet; class AccountDTO extends WalletDTO { + public ?int $user_uid = null; + public ?int $clientinfo_uid = null; public string $bank = ''; public string $alias = ''; public string $issue_at = ''; diff --git a/app/DTOs/Customer/Wallet/CouponDTO.php b/app/DTOs/Customer/Wallet/CouponDTO.php index 944f8e5..9ec3578 100644 --- a/app/DTOs/Customer/Wallet/CouponDTO.php +++ b/app/DTOs/Customer/Wallet/CouponDTO.php @@ -4,6 +4,9 @@ namespace App\DTOs\Customer\Wallet; class CouponDTO extends WalletDTO { + public ?int $user_uid = null; + public ?int $clientinfo_uid = null; + public function __construct(array $datas = []) { parent::__construct($datas); diff --git a/app/DTOs/Customer/Wallet/PointDTO.php b/app/DTOs/Customer/Wallet/PointDTO.php index 0e0fcc4..0c487d1 100644 --- a/app/DTOs/Customer/Wallet/PointDTO.php +++ b/app/DTOs/Customer/Wallet/PointDTO.php @@ -4,6 +4,9 @@ namespace App\DTOs\Customer\Wallet; class PointDTO extends WalletDTO { + public ?int $user_uid = null; + public ?int $clientinfo_uid = null; + public function __construct(array $datas = []) { parent::__construct($datas); diff --git a/app/DTOs/Equipment/CHASSISDTO.php b/app/DTOs/Equipment/CHASSISDTO.php index 9568c41..ccd3223 100644 --- a/app/DTOs/Equipment/CHASSISDTO.php +++ b/app/DTOs/Equipment/CHASSISDTO.php @@ -12,11 +12,11 @@ class CHASSISDTO extends CommonDTO public int $used = 0; public int $stock = 0; public string $status = ''; - public int $cpuinfo_uid = 0; + public ?int $cpuinfo_uid = null; public int $cpu_cnt = 0; - public int $raminfo_uid = 0; + public ?int $raminfo_uid = null; public int $ram_cnt = 0; - public int $diskinfo_uid = 0; + public ?int $diskinfo_uid = null; public int $disk_cnt = 0; public function __construct(array $datas = []) diff --git a/app/DTOs/Equipment/ServerDTO.php b/app/DTOs/Equipment/ServerDTO.php index 828674b..a3fa5ea 100644 --- a/app/DTOs/Equipment/ServerDTO.php +++ b/app/DTOs/Equipment/ServerDTO.php @@ -7,6 +7,9 @@ use App\DTOs\CommonDTO; class ServerDTO extends CommonDTO { public ?int $uid = null; + public ?int $user_uid = null; + public ?int $clientinfo_uid = null; + public ?int $serviceinfo_uid = null; public ?int $chassisinfo_uid = null; public ?int $switchinfo_uid = null; public string $code = ''; diff --git a/app/DTOs/Equipment/ServerPartDTO.php b/app/DTOs/Equipment/ServerPartDTO.php index 7c926f3..2f9efca 100644 --- a/app/DTOs/Equipment/ServerPartDTO.php +++ b/app/DTOs/Equipment/ServerPartDTO.php @@ -7,10 +7,10 @@ use App\DTOs\CommonDTO; class ServerPartDTO extends CommonDTO { public ?int $uid = null; - public ?string $clientinfo_uid = null; - public ?string $serviceinfo_uid = null; - public ?string $serverinfo_uid = null; + public ?int $clientinfo_uid = null; public ?int $part_uid = null; + public ?int $serviceinfo_uid = null; + public ?int $serverinfo_uid = null; public string $title = ''; public string $type = ''; public string $billing = ''; diff --git a/app/Entities/Customer/ClientEntity.php b/app/Entities/Customer/ClientEntity.php index 35ec97e..b61e74d 100644 --- a/app/Entities/Customer/ClientEntity.php +++ b/app/Entities/Customer/ClientEntity.php @@ -113,6 +113,7 @@ class ClientEntity extends CustomerEntity $cleanedRoles = array_map(fn($item) => trim((string) ($item ?? ''), " \t\n\r\0\x0B\""), $roleArray); $roleArray = array_filter($cleanedRoles); // 최종적으로 DB에 삽입될 단일 CSV 문자열로 변환하여 저장합니다. - $this->role = implode(DEFAULTS["DELIMITER_ROLE"], $roleArray); + // ✅ setter함수는 반드시 attributes에 저장 + $this->attributes['role'] = implode(DEFAULTS["DELIMITER_ROLE"], $roleArray); } } diff --git a/app/Entities/Equipment/ServerPartEntity.php b/app/Entities/Equipment/ServerPartEntity.php index 1d57509..536a0b9 100644 --- a/app/Entities/Equipment/ServerPartEntity.php +++ b/app/Entities/Equipment/ServerPartEntity.php @@ -9,13 +9,6 @@ class ServerPartEntity extends EquipmentEntity const PK = ServerPartModel::PK; const TITLE = ServerPartModel::TITLE; - protected $casts = [ - 'clientinfo_uid' => '?integer', - 'part_uid' => '?integer', - 'serverinfo_uid' => 'integer', - 'serviceinfo_uid' => '?integer', - ]; - protected $attributes = [ 'clientinfo_uid' => null, 'part_uid' => null, diff --git a/app/Entities/UserEntity.php b/app/Entities/UserEntity.php index 1db7d24..84e98f0 100644 --- a/app/Entities/UserEntity.php +++ b/app/Entities/UserEntity.php @@ -70,7 +70,8 @@ class UserEntity extends CommonEntity { // 입력된 비밀번호가 null이 아니고 비어있지 않을 때만 해시 처리 if (!empty($password)) { - $this->passwd = password_hash($password, PASSWORD_BCRYPT); + // ✅ setter함수는 반드시 attributes에 저장 + $this->attributes['passwd'] = password_hash($password, PASSWORD_BCRYPT); } } @@ -99,6 +100,7 @@ class UserEntity extends CommonEntity $cleanedRoles = array_map(fn($item) => trim((string) ($item ?? ''), " \t\n\r\0\x0B\""), $roleArray); $roleArray = array_filter($cleanedRoles); // 최종적으로 DB에 삽입될 단일 CSV 문자열로 변환하여 저장합니다. - $this->role = implode(DEFAULTS["DELIMITER_ROLE"], $roleArray); + // ✅ setter함수는 반드시 attributes에 저장 + $this->attributes['role'] = implode(DEFAULTS["DELIMITER_ROLE"], $roleArray); } } diff --git a/app/Services/CommonService.php b/app/Services/CommonService.php index 1886f51..3f73842 100644 --- a/app/Services/CommonService.php +++ b/app/Services/CommonService.php @@ -235,15 +235,19 @@ abstract class CommonService protected function save_process(CommonEntity $entity): CommonEntity { - // INSERT 시 Entity의 PK는 0 또는 NULL이어야 함 (DB가 ID를 생성하도록) - $initialPK = $entity->getPK(); - log_message('debug', __FUNCTION__ . ":" . var_export($entity, true)); - $result = $this->model->save($entity); - log_message('debug', __FUNCTION__ . ":" . $this->model->getLastQuery()); - // 최종적으로 DB에 반영된 PK를 반환받습니다. (UPDATE이면 기존 PK, INSERT이면 새 PK) - $entity->{$this->getPKField()} = $this->handle_save_result($result, $initialPK); - // handle_save_result에서 확인된 최종 PK를 사용하여 DB에서 최신 엔티티를 가져옴 - return $entity; + try { + // INSERT 시 Entity의 PK는 0 또는 NULL이어야 함 (DB가 ID를 생성하도록) + $initialPK = $entity->getPK(); + $result = $this->model->save($entity); + // 최종적으로 DB에 반영된 PK를 반환받습니다. (UPDATE이면 기존 PK, INSERT이면 새 PK) + $entity->{$this->getPKField()} = $this->handle_save_result($result, $initialPK); + // handle_save_result에서 확인된 최종 PK를 사용하여 DB에서 최신 엔티티를 가져옴 + return $entity; + } catch (\Throwable $e) { + log_message('debug', __FUNCTION__ . ":" . var_export($entity, true)); + log_message('debug', __FUNCTION__ . ":" . $this->model->getLastQuery()); + throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생:" . $e->getMessage()); + } } //생성용 @@ -257,6 +261,7 @@ abstract class CommonService } $entityClass = $this->getEntityClass(); $entity = new $entityClass($formDatas); + dd($entity); if (!$entity instanceof $entityClass) { throw new RuntimeException("Return Type은 {$entityClass}만 가능"); }