diff --git a/app/Config/Constants.php b/app/Config/Constants.php index 9c7f86e..d92f34f 100644 --- a/app/Config/Constants.php +++ b/app/Config/Constants.php @@ -197,7 +197,8 @@ define('DEFAULTS', [ 'STATUS' => getenv('default.status') ?: "use", 'EMPTY' => getenv('default.empty') ?: "", 'PERPAGE' => getenv('default.perpage') ?: 20, - 'HIERARCHY_GRPDEPTH' => getenv('default. hierarchy_grpdepth') ?: 20, + 'HIERARCHY_GRPDEPTH' => getenv('default.hierarchy_grpdepth') ?: 20, + 'FILE_DLIMITER' => getenv('default.file_delimiter') ?: "||", ]); //API Adapter초기갑 정의 diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 0382be8..4c66ea4 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -91,7 +91,7 @@ $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'au $routes->get('delete/(:num)', 'BoardController::delete/$1', ['filter' => 'authFilter:master']); $routes->get('toggle/(:num)/(:hash)', 'BoardController::toggle/$1/$2'); $routes->post('batchjob', 'BoardController::batchjob'); - $routes->get('download/(:num)', 'BoardController::download/$1'); + $routes->get('download/(:alpha)/(:num)', 'BoardController::download/$1/$2'); }); $routes->group('hpilo', static function ($routes) { $routes->get('', 'HPILOController::index'); diff --git a/app/Controllers/Admin/BoardController.php b/app/Controllers/Admin/BoardController.php index 5b21434..ff5c886 100644 --- a/app/Controllers/Admin/BoardController.php +++ b/app/Controllers/Admin/BoardController.php @@ -71,21 +71,4 @@ class BoardController extends AdminHierarchyController $this->_model->increaseViewCount($entity->getPrimaryKey()); return parent::view_process($entity); } - //File Download관련 - public function download($uid) - { - try { - $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); - if (!$entity->getFile()) { - throw new \Exception("해당게시물은 첨부파일이 확인되지 않습니다."); - } - list($origin_filename, $filename) = explode("||", $entity->getFile()); - if (is_file(WRITEPATH . PATHS['UPLOAD'] . "/" . $origin_filename)) { - throw new \Exception("파일이 확인되지 않습니다."); - } - return $this->response->download(WRITEPATH . PATHS['UPLOAD'] . "/" . $filename, null)->setFileName(date("YmdHms") . '_' . $origin_filename); - } catch (\Exception $e) { - return alert_CommonHelper($e->getMessage(), 'back'); - } - } } diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php index bb65dc2..924e29f 100644 --- a/app/Controllers/BaseController.php +++ b/app/Controllers/BaseController.php @@ -125,7 +125,7 @@ abstract class BaseController extends Controller $originName = $upfile->getName(); $upfile->move(WRITEPATH . PATHS['UPLOAD'], $upfile->getRandomName()); //move시 중복된파일명이 있다면 파일명이 바뀌므로 여기서 한번더 파일명 확인 필요 - $fileName = $originName . "||" . $upfile->getName(); + $fileName = $originName . DEFAULTS['FILE_DLIMITER'] . $upfile->getName(); } return $fileName; } @@ -399,6 +399,7 @@ abstract class BaseController extends Controller public function view($uid) { try { + $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->_viewDatas['fields'] = $this->_model->getFields('view'); $this->_viewDatas['fieldRules'] = $this->_model->getFieldRules($this->_viewDatas['fields'], 'view'); @@ -563,4 +564,21 @@ abstract class BaseController extends Controller return alert_CommonHelper($e->getMessage(), 'back'); } } + //File Download관련 + final public function download(string $field, $uid) + { + try { + $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); + if (!$entity->$field) { + throw new \Exception("첨부파일이 확인되지 않습니다."); + } + list($origin_filename, $filename) = explode(DEFAULTS['FILE_DLIMITER'], $entity->$field); + if (is_file(WRITEPATH . PATHS['UPLOAD'] . "/" . $origin_filename)) { + throw new \Exception("파일이 확인되지 않습니다."); + } + return $this->response->download(WRITEPATH . PATHS['UPLOAD'] . "/" . $filename, null)->setFileName(date("YmdHms") . '_' . $origin_filename); + } catch (\Exception $e) { + return alert_CommonHelper($e->getMessage(), 'back'); + } + } } diff --git a/app/Database/base.sql b/app/Database/base.sql index 70e496f..b311e5e 100644 --- a/app/Database/base.sql +++ b/app/Database/base.sql @@ -19,7 +19,7 @@ CREATE TABLE servermgr.tw_user ( DROP TABLE IF EXISTS servermgr.tw_user_profile; CREATE TABLE servermgr.tw_user_profile ( - uid int(10) unsigned NOT NULL AUTO_INCREMENT, + uid int(10) UNSIGNED NOT NULL AUTO_INCREMENT, user_uid varchar(36) NULL COMMENT '사용자 정보', type varchar(10) NOT NULL COMMENT 'ICON|ADDRESS|PHONE|MOBILE|EMAIL 등등', content varchar(255) NULL, @@ -34,7 +34,7 @@ CREATE TABLE servermgr.tw_user_profile ( DROP TABLE IF EXISTS servermgr.tw_user_sns; CREATE TABLE servermgr.tw_user_sns ( - uid int(10) unsigned NOT NULL AUTO_INCREMENT, + uid int(10) UNSIGNED NOT NULL AUTO_INCREMENT, user_uid varchar(36) NULL COMMENT '사용자 정보', site varchar(20) NOT NULL COMMENT 'Site: GOOGLE,FACEBOOK 등등', id varchar(255) NOT NULL COMMENT 'sns 로그인 인중후 Return ID값', @@ -76,11 +76,10 @@ DROP TABLE IF EXISTS servermgr.tw_board; -- 3. 게시물 조회시 작업 -- select * from tw_board order by grpno desc,grporder asc CREATE TABLE servermgr.tw_board ( - uid int(10) unsigned NOT NULL AUTO_INCREMENT, - grpno int(10) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Group번호: uid와 Type맞춰야함 , 상위가없을시 기본 uid와 같음', - grporder int(5) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Group순서: 최상위시 1부터시작', - grpdepth int(2) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Group깊이: 최상위시 1부터시작 , 상위 grpdpt+1씩 추가필요', - board_config_uid varchar(36) NOT NULL COMMENT '게시판구분', + uid int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + grpno int(10) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Group번호: 상위가없을시 기본 uid와 같음,항상 숫자여야함', + grporder int(5) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Group순서: 상위가없을시 1부터시작', + grpdepth int(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Group깊이: 상위가없을시 1부터시작 , 상위 grpdepth+1씩 추가필요', board_config_uid varchar(36) NOT NULL COMMENT '게시판구분', user_uid varchar(36) NULL COMMENT '작성자 정보', title varchar(255) NOT NULL COMMENT '제목', content text NOT NULL COMMENT '내용', @@ -97,8 +96,8 @@ CREATE TABLE servermgr.tw_board ( DROP TABLE IF EXISTS servermgr.tw_board_file; CREATE TABLE servermgr.tw_board_file ( - uid int(10) unsigned NOT NULL AUTO_INCREMENT, - board_uid int(10) unsigned NOT NULL COMMENT '게시물 정보', + uid int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + board_uid int(10) UNSIGNED NOT NULL COMMENT '게시물 정보', mime_type varchar(50) NOT NULL COMMENT 'Mime_Type', name varchar(255) NOT NULL COMMENT '파일명', real_name varchar(255) NOT NULL COMMENT '실제파일명', diff --git a/app/Entities/BoardEntity.php b/app/Entities/BoardEntity.php index 0bc53af..7dfcbd5 100644 --- a/app/Entities/BoardEntity.php +++ b/app/Entities/BoardEntity.php @@ -27,10 +27,6 @@ class BoardEntity extends BaseHierarchyEntity { return $this->attributes['passwd']; } - public function getFile() - { - return $this->attributes['board_file']; - } public function getViews() { return $this->attributes['view_cnt']; diff --git a/app/Helpers/Admin/BoardConfig_helper.php b/app/Helpers/Admin/BoardConfig_helper.php index 46fd941..8d6966d 100644 --- a/app/Helpers/Admin/BoardConfig_helper.php +++ b/app/Helpers/Admin/BoardConfig_helper.php @@ -53,6 +53,9 @@ function getFieldForm_BoardConfigHelper($field, $value, array $fieldFormOptions, case 'upload_file': return form_upload($field); break; + case 'name': + return form_input($field, $value, [...$attributes, "placeholder" => "예)", "style" => "width:60%; ::placeholder{ color:silver; opacity: 1; }"]); + break; default: return form_input($field, $value, [...$attributes]); break; @@ -64,7 +67,7 @@ function getFieldView_BoardConfigHelper($field, $entity, array $fieldFilters, ar $value = $entity->$field ?: DEFAULTS['EMPTY']; switch ($field) { case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'head': case 'tail': @@ -102,7 +105,7 @@ function getFieldIndex_Row_BoardConfigHelper($field, $entity, array $fieldFilter return anchor(current_url() . '/view/' . $entity->getPrimaryKey(), $value, [...$attributes, "target" => "_self"]); break; case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'updated_at': case 'created_at': diff --git a/app/Helpers/Admin/Board_helper.php b/app/Helpers/Admin/Board_helper.php index f6aeeb0..deafb36 100644 --- a/app/Helpers/Admin/Board_helper.php +++ b/app/Helpers/Admin/Board_helper.php @@ -48,6 +48,9 @@ function getFieldForm_BoardHelper($field, $value, array $fieldFormOptions, array case 'board_file': return form_upload($field); break; + case 'title': + return form_input($field, $value, [...$attributes, "placeholder" => "예)", "style" => "width:60%; ::placeholder{ color:silver; opacity: 1; }"]); + break; default: return form_input($field, $value, [...$attributes]); break; @@ -60,7 +63,7 @@ function getFieldView_BoardHelper($field, $entity, array $fieldFilters, array $f switch ($field) { case 'board_file': case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . "/download/{$field}/{$entity->getPrimaryKey()}", ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'content': return html_entity_decode($value); @@ -114,12 +117,13 @@ function getFieldIndex_Row_BoardHelper($field, $entity, array $fieldFilters, $fi break; case 'board_file': case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . "/download/{$field}/{$entity->getPrimaryKey()}", ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'updated_at': case 'created_at': return isset($value) ? str_split($value, 10)[0] : ""; break; + default: if (in_array($field, $fieldFilters)) { $attributes["onChange"] = sprintf('location.href="%s/toggle/%s/%s?%s="+this.options[this.selectedIndex].value', current_url(), $entity->getPrimaryKey(), $field, $field); diff --git a/app/Helpers/Admin/UserSNS_helper.php b/app/Helpers/Admin/UserSNS_helper.php index ef0b36c..28429e8 100644 --- a/app/Helpers/Admin/UserSNS_helper.php +++ b/app/Helpers/Admin/UserSNS_helper.php @@ -58,7 +58,7 @@ function getFieldView_UserSNSHelper($field, $entity, array $fieldFilters, array $value = $entity->$field ?: DEFAULTS['EMPTY']; switch ($field) { case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'content': return html_entity_decode($value); @@ -95,7 +95,7 @@ function getFieldIndex_Row_UserSNSHelper($field, $entity, array $fieldFilters, $ return anchor(current_url() . '/view/' . $entity->getPrimaryKey(), $value, [...$attributes, "target" => "_self"]); break; case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'updated_at': case 'created_at': diff --git a/app/Helpers/Admin/User_helper.php b/app/Helpers/Admin/User_helper.php index 3844bce..59fbe51 100644 --- a/app/Helpers/Admin/User_helper.php +++ b/app/Helpers/Admin/User_helper.php @@ -47,6 +47,9 @@ function getFieldForm_UserHelper($field, $value, array $fieldFormOptions, array case 'upload_file': return form_upload($field); break; + case 'name': + return form_input($field, $value, [...$attributes, "placeholder" => "예)홍길동", "style" => "width:60%; ::placeholder{ color:silver; opacity: 1; }"]); + break; default: return form_input($field, $value, [...$attributes]); break; @@ -58,7 +61,7 @@ function getFieldView_UserHelper($field, $entity, array $fieldFilters, array $fi $value = $entity->$field ?: DEFAULTS['EMPTY']; switch ($field) { case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'content': return html_entity_decode($value); @@ -95,7 +98,7 @@ function getFieldIndex_Row_UserHelper($field, $entity, array $fieldFilters, $fie return anchor(current_url() . '/view/' . $entity->getPrimaryKey(), $value, [...$attributes, "target" => "_self"]); break; case 'upload_file': - return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode("||", $value)[0], [...$attributes, "target" => "_self"]); + return $value == DEFAULTS['EMPTY'] ? DEFAULTS['EMPTY'] : anchor(current_url() . '/download/' . $entity->getPrimaryKey(), ICONS['IMAGE_FILE'] . explode(DEFAULTS['FILE_DLIMITER'], $value)[0], [...$attributes, "target" => "_self"]); break; case 'updated_at': case 'created_at': diff --git a/app/Models/BaseHierarchyModel.php b/app/Models/BaseHierarchyModel.php index f4c619c..31cb732 100644 --- a/app/Models/BaseHierarchyModel.php +++ b/app/Models/BaseHierarchyModel.php @@ -19,7 +19,7 @@ abstract class BaseHierarchyModel extends BaseModel case "grpno": case "grporder": case "grpdepth": - $rules[$field] = "if_exist|numeric"; + $rules[$field] = "if_exist|numeric"; //반드시숫자여야함 break; default: $rules = parent::getFieldRule($field, $rules, $action); @@ -31,7 +31,7 @@ abstract class BaseHierarchyModel extends BaseModel final protected function create_process($entity, array $formDatas) { $entity = parent::create_process($entity, $formDatas); - //생성시는 grpno가 primarykey와 같음 + //생성시는 grpno가 primarykey와 같고 숫자여야함 $this->builder()->set("grpno", $entity->getPrimaryKey()); $this->builder()->where($this->primaryKey, $entity->getPrimaryKey()); $this->builder()->update(); diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index e9ba1b6..da859a0 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -61,6 +61,12 @@ abstract class BaseModel extends Model 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; @@ -107,7 +113,7 @@ abstract class BaseModel extends Model return $fields; } - final public function getFieldFormOptions($conditions, $options = array()): array + public function getFieldFormOptions($conditions, $options = array()): array { foreach ($this->getEntitys($conditions) as $entity) { $options[$entity->getPrimaryKey()] = $entity->getTitle(); diff --git a/app/Models/BoardModel.php b/app/Models/BoardModel.php index 6f02d3c..12f2071 100644 --- a/app/Models/BoardModel.php +++ b/app/Models/BoardModel.php @@ -6,6 +6,7 @@ use App\Entities\BoardEntity; class BoardModel extends BaseHierarchyModel { + //BaseHierarchyModel를 확장하면 grpno가 숫자이고, primarykey를 대분류 생성시 copy하여 grpno에 넣고 sorting하므로 protected $table = "tw_board"; protected $returnType = BoardEntity::class; public function __construct() diff --git a/app/Models/UserModel.php b/app/Models/UserModel.php index ee73ec2..32bc2f6 100644 --- a/app/Models/UserModel.php +++ b/app/Models/UserModel.php @@ -12,7 +12,7 @@ class UserModel extends BaseModel public function __construct() { parent::__construct(); - $this->allowedFields = [...$this->allowedFields, ...$this->getFields()]; + $this->allowedFields = ["uid", ...$this->allowedFields, ...$this->getFields()]; $this->validationRules = [...$this->validationRules, ...$this->getFieldRules($this->allowedFields),]; } public function getTitle(): string @@ -42,10 +42,6 @@ class UserModel extends BaseModel protected function getFieldRule(string $field, array $rules, string $action = ""): array { switch ($field) { - case "uid": - $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 "id": $rules[$field] = "required|trim|min_length[4]|max_length[20]"; $rules[$field] .= $action == "insert" ? "|is_unique[{$this->table}.{$field}]" : ""; diff --git a/app/Views/admin/boardconfig/update.php b/app/Views/admin/boardconfig/update.php index 0d7f40b..5d1a137 100644 --- a/app/Views/admin/boardconfig/update.php +++ b/app/Views/admin/boardconfig/update.php @@ -9,7 +9,7 @@ = getFieldLabel_BoardConfigHelper($field, $fieldRules) ?>