485 lines
18 KiB
PHP
485 lines
18 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Helpers\CommonHelper;
|
|
use App\Models\CommonModel;
|
|
use App\Services\Customer\ClientService;
|
|
use App\Services\MyLogService;
|
|
use App\Services\UserService;
|
|
use CodeIgniter\Database\Exceptions\DatabaseException;
|
|
use RuntimeException;
|
|
|
|
abstract class CommonService
|
|
{
|
|
private $_model = null;
|
|
private $_helper = null;
|
|
private $_classNames = [];
|
|
private $_control = [];
|
|
private ?UserService $_userService = null;
|
|
private ?ClientService $_clientService = null;
|
|
private ?MyLogService $_mylogService = null;
|
|
protected function __construct(CommonModel $model, CommonHelper $helper)
|
|
{
|
|
$this->_model = $model;
|
|
$this->_helper = $helper;
|
|
}
|
|
abstract public function getFormFields(): array;
|
|
abstract public function getFormFilters(): array;
|
|
final public function getModel(): mixed
|
|
{
|
|
if (!$this->_model instanceof CommonModel) {
|
|
throw new \Exception(__METHOD__ . "에서 오류발생:Model이 정의되지 않았습니다. ");
|
|
}
|
|
return $this->_model;
|
|
}
|
|
final public function getHelper(): mixed
|
|
{
|
|
if (!$this->_helper instanceof CommonHelper) {
|
|
throw new \Exception(__METHOD__ . "에서 오류발생:Helper가 정의되지 않았습니다. ");
|
|
}
|
|
return $this->_helper;
|
|
}
|
|
final public function getControlDatas(?string $key = null): string|array
|
|
{
|
|
if (!$key) {
|
|
return $this->_control;
|
|
}
|
|
return array_key_exists($key, $this->_control) ? $this->_control[$key] : [];
|
|
}
|
|
final public function setControlDatas(string $key, mixed $values): void
|
|
{
|
|
if (!array_key_exists($key, $this->_control)) {
|
|
$this->_control[$key] = [];
|
|
}
|
|
$this->_control[$key] = $values;
|
|
}
|
|
final protected function addClassName(string $className): void
|
|
{
|
|
$this->_classNames[] = $className;
|
|
}
|
|
final public function getClassName($delimeter = DIRECTORY_SEPARATOR): string
|
|
{
|
|
return implode($delimeter, $this->_classNames);
|
|
}
|
|
final public function setAction(string $action): void
|
|
{
|
|
$this->setControlDatas('action', $action);
|
|
}
|
|
final public function getAction(): string
|
|
{
|
|
if (!$this->getControlDatas('action')) {
|
|
throw new \Exception("action이 정의되지 않았습니다.");
|
|
}
|
|
return $this->getControlDatas('action');
|
|
}
|
|
//FormFields정의
|
|
final public function setFormFields(?array $fields = null): void
|
|
{
|
|
switch ($this->getAction()) {
|
|
case 'index':
|
|
$actionFields = $this->getIndexFields();
|
|
break;
|
|
case 'view':
|
|
$actionFields = $this->getViewFields();
|
|
break;
|
|
default:
|
|
$actionFields = $this->getFormFields();
|
|
break;
|
|
}
|
|
$this->setControlDatas('actionFields', is_array($fields) ? $fields : $actionFields);
|
|
}
|
|
final public function setFormFilters(?array $filters = null): void
|
|
{
|
|
switch ($this->getAction()) {
|
|
case 'index':
|
|
$actionFilters = $this->getIndexFilters();
|
|
break;
|
|
case 'view':
|
|
$actionFilters = $this->getViewFilters();
|
|
break;
|
|
default:
|
|
$actionFilters = $this->getFormFilters();
|
|
break;
|
|
}
|
|
$this->setControlDatas('actionFilters', is_array($filters) ? $filters : $actionFilters);
|
|
}
|
|
//FormRules정의
|
|
final public function getFormRules(array $rules = []): array
|
|
{
|
|
foreach ($this->getControlDatas('field_rules') as $field => $rule) {
|
|
$rules[$field] = $rule;
|
|
}
|
|
return $rules;
|
|
}
|
|
final public function setFormRules(): void
|
|
{
|
|
$rules = [];
|
|
foreach ($this->getControlDatas('actionFields') as $field) {
|
|
$rules[$field] = $this->getFormRule($this->getAction(), $field);
|
|
}
|
|
$this->setControlDatas('field_rules', $rules);
|
|
}
|
|
//FormOptions정의
|
|
final protected function getFormOptions(array $options = []): array
|
|
{
|
|
foreach ($this->getControlDatas('field_optons') as $field => $option) {
|
|
$options[$field] = $option;
|
|
}
|
|
return $options;
|
|
}
|
|
final public function setFormOptions(): void
|
|
{
|
|
//기존 Filter Options 가져와서 field에 해당하는 option이 없으면 field를 key로 배열추가 후 다시 filter_options 전체 적용
|
|
$options = [];
|
|
foreach ($this->getControlDatas('actionFilters') as $field) {
|
|
$options[$field] = $this->getFormOption($field, $options);
|
|
}
|
|
$this->setControlDatas('field_optons', $options);
|
|
}
|
|
//Entity별로 작업처리시
|
|
final public function getLastQuery(): string
|
|
{
|
|
return $this->getModel()->getLastQuery();
|
|
}
|
|
protected function getEntity_process(mixed $entity): mixed
|
|
{
|
|
return $entity;
|
|
}
|
|
final public function getEntity(string|int|array $where, ?string $message = null): mixed
|
|
{
|
|
try {
|
|
$entity = is_array($where) ? $this->getModel()->where($where)->first() : $this->getModel()->find($where);
|
|
if (!$entity) {
|
|
return null;
|
|
}
|
|
if (is_array($entity)) {
|
|
throw new \Exception(__METHOD__ . "에서 결과값 Array 오류발생:\n" . var_export($entity, true));
|
|
}
|
|
return $this->getEntity_process($entity);
|
|
} catch (\Exception $e) {
|
|
$message = sprintf(
|
|
"\n------%s SQL오류-----<BR>\n%s\n%s\n------------------------------\n",
|
|
__FUNCTION__,
|
|
$this->getLastQuery(),
|
|
$e->getMessage()
|
|
);
|
|
throw new \Exception($message);
|
|
}
|
|
}
|
|
//entities를 가져오는 조건
|
|
protected function getEntities_process(mixed $where = null, array $columns = ['*']): array
|
|
{
|
|
if ($where) {
|
|
$this->getModel()->where($where);
|
|
}
|
|
//출력순서 정의
|
|
$this->setOrderBy();
|
|
$entities = [];
|
|
foreach ($this->getModel()->select(implode(',', $columns))->findAll() as $entity) {
|
|
$entities[$entity->getPK()] = $this->getEntity_process($entity);
|
|
}
|
|
return $entities;
|
|
}
|
|
final public function getEntities(mixed $where = null, array $columns = ['*']): array
|
|
{
|
|
try {
|
|
return $this->getEntities_process($where, $columns);
|
|
} catch (\Exception $e) {
|
|
$message = sprintf(
|
|
"\n------%s SQL오류-----<BR>\n%s\n%s\n------------------------------\n",
|
|
__FUNCTION__,
|
|
$this->getModel()->getLastQuery(),
|
|
$e->getMessage()
|
|
);
|
|
throw new \Exception($message);
|
|
}
|
|
} //
|
|
final public function getUserService(): UserService
|
|
{
|
|
if (!$this->_userService) {
|
|
$this->_userService = new UserService();
|
|
}
|
|
return $this->_userService;
|
|
}
|
|
final public function getClientService(): ClientService
|
|
{
|
|
if (!$this->_clientService) {
|
|
$this->_clientService = new ClientService();
|
|
}
|
|
return $this->_clientService;
|
|
}
|
|
final public function getMylogService(): MyLogService
|
|
{
|
|
if (!$this->_mylogService) {
|
|
$this->_mylogService = new MyLogService();
|
|
}
|
|
return $this->_mylogService;
|
|
}
|
|
final public function getLatestPK(): int
|
|
{
|
|
$row = $this->getModel()->selectMax($this->getModel()->getPKField())->get()->getRow();
|
|
return isset($row->uid) ? ((int)$row->uid + 1) : 1;
|
|
}
|
|
//기본 기능부분
|
|
//FieldForm관련용
|
|
final public function getFormDatas(): array
|
|
{
|
|
return $this->getControlDatas('form_datas');
|
|
}
|
|
final public function setFormDatas(array $requestDatas, array $formDatas = []): void
|
|
{
|
|
foreach ($this->getControlDatas('actionFields') as $field) {
|
|
$formDatas = $this->setFormData($field, $requestDatas, $formDatas);
|
|
}
|
|
$this->setControlDatas('form_datas', $formDatas);
|
|
}
|
|
public function getViewFields(): array
|
|
{
|
|
return $this->getFormFields();
|
|
}
|
|
public function getViewFilters(): array
|
|
{
|
|
return $this->getFormFilters();
|
|
}
|
|
public function getIndexFields(): array
|
|
{
|
|
return $this->getFormFields();
|
|
}
|
|
public function getIndexFilters(): array
|
|
{
|
|
return $this->getFormFilters();
|
|
}
|
|
public function getBatchjobFields(): array
|
|
{
|
|
return $this->getIndexFilters();
|
|
}
|
|
public function getBatchjobButtons(): array
|
|
{
|
|
return [
|
|
'batchjob' => '일괄 처리',
|
|
'batchjob_delete' => '일괄 삭제',
|
|
];
|
|
}
|
|
public function getFormOption(string $field, array $options = []): array
|
|
{
|
|
switch ($field) {
|
|
case 'user_uid':
|
|
$options = $this->getUserService()->getEntities();
|
|
break;
|
|
case 'clientinfo_uid':
|
|
$options = $this->getClientService()->getEntities();
|
|
break;
|
|
default:
|
|
$options = lang($this->getClassName() . '.' . strtoupper($field));
|
|
break;
|
|
}
|
|
if (!is_array($options)) {
|
|
throw new \Exception(__FUNCTION__ . "에서 {$field}의 options 값들이 array가 아닙니다.\n" . var_export($options, true));
|
|
}
|
|
return $options;
|
|
}
|
|
public function getFormRule(string $action, string $field): string
|
|
{
|
|
if (is_array($field)) {
|
|
throw new \Exception(__FUNCTION__ . "=> field가 array 입니다.\n" . var_export($field, true));
|
|
}
|
|
switch ($field) {
|
|
default:
|
|
$rule = $this->getModel()->getFormRule($action, $field);
|
|
break;
|
|
}
|
|
return $rule;
|
|
}
|
|
public function setFormData(string $field, array $requestDatas, array $formDatas): array
|
|
{
|
|
switch ($field) {
|
|
default:
|
|
$formDatas[$field] = $requestDatas[$field] ?? null;
|
|
break;
|
|
}
|
|
return $formDatas;
|
|
}
|
|
//생성
|
|
protected function create_process(array $formDatas): mixed
|
|
{
|
|
return $this->getModel()->create($formDatas);
|
|
}
|
|
public function create(array $formDatas): mixed
|
|
{
|
|
$db = \Config\Database::connect();
|
|
try {
|
|
//트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정
|
|
$db->transException(true)->transStart();
|
|
$entity = $this->create_process($formDatas);
|
|
$db->transComplete();
|
|
return $entity;
|
|
} catch (DatabaseException $e) {
|
|
// DatabaseException을 포착하면 자동으로 롤백 처리됨
|
|
// 이 예외 객체($e)에 실패한 쿼리 정보가 포함됨
|
|
// 예외 메시지에 쿼리 정보 포함시키기
|
|
throw new RuntimeException(sprintf(
|
|
"\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n",
|
|
__METHOD__,
|
|
$this->getModel()->getLastQuery(),
|
|
$e->getMessage()
|
|
), $e->getCode(), $e);
|
|
} catch (\Throwable $e) {
|
|
$db->transRollback(); // 예외 발생 시 수동으로 롤백
|
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
|
}
|
|
}
|
|
//수정
|
|
protected function modify_process(mixed $entity, array $formDatas): mixed
|
|
{
|
|
return $this->getModel()->modify($entity, $formDatas);
|
|
}
|
|
public function modify(mixed $entity, array $formDatas): mixed
|
|
{
|
|
$db = \Config\Database::connect();
|
|
try {
|
|
//트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정
|
|
$db->transException(true)->transStart();
|
|
$entity = $this->modify_process($entity, $formDatas);
|
|
$db->transComplete();
|
|
return $entity;
|
|
} catch (DatabaseException $e) { //DB 오류시 발생
|
|
throw new RuntimeException(sprintf(
|
|
"\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n",
|
|
__METHOD__,
|
|
$this->getModel()->getLastQuery(),
|
|
$e->getMessage()
|
|
), $e->getCode(), $e);
|
|
} catch (\Throwable $e) { // 그 외 다른 종류의 예외 처리
|
|
$db->transRollback(); // 예외 발생 시 수동으로 롤백
|
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
|
}
|
|
}
|
|
//단일작업
|
|
protected function toggle_process(mixed $entity, array $formDatas): mixed
|
|
{
|
|
return $this->getModel()->modify($entity, $formDatas);
|
|
}
|
|
public function toggle(mixed $entity, array $formDatas): mixed
|
|
{
|
|
$db = \Config\Database::connect();
|
|
try {
|
|
//트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정
|
|
$db->transException(true)->transStart();
|
|
$entity = $this->toggle_process($entity, $formDatas);
|
|
$db->transComplete();
|
|
return $entity;
|
|
} catch (DatabaseException $e) { //DB 오류시 발생
|
|
throw new RuntimeException(sprintf(
|
|
"\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n",
|
|
__METHOD__,
|
|
$this->getModel()->getLastQuery(),
|
|
$e->getMessage()
|
|
), $e->getCode(), $e);
|
|
} catch (\Throwable $e) { // 그 외 다른 종류의 예외 처리
|
|
$db->transRollback(); // 예외 발생 시 수동으로 롤백
|
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
|
}
|
|
}
|
|
//일괄처리작업
|
|
protected function batchjob_process(mixed $entity, array $formDatas): mixed
|
|
{
|
|
return $this->getModel()->modify($entity, $formDatas);
|
|
}
|
|
public function batchjob(mixed $entity, array $formDatas): mixed
|
|
{
|
|
$db = \Config\Database::connect();
|
|
try {
|
|
//트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정
|
|
$db->transException(true)->transStart();
|
|
$entity = $this->batchjob_process($entity, $formDatas);
|
|
$db->transComplete();
|
|
return $entity;
|
|
} catch (DatabaseException $e) { //DB 오류시 발생
|
|
throw new RuntimeException(sprintf(
|
|
"\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n",
|
|
__METHOD__,
|
|
$this->getModel()->getLastQuery(),
|
|
$e->getMessage()
|
|
), $e->getCode(), $e);
|
|
} catch (\Throwable $e) { // 그 외 다른 종류의 예외 처리
|
|
$db->transRollback(); // 예외 발생 시 수동으로 롤백
|
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
|
}
|
|
}
|
|
//삭제
|
|
protected function delete_process(string $uid): void
|
|
{
|
|
if (!$this->getModel()->delete($uid)) {
|
|
// delete() 메서드 실패 시 모델의 errors()를 통해 상세 정보 확인
|
|
$errors = $this->getModel()->errors();
|
|
throw new RuntimeException("모델 삭제 실패: " . var_export($errors, true));
|
|
}
|
|
}
|
|
public function delete(mixed $entity): mixed
|
|
{
|
|
$db = \Config\Database::connect();
|
|
$db->transStart();
|
|
try {
|
|
//트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정
|
|
$db->transException(true)->transStart();
|
|
$this->delete_process($entity->getPK());
|
|
$db->transComplete();
|
|
return $entity;
|
|
} catch (DatabaseException $e) { //DB 오류시 발생
|
|
throw new RuntimeException(sprintf(
|
|
"\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n",
|
|
__METHOD__,
|
|
$this->getModel()->getLastQuery(),
|
|
$e->getMessage()
|
|
), $e->getCode(), $e);
|
|
} catch (\Throwable $e) { // 그 외 다른 종류의 예외 처리
|
|
$db->transRollback(); // 예외 발생 시 수동으로 롤백
|
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
|
}
|
|
}
|
|
////Index 검색용
|
|
//Index용
|
|
final public function getTotalCount(): int
|
|
{
|
|
return $this->getModel()->countAllResults(false);
|
|
}
|
|
//Limit처리
|
|
final public function setLimit(int $per_page): void
|
|
{
|
|
$this->getModel()->limit($per_page);
|
|
}
|
|
//Offset처리
|
|
final public function setOffset(int $offset): void
|
|
{
|
|
$this->getModel()->offset($offset);
|
|
}
|
|
//FormFilter 조건절 처리
|
|
public function index_condition_filterField(string $field, mixed $filter_value): void
|
|
{
|
|
switch ($field) {
|
|
default:
|
|
$this->getModel()->where("{$this->getModel()->getTable()}.{$field}", $filter_value);
|
|
break;
|
|
}
|
|
}
|
|
//검색어조건절처리
|
|
public function index_condition_filterWord(string $word): void
|
|
{
|
|
$this->getModel()->orLike($this->getModel()->getTable() . "." . $this->getModel()->getTitleField(), $word, 'both');
|
|
}
|
|
//날자검색
|
|
public function index_condition_filterDate(string $start, string $end): void
|
|
{
|
|
$this->getModel()->where(sprintf("%s.created_at >= '%s 00:00:00'", $this->getModel()->getTable(), $start));
|
|
$this->getModel()->where(sprintf("%s.created_at <= '%s 23:59:59'", $this->getModel()->getTable(), $end));
|
|
}
|
|
//OrderBy 처리
|
|
public function setOrderBy(mixed $field = null, mixed $value = null): void
|
|
{
|
|
if ($field !== null && $value !== null) {
|
|
$this->getModel()->orderBy(sprintf("%s.%s %s", $this->getModel()->getTable(), $field, $value));
|
|
}
|
|
}
|
|
}
|