302 lines
11 KiB
PHP
302 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Entities\BaseEntity;
|
|
use CodeIgniter\Model;
|
|
|
|
abstract class BaseModel extends Model
|
|
{
|
|
protected $DBGroup = "default";
|
|
protected $table = "default";
|
|
protected $primaryKey = "uid";
|
|
protected $useAutoIncrement = true;
|
|
protected $insertID = 0;
|
|
protected $returnType = "array"; //object,array,entity명::class
|
|
protected $useSoftDeletes = false;
|
|
protected $protectFields = true;
|
|
protected $allowedFields = [];
|
|
|
|
// Dates
|
|
protected $useTimestamps = true;
|
|
protected $dateFormat = "datetime";
|
|
protected $createdField = "created_at";
|
|
protected $updatedField = "updated_at";
|
|
protected $deletedField = "deleted_at";
|
|
|
|
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 = [];
|
|
|
|
private $_user_options = null;
|
|
private $_className = null;
|
|
protected $_session = null;
|
|
protected $_validation = null;
|
|
protected function __construct(string $className)
|
|
{
|
|
$this->_className = $className;
|
|
parent::__construct();
|
|
$this->allowedFields = ["uid", "updated_at", "created_at"];
|
|
if (!$this->useAutoIncrement) {
|
|
array_push($this->allowedFields, $this->primaryKey);
|
|
}
|
|
$this->validationRules = [];
|
|
$this->_session = \Config\Services::session();
|
|
$this->_validation = \Config\Services::validation();
|
|
}
|
|
final public function getClassName()
|
|
{
|
|
return $this->_className;
|
|
}
|
|
final public function getPrimaryKey(): string
|
|
{
|
|
return $this->primaryKey;
|
|
}
|
|
abstract public function getTitleField(): string;
|
|
public function getEntity($conditions): BaseEntity
|
|
{
|
|
return $this->where($conditions)->first() ?: throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 해당 데이터가 없습니다.\n" . var_export($conditions, true));
|
|
}
|
|
public function getEntitys(array $conditions = array()): array
|
|
{
|
|
return $this->where($conditions)->findAll();
|
|
}
|
|
protected function getFieldRule(string $field, array $rules, string $action = ""): array
|
|
{
|
|
switch ($field) {
|
|
case $this->primaryKey:
|
|
if (!$this->useAutoIncrement) {
|
|
$rules[$field] = "required|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]";
|
|
$rules[$field] .= $action == "insert" ? "|is_unique[{$this->table}.{$field}]" : "";
|
|
}
|
|
break;
|
|
case "user_uid":
|
|
$rules[$field] = "if_exist|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]";
|
|
break;
|
|
case "passwd":
|
|
$rules[$field] = "if_exist|trim|string";
|
|
if ($action != "") {
|
|
$rules["confirmpassword"] = "if_exist|trim|string|matches[passwd]";
|
|
}
|
|
break;
|
|
case "view_cnt":
|
|
$rules[$field] = "if_exist|numeric";
|
|
break;
|
|
case "upload_file": //uploaded[{$field}] == requried와 같은의미
|
|
$rules[$field] = !$action ? "if_exist|string" : "is_image[{$field}]|mime_in[{$field},image/jpg,image/jpeg,image/gif,image/png,image/webp]|max_size[{$field},100]|max_dims[{$field},1024,768]";
|
|
break;
|
|
case "updated_at":
|
|
case "created_at":
|
|
case "deleted_at":
|
|
$rules[$field] = "if_exist|valid_date";
|
|
break;
|
|
default:
|
|
$rules[$field] = "if_exist|string";
|
|
break;
|
|
}
|
|
return $rules;
|
|
}
|
|
final public function getFieldRules(array $fields, string $action = ""): array
|
|
{
|
|
$rules = array();
|
|
foreach ($fields as $field) {
|
|
$rules = $this->getFieldRule($field, $rules, $action);
|
|
}
|
|
return $rules;
|
|
}
|
|
//추후 VersionUP용
|
|
final public function getValidation(array $fields, string $action = "")
|
|
{
|
|
$this->_validation->reset();
|
|
foreach ($fields as $field) {
|
|
$this->_validation->setRule(
|
|
$field,
|
|
lang($this->getClassName() . '.label.' . $field),
|
|
$this->getValidationFieldRule($field, $action)
|
|
);
|
|
}
|
|
return $this->_validation;
|
|
}
|
|
//Field별 Form Option용
|
|
public function getOptions(array $conditions = array(), $options = array()): array
|
|
{
|
|
foreach ($this->getEntitys($conditions) as $entity) {
|
|
$options[$entity->getPrimaryKey()] = $entity->getTitle();
|
|
}
|
|
return $options;
|
|
}
|
|
public function getFieldFormOption(string $field): array
|
|
{
|
|
switch ($field) {
|
|
case 'user_uid':
|
|
if (is_null($this->_user_options)) {
|
|
$userModel = new UserModel();
|
|
$this->_user_options = $userModel->getOptions();
|
|
}
|
|
$options = $this->_user_options;
|
|
break;
|
|
default:
|
|
$options = lang($this->getClassName() . '.' . strtoupper($field));
|
|
break;
|
|
}
|
|
if (!is_array($options)) {
|
|
throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 Field:{$field}의 FormOptionData가 array가 아닙니다.\n" . var_export($options, true));
|
|
}
|
|
return $options;
|
|
}
|
|
//Field별 Form Option용
|
|
final public function getFieldFormOptions(array $fields): array
|
|
{
|
|
$fieldFormOptions = array();
|
|
foreach ($fields as $field) {
|
|
if (!is_string($field)) {
|
|
throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 Field:{$field}가 string 아닙니다.\n" . var_export($fields, true));
|
|
}
|
|
$fieldFormOptions[$field] = $this->getFieldFormOption($field);
|
|
}
|
|
return $fieldFormOptions;
|
|
}
|
|
|
|
final public function getUUID()
|
|
{
|
|
$randomBytes = bin2hex(random_bytes(16));
|
|
return sprintf(
|
|
"%s-%s-%s-%s-%s",
|
|
substr($randomBytes, 0, 8),
|
|
substr($randomBytes, 8, 4),
|
|
substr($randomBytes, 12, 4),
|
|
substr($randomBytes, 16, 4),
|
|
substr($randomBytes, 20)
|
|
);
|
|
}
|
|
|
|
//create , modify 직전 작업용 작업
|
|
protected function changeFormData(string $action, string $field, array $formDatas, $entity)
|
|
{
|
|
switch ($field) {
|
|
case $this->primaryKey:
|
|
//primaryKey가 자동입력이 아니면
|
|
if (!$this->useAutoIncrement) {
|
|
$pk = $this->primaryKey;
|
|
$entity->$pk = $this->getUUID();
|
|
}
|
|
break;
|
|
case "user_uid": //입력데이터로 있을시 관리툴에서 (사용자,등)추가, 없을시는 입력의 경우에만 자동(장바구니,등)으로 추가
|
|
if (array_key_exists($field, $formDatas) && !is_null($formDatas[$field])) {
|
|
//관리툴 USERSNS에서 사용자 연동 시 추가기능등에 사용
|
|
$entity->$field = $formDatas[$field];
|
|
} elseif ($action == 'create' && $this->_session->get(SESSION_NAMES["ISLOGIN"])) {
|
|
//Front에서 장바구니,게시판등에 추가시 로그온한경우 자동 추가기능등에 사용
|
|
$auth = $this->_session->get(SESSION_NAMES["AUTH"]);
|
|
$entity->$field = $auth[AUTH_FIELDS["ID"]];
|
|
}
|
|
break;
|
|
case "passwd":
|
|
// echo var_export($this->validationRules, true);
|
|
// exit;
|
|
if (array_key_exists($field, $formDatas) && !is_null($formDatas[$field])) {
|
|
$entity->$field = password_hash($formDatas[$field], PASSWORD_DEFAULT);
|
|
}
|
|
break;
|
|
case "content":
|
|
if (array_key_exists($field, $formDatas) && !is_null($formDatas[$field])) {
|
|
$entity->$field = htmlentities($formDatas[$field]);
|
|
}
|
|
break;
|
|
default:
|
|
if (array_key_exists($field, $formDatas) && !is_null($formDatas[$field])) {
|
|
$entity->$field = $formDatas[$field];
|
|
}
|
|
break;
|
|
}
|
|
return $entity;
|
|
}
|
|
|
|
final protected function save_process($entity)
|
|
{
|
|
// echo var_export($entity, true);
|
|
// exit;
|
|
if ($entity->hasChanged()) {
|
|
if (!$this->save($entity)) {
|
|
log_message("error", __FUNCTION__ . "에서 호출:" . $this->getLastQuery());
|
|
log_message("error", implode("\n", $this->errors()));
|
|
throw new \Exception(__FUNCTION__ . " 오류 발생.\n" . $this->getLastQuery() . "\n" . var_export($this->errors(), true));
|
|
}
|
|
//primaryKey가 자동입력이면
|
|
if ($this->useAutoIncrement) {
|
|
$pk = $this->primaryKey;
|
|
$entity->$pk = $this->insertID();
|
|
}
|
|
} else {
|
|
throw new \Exception(__FUNCTION__ . " 오류 발생.\n 기존정보와 동일하여 수정되지 않았습니다.");
|
|
}
|
|
return $entity;
|
|
}
|
|
protected function create_process($entity, array $formDatas)
|
|
{
|
|
// echo var_export($entity);
|
|
// exit;
|
|
foreach ($this->allowedFields as $field) {
|
|
$entity = $this->changeFormData('create', $field, $formDatas, $entity);
|
|
}
|
|
// echo var_export($this->allowedFields);
|
|
// exit
|
|
return $this->save_process($entity);
|
|
}
|
|
final protected function modify_process($entity, array $formDatas)
|
|
{
|
|
foreach ($this->allowedFields as $field) {
|
|
if ($field != $this->primaryKey) {
|
|
$entity = $this->changeFormData('modify', $field, $formDatas, $entity);
|
|
}
|
|
}
|
|
$entity->updated_at = time();
|
|
return $this->save_process($entity);
|
|
}
|
|
|
|
//Index관련
|
|
public function setIndexWordFilter(string $word)
|
|
{
|
|
}
|
|
public function setIndexDateFilter($start, $end)
|
|
{
|
|
if ($start !== DEFAULTS['EMPTY'] && $end !== DEFAULTS['EMPTY']) {
|
|
$this->where("created_at >=", $start);
|
|
$this->where("created_at <=", $end);
|
|
}
|
|
}
|
|
public function setIndexOrderBy(?string $field, ?string $order)
|
|
{
|
|
if ($this->useAutoIncrement) {
|
|
$this->orderBy($field ?: $this->primaryKey, $order ?: "DESC");
|
|
} else {
|
|
$this->orderBy($field ?: "created_at", $order ?: "DESC");
|
|
}
|
|
}
|
|
final public function setCondition(array $filterFields, $word, $start, $end, $order_field, $order_value)
|
|
{
|
|
foreach ($filterFields as $field => $value) {
|
|
$this->where($field, $value);
|
|
}
|
|
if (!is_null($word)) {
|
|
$this->setIndexWordFilter($word);
|
|
}
|
|
if (!is_null($start) && !is_null($end)) {
|
|
$this->setIndexDateFilter($start, $end);
|
|
}
|
|
$this->setIndexOrderBy($order_field, $order_value);
|
|
}
|
|
}
|