session = \Config\Services::session(); $this->_session = \Config\Services::session(); $this->_viewDatas['layout'] = LAYOUTS['empty']; $this->_viewDatas['session'] = $this->_session; $this->_viewDatas['title'] = lang($this->_model->getClassName() . '.title'); $this->_viewDatas['className'] = $this->_model->getClassName(); $this->_viewDatas['class_icon'] = CLASS_ICONS[strtoupper($this->_model->getClassName())]; helper($this->_model->getClassName()); //사용자 기본 Role 지정 $this->_viewDatas[SESSION_NAMES['ISLOGIN']] = false; $this->_viewDatas['currentRoles'] = [DEFAULTS["ROLE"]]; if ($this->_session->get(SESSION_NAMES['ISLOGIN'])) { $this->_viewDatas[SESSION_NAMES['ISLOGIN']] = true; $this->_viewDatas['auth'] = $this->_session->get(SESSION_NAMES['AUTH']); $currentRoles = explode(DEFAULTS['DELIMITER_ROLE'], $this->_viewDatas['auth'][AUTH_FIELDS['ROLE']]); $this->_viewDatas['currentRoles'] = is_array($currentRoles) ? $currentRoles : [DEFAULTS["ROLE"]]; } } abstract public function getFields(string $action): array; abstract public function getFieldFilters(): array; public function getFieldBatchFilters(): array { return $this->getFieldFilters(); } //Field별 Form Datas 처리용 protected function getFieldFormData(string $field, $entity = null): array { switch ($field) { default: $value = $this->request->getVar($field); if (!is_null($value)) { $this->_viewDatas['fieldDatas'][$field] = $value; } break; } return $this->_viewDatas['fieldDatas']; } //초기화 final public function init(string $action, $fields = null) { switch ($action) { case 'insert_form': $action = 'insert'; break; case 'update_form': $action = 'update'; break; } $this->_viewDatas['fields'] = $fields ?: $this->getFields($action); $this->_viewDatas['fieldRules'] = $this->_model->getFieldRules($this->_viewDatas['fields'], $action); $this->_viewDatas['fieldFilters'] = $this->getFieldFilters(); $this->_viewDatas['batchjobFilters'] = $this->getFieldBatchFilters(); $this->_viewDatas['fieldFormOptions'] = $this->_model->getFieldFormOptions($this->_viewDatas['fieldFilters']); return $this->_viewDatas; } //Insert관련 protected function insert_form_process() { $this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []]; } public function insert_form() { try { $this->_viewDatas = $this->init(__FUNCTION__); $this->insert_form_process(); helper(['form']); $this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']); return view($this->_viewPath . '/insert', ['viewDatas' => $this->_viewDatas]); } catch (\Exception $e) { log_message("error", $e->getMessage()); return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage()); } } protected function insert_validate() { //fieldData Rule 검사 //추후 VersionUP용 // $this->_model->getValidation($this->getFields()); // if (! $this->_validation->run($user)) { // throw new \Exception("{$this->_viewDatas['title']}의 검증 오류발생\n" . implode("\n", $this->validator->getErrors())); // } //fieldData Rule 검사 if (!$this->validate($this->_viewDatas['fieldRules'])) { throw new \Exception("{$this->_viewDatas['title']}의 검증 오류발생\n" . implode("\n", $this->validator->getErrors())); } //fieldData 적용 $this->_viewDatas['fieldDatas'] = array(); foreach ($this->_viewDatas['fields'] as $field) { $this->_viewDatas['fieldDatas'] = $this->getFieldFormData($field); } } protected function insert_process() { return $this->_model->create($this->_viewDatas['fieldDatas']); } public function insert() { $msg = ""; try { $this->_viewDatas = $this->init(__FUNCTION__); $this->insert_validate(); $entity = $this->insert_process(); $msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}의 " . __FUNCTION__ . " 완료하였습니다."; return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } catch (\Exception $e) { $msg = "{$this->_viewDatas['title']}에서 " . __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage(); log_message("error", $e->getMessage()); $this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']); return redirect()->back()->withInput(); } finally { $this->_session->setFlashdata("return_message", $msg); } } //Update관련 protected function update_form_process($entity) { $this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []]; return $entity; } public function update_form($uid) { try { $this->_viewDatas = $this->init(__FUNCTION__); $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->_viewDatas['entity'] = $this->update_form_process($entity); helper(['form']); $this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']); return view($this->_viewPath . '/update', ['viewDatas' => $this->_viewDatas]); } catch (\Exception $e) { log_message("error", $e->getMessage()); return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage()); } } protected function update_validate($entity) { //fieldData Rule 검사 //추후 VersionUP용 // $this->_model->getValidation($this->getFields()); // if (! $this->_validation->run($user)) { // throw new \Exception("{$this->_viewDatas['title']}의 검증 오류발생\n" . implode("\n", $this->validator->getErrors())); // } if (!$this->validate($this->_viewDatas['fieldRules'])) { throw new \Exception("{$this->_viewDatas['title']}의 검증 오류발생\n" . implode("\n", $this->validator->getErrors())); } //fieldData 적용 $this->_viewDatas['fieldDatas'] = array(); foreach ($this->_viewDatas['fields'] as $field) { $this->_viewDatas['fieldDatas'] = $this->getFieldFormData($field, $entity); } //변견된 데이터 Log로 남기기 foreach ($this->_viewDatas['fieldDatas'] as $field => $value) { if ($field != "passwd") { //보안위험성이 있으므로 passwd는 Log에 남기지 않는다. log_message( "info", sprintf( "{$field} 변경: ---원본--\n%s\n---변경---\n%s", $entity->$field, var_export($value, true) ) ); } } } protected function update_process($entity) { return $this->_model->modify($entity, $this->_viewDatas['fieldDatas']); } public function update($uid) { $msg = ""; try { $this->_viewDatas = $this->init(__FUNCTION__); $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->update_validate($entity); $entity = $this->update_process($entity); $msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}의 " . __FUNCTION__ . " 완료하였습니다."; return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } catch (\Exception $e) { $msg = "{$this->_viewDatas['title']}에서 " . __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage(); log_message("error", $e->getMessage()); $this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']); return redirect()->back()->withInput(); } finally { $this->_session->setFlashdata("return_message", $msg); } } //Reply관련 protected function reply_form_process($entity) { $titleField = $this->_model->getTitleField(); $entity->$titleField = "RE: " . $entity->$titleField; $this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []]; return $entity; } public function reply_form($uid) { try { $this->_viewDatas = $this->init(__FUNCTION__); $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->_viewDatas['entity'] = $this->reply_form_process($entity); helper(['form']); $this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']); return view($this->_viewPath . '/reply', ['viewDatas' => $this->_viewDatas]); } catch (\Exception $e) { log_message("error", $e->getMessage()); return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage()); } } protected function reply_validate($entity) { $this->update_validate($entity); } protected function reply_process($entity) { return $this->_model->reply($entity, $this->_viewDatas['fieldDatas']); } public function reply($uid) { $msg = ""; try { $this->_viewDatas = $this->init(__FUNCTION__); $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->reply_validate($entity); $entity = $this->reply_process($entity); $msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}의 " . __FUNCTION__ . " 완료하였습니다."; return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } catch (\Exception $e) { $msg = "{$this->_viewDatas['title']}에서 " . __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage(); log_message("error", $e->getMessage()); $this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']); return redirect()->back()->withInput(); } finally { $this->_session->setFlashdata("return_message", $msg); } } //Toggle 관련 protected function toggle_validate($entity) { $this->update_validate($entity); } protected function toggle_process($entity) { return $this->update_process($entity); } public function toggle($uid, string $field) { $msg = ""; try { $this->_viewDatas = $this->init(__FUNCTION__, [$field]); $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->toggle_validate($entity); $entity = $this->toggle_process($entity); $msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}의 " . __FUNCTION__ . " 완료하였습니다."; return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } catch (\Exception $e) { $msg = "{$this->_viewDatas['title']}에서 " . __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage(); log_message("error", $e->getMessage()); return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } finally { $this->_session->setFlashdata("return_message", $msg); } } //Batchjob 관련 protected function batchjob_validate($entity) { $this->update_validate($entity); } protected function batchjob_process($entity) { return $this->update_process($entity); } public function batchjob() { $msg = ""; $entitys = array(); $batchjobs = array(); try { //fields 해당하는 field중 선택된 값이 있는경우만 fields로 정의 $fields = array(); foreach ($this->_model->getFieldBatchFilters() as $field) { if ($this->request->getVar($field)) { array_push($fields, $field); } } if (!is_array($fields) || count($fields) === 0) { throw new \Exception($this->_viewDatas['title'] . '에서 변경할 항목(field)이 선택되지 않았습니다.'); } $this->_viewDatas = $this->init(__FUNCTION__, $fields); $uids = $this->request->getVar('batchjob_uids') ?: throw new \Exception($this->_viewDatas['title'] . '에서 변경할 항목(uid)이 선택되지 않았습니다.'); $cnt = 1; //Transaction 시작 $this->_model->transStart(); foreach ($uids as $uid) { try { $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->batchjob_validate($entity); $entity = $this->batchjob_process($entity); array_push($entitys, $this->_model->modify($entity, $this->_viewDatas['fieldDatas'])); array_push($batchjobs, "{$cnt}. {$uid}->{$entity->getTitle()}는 완료."); } catch (\Exception $e) { array_push($batchjobs, "{$cnt}. {$uid}는 실패."); } $cnt++; } //Transaction Commit $this->_model->transComplete(); $msg = sprintf( "%s에서 총:%s개의 %s 완료하였습니다.", $this->_viewDatas['title'], count($entitys), __FUNCTION__ ); return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } catch (\Exception $e) { //Transaction Rollback $this->_model->transRollback(); log_message('error', sprintf("---------batchjob 작업결과--------\n%s\n", implode("\n", $batchjobs))); return sprintf( "총:%s개의 작업중 %s개는 성공하였지만 , %s개가 실패하여 %s 취소되었습니다.\n%s", count($uids), count($entitys), count($uids) - count($entitys), __FUNCTION__, ); log_message("error", $e->getMessage()); return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } finally { $this->_session->setFlashdata("return_message", $msg); } } //Delete 관련 protected function delete_process($entity) { if (!$this->_model->delete($entity->getPrimaryKey())) { log_message("error", __FUNCTION__ . "에서 호출:" . $this->_model->getLastQuery()); log_message("error", implode("\n", $this->_model->errors())); throw new \Exception(__FUNCTION__ . " 오류 발생.\n" . var_export($this->_model->errors(), true)); } return $entity; } public function delete($uid) { $msg = ""; try { $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->delete_process($entity); $msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}의 " . __FUNCTION__ . " 완료하였습니다."; return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } catch (\Exception $e) { $msg = "{$this->_viewDatas['title']}에서 " . __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage(); log_message("error", $e->getMessage()); return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/"); } finally { $this->_session->setFlashdata("return_message", $msg); } } //View 관련 protected function view_process($entity) { $this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []]; return $entity; } public function view($uid) { try { $this->_viewDatas = $this->init(__FUNCTION__); $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); $this->_viewDatas['entity'] = $this->view_process($entity); helper(['form']); $this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']); return view($this->_viewPath . '/view', ['viewDatas' => $this->_viewDatas]); } catch (\Exception $e) { return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage()); } } //Index 관련 protected function index_process() { $this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []]; } protected function index_setCondition() { //조건절 처리 $filterFields = array(); foreach ($this->_viewDatas['fieldFilters'] as $field) { if (!is_null($this->request->getVar($field))) { $filterFields[$field] = $this->request->getVar($field); } } $this->_viewDatas['word'] = $this->request->getVar('word') ?: ''; $this->_viewDatas['start'] = $this->request->getVar('start') ?: ''; $this->_viewDatas['end'] = $this->request->getVar('end') ?: ''; $this->_viewDatas['order_field'] = $this->request->getVar('order_field') ?: 'uid'; $this->_viewDatas['order_value'] = $this->request->getVar('order_value') ?: 'DESC'; $this->_model->setCondition( $filterFields, $this->_viewDatas['word'], $this->_viewDatas['start'], $this->_viewDatas['end'], $this->_viewDatas['order_field'], $this->_viewDatas['order_value'] ); } private function index_getPagination($pager_group = 'default', int $segment = 0, $template = 'bootstrap_full'): string { // 1.Views/Pagers/에 bootstrap_full.php,bootstrap_simple.php 생성 // 2.app/Config/Pager.php/$templates에 'bootstrap_full => 'Pagers\bootstrap_full', // 'bootstrap_simple' => 'Pagers\bootstrap_simple', 추가 $pager = \Config\Services::pager(); // $this->_model->paginate($this->_viewDatas['per_page'], $pager_group, $this->_viewDatas['page'], $segment); $pager->makeLinks( $this->_viewDatas['page'], $this->_viewDatas['per_page'], $this->_viewDatas['total_count'], $template, $segment, $pager_group ); $this->_viewDatas['page'] = $pager->getCurrentPage($pager_group); $this->_viewDatas['total_page'] = $pager->getPageCount($pager_group); return $pager->links($pager_group, $template); } private function index_getEntitys(): array { $this->index_setCondition(); return $this->_viewDatas['page'] ? $this->_model->findAll( $this->_viewDatas['per_page'], $this->_viewDatas['page'] * $this->_viewDatas['per_page'] - $this->_viewDatas['per_page'] ) : $this->_model->findAll(); } public function index() { try { $this->_viewDatas = $this->init(__FUNCTION__); foreach ($this->_viewDatas['fieldFilters'] as $field) { $this->_viewDatas[$field] = $this->request->getVar($field) ?: DEFAULTS['EMPTY']; } $this->index_process(); //Totalcount 처리 $this->index_setCondition(); $this->_viewDatas['total_count'] = $this->_model->countAllResults(); // echo $this->_model->getLastQuery(); // echo "
"; // log_message("debug", __METHOD__ . "에서 TotalCount 호출:" . $this->_model->getLastQuery()); //Page, Per_page필요부분 $this->_viewDatas['page'] = (int)$this->request->getVar('page') ?: 1; $this->_viewDatas['per_page'] = (int)$this->request->getVar('per_page') ?: DEFAULTS['PERPAGE']; $this->_viewDatas['uri'] = $this->request->getUri(); //줄수 처리용 $this->_viewDatas['pageOptions'] = array("" => "줄수선택"); for ($i = 10; $i <= $this->_viewDatas['total_count'] + $this->_viewDatas['per_page']; $i += 10) { $this->_viewDatas['pageOptions'][$i] = $i; } //pagenation 처리 $this->_viewDatas['pagination'] = $this->index_getPagination(); //모델 처리 $this->_viewDatas['entitys'] = $this->index_getEntitys(); // echo $this->_model->getLastQuery(); // log_message("debug", __METHOD__ . "에서 findAll 호출:" . $this->_model->getLastQuery()); //setting return_url to session flashdata helper(['form']); $this->_session->setFlashdata(SESSION_NAMES['RETURN_URL'], current_url() . '?' . $this->request->getUri()->getQuery() ?: ""); return view($this->_viewPath . '/index' . $this->request->getVar('v') ?: '', ['viewDatas' => $this->_viewDatas]); } catch (\Exception $e) { return alert_CommonHelper($e->getMessage(), "back"); // return redirect()->back()->with('return_message', $e->getMessage()); } } //Excel 관련 private function excel_spreadSheet(array $viewDatas) { //Excepl 초기화 $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); //Header용 $column = 'A'; foreach ($viewDatas['fields'] as $field) { $sheet->setCellValue($column++ . '1', lang($this->_model->getClassName() . '.label.' . $field)); } //본문용 $line = 2; foreach ($this->index_getEntitys() as $entity) { $column = 'A'; foreach ($viewDatas['fields'] as $field) { $value = in_array($field, $viewDatas['fieldFilters']) ? $viewDatas['fieldFormOptions'][$field][$entity->$field] : $entity->$field; $sheet->setCellValue($column . $line, $value); $column++; } $line++; } return $spreadsheet; } public function excel() { try { $this->_viewDatas = $this->init(__FUNCTION__); $fileName = date('Y-m-d_Hm') . '.xlsx'; $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($this->excel_spreadSheet($this->_viewDatas), 'Xlsx'); //결과파일저장 $writer->save(PATHS['EXCEL'] . '/' . $fileName); //Download시 header("Content-Type: application/vnd.ms-excel"); header(sprintf("Content-Disposition: attachment; filename=%s", urlencode($fileName))); header("Expires: 0"); header("Cache-Control: must-revalidate"); header("Pragma: public"); header("Content-Length:" . filesize(PATHS['EXCEL'] . '/' . $fileName)); // flush(); // return readfile(PATHS['EXCEL'] . '/' . $fileName); return $writer->save('php://output'); } catch (\Exception $e) { return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage()); } } //File Download관련 public function download_process($entity) { return $entity; } public function download(string $field, $uid) { try { $entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]); if (!$entity->$field) { throw new \Exception("첨부파일이 확인되지 않습니다."); } $entity = $this->download_process($entity); list($filename, $uploaded_filename) = explode(DEFAULTS['DELIMITER_FILE'], $entity->$field); if (!is_file(PATHS['UPLOAD'] . "/" . $uploaded_filename)) { throw new \Exception("파일이 확인되지 않습니다.\n" . PATHS['UPLOAD'] . "/" . $uploaded_filename); } return $this->response->download(PATHS['UPLOAD'] . "/" . $uploaded_filename, null)->setFileName(date("Ymd") . '_' . $filename); } catch (\Exception $e) { return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage()); } } }