trafficmonitor init...1

This commit is contained in:
choi.jh 2025-11-14 17:04:12 +09:00
parent b05dfed46c
commit 102ba52c16
18 changed files with 352 additions and 203 deletions

View File

@ -4,7 +4,6 @@ namespace App\Controllers\Admin;
use App\Controllers\CommonController; use App\Controllers\CommonController;
use App\DTOs\CommonDTO;
use App\Entities\CommonEntity; use App\Entities\CommonEntity;
use App\Traits\LogTrait; use App\Traits\LogTrait;
use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\HTTP\RedirectResponse;
@ -27,7 +26,6 @@ abstract class AdminController extends CommonController
parent::initController($request, $response, $logger); parent::initController($request, $response, $logger);
$this->addActionPaths(self::PATH); $this->addActionPaths(self::PATH);
} }
abstract protected function createDTO(array $formDatas): CommonDTO;
final protected function getLayout(): string final protected function getLayout(): string
{ {
return 'admin'; return 'admin';
@ -47,7 +45,7 @@ abstract class AdminController extends CommonController
$this->addViewDatas('formRules', $this->service->getFormService()->getFormRules()); $this->addViewDatas('formRules', $this->service->getFormService()->getFormRules());
$this->addViewDatas('formFilters', $this->service->getFormService()->getFormFilters()); $this->addViewDatas('formFilters', $this->service->getFormService()->getFormFilters());
$this->addViewDatas('formOptions', $this->service->getFormService()->getFormOptions()); $this->addViewDatas('formOptions', $this->service->getFormService()->getFormOptions());
$this->addViewDatas('index_actionButtons', $this->service->getFormService()->getActionButtons()); $this->addViewDatas('index_actionButtons', $this->service->getFormService()->getactionButtons());
$this->addViewDatas('index_batchjobFields', $this->service->getFormService()->getBatchjobFilters()); $this->addViewDatas('index_batchjobFields', $this->service->getFormService()->getBatchjobFilters());
$this->addViewDatas('index_batchjobButtons', $this->service->getFormService()->getBatchjobButtons()); $this->addViewDatas('index_batchjobButtons', $this->service->getFormService()->getBatchjobButtons());
parent::action_init_process($action); parent::action_init_process($action);
@ -72,7 +70,7 @@ abstract class AdminController extends CommonController
protected function create_process(): CommonEntity protected function create_process(): CommonEntity
{ {
//요청 데이터를 DTO 객체로 변환 //요청 데이터를 DTO 객체로 변환
$dto = $this->createDTO($this->request->getPost()); $dto = $this->service->createDTO($this->request->getPost());
return $this->service->create($dto); return $this->service->create($dto);
} }
final public function create(): string|RedirectResponse final public function create(): string|RedirectResponse
@ -113,7 +111,7 @@ abstract class AdminController extends CommonController
protected function modify_process($uid): CommonEntity protected function modify_process($uid): CommonEntity
{ {
//요청 데이터를 DTO 객체로 변환 //요청 데이터를 DTO 객체로 변환
$dto = $this->createDTO($this->request->getPost()); $dto = $this->service->createDTO($this->request->getPost());
return $this->service->modify($uid, $dto); return $this->service->modify($uid, $dto);
} }
final public function modify($uid): string|RedirectResponse final public function modify($uid): string|RedirectResponse
@ -128,46 +126,64 @@ abstract class AdminController extends CommonController
return $this->action_redirect_process('error', "{$this->getTitle()}에서 {$uid} 수정 오류:" . $e->getMessage()); return $this->action_redirect_process('error', "{$this->getTitle()}에서 {$uid} 수정 오류:" . $e->getMessage());
} }
} }
protected function batchjob_process($uid, array $formDatas): CommonEntity
{
return $this->service->batchjob($uid, $formDatas);
}
final public function batchjob(): string|RedirectResponse final public function batchjob(): string|RedirectResponse
{ {
try { try {
$action = __FUNCTION__; $postDatas = $this->request->getPost();
$this->action_init_process($action); //1. postDatas에서 선택된 uids 정보 추출
$selectedFields = []; $uids = [];
if (isset($postDatas['batchjob_uids'])) {
$uids = $postDatas['batchjob_uids'];
unset($postDatas['batchjob_uids']);
}
if (empty($uids)) {
throw new \Exception("적용할 리스트을 선택하셔야합니다.");
}
//2. postDatas에서 필요없는 정보 버림
unset($postDatas['batchjob_submit']);
//3. 나머지는 $formDatas로 사용할 데이터 추출
$formDatas = []; $formDatas = [];
foreach ($this->service->getFormService->getBatchjobFilters() as $field) { foreach ($postDatas as $field => $value) {
$value = $this->request->getPost($field); if ($value !== "") {
if ($value) {
$selectedFields[] = $field;
$formDatas[$field] = $value; $formDatas[$field] = $value;
} }
} }
if (!count($selectedFields)) { if (empty($formDatas)) {
throw new \Exception("변경할 조건항목을 선택하셔야합니다."); throw new \Exception("변경할 조건항목을 선택하셔야합니다.");
} }
//변경할 UIDS 정의 //4. 데이터가 있는 필드 추출
$uids = $this->request->getPost('batchjob_uids[]'); $selectedFields = array_keys($formDatas);
if (!is_array($uids) || !count($uids)) { //초기화
throw new \Exception("적용할 리스트을 선택하셔야합니다.");
}
$this->service->getFormService()->setFormFields($selectedFields); $this->service->getFormService()->setFormFields($selectedFields);
$this->service->getFormService()->setFormRules($action, $selectedFields); $this->service->getFormService()->setFormRules(__FUNCTION__, $selectedFields);
$this->service->getFormService()->setFormFilters($selectedFields); $this->service->getFormService()->setFormFilters($selectedFields);
$this->service->getFormService()->setFormOptions($selectedFields); $this->service->getFormService()->setFormOptions($selectedFields);
$entities = []; $entities = [];
$errors = []; $error = 0;
foreach ($uids as $uid) { foreach ($uids as $uid) {
try { try {
$entities[] = $this->modify_process($uid); $entities[] = $this->batchjob_process($uid, $formDatas);
} catch (ValidationException $e) { } catch (ValidationException $e) {
$errors[] = "{$this->getTitle()}에서 {$uid} 수정 검증오류:" . $e->getMessage(); log_message('error', "{$this->getTitle()}에서 {$uid} 수정 검증오류:" . $e->getMessage());
$error++;
} catch (\Exception $e) { } catch (\Exception $e) {
$errors[] = "{$this->getTitle()}에서 {$uid} 수정 오류:" . $e->getMessage(); log_message('error', "{$this->getTitle()}에서 {$uid} 수정 오류:" . $e->getMessage());
$error++;
} }
} }
return $this->action_modal_process("{$this->getTitle()}에서 " . count($entities) . "개, 총:" . count($uids) . " 수정이 완료되었습니다."); return $this->action_redirect_process('info', sprintf(
"%s에서 %s개 처리완료, %s개 오류, 총:%s개 수정이 완료되었습니다.",
$this->getTitle(),
count($entities),
$error,
count($uids)
));
} catch (\Exception $e) { } catch (\Exception $e) {
return $this->action_redirect_process('error', "{$this->getTitle()}에서 {$uid} 수정 오류:" . $e->getMessage()); return $this->action_redirect_process('error', "{$this->getTitle()}에서 일괄작업처리 오류:" . $e->getMessage());
} }
} }
protected function delete_process($uid): CommonEntity protected function delete_process($uid): CommonEntity
@ -183,6 +199,44 @@ abstract class AdminController extends CommonController
return $this->action_redirect_process('error', "{$this->getTitle()}에서 {$uid} 삭제 오류:" . $e->getMessage()); return $this->action_redirect_process('error', "{$this->getTitle()}에서 {$uid} 삭제 오류:" . $e->getMessage());
} }
} }
protected function batchjob_delete_process($uid): CommonEntity
{
return $this->service->batchjob_delete($uid);
}
final public function batchjob_delete(): string|RedirectResponse
{
try {
$postDatas = $this->request->getPost();
//1. postDatas에서 선택된 uids 정보 추출
$uids = [];
if (isset($postDatas['batchjob_uids'])) {
$uids = $postDatas['batchjob_uids'];
unset($postDatas['batchjob_uids']);
}
if (empty($uids)) {
throw new \Exception("삭제할 리스트을 선택하셔야합니다.");
}
$entities = [];
$error = 0;
foreach ($uids as $uid) {
try {
$entities[] = $this->batchjob_delete_process($uid);
} catch (\Exception $e) {
log_message('error', "{$this->getTitle()}에서 {$uid} 삭제 오류:" . $e->getMessage());
$error++;
}
}
return $this->action_redirect_process('info', sprintf(
"%s에서 %s개 처리완료, %s개 오류, 총:%s개 일괄삭제가 완료되었습니다.",
$this->getTitle(),
count($entities),
$error,
count($uids)
));
} catch (\Exception $e) {
return $this->action_redirect_process('error', "{$this->getTitle()}에서 일괄삭제 오류:" . $e->getMessage());
}
}
protected function view_process($uid): CommonEntity protected function view_process($uid): CommonEntity
{ {
if (!$uid) { if (!$uid) {

View File

@ -2,7 +2,6 @@
namespace App\Controllers\Admin; namespace App\Controllers\Admin;
use App\DTOs\CollectorDTO;
use App\Entities\CollectorEntity; use App\Entities\CollectorEntity;
use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\ResponseInterface;
@ -19,14 +18,13 @@ class CollectorController extends AdminController
} }
$this->addActionPaths(self::PATH); $this->addActionPaths(self::PATH);
} }
protected function createDTO(array $formDatas): CollectorDTO
{
return new CollectorDTO($formDatas);
}
protected function action_init_process(string $action): void protected function action_init_process(string $action): void
{ {
$fields = ['trafficinfo_uid', 'in', 'out', 'raw_in', 'raw_out']; $fields = ['trafficinfo_uid', 'in', 'out', 'raw_in', 'raw_out'];
$filters = ['trafficinfo_uid']; $filters = ['trafficinfo_uid'];
$batchjobFilters = $filters;
$actionButtons = ['view' => ICONS['SEARCH']];
$batchjobButtons = [];
parent::action_init_process($action); parent::action_init_process($action);
switch ($action) { switch ($action) {
case 'create': case 'create':
@ -49,7 +47,9 @@ class CollectorController extends AdminController
$this->service->getFormService()->setFormRules($action, $fields); $this->service->getFormService()->setFormRules($action, $fields);
$this->service->getFormService()->setFormFilters($filters); $this->service->getFormService()->setFormFilters($filters);
$this->service->getFormService()->setFormOptions($filters); $this->service->getFormService()->setFormOptions($filters);
$this->service->getFormService()->setBatchjobFilters($filters); $this->service->getFormService()->setBatchjobFilters($batchjobFilters);
$this->service->getFormService()->setActionButtons($actionButtons);
$this->service->getFormService()->setBatchjobButtons($batchjobButtons);
parent::action_init_process($action); parent::action_init_process($action);
} }
protected function create_process(): CollectorEntity protected function create_process(): CollectorEntity
@ -72,4 +72,8 @@ class CollectorController extends AdminController
{ {
return parent::view_process($uid); return parent::view_process($uid);
} }
protected function batchjob_process($uid, array $formDatas): CollectorEntity
{
return parent::batchjob_process($uid, $formDatas);
}
} }

View File

@ -2,7 +2,6 @@
namespace App\Controllers\Admin; namespace App\Controllers\Admin;
use App\DTOs\MylogDTO;
use App\Entities\MylogEntity; use App\Entities\MylogEntity;
use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\ResponseInterface;
@ -19,14 +18,11 @@ class MylogController extends AdminController
} }
$this->addActionPaths(self::PATH); $this->addActionPaths(self::PATH);
} }
protected function createDTO(array $formDatas): MylogDTO
{
return new MylogDTO($formDatas);
}
protected function action_init_process(string $action): void protected function action_init_process(string $action): void
{ {
$fields = ['title', 'content']; $fields = ['title', 'content'];
$filters = []; $filters = [];
$batchjobFilters = $filters;
parent::action_init_process($action); parent::action_init_process($action);
switch ($action) { switch ($action) {
case 'create': case 'create':
@ -49,7 +45,7 @@ class MylogController extends AdminController
$this->service->getFormService()->setFormRules($action, $fields); $this->service->getFormService()->setFormRules($action, $fields);
$this->service->getFormService()->setFormFilters($filters); $this->service->getFormService()->setFormFilters($filters);
$this->service->getFormService()->setFormOptions($filters); $this->service->getFormService()->setFormOptions($filters);
$this->service->getFormService()->setBatchjobFilters($filters); $this->service->getFormService()->setBatchjobFilters($batchjobFilters);
parent::action_init_process($action); parent::action_init_process($action);
} }
protected function create_process(): MylogEntity protected function create_process(): MylogEntity
@ -72,4 +68,8 @@ class MylogController extends AdminController
{ {
return parent::view_process($uid); return parent::view_process($uid);
} }
protected function batchjob_process($uid, array $formDatas): MylogEntity
{
return parent::batchjob_process($uid, $formDatas);
}
} }

View File

@ -2,7 +2,6 @@
namespace App\Controllers\Admin; namespace App\Controllers\Admin;
use App\DTOs\TrafficDTO;
use App\Entities\TrafficEntity; use App\Entities\TrafficEntity;
use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\ResponseInterface;
@ -19,14 +18,12 @@ class TrafficController extends AdminController
} }
$this->addActionPaths(self::PATH); $this->addActionPaths(self::PATH);
} }
protected function createDTO(array $formDatas): TrafficDTO
{
return new TrafficDTO($formDatas);
}
protected function action_init_process(string $action): void protected function action_init_process(string $action): void
{ {
$fields = ['client', 'server', 'switch', 'server_ip', 'interface', 'ip', 'status']; $fields = ['client', 'server', 'switch', 'server_ip', 'interface', 'ip', 'status'];
$filters = ['status']; $filters = ['status'];
$batchjobFilters = $filters;
$actionButtons = ['view' => ICONS['SEARCH'], 'dashboard' => ICONS['CHART'], 'delete' => ICONS['DELETE']];
switch ($action) { switch ($action) {
case 'create': case 'create':
case 'create_form': case 'create_form':
@ -48,7 +45,8 @@ class TrafficController extends AdminController
$this->service->getFormService()->setFormRules($action, $fields); $this->service->getFormService()->setFormRules($action, $fields);
$this->service->getFormService()->setFormFilters($filters); $this->service->getFormService()->setFormFilters($filters);
$this->service->getFormService()->setFormOptions($filters); $this->service->getFormService()->setFormOptions($filters);
$this->service->getFormService()->setBatchjobFilters($filters); $this->service->getFormService()->setBatchjobFilters($batchjobFilters);
$this->service->getFormService()->setActionButtons($actionButtons);
parent::action_init_process($action); parent::action_init_process($action);
} }
protected function create_process(): TrafficEntity protected function create_process(): TrafficEntity
@ -71,6 +69,10 @@ class TrafficController extends AdminController
{ {
return parent::view_process($uid); return parent::view_process($uid);
} }
protected function batchjob_process($uid, array $formDatas): TrafficEntity
{
return parent::batchjob_process($uid, $formDatas);
}
public function dashboard($uid): string public function dashboard($uid): string
{ {
$entity = $this->service->getEntity($uid); $entity = $this->service->getEntity($uid);

View File

@ -2,7 +2,6 @@
namespace App\Controllers\Admin; namespace App\Controllers\Admin;
use App\DTOs\UserDTO;
use App\Entities\UserEntity; use App\Entities\UserEntity;
use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\ResponseInterface;
@ -19,15 +18,12 @@ class UserController extends AdminController
} }
$this->addActionPaths(self::PATH); $this->addActionPaths(self::PATH);
} }
protected function createDTO(array $formDatas): UserDTO
{
return new UserDTO($formDatas);
}
//Action작업관련 //Action작업관련
protected function action_init_process(string $action): void protected function action_init_process(string $action): void
{ {
$fields = ['id', 'passwd', 'confirmpassword', 'name', 'email', 'mobile', 'role']; $fields = ['id', 'passwd', 'confirmpassword', 'name', 'email', 'mobile', 'role'];
$filters = ['role', 'status']; $filters = ['role', 'status'];
$batchjobFilters = ['status'];
switch ($action) { switch ($action) {
case 'create': case 'create':
case 'create_form': case 'create_form':
@ -49,7 +45,7 @@ class UserController extends AdminController
$this->service->getFormService()->setFormRules($action, $fields); $this->service->getFormService()->setFormRules($action, $fields);
$this->service->getFormService()->setFormFilters($filters); $this->service->getFormService()->setFormFilters($filters);
$this->service->getFormService()->setFormOptions($filters); $this->service->getFormService()->setFormOptions($filters);
$this->service->getFormService()->setBatchjobFilters($filters); $this->service->getFormService()->setBatchjobFilters($batchjobFilters);
parent::action_init_process($action); parent::action_init_process($action);
} }
protected function create_form_process(array $formDatas = []): array protected function create_form_process(array $formDatas = []): array
@ -77,4 +73,8 @@ class UserController extends AdminController
{ {
return parent::view_process($uid); return parent::view_process($uid);
} }
protected function batchjob_process($uid, array $formDatas): UserEntity
{
return parent::batchjob_process($uid, $formDatas);
}
} }

View File

@ -4,10 +4,11 @@ namespace App\DTOs\Auth;
use App\DTOs\CommonDTO; use App\DTOs\CommonDTO;
class AuthDTO extends CommonDTO abstract class AuthDTO extends CommonDTO
{ {
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
} }
abstract public function toArray();
} }

View File

@ -9,7 +9,6 @@ class CollectorForm extends CommonForm
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
$this->setActionButtons(['view' => ICONS['SEARCH']]);
} }
public function getFormRule(string $action, string $field): string public function getFormRule(string $action, string $field): string

View File

@ -36,39 +36,32 @@ abstract class CommonForm
//$fields 매치된것만 반환, []->전체 //$fields 매치된것만 반환, []->전체
final public function getFormFields(array $fields = []): array final public function getFormFields(array $fields = []): array
{ {
// 1. $fields 배열이 비어있는지 확인합니다.
// getFormFields('create') 와 같이 호출될 경우 $fields는 빈 배열[]이 됩니다.
if (empty($fields)) { if (empty($fields)) {
// 비어있다면, _formFields 전체를 반환합니다.
return $this->_formFields; return $this->_formFields;
} }
// $fields의 값(원하는 필드명)을 키로 변환합니다. // _formFields와 키를 비교하여 교집합을 반환합니다. $fields에 지정된 필드 정의만 추출됩니다.
// 예: ['test1'] -> ['test1' => 0] return array_intersect_key($this->_formFields, array_flip($fields));
$fieldsAsKeys = array_flip($fields);
// _formFields와 $fieldsAsKeys 간의 키를 비교하여 교집합을 반환합니다.
// 즉, $fields에 지정된 필드 정의만 추출됩니다.
return array_intersect_key($this->_formFields, $fieldsAsKeys);
} }
final public function setFormRules(string $action, array $fields): void final public function setFormRules(string $action, array $fields, $formRules = []): void
{ {
foreach ($fields as $field) { foreach ($fields as $field) {
$this->_formRules[$field] = $this->getFormRule($action, $field); $formRules[$field] = $formRules[$field] ?? $this->getFormRule($action, $field);
} }
$this->_formRules = $formRules;
} }
//$fields 매치된것만 반환, []->전체
final public function getFormRules(array $fields = []): array final public function getFormRules(array $fields = []): array
{ {
if (empty($fields)) { if (empty($fields)) {
return $this->_formRules; return $this->_formRules;
} }
$fieldsAsKeys = array_flip($fields); return array_intersect_key($this->_formRules, array_flip($fields));
return array_intersect_key($this->_formRules, $fieldsAsKeys);
} }
final public function setFormOptions(array $fields): void final public function setFormOptions(array $fields, $formOptions = []): void
{ {
foreach ($fields as $field) { foreach ($fields as $field) {
$this->_formOptions[$field] = $this->getFormOption($field); $formOptions[$field] = $formOptions[$field] ?? $this->getFormOption($field);
} }
$this->_formOptions = $formOptions;
// dd($this->_formOptions[$field]); // dd($this->_formOptions[$field]);
} }
//$fields 매치된것만 반환, []->전체 //$fields 매치된것만 반환, []->전체
@ -77,8 +70,7 @@ abstract class CommonForm
if (empty($fields)) { if (empty($fields)) {
return $this->_formOptions; return $this->_formOptions;
} }
$fieldsAsKeys = array_flip($fields); return array_intersect_key($this->_formOptions, array_flip($fields));
return array_intersect_key($this->_formOptions, $fieldsAsKeys);
} }
final public function setFormFilters(array $fields): void final public function setFormFilters(array $fields): void
{ {
@ -96,17 +88,17 @@ abstract class CommonForm
{ {
return $this->_batchjobFilters; return $this->_batchjobFilters;
} }
final public function setActionButtons(array $buttions): array final public function setActionButtons(array $buttons): array
{ {
return $this->_actionButtons = $buttions; return $this->_actionButtons = $buttons;
} }
final public function getActionButtons(): array final public function getactionButtons(): array
{ {
return $this->_actionButtons; return $this->_actionButtons;
} }
final public function setBatchjobButtons(array $buttions): array final public function setBatchjobButtons(array $buttons): array
{ {
return $this->_batchjobButtons = $buttions; return $this->_batchjobButtons = $buttons;
} }
final public function getBatchjobButtons(): array final public function getBatchjobButtons(): array
{ {

View File

@ -9,7 +9,6 @@ class TrafficForm extends CommonForm
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
$this->setActionButtons(['view' => ICONS['SEARCH'], 'dashboard' => ICONS['CHART'], 'delete' => ICONS['DELETE']]);
} }
public function getFormRule(string $action, string $field): string public function getFormRule(string $action, string $field): string
{ {

View File

@ -0,0 +1,37 @@
<?php
namespace App\Libraries;
class SNMPLibrary
{
private $_ip = null;
private $_community = null;
private $_version = '2c';
public function __construct(string $ip, string $community, ?string $version = null)
{
$this->_ip = $ip;
$this->_community = $community;
}
public function get(string $fullOid): ?int
{
// snmp2_get을 사용하여 SNMP v2c로 요청
// 💡 snmp2_get() 함수가 존재하지 않는다는 LSP 오류를 무시하기 위해 @suppress 태그 사용
/** @phpstan-ignore-next-line */
$result = @snmp2_get($this->_ip, $this->_community, $fullOid, 100000, 3);
if ($result === false || $result === null) {
log_message('error', "SNMP 통신 실패: {$this->_ip} ({$fullOid}, Community: {$this->_community})");
return null;
}
// 💡 정규식 수정: /\d+$/ (문자열 끝의 숫자만 추출)
if (preg_match('/\d+$/', $result, $matches)) {
// SNMP Counter는 64비트 BigInt가 될 수 있으므로, 64비트 PHP 환경에서는
// (int) 캐스팅을 사용하여 안전하게 64비트 정수로 변환합니다.
// (BigInt 값을 DB에 저장할 때도 PHP의 정수형/문자열 처리 능력이 중요합니다.)
return (int)$matches[0];
}
return null;
}
}

View File

@ -3,6 +3,7 @@
namespace App\Services\Auth; namespace App\Services\Auth;
use App\DTOs\Auth\AuthDTO; use App\DTOs\Auth\AuthDTO;
use App\Entities\CommonEntity;
use App\Entities\UserEntity; use App\Entities\UserEntity;
use App\Helpers\AuthHelper; use App\Helpers\AuthHelper;
use App\Libraries\AuthContext; use App\Libraries\AuthContext;
@ -56,10 +57,7 @@ abstract class AuthService
{ {
return $isArray ? $this->_classPaths : implode($delimeter, $this->_classPaths); return $isArray ? $this->_classPaths : implode($delimeter, $this->_classPaths);
} }
protected function getEntity_process(mixed $entity): mixed abstract protected function getEntity_process(mixed $entity): CommonEntity;
{
return $entity;
}
final public function getEntity(string|int|array $where, ?string $message = null): mixed final public function getEntity(string|int|array $where, ?string $message = null): mixed
{ {
try { try {
@ -100,7 +98,7 @@ abstract class AuthService
abstract protected function login_process(array $formDatas): UserEntity; abstract protected function login_process(array $formDatas): UserEntity;
public function login(AuthDTO $dto): UserEntity public function login(AuthDTO $dto): UserEntity
{ {
$formDatas = (array)$dto; $formDatas = $dto->toArray();
// dd($formDatas); // dd($formDatas);
//입력값 검증 //입력값 검증
if (!$this->getFormService()->validate($formDatas)) { if (!$this->getFormService()->validate($formDatas)) {

View File

@ -33,6 +33,10 @@ class GoogleService extends AuthService
} }
return $this->_form; return $this->_form;
} }
protected function getEntity_process(mixed $entity): UserEntity
{
return $entity;
}
//기본기능 //기본기능
protected function login_process(array $formDatas): UserEntity protected function login_process(array $formDatas): UserEntity
{ {

View File

@ -33,6 +33,10 @@ class LocalService extends AuthService
} }
return $this->_form; return $this->_form;
} }
protected function getEntity_process(mixed $entity): UserEntity
{
return $entity;
}
protected function login_process(array $formDatas): UserEntity protected function login_process(array $formDatas): UserEntity
{ {
$entity = $this->getEntity(['id' => $formDatas['id'], 'status' => 'AVAILABLE'], true); $entity = $this->getEntity(['id' => $formDatas['id'], 'status' => 'AVAILABLE'], true);

View File

@ -7,30 +7,27 @@ use App\Entities\CollectorEntity;
use App\Entities\TrafficEntity; use App\Entities\TrafficEntity;
use App\Forms\CollectorForm; use App\Forms\CollectorForm;
use App\Helpers\CollectorHelper; use App\Helpers\CollectorHelper;
use App\Libraries\SNMPLibrary;
use App\Models\CollectorModel; use App\Models\CollectorModel;
use CodeIgniter\I18n\Time; use CodeIgniter\I18n\Time;
use RuntimeException; use RuntimeException;
class CollectorService extends CommonService class CollectorService extends CommonService
{ {
const OID_IF_IN_OCTETS = '1.3.6.1.2.1.31.1.1.1.6.';
const OID_IF_OUT_OCTETS = '1.3.6.1.2.1.31.1.1.1.10.';
private $_form = null; private $_form = null;
private $_helper = null; private $_helper = null;
// 💡 64비트 카운터를 위해 High Capacity OID로 변경: ifHCInOctets
const OID_IF_IN_OCTETS = '1.3.6.1.2.1.31.1.1.1.6.';
// 💡 64비트 카운터를 위해 High Capacity OID로 변경: ifHCOutOctets
const OID_IF_OUT_OCTETS = '1.3.6.1.2.1.31.1.1.1.10.';
const SNMP_VERSION = '2c';
// 💡 32비트 롤오버 로직을 제거했으므로 해당 상수는 필요 없습니다.
// const MAX_COUNTER_32BIT = 4294967296;
public function __construct(CollectorModel $model) public function __construct(CollectorModel $model)
{ {
parent::__construct($model); parent::__construct($model);
$this->addClassPaths('Collector'); $this->addClassPaths('Collector');
} }
public function createDTO(array $formDatas): CollectorDTO
{
return new CollectorDTO($formDatas);
}
public function getFormService(): CollectorForm public function getFormService(): CollectorForm
{ {
if ($this->_form === null) { if ($this->_form === null) {
@ -60,8 +57,15 @@ class CollectorService extends CommonService
} }
return $this->_helper; return $this->_helper;
} }
//기본 기능부분 //기본 기능부분
protected function getEntity_process(mixed $entity): CollectorEntity
{
return $entity;
}
protected function create_process(array $formDatas): CollectorEntity
{
return new CollectorEntity($formDatas);
}
public function create(object $dto): CollectorEntity public function create(object $dto): CollectorEntity
{ {
if (!$dto instanceof CollectorDTO) { if (!$dto instanceof CollectorDTO) {
@ -69,7 +73,10 @@ class CollectorService extends CommonService
} }
return parent::create($dto); return parent::create($dto);
} }
protected function modify_process($uid, array $formDatas): CollectorEntity
{
return parent::modify_process($uid, $formDatas);
}
public function modify($uid, object $dto): CollectorEntity public function modify($uid, object $dto): CollectorEntity
{ {
if (!$dto instanceof CollectorDTO) { if (!$dto instanceof CollectorDTO) {
@ -97,51 +104,23 @@ class CollectorService extends CommonService
return $entities; return $entities;
} }
//SNMP연결
private function getSNMPOctets(TrafficEntity $trafficEntity, string $oid): ?int
{
$fullOid = $oid . $trafficEntity->getInterface();
$community = $trafficEntity->getCommunity();
$ip = $trafficEntity->getIP();
// snmp2_get을 사용하여 SNMP v2c로 요청
// 💡 snmp2_get() 함수가 존재하지 않는다는 LSP 오류를 무시하기 위해 @suppress 태그 사용
/** @phpstan-ignore-next-line */
$result = @snmp2_get($ip, $community, $fullOid, 100000, 3);
if ($result === false || $result === null) {
log_message('error', "SNMP 통신 실패: {$ip} ({$fullOid}, Community: {$community})");
return null;
}
// 💡 정규식 수정: /\d+$/ (문자열 끝의 숫자만 추출)
if (preg_match('/\d+$/', $result, $matches)) {
// SNMP Counter는 64비트 BigInt가 될 수 있으므로, 64비트 PHP 환경에서는
// (int) 캐스팅을 사용하여 안전하게 64비트 정수로 변환합니다.
// (BigInt 값을 DB에 저장할 때도 PHP의 정수형/문자열 처리 능력이 중요합니다.)
return (int)$matches[0];
}
return null;
}
public function getCalculatedData(TrafficEntity $trafficEntity): array public function getCalculatedData(TrafficEntity $trafficEntity): array
{ {
$currentInOctets = $this->getSNMPOctets($trafficEntity, self::OID_IF_IN_OCTETS); $snmp = new SNMPLibrary($trafficEntity->getIP(), $trafficEntity->getCommunity());
$currentOutOctets = $this->getSNMPOctets($trafficEntity, self::OID_IF_OUT_OCTETS); $currentInOctets = $snmp->get(self::OID_IF_IN_OCTETS . $trafficEntity->getInterface());
$currentOutOctets = $snmp->get(self::OID_IF_OUT_OCTETS . $trafficEntity->getInterface());
if ($currentInOctets === null || $currentOutOctets === null) { if ($currentInOctets === null || $currentOutOctets === null) {
$message = "트래픽 수집 실패: {$trafficEntity->getIP()} - IF{$trafficEntity->getInterface()} (UID: {$trafficEntity->getPK()})"; $message = "트래픽 수집 실패: {$trafficEntity->getIP()} - IF{$trafficEntity->getInterface()} (UID: {$trafficEntity->getPK()})";
log_message('warning', $message); log_message('error', $message);
throw new \Exception($message); throw new \Exception($message);
} }
// 이전 데이터를 조회하여 Rate 계산에 사용 // 이전 데이터를 조회하여 Rate 계산에 사용
// $this->model은 TrafficDataModel의 인스턴스라고 가정
$lastEntity = $this->model->getLastEntity($trafficEntity->getPK()); $lastEntity = $this->model->getLastEntity($trafficEntity->getPK());
$inKbitsSec = 0.0; $inKbitsSec = 0.0;
$outKbitsSec = 0.0; $outKbitsSec = 0.0;
// 이전 데이터가 있어야만 Rate 계산 가능 // 이전 데이터가 있어야만 Rate 계산 가능
if ($lastEntity !== null) { if ($lastEntity !== null) {
$lastTime = Time::parse($lastEntity->getCreatedAt())->getTimestamp(); $lastTime = Time::parse($lastEntity->getCreatedAt())->getTimestamp();
@ -153,28 +132,18 @@ class CollectorService extends CommonService
$lastIn = $lastEntity->getRawIn(); $lastIn = $lastEntity->getRawIn();
$lastOut = $lastEntity->getRawOut(); $lastOut = $lastEntity->getRawOut();
// 💡 1. 인바운드 Octets 차분 계산 (32비트 롤오버 로직 제거) // 💡 1. IN/OUT바운드 Octets 차분 계산 64비트 카운터(BIGINT)를 사용하기 때문에 단순 뺄셈으로 처리합니다.
// 64비트 카운터(BIGINT)를 사용하기 때문에 단순 뺄셈으로 처리합니다.
// 64비트 카운터는 실질적으로 롤오버될 일이 없습니다.
$deltaInOctets = $currentInOctets - $lastIn; $deltaInOctets = $currentInOctets - $lastIn;
// 💡 2. 아웃바운드 Octets 차분 계산 (32비트 롤오버 로직 제거)
// 64비트 카운터(BIGINT)를 사용하기 때문에 단순 뺄셈으로 처리합니다.
$deltaOutOctets = $currentOutOctets - $lastOut; $deltaOutOctets = $currentOutOctets - $lastOut;
// Kbit/s 계산: (Delta_Octets * 8 bits) / Delta_Time_Seconds / 1000 (-> Kbit/s) // Kbit/s 계산: (Delta_Octets * 8 bits) / Delta_Time_Seconds / 1000 (-> Kbit/s) 실수(float) 연산으로 정확도를 높입니다.
// 실수(float) 연산으로 정확도를 높입니다.
$inKbitsSec = ($deltaInOctets * 8.0) / $deltaTime / 1000.0; $inKbitsSec = ($deltaInOctets * 8.0) / $deltaTime / 1000.0;
$outKbitsSec = ($deltaOutOctets * 8.0) / $deltaTime / 1000.0; $outKbitsSec = ($deltaOutOctets * 8.0) / $deltaTime / 1000.0;
} else { } else {
log_message('error', "시간 차이 오류 발생: {$trafficEntity->getIP()} - {$deltaTime}초 (UID: {$trafficEntity->getPK()})"); log_message('error', "시간 차이 오류 발생: {$trafficEntity->getIP()} - {$deltaTime}초 (UID: {$trafficEntity->getPK()})");
} }
} }
// DB에 저장할 데이터를 배열로 반환
return [ return [
// 'raw_in'과 'raw_out'은 이제 64비트 정수(BIGINT)를 담습니다.
// PHP에서 (int) 캐스팅은 64비트 환경에서 64비트 정수를 의미합니다.
'trafficinfo_uid' => (int)$trafficEntity->getPK(), 'trafficinfo_uid' => (int)$trafficEntity->getPK(),
'in' => (int)$inKbitsSec, // 정수형으로 반환 'in' => (int)$inKbitsSec, // 정수형으로 반환
'out' => (int)$outKbitsSec, // 정수형으로 반환 'out' => (int)$outKbitsSec, // 정수형으로 반환

View File

@ -2,6 +2,7 @@
namespace App\Services; namespace App\Services;
use App\DTOs\CommonDTO;
use App\Entities\CommonEntity; use App\Entities\CommonEntity;
use App\Models\CommonModel; use App\Models\CommonModel;
use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\Exceptions\DatabaseException;
@ -13,6 +14,7 @@ abstract class CommonService
private array $_classPaths = []; private array $_classPaths = [];
protected $title = null; protected $title = null;
protected function __construct(protected CommonModel $model) {} protected function __construct(protected CommonModel $model) {}
abstract public function createDTO(array $formDatas): CommonDTO;
abstract public function getFormService(): mixed; abstract public function getFormService(): mixed;
abstract public function getHelper(): mixed; abstract public function getHelper(): mixed;
final protected function addClassPaths(string $path): void final protected function addClassPaths(string $path): void
@ -24,18 +26,22 @@ abstract class CommonService
return $isArray ? $this->_classPaths : implode($delimeter, $this->_classPaths); return $isArray ? $this->_classPaths : implode($delimeter, $this->_classPaths);
} }
final public function getEntity(string|int|array $where, ?string $message = null): mixed /**
* 단일 엔티티를 조회합니다.
* @return CommonEntity|null CommonEntity 인스턴스 또는 찾지 못했을 경우 null
*/
final public function getEntity(string|int|array $where, ?string $message = null): ?CommonEntity
{ {
try { try {
$entity = is_array($where) ? $this->model->where($where)->first() : $this->model->find($where); $entity = is_array($where) ? $this->model->where($where)->first() : $this->model->find($where);
if (!$entity) { if (!$entity) {
return null; return null;
} }
if (is_array($entity)) { if (!$entity instanceof CommonEntity) {
throw new \Exception(__METHOD__ . "에서 결과값 Array 오류발생:\n" . var_export($entity, true)); throw new \Exception(__METHOD__ . "에서 결과값 오류발생:\n" . var_export($entity, true));
} }
return $this->getEntity_process($entity); return $this->getEntity_process($entity);
} catch (DatabaseException $e) { // 💡 DB 오류를 명시적으로 잡음 } catch (DatabaseException $e) {
$errorMessage = sprintf( $errorMessage = sprintf(
"\n------DB Query 오류 (%s)-----\nQuery: %s\nError: %s\n------------------------------\n", "\n------DB Query 오류 (%s)-----\nQuery: %s\nError: %s\n------------------------------\n",
__FUNCTION__, __FUNCTION__,
@ -44,7 +50,7 @@ abstract class CommonService
); );
log_message('error', $errorMessage); log_message('error', $errorMessage);
throw new RuntimeException($errorMessage, $e->getCode(), $e); throw new RuntimeException($errorMessage, $e->getCode(), $e);
} catch (\Exception $e) { // 기타 일반적인 예외 처리 } catch (\Exception $e) {
$errorMessage = sprintf( $errorMessage = sprintf(
"\n------일반 오류 (%s)-----\nError: %s\n------------------------------\n", "\n------일반 오류 (%s)-----\nError: %s\n------------------------------\n",
__FUNCTION__, __FUNCTION__,
@ -59,7 +65,7 @@ abstract class CommonService
$entities = $this->getEntities_process($where, $columns); $entities = $this->getEntities_process($where, $columns);
log_message('debug', $this->model->getLastQuery()); log_message('debug', $this->model->getLastQuery());
return $entities; return $entities;
} catch (DatabaseException $e) { // 💡 DB 오류를 명시적으로 잡음 } catch (DatabaseException $e) {
$errorMessage = sprintf( $errorMessage = sprintf(
"\n------DB Query 오류 (%s)-----\nQuery: %s\nError: %s\n------------------------------\n", "\n------DB Query 오류 (%s)-----\nQuery: %s\nError: %s\n------------------------------\n",
__FUNCTION__, __FUNCTION__,
@ -68,7 +74,7 @@ abstract class CommonService
); );
log_message('error', $errorMessage); log_message('error', $errorMessage);
throw new RuntimeException($errorMessage, $e->getCode(), $e); throw new RuntimeException($errorMessage, $e->getCode(), $e);
} catch (\Exception $e) { // 기타 일반적인 예외 처리 } catch (\Exception $e) {
$errorMessage = sprintf( $errorMessage = sprintf(
"\n------일반 오류 (%s)-----\nError: %s\n------------------------------\n", "\n------일반 오류 (%s)-----\nError: %s\n------------------------------\n",
__FUNCTION__, __FUNCTION__,
@ -76,19 +82,17 @@ abstract class CommonService
); );
throw new \Exception($errorMessage, $e->getCode(), $e); throw new \Exception($errorMessage, $e->getCode(), $e);
} }
} // }
final public function getLatestPK(): int final public function getNextPK(): int
{ {
$pkField = $this->model->getPKField(); $pkField = $this->model->getPKField();
// $this->model->selectMax($pkField)->get()->getRow() 대신 row() 사용 권장
$row = $this->model->selectMax($pkField)->get()->getRow(); $row = $this->model->selectMax($pkField)->get()->getRow();
// uid 대신 PK 필드명을 동적으로 사용
return isset($row->{$pkField}) ? ((int)$row->{$pkField} + 1) : 1; return isset($row->{$pkField}) ? ((int)$row->{$pkField} + 1) : 1;
} }
//Entity관련 //Entity관련
protected function getEntity_process(mixed $entity): mixed protected function getEntity_process(CommonEntity $entity): CommonEntity
{ {
return $entity; return $entity;
} }
@ -99,11 +103,7 @@ abstract class CommonService
if ($where) { if ($where) {
$this->model->where($where); $this->model->where($where);
} }
//출력순서 정의
$this->setOrderBy();
$entities = []; $entities = [];
// findAll()이 DB 오류 없이 실행되었다면 문제 없음
foreach ($this->model->select(implode(',', $columns))->findAll() as $entity) { foreach ($this->model->select(implode(',', $columns))->findAll() as $entity) {
$entities[$entity->getPK()] = $this->getEntity_process($entity); $entities[$entity->getPK()] = $this->getEntity_process($entity);
} }
@ -111,100 +111,148 @@ abstract class CommonService
} }
//CURD 결과처리용 //CURD 결과처리용
//DB 결과 처리 로직 통합 및 개선 protected function handle_save_result(mixed $result, int|string $uid): int|string
protected function handle_save_result(mixed $result, ?int $uid = null): CommonEntity
{ {
//최종 PK 값 결정 (insert/update 공통)
$pk = $this->model->useAutoIncrement() && is_numeric($result) && (int)$result > 0 ? (int)$result : $uid;
if (empty($pk)) {
// 모델의 insert/update가 실패했을 경우 에러 메시지를 포함하여 RuntimeException을 던집니다.
$errors = $this->model->errors();
$errorMsg = is_array($errors) && !empty($errors) ? implode(", ", $errors) : "DB 작업 성공 후 PK를 확인할 수 없거나 모델 오류 발생.";
throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg);
}
$entity = $this->getEntity($pk);
if (!$entity instanceof CommonEntity) {
throw new RuntimeException(__METHOD__ . "에서 오류발생: {$pk}에 해당하는 정보를 찾을수 없습니다.");
}
return $entity;
}
//생성용
protected function create_process(array $formDatas): CommonEntity
{
$result = $this->model->insert($formDatas, $this->model->useAutoIncrement());
log_message('debug', $this->model->getLastQuery()); log_message('debug', $this->model->getLastQuery());
if ($result === false) { if ($result === false) {
$errors = $this->model->errors(); $errors = $this->model->errors();
$errorMsg = is_array($errors) ? implode(", ", $errors) : "삽입 작업이 실패했습니다."; $errorMsg = is_array($errors) ? implode(", ", $errors) : "삽입 작업이 실패했습니다.";
throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg); throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg);
} }
return $this->handle_save_result($result); // $pk는 auto-increment가 사용된 경우 새로 생성된 ID, 아니면 기존 $uid (업데이트의 경우)
$pk = $this->model->useAutoIncrement() && is_numeric($result) && (int)$result > 0 ? (int)$result : $uid;
if (empty($pk)) {
$errors = $this->model->errors();
$errorMsg = is_array($errors) && !empty($errors) ? implode(", ", $errors) : "DB 작업 성공 후 PK를 확인할 수 없거나 모델 오류 발생:{$pk}";
throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg);
}
return $pk;
} }
protected function save_process(CommonEntity $entity): CommonEntity
{
$result = $this->model->save($entity);
// 최종적으로 DB에 반영된 PK를 반환받습니다. (UPDATE이면 기존 PK, INSERT이면 새 PK)
$finalPK = $this->handle_save_result($result, $entity->getPK());
return $this->getEntity($finalPK);
}
//생성용
abstract protected function create_process(array $formDatas): CommonEntity;
public function create(object $dto): CommonEntity public function create(object $dto): CommonEntity
{ {
$formDatas = (array)$dto; $formDatas = $dto->toArray();
//입력값 검증
if (!$this->getFormService()->validate($formDatas)) { if (!$this->getFormService()->validate($formDatas)) {
throw new ValidationException(implode("\n", service('validation')->getErrors())); throw new ValidationException(implode("\n", service('validation')->getErrors()));
} }
return $this->create_process($formDatas); $entity = $this->create_process($formDatas);
return $this->save_process($entity);
} }
//수정용 //수정용
protected function modify_process($uid, array $formDatas): CommonEntity protected function modify_process(string|int $uid, array $formDatas): CommonEntity
{ {
if (!$uid) {
throw new \Exception("수정에 필요한 PrimaryKey 가 정의 되지 않았습니다.");
}
$entity = $this->getEntity($uid); $entity = $this->getEntity($uid);
if (!$entity instanceof CommonEntity) { if (!$entity) {
throw new \Exception(__METHOD__ . "에서 오류발생: {$uid}에 해당하는 정보을 찾을수 없습니다."); throw new \Exception(__METHOD__ . "에서 오류발생: {$uid}에 해당하는 정보을 찾을수 없습니다.");
} }
//PrimaryKey 필드는 수정에서 제외
unset($formDatas[$this->model->primaryKey]); $pkField = $this->model->getPKField();
$result = $this->model->update($uid, $formDatas);
log_message('debug', $this->model->getLastQuery()); // DTO에서 넘어온 데이터에 PK 필드가 포함되어 있으면 제거하여,
if ($result === false) { // 기존 엔티티의 PK를 덮어쓰지 못하도록 방어
$errors = $this->model->errors(); if (isset($formDatas[$pkField])) {
$errorMsg = is_array($errors) ? implode(", ", $errors) : "업데이트 작업이 실패했습니다."; unset($formDatas[$pkField]);
throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg);
} }
return $this->handle_save_result($result, $uid);
$entity->fill($formDatas);
// <<< FIX: fill() 후 PK가 유실되었는지 확인하고 강제로 재설정 (방어적 코딩) >>>
if (empty($entity->getPK())) {
log_message('warning', "modify_process에서 fill() 후 PK가 유실되어 uid {$uid}를 강제로 재설정합니다.");
// Entity의 PK 필드를 직접 설정하여 UPDATE가 실행되도록 보장
$entity->{$pkField} = $uid;
}
// save_process 진입 전 Entity의 PK 최종 확인 로그
log_message('debug', "save_process 진입 전 Entity PK: " . $entity->getPK() . " (기대값: {$uid})");
return $entity;
} }
public function modify($uid, object $dto): CommonEntity public function modify(string|int $uid, object $dto): CommonEntity
{ {
$formDatas = (array)$dto; $formDatas = $dto->toArray();
//입력값 검증
if (!$this->getFormService()->validate($formDatas)) { if (!$this->getFormService()->validate($formDatas)) {
throw new ValidationException(implode("\n", service('validation')->getErrors())); throw new ValidationException(implode("\n", service('validation')->getErrors()));
} }
return $this->modify_process($uid, $formDatas); $entity = $this->modify_process($uid, $formDatas);
return $this->save_process($entity);
} }
protected function delete_process($uid): CommonEntity
//배치 작업용 수정
protected function batchjob_process(string|int $uid, array $formDatas): CommonEntity
{
// modify_process를 호출하여 로직 재사용 (PK 로드 및 PK 제거/방어 로직 포함)
$entity = $this->modify_process($uid, $formDatas);
return $entity;
}
public function batchjob(string|int $uid, array $formDatas): CommonEntity
{
if (!$this->getFormService()->validate($formDatas)) {
throw new ValidationException(implode("\n", service('validation')->getErrors()));
}
$entity = $this->batchjob_process($uid, $formDatas);
return $this->save_process($entity);
}
//삭제용 (일반)
protected function delete_process(string|int $uid): CommonEntity
{ {
if (!$uid) { if (!$uid) {
throw new \Exception("삭제에 필요한 PrimaryKey 가 정의 되지 않았습니다."); throw new \Exception("삭제에 필요한 PrimaryKey 가 정의 되지 않았습니다.");
} }
$entity = $this->getEntity($uid); $entity = $this->getEntity($uid);
if (!$entity instanceof CommonEntity) { if (!$entity) {
throw new \Exception(__METHOD__ . "에서 오류발생: {$uid}에 해당하는 정보을 찾을수 없습니다."); throw new \Exception(__METHOD__ . "에서 오류발생: {$uid}에 해당하는 정보을 찾을수 없습니다.");
} }
return $entity; return $entity;
} }
final public function delete($uid): CommonEntity final public function delete(string|int $uid): CommonEntity
{ {
$entity = $this->delete_process($uid); $entity = $this->delete_process($uid);
$result = $this->model->delete($entity->getPK()); $result = $this->model->delete($entity->getPK());
log_message('debug', $this->model->getLastQuery()); log_message('debug', $this->model->getLastQuery());
if ($result === false) { if ($result === false) {
$errors = $this->model->errors(); $errors = $this->model->errors();
$errorMsg = is_array($errors) ? implode(", ", $errors) : "모델 삭제 작업이 실패했습니다."; $errorMsg = is_array($errors) ? implode(", ", $errors) : "삭제 작업이 실패했습니다.";
throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg); throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg);
} }
return $entity; return $entity;
} }
//삭제용 (배치 작업)
protected function batchjob_delete_process(string|int $uid): CommonEntity
{
// delete_process를 호출하여 로직 재사용 (CommonEntity 로드 및 유효성 검사)
$entity = $this->delete_process($uid);
return $entity;
}
final public function batchjob_delete(string|int $uid): CommonEntity
{
$entity = $this->batchjob_delete_process($uid);
$result = $this->model->delete($entity->getPK());
log_message('debug', $this->model->getLastQuery());
if ($result === false) {
$errors = $this->model->errors();
$errorMsg = is_array($errors) ? implode(", ", $errors) : "삭제 작업이 실패했습니다.";
throw new RuntimeException(__METHOD__ . "에서 오류발생: " . $errorMsg);
}
return $entity;
}
//Index용 //Index용
final public function getTotalCount(): int final public function getTotalCount(): int
{ {

View File

@ -18,6 +18,10 @@ class MylogService extends CommonService
parent::__construct($model); parent::__construct($model);
$this->addClassPaths('Mylog'); $this->addClassPaths('Mylog');
} }
public function createDTO(array $formDatas): MylogDTO
{
return new MylogDTO($formDatas);
}
public function getFormService(): MylogForm public function getFormService(): MylogForm
{ {
if ($this->_form === null) { if ($this->_form === null) {
@ -47,6 +51,14 @@ class MylogService extends CommonService
return $this->_helper; return $this->_helper;
} }
//기본 기능부분 //기본 기능부분
protected function getEntity_process(mixed $entity): MylogEntity
{
return $entity;
}
protected function create_process(array $formDatas): MylogEntity
{
return new MylogEntity($formDatas);
}
public function create(object $dto): MylogEntity public function create(object $dto): MylogEntity
{ {
if (!$dto instanceof MylogDTO) { if (!$dto instanceof MylogDTO) {
@ -54,6 +66,10 @@ class MylogService extends CommonService
} }
return parent::create($dto); return parent::create($dto);
} }
protected function modify_process($uid, array $formDatas): MyLogEntity
{
return parent::modify_process($uid, $formDatas);
}
public function modify($uid, object $dto): MyLogEntity public function modify($uid, object $dto): MyLogEntity
{ {
if (!$dto instanceof MylogDTO) { if (!$dto instanceof MylogDTO) {

View File

@ -18,6 +18,10 @@ class TrafficService extends CommonService
parent::__construct($model); parent::__construct($model);
$this->addClassPaths('Traffic'); $this->addClassPaths('Traffic');
} }
public function createDTO(array $formDatas): TrafficDTO
{
return new TrafficDTO($formDatas);
}
public function getFormService(): TrafficForm public function getFormService(): TrafficForm
{ {
if ($this->_form === null) { if ($this->_form === null) {
@ -47,6 +51,14 @@ class TrafficService extends CommonService
return $this->_helper; return $this->_helper;
} }
//기본 기능부분 //기본 기능부분
protected function getEntity_process(mixed $entity): TrafficEntity
{
return $entity;
}
protected function create_process(array $formDatas): TrafficEntity
{
return new TrafficEntity($formDatas);
}
public function create(object $dto): TrafficEntity public function create(object $dto): TrafficEntity
{ {
if (!$dto instanceof TrafficDTO) { if (!$dto instanceof TrafficDTO) {
@ -54,6 +66,10 @@ class TrafficService extends CommonService
} }
return parent::create($dto); return parent::create($dto);
} }
protected function modify_process($uid, array $formDatas): TrafficEntity
{
return parent::modify_process($uid, $formDatas);
}
public function modify($uid, object $dto): TrafficEntity public function modify($uid, object $dto): TrafficEntity
{ {
if (!$dto instanceof TrafficDTO) { if (!$dto instanceof TrafficDTO) {

View File

@ -18,6 +18,10 @@ class UserService extends CommonService
parent::__construct($model); parent::__construct($model);
$this->addClassPaths('User'); $this->addClassPaths('User');
} }
public function createDTO(array $formDatas): UserDTO
{
return new UserDTO($formDatas);
}
public function getFormService(): UserForm public function getFormService(): UserForm
{ {
if ($this->_form === null) { if ($this->_form === null) {
@ -47,14 +51,17 @@ class UserService extends CommonService
return $this->_helper; return $this->_helper;
} }
//기본 기능부분 //기본 기능부분
protected function getEntity_process(mixed $entity): UserEntity
{
return $entity;
}
protected function create_process(array $formDatas): UserEntity protected function create_process(array $formDatas): UserEntity
{ {
//confirmpassword 필드는 Entity에 필요없으므로 제거 //confirmpassword 필드는 Entity에 필요없으므로 제거
if (isset($formDatas['confirmpassword'])) { if (isset($formDatas['confirmpassword'])) {
unset($formDatas['confirmpassword']); unset($formDatas['confirmpassword']);
} }
$entity = parent::create_process($formDatas); return new UserEntity($formDatas);
return $entity;
} }
public function create(object $dto): UserEntity public function create(object $dto): UserEntity
{ {
@ -69,8 +76,7 @@ class UserService extends CommonService
if (isset($formDatas['confirmpassword'])) { if (isset($formDatas['confirmpassword'])) {
unset($formDatas['confirmpassword']); unset($formDatas['confirmpassword']);
} }
$entity = parent::modify_process($uid, $formDatas); return parent::modify_process($uid, $formDatas);
return $entity;
} }
public function modify($uid, object $dto): UserEntity public function modify($uid, object $dto): UserEntity
{ {