Automation init...4

This commit is contained in:
최준흠 2024-09-22 23:04:57 +09:00
parent 4a7b0deefc
commit dcb78a3745
65 changed files with 1925 additions and 535 deletions

View File

@ -6,14 +6,11 @@ use CodeIgniter\Router\RouteCollection;
* @var RouteCollection $routes * @var RouteCollection $routes
*/ */
//추가 Custom RULE 만들때 : ex)UUID형식 //추가 Custom RULE 만들때 : ex)UUID형식
$routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'); $routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}');
//authFilter는 추가적인 작업이 필요 //authFilter는 추가적인 작업이 필요
//1. app/Filters/AuthFilter.php //1. app/Filters/AuthFilter.php
//2. Config/Filters.php -> $aliases = ['authFilter' => AuthFilter::class] //2. Config/Filters.php -> $aliases = ['authFilter' => AuthFilter::class]
$routes->get('/', 'Home::index'); $routes->get('/', 'Home::index');
$routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'authFilter:manager'], function ($routes) { $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'authFilter:manager'], function ($routes) {
$routes->get('/', 'Home::index'); $routes->get('/', 'Home::index');
@ -35,3 +32,13 @@ $routes->group('mangboard', ['namespace' => 'App\Controllers\Mangboard'], functi
$routes->cli('(:alpha)/(:any)/(:any)', 'CrawlerController::$1/$2'); $routes->cli('(:alpha)/(:any)/(:any)', 'CrawlerController::$1/$2');
}); });
}); });
$routes->group(name: 'cloudflare', ['namespace' => 'App\Controllers\Cloudflare'], function ($routes) {
$routes->group('account', function ($routes) {
$routes->get('/', 'AccountController::index');
$routes->get('/create', 'AccountController::create_form');
});
$routes->group('zone', function ($routes) {
$routes->get('/', 'ZoneController::index');
$routes->get('/create', 'ZoneController::create_form');
});
});

View File

@ -12,8 +12,6 @@ use CodeIgniter\HTTP\RedirectResponse;
use App\Traits\AuthTrait; use App\Traits\AuthTrait;
use App\Models\Cloudflare\AccountModel; use App\Models\Cloudflare\AccountModel;
use App\Entities\Cloudflare\AccountEntity; use App\Entities\Cloudflare\AccountEntity;
use App\Libraries\MySocket\CloudflareSocket;
class AccountController extends MVController class AccountController extends MVController
{ {
@ -24,9 +22,9 @@ class AccountController extends MVController
parent::initController($request, $response, $logger); parent::initController($request, $response, $logger);
$this->session = $this->session_AuthTrait(); $this->session = $this->session_AuthTrait();
$this->class_name = 'Account'; $this->class_name = 'Account';
$this->view_path = 'Account';
helper($this->class_name); helper($this->class_name);
} }
final protected function getModel(): AccountModel final protected function getModel(): AccountModel
{ {
if ($this->_model === null) { if ($this->_model === null) {
@ -36,7 +34,7 @@ class AccountController extends MVController
} }
protected function create_init(): void protected function create_init(): void
{ {
$this->fields = ['id', 'apikey']; $this->fields = [$this->getModel()::TITLE, 'apikey', 'status'];
$this->filter_fields = ['status']; $this->filter_fields = ['status'];
$this->action = DB_ACTION["CREATE"]; $this->action = DB_ACTION["CREATE"];
$this->getModel()->setAction($this->action); $this->getModel()->setAction($this->action);

View File

@ -11,11 +11,9 @@ use App\Traits\AuthTrait;
use App\Models\Cloudflare\ZoneModel; use App\Models\Cloudflare\ZoneModel;
use App\Models\Cloudflare\AccountModel; use App\Models\Cloudflare\AccountModel;
use App\Libraries\MySocket\CloudflareSocket;
use App\Libraries\MyCloudflare\Zone; use App\Libraries\MyCloudflare\Zone;
use App\Entities\Cloudflare\ZoneEntity; use App\Entities\Cloudflare\ZoneEntity;
class ZoneController extends MVController class ZoneController extends MVController
{ {
use AuthTrait; use AuthTrait;
@ -42,10 +40,25 @@ class ZoneController extends MVController
} }
return $this->_accountModel; return $this->_accountModel;
} }
protected function getFormFieldOption(string $field, array $options = []): array
{
switch ($field) {
case ZoneModel::PARENT:
$options = [
DEFAULTS['EMPTY'] => lang($this->_className . '.label.' . $field) . ' 선택'
];
$options = $this->getAccountModel()->getFilterFieldOption($field, $options);
break;
default:
$options = parent::getFormFieldOption($field, $options);
break;
}
return $options;
}
protected function create_init(): void protected function create_init(): void
{ {
$this->fields = ['id', 'apikey']; $this->fields = [$this->getModel()::PARENT, $this->getModel()::TITLE, 'status', 'type'];
$this->filter_fields = ['status']; $this->filter_fields = [$this->getModel()::PARENT, 'status', 'type'];
$this->action = 'create'; $this->action = 'create';
$this->getModel()->setAction($this->action); $this->getModel()->setAction($this->action);
} }

View File

@ -16,32 +16,51 @@ abstract class MVController extends CommonController
abstract protected function create_init(): void; abstract protected function create_init(): void;
abstract protected function getModel(): mixed; abstract protected function getModel(): mixed;
//Field별 Form Option용 //Field별 Form Option용
protected function getFormFilterOption(string $filter_field, array $filter_options): array protected function getFormFieldOption(string $field, array $options = []): array
{ {
switch ($filter_field) { switch ($field) {
default: default:
$temps = lang($this->class_name . '.' . strtoupper($filter_field)); $temps = lang($this->class_name . '.' . strtoupper($field));
if (!is_array($temps)) { if (!is_array($temps)) {
throw new \Exception(__FUNCTION__ . "에서 {$filter_field}의 데이터가 array가 아닙니다.\n" . var_export($temps, true)); throw new \Exception(__FUNCTION__ . "에서 {$field}의 데이터가 array가 아닙니다.\n" . var_export($temps, true));
} }
$filter_options[$filter_field] = [ $options = [
["" => lang($this->class_name . '.label.' . $filter_field) . ' 선택'], ["" => lang($this->class_name . '.label.' . $field) . ' 선택'],
lang($this->class_name . '.' . strtoupper($filter_field)) lang($this->class_name . '.' . strtoupper($field))
]; ];
break; break;
} }
return $filter_options; return $options;
} }
//Field별 Form Option용 protected function getFormFieldInput(string $field, mixed $value, array $inputs = []): array
final public function getFormFilterOptions(array $filter_options = []): array
{ {
foreach ($this->filter_fields as $filter_field) { switch ($field) {
if (is_array($filter_field)) { case 'status':
throw new \Exception(__FUNCTION__ . "에서 filter_field가 array 입니다.\n" . var_export($filter_field, true)); $inputs[$field] = form_dropdown(
$field,
$this->getFormFieldOption($field),
$value
);
break;
case 'updated_at':
case 'created_at':
$inputs[$field] = form_input($field, $value, ["class" => " calender"]);
break;
default:
$inputs[$field] = form_input($field, $value);
break;
} }
$filter_options = $this->getFormFilterOption($filter_field, $filter_options); return $inputs;
} }
return $filter_options; final public function getFormFieldInputs(array $inputs = []): array
{
foreach ($this->fields as $field) {
if (is_array($field)) {
throw new \Exception(__FUNCTION__ . "에서 field array 입니다.\n" . var_export($field, true));
}
$inputs = $this->getFormFieldInput($field, old($field), $inputs);
}
return $inputs;
} }
protected function getFormFieldRule(string $field, array $rules): array protected function getFormFieldRule(string $field, array $rules): array
{ {
@ -95,9 +114,12 @@ abstract class MVController extends CommonController
helper(['form']); helper(['form']);
try { try {
$this->create_init(); $this->create_init();
$this->create_form_process(); $this->forminputs = $this->getFormFieldInputs();
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']); $this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return view("/{$this->class_name}/insert", ['attributes' => $this->getAttributes]); return view(
$this->view_path . "/" . strtolower($this->class_name) . "/create",
['viewDatas' => $this->getAttributes()]
);
} catch (\Exception $e) { } catch (\Exception $e) {
log_message("error", $e->getMessage()); log_message("error", $e->getMessage());
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with(SESSION_NAMES['RETURN_MSG'], $e->getMessage()); return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with(SESSION_NAMES['RETURN_MSG'], $e->getMessage());

View File

@ -0,0 +1,22 @@
<?php
return [
'title' => "Account정보",
'label' => [
'uid' => "번호",
'id' => "인증ID",
'apikey' => "인증Key",
'oldkey' => "이전인증Key",
'type' => "가입방식",
'status' => "상태",
'updated_at' => "수정일",
'created_at' => "작성일"
],
"TYPE" => [
"standard" => "standard",
"enterprise" => "enterprise"
],
"STATUS" => [
"use" => "사용",
"unuse" => "사용않함",
]
];

View File

@ -0,0 +1,47 @@
<?php
return [
'title' => "Record정보",
'label' => [
'uid' => "번호",
'zone_uid' => "도메인",
'type' => "Type",
'host' => "호스트명",
'content' => "IP정보",
'ttl' => "TTL",
'proxiable' => "proxiable",
'fixed' => "CDN잠금",
'proxied' => "CDN기능",
'locked' => "서비스",
'updated_at' => "수정일",
'created_at' => "작성일"
],
"ZONE_UID" => [],
"TYPE" => [
'A' => 'A',
'AAAA' => 'AAAA(ipv6)',
'CNAME' => 'CNAME',
'MX' => 'MX',
'SRV' => 'SRV',
'PTR' => 'PTR',
'SPF' => 'SPF',
'TXT' => 'TXT',
'NS' => 'NS',
'INFO' => 'INFO',
],
"PROXIABLE" => [
"on" => "사용",
"off" => "사용 않함",
],
"FIXED" => [
"on" => "사용",
"off" => "사용 않함",
],
"PROXIED" => [
"on" => "사용",
"off" => "사용 않함",
],
"LOCKED" => [
"on" => "운영중",
"off" => "잠김",
],
];

View File

@ -0,0 +1,38 @@
<?php
return [
'title' => "Zone정보",
'label' => [
'uid' => "번호",
'account_uid' => "계정",
'domain' => "도메인",
'name_servers' => "네임서버",
'original_name_servers' => "이전네임서버",
'plan' => "plan",
'development_mode' => "개발모드",
'ipv6' => "ipv6",
'security_level' => "공격방어",
'status' => "서비스",
'updated_at' => "수정일",
'created_at' => "작성일"
],
"ACCOUNT_UID" => [
],
"DEVELOPMENT_MODE" => [
"on" => "사용",
"off" => "사용않함",
],
"IPV6" => [
"on" => "사용",
"off" => "사용않함",
],
"SECURITY_LEVEL" => [
"under_attack" => "under_attack",
"medium" => "medium",
"low" => "low",
"essentially_off" => "essentially_off"
],
"STATUS" => [
"active" => "active",
"pending" => "pending",
],
];

16
app/Language/Mapurl.php Normal file
View File

@ -0,0 +1,16 @@
<?php
return [
'title' => "URL Mapping 정보",
'label' => [
'uid' => "번호",
'oldurl' => "기존URL",
'newurl' => "신규URL",
'status' => "상태",
'updated_at' => "수정일",
'created_at' => "작성일"
],
"STATUS" => [
"use" => "사용",
"unuse" => "사용않함",
]
];

27
app/Language/User.php Normal file
View File

@ -0,0 +1,27 @@
<?php
return [
'title' => "계정정보",
'label' => [
'uid' => "번호",
'id' => "계정",
'passwd' => "암호",
'confirmpassword' => "암호확인",
'email' => "메일",
'role' => "권한",
'name' => "이름",
'status' => "상태",
'updated_at' => "수정일",
'created_at' => "작성일"
],
"ROLE" => [
"member" => "회원",
"manager" => "관리자",
"cloudflare" => "Cloudflare관리자",
"director" => "감독자",
"master" => "마스터"
],
"STATUS" => [
"use" => "사용",
"unuse" => "사용않함",
]
];

View File

@ -1,119 +0,0 @@
<?php
namespace App\Libraries;
abstract class CloudflareLibrary
{
private static $_requestCount = 1;
private $_parent = null;
protected $_adapter = null;
protected $_model = null;
protected function __construct($parent)
{
$this->_parent = $parent;
$this->setAdapter();
}
abstract public function getClassName();
abstract protected function setAdapter();
abstract protected function createEntity(\stdClass $cfResult);
abstract protected function getCFResults_List(int $page): array;
final protected static function getRequestCount()
{
return self::$_requestCount;
}
protected function setAdapter()
{
if (!is_null($this->_adapter)) {
throw new \Exception("Adapter가 이미 지정되었습니다.");
}
$apikey = new \Cloudflare\API\Auth\APIKey(
$this->getParent()->getAuthId(),
$this->getParent()->getAuthKey()
);
$this->_adapter = new \Cloudflare\API\Adapter\Guzzle($apikey);
// throw new \Exception(var_export($this->_adapter, true));
}
final protected function getAdapter(): \Cloudflare\API\Adapter\Guzzle
{
if (CF_REQUEST_MAX <= self::$_requestCount) {
log_message('warning', sprintf("--Cloudflare API Call %s초 대기 시작--", CF_REQUEST_WAITTIME));
sleep(CF_REQUEST_WAITTIME);
self::$_requestCount = 0;
log_message('warning', sprintf("--Cloudflare API Call %s초 대기 종료--", CF_REQUEST_WAITTIME));
}
self::$_requestCount++;
if (is_null($this->_adapter)) {
throw new \Exception("해당 Adapter가 없습니다.");
}
// throw new \Exception(var_export($this->_adapter, true));
return $this->_adapter;
}
final public function getParent()
{
if (!isset($this->_parent)) {
throw new \Exception(__METHOD__ . "에서 오류발생: ParentEntity가 선언되지 않았습니다.");
}
return $this->_parent;
}
//reload관련
//부모키를 기준으로 CF에 존재하지 않는 데이터 삭제용
final protected function reload_delete(array $entitys)
{
$availableUids = array();
if (count($entitys)) {
foreach ($entitys as $entity) {
array_push($availableUids, $entity->getPrimaryKey());
}
$this->_model->where($this->_model::PARENT_FIELD, $this->getParent()->getPrimaryKey())->whereNotIn('uid', $availableUids)->delete();
} else {
$this->_model->where($this->_model::PARENT_FIELD, $this->getParent()->getPrimaryKey())->delete();
}
}
final protected function reload_entitys(array $cfResults): array
{
$entitys = array();
if (count($cfResults)) {
$cnt = 1;
foreach ($cfResults as $cfResult) {
$entity = $this->getEntityByResult((object)$cfResult);
log_message("debug", "{$cnt}번째: {$entity->getTitle()} 저장");
if (!$this->_model->save($entity)) {
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));
}
array_push($entitys, $entity);
$cnt++;
}
}
return $entitys;
}
final protected function reload_cfResults(int $page_limit = 0)
{
$page = 1; //Page는 1부터 시작해야함
$page_cnt = 1;
$cfResults = array();
do {
$temp_cfResults = $this->getCFResults_List($page);
// throw new \Exception(var_export($temp_cfResults, true));
$page = count($temp_cfResults) < CF_ADAPTER_PERPAGE_MAX ? 0 : $page + 1;
//Loop 갯수제한시
if ($page_limit !== 0 && $page >= $page_limit + 1) {
$page = 0;
}
$cfResults = array_merge($cfResults, $temp_cfResults);
$page_cnt++;
} while (0 < $page);
return $cfResults;
}
final public function reload(int $page_limit = 0): array
{
$cfResults = $this->reload_cfResults($page_limit);
log_message("notice", "-----{$this->getParent()->getTitle()} {$this->getClassName()} cfResult 처리[" . count($cfResults) . "개] 시작-----");
$entitys = $this->reload_entitys($cfResults);
$this->reload_delete($entitys);
log_message("notice", "-----{$this->getParent()->getTitle()} {$this->getClassName()} DB 처리[" . count($entitys) . "개] 완료-----");
return $entitys;
}
}

View File

@ -1,103 +0,0 @@
<?php
namespace App\Libraries\Cloudflare\API\Magictransit;
use App\Entities\Cloudflare\AllowListEntity;
class AllowList extends \App\Libraries\Cloudflare\API\API
{
private $_entity = null;
public function __construct()
{
parent::__construct();
$this->_model = new \App\Models\Cloudflare\Magictransit\AllowListModel();
}
public function setParentAuthEntity($parent_uid): void
{
$parent_entity = $this->getAccountModel()->getEntity($parent_uid);
$this->setParent($parent_entity);
$auth_entity = $this->getAuthModel()->getEntity($parent_entity->getParentFieldData());
$this->setAuth($auth_entity);
}
public function getClassName()
{
return 'AllowList';
}
protected function getEndPoint()
{
return is_null($this->_endPoint) ? "client/v4/accounts/{$this->getParent()->getPrimaryKey()}5/magic/advanced_tcp_protection/configs/allowlist" : $this->_endPoint;
}
public function getEntityByResult(\stdClass $cfResult): AllowListEntity
{
$entity = is_null($this->_entity) ? new AllowListEntity() : $this->_entity;
$entity->uid = $cfResult->id;
$entity->zone_uid = $this->getParent()->getPrimaryKey();
$entity->description = $cfResult->description;
$entity->filter_id = $cfResult->filter->id;
$entity->filter_expression = isset($cfResult->filter->expression) && $cfResult->filter->expression ? $cfResult->filter->expression : ' ';
$entity->filter_paused = isset($cfResult->filter->paused) && $cfResult->filter->paused ? 'on' : 'off';
$entity->action = $cfResult->action;
$entity->paused = $cfResult->paused ? 'off' : 'on';
$entity->updated_at = $cfResult->modified_on;
$entity->created_at = $cfResult->created_on;
// parent::add_logs("notice","host:[{$cfResult->name}<>{$entity->description}] | proxied:[{$cfResult->proxied}<>{$entity->proxied}] | locked:[{$cfResult->locked}<>{$entity->locked}]");
return $entity;
}
// public function insert(){ }
public function update(AllowListEntity $entity, array $fieldDatas): AllowListEntity
{
$this->setParentAuthEntity($entity->getParentFieldData());
$isChanged = false;
foreach ($fieldDatas as $field => $value) {
if ($entity->$field != $value) {
$entity->$field = $value;
$isChanged = true;
}
}
if (!$isChanged) {
return $entity;
}
$rule = array_merge(
[
'id' => $entity->getPrimaryKey(),
'filter' => [
'id' => $entity->filter_id,
'expression' => $entity->filter_expression,
'paused' => isset($entity->filter_paused) && $entity->filter_paused === 'on' ? true : false
]
],
[
'paused' => isset($entity->paused) && $entity->paused === 'on' ? false : true,
'action' => $entity->action
]
);
if (!is_null($entity->description)) {
$rule['description'] = $entity->description;
}
$cfResult = $this->getAdapter()->put('zones/' . $this->getParent()->getPrimaryKey() . '/AllowList/rules/' . $entity->getPrimaryKey(), $rule);
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
return $this->getEntityByResult($cfResult->result);
}
// public function delete(){ }
public function sync(AllowListEntity $entity): AllowListEntity
{
$this->setParentAuthEntity($entity->getParentFieldData());
$cfResult = $this->getAdapter()->get('zones/' . $this->getParent()->getPrimaryKey() . '/AllowList/rules/' . $entity->getPrimaryKey());
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
return $this->getEntityByResult($cfResult->result);
}
protected function getCFResults_List(int $page): array
{
return $this->getEndPoint()->listAllowListRules($this->getParent()->getPrimaryKey(), $page, CF_ADAPTER_PERPAGE_MAX)->result;
}
}

View File

@ -1,127 +0,0 @@
<?php
namespace App\Libraries\Cloudflare\API;
use App\Libraries\Log\Log;
class Record extends API
{
private $_endPoint = null;
private $_entity = null;
public function __construct(\App\Entities\Cloudflare\API\ZoneEntity $parent)
{
parent::__construct($parent);
$this->_model = new \App\Models\Cloudflare\API\RecordModel();
}
final protected function setAdapter()
{
if (!is_null($this->_adapter)) {
throw new \Exception("Adapter가 이미 지정되었습니다.");
}
$accountModel = new \App\Models\Cloudflare\API\AccountModel();
$account = $accountModel->getEntity($this->getParent()->getParentFieldData());
$authModel = new \App\Models\Cloudflare\API\AuthModel();
$auth = $authModel->getEntity($account->getParentFieldData());
$apikey = new \Cloudflare\API\Auth\APIKey($auth->getAuthId(), $auth->getAuthKey());
$this->_adapter = new \Cloudflare\API\Adapter\Guzzle($apikey);
// throw new \Exception(var_export($this->_adapter, true));
}
public function getClassName()
{
return 'Record';
}
protected function getEntityByResult(\stdClass $cfResult): \App\Entities\Cloudflare\API\RecordEntity
{
// throw new \Exception(var_export($cfResult, true));
$entity = is_null($this->_entity) ? new \App\Entities\Cloudflare\API\RecordEntity() : $this->_entity;
// throw new \Exception(var_export($cfResult, true));
$entity->uid = $cfResult->id;
$entity->zone_uid = $cfResult->zone_id;
$entity->host = $cfResult->name;
$entity->type = $cfResult->type;
$entity->content = $cfResult->content;
$entity->ttl = (int) $cfResult->ttl;
$entity->proxiable = $cfResult->proxiable ? "on" : "off";
$entity->proxied = $cfResult->proxied ? "on" : "off";
$entity->locked = "on";
if (isset($cfResult->locked) && $cfResult->locked) {
$entity->locked = "off";
}
// $entity->updated_at = $cfResult->modified_on;
$entity->created_at = $cfResult->created_on;
// throw new \Exception(var_export($cfResult, true));
return $entity;
}
public function insert(array $fieldDatas): \App\Entities\Cloudflare\API\RecordEntity
{
//TTL값은 CDN(proxied)가 사용함일때는 무조건 1, 않함일때는 120이 적용
$options = [
'name' => $fieldDatas['host'],
'type' => $fieldDatas['type'],
'content' => $fieldDatas['content'],
'proxied' => isset($fieldDatas['proxied']) && $fieldDatas['proxied'] === 'on' ? true : false
];
// throw new \Exception(var_export($options, true));
$cfResult = $this->getAdapter()->post('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records', $options);
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
$entity = $this->getEntityByResult($cfResult->result);
Log::add("warning", "Record API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
return $entity;
}
public function update(\App\Entities\Cloudflare\API\RecordEntity $entity, array $fieldDatas): \App\Entities\Cloudflare\API\RecordEntity
{
//TTL값은 CDN(proxied)가 사용함일때는 무조건 1, 않함일때는 120이 적용
$options = [
'type' => isset($fieldDatas['type']) ? $fieldDatas['type'] : $entity->type,
'name' => isset($fieldDatas['host']) ? $fieldDatas['host'] : $entity->host,
'content' => isset($fieldDatas['content']) ? $fieldDatas['content'] : $entity->content,
'proxied' => $entity->proxied == 'on' ? true : false,
'ttl' => intval($entity->ttl)
];
//변경작업: 2024-08-09
if (isset($fieldDatas['proxied']) && $fieldDatas['proxied'] === 'on') {
$options['proxied'] = true;
$options['ttl'] = 1;
} elseif (isset($fieldDatas['proxied']) && $fieldDatas['proxied'] === 'off') {
$options['proxied'] = false;
$options['ttl'] = 120;
}
//dd($options);
// throw new \Exception(var_export($fieldDatas, true) . "<HR>" . var_export($options, true));
$cfResult = $this->getAdapter()->put('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records/' . $entity->getPrimaryKey(), $options);
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
Log::add("warning", "Record API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
return $this->getEntityByResult($cfResult->result);
}
public function delete(\App\Entities\Cloudflare\API\RecordEntity $entity)
{
$cfResult = $this->getAdapter()->delete('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records/' . $entity->getPrimaryKey());
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
Log::add("warning", "Record API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
}
public function sync(\App\Entities\Cloudflare\API\RecordEntity $entity): \App\Entities\Cloudflare\API\RecordEntity
{
$cfResult = $this->getAdapter()->get('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records/' . $entity->getPrimaryKey());
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
Log::add("warning", "Record API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
return $this->getEntityByResult($cfResult->result);
}
protected function getCFResults_List(int $page): array
{
$this->_endPoint = is_null($this->_endPoint) ? new \Cloudflare\API\Endpoints\DNS($this->getAdapter()) : $this->_endPoint;
return $this->_endPoint->listRecords($this->getParent()->getPrimaryKey(), '', '', '', $page, CF_ADAPTER_PERPAGE_MAX)->result;
}
}

View File

@ -1,152 +0,0 @@
<?php
namespace App\Libraries\Cloudflare\API;
use App\Libraries\Log\Log;
class Zone extends API
{
private $_endPoint = null;
private $_entity = null;
private $_isGetSetting = true;
public function __construct(\App\Entities\Cloudflare\API\AccountEntity $parent, bool $isGetSetting = true)
{
parent::__construct($parent);
$this->_isGetSetting = $isGetSetting;
$this->_model = new \App\Models\Cloudflare\API\ZoneModel();
}
final protected function setAdapter()
{
if (!is_null($this->_adapter)) {
throw new \Exception("Adapter가 이미 지정되었습니다.");
}
$authModel = new \App\Models\Cloudflare\API\AuthModel();
$auth = $authModel->getEntity($this->getParent()->getParentFieldData());
$apikey = new \Cloudflare\API\Auth\APIKey($auth->getAuthId(), $auth->getAuthKey());
$this->_adapter = new \Cloudflare\API\Adapter\Guzzle($apikey);
// throw new \Exception(var_export($this->_adapter, true));
}
public function getClassName()
{
return 'Zone';
}
//Cfzone에서 가져온 값을 zone에 setting
protected function getEntityByResult(\stdClass $cfResult): \App\Entities\Cloudflare\API\ZoneEntity
{
$entity = is_null($this->_entity) ? new \App\Entities\Cloudflare\API\ZoneEntity() : $this->_entity;
$entity->uid = $cfResult->id;
$entity->account_uid = $cfResult->account->id;
$entity->domain = $cfResult->name;
$entity->status = $cfResult->status;
//$entity->type = $cfResult->type; // full 이게있는데 뭔지 잘모름
$entity->name_servers = 'none';
if (isset($cfResult->name_servers)) {
$entity->name_servers = is_array($cfResult->name_servers) ?
implode(',', $cfResult->name_servers) : $cfResult->name_servers;
}
$entity->original_name_servers = 'none';
if (isset($cfResult->original_name_servers)) {
$entity->original_name_servers = is_array($cfResult->original_name_servers) ?
implode(',', $cfResult->original_name_servers) : $cfResult->original_name_servers;
}
$entity->updated_at = $cfResult->modified_on;
$entity->created_at = $cfResult->created_on;
$entity->plan = $cfResult->plan->name;
return $this->_isGetSetting ? $this->getCFSetting($entity) : $entity;
}
//Cfzone에서 가져온 값을 zone에 setting
final public function getCFSetting(\App\Entities\Cloudflare\API\ZoneEntity $entity): \App\Entities\Cloudflare\API\ZoneEntity
{
$cfResult = $this->getAdapter()->get('zones/' . $entity->getPrimaryKey() . '/settings/');
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(__FUNCTION__ . "에서 Call Error:\n" . var_export($cfResult, true));
}
foreach ($cfResult->result as $cfResult) {
switch ($cfResult->id) {
case 'development_mode':
$entity->development_mode = $cfResult->value;
break;
case 'ipv6':
$entity->ipv6 = $cfResult->value;
break;
case 'security_level':
$entity->security_level = $cfResult->value;
break;
}
}
return $entity;
}
//Cfzone에 해당 키값 변경용
final public function setCFSetting(\App\Entities\Cloudflare\API\ZoneEntity $entity, string $field, string $value): \App\Entities\Cloudflare\API\ZoneEntity
{
$cfResult = $this->getAdapter()->patch('zones/' . $entity->getPrimaryKey() . '/settings/' . $field, array('value' => $value));
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success || $cfResult->result->id !== $field) {
throw new \Exception(__FUNCTION__ . "에서 {$field}->{$value} 변경오류:\n" . var_export($cfResult, true));
}
//최종 결과값은 body->result->id='필드명',body->result->value='on/off'이런식으로 받음
$entity->$field = $cfResult->result->value;
Log::add("warning", "Zone API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
return $entity;
}
public function insert(array $fieldDatas): \App\Entities\Cloudflare\API\ZoneEntity
{
//도메인생성을 위해 Cloudflare에 전송
$options = [
'accountId' => $this->getParent()->getPrimaryKey(),
'name' => $fieldDatas['domain'],
'jump_start' => false,
];
$cfResult = $this->getAdapter()->post('zones/', $options);
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
$entity = $this->getEntityByResult($cfResult->result);
//아래는 추가 셋팅 ipv6 TurnOFF , //Development mode TurnOFF
$entity = $this->setCFSetting($entity, 'ipv6', 'off');
$entity = $this->setCFSetting($entity, 'development_mode', 'off');
$entity = $this->setCFSetting($entity, 'security_level', 'medium');
Log::add("warning", "Record API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
return $entity;
}
public function update(\App\Entities\Cloudflare\API\ZoneEntity $entity, array $fieldDatas): \App\Entities\Cloudflare\API\ZoneEntity
{
//ipv6 , //development_mode , //security_level
foreach ($fieldDatas as $field => $value) {
$entity = $this->setCFSetting($entity, $field, $value);
}
Log::add("warning", "API {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
return $entity;
}
public function delete(\App\Entities\Cloudflare\API\ZoneEntity $entity)
{
//Zone 삭제
$cfResult = $this->getAdapter()->delete('zones/' . $entity->getPrimaryKey());
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
Log::add("warning", "Zone API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
}
public function sync(\App\Entities\Cloudflare\API\ZoneEntity $entity): \App\Entities\Cloudflare\API\ZoneEntity
{
$cfResult = $this->getAdapter()->get('zones/' . $entity->getPrimaryKey());
$cfResult = json_decode($cfResult->getBody());
if (!$cfResult->success) {
throw new \Exception(var_export($cfResult, true));
}
Log::add("warning", "Zone API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
return $this->getEntityByResult($cfResult->result);
}
protected function getCFResults_List(int $page): array
{
$this->_endPoint = is_null($this->_endPoint) ? new \Cloudflare\API\Endpoints\Zones($this->getAdapter()) : $this->_endPoint;
return $this->_endPoint->listZones('', '', $page, CF_ADAPTER_PERPAGE_MAX)->result;
}
}

View File

@ -33,7 +33,7 @@ class AccountModel extends CommonModel
$rules[$field] = $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}/]";; $rules[$field] = $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; break;
case "type": case "type":
$rules[$field] = "if_exist|trim|string"; $rules[$field] = "if_exist|in_list[standard,enterprise]";
break; break;
default: default:
$rules = parent::getFieldRule($field, $rules); $rules = parent::getFieldRule($field, $rules);
@ -41,6 +41,17 @@ class AccountModel extends CommonModel
} }
return $rules; return $rules;
} }
public function getFormFieldOption(string $field, array $options = []): array
{
switch ($field) {
default:
$this->where('status', DEFAULTS['STATUS']);
$this->orderBy(self::TITLE, 'asc');
$options = parent::getFormFieldOption($field, $options);
break;
}
return $options;
}
public function getEntityByPK(int $uid): null | AccountEntity public function getEntityByPK(int $uid): null | AccountEntity
{ {
$this->where($this->getPKField(), $uid); $this->where($this->getPKField(), $uid);
@ -51,7 +62,6 @@ class AccountModel extends CommonModel
$this->where($this->getTitleField(), $id); $this->where($this->getTitleField(), $id);
return $this->getEntity(); return $this->getEntity();
} }
//create용 //create용
public function create(array $formDatas = []): AccountEntity public function create(array $formDatas = []): AccountEntity
{ {

View File

@ -16,7 +16,7 @@ class RecordModel extends Model
protected $primaryKey = self::PK; protected $primaryKey = self::PK;
protected $useAutoIncrement = false; protected $useAutoIncrement = false;
protected $returnType = RecordEntity::class; //object,array,entity명::class protected $returnType = RecordEntity::class; //object,array,entity명::class
protected $allowedFields = [self::PK, self::PARENT, 'type', self::TITLE, 'content', 'ttl', 'proxiable', 'proxied', 'fixed', 'locked', 'updated_at', 'crated_at']; protected $allowedFields = [self::PK, self::PARENT, self::TITLE, 'type', 'content', 'ttl', 'proxiable', 'proxied', 'fixed', 'locked', 'updated_at', 'crated_at'];
protected $useTimestamps = true; protected $useTimestamps = true;
public function __construct() public function __construct()
@ -35,9 +35,11 @@ class RecordModel extends Model
break; break;
case self::TITLE: case self::TITLE:
case "content": case "content":
case "type":
$rules[$field] = "required|trim|string"; $rules[$field] = "required|trim|string";
break; break;
case "type":
$rules[$field] = "required|in_list[A,AAA,CNAME,MX,NS,PTR,SPF,TXT,SRV,INFO]";
break;
case "ttl": case "ttl":
$rules[$field] = "if_exist|numeric"; $rules[$field] = "if_exist|numeric";
break; break;

View File

@ -130,6 +130,17 @@ abstract class CommonModel extends Model
} }
return $rules; return $rules;
} }
public function getFormFieldOption(string $field, array $options = []): array
{
switch ($field) {
default:
foreach ($this->getEntitys() as $entity) {
$options[$field][$entity->getPK()] = $entity->getTitle();
}
break;
}
return $options;
}
final public function getEntity(): array|object|null final public function getEntity(): array|object|null
{ {
return $this->asObject($this->returnType)->first(); return $this->asObject($this->returnType)->first();
@ -138,7 +149,6 @@ abstract class CommonModel extends Model
{ {
return $this->asObject($this->returnType)->findAll(); return $this->asObject($this->returnType)->findAll();
} }
//create , modify 직전 작업용 작업 //create , modify 직전 작업용 작업
final protected function convertEntityData(string $field, array $formDatas): mixed final protected function convertEntityData(string $field, array $formDatas): mixed
{ {

View File

@ -0,0 +1,50 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<div class="top container-fluid">
<?= form_open(current_url(), array("method" => "get")) ?>
<nav class="nav">
조건검색:<?php foreach ($viewDatas['fieldFilters'] as $field) : ?><?= getFieldFilter_UserHelper($field, $viewDatas[$field], $viewDatas) ?><?php endforeach ?>
</nav>
<?= $this->include('templates/admin/index_head') ?>
<?= form_close() ?>
</div>
<?= form_open(current_url() . '/batchjob', $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<?php foreach ($viewDatas['fields'] as $field) : ?><?= getFieldIndex_Column_UserHelper($field, $viewDatas) ?><?php endforeach ?>
<th>@</th>
</tr>
</thead>
<tbody>
<?php $cnt = 0 ?>
<?php foreach ($viewDatas['entitys'] as $entity) : ?>
<tr id="<?= $entity->getPrimaryKey() ?>" <?= $entity->status != DEFAULTS['STATUS'] ? 'class="table-danger" rowcolor="red"' : 'rowcolor="red"' ?> onClick="indexRowCheckBoxToggle(this)">
<td nowarp>
<?= form_checkbox(["id" => "checkbox_uid_{$entity->getPrimaryKey()}", "name" => "batchjob_uids[]", "value" => $entity->getPrimaryKey(), "class" => "batchjobuids_checkboxs"]); ?>
<?= anchor(current_url() . '/update/' . $entity->getPrimaryKey(), $viewDatas['total_count'] - (($viewDatas['page'] - 1) * $viewDatas['per_page'] + $cnt), ["target" => "_self"]) ?>
</td>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<td><?= getFieldIndex_Row_UserHelper_Admin($field, $entity, $viewDatas) ?></td>
<?php endforeach ?>
<td><?= anchor(current_url() . '/delete/' . $entity->getPrimaryKey(), ICONS['DELETE'], ["class" => "btn btn-sm btn-danger btn-circle", "target" => "_self"]) ?></td>
</tr>
<?php $cnt++ ?>
<?php endforeach ?>
</tbody>
</table>
<div class="bottom">
<ul class="nav justify-content-center">
<li class="nav-item"><?= form_checkbox(array("id" => "batchjobuids_checkbox")) ?>ALL</li>
<?php foreach ($viewDatas['batchjobFilters'] as $field) : ?><?= getFieldFilter_UserHelper($field, DEFAULTS['EMPTY'], $viewDatas) ?><?php endforeach ?>
<li class="nav-item"><?= form_submit('', '일괄처리', array("class" => "btn btn-outline btn-warning")) ?></li>
<li class="nav-item"><?= anchor(current_url() . '/insert', '입력', ["class" => "btn btn-sm btn-primary btn-circle", "target" => "_self"]) ?></li>
</ul>
<?= $viewDatas['pagination'] ?>
</div>
<?= form_close() ?>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,24 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<?= form_open_multipart(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="form table table-bordered table-striped">
<tbody>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= getFieldLabel_UserHelper($field, $viewDatas) ?></td>
<td class="column">
<?= getFieldForm_UserHelper($field, DEFAULTS['EMPTY'], $viewDatas) ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td valign="bottom" colspan="2"><?= form_submit('', '입력', array("class" => "btn btn-outline btn-primary")); ?></td>
</tr>
</tbody>
<?= form_close(); ?>
</table>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,24 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<?= form_open_multipart(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="form table table-bordered table-striped">
<tbody>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= getFieldLabel_UserHelper($field, $viewDatas) ?></td>
<td class="column">
<?= getFieldForm_UserHelper($field, $viewDatas['entity']->$field ?: DEFAULTS['EMPTY'], $viewDatas) ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td valign="bottom" colspan="2"><?= form_submit('', '수정', array("class" => "btn btn-outline btn-primary")); ?></td>
</tr>
</tbody>
<?= form_close(); ?>
</table>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,19 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<table class="form table table-bordered table-striped">
<tbody>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= getFieldLabel_UserHelper($field, $viewDatas) ?></td>
<td class="column">
<?= getFieldView_UserHelper($field, $viewDatas['entity'], $viewDatas) ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,5 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<?= $this->include('templates/admin/header'); ?>
<?= $this->include('templates/admin/footer'); ?>
<?= $this->endSection() ?>

View File

@ -0,0 +1,5 @@
<?php foreach ($cellDatas['entitys'] as $entity) : ?>
<?php foreach (['title', 'created_at'] as $field) : ?>
<div><?= getFieldCell_Row_BoardHelper($field, $entity, $cellDatas) ?></div>
<?php endforeach ?>
<?php endforeach ?>

View File

@ -0,0 +1,5 @@
<?php foreach ($cellDatas['entitys'] as $entity) : ?>
<?php foreach (['title', 'created_at'] as $field) : ?>
<div><?= getFieldCell_Row_BoardHelper($field, $entity, $cellDatas) ?></div>
<?php endforeach ?>
<?php endforeach ?>

View File

@ -0,0 +1,82 @@
<link href="/css/front/device_calculator.css" media="screen" rel="stylesheet" type="text/css" />
<script>
function calculator(order_price = 0) {
var cellDatas = Array.from(document.getElementsByClassName("vhost_cellDatas"));
cellDatas.forEach(function(part) { //loop
//console.log(part);
order_price += parseInt((part.getAttribute('cost') - part.getAttribute('sale')) * part.options[part.selectedIndex].value);
document.getElementById('price').value = order_price;
document.getElementById('order_price').textContent = new Intl.NumberFormat().format(order_price);
});
var current = document.getElementById('paymentday');
if (!current.selectedIndex) {
alert("결제일을 선택해주세요");
current.focus();
return false
}
}
</script>
<div id="device_calculator">
<?= form_open(URLS['addCart'], [
'method' => 'post',
"onsubmit" => 'return calculator()'
]) ?>
<input type="hidden" id="category" name="category" value="device">
<input type="hidden" id="price" name="price">
<table>
<thead>
<tr>
<th scope="col" colspan="3">가상서버 견적 계산기</th>
</tr>
</thead>
<tbody>
<?php foreach ($cellDatas['device']['categorys'] as $category) : ?>
<?php
$options = [];
foreach ($cellDatas['device']['options'][$category] as $entity) {
$options[$entity->getPrimaryKey()] = $entity->getTitleWithPrice();
}
?>
<tr>
<td><?= lang("Device.CATEGORY.{$category}") ?></td>
<td>
<?= form_dropdown(
$category,
$options,
old($category, 0),
[
'id' => $category,
'class' => 'vhost_cellDatas',
'onChange' => "calculator()"
]
) ?>
</td>
</tr>
<?php endforeach ?>
<tr>
<th>결제일</th>
<td class="column">
<?php $paymentDayOptions = ['' => "결제일 선택"];
for ($i = 1; $i <= 28; $i++) {
$paymentDayOptions[$i] = "매월 {$i}";
}
?>
<?= form_dropdown('paymentday', $paymentDayOptions, old('paymentday', 25), ['id' => 'paymentday']);
?>
</td>
</tr>
<tr>
<th class="none">주문금액</th>
<td class="none" colspan="3">
<span id="order_price">0</span>
<?= form_submit('', '신청', array("class" => "btn btn-outline btn-primary")); ?>
</td>
</tr>
</tbody>
</table>
<?= form_close() ?>
<script type="text/javascript">
window.onload = calculator();
</script>
<?= $cellDatas['session']->getFlashdata('return_message') ? alert_CommonHelper($cellDatas['session']->getFlashdata('return_message')) : "" ?>
</div>

View File

@ -0,0 +1,43 @@
<script>
function addDevice(category, key, label) {
var categoryBox = document.getElementById(category + "Box");
var div = document.createElement("div");
var checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
checkbox.setAttribute("name", category + '[]');
checkbox.setAttribute("value", key);
checkbox.setAttribute("checked", true);
checkbox.setAttribute("class", 'device');
div.appendChild(checkbox);
div.appendChild(document.createTextNode(label));
// console.log(div);
categoryBox.appendChild(div);
}
</script>
<table class="table table-bordered" style="width: auto;">
<tr>
<?php foreach ($cellDatas['categorys'] as $category) : ?>
<th style="background-color:silver; text-align:center;"><?= lang('Device.CATEGORY.' . $category) . " 선택" ?></th>
<?php endforeach ?>
</tr>
<tr>
<?php foreach ($cellDatas['categorys'] as $category) : ?>
<td id="<?= $category ?>Box">
<?php foreach ($cellDatas['selecteds'][$category] as $key => $productDevieceEntity) : ?>
<div><input type="checkbox" id="<?= $key ?>" name="<?= $category ?>[]" value="<?= $productDevieceEntity->device_uid ?>" checked class="device"><?= $cellDatas['deviceEntitys'][$productDevieceEntity->device_uid]->getTitle() ?></div>
<?php endforeach ?>
</td>
<?php endforeach ?>
</tr>
<tr>
<?php foreach ($cellDatas['categorys'] as $category) : ?>
<td>
<?php foreach ($cellDatas['device']['options'][$category] as $key => $label) : ?>
<button type="button" class="device btn btn-light" data-bs-toggle="tooltip" data-bs-placement="bottom" title="<?= number_format($cellDatas['deviceEntitys'][$key]->getPrice()) ?>원" onClick="addDevice('<?= $category ?>','<?= $key ?>','<?= $label ?>')">
<?= $label ?>
</button>
<?php endforeach ?>
</td>
<?php endforeach ?>
</tr>
</table>

View File

@ -0,0 +1,30 @@
<div class="modal fade device-virtual" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<table class="table table-bordered" style="width: auto;">
<tr>
<?php foreach ($cellDatas['device']['categorys'] as $category) : ?>
<th style="background-color:silver; text-align:center;"><?= lang('Device.CATEGORY.' . $category) . " 선택" ?></th>
<?php endforeach ?>
</tr>
<tr>
<?php foreach ($cellDatas['device']['categorys'] as $category) : ?>
<td>
<?= form_dropdown(
$category,
$cellDatas['device']['options'][$category],
old($category, 0),
[
'id' => $category,
'size' => "6",
'class' => 'vhost_cellDatas',
'onChange' => "calculator()"
]
) ?>
</td>
<?php endforeach ?>
</tr>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,87 @@
<link href="/css/front/virtual_calculator.css" media="screen" rel="stylesheet" type="text/css" />
<script>
function calculator(order_price) {
var parts = Array.from(document.getElementsByClassName("vhost_parts"));
parts.forEach(function(part) { //loop
//console.log(part);
order_price += parseInt((part.getAttribute('cost') - part.getAttribute('sale')) * part.options[part.selectedIndex].value);
document.getElementById('price').value = order_price;
document.getElementById('order_price').textContent = new Intl.NumberFormat().format(order_price);
});
var current = document.getElementById('paymentday');
if (!current.selectedIndex) {
alert("결제일을 선택해주세요");
current.focus();
return false
}
}
</script>
<div id="virtual_calculator">
<?= form_open(URLS['addCart'], [
'method' => 'post',
"onsubmit" => 'return calculator(' . $cellDatas['parts']['virtual']['default']['baserate'] . ')'
]) ?>
<input type="hidden" id="category" name="category" value="virtual">
<input type="hidden" id="price" name="price">
<table>
<thead>
<tr>
<th scope="col" colspan="3">가상서버 견적 계산기</th>
</tr>
</thead>
<tbody>
<tr>
<th>기본요금</th>
<td>
<strong><?= number_format($cellDatas['parts']['virtual']['default']['baserate']) ?>원</strong>
</td>
</tr>
<?php foreach ($cellDatas['parts']['virtual']['category'] as $category => $attrs) : ?>
<tr>
<th><?= $attrs['label'] ?></th>
<td>
<strong class="line-through"><?= number_format($attrs['cost']) ?>원</strong>
<strong class="f-back">할인가 <?= number_format($attrs['cost'] - $attrs['sale']) ?></strong> *
<?= form_dropdown(
$category,
$attrs['options'],
old($category, 0),
[
'id' => $category,
'class' => 'vhost_parts',
'cost' => $attrs['cost'],
'sale' => $attrs['sale'],
'onChange' => "calculator(" . $cellDatas['parts']['virtual']['default']['baserate'] . ")"
]
) ?>
<?= $attrs['unit'] ?>
</td>
</tr>
<?php endforeach ?>
<tr>
<th>결제일</th>
<td class="column">
<?php $paymentDayOptions = ['' => "결제일 선택"];
for ($i = 1; $i <= 28; $i++) {
$paymentDayOptions[$i] = "매월 {$i}";
}
?>
<?= form_dropdown('paymentday', $paymentDayOptions, old('paymentday', 25), ['id' => 'paymentday']);
?>
</td>
</tr>
<tr>
<th class="none">주문금액</th>
<td class="none" colspan="3">
<span id="order_price">0</span>
<?= form_submit('', '신청', array("class" => "btn btn-outline btn-primary")); ?>
</td>
</tr>
</tbody>
</table>
<?= form_close() ?>
<script type="text/javascript">
window.onload = calculator(<?= $cellDatas['parts']['virtual']['default']['baserate'] ?>);
</script>
<?= $cellDatas['session']->getFlashdata('return_message') ? alert_CommonHelper($cellDatas['session']->getFlashdata('return_message')) : "" ?>
</div>

View File

@ -0,0 +1,24 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<?= form_open_multipart(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="form table table-bordered table-striped">
<tbody>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= lang($this->class_name . '.label.' . $field) ?></td>
<td class="column">
<?= $viewDatas['forminputs'][$field] ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td valign="bottom" colspan="2"><?= form_submit('', '입력', array("class" => "btn btn-outline btn-primary")); ?></td>
</tr>
</tbody>
<?= form_close(); ?>
</table>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,50 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<div class="top container-fluid">
<?= form_open(current_url(), array("method" => "get")) ?>
<nav class="nav">
조건검색:<?php foreach ($viewDatas['fieldFilters'] as $field) : ?><?= getFieldFilter_UserHelper($field, $viewDatas[$field], $viewDatas) ?><?php endforeach ?>
</nav>
<?= $this->include('templates/admin/index_head') ?>
<?= form_close() ?>
</div>
<?= form_open(current_url() . '/batchjob', $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<?php foreach ($viewDatas['fields'] as $field) : ?><?= getFieldIndex_Column_UserHelper($field, $viewDatas) ?><?php endforeach ?>
<th>@</th>
</tr>
</thead>
<tbody>
<?php $cnt = 0 ?>
<?php foreach ($viewDatas['entitys'] as $entity) : ?>
<tr id="<?= $entity->getPrimaryKey() ?>" <?= $entity->status != DEFAULTS['STATUS'] ? 'class="table-danger" rowcolor="red"' : 'rowcolor="red"' ?> onClick="indexRowCheckBoxToggle(this)">
<td nowarp>
<?= form_checkbox(["id" => "checkbox_uid_{$entity->getPrimaryKey()}", "name" => "batchjob_uids[]", "value" => $entity->getPrimaryKey(), "class" => "batchjobuids_checkboxs"]); ?>
<?= anchor(current_url() . '/update/' . $entity->getPrimaryKey(), $viewDatas['total_count'] - (($viewDatas['page'] - 1) * $viewDatas['per_page'] + $cnt), ["target" => "_self"]) ?>
</td>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<td><?= getFieldIndex_Row_UserHelper_Admin($field, $entity, $viewDatas) ?></td>
<?php endforeach ?>
<td><?= anchor(current_url() . '/delete/' . $entity->getPrimaryKey(), ICONS['DELETE'], ["class" => "btn btn-sm btn-danger btn-circle", "target" => "_self"]) ?></td>
</tr>
<?php $cnt++ ?>
<?php endforeach ?>
</tbody>
</table>
<div class="bottom">
<ul class="nav justify-content-center">
<li class="nav-item"><?= form_checkbox(array("id" => "batchjobuids_checkbox")) ?>ALL</li>
<?php foreach ($viewDatas['batchjobFilters'] as $field) : ?><?= getFieldFilter_UserHelper($field, DEFAULTS['EMPTY'], $viewDatas) ?><?php endforeach ?>
<li class="nav-item"><?= form_submit('', '일괄처리', array("class" => "btn btn-outline btn-warning")) ?></li>
<li class="nav-item"><?= anchor(current_url() . '/insert', '입력', ["class" => "btn btn-sm btn-primary btn-circle", "target" => "_self"]) ?></li>
</ul>
<?= $viewDatas['pagination'] ?>
</div>
<?= form_close() ?>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,24 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<?= form_open_multipart(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="form table table-bordered table-striped">
<tbody>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= getFieldLabel_UserHelper($field, $viewDatas) ?></td>
<td class="column">
<?= getFieldForm_UserHelper($field, $viewDatas['entity']->$field ?: DEFAULTS['EMPTY'], $viewDatas) ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td valign="bottom" colspan="2"><?= form_submit('', '수정', array("class" => "btn btn-outline btn-primary")); ?></td>
</tr>
</tbody>
<?= form_close(); ?>
</table>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,19 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<link href="/css/admin/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<table class="form table table-bordered table-striped">
<tbody>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= getFieldLabel_UserHelper($field, $viewDatas) ?></td>
<td class="column">
<?= getFieldView_UserHelper($field, $viewDatas['entity'], $viewDatas) ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,41 @@
<?= $this->extend('layouts/front') ?>
<?= $this->section('content') ?>
<link href="/css/front/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<div><?= html_entity_decode($viewDatas['currentCategory']->head) ?></div>
<div class="top"><?= $this->include('templates/front/index_head') ?></div>
<?= form_open(current_url() . '/batchjob', $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<?php foreach ($viewDatas['fields'] as $field) : ?><?= getFieldIndex_Column_UserHelper($field, $viewDatas) ?><?php endforeach ?>
</tr>
</thead>
<tbody>
<?php $cnt = 0 ?>
<?php foreach ($viewDatas['entitys'] as $entity) : ?>
<tr id="<?= $entity->getPrimaryKey() ?>" <?= $entity->status != DEFAULTS['STATUS'] ? 'class="table-danger" rowcolor="red"' : 'rowcolor="red"' ?> onClick="indexRowCheckBoxToggle(this)">
<td nowrap>
<!-- 사용자가 자신의 작성한것인지 확인되면 update 가능-->
<?php if ($viewDatas[SESSION_NAMES['ISLOGIN']] && $entity->getPrimaryKey() == $viewDatas['auth'][AUTH_FIELDS['ID']]) : ?>
<?= anchor(current_url() . '/update/' . $entity->getPrimaryKey(), $viewDatas['total_count'] - (($viewDatas['page'] - 1) * $viewDatas['per_page'] + $cnt), ["target" => "_self"]) ?>
<?php else : ?>
<?= $viewDatas['total_count'] - (($viewDatas['page'] - 1) * $viewDatas['per_page'] + $cnt) ?>
<?php endif ?>
</td>
<?php foreach ($viewDatas['fields'] as $field) : ?>
<td><?= getFieldIndex_Row_UserHelper($field, $entity, $viewDatas) ?></td>
<?php endforeach ?>
</tr>
<?php $cnt++ ?>
<?php endforeach ?>
</tbody>
</table>
<div class="bottom">
<?= $viewDatas['pagination'] ?>
</div>
<?= form_close() ?>
<div><?= html_entity_decode($viewDatas['currentCategory']->tail) ?></div>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,24 @@
<?= $this->extend('layouts/front') ?>
<?= $this->section('content') ?>
<link href="/css/front/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<div><?= html_entity_decode($viewDatas['currentCategory']->head) ?></div>
<?= form_open_multipart(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="form table table-bordered table-hover table-striped">
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= getFieldLabel_UserHelper($field, $viewDatas) ?></td>
<td class="column">
<?= getFieldForm_UserHelper($field, old($field, DEFAULTS['EMPTY']), $viewDatas) ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td valign="bottom" colspan="2" style="text-align:center;"><?= form_submit('', '회원가입', array("class" => "btn btn-outline btn-primary")); ?></td>
</tr>
</table>
<?= form_close(); ?>
<div><?= html_entity_decode($viewDatas['currentCategory']->tail) ?></div>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,39 @@
<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<link href="/css/front/content.css" media="screen" rel="stylesheet" type="text/css" />
<link href="/css/common/login.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<div class="login container">
<?= form_open(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table style="width:60%; margin-left:80px;">
<tr>
<td class=" label" nowrap>계정</td>
<td class="column">
<?= form_input('id', old('id', DEFAULTS['EMPTY']), ['tabindex' => 0]) ?>
</td>
<td rowspan="2" class="submit">
<?= form_input([
'type' => 'image', 'src' => "/images/common/btn_login.png",
'width' => '57', 'height' => '60', 'tabindex' => 2
]) ?>
</td>
</tr>
<tr>
<td class="label" nowrap>암호</td>
<td class="column">
<?= form_password('passwd', old('passwd', DEFAULTS['EMPTY']), ['tabindex' => 1]) ?>
</td>
</tr>
<tr>
<td colspan="3" class="login_bottom">
<a href="/front/user/insert">회원가입</a>
<?php foreach ($viewDatas['login_buttons'] as $key => $login_button) : ?>
<?= $login_button ?>
<?php endforeach ?>
</td>
</tr>
</table>
<?= form_close(); ?>
</div>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,37 @@
<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<link href="/css/front/content.css" media="screen" rel="stylesheet" type="text/css" />
<link href="/css/common/login_v1.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<div class="login container">
<?= form_open(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<div class="row mb-3">
<div class="label_column col-3">
<label class="col-form-label">아이디</label>
</div>
<div class="col-9">
<?= form_input('id', old('id', DEFAULTS['EMPTY'])) ?>
</div>
</div>
<div class="row mb-3">
<div class="label_column col-3">
<label class="col-form-label">비밀번호</label>
</div>
<div class="col-9">
<?= form_password('passwd', old('passwd', DEFAULTS['EMPTY'])) ?>
</div>
</div>
<div class="row">
<div class="col-12 text-center d-grid">
<?= form_submit('', '로그인', array("class" => "btn btn-outline btn-primary")) ?>
</div>
</div>
<div class="login_bottom row">
<div class="col"><a href="/front/user/insert">회원가입</a></div>
<!-- <div class="col"><a href="/front/user/findid">아이디찾기</a></div>
<div class="col"><a href="/front/user/findpw">비밀번호찾기</a></div> -->
</div>
</div>
<?= form_close(); ?>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,24 @@
<?= $this->extend('layouts/front') ?>
<?= $this->section('content') ?>
<link href="/css/front/content.css" media="screen" rel="stylesheet" type="text/css" />
<div id="content">
<div><?= html_entity_decode($viewDatas['currentCategory']->head) ?></div>
<?= form_open_multipart(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<table class="form table table-bordered table-hover table-striped">
<?php foreach ($viewDatas['fields'] as $field) : ?>
<tr>
<td class="label"><?= getFieldLabel_UserHelper($field, $viewDatas) ?></td>
<td class="column">
<?= getFieldForm_UserHelper($field, old($field, $viewDatas['entity']->$field ?: DEFAULTS['EMPTY']), $viewDatas) ?>
<?= validation_show_error($field); ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td valign="bottom" colspan="2" style="text-align:center;"><?= form_submit('', '수정', array("class" => "btn btn-outline btn-primary")); ?></td>
</tr>
</table>
<?= form_close(); ?>
<div><?= html_entity_decode($viewDatas['currentCategory']->tail) ?></div>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,342 @@
<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<link href="/css/main/content.css" media="screen" rel="stylesheet" type="text/css" />
<div class="main-bnr">
<ul>
<li class="bg1">
<div class="info">
<dl>
<dt>SERVER</dt>
<dd>- 정품HP 서버 사용</dd>
<dd>- 안정적인 RAID 1+0 구성</dd>
<dd>- 365/24 기술문의 가능</dd>
</dl>
</div>
</li>
<li class="bg2">
<div class="info">
<dl>
<dt>NETWORK</dt>
<dd>- 안정적인 기가망 사용</dd>
<dd>- 100% 도전! DDOS 방어</dd>
<dd>- 실시간 트래픽 관제</dd>
</dl>
</div>
</li>
<li class="bg3">
<div class="info">
<dl>
<dt>SERVICE</dt>
<dd>- 365일24시간 고객대응</dd>
<dd>- 친절한 고객 응대</dd>
<dd>- 신속하고 정확한 작업 처리</dd>
</dl>
</div>
</li>
</ul>
</div>
<div class="contain">
<div class="main-title">
<h2>가상서버 안내 사양, 가격정보입니다.</h2>
</div>
<div class="main-table">
<table class="table">
<caption>4core</caption>
<colgroup>
<col width="495px">
</colgroup>
<thead>
<tr class="table-primary">
<th style="text-align:center">지원 서비스 </th>
<th style="text-align:center">문의</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<ul style="list-style-type: circle;">
<li>서비스 방어</li>
<li>DDOS 방어</li>
<li>무료 SSL(Let's Encrypt)</li>
<li>기본 OS Application 설치</li>
<li>내부 사설네트워크 추가</li>
<li>Backup/Restore,Snapshot</li>
<li>공통 가상서버 Template</li>
<li>Online 스펙변경가능</li>
<li>서비스 신청 1시간내 사용가능</li>
<li>OS(x64) : Linux , Windows 지원</li>
</ul>
</td>
<td>
<ul style="list-style-type: circle;">
<li>웹호스팅의 제약으로인해, 단독서버호스팅으로 전환해야 하나,<BR> 비용/관리 부분이 걱정되시는 </li>
<li>장비 구매/임대/유지 비용을 절감하고자 하는, / 규모 서비스</li>
<li>신규 사업 시작시 독자적인 사이트 운영이 필요하신 </li>
<li>사용량이 낮은 단독 서버호스팅 운영비용 절감이 필요하신 </li>
<li>비정기적 이벤트에 따른 일시적/한시적 서버환경이 필요하신 </li>
<li>최신 하드웨어에서 설치 불가한 구버전 운영체제를 이용하실 경우</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<div class="main-price">
<div class="col">
<div class="main-table type2">
<table>
<caption>VPS Basic(HP DL360Gen9)</caption>
<thead>
<tr>
<th scope="col" colspan="2">VPS Basic(HP DL360Gen9)</th>
</tr>
</thead>
<tbody>
<tr>
<th>VCPU</th>
<td>Xeon 4Core</td>
</tr>
<tr>
<th>RAM</th>
<td>8G</td>
</tr>
<tr>
<th>SSD</th>
<td>100G</td>
</tr>
<tr>
<th class="none">기본임대료</th>
<td class="none"><strong class="line-through">15만원</strong> <strong class="f-back">할인가 10만원</strong> <span class="text-gray">(공인IP,회선비 별도)</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col">
<div class="main-table type2">
<table>
<caption>VPS Pro(HP DL360Gen9)</caption>
<thead>
<tr>
<th scope="col" colspan="2">VPS Pro(HP DL360Gen9)</th>
</tr>
</thead>
<tbody>
<tr>
<th>VCPU</th>
<td>Xeon 8Core</td>
</tr>
<tr>
<th>RAM</th>
<td>16G</td>
</tr>
<tr>
<th>SSD</th>
<td>150G</td>
</tr>
<tr>
<th class="none">기본임대료</th>
<td class="none"><strong class="line-through">25만원</strong> <strong class="f-back">할인가 15만원</strong> <span class="text-gray">(공인IP,회선비 별도)</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="main-title">
<h2>단독서버 안내 사양, 가격정보입니다.</h2>
</div>
<div class="main-price">
<div class="col">
<div class="main-table">
<table>
<caption>4core</caption>
<colgroup>
<col width="195px">
<col>
</colgroup>
<thead>
<tr>
<th scope="col" colspan="2">4core</th>
</tr>
</thead>
<tbody>
<tr>
<th>CPU</th>
<td>E5530</td>
</tr>
<tr>
<th>RAM</th>
<td>8G</td>
</tr>
<tr>
<th>HDD</th>
<td>SAS146G*4</td>
</tr>
<tr>
<th class="none">임대료</th>
<td class="none"><strong class="line-through">35만원</strong> <strong class="f-back">할인가 25만원</strong> <span class="text-gray">(회선비 별도)</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col">
<div class="main-table">
<table>
<caption>8core</caption>
<colgroup>
<col width="195px">
<col>
</colgroup>
<thead>
<tr>
<th scope="col" colspan="2">8core</th>
</tr>
</thead>
<tbody>
<tr>
<th>CPU</th>
<td>X5560*2</td>
</tr>
<tr>
<th>RAM</th>
<td>16G</td>
</tr>
<tr>
<th>HDD</th>
<td>SSD128G*2+SATA500G*2</td>
</tr>
<tr>
<th class="none">임대료</th>
<td class="none"><strong class="line-through">45만원</strong> <strong class="f-back">할인가 35만원</strong> <span class="text-gray">(회선비 별도)</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col">
<div class="main-table">
<table>
<caption>12core</caption>
<colgroup>
<col width="195px">
<col>
</colgroup>
<thead>
<tr>
<th scope="col" colspan="2">12core</th>
</tr>
</thead>
<tbody>
<tr>
<th>CPU</th>
<td>X5650*2</td>
</tr>
<tr>
<th>RAM</th>
<td>16G</td>
</tr>
<tr>
<th>HDD</th>
<td>SSD128G*2+SATA500G*2</td>
</tr>
<tr>
<th class="none">임대료</th>
<td class="none"><strong class="line-through">55만원</strong> <strong class="f-back">할인가 45만원</strong> <span class="text-gray">(회선비 별도)</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col type2">
<div class="main-table">
<table>
<caption>20core</caption>
<colgroup>
<col width="195px">
<col>
</colgroup>
<thead>
<tr>
<th scope="col" colspan="2">20core</th>
</tr>
</thead>
<tbody>
<tr>
<th>CPU</th>
<td>E2690v2*2</td>
</tr>
<tr>
<th>RAM</th>
<td>32G</td>
</tr>
<tr>
<th>HDD</th>
<td>SSD128G*2+SATA500G*2</td>
</tr>
<tr>
<th class="none">임대료</th>
<td class="none"><strong class="line-through">65만원</strong> <strong class="f-back">할인가 55만원</strong> <span class="text-gray">(회선비 별도)</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="main-service">
<div class="contain">
<div class="col" style="padding-left:300px;">
<div class="link">
<dl>
<dt>회선 서비스</dt>
<dd>회선서비스 코로케이션 / 단독회선 등이 있습니다.</dd>
</dl>
</div>
</div>
<div class="col">
<div class="link">
<dl>
<dt>기타 서비스</dt>
<dd>방화벽 / 웹방화벽 / 우회망 / 도메인 구매대행이 있습니다.</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="main-notice">
<div class="contain">
<div class="main-bnr2">
<ul>
<li class="bg1">
<div class="info">
<dl>
<dt>고객센터</dt>
<dd><a href="<?= MESSENGERS['skype']['url'] ?>"><?= MESSENGERS['skype']['icon'] ?><?= MALLS['email'] ?></a></dd>
</dl>
</div>
</li>
<li class="bg2">
<div class="info">
<dl>
<dt>자료실</dt>
<dd><?= view_cell('BoardCell::reference', $viewDatas) ?></dd>
</dl>
</div>
</li>
<li class=" bg3">
<div class="info">
<dl>
<dt>공지사항</dt>
<dd><?= view_cell('BoardCell::information', $viewDatas) ?></dd>
</dl>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="bottom"></div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" id="viewport" content="width=1280">
<?php foreach ($viewDatas['layout']['stylesheets'] as $stylesheet) : ?>
<?= $stylesheet ?>
<?php endforeach; ?>
<?php foreach ($viewDatas['layout']['javascripts'] as $javascript) : ?>
<?= $javascript ?>
<?php endforeach; ?>
<link href="/css/admin.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/admin.js"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<title><?= $viewDatas['title'] ?></title>
</head>
<body>
<div id="head">
<?= $this->include($viewDatas['layout']['path'] . '/top_navigator'); ?>
</div>
<div class="container-fluid">
<nav class="nav"></nav>
<nav class="nav justify-content-center">
<table id="layout">
<tr>
<td id="left" valign="top" width="160">
<?= $this->include($viewDatas['layout']['path'] . '/left_menu'); ?>
</td>
<td id="body" valign="top" width="*">
<?= $this->include('templates/admin/header'); ?>
<?= $this->renderSection('content') ?>
<?= $this->include('templates/admin/footer'); ?>
</td>
</tr>
</table>
<nav class="nav justify-content-end"></nav>
</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!-- left menu start -->
<link href="/css/admin/left_menu.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/admin/side_menu.js"></script>
<div id="left_menu" class="shadow-lg rounded">
<div class="accordion accordion-flush">
<?= $this->include($viewDatas['layout']['path'] . '/left_menu/base'); ?>
<?= $this->include($viewDatas['layout']['path'] . '/left_menu/site'); ?>
<?= $this->include($viewDatas['layout']['path'] . '/left_menu/shoppingmall'); ?>
</div>
</div>

View File

@ -0,0 +1,12 @@
<div class="accordion-item" style="background-color: #eaeaea;">
<h2><a href=" /admin"><i class="fa fa-home"></i>Main</a></h2>
</div>
<div class="accordion-item">
<h2><a href="/admin/user"><?= CLASS_ICONS['USER'] ?></i>계정 관리</a></h2>
</div>
<div class="accordion-item">
<h2><a href="/admin/usersns"><?= CLASS_ICONS['USERSNS'] ?></i>SNS 계정 관리</a></h2>
</div>
<div class="accordion-item">
<h2><a href="/admin/category"><?= CLASS_ICONS['CATEGORY'] ?>분류 관리</a></h2>
</div>

View File

@ -0,0 +1,19 @@
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-heading-Shoppingmall" aria-expanded="false" aria-controls="flush-heading-Shoppingmall"><b>상점관리</b></button>
</h2>
<div id="flush-heading-Shoppingmall" class="accordion-collapse collapse show" aria-labelledby="panelsStayOpen-heading-Shoppingmall">
<div class="accordion-item">
<h2><a href="/admin/device"><?= CLASS_ICONS['DEVICE'] ?>장비 관리</a></h2>
</div>
<div class="accordion-item">
<h2><a href="/admin/product"><?= CLASS_ICONS['PRODUCT'] ?>상품 관리</a></h2>
</div>
<div class="accordion-item">
<h2><a href="/admin/order"><?= CLASS_ICONS['ORDER'] ?></i>주문 관리</a></h2>
</div>
<div class="accordion-item">
<h2><a href="/admin/billing"><?= CLASS_ICONS['BILLING'] ?></i>청구서 관리</a></h2>
</div>
</div>
</div>

View File

@ -0,0 +1,13 @@
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-heading-Board" aria-expanded="false" aria-controls="flush-heading-Board"><b>사이트관리</b></button>
</h2>
<div id="flush-heading-Board" class="accordion-collapse collapse show" aria-labelledby="flush-heading-Board">
<div class="accordion-item">
<h2><a href="/admin/board"><?= CLASS_ICONS['BOARD'] ?>게시글 관리</a></h2>
</div>
<div class="accordion-item">
<h2><a href="/admin/sitepage"><?= CLASS_ICONS['SITEPAGE'] ?>SitePage 관리</a></h2>
</div>
</div>
</div>

View File

@ -0,0 +1,4 @@
<div class="input-group custom-search-form" id="mkbutton2" style="width:170px;">
<input type="text" class="form-control" value="<?= getPasswordString_CommonHelper() ?>" id="makePassword">
<span class="input-group-btn" id="mkbutton"><button class="btn btn-default" type="button" id="totSearchBtn" onClick="window.location.reload();"><i class="fa fa-search"></i></button></span>
</div>

View File

@ -0,0 +1,20 @@
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: #e3f2fd;">
<div id="head" class="container-fluid">
<nav class="nav">
<a class="navbar-brand" href="#">관리페이지</a>
</nav>
<ul class="nav justify-content-center">
<li class="nav-item">
<?= $this->include($viewDatas['layout']['path'] . '/top_navigator/make_password'); ?>
</li>
<li class="nav-item">
<?= $this->include($viewDatas['layout']['path'] . '/top_navigator/search'); ?>
</li>
</ul>
<ul class="nav justify-content-end">
<li class="nav-item">
<?= $this->include($viewDatas['layout']['path'] . '/top_navigator/member_link'); ?>
</li>
</ul>
</div>
</nav>

View File

@ -0,0 +1,5 @@
<ul class="navbar-nav me-auto my-2 my-lg-0 navbar-nav-scroll" style="--bs-scroll-height: 100px;">
<li class="nav-item"><?= ICONS['LOCK'] ?></li>
<li class="nav-item"><input type="text" class="form-control" value="<?= getPasswordString_CommonHelper() ?>" id="makePassword"></li>
<li class="nav-item"><button class="btn btn-default border border-dark" type="button" id="totSearchBtn" onClick="window.location.reload();"><?= ICONS['SEARCH'] ?></button></li>
</ul>

View File

@ -0,0 +1,14 @@
<li class="nav-item dropdown">
<?php if ($viewDatas[SESSION_NAMES['ISLOGIN']]) : ?>
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<?= ICONS['LOGIN'] ?><?= $viewDatas['session']->get(SESSION_NAMES['AUTH'])[AUTH_FIELDS['TITLE']] ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="/front/user/update/<?= $viewDatas['session']->get(SESSION_NAMES['AUTH'])[AUTH_FIELDS['ID']] ?>"><?= ICONS['SETUP'] ?>수정</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="<?= URLS['LOGOUT'] ?>"><?= ICONS['LOGOUT'] ?>Logout</a></li>
</ul>
<?php else : ?><a class="nav-link dropdown-toggle" href="<?= URLS['LOGIN'] ?>" role="button"><?= ICONS['LOGIN'] ?>Login</a><?php endif ?>
</li>

View File

@ -0,0 +1,4 @@
<form class="d-flex me-20" role="search">
<input class="form-control" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>

View File

@ -0,0 +1,44 @@
<!-- Copyright 시작-->
<link href="/css/common/copyright.css" media="screen" rel="stylesheet" type="text/css" />
<div id="copyright" class="container-fluid">
<nav class="nav">&nbsp;</nav>
<nav class="nav justify-content-center">
<div>
<div style="padding: 10px; margin: 10px;">
<ul class=" nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="companyinfo-tab" data-bs-toggle="tab" data-bs-target="#companyinfo" type="button" role="tab" aria-controls="companyinfo" aria-selected="true">
회사소개</button>
</li>
<!-- <li class="nav-item" role="presentation">
<button class="nav-link" id="usageterms-tab" data-bs-toggle="tab" data-bs-target="#usageterms" type="button" role="tab" aria-controls="usageterms" aria-selected="false">
이용약관</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="privacyhandling-tab" data-bs-toggle="tab" data-bs-target="#privacyhandling" type="button" role="tab" aria-controls="privacyhandling" aria-selected="false">
개인정보취급방침</button>
</li> -->
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="companyinfo" role="tabpanel" aria-labelledby="companyinfo-tab" style="height:150px; text-align:left;">
항상 빠르고 안전하고 저렴한 가격으로 고객님을 대신해서 구매대행을 진행할 있도록 하겠습니다.<BR>
언제나 믿고 신뢰할 있는 르호봇이 되도록 노력하겠습니다.<BR>
감사합니다.<BR>
</div>
<div class=" tab-pane fade" id="usageterms" role="tabpanel" aria-labelledby="usageterms-tab" style="height:150px; text-align:left;">
이용약관
</div>
<div class="tab-pane fade" id="privacyhandling" role="tabpanel" aria-labelledby="privacyhandling-tab" style="height:150px; text-align:left;">
개인정보취급방침
</div>
</div>
</div>
<div class="address">
<a href="<?= MESSENGERS['skype']['url'] ?>"><?= MESSENGERS['skype']['icon'] ?><?= MALLS['email'] ?></a><BR>
Copyright(c) <?= MALLS['host_name'] ?> All Right Reserved.
</div>
</div>
</nav>
<nav class="nav justify-content-end"></nav>
</div>
<!-- Copyright -->

View File

@ -0,0 +1,34 @@
<!doctype html>
<html>
<head>
<base href="/" target="_self" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<?php foreach ($viewDatas['layout']['stylesheets'] as $stylesheet) : ?>
<?= $stylesheet ?>
<?php endforeach ?>
<?php foreach ($viewDatas['layout']['javascripts'] as $javascript) : ?>
<?= $javascript ?>
<?php endforeach ?>
<link href="/css/empty.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/empty.js"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<title><?= $viewDatas['title'] ?></title>
</head>
<body>
<div id="body">
<?= $this->include('templates/empty/header'); ?>
<?= $this->renderSection('content') ?>
<?= $this->include('templates/empty/footer'); ?>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<?php foreach ($viewDatas['layout']['metas'] as $meta) : ?><?= $meta ?><?php endforeach; ?>
<?php foreach ($viewDatas['layout']['stylesheets'] as $stylesheet) : ?><?= $stylesheet ?><?php endforeach; ?>
<?php foreach ($viewDatas['layout']['javascripts'] as $javascript) : ?><?= $javascript ?><?php endforeach; ?>
<link href="/css/front.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/front.js"></script>
<title><?= $viewDatas['title'] ?></title>
</head>
<body>
<div id="head">
<?= $this->include($viewDatas['layout']['path'] . '/top_navigator'); ?>
<?= $this->include($viewDatas['layout']['path'] . '/top_menu'); ?>
<?= TOP_BANNER[array_key_exists('currentCategory', $viewDatas) ? $viewDatas['currentCategory']->parent : 'default'] ?>
</div>
<div class="container-fluid">
<nav class="nav"></nav>
<nav class="nav justify-content-center">
<table id="layout">
<tr>
<td id="left" valign="top" width="200">
<?= $this->include($viewDatas['layout']['path'] . '/left_menu'); ?>
</td>
<td id="body" valign="top" width="*">
<?= $this->include('templates/front/header'); ?>
<?= $this->renderSection('content') ?>
<?= $this->include('templates/front/footer'); ?>
</td>
</tr>
</table>
<nav class="nav justify-content-end"></nav>
</div>
<nav id="tail" class="navbar navbar-expand-lg" style="background-color:white">
<?= $this->include($viewDatas['layout']['path'] . '/../common/copyright'); ?>
</nav>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!-- left menu start -->
<link href="/css/common/left_menu.css" media="screen" rel="stylesheet" type="text/css" />
<div id="left_menu">
<div class="parent">
<div>-</div>
<div class="title"><?= $viewDatas['menus'][$viewDatas['currentCategory']->parent]['entity']->getTitle() ?></div>
</div>
<?php foreach ($viewDatas['menus'][$viewDatas['currentCategory']->parent]['childs'] as $child) : ?>
<div class="sibling <?= $child->getPrimaryKey() == $viewDatas['category'] ? "active" : "" ?>">
<a href="<?= $child->linkurl ?>?category=<?= $child->getPrimaryKey() ?>" target="_self"><?= $child->getTitle() ?></a><span class="play"><i class="bi bi-play-fill"></i></span>
</div>
<?php endforeach ?>
</div>
<!-- left menu end -->

View File

@ -0,0 +1,37 @@
<link href="/css/common/top_menu.css" media="screen" rel="stylesheet" type="text/css" />
<nav class="navbar navbar-expand-lg">
<div class="container-fluid">
<nav class="nav"></nav>
<nav class="nav justify-content-center">
<nav id="top_menu" class="navbar navbar-expand-lg">
<div class="container-fluid">
<nav class="nav"><a class="navbar-brand" href="/"><?= ICONS['HOME'] ?></a></nav>
<nav class="nav justify-content-center"></nav>
<ul class="nav justify-content-end">
<li class="nav-item" style="padding-top:10px;">|</li>
<?php foreach ($viewDatas['layout']['topmenus'] as $topmenus_key) : ?>
<li class="nav-item">
<div class="dropdown-center">
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link" id="navbarDarkDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<?= $viewDatas['menus'][$topmenus_key]['entity']->getTitle() ?>
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDarkDropdownMenuLink">
<?php foreach ($viewDatas['menus'][$topmenus_key]['childs'] as $child) : ?>
<li class="<?= $child->getPrimaryKey() == $viewDatas['category'] ? "active" : "" ?>"><a class=" dropdown-item" href="<?= $child->linkurl ?>?category=<?= $child->getPrimaryKey() ?>"><?= $child->getTitle() ?></a></li>
<?php endforeach ?>
</ul>
</li>
</ul>
</div>
</li>
<li class="nav-item" style="padding-top:10px;">|</li>
<?php endforeach ?>
</ul>
</div>
</nav>
</nav>
<nav class="nav justify-content-end"></nav>
</div>
</nav>

View File

@ -0,0 +1,42 @@
<link href="/css/common/top_navigator.css" media="screen" rel="stylesheet" type="text/css" />
<nav id="top_navigator" class="navbar navbar-expand-lg">
<div class="container-fluid">
<nav class="nav">
<span style="float:left;"><?= ICONS['LOGO'] ?></span>
</nav>
<ul class="nav justify-content-center">
<li class="nav-item">
<a href="<?= MESSENGERS['skype']['url'] ?>"><?= MESSENGERS['skype']['icon'] ?></a>&nbsp;
<a href="<?= MESSENGERS['discord']['url'] ?>"><?= MESSENGERS['discord']['icon'] ?></a>&nbsp;
<a href="<?= MESSENGERS['telegram']['url'] ?>"><?= MESSENGERS['telegram']['icon'] ?></a>&nbsp;
<a href="<?= MESSENGERS['kakaotalk']['url'] ?>"><?= MESSENGERS['kakaotalk']['icon'] ?></a>
<!-- <form class="d-flex me-20" role="search">
<input class="form-control" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form> -->
</li>
</ul>
<ul class="nav justify-content-end">
<li class="cart nav-item">
<?= anchor('/front/order', ICONS['CART'], ["target" => "_self"]); ?>
</li>
<li class="nav-item">
<li class="nav-item dropdown">
<?php if ($viewDatas[SESSION_NAMES['ISLOGIN']]) : ?>
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<?= ICONS['LOGIN'] ?><?= $viewDatas['session']->get(SESSION_NAMES['AUTH'])[AUTH_FIELDS['TITLE']] ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="/front/user/update/<?= $viewDatas['session']->get(SESSION_NAMES['AUTH'])[AUTH_FIELDS['ID']]
?>"><?= ICONS['SETUP'] ?>수정</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="<?= URLS['LOGOUT'] ?>"><?= ICONS['LOGOUT'] ?>Logout</a></li>
</ul>
<?php else : ?><a class="nav-link dropdown-toggle" href="<?= URLS['LOGIN'] ?>" role="button"><?= ICONS['LOGIN'] ?>Login</a><?php endif ?>
</li>
</li>
</ul>
</div>
</nav>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" id="viewport" content="width=1280">
<meta name="subject" content="IT Solution">
<meta name="description" content="일본IDC 일본서버 일본 서버 일본호스팅 서버호스팅 디도스 공격 해외 호스팅 DDOS 방어 ddos 의뢰 디도스 보안 일본 단독서버">
<meta name="keywords" content="일본IDC 일본서버 일본 서버 일본호스팅 서버호스팅 디도스 공격 해외 호스팅 DDOS 방어 ddos 의뢰 디도스 보안 일본 단독서버">
<meta property="og:type" content="website">
<meta property="og:title" content="IT Solution">
<meta property="og:description" content="일본IDC 일본서버 일본 서버 일본호스팅 서버호스팅 디도스 공격 해외 호스팅 DDOS 방어 ddos 의뢰 디도스 보안 일본 단독서버">
<?php foreach ($viewDatas['layout']['stylesheets'] as $stylesheet) : ?>
<?= $stylesheet ?>
<?php endforeach; ?>
<?php foreach ($viewDatas['layout']['javascripts'] as $javascript) : ?>
<?= $javascript ?>
<?php endforeach; ?>
<link href="/css/front.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/front.js"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<title><?= $viewDatas['title'] ?></title>
</head>
<body>
<div id="head">
<?= $this->include($viewDatas['layout']['path'] . '/top_navigator'); ?>
<?= $this->include($viewDatas['layout']['path'] . '/top_menu'); ?>
</div>
<div class="container-fluid">
<nav class="nav"></nav>
<nav class="nav justify-content-center">
<?= $this->renderSection('content') ?>
</nav>
<nav class="nav justify-content-end"></nav>
</div>
<nav id="tail" class="navbar navbar-expand-lg" style="background-color:white">
<?= $this->include($viewDatas['layout']['path'] . '/../common/copyright'); ?>
</nav>
</body>
</html>

View File

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" id="viewport" content="width=1280">
<meta name="subject" content="IT Solution">
<meta name="description" content="일본IDC 일본서버 일본 서버 일본호스팅 서버호스팅 디도스 공격 해외 호스팅 DDOS 방어 ddos 의뢰 디도스 보안 일본 단독서버">
<meta name="keywords" content="일본IDC 일본서버 일본 서버 일본호스팅 서버호스팅 디도스 공격 해외 호스팅 DDOS 방어 ddos 의뢰 디도스 보안 일본 단독서버">
<meta property="og:type" content="website">
<meta property="og:title" content="IT Solution">
<meta property="og:description" content="일본IDC 일본서버 일본 서버 일본호스팅 서버호스팅 디도스 공격 해외 호스팅 DDOS 방어 ddos 의뢰 디도스 보안 일본 단독서버">
<?php foreach ($viewDatas['layout']['stylesheets'] as $stylesheet) : ?>
<?= $stylesheet ?>
<?php endforeach; ?>
<?php foreach ($viewDatas['layout']['javascripts'] as $javascript) : ?>
<?= $javascript ?>
<?php endforeach; ?>
<link href="/css/main.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/main.js"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<title><?= $viewDatas['title'] ?></title>
</head>
<body>
<div id="head">
<?= $this->include($viewDatas['layout']['path'] . '/top_navigator'); ?>
<?= $this->include($viewDatas['layout']['path'] . '/top_menu'); ?>
</div>
<div id="carouselExampleAutoplaying" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="/images/main/visual1.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="/images/main/visual2.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="/images/main/visual3.jpg" class="d-block w-100" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
<div class="container-fluid">
<nav class="nav"></nav>
<nav class="nav justify-content-center">
<?= $this->renderSection('content') ?>
</nav>
<nav class="nav justify-content-end"></nav>
</div>
<nav id="tail" class="navbar navbar-expand-lg" style="background-color:white">
<?= $this->include($viewDatas['layout']['path'] . '/../common/copyright'); ?>
</nav>
</body>
</html>

View File

@ -0,0 +1,34 @@
<?php
/**
* bs_full.php - - Bootstrap 4.5.2 Pager Template.
* @var \CodeIgniter\Pager\PagerRenderer $pager
*/
$pager->setSurroundCount(2);
?>
<nav aria-label="<?= lang('Pager.pageNavigation') ?>">
<ul class="pagination justify-content-center">
<?php if ($pager->hasPreviousPage()) : ?>
<li class="page-item">
<a class="page-link" href="<?= $pager->getFirst() ?>" aria-label="<?= lang('Pager.first') ?>"><?= lang('Pager.first') ?></a>
</li>
<li class="page-item">
<a class="page-link" href="<?= $pager->getPreviousPage() ?>" aria-label="<?= lang('Pager.previous') ?>"><?= lang('Pager.previous') ?></a>
</li>
<?php endif ?>
<?php foreach ($pager->links() as $link) : ?>
<li <?= $link['active'] ? 'class="page-item active"' : '' ?>>
<a class="page-link" href="<?= $link['uri'] ?>"><?= $link['title'] ?></a>
</li>
<?php endforeach ?>
<?php if ($pager->hasNextPage()) : ?>
<li class="page-item">
<a class="page-link" href="<?= $pager->getNextPage() ?>" aria-label="<?= lang('Pager.next') ?>"><?= lang('Pager.next') ?></a>
</li>
<li class="page-item">
<a class="page-link" href="<?= $pager->getLast() ?>" aria-label="<?= lang('Pager.last') ?>"><?= lang('Pager.last') ?></a>
</li>
<?php endif ?>
</ul>
</nav>

View File

@ -0,0 +1,17 @@
<?php
/**
* bs_simple - Bootstrap 4.5.2 Pager Template.
* @var \CodeIgniter\Pager\PagerRenderer $pager
*/
$pager->setSurroundCount(0);
?>
<nav aria-label="<?= lang('Pager.pageNavigation') ?>">
<ul class="pagination justify-content-center">
<li <?= $pager->hasPrevious() ? 'class="page-item active"' : 'class="page-item disabled"' ?>>
<a class="page-link" href="<?= $pager->getPrevious() ?? '#' ?>" aria-label="<?= lang('Pager.previous') ?>"><?= lang('Pager.newer') ?></a>
</li>
<li <?= $pager->hasNext() ? 'class="page-item active"' : 'class="page-item disabled"' ?>>
<a class="page-link" href="<?= $pager->getnext() ?? '#' ?>" aria-label="<?= lang('Pager.next') ?>"><?= lang('Pager.older') ?></a>
</li>
</ul>
</nav>

View File

@ -0,0 +1,64 @@
<div class="footer"></div>
<?= $viewDatas['session']->getFlashdata('return_message') ? alert_CommonHelper($viewDatas['session']->getFlashdata('return_message')) : "" ?>
<script type="text/javascript">
$(document).ready(function() {
//class가 calender인 inputbox용,날짜field용
$(".calender").datepicker({
changeYear: true,
changeMonth: true,
yearRange: "-10:+0",
dateFormat: "yy-mm-dd"
});
//id가 batchjobuids_checkbox인 버튼을 클릭시 class가 batchjobuids_checkboxs인 checkbox용
$('#batchjobuids_checkbox').click(function(event) {
if (this.checked) {
$('.batchjobuids_checkboxs').each(function() { //loop checkbox
$(this).prop('checked', true); //check
});
} else {
$('.batchjobuids_checkboxs').each(function() { //loop checkbox
$(this).prop('checked', false); //uncheck
});
}
});
//class가 select-field인 SelectBox용
$(".select-field").select2({
theme: "classic",
width: 'style'
});
// text editor 초기화
//참고: https://phppot.com/menu/php/learn-php/
// class가 editor인 textarea용
tinymce.init({
selector: 'textarea.editor',
plugins: ['code', 'image', 'preview', 'table', 'emoticons', 'autoresize'],
height: 600,
// content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
automatic_uploads: false,
images_upload_url: '/tinymce_upload.php',
// images_upload_base_path: '/upload_images',
images_upload_handler: function(blobInfo, success, failure) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '/tinymce_upload.php');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.file_path != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.file_path);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
},
});
});
</script>

View File

@ -0,0 +1,9 @@
<nav class="header navbar navbar-expand-lg">
<div class="container-fluid">
<nav class="nav">
<h4><?= $viewDatas['class_icon'] ?></i><?= $viewDatas['title'] ?></h4>
</nav>
<nav class="nav justify-content-center"></nav>
<nav class="nav justify-content-end"></nav>
</div>
</nav>

View File

@ -0,0 +1,12 @@
<nav class="nav justify-content-end">
검색어:<?= form_input('word', $viewDatas['word']) ?>
검색일:<?= form_input('start', $viewDatas['start'], ["class" => "calender"]) ?><?= form_input('end', $viewDatas['end'], ["class" => "calender"]) ?>
<?= form_submit('', '검색하기') ?>
<?= anchor(current_url() . '/excel?' . $viewDatas['uri']->getQuery(), ICONS['EXCEL'], ["target" => "_self"]) ?>
</nav>
<nav class="nav justify-content-end">
<span class="pageinfo">
페이지정보 : <?= $viewDatas['page'] ?>/<?= $viewDatas['total_page'] ?>
<?= form_dropdown('per_page', $viewDatas['pageOptions'], $viewDatas['per_page'], array('onChange' => 'this.form.submit()')) ?> / 총:<?= $viewDatas['total_count'] ?>
</span>
</nav>

View File

@ -0,0 +1,2 @@
<div class="footer"></div>
<?= $viewDatas['session']->getFlashdata('return_message') ? alert_CommonHelper($viewDatas['session']->getFlashdata('return_message')) : "" ?>

View File

@ -0,0 +1 @@
<div class="header"></div>

View File

@ -0,0 +1,35 @@
<div class="footer"></div>
<?= $viewDatas['session']->getFlashdata('return_message') ? alert_CommonHelper($viewDatas['session']->getFlashdata('return_message')) : "" ?>
<script type="text/javascript">
$(document).ready(function() {
//class가 calender인 inputbox용,날짜field용
$(".calender").datepicker({
changeYear: true,
changeMonth: true,
yearRange: "-10:+0",
dateFormat: "yy-mm-dd"
});
//id가 batchjobuids_checkbox인 버튼을 클릭시 class가 batchjobuids_checkboxs인 checkbox용
$('#batchjobuids_checkbox').click(function(event) {
if (this.checked) {
$('.batchjobuids_checkboxs').each(function() { //loop checkbox
$(this).prop('checked', true); //check
});
} else {
$('.batchjobuids_checkboxs').each(function() { //loop checkbox
$(this).prop('checked', false); //uncheck
});
}
});
//class가 select-field인 SelectBox용
$(".select-field").select2({
theme: "bootstrap-5",
});
//class가 editor인 textarea용
tinymce.init({
selector: '.editor',
theme: 'silver',
height: 500
});
});
</script>

View File

@ -0,0 +1,11 @@
<nav class="header navbar navbar-expand-lg">
<div class="container-fluid">
<nav class="nav">
<h4 class="title"><?= $viewDatas['class_icon'] ?><?= $viewDatas['currentCategory']->getTitle() ?></h4>
</nav>
<nav class="nav justify-content-center"></nav>
<nav class="nav justify-content-end">
<span class="flow"><?= ICONS['HOME'] ?> > <?= $viewDatas['menus'][$viewDatas['currentCategory']->parent]['entity']->getTitle() ?> > <?= $viewDatas['currentCategory']->getTitle() ?></span>
</nav>
</div>
</nav>

View File

@ -0,0 +1,14 @@
<nav class="navbar navbar-expand-lg">
<div class="container-fluid">
<nav class="nav">
<span class="pageinfo">페이지정보 : <?= $viewDatas['page'] ?>/<?= $viewDatas['total_page'] ?></span>
</nav>
<nav class="nav justify-content-center"></nav>
<nav class="nav justify-content-end">
<?= form_open(current_url(), array("method" => "get")) ?>
<?= form_input('word', $viewDatas['word']) ?>
<?= form_submit('', '검색하기') ?>
<?= form_close() ?>
</nav>
</div>
</nav>