bt-trader/app/Models/CommonModel.php
2026-02-24 18:58:30 +09:00

185 lines
5.0 KiB
PHP

<?php
namespace App\Models;
use CodeIgniter\Model;
abstract class CommonModel extends Model
{
protected $table = '';
protected $primaryKey = '';
protected $useAutoIncrement = true;
protected $useSoftDeletes = false;
protected $protectFields = true;
protected $allowedFields = [];
protected bool $allowEmptyInserts = false;
protected bool $updateOnlyChanged = true;
protected $useEmptyStringIfNull = false; // NULL도 DB로 보내기
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;
/**
* ✅ 변경:
* - beforeInsert: emptyStringToNull + applyDbDefaultsOnInsert
* - beforeUpdate: emptyStringToNull만 유지 (UPDATE에서는 DB default를 쓰려고 컬럼을 빼면 위험/의도와 다름)
*/
protected $beforeInsert = ['emptyStringToNull', 'applyDbDefaultsOnInsert'];
protected $afterInsert = [];
protected $beforeUpdate = ['emptyStringToNull'];
protected $afterUpdate = [];
protected $beforeFind = [];
protected $afterFind = [];
protected $beforeDelete = [];
protected $afterDelete = [];
/**
* 빈 문자열을 NULL로 바꾸고 싶은 필드들 (모델별 override)
* - 예: FK, 숫자필드 등
*/
protected array $nullableFields = [];
/**
* ✅ 추가: DB DEFAULT를 “사용하고 싶은” 필드들 (모델별 override)
* - INSERT 시 값이 null/''/공백이면 payload에서 제거(unset)해서 DB default가 동작하게 함
* - UPDATE에서는 적용하지 않음 (비우기 가능)
*/
protected array $allowedDbDefaultFields = [];
/**
* 공백문자열도 빈값으로 취급할지 정책
*/
protected bool $dbDefaultTreatWhitespaceAsEmpty = true;
protected function __construct()
{
parent::__construct();
}
final public function getTable(): string
{
return constant("static::TABLE");
}
final public function getPKField(): string
{
return constant("static::PK");
}
final public function getTitleField(): string
{
return constant("static::TITLE");
}
final public function useAutoIncrement(): bool
{
return $this->useAutoIncrement;
}
final public function getAllowedFields(): array
{
return $this->allowedFields;
}
/**
* 기존 로직 유지:
* - nullableFields에 지정된 필드만 '' => null 로 변환
*/
protected function emptyStringToNull(array $data): array
{
if (!isset($data['data']) || !is_array($data['data'])) {
return $data;
}
if (empty($this->nullableFields)) {
return $data;
}
foreach ($this->nullableFields as $field) {
if (!array_key_exists($field, $data['data'])) {
continue;
}
$v = $data['data'][$field];
if (is_string($v)) {
$v = trim($v);
$data['data'][$field] = ($v === '') ? null : $v;
} else {
if ($v === '') {
$data['data'][$field] = null;
}
}
}
return $data;
}
/**
* ✅ 추가 로직:
* INSERT 때만 DB DEFAULT를 쓰고 싶은 필드를 payload에서 제거(unset)
*
* - allowedDbDefaultFields에 있는 필드만 처리
* - 값이 null / '' / (옵션)공백문자열 이면 unset
* - 이렇게 하면 INSERT 쿼리에서 컬럼 자체가 빠져서 DB default가 적용됨
*/
protected function applyDbDefaultsOnInsert(array $data): array
{
if (!isset($data['data']) || !is_array($data['data'])) {
return $data;
}
if (empty($this->allowedDbDefaultFields)) {
return $data;
}
foreach ($this->allowedDbDefaultFields as $field) {
if (!array_key_exists($field, $data['data'])) {
continue;
}
$v = $data['data'][$field];
// null이면 제거
if ($v === null) {
unset($data['data'][$field]);
continue;
}
// 문자열이면 '' 또는 (옵션)trim 후 '' 이면 제거
if (is_string($v)) {
if ($v === '') {
unset($data['data'][$field]);
continue;
}
if ($this->dbDefaultTreatWhitespaceAsEmpty && trim($v) === '') {
unset($data['data'][$field]);
continue;
}
}
}
return $data;
}
}