236 lines
8.2 KiB
PHP
236 lines
8.2 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use CodeIgniter\Model;
|
|
|
|
abstract class CommonModel extends Model
|
|
{
|
|
protected $table = '';
|
|
protected $primaryKey = '';
|
|
protected $useAutoIncrement = true;
|
|
protected $returnType = 'array';
|
|
|
|
protected $useSoftDeletes = false;
|
|
protected $protectFields = true;
|
|
protected $allowedFields = [];
|
|
|
|
protected bool $allowEmptyInserts = false;
|
|
protected bool $updateOnlyChanged = true;
|
|
|
|
protected array $casts = [];
|
|
protected array $castHandlers = [];
|
|
|
|
// Dates
|
|
protected $useTimestamps = false;
|
|
protected $dateFormat = 'datetime';
|
|
protected $createdField = 'created_at';
|
|
protected $updatedField = 'updated_at';
|
|
protected $deletedField = 'deleted_at';
|
|
|
|
// Validation
|
|
protected $validationRules = [];
|
|
protected $validationMessages = [];
|
|
protected $skipValidation = false;
|
|
protected $cleanValidationRules = true;
|
|
|
|
// Callbacks
|
|
protected $allowCallbacks = true;
|
|
protected $beforeInsert = [];
|
|
protected $afterInsert = [];
|
|
protected $beforeUpdate = [];
|
|
protected $afterUpdate = [];
|
|
protected $beforeFind = [];
|
|
protected $afterFind = [];
|
|
protected $beforeDelete = [];
|
|
protected $afterDelete = [];
|
|
|
|
protected function __construct()
|
|
{
|
|
parent::__construct();
|
|
}
|
|
abstract public function getTitleField(): string;
|
|
final public function getTable(): string
|
|
{
|
|
return $this->table;
|
|
}
|
|
final public function getPKField(): string
|
|
{
|
|
return $this->primaryKey;
|
|
}
|
|
// final public function getFields(array $except_fields = []): array
|
|
// {
|
|
// return array_diff($this->allowedFields, $except_fields); //제외한 fields
|
|
// }
|
|
public function getFieldRule(string $action, string $field): string
|
|
{
|
|
if (is_array($field)) {
|
|
throw new \Exception(__FUNCTION__ . "=> field가 array 입니다.\n" . var_export($field, true));
|
|
}
|
|
switch ($field) {
|
|
case $this->getPKField():
|
|
//수동입력인경우
|
|
if (!$this->useAutoIncrement) {
|
|
$rule = "required|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]";
|
|
$rule .= $action == "create" ? "|is_unique[{$this->table}.{$field}]" : "";
|
|
} else {
|
|
$rule = "required|numeric";
|
|
};
|
|
break;
|
|
case $this->getTitleField():
|
|
$rule = "required|string";
|
|
break;
|
|
case 'image':
|
|
$rule = "is_image[{$field}]|mime_in[{$field},image/jpg,image/jpeg,image/gif,image/png,image/webp]|max_size[{$field},300]|max_dims[{$field},2048,768]";
|
|
break;
|
|
case "status":
|
|
$rule = "if_exist|in_list[use,unuse]";
|
|
break;
|
|
case "updated_at":
|
|
case "created_at":
|
|
case "deleted_at":
|
|
$rule = "if_exist|valid_date";
|
|
break;
|
|
default:
|
|
$rule = "if_exist|string";
|
|
break;
|
|
}
|
|
return $rule;
|
|
}
|
|
final public function getFieldRules(string $action, array $fields, $rules = []): array
|
|
{
|
|
foreach ($fields as $field) {
|
|
$rules[$field] = $this->getFieldRule($action, $field);
|
|
}
|
|
return $rules;
|
|
}
|
|
public function getFormFieldOption(string $field, array $options = []): array
|
|
{
|
|
switch ($field) {
|
|
default:
|
|
foreach ($this->getEntitys() as $entity) {
|
|
$options[$entity->getPK()] = $entity->getTitle();
|
|
}
|
|
break;
|
|
}
|
|
// dd($options);
|
|
return $options;
|
|
}
|
|
final public function getEntity(): array|object|null
|
|
{
|
|
return $this->asObject($this->returnType)->first();
|
|
}
|
|
final public function getEntitys(): array
|
|
{
|
|
return $this->asObject($this->returnType)->findAll();
|
|
}
|
|
//create , modify 직전 작업용 작업
|
|
protected function convertEntityData(string $field, array $formDatas): mixed
|
|
{
|
|
switch ($field) {
|
|
case $this->getPKField():
|
|
//$formDatas에 전달된 값이 없는경우
|
|
if (!array_key_exists($field, $formDatas)) {
|
|
$randomBytes = bin2hex(random_bytes(32));
|
|
$value = sprintf(
|
|
'%08s-%04s-%04x-%04x-%12s',
|
|
substr($randomBytes, 0, 8),
|
|
substr($randomBytes, 8, 4),
|
|
substr($randomBytes, 12, 4),
|
|
substr($randomBytes, 16, 4),
|
|
substr($randomBytes, 20, 12)
|
|
);
|
|
} else {
|
|
$value = $formDatas[$field];
|
|
}
|
|
break;
|
|
case "editor": //content등 textarea를 사용한 Field
|
|
$value = htmlentities($formDatas[$field], ENT_QUOTES);
|
|
break;
|
|
default:
|
|
$value = $formDatas[$field];
|
|
break;
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
private function save_process($entity): mixed
|
|
{
|
|
try {
|
|
//최종 변경사항이 없으면
|
|
if (!$entity->hasChanged()) {
|
|
throw new \Exception(__FUNCTION__ . " 변경된 내용이 없습니다.");
|
|
}
|
|
// log_message("debug", var_export($entity, true));
|
|
//최종 저장시 오류발생하면
|
|
if (!$this->save($entity)) {
|
|
throw new \Exception("저장오류:" . var_export($this->errors(), true));
|
|
}
|
|
log_message("notice", $this->getTable() . " => " . __FUNCTION__ . " DB에 {$entity->getTitle()} 저장이 완료되었습니다.");
|
|
return $entity;
|
|
} catch (\Exception $e) {
|
|
$message = sprintf(
|
|
"\n------%s SQL오류-----\n%s\n%s\n------------------------------\n",
|
|
__FUNCTION__,
|
|
$this->getLastQuery(),
|
|
$e->getMessage()
|
|
);
|
|
throw new \Exception($message);
|
|
}
|
|
}
|
|
final protected function create_process($entity, array $formDatas): mixed
|
|
{
|
|
//Field에 맞는 Validation Rule 재정의
|
|
$this->setValidationRules($this->getFieldRules('create', $this->allowedFields));
|
|
//저장하기 전에 데이터 값 변경이 필요한 Field
|
|
foreach (array_keys($formDatas) as $field) {
|
|
$entity->$field = $this->convertEntityData($field, $formDatas);
|
|
}
|
|
$entity = $this->save_process($entity);
|
|
//primaryKey가 자동입력이면
|
|
if ($this->useAutoIncrement) {
|
|
$pkField = $this->getPKField();
|
|
$entity->$pkField = $this->getInsertID();
|
|
}
|
|
// log_message("debug", $this->getTable() . " => " . __FUNCTION__ . " DB 작업 완료");
|
|
return $entity;
|
|
}
|
|
final protected function modify_process($entity, array $formDatas): mixed
|
|
{
|
|
//Field에 맞는 Validation Rule 재정의
|
|
$this->setValidationRules($this->getFieldRules('modify', $this->allowedFields));
|
|
//저장하기 전에 데이터 값 변경이 필요한 Field
|
|
foreach (array_keys($formDatas) as $field) {
|
|
$entity->$field = $this->convertEntityData($field, $formDatas);
|
|
}
|
|
$this->save_process($entity);
|
|
// log_message("debug", $this->getTable() . " => " . __FUNCTION__ . " DB 작업 완료");
|
|
return $entity;
|
|
}
|
|
|
|
//List용
|
|
final public function setList_FieldFilter(string $field, int|string $value): void
|
|
{
|
|
$this->where($field, $value);
|
|
}
|
|
public function setList_WordFilter(string $word, string $field = null): void
|
|
{
|
|
$this->like($field ?? $this->getTitleField(), $word, 'both'); //befor , after , both
|
|
}
|
|
final public function setList_DateFilter(string $start, string $end, $field = "created_at"): void
|
|
{
|
|
if ($start !== DEFAULTS['EMPTY']) {
|
|
$this->where("{$field} >= '{$start} 00:00:00'");
|
|
}
|
|
if ($end !== DEFAULTS['EMPTY']) {
|
|
$this->where("{$field} <= '{$end} 23:59:59'");
|
|
}
|
|
}
|
|
public function setList_OrderBy(string $order = ""): void
|
|
{
|
|
if ($order) {
|
|
$this->orderBy($order);
|
|
}
|
|
}
|
|
}
|