diff --git a/.gitignore b/.gitignore
index a6404be..eb8750e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,4 +42,4 @@ composer.lock
.env
test.php
writeable/logs/*
-writeable/session/*
\ No newline at end of file
+writeable/sessions/*
\ No newline at end of file
diff --git a/extdbms/.htaccess b/extdbms/.htaccess
new file mode 100644
index 0000000..f47adc9
--- /dev/null
+++ b/extdbms/.htaccess
@@ -0,0 +1,49 @@
+# Disable directory browsing
+Options -Indexes
+
+# ----------------------------------------------------------------------
+# Rewrite engine
+# ----------------------------------------------------------------------
+
+# Turning on the rewrite engine is necessary for the following rules and features.
+# FollowSymLinks must be enabled for this to work.
+
+ Options +FollowSymlinks
+ RewriteEngine On
+
+ # If you installed CodeIgniter in a subfolder, you will need to
+ # change the following line to match the subfolder you need.
+ # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
+ # RewriteBase /
+
+ # Redirect Trailing Slashes...
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_URI} (.+)/$
+ RewriteRule ^ %1 [L,R=301]
+
+ # Rewrite "www.example.com -> example.com"
+ RewriteCond %{HTTPS} !=on
+ RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
+ RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
+
+ # Checks to see if the user is attempting to access a valid file,
+ # such as an image or css document, if this isn't true it sends the
+ # request to the front controller, index.php
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]
+
+ # Ensure Authorization header is passed along
+ RewriteCond %{HTTP:Authorization} .
+ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+
+
+
+ # If we don't have mod_rewrite installed, all 404's
+ # can be sent to index.php, and everything works as normal.
+ ErrorDocument 404 index.php
+
+
+# Disable server signature start
+ServerSignature Off
+# Disable server signature end
\ No newline at end of file
diff --git a/extdbms/cli.php b/extdbms/cli.php
new file mode 100644
index 0000000..adfc8ff
--- /dev/null
+++ b/extdbms/cli.php
@@ -0,0 +1,21 @@
+=8.2"
+ },
+ "autoload": {
+ "psr-4": {
+ "lib\\": "lib/"
+ }
+ }
+}
\ No newline at end of file
diff --git a/extdbms/index.html b/extdbms/index.html
new file mode 100644
index 0000000..699efb7
--- /dev/null
+++ b/extdbms/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extdbms/lib/Configs/App.php b/extdbms/lib/Configs/App.php
new file mode 100644
index 0000000..6e72e46
--- /dev/null
+++ b/extdbms/lib/Configs/App.php
@@ -0,0 +1,121 @@
+load();
+
+ // 환경 변수 설정
+ //Application 관련
+ define('APP_ENV', $_ENV['APP_ENV'] ?? 'production');
+ define('APP_URL', $_ENV['APP_URL'] ?? 'http://localhost');
+ define('APP_NAME', $_ENV['APP_NAME'] ?? 'MyApp');
+ define('APP_VERSION', $_ENV['APP_VERSION'] ?? '1.0.0');
+ define('APP_TIMEZONE', $_ENV['APP_TIMEZONE'] ?? 'Asia/Seoul');
+ define('APP_LOCALE', $_ENV['APP_LOCALE'] ?? 'en');
+ define('APP_CHARSET', $_ENV['APP_CHARSET'] ?? 'UTF-8');
+
+ //디버그관련련
+ //APP_DEBUG는 true로 설정하면 디버그 모드로 작동합니다.
+ define('APP_DEBUG', $_ENV['APP_DEBUG'] ?? false);
+ define('APP_DEBUG_LEVEL', $_ENV['APP_DEBUG_LEVEL'] ?? 'error');
+
+ //Session 관련
+ define('APP_SESSION_DRIVER', $_ENV['APP_SESSION_DRIVER'] ?? 'file');
+ define('APP_SESSION_NAME', $_ENV['APP_SESSION_NAME'] ?? 'PHPSESSID');
+ define('APP_SESSION_LIFETIME', $_ENV['APP_SESSION_LIFETIME'] ?? 120);
+ define('APP_SESSION_PATH', $_ENV['APP_SESSION_PATH'] ?? ROOT_PATH . '/writeable/sessions');
+ define('APP_SESSION_PERMISSION', $_ENV['APP_SESSION_PERMISSION'] ?? 0775);
+
+ //Cookie 관련
+ define('APP_SESSION_COOKIE_PATH', $_ENV['APP_SESSION_COOKIE_PATH'] ?? '/');
+ define('APP_SESSION_COOKIE_EXPIRE', $_ENV['APP_SESSION_COOKIE_EXPIRE'] ?? 3600);
+ define('APP_SESSION_COOKIE_DOMAIN', $_ENV['APP_SESSION_COOKIE_DOMAIN'] ?? null);
+ define('APP_SESSION_COOKIE_SECURE', $_ENV['APP_SESSION_COOKIE_SECURE'] ?? false);
+ define('APP_SESSION_COOKIE_HTTPONLY', $_ENV['APP_SESSION_COOKIE_HTTPONLY'] ?? true);
+ define('APP_SESSION_USE_ONLY_COOKIES', $_ENV['APP_SESSION_USE_ONLY_COOKIES'] ?? true);
+ define('APP_SESSION_USE_STRICT_MODE', $_ENV['APP_SESSION_USE_STRICT_MODE'] ?? true);
+ define('APP_SESSION_USE_UNIQUE_ID', $_ENV['APP_SESSION_USE_UNIQUE_ID'] ?? false);
+ define('APP_SESSION_USE_FLASH', $_ENV['APP_SESSION_USE_FLASH'] ?? true);
+ define('APP_SESSION_USE_INPUT', $_ENV['APP_SESSION_USE_INPUT'] ?? true);
+
+ //CSRF 관련
+ define('APP_SESSION_USE_CSRF', $_ENV['APP_SESSION_USE_CSRF'] ?? true);
+ define('APP_SESSION_USE_CSRF_TOKEN', $_ENV['APP_SESSION_USE_CSRF_TOKEN'] ?? true);
+ define('APP_SESSION_USE_CSRF_NAME', $_ENV['APP_SESSION_USE_CSRF_NAME'] ?? 'csrf_token');
+ define('APP_SESSION_USE_CSRF_EXPIRE', $_ENV['APP_SESSION_USE_CSRF_EXPIRE'] ?? 3600);
+ define('APP_SESSION_USE_CSRF_EXCLUDE', $_ENV['APP_SESSION_USE_CSRF_EXCLUDE'] ?? []);
+ define('APP_SESSION_USE_CSRF_EXCLUDE_METHOD', $_ENV['APP_SESSION_USE_CSRF_EXCLUDE_METHOD'] ?? ['GET', 'HEAD', 'OPTIONS']);
+ define('APP_SESSION_USE_CSRF_EXCLUDE_URI', $_ENV['APP_SESSION_USE_CSRF_EXCLUDE_URI'] ?? []);
+
+ //Log관련
+ define('APP_LOG_PATH', $_ENV['APP_LOG_PATH'] ?? ROOT_PATH . '/logs');
+ define('APP_LOG_PERMISSION', $_ENV['APP_LOG_PERMISSION'] ?? 0775);
+ define('APP_LOG_LEVEL', $_ENV['APP_LOG_LEVEL'] ?? 'error');
+ define('APP_LOG_FORMAT', $_ENV['APP_LOG_FORMAT'] ?? 'text');
+ define('APP_LOG_MAX_SIZE', $_ENV['APP_LOG_MAX_SIZE'] ?? 1048576); // 1MB
+ define('APP_LOG_MAX_FILES', $_ENV['APP_LOG_MAX_FILES'] ?? 5);
+ define('APP_LOG_DATE_FORMAT', $_ENV['APP_LOG_DATE_FORMAT'] ?? 'Y-m-d H:i:s');
+ define('APP_LOG_CHANNEL', $_ENV['APP_LOG_CHANNEL'] ?? 'default');
+ define('APP_LOG_LEVELS', $_ENV['APP_LOG_LEVELS'] ?? [
+ 'emergency' => 0,
+ 'alert' => 1,
+ 'critical' => 2,
+ 'error' => 3,
+ 'warning' => 4,
+ 'notice' => 5,
+ 'info' => 6,
+ 'debug' => 7,
+ ]);
+ define('APP_LOG_FORMATS', $_ENV['APP_LOG_FORMATS'] ?? [
+ 'text' => "{date} [{level}] {message}",
+ 'json' => '{"date": "{date}", "level": "{level}", "message": "{message}"}',
+ ]);
+ define('APP_LOG_CHANNELS', $_ENV['APP_LOG_CHANNELS'] ?? [
+ 'default' => [
+ 'driver' => 'single',
+ 'path' => APP_LOG_PATH . '/app.log',
+ 'level' => APP_LOG_LEVEL,
+ 'formatter' => APP_LOG_FORMAT,
+ 'max_size' => APP_LOG_MAX_SIZE,
+ 'max_files' => APP_LOG_MAX_FILES,
+ ],
+ ]);
+
+ //Database 정보
+ define('DATABASE_DRIVER', $_ENV['DATABASE_DRIVER'] ?? $_SERVER['DATABASE_DRIVER'] ?? 'mysql');
+ define('DATABASE_HOST', $_ENV['DATABASE_HOST'] ?? $_SERVER['DATABASE_HOST'] ?? 'localhost');
+ define('DATABASE_DB', $_ENV['DATABASE_DB'] ?? $_SERVER['DATABASE_DB'] ?? 'test');
+ define('DATABASE_CHARSET', $_ENV['DATABASE_CHARSET'] ?? $_SERVER['DATABASE_CHARSET'] ?? 'utf8');
+ define('DATABASE_ID', $_ENV['DATABASE_ID'] ?? $_SERVER['DATABASE_ID'] ?? 'test');
+ define('DATABASE_PASSWORD', $_ENV['DATABASE_PASSWORD'] ?? $_SERVER['DATABASE_PASSWORD'] ?? 'test');
+ define('DATABASE_QUERY_DEBUG', $_ENV['DATABASE_QUERY_DEBUG'] ?? $_SERVER['DATABASE_QUERY_DEBUG'] ?? false);
+
+ //View 관련
+ define('VIEW_PATH', $_ENV['VIEW_PATH'] ?? ROOT_PATH . '/views');
+ define('VIEW_CACHE_PATH', $_ENV['VIEW_CACHE_PATH'] ?? ROOT_PATH . '/cache/views');
+ define('VIEW_CACHE_ENABLED', $_ENV['VIEW_CACHE_ENABLED'] ?? true);
+ define('VIEW_CACHE_LIFETIME', $_ENV['VIEW_CACHE_LIFETIME'] ?? 3600);
+ define('VIEW_CACHE_DRIVER', $_ENV['VIEW_CACHE_DRIVER'] ?? 'file');
+ define('VIEW_CACHE_PREFIX', $_ENV['VIEW_CACHE_PREFIX'] ?? 'view_cache_');
+ define('VIEW_CACHE_SUFFIX', $_ENV['VIEW_CACHE_SUFFIX'] ?? '.php');
+ define('VIEW_CACHE_EXTENSION', $_ENV['VIEW_CACHE_EXTENSION'] ?? '.html');
+
+ if (APP_DEBUG) {
+ error_reporting(E_ALL);
+ ini_set('display_errors', '1');
+ } else {
+ error_reporting(0);
+ ini_set('display_errors', '0');
+ }
+ parent::__construct();
+ }
+}
diff --git a/extdbms/lib/Configs/Constant.php b/extdbms/lib/Configs/Constant.php
new file mode 100644
index 0000000..f01a269
--- /dev/null
+++ b/extdbms/lib/Configs/Constant.php
@@ -0,0 +1,121 @@
+ [
+ "id" => "PRIMEIDC",
+ "domain" => "dbms.prime-idc.jp",
+ "name" => "PrimeIDC",
+ "email" => "primeidc.jp@gmail.com",
+ "totalcount_types" => ["normal", "defence", "solo", "substitution", "test"],
+ "totalcount_customers" => [
+ "idcjp" => "Client_Code NOT IN ('C116','C012','C636')",
+ "winidc" => "Client_Code='C116'",
+ "gamewing" => "Client_Code='C012'",
+ "GDIDC" => "Client_Code='C636'",
+ ],
+ "banks" => [
+ ["id" => "331301-04-217387", "name" => '국민은행', "owner" => "주)듀나미스"]
+ ]
+ ],
+ 'dbms.itsolution-idc.jp' => [
+ "id" => "ITSOLUTION",
+ "domain" => "dbms.itsolution-idc.jp",
+ "name" => "Itsolution",
+ "email" => "support@itsoution-idc.jp",
+ "totalcount_types" => ["normal", "defence", "solo", "substitution", "test"],
+ "totalcount_customers" => [
+ "winidc" => "Client_Code NOT IN ('C237')",
+ "bosch" => "Client_Code='C237'",
+ ],
+ "banks" => [
+ ["id" => "9002-1932-1654-1", "name" => '새마을금고', "owner" => "주식회사 르호봇"],
+ ["id" => "351-0995-6751-73", "name" => '농협', "owner" => "주식회사 르호봇"],
+ ],
+ ],
+ 'dbms.gdidc.jp' => [
+ "id" => "GDIDC",
+ "domain" => "dbms.gdidc.jp",
+ "name" => "GDIDC",
+ "email" => "support@gdidc.jp",
+ "totalcount_types" => ["normal", "defence", "solo", "substitution", "test"],
+ "totalcount_customers" => [
+ "gdidc" => "",
+ ],
+ "banks" => [
+ ["id" => "1005-204-100758", "name" => '우리은행', "owner" => " (주)브엘라해로이"],
+ ],
+ ]
+]);
+define('DBMS_SERVICE_SWITCHCODE', [
+ 'Chiba' => ['begin' => 'C00%', 'end' => 'C64%'],
+ 'Tokyo' => ['begin' => 'C80%', 'end' => 'C99%']
+]);
+define('DBMS_SERVICE_LINE_ALL', [
+ 'normal' => '일반',
+ 'defence' => '방어',
+ 'solo' => '전용',
+ 'substitution' => '대체',
+ 'test' => '테스트',
+ 'vpn' => 'VPN',
+ 'event' => '이벤트',
+]);
+define('DBMS_GEARLIST_PROCESS_TYPES', [
+ '',
+ 'COLOCATION',
+ 'XEON Single',
+ 'CUSTOM',
+ 'INS-일회성',
+ 'NEHALEM',
+ 'Cisco Router',
+]);
+define('DBMS_GEARLIST_CPU_TYPES', [
+ '',
+ 'X6-Q',
+ 'C2800',
+ 'C2600',
+ 'COL',
+ 'CUS',
+ 'NX227',
+ 'NX20',
+ 'NX21',
+ 'DQ28',
+ 'DQ26',
+ 'DQ31',
+ 'DQ18',
+ 'DQ23',
+ 'DQ20',
+ 'DX34',
+ 'DX38',
+ 'DX28',
+ 'DX32',
+ 'DX36',
+ 'DX30',
+ 'MD32',
+ 'MD30',
+ 'Q16R',
+ 'Q316',
+ 'Q310',
+ 'Q283',
+ 'Q266',
+ 'Q25R',
+ 'Q213',
+ 'Q20R',
+ 'Q186',
+ 'Q24',
+ 'Q20',
+ 'Q240',
+ 'DX3',
+ 'DQ233'
+]);
+define('DBMS_CLIENT_POINT_TYPE', [
+ 'deposit' => '입금',
+ 'withdrawal' => '출금',
+]);
diff --git a/extdbms/lib/Configs/Route.php b/extdbms/lib/Configs/Route.php
new file mode 100644
index 0000000..cbc5995
--- /dev/null
+++ b/extdbms/lib/Configs/Route.php
@@ -0,0 +1,166 @@
+group('dbms/client', function (Router $router) {
+ //Dashboard관련
+ $router->group('dashboard', function (Router $router) {
+ $router->add('GET', 'totalcount', function ($params) {
+ $controller = new ClientDashboardController($params);
+ return $controller->totalcount();
+ // Response::view($result);
+ });
+ });
+ //메모관련
+ $router->group('memo', function (Router $router) {
+ $router->add('GET', 'update_form', function ($params) {
+ $controller = new MemoCOntroller($params);
+ return $controller->update_form();
+ // Response::view($result);
+ });
+ $router->add('POST', 'update', function ($params) {
+ $controller = new MemoCOntroller($params);
+ return $controller->update();
+ // Response::view($result);
+ });
+ });
+ //쿠폰관련
+ $router->group('coupon', function (Router $router) {
+ $router->add('GET', 'index', function ($params) {
+ $controller = new CouponCOntroller($params);
+ return $controller->index();
+ // Response::view($result);
+ });
+ $router->add('GET', 'insert_form', function ($params) {
+ $controller = new CouponCOntroller($params);
+ return $controller->insert_form();
+ // Response::view($result);
+ });
+ $router->add('POST', 'insert', function ($params) {
+ $controller = new CouponCOntroller($params);
+ return $controller->insert();
+ // Response::view($result);
+ });
+ });
+ //Point관련
+ $router->group('point', function (Router $router) {
+ $router->add('GET', 'index', function ($params) {
+ $controller = new PointController($params);
+ return $controller->index();
+ // Response::view($result);
+ });
+ $router->add('GET', 'insert_form', function ($params) {
+ $controller = new PointController($params);
+ return $controller->insert_form();
+ // Response::view($result);
+ });
+ $router->add('POST', 'insert', function ($params) {
+ $controller = new PointController($params);
+ return $controller->insert();
+ // Response::view($result);
+ });
+ });
+ //결제관련
+ $router->group('payment', function (Router $router) {
+ $router->add('GET', 'index', function ($params) {
+ $controller = new PaymentCOntroller($params);
+ return $controller->index();
+ // Response::view($result);
+ });
+ $router->add('GET', 'billpaper', function ($params) {
+ $controller = new PaymentCOntroller($params);
+ return $controller->billpaper();
+ // Response::view($result);
+ });
+ });
+});
+
+// 예제 라우트 그룹: dbms/dashboard/index 이후에 key/value 파라미터 허용
+$router->group('dbms/dashboard', function (Router $router) {
+ // // 동적 파라미터 없이 기본 path에 추가 파라미터를 받아 key/value 형식으로 처리
+ // $router->add('GET', 'index', function ($params) {
+ // Response::json([
+ // 'message' => 'DashboardController::index 실행됨',
+ // 'params' => $params
+ // ]);
+ // });
+ // 동적 파라미터 없이 기본 path에 추가 파라미터를 받아 key/value 형식으로 처리
+ $router->add('GET', 'topboard', function ($params) {
+ $controller = new DashboardCOntroller($params);
+ return $controller->topboard();
+ // Response::view($result);
+ });
+ $router->add('GET', 'totalcount', function ($params) {
+ $controller = new DashboardCOntroller($params);
+ return $controller->totalcount();
+ // Response::view($result);
+ });
+ $router->add('GET', 'latest_service', function ($params) {
+ $controller = new DashboardCOntroller($params);
+ return $controller->latest_service();
+ // Response::view($result);
+ });
+ $router->add('GET', 'latest_history', function ($params) {
+ $controller = new DashboardCOntroller($params);
+ return $controller->latest_history();
+ // Response::view($result);
+ });
+ $router->add('GET', 'cscount', function ($params) {
+ $controller = new DashboardCOntroller($params);
+ return $controller->cscount();
+ // Response::view($result);
+ });
+ $router->add('GET', 'coupon', function ($params) {
+ $controller = new DashboardCOntroller($params);
+ return $controller->coupon();
+ // Response::view($result);
+ });
+});
+
+$router->group('dbms/navigator', function (Router $router) {
+ // 동적 파라미터 없이 기본 path에 추가 파라미터를 받아 key/value 형식으로 처리
+ $router->add('GET', 'index', function ($params) {
+ $controller = new NavigatorCOntroller($params);
+ return $controller->index();
+ // Response::view($result);
+ });
+});
+
+$router->group('dbms/defence', function (Router $router) {
+ // 동적 파라미터 없이 기본 path에 추가 파라미터를 받아 key/value 형식으로 처리
+ $router->add('GET', 'index', function ($params) {
+ $controller = new DefenceCOntroller($params);
+ return $controller->index();
+ // Response::view($result);
+ });
+});
+
+$router->group('dbms/service', function (Router $router) {
+ // 동적 파라미터 없이 기본 path에 추가 파라미터를 받아 key/value 형식으로 처리
+ $router->add('GET', 'extra', function ($params) {
+ $controller = new ServiceCOntroller($params);
+ return $controller->extra();
+ // Response::view($result);
+ });
+});
+
+$router->group('dbms/gearlist', function (Router $router) {
+ $router->add('GET', 'index', function ($params) {
+ $controller = new GearlistCOntroller($params);
+ return $controller->index();
+ // Response::view($result);
+ });
+});
diff --git a/extdbms/lib/Configs/View.php b/extdbms/lib/Configs/View.php
new file mode 100644
index 0000000..a741760
--- /dev/null
+++ b/extdbms/lib/Configs/View.php
@@ -0,0 +1,13 @@
+getView()->setPath('client');
+ } //
+ final public function getClientService(): ClientService
+ {
+ if ($this->_clientService === null) {
+ $this->_clientService = new ClientService();
+ }
+ return $this->_clientService;
+ }
+ final public function getMemberService(): MemberService
+ {
+ if ($this->_memberService === null) {
+ $this->_memberService = new MemberService();
+ }
+ return $this->_memberService;
+ }
+ protected function setDefaultRequestData(): array
+ {
+ $this->client = null;
+ $this->member = null;
+ $this->service = null;
+ //사용자정보
+ $client_code = $this->request->get('client_code');
+ // echo "Client_Code:" . $client_code;
+ // exit;
+ if ($client_code) {
+ $this->getClientService()->getModel()->where('Client_Code', $client_code);
+ $client = $this->getClientService()->getEntity();
+ if (!$client) {
+ throw new \Exception("[$client_code]에 해당하는 고객정보가 존재하지 않습니다.");
+ }
+ $this->client = $client;
+ }
+ //관리자정보(등록자)
+ $member_code = $this->request->get('mkid');
+ // echo "member_code:" . $member_code;
+ if ($member_code) {
+ $this->getMemberService()->getModel()->where($this->getMemberService()->getModel()::PKField, $member_code);
+ $member = $this->getMemberService()->getEntity();
+ if (!$member) {
+ throw new \Exception("[$member_code]에 해당하는 관리자정보가 존재하지 않습니다.");
+ }
+ $this->member = $member;
+ }
+ //서비스정보
+ $service_code = $this->request->get('service_code');
+ // echo "service_code:" . $service_code;
+ if ($service_code) {
+ $this->getServiceService()->getModel()->where($this->getServiceService()->getModel()::PKField, $service_code);
+ $service = $this->getServiceService()->getEntity();
+ if (!$service) {
+ throw new \Exception("[$service_code]에 해당하는 서비스정보가 존재하지 않습니다.");
+ }
+ $this->service = $service;
+ }
+ return [$client_code, $member_code, $service_code];
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/Client/CouponController.php b/extdbms/lib/Controllers/Client/CouponController.php
new file mode 100644
index 0000000..0dfdf12
--- /dev/null
+++ b/extdbms/lib/Controllers/Client/CouponController.php
@@ -0,0 +1,103 @@
+getView()->setPath('coupon');
+ } //
+ public function getOnetimeService(): OnetimeService
+ {
+ if ($this->_onetimeService === null) {
+ $this->_onetimeService = new OnetimeService();
+ }
+ return $this->_onetimeService;
+ }
+ public function getHistoryService(): HistoryService
+ {
+ if ($this->_historyService === null) {
+ $this->_historyService = new HistoryService();
+ }
+ return $this->_historyService;
+ }
+
+ //IdcCouponListMK.jsp -> domain_coupon.php
+ //CLI 접속방법 : php index.php site/client/counpon/index
+ //WEB 접속방법 : http://localhost/site/client/coupon/index
+ public function index()
+ {
+ //기본적으로 필요한 client_code, mkid, service_code를 설정합니다.
+ list($client_code, $member_code, $service_code) = $this->setDefaultRequestData();
+ //사용자별 쿠폰내역
+ if ($client_code) {
+ $this->getServiceService()->getModel()->where('client_code', $client_code);
+ }
+ $this->curPage = intval($this->request->get('curPage', 1));
+ $this->perPage = intval($this->request->get('perPage', VIEW_LIST_PERPAGE));
+ [$this->total, $this->entities] = $this->getServiceService()->getList($this->curPage, $this->perPage);
+ $this->pagination = new Pagination($this->total, (int)$this->curPage, (int)$this->perPage);
+ $total_coupon = 0;
+ foreach ($this->entities as $entity) {
+ $total_coupon += $entity->getCoupon();
+ }
+ $this->total_coupon = $total_coupon;
+ return $this->render(__FUNCTION__);
+ }
+
+ //IdcCouponBuyMK.jsp -> domain_coupon_buy.php
+ //CLI 접속방법 : php index.php site/client/counpon/insert_form
+ //WEB 접속방법 : http://localhost/site/client/coupon/insert_form
+ public function insert_form()
+ {
+ //기본적으로 필요한 client_code, mkid, service_code를 설정합니다.
+ list($client_code, $member_code, $service_code) = $this->setDefaultRequestData();
+ $this->today = date("Y-m-d");
+ return $this->render(__FUNCTION__);
+ }
+
+ //IdcCouponBuyMK.jsp -> domain_coupon_buy.php
+ //CLI 접속방법 : php index.php site/client/counpon/insert_form
+ //WEB 접속방법 : http://localhost/site/client/coupon/insert_form
+ public function insert()
+ {
+ //기본적으로 필요한 client_code, mkid, service_code를 설정합니다.
+ list($client_code, $member_code, $service_code) = $this->setDefaultRequestData();
+ //onetime_sub 도메인 구매 수량
+ $coupon = $this->request->get('coupon');
+ if (! $coupon || $coupon < 1) {
+ throw new \Exception("도메인 구매 수량 값이 정의되지 않았거나, 도메인 구매 수량은 1개 이상이어야 합니다.");
+ }
+ //onetime_note 도메인 구매 수량
+ $note = $this->request->get('note');
+ if (!$note) {
+ throw new \Exception("도메인 리스트 값이 정의되지 않았습니다.");
+ }
+ //onetime_case 사용용도
+ $onetime_case = $this->request->get('onetime_case', 'domain');
+ //onetime_request_date 사용일
+ $onetime_request_date = $this->request->get('onetime_request_date') ?? date("Y-m-d");
+ try {
+ $this->getServiceService()->beginTransaction();
+ //서비스쿠폰 갯수 수정
+ $this->getServiceService()->useCouponByService($this->service, $coupon);
+ //쿠폰 사용내역 onetime에 등록
+ $this->getOnetimeService()->useCouponByService($this->service, $this->client, $this->member, $onetime_case, $coupon, $note, $onetime_request_date);
+ //쿠폰 사용내역 history에 등록
+ $this->getHistoryService()->useCouponByService($this->service, $this->client, $onetime_case, $coupon, $note, $onetime_request_date);;
+ $this->getServiceService()->commit();
+ return $this->redirect->to(DBMS_SITE_URL . "/IdcCouponUseMK.cup?client_code=" . $this->service->getClientCode());
+ } catch (\Exception $e) {
+ $this->getServiceService()->rollback();
+ return $this->redirect->back()->withInput()->with('error', ['message' => '쿠폰 사용에 실패하였습니다.:' . $e->getMessage()]);
+ }
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/Client/DashboardController.php b/extdbms/lib/Controllers/Client/DashboardController.php
new file mode 100644
index 0000000..be73275
--- /dev/null
+++ b/extdbms/lib/Controllers/Client/DashboardController.php
@@ -0,0 +1,99 @@
+getView()->setPath('dashboard');
+ } //
+
+ protected function setDefaultRequestData(): array
+ {
+ $this->client = null;
+ $this->member = null;
+ $this->service = null;
+ //사용자정보
+ $client_code = $this->request->get('client_code');
+ // echo "Client_Code:" . $client_code;
+ // exit;
+ if ($client_code) {
+ $this->getClientService()->getModel()->where('Client_Code', $client_code);
+ $client = $this->getClientService()->getEntity();
+ if (!$client) {
+ throw new \Exception("[$client_code]에 해당하는 고객정보가 존재하지 않습니다.");
+ }
+ $this->client = $client;
+ }
+ //관리자정보(등록자)
+ $member_code = $this->request->get('mkid');
+ // echo "member_code:" . $member_code;
+ if ($member_code) {
+ $this->getMemberService()->getModel()->where($this->getMemberService()->getModel()::PKField, $member_code);
+ $member = $this->getMemberService()->getEntity();
+ if (!$member) {
+ throw new \Exception("[$member_code]에 해당하는 관리자정보가 존재하지 않습니다.");
+ }
+ $this->member = $member;
+ }
+ //서비스정보
+ $service_code = $this->request->get('service_code');
+ // echo "service_code:" . $service_code;
+ if ($service_code) {
+ $this->getServiceService()->getModel()->where($this->getServiceService()->getModel()::PKField, $service_code);
+ $service = $this->getServiceService()->getEntity();
+ if (!$service) {
+ throw new \Exception("[$service_code]에 해당하는 서비스정보가 존재하지 않습니다.");
+ }
+ $this->service = $service;
+ }
+ return [$client_code, $member_code, $service_code];
+ }
+
+ //서비스카운팅 , total_counting_customer.php
+ //CLI 접속방법 : php index.php site/client/totalcount/client_code/코드번호
+ //WEB 접속방법 : http://localhost/site/client/totalcount/client_code/코드번호
+ public function totalcount()
+ {
+ //사용자정보
+ $client_code = $this->request->get('client_code');
+ // echo "Client_Code:" . $client_code;
+ if ($client_code) {
+ $this->getClientService()->getModel()->where('Client_Code', $client_code);
+ $client = $this->getClientService()->getEntity();
+ if (!$client) {
+ throw new \Exception("[$client_code]에 해당하는 고객정보가 존재하지 않습니다.");
+ }
+ $this->client = $client;
+ }
+ //서비스위치별(치바,도쿄등)
+ $dashboard = [];
+ foreach (DBMS_SERVICE_SWITCHCODE as $district => $switchcodes) {
+ $switchcode_begin = $switchcodes['begin'];
+ $switchcode_end = $switchcodes['end'];
+ $this->getServiceService()->getModel()->where("client_code", "{$client_code}");
+ $this->getServiceService()->getModel()->where("service_sw BETWEEN '{$switchcode_begin}' AND '{$switchcode_end}'");
+ $this->getServiceService()->getModel()->where("service_status", "o");
+ $this->getServiceService()->getModel()->whereNotIn("service_line", ['solo', 'test', 'event', 'substitution']);
+ $dashboard[$district] = $this->getServiceService()->getCount();
+ } //foreach
+ //서비스라인별(일반,방어,전용,테스트,대체,vpn,event등)
+ foreach (DBMS_SERVICE_LINE_ALL as $service_line => $label) {
+ $this->getServiceService()->getModel()->where('client_code', $client_code);
+ $this->getServiceService()->getModel()->where('service_line', $service_line);
+ $dashboard[$service_line] = $this->getServiceService()->getCount("SUM(coupon) as cnt");
+ } //foreach
+ //서비스상태별(일반,방어만)
+ $this->getServiceService()->getModel()->where("client_code", $client_code);
+ $this->getServiceService()->getModel()->whereNotIn("service_line", ['solo', 'test', 'event', 'substitution']);
+ $dashboard['coupon'] = $this->getServiceService()->getCount("SUM(coupon) as cnt");
+ $this->dashboard = $dashboard;
+ $this->client_code = $client_code;
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/Client/MemoController.php b/extdbms/lib/Controllers/Client/MemoController.php
new file mode 100644
index 0000000..6f73426
--- /dev/null
+++ b/extdbms/lib/Controllers/Client/MemoController.php
@@ -0,0 +1,31 @@
+getView()->setPath('memo');
+ $this->helper = new ServiceHelper();
+ } //
+ //사용자용메모장 , customer_memo.php
+ //CLI 접속방법 : php index.php site/client/memo/update_form/client_code/코드번호
+ //WEB 접속방법 : http://localhost/site/client/memo/update_form/client_code/코드번호
+ public function update_form()
+ {
+ //기본적으로 필요한 client_code, mkid, service_code를 설정합니다.
+ list($client_code, $member_code, $service_code) = $this->setDefaultRequestData();
+ return $this->render(__FUNCTION__);
+ }
+
+ public function update()
+ {
+ //기본적으로 필요한 client_code, mkid, service_code를 설정합니다.
+ list($client_code, $member_code, $service_code) = $this->setDefaultRequestData();
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/Client/PaymentController.php b/extdbms/lib/Controllers/Client/PaymentController.php
new file mode 100644
index 0000000..cb06e86
--- /dev/null
+++ b/extdbms/lib/Controllers/Client/PaymentController.php
@@ -0,0 +1,66 @@
+getView()->setPath('payment');
+ } //
+
+ //청구서, depositbillpaper.php
+ //CLI 접속방법 : php index.php site/client/payment/billpaper
+ //WEB 접속방법 : http://localhostsite/client/payment/billpaper
+ public function billpaper(): string
+ {
+ //기본적으로 필요한 client_code, mkid, service_code를 설정합니다.
+ list($client_code, $member_code, $service_code) = $this->setDefaultRequestData();
+ return $this->render(__FUNCTION__);
+ }
+ //미납리스트트, NonPaymentList.php
+ //CLI 접속방법 : php index.php site/client/payment/index
+ //WEB 접속방법 : http://localhostsite/client/payment/index
+ public function index(): string
+ {
+ //Client_Code = ["C219"=>WinIDC,"C116"=>IDC-JP"] -> 미지급금계산 제외 Client_Code
+ $exclude_clients = ['C116', 'C219'];
+ //mode 당일,1일전,2일전,3일전,custom
+ $today = date("Y-m-d");;
+ $mode = $this->request->get('mode', 'all');
+ switch ($mode) {
+ case 'today':
+ $this->message = "[{$today} 기준 당일 ";
+ $this->getServiceService()->getModel()->where("service_payment_date = CURDATE()");
+ break;
+ case '1day':
+ $nonpaymentDay = 1;
+ $this->message = "[{$today}] 기준 {$nonpaymentDay}일전";
+ $this->getServiceService()->getModel()->where("service_payment_date = Date_Add(CURDATE(),INTERVAL {$nonpaymentDay} DAY)");
+ break;
+ case '2day':
+ $nonpaymentDay = 2;
+ $this->message = "[{$today}] 기준 {$nonpaymentDay}일전";
+ $this->getServiceService()->getModel()->where("service_payment_date = Date_Add(CURDATE(),INTERVAL {$nonpaymentDay} DAY)");
+ break;
+ case '3day':
+ $nonpaymentDay = 3;
+ $this->message = "[{$today}] 기준 {$nonpaymentDay}일전";
+ $this->getServiceService()->getModel()->where("service_payment_date = Date_Add(CURDATE(),INTERVAL {$nonpaymentDay} DAY)");
+ break;
+ case 'all':
+ default:
+ $this->message = "[{$today}] 기준 전체";
+ break;
+ }
+ $this->mode = $mode;
+ $this->curPage = intval($this->request->get('curPage', 1));
+ $this->perPage = intval($this->request->get('perPage', VIEW_LIST_PERPAGE));
+ [$this->total, $this->entities] = $this->getServiceService()->getEntitiesForNonPayment($this->curPage, $this->perPage, $exclude_clients);
+ $this->pagination = new Pagination($this->total, (int)$this->curPage, (int)$this->perPage);
+ return $this->render(path: __FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/Client/PointController.php b/extdbms/lib/Controllers/Client/PointController.php
new file mode 100644
index 0000000..c4acb0c
--- /dev/null
+++ b/extdbms/lib/Controllers/Client/PointController.php
@@ -0,0 +1,144 @@
+getView()->setPath('point');
+ $this->helper = new PointHelper();
+ } //
+ public function getPointService(): PointService
+ {
+ if ($this->_pointService === null) {
+ $this->_pointService = new PointService();
+ }
+ return $this->_pointService;
+ }
+ public function getOnetimeService(): OnetimeService
+ {
+ if ($this->_onetimeService === null) {
+ $this->_onetimeService = new OnetimeService();
+ }
+ return $this->_onetimeService;
+ }
+ public function getHistoryService(): HistoryService
+ {
+ if ($this->_historyService === null) {
+ $this->_historyService = new HistoryService();
+ }
+ return $this->_historyService;
+ }
+
+ //IdcClientPointList.jsp
+ //CLI 접속방법 : php index.php site/client/point/index
+ //WEB 접속방법 : http://localhost/site/client/point/index
+ public function index()
+ {
+ //전체 고객객정보
+ $this->clients = $this->getClientService()->getEntities();
+ //사용자코드가 있으면,
+ $client_code = $this->request->get('client_code');
+ if ($client_code) {
+ $this->getPointService()->getModel()->where('client_code', $client_code);
+ }
+ $this->client_code = $client_code;
+ $this->curPage = intval($this->request->get('curPage', 1));
+ $this->perPage = intval($this->request->get('perPage', VIEW_LIST_PERPAGE));
+ [$this->total, $this->entities] = $this->getPointService()->getList($this->curPage, $this->perPage);
+ $this->pagination = new Pagination($this->total, (int)$this->curPage, (int)$this->perPage);
+ return $this->render(__FUNCTION__);
+ }
+
+ //IdcClientPointInsert.jsp
+ //CLI 접속방법 : php index.php site/client/point/insert_form
+ //WEB 접속방법 : http://localhost/site/client/point/insert_form
+ public function insert_form()
+ {
+ //전체 고객객정보
+ $this->clients = $this->getClientService()->getEntities();
+ //사용자코드가 있으면,
+ $client_code = $this->request->get('client_code');
+ if ($client_code) {
+ $this->getPointService()->getModel()->where('client_code', $client_code);
+ }
+ $this->client_code = $client_code;
+ return $this->render(__FUNCTION__);
+ }
+
+ //IdcPointBuyMK.jsp -> domain_point_buy.php
+ //CLI 접속방법 : php index.php site/client/point/insert_form
+ //WEB 접속방법 : http://localhost/site/client/point/insert_form
+ public function insert()
+ {
+ try {
+ //Client Code 형식
+ $client_code = $this->request->get('client_code');
+ if (!$client_code) {
+ throw new \Exception("고객을 선택하지 않으셨습니다.");
+ }
+ $this->getClientService()->getModel()->where('Client_Code', $client_code);
+ $client = $this->getClientService()->getEntity();
+ if (!$client) {
+ throw new \Exception("[$client_code]에 해당하는 고객정보가 존재하지 않습니다.");
+ }
+ //포인트 형식
+ $type = $this->request->get('type');
+ if (!$type) {
+ throw new \Exception("포인트 형식이 정의되지 않았습니다.");
+ }
+ //포인트 값
+ $amount = intval($this->request->get('amount'));
+ if (! $amount || $amount < 1) {
+ throw new \Exception("포인트 값이 정의되지 않았거나, 포인트값은 1 이상이어야 합니다.");
+ }
+ //포인트 작업 내용
+ $note = $this->request->get('note');
+ // //onetime_case 사용용도
+ // $onetime_case = $this->request->get('onetime_case', 'point');
+ // //onetime_request_date 사용일
+ // $onetime_request_date = $this->request->get('onetime_request_date') ?? date("Y-m-d");
+ $formDatas = [
+ 'client_code' => $client_code,
+ 'type' => $type,
+ 'title' => date("Y-m-d") . ", [$amount] 포인트, " . DBMS_CLIENT_POINT_TYPE[$type],
+ 'amount' => $amount,
+ 'note' => $note
+ ];
+ $this->getServiceService()->beginTransaction();
+ // //포인트 사용내역 onetime에 등록
+ // $this->getOnetimeService()->usePointByService($service, $client, $member, $onetime_case, $point, $note, $onetime_request_date);
+ // //포인트 사용내역 history에 등록
+ // $this->getHistoryService()->usePointByService($service, $client, $onetime_case, $point, $note, $onetime_request_date);;
+ //포인트 사용내역 point에 등록
+ $this->getPointService()->getModel()->insert($formDatas);
+ if ($type == 'withdrawal') { //사용자 포인트 출금
+ $this->getClientService()->withdrawalPoint($this->client, $amount);
+ } else { //사용자 포인트 입금
+ $this->getClientService()->depositPoint($this->client, $amount);
+ }
+ $this->getServiceService()->commit();
+ $message_key = 'success';
+ $message = "포인트 : [$amount]" . DBMS_CLIENT_POINT_TYPE[$type] . "이 완료되었습니다";
+ } catch (\PDOException $e) {
+ $this->getServiceService()->rollback();
+ $message_key = 'error';
+ $message = "실패:" . $e->getMessage();
+ } catch (\Exception $e) {
+ $message_key = 'error';
+ $message = "실패" . $e->getMessage();
+ }
+ return $this->redirect->to(DBMS_SITE_URL . "/IdcPointList.cup?client_code=$client_code")->with($message_key, ['message' => $message]);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/CommonController.php b/extdbms/lib/Controllers/CommonController.php
new file mode 100644
index 0000000..3a07645
--- /dev/null
+++ b/extdbms/lib/Controllers/CommonController.php
@@ -0,0 +1,13 @@
+getView()->setPath('dbms');
+ } //
+
+ final public function getServiceService(): ServiceService
+ {
+ if ($this->_service === null) {
+ $this->_service = new ServiceService();
+ }
+ return $this->_service;
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/DashboardController.php b/extdbms/lib/Controllers/DashboardController.php
new file mode 100644
index 0000000..40c3412
--- /dev/null
+++ b/extdbms/lib/Controllers/DashboardController.php
@@ -0,0 +1,216 @@
+getView()->setPath('dashboard');
+ $this->helper = new ServiceHelper();
+ } //
+ public function getMemberService(): MemberService
+ {
+ if ($this->_memberService === null) {
+ $this->_memberService = new MemberService();
+ }
+ return $this->_memberService;
+ }
+
+ public function getClientService(): ClientService
+ {
+ if ($this->_clientService === null) {
+ $this->_clientService = new ClientService();
+ }
+ return $this->_clientService;
+ }
+
+ public function getVPCService(): VPCService
+ {
+ if ($this->_vpcService === null) {
+ $this->_vpcService = new VPCService();
+ }
+ return $this->_vpcService;
+ }
+ public function getKCSService(): KCSService
+ {
+ if ($this->_kcsService === null) {
+ $this->_kcsService = new KCSService();
+ }
+ return $this->_kcsService;
+ }
+ public function getHistoryService(): HistoryService
+ {
+ if ($this->_historyService === null) {
+ $this->_historyService = new HistoryService();
+ }
+ return $this->_historyService;
+ }
+ //Dashboard , default_alert.php
+ //CLI 접속방법 : php index.php site/dashboard/topboard
+ //WEB 접속방법 : http://localhost/site/dashboard/topboard
+ public function topboard()
+ {
+ // 최근7일 신규서버수
+ //예외,service_line = "test","substitution"
+ $excepts = ["test", "substitution"];
+ $this->day = intval(DBMS_SITE_DASHBOARD_DAY);
+ $this->getServiceService()->getModel()->where("service_open_date > DATE_ADD(now(), INTERVAL -{$this->day} DAY)");
+ $this->getServiceService()->getModel()->where("service_status", 'o');
+ $this->getServiceService()->getModel()->whereNotIn("service_line", $excepts);
+ $this->newServices = $this->getServiceService()->getCount();
+ // 금일기준 미납서버수
+ //예외,service_line = "test","substitution",C012:게임윙,C116:WinIDC,C219:IDC-JP
+ $excepts = ["test", "substitution", 'C116', 'C012', 'C219'];
+ $this->getServiceService()->getModel()->where("service_payment_date > now()");
+ $this->getServiceService()->getModel()->where("service_status", 'o');
+ $this->getServiceService()->getModel()->whereNotIn("service_line", $excepts);
+ $this->unPayments = $this->getServiceService()->getCount();
+ return $this->render(__FUNCTION__);
+ }
+
+ //서비스카운팅 , total_counting.php
+ //CLI 접속방법 : php index.php site/dashboard/totalcount/sitekey/도메인
+ //WEB 접속방법 : http://localhost/site/dashboard/totalcount/sitekey/도메인
+ public function totalcount()
+ {
+ $sitekey = $this->request->get('sitekey');
+ if (!$sitekey) {
+ throw new \Exception("sitekey 값이 정의되지 않았습니다.");
+ }
+ $this->siteInfo = DBMS_SITEINFOS[$sitekey];
+ $this->totalcount = $this->getServiceService()->getTotalCountForDashboard($this->siteInfo);
+ $summary = array();
+ foreach ($this->siteInfo['totalcount_types'] as $type) {
+ $summary[$type] = array("Tokyo" => 0, "Chiba" => 0);
+ }
+ foreach ($this->totalcount as $company => $service) {
+ $summary[$company] = array("Tokyo" => 0, "Chiba" => 0);
+ foreach ($service as $name => $location) {
+ $summary[$company]['Tokyo'] += $location['Tokyo'];
+ $summary[$name]['Tokyo'] += $location['Tokyo'];
+ $summary[$company]['Chiba'] += $location['Chiba'];
+ $summary[$name]['Chiba'] += $location['Chiba'];
+ }
+ }
+ $total = array("Tokyo" => 0, "Chiba" => 0);
+ foreach ($this->siteInfo['totalcount_types'] as $type) {
+ $total['Tokyo'] += $summary[$type]['Tokyo'];
+ $total['Chiba'] += $summary[$type]['Chiba'];
+ }
+ $this->summary = $summary;
+ $this->total = $total;
+ return $this->render(__FUNCTION__);
+ }
+ //신규서버현황 new_server_list.php
+ //CLI 접속방법 : php index.php site/dashboard/latest_service/limit/5
+ //WEB 접속방법 : http://localhost/site/dashboard/latest_service/limit/5
+ public function latest_service()
+ {
+ //신규서버정보
+ $this->limit = intval($this->request->get('limit', 5));
+ $this->getServiceService()->getModel()->orderBy($this->getServiceService()->getModel()->getPKField(), 'DESC');
+ $this->getServiceService()->getModel()->limit($this->limit);
+ $this->entities = $this->getServiceService()->getEntities();
+
+ //전체 관리자정보(등록자)
+ $this->members = $this->getMemberService()->getEntities();
+ $clients = [];
+ $vpcs = [];
+ $kcss = [];
+ $cnt = 1;
+ foreach ($this->entities as $entity) {
+ $serviceCode = $entity->getServiceCode();
+ //해당 고객정보
+ $this->getClientService()->getModel()->where('client_code', $entity->getClientCode());
+ $client = $this->getClientService()->getEntity();
+ if (!$client) {
+ throw new \Exception("{$entity->getClientCode()}에 해당하는 고객정보가 존재하지 않습니다.");
+ }
+ $clients[$serviceCode] = $client;
+ //VPC정보갯수
+ $this->getVPCService()->getModel()->where('service_code', $serviceCode);
+ $vpcs[$serviceCode] = $this->getVPCService()->getCount();
+ //KCS정보갯수
+ $this->getKCSService()->getModel()->where('service_code', $serviceCode);
+ $kcss[$serviceCode] = $this->getKCSService()->getCount();
+ $cnt++;
+ }
+ // dd($this->entitys);
+ $this->clients = $clients;
+ $this->vpcs = $vpcs;
+ $this->kcss = $kcss;
+ return $this->render(__FUNCTION__);
+ }
+ //CLI 접속방법 : php index.php site/dashboard/latest_history/limit/5
+ //WEB 접속방법 : http://localhost/site/dashboard/latest_history/limit/5
+ public function latest_history(): string
+ {
+ //신규History정보
+ $this->limit = intval($this->request->get('limit', 5));
+ $this->getHistoryService()->getModel()->orderBy($this->getHistoryService()->getModel()->getPKField(), 'DESC');
+ $this->getHistoryService()->getModel()->limit($this->limit);
+ $this->entities = $this->getHistoryService()->getEntities();
+ //전체 서비스정보
+ $this->services = $this->getServiceService()->getEntities();
+ //services 고객정보
+ $this->clients = $this->getClientService()->getEntities();
+ return $this->render(__FUNCTION__);
+ }
+ //service_list_cs_count.php
+ //CLI 접속방법 : php index.php site/dashboard/cscount/service_code/서비스코드/client_code/고객코드
+ //WEB 접속방법 : http://localhost/site/dashboard/cscount/service_code/서비스코드/client_code/고객코드
+ public function cscount(): string
+ {
+ //서비스정보
+ $service_code = $this->request->get('service_code');
+ // echo "service_code:" . $service_code;
+ if ($service_code) {
+ $this->getServiceService()->getModel()->where($this->getServiceService()->getModel()::PKField, $service_code);
+ $service = $this->getServiceService()->getEntity();
+ if (!$service) {
+ throw new \Exception("[$service_code]에 해당하는 서비스정보가 존재하지 않습니다.");
+ }
+ $this->service = $service;
+ }
+ //VPC정보갯수
+ $this->getVPCService()->getModel()->where('service_code', $this->service->getServiceCode());
+ $this->vpc = $this->getVPCService()->getCount();
+ //KCS정보갯수
+ $this->getKCSService()->getModel()->where('service_code', $this->service->getServiceCode());
+ $this->kcs = $this->getKCSService()->getCount();
+ return $this->render(__FUNCTION__);
+ }
+ //service_list_cs_count.php
+ //CLI 접속방법 : php index.php site/dashboard/cscount/service_code/서비스코드/client_code/고객코드
+ //WEB 접속방법 : http://localhost/site/dashboard/cscount/service_code/서비스코드/client_code/고객코드
+ public function coupon(): string
+ {
+ //서비스정보
+ $service_code = $this->request->get('service_code');
+ // echo "service_code:" . $service_code;
+ if ($service_code) {
+ $this->getServiceService()->getModel()->where($this->getServiceService()->getModel()::PKField, $service_code);
+ $service = $this->getServiceService()->getEntity();
+ if (!$service) {
+ throw new \Exception("[$service_code]에 해당하는 서비스정보가 존재하지 않습니다.");
+ }
+ $this->service = $service;
+ }
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/DefenceController.php b/extdbms/lib/Controllers/DefenceController.php
new file mode 100644
index 0000000..25a9334
--- /dev/null
+++ b/extdbms/lib/Controllers/DefenceController.php
@@ -0,0 +1,42 @@
+getView()->setPath('defence');
+ } //
+ public function getDefenceService(): DefenceService
+ {
+ if ($this->_clientService === null) {
+ $this->_clientService = new DefenceService();
+ }
+ return $this->_clientService;
+ }
+
+ //방어 defense_index.php
+ //CLI 접속방법 : php index.php site/defence/index/zone/존/parent/부모키/child/자식키
+ //WEB 접속방법 : http://localhost/site/defence/index/zone/존/parent/부모키/child/자식키
+ public function index(): string
+ {
+ $zone = $this->request->get('zone');
+ if (!$zone) {
+ throw new \Exception("zone 값이 정의되지 않았습니다.");
+ }
+ $this->zone = urldecode($zone);
+ $this->getDefenceService()->getModel()->where(['zone' => $this->zone]);
+ $this->getDefenceService()->getModel()->orderBy(['zone' => 'asc', 'parents' => 'asc', 'child' => 'asc']);
+ $this->curPage = intval($this->request->get('curPage', 1));
+ $this->perPage = intval($this->request->get('perPage', VIEW_LIST_PERPAGE));
+ [$this->total, $this->entities] = $this->getDefenceService()->getList($this->curPage, $this->perPage);
+ $this->pagination = new Pagination($this->total, (int)$this->curPage, (int)$this->perPage);
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/GearlistController.php b/extdbms/lib/Controllers/GearlistController.php
new file mode 100644
index 0000000..4ad759d
--- /dev/null
+++ b/extdbms/lib/Controllers/GearlistController.php
@@ -0,0 +1,60 @@
+getView()->setPath('gearlist');
+ } //
+ public function getGearlistService(): GearlistService
+ {
+ if ($this->_gearlistServicerService === null) {
+ $this->_gearlistServicerService = new GearlistService();
+ }
+ return $this->_gearlistServicerService;
+ }
+ public function getServerService(): ServerService
+ {
+ if ($this->_serverService === null) {
+ $this->_serverService = new ServerService();
+ }
+ return $this->_serverService;
+ }
+ //가용장비 현황 server_use.php
+ //CLI 접속방법 : php index.php site/server/use
+ //WEB 접속방법 : http://localhost site/server/use
+ private function setMode(GearlistEntity $entity): GearlistEntity
+ {
+ $lineup_explode = explode('.', $entity->getSpec());
+ $spec = $lineup_explode[0];
+ $cpu = $entity->getCPUName();
+ $entity->all = $this->getServerService()->getCountByMode("all", $cpu, $spec);
+ $entity->use = $this->getServerService()->getCountByMode("use", $cpu, $spec);
+ $entity->empty = $this->getServerService()->getCountByMode("empty", $cpu, $spec);
+ $entity->format = $this->getServerService()->getCountByMode("format", $cpu, $spec);
+ return $entity;
+ }
+ public function index(): string
+ {
+ $gearlistEntities = $this->getGearlistService()->getEntitiesForLineUp();
+ //DB에 넣지않는 이유가 뭘까? DB에 넣으면 관리가 힘들어서?
+ $gearlistEntities[] = new GearlistEntity(['process' => "INTEL i5(구세대)", 'spec' => "i5-2.xx", "cpuname" => "i5-2", 'price' => "23"]);
+ $gearlistEntities[] = new GearlistEntity(['process' => "INTEL i7(구세대)", 'spec' => "i7-2.xx", "cpuname" => "i7-2", 'price' => "45"]);
+ $gearlistEntities[] = new GearlistEntity(['process' => "INTEL i7(4세대)", 'spec' => "i7-4.xx", "cpuname" => "i7-4", 'price' => "45"]);
+ $entities = [];
+ foreach ($gearlistEntities as $idx => $gearlistEntity) {
+ $entities[] = $this->setMode($gearlistEntity);
+ }
+ $this->entities = $entities;
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/HomeController.php b/extdbms/lib/Controllers/HomeController.php
new file mode 100644
index 0000000..a84f7e6
--- /dev/null
+++ b/extdbms/lib/Controllers/HomeController.php
@@ -0,0 +1,14 @@
+getView()->setPath('navigator');
+ $this->helper = new ServiceHelper();
+ } //
+ public function getClientService(): ClientService
+ {
+ if ($this->_clientService === null) {
+ $this->_clientService = new ClientService();
+ }
+ return $this->_clientService;
+ }
+
+ //부가서비스 : 닷디펜더,딥파인더 등, deepfinder_list.php,dotdefender_list.php
+ //CLI 접속방법 : php index.php site/navigator/index
+ //WEB 접속방법 : http://localhost/site/navigator/index
+ public function index(): string
+ {
+ $ip = $this->request->get('ip');
+ //전체 고객정보
+ $this->clients = $this->getClientService()->getEntities();
+ //IP형식이 ipv4이면 해당 IP만 , 아니면 like , 없으면 all 값가져오기
+ if ($ip && $this->helper->isIPAddress($ip)) {
+ $this->getServiceService()->getModel()->where('service_ip', $ip);
+ } elseif ($ip) {
+ $this->getServiceService()->getModel()->like('service_ip', $ip);
+ }
+ $this->curPage = intval($this->request->get('curPage', 1));
+ $this->perPage = intval($this->request->get('perPage', VIEW_LIST_PERPAGE));
+ [$this->total, $this->entities] = $this->getServiceService()->getList($this->curPage, $this->perPage);
+ $this->pagination = new Pagination($this->total, (int)$this->curPage, (int)$this->perPage);
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/ServerController.php b/extdbms/lib/Controllers/ServerController.php
new file mode 100644
index 0000000..f0ae6f5
--- /dev/null
+++ b/extdbms/lib/Controllers/ServerController.php
@@ -0,0 +1,54 @@
+getView()->setPath('server');
+ } //
+ public function getServerService(): ServerService
+ {
+ if ($this->_serverService === null) {
+ $this->_serverService = new ServerService();
+ }
+ return $this->_serverService;
+ }
+ public function getClientService(): ClientService
+ {
+ if ($this->_clientService === null) {
+ $this->_clientService = new ClientService();
+ }
+ return $this->_clientService;
+ }
+ //IdcCouponListMK.jsp -> domain_coupon.php
+ //CLI 접속방법 : php index.php site/client/counpon/index
+ //WEB 접속방법 : http://localhost/site/client/coupon/index
+ public function index()
+ {
+ //서비스스코드가 있는
+ $service_code = $this->request->get('service_code');
+ if ($service_code) {
+ $this->getServerService()->getModel()->where('service_code', $service_code);
+ }
+ //쿠폰내역
+ $this->curPage = intval($this->request->get('curPage', 1));
+ $this->perPage = intval($this->request->get('perPage', VIEW_LIST_PERPAGE));
+ [$this->total, $this->entities] = $this->getServerService()->getList($this->curPage, $this->perPage);
+ $this->pagination = new Pagination($this->total, (int)$this->curPage, (int)$this->perPage);
+ $total_coupon = 0;
+ foreach ($this->entities as $entity) {
+ $total_coupon += $entity->getCoupon();
+ }
+ $this->total_coupon = $total_coupon;
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Controllers/ServiceController.php b/extdbms/lib/Controllers/ServiceController.php
new file mode 100644
index 0000000..ca063eb
--- /dev/null
+++ b/extdbms/lib/Controllers/ServiceController.php
@@ -0,0 +1,66 @@
+getView()->setPath('service');
+ } //
+ public function getClientService(): ClientService
+ {
+ if ($this->_clientService === null) {
+ $this->_clientService = new ClientService();
+ }
+ return $this->_clientService;
+ }
+ public function getAddDbService(): AddDbService
+ {
+ if ($this->_addDbService === null) {
+ $this->_addDbService = new AddDbService();
+ }
+ return $this->_addDbService;
+ }
+
+ //부가서비스 : 닷 디펜더,딥 파인더 ,M307-1,M394-2등, deepfinder_list.php,dotdefender_list.php
+ //CLI 접속방법 : php index.php site/service//extra/adddb_code/코드번호
+ //WEB 접속방법 : http://localhost/site/service/extra/adddb_code/코드번호
+ public function extra(): string
+ {
+ $adddb_code = $this->request->get('adddb_code');
+ if (!$adddb_code) {
+ throw new \Exception("adddb_code 값이 정의되지 않았습니다.");
+ }
+ $this->adddb_code = urldecode($adddb_code);
+ //해당 부가서비스의 services_code 목록 가져오기
+ //segment의 값이 한글인경우 urldecode가 필요
+ $this->getAddDbService()->getModel()->where('addDB_code', $this->adddb_code);
+ $addDbEntities = $this->getAddDbService()->getEntities();
+ $service_codes = [];
+ foreach ($addDbEntities as $entity) {
+ $service_codes[] = $entity->getServiceCode();
+ }
+ if (!count($service_codes)) {
+ throw new \Exception("[{$this->adddb_code}] 값에 해당하는 부가서비스정보가 존재하지 않습니다.");
+ }
+ //전체 사용자정보
+ $this->clients = $this->getClientService()->getEntities();
+ //부가서비스용 서비스목록 가져오기
+ $this->curPage = intval($this->request->get('curPage', 1));
+ $this->perPage = intval($this->request->get('perPage', VIEW_LIST_PERPAGE));
+ $this->getServiceService()->getModel()->whereIn('service_code', $service_codes);
+ [$this->total, $this->entities] = $this->getServiceService()->getList($this->curPage, $this->perPage);
+ $this->pagination = new Pagination($this->total, (int)$this->curPage, (int)$this->perPage);
+ return $this->render(__FUNCTION__);
+ }
+} //Class
diff --git a/extdbms/lib/Core/App.php b/extdbms/lib/Core/App.php
new file mode 100644
index 0000000..6e8ec06
--- /dev/null
+++ b/extdbms/lib/Core/App.php
@@ -0,0 +1,28 @@
+parseCliUri() : $_SERVER['REQUEST_URI'];
+ $method = php_sapi_name() === 'cli' ? 'GET' : $_SERVER['REQUEST_METHOD'];
+ $router->dispatch($uri, $method);
+ }
+
+ private function parseCliUri(): string
+ {
+ global $argv;
+ return $argv[1] ?? '';
+ }
+}
diff --git a/extdbms/lib/Core/Controller.php b/extdbms/lib/Core/Controller.php
new file mode 100644
index 0000000..7b75642
--- /dev/null
+++ b/extdbms/lib/Core/Controller.php
@@ -0,0 +1,50 @@
+url = new Url();
+ $this->session = new Session();
+ $this->redirect = new Redirect($this->session);
+ $this->request = new Request($params);
+ } //
+ final public function __get($name)
+ {
+ return $this->getView()->$name;
+ }
+ final public function __set($name, $value)
+ {
+ $this->getView()->$name = $value;
+ }
+ final public function getView(): View
+ {
+ if ($this->_view === null) {
+ $this->_view = new View();
+ $this->_view->url = $this->url;
+ $this->_view->session = $this->session;
+ $this->_view->redirect = $this->redirect;
+ $this->_view->request = $this->request;
+ }
+ return $this->_view;
+ }
+ public function render(string $path)
+ {
+ return $this->getView()->render($path);
+ }
+} //Class
diff --git a/extdbms/lib/Core/Database/DB.php b/extdbms/lib/Core/Database/DB.php
new file mode 100644
index 0000000..0a2e89d
--- /dev/null
+++ b/extdbms/lib/Core/Database/DB.php
@@ -0,0 +1,23 @@
+setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ }
+ return self::$pdo;
+ }
+}
diff --git a/extdbms/lib/Core/Database/QueryBuilder.php b/extdbms/lib/Core/Database/QueryBuilder.php
new file mode 100644
index 0000000..dc21fcb
--- /dev/null
+++ b/extdbms/lib/Core/Database/QueryBuilder.php
@@ -0,0 +1,393 @@
+pdo = $pdo;
+ }
+ final public function setDebug(bool $debug): void
+ {
+ $this->_debug = $debug;
+ }
+ final public function setContinue(bool $continue): void
+ {
+ $this->_continue = $continue;
+ }
+ final public function getLastQuery(): string
+ {
+ return $this->latestQuery;
+ }
+ final public function table(string $table): static
+ {
+ $this->table = $table;
+ return $this;
+ }
+
+ protected function buildSelectSql(?string $select = null): string
+ {
+ $select = $select ?? implode(', ', $this->select);
+ $sql = "SELECT {$select} FROM {$this->table}";
+ // ⬇️ Join 처리 추가
+ if (!empty($this->joins)) {
+ $sql .= ' ' . implode(' ', $this->joins);
+ }
+ if (!empty($this->where)) {
+ $sql .= " WHERE " . $this->buildWhereSql();
+ }
+ if (!empty($this->order)) {
+ $sql .= " ORDER BY " . implode(', ', $this->order);
+ }
+ if ($this->limit) {
+ $sql .= " LIMIT {$this->limit}";
+ }
+ if ($this->offset) {
+ $sql .= " OFFSET {$this->offset}";
+ }
+ return $sql;
+ }
+ protected function buildWhereSql(): string
+ {
+ $sql = '';
+ foreach ($this->where as $index => $clause) {
+ if (is_array($clause)) {
+ $boolean = $index === 0 ? '' : $clause['boolean'] . ' ';
+ $sql .= $boolean . $clause['condition'] . ' ';
+ } else {
+ // 문자열 형태일 경우 (like에서 사용됨)
+ $boolean = $index === 0 ? '' : 'AND ';
+ $sql .= $boolean . $clause . ' ';
+ }
+ }
+ return trim($sql);
+ }
+
+ //Select부분분
+ final public function select(array|string $columns): static
+ {
+ $this->select = is_array($columns) ? $columns : explode(',', $columns);
+ return $this;
+ }
+
+ //Where절부분
+ final public function where(array|string $column, mixed $value = null, ?string $operator = null, string $boolean = "AND"): static
+ {
+ if (is_array($column)) {
+ foreach ($column as $col => $val) {
+ $this->where($col, $val); // 재귀 호출
+ }
+ return $this;
+ }
+ // where("col = NOW()") 형태의 raw 처리
+ if ($value === null && $operator === null) {
+ $this->where[] = ['condition' => $column, 'boolean' => $boolean];
+ return $this;
+ }
+ // where("col", "val") → operator 생략 시 = 처리
+ if ($operator === null) {
+ $operator = "=";
+ }
+ $placeholder = ':w_' . count($this->bindings);
+ $this->where[] = ['condition' => "$column $operator $placeholder", 'boolean' => $boolean];
+ $this->bindings[$placeholder] = $value;
+ return $this;
+ }
+ final public function orWhere(array|string $column, mixed $value = null, ?string $operator = null, string $boolean = "OR"): static
+ {
+ return $this->where($column, $value, $operator, $boolean);
+ }
+ final public function whereIn(string $column, array $values, string $boolean = 'AND', $conditon = "IN"): static
+ {
+ if (empty($values)) {
+ throw new \InvalidArgumentException(__FUNCTION__ . ": values 배열이 비어있을 수 없습니다.");
+ }
+ $placeholders = [];
+ foreach ($values as $index => $value) {
+ $placeholder = ":in_" . count($this->bindings);
+ $placeholders[] = $placeholder;
+ $this->bindings[$placeholder] = $value;
+ }
+ $condition = "$column $conditon (" . implode(', ', $placeholders) . ")";
+ $this->where[] = ['condition' => $condition, 'boolean' => $boolean];
+ return $this;
+ }
+ final public function whereNotIn(string $column, array $values, $boolean = "AND", $conditon = "NOT IN"): static
+ {
+ if (empty($values)) {
+ throw new \InvalidArgumentException(__FUNCTION__ . ": values 배열이 비어있을 수 없습니다.");
+ }
+ return $this->whereIn($column, $values, $boolean, $conditon);
+ }
+ final public function orWhereIn(string $column, array $values, $boolean = "OR", $conditon = "IN"): static
+ {
+ if (empty($values)) {
+ throw new \InvalidArgumentException(__FUNCTION__ . ": values 배열이 비어있을 수 없습니다.");
+ }
+ return $this->whereIn($column, $values, $boolean, $conditon);
+ }
+
+ //Join
+ final public function join(string $table, string $on, string $type = 'INNER'): static
+ {
+ $this->joins[] = strtoupper($type) . " JOIN $table ON $on";
+ return $this;
+ }
+
+ //Like
+ //사용예:
+ // $model->like(['name' => '%홍%', 'email' => '%@naver.com%']);
+ // $model->likeIn(['title', 'description'], '%공지%');
+ // $model->orLikeIn(['name', 'nickname'], '%철수%');
+ public function like(array|string $column, ?string $value = null, string $operator = 'LIKE', string $boolean = "AND"): static
+ {
+ if (is_array($column)) {
+ $conditions = [];
+ foreach ($column as $col => $val) {
+ $placeholder = ':l_' . count($this->bindings);
+ $conditions[] = "$col $operator $placeholder";
+ $this->bindings[$placeholder] = $val;
+ }
+ $this->where[] = '(' . implode(" $boolean ", $conditions) . ')';
+ } else {
+ $placeholder = ':l_' . count($this->bindings);
+ $condition = "$column $operator $placeholder";
+ if (empty($this->where)) {
+ $this->where[] = $condition;
+ } else {
+ $last = array_pop($this->where);
+ $this->where[] = "($last $boolean $condition)";
+ }
+ $this->bindings[$placeholder] = $value;
+ }
+ return $this;
+ }
+ public function orLike(array|string $column, ?string $value = null, string $operator = 'LIKE', string $boolean = "OR"): static
+ {
+ return $this->like($column, $value, $operator, $boolean);
+ }
+
+ public function likeIn(array $columns, string $value, string $operator = "LIKE", string $boolean = "AND"): static
+ {
+ $orConditions = [];
+ foreach ($columns as $col) {
+ $placeholder = ':li_' . count($this->bindings);
+ $orConditions[] = "$col $operator $placeholder";
+ $this->bindings[$placeholder] = $value;
+ }
+ $this->where[] = '(' . implode(" $boolean ", $orConditions) . ')';
+ return $this;
+ }
+ public function orLikeIn(array $columns, string $value, string $operator = "LIKE", string $boolean = "OR"): static
+ {
+ return $this->likeIn($columns, $value, $operator, $boolean);
+ }
+ public function notLikeIn(array $columns, string $value, string $operator = "NOT LIKE", string $boolean = "AND"): static
+ {
+ return $this->likeIn($columns, $value, $operator, $boolean);
+ }
+
+ //Order
+ final public function orderBy(mixed $column, string $direction = 'ASC'): static
+ {
+ if (is_array($column)) {
+ // 배열 형식의 여러 컬럼 정렬을 처리
+ foreach ($column as $col => $dir) {
+ // 배열 키가 컬럼 이름이고 값이 방향임
+ $this->order[] = "$col $dir";
+ }
+ } else {
+ // 단일 컬럼에 대한 정렬
+ $this->order[] = "$column $direction";
+ }
+ return $this;
+ }
+ //Limit부분
+ final public function limit(int $limit): static
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+ final public function offset(int $offset): static
+ {
+ $this->offset = $offset;
+ return $this;
+ }
+
+ //Customer SQL 실행부분
+ final public function raw(string $sql, array $bindings = []): array
+ {
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($bindings as $key => $value) {
+ $stmt->bindValue(is_int($key) ? $key + 1 : $key, $value);
+ }
+ $stmt->execute();
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+
+ //Result부분
+ //binding까지 완료한 SQL문을 return함
+ final public function toRawSql(?string $select = null): string
+ {
+ $raw = $this->buildSelectSql($select);
+ foreach ($this->bindings as $key => $value) {
+ $escaped = is_numeric($value) ? $value : $this->pdo->quote($value);
+ // 명명된 바인딩
+ if (str_starts_with($key, ':')) {
+ $raw = str_replace($key, $escaped, $raw);
+ } else {
+ // 물음표 바인딩인 경우 (whereIn 등)
+ $raw = preg_replace('/\?/', $escaped, $raw, 1);
+ }
+ }
+ return $raw;
+ }
+ private function execute(?string $select = null): PDOStatement
+ {
+ if ($this->_debug) {
+ echo php_sapi_name() === 'cli'
+ ? "\nSQL DEBUG: " . $this->toRawSql($select) . "\n"
+ : "
SQL DEBUG: " . $this->toRawSql($select) . " ";
+ }
+ $this->latestQuery = $this->toRawSql();
+ $stmt = $this->pdo->prepare($this->buildSelectSql($select));
+ foreach ($this->bindings as $key => $value) {
+ $stmt->bindValue($key, $value);
+ }
+ $stmt->execute();
+ return $stmt;
+ }
+ final public function get(?string $select = null): array
+ {
+ $stmt = $this->execute($select);
+ if (!$this->_continue) {
+ $this->where = [];
+ $this->bindings = [];
+ }
+ $this->setContinue(false);
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+ final public function first(): ?array
+ {
+ $this->limit = 1;
+ $results = $this->get();
+ return $results[0] ?? null;
+ }
+ final public function count(string $select = "COUNT(*) as cnt"): int
+ {
+ $results = $this->get($select);
+ return (int)($results[0]['cnt'] ?? 0);
+ }
+
+ //CUD부분
+ final public function insert(array $data): bool|int
+ {
+ $columns = [];
+ $placeholders = [];
+ $this->bindings = [];
+
+ foreach ($data as $col => $val) {
+ $safePlaceholder = ':i_' . count($this->bindings);
+ if ($val === null) {
+ // null 값인 경우 SQL 조각으로 처리
+ $placeholders[] = $col;
+ } else {
+ $columns[] = $col;
+ $placeholders[] = $safePlaceholder;
+ $this->bindings[$safePlaceholder] = $val;
+ }
+ }
+
+ $columnsSql = $columns ? '(' . implode(', ', $columns) . ')' : '';
+ $placeholdersSql = '(' . implode(', ', $placeholders) . ')';
+
+ $sql = "INSERT INTO {$this->table} {$columnsSql} VALUES {$placeholdersSql}";
+
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($this->bindings as $key => $value) {
+ $stmt->bindValue($key, $value);
+ }
+
+ $result = $stmt->execute();
+ return $result && $stmt->rowCount() > 0 ? (int)$this->pdo->lastInsertId() : false;
+ }
+
+ final public function update(array $data): bool
+ {
+ if (empty($this->where)) {
+ throw new \Exception(__FUNCTION__ . " 구문은 WHERE절 없이 사용할수 없습니다.");
+ }
+
+ $setParts = [];
+ foreach ($data as $col => $val) {
+ if ($val === null) {
+ // 값이 null이면 $col을 SQL로 직접 사용
+ $setParts[] = $col;
+ } else {
+ $placeholder = ':u_' . preg_replace('/\W+/', '_', $col); // 안전한 placeholder 이름
+ $setParts[] = "$col = $placeholder";
+ $this->bindings[$placeholder] = $val;
+ }
+ }
+
+ $sql = "UPDATE {$this->table} SET " . implode(', ', $setParts)
+ . " WHERE " . $this->buildWhereSql(); // <<< 수정된 부분
+
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($this->bindings as $k => $v) {
+ $stmt->bindValue($k, $v);
+ }
+ return $stmt->execute();
+ }
+
+ final public function delete(): bool
+ {
+ if (empty($this->where)) {
+ throw new \Exception("DELETE 문에는 WHERE 절이 반드시 필요합니다.");
+ }
+
+ $sql = "DELETE FROM {$this->table} WHERE " . $this->buildWhereSql();
+
+ $stmt = $this->pdo->prepare($sql);
+ foreach ($this->bindings as $key => $value) {
+ $stmt->bindValue($key, $value);
+ }
+
+ return $stmt->execute();
+ }
+
+ //transaction관련련
+ final public function beginTransaction(): void
+ {
+ $this->pdo->beginTransaction();
+ }
+
+ final public function commit(): void
+ {
+ $this->pdo->commit();
+ }
+
+ final public function rollBack(): void
+ {
+ if ($this->pdo->inTransaction()) {
+ $this->pdo->rollBack();
+ }
+ }
+}
diff --git a/extdbms/lib/Core/Entity.php b/extdbms/lib/Core/Entity.php
new file mode 100644
index 0000000..53e2b7c
--- /dev/null
+++ b/extdbms/lib/Core/Entity.php
@@ -0,0 +1,24 @@
+_values = $datas;
+ } //
+ final public function __get($name)
+ {
+ return $this->_values[$name];
+ }
+ final public function __set($name, $value)
+ {
+ $this->_values[$name] = $value;
+ }
+ final public function toArray(): array
+ {
+ return $this->_values;
+ }
+} //Class
diff --git a/extdbms/lib/Core/Helper.php b/extdbms/lib/Core/Helper.php
new file mode 100644
index 0000000..83c4a4e
--- /dev/null
+++ b/extdbms/lib/Core/Helper.php
@@ -0,0 +1,8 @@
+getHeader('Authorization');
+ if ($header && str_starts_with($header, 'Bearer ')) {
+ return substr($header, 7);
+ }
+ return null;
+ }
+}
diff --git a/extdbms/lib/Core/Http/Cookie.php b/extdbms/lib/Core/Http/Cookie.php
new file mode 100644
index 0000000..3153259
--- /dev/null
+++ b/extdbms/lib/Core/Http/Cookie.php
@@ -0,0 +1,25 @@
+headers;
+ }
+
+ public function getHeader(string $key): ?string
+ {
+ return $this->headers[$key] ?? null;
+ }
+}
diff --git a/extdbms/lib/Core/Http/Redirect.php b/extdbms/lib/Core/Http/Redirect.php
new file mode 100644
index 0000000..b41007a
--- /dev/null
+++ b/extdbms/lib/Core/Http/Redirect.php
@@ -0,0 +1,52 @@
+session = $session;
+ }
+
+ // 리다이렉트할 때 캐시를 방지하는 헤더 추가
+ private function noCacheHeaders(): void
+ {
+ header("Cache-Control: no-cache, no-store, must-revalidate");
+ header("Pragma: no-cache");
+ header("Expires: 0");
+ }
+
+ // 이전 페이지로 리다이렉트 (캐시 방지)
+ public function back(): self
+ {
+ $this->noCacheHeaders(); // 캐시 방지
+ $backUrl = $_SERVER['HTTP_REFERER'] ?? '/';
+ header("Location: {$backUrl}");
+ return $this;
+ }
+
+ // 특정 URL로 리다이렉트 (캐시 방지)
+ public function to(string $url): self
+ {
+ $this->noCacheHeaders(); // 캐시 방지
+ header("Location: {$url}");
+ return $this;;
+ }
+
+ // 세션에 값 추가 후 리다이렉트
+ public function withInput(): self
+ {
+ $this->session->flashInput($_POST);
+ return $this;
+ }
+
+ // 세션에 에러 메시지 저장 후 리다이렉트
+ public function with(string $key, mixed $value): self
+ {
+ $this->session->flash($key, $value);
+ return $this;
+ }
+}
diff --git a/extdbms/lib/Core/Http/Request.php b/extdbms/lib/Core/Http/Request.php
new file mode 100644
index 0000000..4f7ff96
--- /dev/null
+++ b/extdbms/lib/Core/Http/Request.php
@@ -0,0 +1,67 @@
+_datas = array_merge($_GET, $_POST, $params);
+ }
+
+ public function all(): array
+ {
+ return $this->_datas;
+ }
+
+ public function get(?string $key = null, $default = null): mixed
+ {
+ if ($key === null) {
+ return $this->all();
+ }
+ return $this->_datas[$key] ?? $default;
+ }
+
+ public function only(array $keys): array
+ {
+ return array_intersect_key($this->_datas, array_flip($keys));
+ }
+
+ public function has(string $key): bool
+ {
+ return array_key_exists($key, $this->_datas);
+ }
+
+ /**
+ * Validator 연동
+ */
+ //사용예:
+ // $request = new Request();
+
+ // $validation = $request->validate([
+ // 'username' => 'required|alpha_numeric|min[4]',
+ // 'email' => 'required|email',
+ // 'password' => 'required|min[6]'
+ // ]);
+
+ // if ($validation !== true) {
+ // // 에러 처리
+ // print_r($validation);
+ // } else {
+ // // 통과
+ // echo "유효성 검사 통과!";
+ // }
+ public function validate(array $rules, array $messages = []): bool|array
+ {
+ $validator = new Validator();
+ $validator->setData($this->all())->setRules($rules)->setMessages($messages);
+
+ if (!$validator->run()) {
+ return $validator->errors();
+ }
+
+ return true;
+ }
+}
diff --git a/extdbms/lib/Core/Http/Response.php b/extdbms/lib/Core/Http/Response.php
new file mode 100644
index 0000000..a6a3d11
--- /dev/null
+++ b/extdbms/lib/Core/Http/Response.php
@@ -0,0 +1,32 @@
+init();
+ }
+
+ // 세션 시작
+ public function init(): void
+ {
+ if (session_status() === PHP_SESSION_NONE) {
+ if (!is_dir(APP_SESSION_PATH)) {
+ mkdir(APP_SESSION_PATH, APP_SESSION_PERMISSION, true);
+ }
+ session_save_path(APP_SESSION_PATH);
+ session_start();
+ }
+ }
+
+ // 세션에 값 저장
+ public function set(string $key, $value): void
+ {
+ $_SESSION[$key] = $value;
+ }
+
+ // 세션에서 값 가져오기
+ public function get(string $key): mixed
+ {
+ return $_SESSION[$key] ?? null;
+ }
+
+ // 세션에서 값 삭제
+ public function remove(string $key): void
+ {
+ unset($_SESSION[$key]);
+ }
+
+ // 세션에 에러 메시지 설정
+ public function flash(string $key, $message): void
+ {
+ $_SESSION['flash'][$key] = $message;
+ }
+
+ // 세션에 입력값 설정 (입력값 유지)
+ public function flashInput(array $input): void
+ {
+ $_SESSION['flash']['input'] = $input;
+ }
+
+ // 세션에 flash 메시지가 있는지 확인
+ public function hasFlash(string $key): bool
+ {
+ return isset($_SESSION['flash'][$key]);
+ }
+
+ // flash 메시지 가져오기
+ public function getFlash(string $key): mixed
+ {
+ return $_SESSION['flash'][$key] ?? null;
+ }
+
+ // flash 메시지 삭제
+ public function clearFlash(): void
+ {
+ unset($_SESSION['flash']);
+ }
+}
diff --git a/extdbms/lib/Core/Http/Url.php b/extdbms/lib/Core/Http/Url.php
new file mode 100644
index 0000000..77ff698
--- /dev/null
+++ b/extdbms/lib/Core/Http/Url.php
@@ -0,0 +1,103 @@
+baseUrl = $this->detectBaseUrl();
+ $this->uri = $this->detectUri();
+ }
+
+ // 현재 전체 URL 반환
+ public function current(): string
+ {
+ return $this->baseUrl . '/' . ltrim($this->uri, '/');
+ }
+
+ // base URL만 반환
+ public function base(): string
+ {
+ return $this->baseUrl;
+ }
+
+ // 세그먼트 배열 반환
+ public function segments(): array
+ {
+ return explode('/', trim($this->uri, '/'));
+ }
+
+ // N번째 세그먼트 반환 (1부터 시작)
+ public function segment(int $n): ?string
+ {
+ $segments = $this->segments();
+ return $segments[$n - 1] ?? null;
+ }
+
+ // 특정 경로에 대한 URL 생성
+ public function to(string $path): string
+ {
+ return rtrim($this->baseUrl, '/') . '/' . ltrim($path, '/');
+ }
+
+ // URI 추출 (도메인 제외)
+ protected function detectUri(): string
+ {
+ $uri = $_SERVER['REQUEST_URI'] ?? '/';
+ $scriptName = dirname($_SERVER['SCRIPT_NAME'] ?? '');
+ $uri = str_replace($scriptName, '', $uri);
+ $uri = strtok($uri, '?'); // 쿼리 스트링 제거
+ return $uri;
+ }
+
+ // base URL 추출
+ protected function detectBaseUrl(): string
+ {
+ $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
+ $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
+ $scriptDir = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/');
+ return $scheme . '://' . $host . $scriptDir;
+ }
+
+ public static function baseUrl(): string
+ {
+ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
+ $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
+ $script = str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
+
+ return rtrim($protocol . $host . $script, '/');
+ }
+
+ public static function currentUrl(): string
+ {
+ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
+ $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
+ $uri = $_SERVER['REQUEST_URI'] ?? '';
+
+ return $protocol . $host . $uri;
+ }
+
+ public static function previousUrl(): ?string
+ {
+ return $_SERVER['HTTP_REFERER'] ?? null;
+ }
+
+ public static function urlIs(string $pattern): bool
+ {
+ $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
+ $pattern = str_replace('*', '.*', preg_quote($pattern, '/'));
+ return preg_match("/^{$pattern}$/", $uri) === 1;
+ }
+
+ public static function getSegment(int $index): ?string
+ {
+ $uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
+ $segments = explode('/', $uri);
+ return $segments[$index - 1] ?? null;
+ }
+}
diff --git a/extdbms/lib/Core/Http/Validator.php b/extdbms/lib/Core/Http/Validator.php
new file mode 100644
index 0000000..b092527
--- /dev/null
+++ b/extdbms/lib/Core/Http/Validator.php
@@ -0,0 +1,153 @@
+setData([
+// 'username' => 'admin123',
+// 'email' => 'admin@example.com',
+// 'password' => '1234'
+// ])->setRules([
+// 'username' => 'required|alpha_numeric|min[4]|max[20]',
+// 'email' => 'required|email',
+// 'password' => 'required|min[6]'
+// ]);
+
+// if (!$validator->run()) {
+// print_r($validator->errors());
+// }
+
+class Validator extends Http
+{
+ protected array $data = [];
+ protected array $rules = [];
+ protected array $errors = [];
+ protected array $customMessages = [];
+
+ protected array $availableRules = [
+ 'required',
+ 'min',
+ 'max',
+ 'email',
+ 'numeric',
+ 'alpha',
+ 'alpha_numeric'
+ ];
+
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+ public function setData(array $data): self
+ {
+ $this->data = $data;
+ return $this;
+ }
+
+ public function setRules(array $rules): self
+ {
+ $this->rules = $rules;
+ return $this;
+ }
+
+ public function setMessages(array $messages): self
+ {
+ $this->customMessages = $messages;
+ return $this;
+ }
+
+ public function run(): bool
+ {
+ $this->errors = [];
+
+ foreach ($this->rules as $field => $ruleStr) {
+ $rules = explode('|', $ruleStr);
+ $value = $this->data[$field] ?? null;
+
+ foreach ($rules as $rule) {
+ $param = null;
+ if (strpos($rule, '[') !== false) {
+ preg_match('/(\w+)\[(.*?)\]/', $rule, $matches);
+ $rule = $matches[1];
+ $param = $matches[2];
+ }
+
+ $method = "validate_$rule";
+ if (method_exists($this, $method)) {
+ $result = $this->$method($value, $param);
+ if (!$result) {
+ $this->addError($field, $rule, $param);
+ }
+ }
+ }
+ }
+
+ return empty($this->errors);
+ }
+
+ public function errors(): array
+ {
+ return $this->errors;
+ }
+
+ protected function addError(string $field, string $rule, $param = null): void
+ {
+ $message = $this->customMessages["$field.$rule"] ?? $this->defaultMessage($field, $rule, $param);
+ $this->errors[$field][] = $message;
+ }
+
+ protected function defaultMessage(string $field, string $rule, $param): string
+ {
+ return match ($rule) {
+ 'required' => "$field is required.",
+ 'min' => "$field must be at least $param characters.",
+ 'max' => "$field must be at most $param characters.",
+ 'email' => "$field must be a valid email address.",
+ 'numeric' => "$field must be a number.",
+ 'alpha' => "$field must contain only letters.",
+ 'alpha_numeric' => "$field must contain only letters and numbers.",
+ default => "$field is invalid.",
+ };
+ }
+
+ // --- 기본 유효성 검사 메서드 ---
+ protected function validate_required($value): bool
+ {
+ return !empty($value) || $value === '0';
+ }
+
+ protected function validate_min($value, $param): bool
+ {
+ return strlen($value) >= (int)$param;
+ }
+
+ protected function validate_max($value, $param): bool
+ {
+ return strlen($value) <= (int)$param;
+ }
+
+ protected function validate_email($value): bool
+ {
+ return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
+ }
+
+ protected function validate_numeric($value): bool
+ {
+ return is_numeric($value);
+ }
+
+ protected function validate_alpha($value): bool
+ {
+ return ctype_alpha($value);
+ }
+
+ protected function validate_alpha_numeric($value): bool
+ {
+ return ctype_alnum($value);
+ }
+
+ // 사용자 정의 규칙도 등록할 수 있도록 향후 확장 가능
+}
diff --git a/extdbms/lib/Core/Logger.php b/extdbms/lib/Core/Logger.php
new file mode 100644
index 0000000..e290809
--- /dev/null
+++ b/extdbms/lib/Core/Logger.php
@@ -0,0 +1,49 @@
+logPath = rtrim($logDir, DIRECTORY_SEPARATOR);
+ if (!is_dir($this->logPath)) {
+ mkdir($this->logPath, APP_LOG_PERMISSION, true);
+ }
+ }
+
+ public function log(string $message, string $level = 'INFO'): void
+ {
+ $filename = date('Y-m-d') . '.log';
+ $filepath = "{$this->logPath}/{$filename}";
+ $time = date('Y-m-d H:i:s');
+
+ $formatted = "[{$time}] [{$level}] {$message}\n";
+
+ file_put_contents($filepath, $formatted, FILE_APPEND);
+ }
+
+ public function info(string $message): void
+ {
+ $this->log($message, 'INFO');
+ }
+
+ public function error(string $message): void
+ {
+ $this->log($message, 'ERROR');
+ }
+
+ public function warning(string $message): void
+ {
+ $this->log($message, 'WARNING');
+ }
+
+ public function debug(string $message): void
+ {
+ if (defined('APP_DEBUG') && APP_DEBUG) {
+ $this->log($message, 'DEBUG');
+ }
+ }
+}
diff --git a/extdbms/lib/Core/Middlewares/AuthMiddleware.php b/extdbms/lib/Core/Middlewares/AuthMiddleware.php
new file mode 100644
index 0000000..be80bfb
--- /dev/null
+++ b/extdbms/lib/Core/Middlewares/AuthMiddleware.php
@@ -0,0 +1,19 @@
+ 'Unauthorized'], 401);
+ return;
+ }
+ return $next($params);
+ }
+}
diff --git a/extdbms/lib/Core/Middlewares/MiddlewareInterface.php b/extdbms/lib/Core/Middlewares/MiddlewareInterface.php
new file mode 100644
index 0000000..7d03387
--- /dev/null
+++ b/extdbms/lib/Core/Middlewares/MiddlewareInterface.php
@@ -0,0 +1,8 @@
+getTable());
+ parent::setDebug($_ENV['DATABASE_QUERY_DEBUG'] ?? $_SERVER['DATABASE_QUERY_DEBUG'] ?? false);
+ }
+
+ abstract public function getTable(): string;
+ abstract public function getPKField(): string;
+ abstract public function getTitleField(): string;
+}
diff --git a/extdbms/lib/Core/Router.php b/extdbms/lib/Core/Router.php
new file mode 100644
index 0000000..f4ccf7a
--- /dev/null
+++ b/extdbms/lib/Core/Router.php
@@ -0,0 +1,133 @@
+currentGroupPrefix . '/' . trim($path, '/'), '/');
+
+ $route = [
+ 'method' => strtoupper($method),
+ 'path' => $fullPath,
+ 'callback' => $callback,
+ 'middlewares' => array_merge($this->currentGroupMiddlewares, $middlewares)
+ ];
+
+ // 동적 파라미터({param})가 있으면 정규식 패턴 생성
+ if (strpos($fullPath, '{') !== false) {
+ $pattern = preg_replace_callback('/\{(\w+)\}/', function ($matches) {
+ return '(?P<' . $matches[1] . '>[^/]+)';
+ }, $fullPath);
+ $route['pattern'] = '/^' . str_replace('/', '\/', $pattern) . '(\/.*)?$/';
+ } else {
+ // SEO key/value 형태를 위해 접두사 이후의 추가 파라미터를 허용
+ $route['pattern'] = '/^' . str_replace('/', '\/', $fullPath) . '(\/(?P.*))?$/';
+ }
+
+ $this->routes[] = $route;
+ }
+
+ /**
+ * 라우트 그룹: 공통 접두사와 공통 미들웨어를 적용
+ */
+ public function group(string $prefix, callable $callback, array $middlewares = []): void
+ {
+ $previousGroupPrefix = $this->currentGroupPrefix;
+ $previousGroupMiddlewares = $this->currentGroupMiddlewares;
+
+ $this->currentGroupPrefix = trim($previousGroupPrefix . '/' . trim($prefix, '/'), '/');
+ $this->currentGroupMiddlewares = array_merge($previousGroupMiddlewares, $middlewares);
+
+ $callback($this);
+
+ $this->currentGroupPrefix = $previousGroupPrefix;
+ $this->currentGroupMiddlewares = $previousGroupMiddlewares;
+ }
+
+ /**
+ * 라우트 매칭 및 실행
+ */
+ public function dispatch(string $uri, string $method = 'GET'): void
+ {
+ $uri = trim(parse_url($uri, PHP_URL_PATH), '/');
+
+ // 정적 파일 처리: public 폴더 내에 파일이 있으면 직접 서빙
+ $staticFile = __DIR__ . '/../../public/' . $uri;
+ if (file_exists($staticFile) && is_file($staticFile)) {
+ $this->serveStaticFile($staticFile);
+ return;
+ }
+ foreach ($this->routes as $route) {
+ if ($route['method'] !== strtoupper($method)) {
+ continue;
+ }
+ if (preg_match($route['pattern'], $uri, $matches)) {
+ $params = [];
+
+ // 패턴에 named 그룹이 있다면 추출
+ foreach ($matches as $key => $value) {
+ if (is_string($key)) {
+ $params[$key] = $value;
+ }
+ }
+ //추가 SEO key/value 파라미터로 파싱
+ if (isset($params['extra']) && $params['extra'] !== '') {
+ $extra = trim($params['extra'], '/');
+ $extraSegments = explode('/', $extra);
+ // 짝수개여야 key/value 쌍으로 변환 가능
+ if (count($extraSegments) % 2 === 0) {
+ for ($i = 0; $i < count($extraSegments); $i += 2) {
+ $key = $extraSegments[$i];
+ $value = $extraSegments[$i + 1];
+ $params[$key] = $value;
+ }
+ }
+ unset($params['extra']);
+ } else {
+ // 패턴에 extra 그룹이 없으면, 기본 GET 파라미터와 병합
+ $params = array_merge($_GET, $params);
+ }
+ $this->handle($route, $params);
+ return;
+ }
+ }
+ http_response_code(404);
+ echo "해당 Controller나 함수를 찾을수없습니다.";
+ }
+
+ /**
+ * 미들웨어 체인을 거쳐 최종 콜백 실행
+ */
+ private function handle(array $route, array $params): void
+ {
+ $handler = $route['callback'];
+ $middlewares = $route['middlewares'];
+
+ $pipeline = array_reduce(
+ array_reverse($middlewares),
+ fn($next, $middleware) => fn($params) => (new $middleware)->handle($params, $next),
+ $handler
+ );
+ $pipeline($params);
+ }
+
+ /**
+ * 정적 파일 서빙 (이미지, CSS, JS 등)
+ */
+ private function serveStaticFile(string $file): void
+ {
+ $mimeType = mime_content_type($file);
+ header('Content-Type: ' . $mimeType);
+ readfile($file);
+ }
+}
diff --git a/extdbms/lib/Core/Service.php b/extdbms/lib/Core/Service.php
new file mode 100644
index 0000000..834fa20
--- /dev/null
+++ b/extdbms/lib/Core/Service.php
@@ -0,0 +1,8 @@
+totalItems = $totalItems;
+ $this->perPage = $perPage;
+ $this->currentPage = max(1, $currentPage);
+ $this->totalPages = (int)ceil($totalItems / $perPage);
+ $this->start = ($this->currentPage - 1) * $perPage;
+ $this->end = min($this->start + $perPage, $totalItems);
+ $this->groupSize = intval(VIEW_LIST_PAGINATION_GROUPSIZE);
+ }
+
+ public function hasPrevious(): bool
+ {
+ return $this->currentPage > 1;
+ }
+
+ public function hasNext(): bool
+ {
+ return $this->currentPage < $this->totalPages;
+ }
+
+ public function previousPage(): int
+ {
+ return max(1, $this->currentPage - 1);
+ }
+
+ public function nextPage(): int
+ {
+ return min($this->totalPages, $this->currentPage + 1);
+ }
+
+ public function getOffset(): int
+ {
+ return $this->start;
+ }
+
+ public function getLimit(): int
+ {
+ return $this->perPage;
+ }
+
+ public function toArray(): array
+ {
+ return [
+ 'current_page' => $this->currentPage,
+ 'per_page' => $this->perPage,
+ 'total_items' => $this->totalItems,
+ 'total_pages' => $this->totalPages,
+ 'has_previous' => $this->hasPrevious(),
+ 'has_next' => $this->hasNext(),
+ 'previous_page' => $this->previousPage(),
+ 'next_page' => $this->nextPage(),
+ 'offset' => $this->getOffset(),
+ 'limit' => $this->getLimit(),
+ ];
+ }
+
+ public function render(string $baseUrl = '', array $query = []): string
+ {
+ if ($this->totalPages <= 1) {
+ return '';
+ }
+
+ $html = ' ';
+ return $html;
+ }
+ private function pageLink(int $page, string $label, string $baseUrl, array $query): string
+ {
+ $query['curPage'] = $page;
+ $url = $baseUrl . '?' . http_build_query($query);
+ return '' . $label . ' ';
+ }
+}
diff --git a/extdbms/lib/Core/View.php b/extdbms/lib/Core/View.php
new file mode 100644
index 0000000..0800ca3
--- /dev/null
+++ b/extdbms/lib/Core/View.php
@@ -0,0 +1,41 @@
+_values[$name];
+ }
+ final public function __set($name, $value)
+ {
+ $this->_values[$name] = $value;
+ }
+ final public function setPath(string $path): void
+ {
+ $this->_paths[] = $path;
+ }
+ final public function setPaths(array $paths): void
+ {
+ $this->_paths[] = $paths;
+ }
+ final public function getPath(): array
+ {
+ return $this->_paths;
+ }
+ public function render($file)
+ {
+ $path = count($this->getPath()) ? DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $this->getPath()) : "";
+ $fullPathFile = ROOT_PATH . $path . DIRECTORY_SEPARATOR . $file . ".php";
+ if (!file_exists($fullPathFile)) {
+ throw new \Exception(sprintf("%s 파일이 존재하지 않습니다.", $fullPathFile));
+ }
+ ob_start();
+ require_once $fullPathFile;
+ return ob_end_flush();
+ }
+} //Class
diff --git a/extdbms/lib/Entities/AddDbEntity.php b/extdbms/lib/Entities/AddDbEntity.php
new file mode 100644
index 0000000..b305c49
--- /dev/null
+++ b/extdbms/lib/Entities/AddDbEntity.php
@@ -0,0 +1,20 @@
+service_code;
+ }
+} //Class
diff --git a/extdbms/lib/Entities/ClientEntity.php b/extdbms/lib/Entities/ClientEntity.php
new file mode 100644
index 0000000..7604882
--- /dev/null
+++ b/extdbms/lib/Entities/ClientEntity.php
@@ -0,0 +1,37 @@
+Client_Code;
+ }
+ public function getPhone(string $field = "", string $delimeter = ","): string
+ {
+ return $field ? $this->$field : "{$this->Client_Phone1} {$delimeter} {$this->Client_Phone2}";
+ }
+ public function getEmail(string $field = "", string $delimeter = ","): string
+ {
+ return $field ? $this->$field : "{$this->Client_EMail1} {$delimeter} {$this->Client_EMail2}";
+ }
+ public function getNote(): string
+ {
+ return $this->Client_Note;
+ }
+ public function getPoint(): string
+ {
+ return $this->Client_Point;
+ }
+} //Class
diff --git a/extdbms/lib/Entities/CommonEntity.php b/extdbms/lib/Entities/CommonEntity.php
new file mode 100644
index 0000000..3062949
--- /dev/null
+++ b/extdbms/lib/Entities/CommonEntity.php
@@ -0,0 +1,33 @@
+$field;
+ }
+ public function getTitle(): string
+ {
+ $field = constant("static::TitleField");
+ return $this->$field;
+ }
+ public function getPairKey(): string
+ {
+ $field = constant("static::PairField");
+ return $this->$field;
+ }
+ public function getCreatedAt(): string
+ {
+ return $this->created_at;
+ } //
+ //공통부분
+} //Class
diff --git a/extdbms/lib/Entities/DefenceEntity.php b/extdbms/lib/Entities/DefenceEntity.php
new file mode 100644
index 0000000..44cef5d
--- /dev/null
+++ b/extdbms/lib/Entities/DefenceEntity.php
@@ -0,0 +1,34 @@
+getTitle();
+ } //
+ public function getParent(): string
+ {
+ return $this->parents;
+ } //
+ public function getChild(): string
+ {
+ return $this->child;
+ } //
+ public function getRealAddress(): string
+ {
+ return $this->real_address;
+ } //
+} //Class
diff --git a/extdbms/lib/Entities/GearlistEntity.php b/extdbms/lib/Entities/GearlistEntity.php
new file mode 100644
index 0000000..eb890fe
--- /dev/null
+++ b/extdbms/lib/Entities/GearlistEntity.php
@@ -0,0 +1,33 @@
+process;
+ } //
+ public function getSpec(): string
+ {
+ return $this->spec;
+ } //
+ public function getCPUName(): string
+ {
+ return $this->cpuname;
+ } //
+ public function getPrice(): string
+ {
+ return $this->price;
+ } //
+} //Class
diff --git a/extdbms/lib/Entities/HistoryEntity.php b/extdbms/lib/Entities/HistoryEntity.php
new file mode 100644
index 0000000..863f4d4
--- /dev/null
+++ b/extdbms/lib/Entities/HistoryEntity.php
@@ -0,0 +1,25 @@
+service_code;
+ }
+ public function getClientName(): string
+ {
+ return $this->client_name;
+ }
+} //Class
diff --git a/extdbms/lib/Entities/KCSEntity.php b/extdbms/lib/Entities/KCSEntity.php
new file mode 100644
index 0000000..86c1a57
--- /dev/null
+++ b/extdbms/lib/Entities/KCSEntity.php
@@ -0,0 +1,17 @@
+id;
+ }
+ public function getPassword(): string
+ {
+ return $this->pass;
+ }
+ public function getName(): string
+ {
+ return $this->name;
+ }
+ public function getRole(): string
+ {
+ return $this->role;
+ }
+} //Class
diff --git a/extdbms/lib/Entities/OnetimeEntity.php b/extdbms/lib/Entities/OnetimeEntity.php
new file mode 100644
index 0000000..992e328
--- /dev/null
+++ b/extdbms/lib/Entities/OnetimeEntity.php
@@ -0,0 +1,50 @@
+service_code;
+ }
+ public function getMemberCode(): string
+ {
+ return $this->onetime_manager;
+ }
+ public function getClientCode(): string
+ {
+ return $this->client_code;
+ }
+ public function getAmount(): string
+ {
+ return $this->onetime_amount;
+ }
+ public function getNonPayment(): string
+ {
+ return $this->onetime_nonpayment;
+ }
+ public function getRequestDate(): string
+ {
+ return $this->onetime_request_date;
+ }
+ public function getPaymentDate(): string
+ {
+ return $this->onetime_payment_date;
+ }
+ public function getNote(): string
+ {
+ return $this->onetime_note;
+ }
+} //Class
diff --git a/extdbms/lib/Entities/PointEntity.php b/extdbms/lib/Entities/PointEntity.php
new file mode 100644
index 0000000..de54f4d
--- /dev/null
+++ b/extdbms/lib/Entities/PointEntity.php
@@ -0,0 +1,34 @@
+client_code;
+ } //
+
+ public function getType(): string
+ {
+ return $this->type;
+ } //
+ public function getAmount(): string
+ {
+ return $this->amount;
+ } //
+ public function getNote(): string
+ {
+ return $this->note;
+ } //
+} //Class
diff --git a/extdbms/lib/Entities/ServerEntity.php b/extdbms/lib/Entities/ServerEntity.php
new file mode 100644
index 0000000..9b75ee4
--- /dev/null
+++ b/extdbms/lib/Entities/ServerEntity.php
@@ -0,0 +1,25 @@
+server_code;
+ }
+ public function getServiceCode(): string
+ {
+ return $this->service_code;
+ }
+} //Class
diff --git a/extdbms/lib/Entities/ServiceEntity.php b/extdbms/lib/Entities/ServiceEntity.php
new file mode 100644
index 0000000..2a46d9e
--- /dev/null
+++ b/extdbms/lib/Entities/ServiceEntity.php
@@ -0,0 +1,42 @@
+service_code;
+ }
+ public function getServerCode(): string
+ {
+ return $this->server_code;
+ }
+ public function getMemberCode(): string
+ {
+ return $this->service_manager;
+ }
+ public function getClientCode(): string
+ {
+ return $this->client_code;
+ }
+ public function getCoupon(): string
+ {
+ return $this->coupon;
+ }
+ public function getUsedCoupon(): string
+ {
+ return $this->coupon_use;
+ }
+} //Class
diff --git a/extdbms/lib/Entities/VPCEntity.php b/extdbms/lib/Entities/VPCEntity.php
new file mode 100644
index 0000000..b4e5466
--- /dev/null
+++ b/extdbms/lib/Entities/VPCEntity.php
@@ -0,0 +1,17 @@
+getRandomString($length, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?");
+ }
+
+ final function truncateString(string $text, int $maxLength = 10): string
+ {
+ if (mb_strlen($text, 'UTF-8') > $maxLength) {
+ return mb_substr($text, 0, $maxLength, 'UTF-8') . "...";
+ }
+ return $text;
+ }
+
+ // byte값을 알아보기 쉽게 변환
+ final public function getSizeForHuman($bytes)
+ {
+ $ext = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
+ $unitCount = 0;
+ for (; $bytes > 1024; $unitCount++) {
+ $bytes /= 1024;
+ }
+ return floor($bytes) . $ext[$unitCount];
+ }
+
+ // Proxy등을 통하여 Client_IP가 알수없는경우 실제사용자의 IP를 가져오기 위한것
+ final public function getClientIP($clientIP = false)
+ {
+ if (isset($_SERVER['HTTP_CLIENT_IP'])) {
+ $clientIP = $_SERVER['HTTP_CLIENT_IP'];
+ } else if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+ $clientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
+ } else if (isset($_SERVER['HTTP_X_FORWARDED'])) {
+ $clientIP = $_SERVER['HTTP_X_FORWARDED'];
+ } else if (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
+ $clientIP = $_SERVER['HTTP_FORWARDED_FOR'];
+ } else if (isset($_SERVER['HTTP_FORWARDED'])) {
+ $clientIP = $_SERVER['HTTP_FORWARDED'];
+ } else if (isset($_SERVER['REMOTE_ADDR'])) {
+ $clientIP = $_SERVER['REMOTE_ADDR'];
+ }
+ return $clientIP;
+ }
+
+ final public function isDomain(string $domain): bool
+ {
+ $pattern_validation = '/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/';
+ return preg_match($pattern_validation, $domain);
+ }
+
+ final public function isIPAddress(?string $ip = null, $type = 'ipv4'): bool
+ {
+ switch ($type) {
+ case 'ipv4':
+ $result = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
+ break;
+ case 'ipv6':
+ $result = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
+ break;
+ case 'all':
+ $result = filter_var($ip, FILTER_VALIDATE_IP);
+ break;
+ default:
+ $result = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
+ break;
+ }
+ return $result;
+ }
+
+ final public function isHost(string $host): bool
+ {
+ $pattern_validation = '/[a-zA-Z0-9\.\/\?\:@\*\-_=#]/';
+ return preg_match($pattern_validation, $host);
+ }
+
+ // (EX:192.168.1.0 -> 192.168.001.000)
+ final public function convertIPV4toCIDR($cidr)
+ {
+ $temps = explode(".", $cidr);
+ return sprintf("%03d.%03d.%03d.%03d", $temps[0], $temps[1], $temps[2], $temps[3]);
+ }
+
+ // (EX:192.168.001.0000 -> 192.168.1.0)
+ final public function convertCIDRtoIPV4($ipv4)
+ {
+ $temps = explode(".", $ipv4);
+ return sprintf("%d.%d.%d.%d", $temps[0], $temps[1], $temps[2], $temps[3]);
+ }
+
+ final public function isMobile()
+ {
+ // Check the server headers to see if they're mobile friendly
+ if (isset($_SERVER["HTTP_X_WAP_PROFILE"])) {
+ return true;
+ }
+ // If the http_accept header supports wap then it's a mobile too
+ if (preg_match("/wap\.|\.wap/i", $_SERVER["HTTP_ACCEPT"])) {
+ return true;
+ }
+ // Still no luck? Let's have a look at the user agent on the browser. If it contains
+ // any of the following, it's probably a mobile device. Kappow!
+ if (isset($_SERVER["HTTP_USER_AGENT"])) {
+ $user_agents = array("midp", "j2me", "avantg", "docomo", "novarra", "palmos", "palmsource", "240x320", "opwv", "chtml", "pda", "windows\ ce", "mmp\/", "blackberry", "mib\/", "symbian", "wireless", "nokia", "hand", "mobi", "phone", "cdm", "up\.b", "audio", "SIE\-", "SEC\-", "samsung", "HTC", "mot\-", "mitsu", "sagem", "sony", "alcatel", "lg", "erics", "vx", "NEC", "philips", "mmm", "xx", "panasonic", "sharp", "wap", "sch", "rover", "pocket", "benq", "java", "pt", "pg", "vox", "amoi", "bird", "compal", "kg", "voda", "sany", "kdd", "dbt", "sendo", "sgh", "gradi", "jb", "\d\d\di", "moto");
+ foreach ($user_agents as $user_string) {
+ if (preg_match("/" . $user_string . "/i", $_SERVER["HTTP_USER_AGENT"])) {
+ return true;
+ }
+ }
+ }
+ // Let's NOT return "mobile" if it's an iPhone, because the iPhone can render normal pages quite well.
+ if (preg_match("/iphone/i", $_SERVER["HTTP_USER_AGENT"])) {
+ return false;
+ }
+ // None of the above? Then it's probably not a mobile device.
+ return false;
+ }
+} //Class
diff --git a/extdbms/lib/Helpers/ServiceHelper.php b/extdbms/lib/Helpers/ServiceHelper.php
new file mode 100644
index 0000000..1b98297
--- /dev/null
+++ b/extdbms/lib/Helpers/ServiceHelper.php
@@ -0,0 +1,14 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+}
diff --git a/extdbms/lib/Services/ClientService.php b/extdbms/lib/Services/ClientService.php
new file mode 100644
index 0000000..3f7395b
--- /dev/null
+++ b/extdbms/lib/Services/ClientService.php
@@ -0,0 +1,54 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+
+ //사용자 포인트 입금
+ public function depositPoint(Entity $client, int $point): bool
+ {
+ if ($point < 0) {
+ throw new \Exception("포인트금액이 잘못되었습니다. 포인트 : $point");
+ }
+ $this->getModel()->where("Client_Code", $client->getClientCode());
+ $this->getModel()->update(["Client_Point=(Client_Point+{$point})" => null]);
+ return true;
+ }
+ //사용자 포인트 출금
+ public function withdrawalPoint(Entity $client, int $point): bool
+ {
+ if ($point < 0) {
+ throw new \Exception("포인트금액이 잘못되었습니다. 포인트 : $point");
+ }
+ if ($client->getPoint() < $point) {
+ throw new \Exception("포인트금액이 잘못되었습니다. 남은 포인트: " . $client->getPoint() . ", 포인트 : $point");
+ }
+ $this->getModel()->where("Client_Code", $client->getClientCode());
+ $this->getModel()->update(["Client_Point=(Client_Point-{$point})" => null]);
+ return true;
+ }
+}
diff --git a/extdbms/lib/Services/CommonService.php b/extdbms/lib/Services/CommonService.php
new file mode 100644
index 0000000..03735f2
--- /dev/null
+++ b/extdbms/lib/Services/CommonService.php
@@ -0,0 +1,89 @@
+_model === null) {
+ $modelClass = $this->getModelClass();
+ $this->_model = new $modelClass();
+ // $this->_model->setDebug(true);
+ }
+ return $this->_model;
+ }
+ final public function getEntity(): mixed
+ {
+ $result = $this->getModel()->first();
+ if (!$result) { //결과값이 없으면 null
+ return $result;
+ }
+ $entityClass = $this->getEntityClass();
+ return new $entityClass($result);
+ }
+ final public function getEntities(): array
+ {
+ $entitys = [];
+ foreach ($this->getModel()->get() as $result) {
+ $entityClass = $this->getEntityClass();
+ $entity = new $entityClass($result);
+ $pairField = $this->getModel()->getPairField();
+ $entitys[$entity->$pairField] = $entity;
+ }
+ return $entitys;
+ } //
+ final public function getCount(string $select = "COUNT(*) as cnt"): int
+ {
+ $count = $this->getModel()->count($select);
+ // echo " " . $this->getModel()->getLastQuery();
+ return $count;
+ }
+ final public function getList(int $curPage = 1, int $perPage = VIEW_LIST_PERPAGE): array
+ {
+ //Query문 Rest여부 -> 같은조건에 Count 받고, 결과값을 받고 싶을때는 continue()
+ $this->getModel()->setContinue(true);
+ $total = $this->getCount();
+ //limit, offset 설정
+ $this->getModel()->limit($perPage);
+ $this->getModel()->offset(($curPage - 1) * $perPage);
+ $entities = $this->getEntities();
+ return [$total, $entities];
+ }
+
+ protected function insert(array $formData): mixed
+ {
+ $insertId = $this->getModel()->insert($formData);
+ if (!$insertId) {
+ throw new \Exception("Insert Error : " . $this->getModel()->getLastError());
+ }
+ $entityClass = $this->getEntityClass();
+ $entity = new $entityClass($formData);
+ $pkField = $this->getModel()::PKFIELD;
+ $entity->$pkField = $insertId;
+ return $entity;
+ } //
+
+ //transaction관련련
+ final public function beginTransaction(): void
+ {
+ $this->getModel()->beginTransaction();
+ }
+ final public function commit(): void
+ {
+ $this->getModel()->commit();
+ }
+ final public function rollBack(): void
+ {
+ $this->getModel()->rollBack();
+ }
+} //Class
diff --git a/extdbms/lib/Services/DefenceService.php b/extdbms/lib/Services/DefenceService.php
new file mode 100644
index 0000000..ad54391
--- /dev/null
+++ b/extdbms/lib/Services/DefenceService.php
@@ -0,0 +1,30 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+}
diff --git a/extdbms/lib/Services/GearlistService.php b/extdbms/lib/Services/GearlistService.php
new file mode 100644
index 0000000..84f5681
--- /dev/null
+++ b/extdbms/lib/Services/GearlistService.php
@@ -0,0 +1,38 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+
+ public function getEntitiesForLineUp(): array
+ {
+ $this->getModel()->whereNotIn("process", DBMS_GEARLIST_PROCESS_TYPES);
+ $this->getModel()->whereNotIn("cpuname", DBMS_GEARLIST_CPU_TYPES);
+ $this->getModel()->orderBy(["process" => "ASC", "price" => "ASC", "cpuname" => "asc"]);
+ return $this->getEntities();
+ }
+}
diff --git a/extdbms/lib/Services/HistoryService.php b/extdbms/lib/Services/HistoryService.php
new file mode 100644
index 0000000..0897cd3
--- /dev/null
+++ b/extdbms/lib/Services/HistoryService.php
@@ -0,0 +1,47 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+ //도메인쿠폰 사용
+ public function useCouponByService(ServiceEntity $service, ClientEntity $client, string $onetime_case, int $coupon, string $note, string $onetime_request_date): bool
+ {
+ $formDatas = [
+ "service_code" => $service->getServiceCode(),
+ "server_code" => $service->getServerCode(),
+ "behavior_case" => $onetime_case,
+ "behavior" => "도메인 쿠폰 구매 / {$coupon} 개",
+ "behavior_date" => $onetime_request_date,
+ "note" => trim($note),
+ "client_name" => $client->getTitle()
+ ];
+ return $this->getModel()->insert($formDatas);
+ }
+}
diff --git a/extdbms/lib/Services/KCSService.php b/extdbms/lib/Services/KCSService.php
new file mode 100644
index 0000000..0698760
--- /dev/null
+++ b/extdbms/lib/Services/KCSService.php
@@ -0,0 +1,30 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+}
diff --git a/extdbms/lib/Services/MemberService.php b/extdbms/lib/Services/MemberService.php
new file mode 100644
index 0000000..ae201fa
--- /dev/null
+++ b/extdbms/lib/Services/MemberService.php
@@ -0,0 +1,30 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+}
diff --git a/extdbms/lib/Services/OnetimeService.php b/extdbms/lib/Services/OnetimeService.php
new file mode 100644
index 0000000..cfbab15
--- /dev/null
+++ b/extdbms/lib/Services/OnetimeService.php
@@ -0,0 +1,57 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+
+ //도메인쿠폰 사용용
+ public function useCouponByService(ServiceEntity $service, ClientEntity $client, MemberEntity $member, string $onetime_case, int $coupon, string $note, string $onetime_request_date): bool
+ {
+ $formDatas = [
+ "client_code" => $service->getClientCode(),
+ "service_code" => $service->getServiceCode(),
+ "onetime_case" => $onetime_case,
+ "onetime_sub" => "도메인 쿠폰 구매 / {$coupon} 개",
+ "onetime_amount" => 0,
+ "onetime_payment" => 0,
+ "onetime_nonpayment" => 0,
+ "onetime_accountStatus" => 'complete',
+ "onetime_request_date" => $onetime_request_date,
+ "onetime_payment_date" => $onetime_request_date,
+ "onetime_note" => trim($note),
+ "onetime_handle_date" => $onetime_request_date,
+ "onetime_manager" => $member->getPK(),
+ "client_name" => $client->getTitle(),
+ "server_code" => $service->getServerCode(),
+ ];
+ return $this->getModel()->insert($formDatas);
+ }
+}
diff --git a/extdbms/lib/Services/PointService.php b/extdbms/lib/Services/PointService.php
new file mode 100644
index 0000000..15650b7
--- /dev/null
+++ b/extdbms/lib/Services/PointService.php
@@ -0,0 +1,30 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+} //Class
diff --git a/extdbms/lib/Services/ServerService.php b/extdbms/lib/Services/ServerService.php
new file mode 100644
index 0000000..e488b34
--- /dev/null
+++ b/extdbms/lib/Services/ServerService.php
@@ -0,0 +1,54 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+ public function getCountByMode(string $mode, string $cpu, ?string $spec = null): int
+ {
+ switch ($mode) {
+ case 'all':
+ $this->getModel()->like(["server_cpuname" => "%$cpu%", "server_spec" => "%$spec%"]);
+ break;
+ case 'use':
+ $this->getModel()->where("server_use_status", "n");
+ $this->getModel()->like(["server_cpuname" => "%$cpu%", "server_spec" => "%$spec%"]);
+ break;
+ case 'empty':
+ $this->getModel()->where("server_use_status", "y");
+ $this->getModel()->like(["server_cpuname" => "%$cpu%", "server_spec" => "%$spec%"]);
+ break;
+ case 'format':
+ $this->getModel()->where("server_use_status", "y");
+ $this->getModel()->where("server_fomat_date !='NULL'");
+ $this->getModel()->like(["server_cpuname" => "%$cpu%"]);
+ break;
+ default:
+ throw new \InvalidArgumentException("Invalid mode: $mode");
+ }
+ return $this->getCount();
+ }
+}
diff --git a/extdbms/lib/Services/ServiceService.php b/extdbms/lib/Services/ServiceService.php
new file mode 100644
index 0000000..3201144
--- /dev/null
+++ b/extdbms/lib/Services/ServiceService.php
@@ -0,0 +1,104 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+
+ //미지급금 리스트
+ public function getEntitiesForNonPayment(int $curPage, int $perPage, array $exclude_clients): array
+ {
+ $table = $this->getModel()->getTable();
+ $clientTable = ClientModel::TABLE;
+ $addDbTable = AddDbModel::TABLE;
+ $this->getModel()->select("{$clientTable}.Client_Name,{$table}.service_code,service_line,server_code,service_ip,service_payment_date,service_amount,service_nonpayment,service_note,addDB_case,addDB_nonpayment,addDB_payment,addDB_accountStatus,addDB_ip,addDB_payment_date");
+ $this->getModel()->join($clientTable, "{$table}.client_code = {$clientTable}.Client_Code");
+ $this->getModel()->join($addDbTable, "{$table}.service_code = {$addDbTable}.service_code");
+ $this->getModel()->whereNotIn("{$addDbTable}.client_code", $exclude_clients);
+ $this->getModel()->whereNotIn("{$addDbTable}.addDB_accountStatus", ["complete"]);
+ $this->getModel()->orderBy("service_payment_date", "DESC");
+ //Query문 Rest여부 -> 같은조건에 Count 받고, 결과값을 받고 싶을때는 continue()
+ $this->getModel()->setContinue(true);
+ $total = $this->getCount();
+ //limit, offset 설정
+ $this->getModel()->limit($perPage);
+ $this->getModel()->offset(($curPage - 1) * $perPage);
+ return [$total, $this->getEntities()];
+ }
+
+ //지역(치바,도쿄등)에 따른 DASHBOARD용 서비스 카운트
+ private function getDistrictCountForDashboard(string $where, string $type, array $switchcodes): int
+ {
+ $switchcode_begin = $switchcodes['begin'];
+ $switchcode_end = $switchcodes['end'];
+ $this->getModel()->where($where);
+ $this->getModel()->where(["service_line" => $type, "service_status" => 'o']);
+ $this->getModel()->where("service_sw BETWEEN '{$switchcode_begin}' AND '$switchcode_end'");
+ $count = $this->getModel()->count();
+ // echo " " . $this->getModel()->getLastQuery();
+ return $count;
+ }
+ final public function getTotalCountForDashboard(array $siteinfo): array
+ {
+ $temps = array();
+ foreach ($siteinfo['totalcount_customers'] as $customer => $where) {
+ $temps[$customer] = [];
+ foreach ($siteinfo['totalcount_types'] as $type) {
+ foreach (DBMS_SERVICE_SWITCHCODE as $district => $switchcodes) {
+ $temps[$customer][$type][$district] = $this->getDistrictCountForDashboard($where, $type, $switchcodes);
+ }
+ } //foreach
+ // echo var_dump($temps);
+ } //foreach
+ return $temps;
+ }
+
+ //도메인쿠폰 사용용
+ public function useCouponByService(ServiceEntity $service, int $coupon): bool
+ {
+ if ($coupon < 0) {
+ throw new \Exception("쿠폰수량이 잘못되었습니다. 쿠폰수량 : $coupon");
+ }
+ $this->getModel()->where("service_code", $service->getServiceCode());
+ $this->getModel()->update(["coupon=(coupon-{$coupon})" => null, "coupon_use=(coupon_use+{$coupon})" => null]);
+ return true;
+ }
+ //도메인쿠폰 Reset
+ public function resetCouponByClient(ClientEntity $client, int $coupon): bool
+ {
+ if ($coupon < 0) {
+ throw new \Exception("쿠폰수량이 잘못되었습니다. 쿠폰수량 : $coupon");
+ }
+ $this->getModel()->where("client_code", $client->getClientCode());
+ $this->getModel()->where("server_code", $client->getTitle() . "_일회성");
+ $this->getModel()->update(["coupon" => $coupon, "coupon_use" => 0]);
+ return true;
+ } //setCoupon
+}
diff --git a/extdbms/lib/Services/VPCService.php b/extdbms/lib/Services/VPCService.php
new file mode 100644
index 0000000..88f2a68
--- /dev/null
+++ b/extdbms/lib/Services/VPCService.php
@@ -0,0 +1,30 @@
+getClassName();
+ }
+ public function getModelClass(): string
+ {
+ return Model::class;
+ }
+ public function getEntityClass(): string
+ {
+ return Entity::class;
+ }
+}
diff --git a/extdbms/lib/Utils/Pagination.php b/extdbms/lib/Utils/Pagination.php
new file mode 100644
index 0000000..cd504de
--- /dev/null
+++ b/extdbms/lib/Utils/Pagination.php
@@ -0,0 +1,13 @@
+client) { ?>
+ 고객명 : = $this->client->getTitle() ?> / 쿠폰발급대상 : = count($this->entities) ?> 대 / 전체 남은 수량 : = $this->total_coupon; ?> 개
+
+
+
+
+
+
+ No
+ 서비스코드
+ 장비명
+ 서버IP
+ 서비스개시일
+ 회선종류
+ 쿠폰 누적수
+ 쿠폰 잔량수
+ 쿠폰 사용수
+ 사용
+
+
+
+
+ entities as $entity) { ?>
+ entities) - $i; ?>
+
+ = $num ?>
+ = $entity->getServiceCode() ?>
+ = $entity->getServerCode() ?>
+ = $entity->service_ip ?>
+ = $entity->service_open_date ?>
+ = $entity->service_line ?>
+ = $entity->getCoupon() + $entity->getUsedCoupon() ?>
+ = $entity->getCoupon() ?>
+ = $entity->getUsedCoupon() ?>
+ ">= !$entity->getCoupon() ? "사용완료" : "사용하기" ?>
+
+
+
+
+
+
+= $this->pagination->render(DBMS_SITE_URL . "/IdcCouponUseMK.cup", ['client_code' => $this->client ? $this->client->getClientCode() : "", 'mkid' => $this->member ? $this->member->getPK() : "", 'curPage' => $this->curPage, 'perPage' => $this->perPage]) ?>
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/client/coupon/insert_form.php b/extdbms/lib/Views/dbms/client/coupon/insert_form.php
new file mode 100644
index 0000000..f935d23
--- /dev/null
+++ b/extdbms/lib/Views/dbms/client/coupon/insert_form.php
@@ -0,0 +1,57 @@
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/client/dashboard/totalcount.php b/extdbms/lib/Views/dbms/client/dashboard/totalcount.php
new file mode 100644
index 0000000..9a1be2d
--- /dev/null
+++ b/extdbms/lib/Views/dbms/client/dashboard/totalcount.php
@@ -0,0 +1,56 @@
+
+
+
+
+ 도쿄
+ 치바
+ VPN
+
+
+
+
+ = $this->dashboard['Tokyo'] ?>
+ = $this->dashboard['Chiba'] ?>
+ = $this->dashboard['vpn'] ?>
+
+
+
+
+
+
+
+
+ 일반
+ 방어
+ 전용
+ 이벤트
+
+
+
+
+ = $this->dashboard['normal'] ?>
+ = $this->dashboard['defence'] ?>
+ = $this->dashboard['solo'] ?>
+ = $this->dashboard['event'] ?>
+
+
+
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/client/memo/update_form.php b/extdbms/lib/Views/dbms/client/memo/update_form.php
new file mode 100644
index 0000000..aa60673
--- /dev/null
+++ b/extdbms/lib/Views/dbms/client/memo/update_form.php
@@ -0,0 +1,16 @@
+client) { ?>
+
+
+
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/client/payment/billpaper.php b/extdbms/lib/Views/dbms/client/payment/billpaper.php
new file mode 100644
index 0000000..cbea492
--- /dev/null
+++ b/extdbms/lib/Views/dbms/client/payment/billpaper.php
@@ -0,0 +1,79 @@
+
+
※ 청구서를 받으셨던 서버인 경우에도 발행하는 시점까지 미납인 경우 재 발행됩니다. 입금을 하신 경우에는 연락 부탁드립니다.
+
입금 하실 계좌 번호 입니다.
+ siteInfo['banks'] as $bank) { ?>
+
+ 은행명 : = $bank['name'] ?>
+ 계좌번호 : = $bank['id'] ?>
+ 예금주: = $bank['owner'] ?>
+
+
+
고객명과 입금자명이 상이한 경우 반드시 확인 연락이 필요합니다.
+ 입금 시 당 청구서에 기재되어 있는 고객명으로 입금해주시면 별도의 입금 확인 전화가 필요없습니다.
+
+
※ 할인안내
+ - 서버비 입금시 3개월 이상 선납하는 고객분들께 드리는 할인혜택 (중도 해약하시더라도 환불은 되지 않습니다.)
+ 3개월 - 10%, 6개월 - 15%, 12개월 -20% 의 비율로 결제금액을 할인 해 드리고 있습니다.
+ - 장기사용하시는 고객분들께 드리는 할인혜택
+ 1년 이상 10%, 2년 이상 15% 3년 이상 20%, 4년 이상 25%, 최대 5년 이상 30%의 비율로 결제금액을 할인해 드리고 있습니다.
+ 단, 중도 해지 후 신규 가입시 할인혜택은 없습니다.
+
+
+ ※ 기타 서비스 요금 안내
+ - 도메인 구매 대행 서비스 : 도메인 1개당 3만원 (1회성 비용으로 구매를
요청하신 달에만 요금이 청구 됩니다)
+ - IP 추가 : 일반회선 10만원 / 보안회선 10만원(추가 하신 날로 부터 사용을 중지 하시는 달까지
매월 요금이 청구 됩니다.)
+ - IP 변경
+ - 단순 IP 변경의 경우(오래 사용하여 변경, 정기적인 변경, 관리자 변경 등)에는 무료로 변경 해 드리고 있습니다.
+ - IP에 문제(
KCSC로 연결, 접근(원격접속) 차단, 공격을 받아 다른 IP로 변경 등 )가 있어 변경 하실 경우에는
요금이 청구 됩니다.
+ * 청구비용 10만원 (1회성 비용으로 구매를
요청하신 달에만 요금이 청구 됩니다)
+ - 위 서비스는 선입금으로 제공 해 드리고 있습니다.
+ - VPN 결제일의 자정까지 결제처리가 안될시 자동차단처리가 되게됩니다.
+ 이점 양해 부탁드리겠습니다.
+
※ 이용 해지시에는 사용하셨던 IP에 연결 되어 있는 도메인들은 꼭 연결 해제를 해 주시기 바랍니다.
+
+ 보장 트래픽 : 기본 트래픽 사용량은 IN 10Mbps / OUT 10Mbps 입니다
+ 보장 트래픽 이상을 사용할 경우 트래픽 과금이 발생할 수 있습니다
+
※ 알림(필히 숙지 하여 주시기 바랍니다.)
+
+ 1. = $this->siteInfo['name'] ?>에 등록 하신 고객명 / 전화번호 / 메일 주소는 차후 고객님 확인을 위해 사용 되니 고객님께서도 필히 알고 계셔야 합니다.
+ 또한 전화번호와 메일주소 또는 메신져는 = $this->siteInfo['name'] ?>에서 고객님에게 연락을 취해야 할 경우 사용됩니다.변동사항이 있을 경우에는
+ 반드시 = $this->siteInfo['name'] ?>에 연락을 하여 변경해 주시기 바랍니다.
+
+
변동사항을 = $this->siteInfo['name'] ?>에게 알려 주시지 않거나, = $this->siteInfo['name'] ?>에 등록된 연락처로 연락을 해도 연결이 안되어 발생하는 피해에 대해서는
+ 저희 = $this->siteInfo['name'] ?>에서 책임을 지지 않습니다.
+
2. 결제는 납부기한내에 해 주셔야 합니다.
+ 혹시라도 납부기한내에 결제를 하지 못하실 경우는 미리 연락을 주시면 납부기한 후 최대 3일간은 서버 접속이 유지됩니다.
+ 하지만 납부기한까지 연락을 안주시거나 연락을 하셨더라도 납부기한을 3일 초과하시면 서버 접속이 차단되고 차단후에도
+ 3일동안 연락이 없을 경우 자동 해지 처리 되고 데이터는 삭제처리 되오니 주의 하시기 바랍니다.
+
3. 환불정책
+ 월단위 계약(계산)이므로 중도 환불(일할계산)은 안됩니다.
+ 단, 셋팅에 문제가 있거나 기타 문제가 있을 경우 서버를 인계 받으시고 3일 안으로는 환불 요청을 하실 수 있습니다.
+
+
4. 서버 운영중 해킹으로 발생한 피해는 저희 = $this->siteInfo['name'] ?>에서 책임을 지지 않습니다.
+ 서버운영에 있어서 보안에 각별히 주의 부탁드리겠습니다.
+ <해킹 대비 및 보안조치사항>
+ - 주기적인 window 보안 업데이트
+ - linux ,mysql , php, jsp 보안권고
+ - 서버 원격 접속 패스워드 및 mssql 패스워드 변경
+ * 영문,숫자,특수문자 8자리 이상 조합하여 사용 권고
+ * 매월 주기적으로 패스워드 변경
+ * 패스워드 노출 시 즉각 변경
+ - 서버내 방화벽에서 특정IP만 서버에 접속할 수 있도록 방화벽 설정
+ - 원격접속 포트 기본포트에서 변경 설정 (기본 포트 window : 3389 / linux : 22 )
+
+
+ * 무료 설치 : Microsoft Security Essential 설치
+
+ - 웹서비스 보안을 위한 웹방화벽 설치 대행서비스(유료)
+
+
# 원격포트 변경 및 원격접속 제한 설정은 = $this->siteInfo['name'] ?>홈페이지에 등록되어 있습니다.
+ 자세한 사항은 센터로 문의주시기 바랍니다.
+
5. 서버 운영중 장비부품 문제(예:하드디스크의 고장 등)로 발생한 피해는 저희 = $this->siteInfo['name'] ?>에서 책임을 지지 않습니다.
+ (요청하시면 백업을 위해 무료로 추가 하드를 제공해 드리고 있지만, 추가가 불가능한 경우도 있습니다.
+ 번거로우시더라도 주기적인 데이터백업을 부탁드리겠습니다.)
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/client/payment/index.php b/extdbms/lib/Views/dbms/client/payment/index.php
new file mode 100644
index 0000000..e3242d5
--- /dev/null
+++ b/extdbms/lib/Views/dbms/client/payment/index.php
@@ -0,0 +1,46 @@
+
+ mode == "all" || $this->mode == "" ? "checked" : "" ?>>전체
+ mode == "today" ? "checked" : "" ?>>당일
+ mode == "1day" ? "checked" : "" ?>>1일전
+ mode == "2day" ? "checked" : "" ?>>2일전
+ mode == "3day" ? "checked" : "" ?>>3일전
+
+
+
+= $this->message ?> 미납리스트 엑셀
+
+
+
+
+ 고객명
+ 종류
+ 장비명
+ IP
+ 결제일
+ 서비스 가격
+ 과금상태
+ 미납과금
+ 비고
+
+
+
+ entities as $entity) { ?>
+
+ = $entity->Client_Name ?>
+ = $entity->addDB_case ?>
+ = $entity->server_code ?>
+ = $entity->service_ip ?>
+
+ = $entity->service_payment_date ?>
+ = $entity->service_amount ?>
+
+ = $entity->addDB_accountStatus ?>
+ = $entity->addDB_nonpayment ?>
+
+ = $entity->service_note ?>
+
+
+
+
+
+
= $this->pagination->render(DBMS_SITE_URL . "/IdcDepositNonPaymentListMK.dep", ['mode' => $this->mode, 'curPage' => $this->curPage, 'perPage' => $this->perPage]) ?>
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/client/point/index.php b/extdbms/lib/Views/dbms/client/point/index.php
new file mode 100644
index 0000000..92da629
--- /dev/null
+++ b/extdbms/lib/Views/dbms/client/point/index.php
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+ No
+ 제목
+ 고객명
+ 현재금액
+ 입금액
+ 출금액
+ 작업일
+ 비고
+
+
+
+
+ entities as $entity) { ?>
+ entities) - $i; ?>
+
+ = $num ?>
+ = $entity->getTitle() ?>
+ = $this->clients[$entity->getClientCode()]->getTitle() ?>
+ = number_format($this->clients[$entity->getClientCode()]->getPoint()) ?>
+ = number_format($entity->getType() == 'deposit' ? $entity->getAmount() : 0) ?>
+ = number_format($entity->getType() == 'withdrawal' ? $entity->getAmount() : 0) ?>
+ = $entity->getCreatedAt() ?>
+ = $entity->getNote() ?>
+
+
+
+
+
+
= $this->pagination->render(DBMS_SITE_URL . "/IdcClientPointList.cli", ['client_code' => $this->client_code, 'curPage' => $this->curPage, 'perPage' => $this->perPage]) ?>
+ client_code ?>
+
포인트 추가
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/client/point/insert_form.php b/extdbms/lib/Views/dbms/client/point/insert_form.php
new file mode 100644
index 0000000..d726759
--- /dev/null
+++ b/extdbms/lib/Views/dbms/client/point/insert_form.php
@@ -0,0 +1,45 @@
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/dashboard/coupon.php b/extdbms/lib/Views/dbms/dashboard/coupon.php
new file mode 100644
index 0000000..c2ba4e8
--- /dev/null
+++ b/extdbms/lib/Views/dbms/dashboard/coupon.php
@@ -0,0 +1 @@
+
= $this->service->coupon ?>개
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/dashboard/cscount.php b/extdbms/lib/Views/dbms/dashboard/cscount.php
new file mode 100644
index 0000000..f9a41da
--- /dev/null
+++ b/extdbms/lib/Views/dbms/dashboard/cscount.php
@@ -0,0 +1,2 @@
+
client_code ?>&csInfoFlag=true&service_code== $this->service_code ?>">= $this->vpc ?>
+
client_code ?>&csInfoFlag=false&service_code== $this->service_code ?>">= $this->kcs ?>
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/dashboard/latest_history.php b/extdbms/lib/Views/dbms/dashboard/latest_history.php
new file mode 100644
index 0000000..55b2f8c
--- /dev/null
+++ b/extdbms/lib/Views/dbms/dashboard/latest_history.php
@@ -0,0 +1,21 @@
+
+
패스워드용 난수 :
+entities as $entity): ?>
+ services[$entity->getServiceCode()]; ?>
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/dashboard/latest_service.php b/extdbms/lib/Views/dbms/dashboard/latest_service.php
new file mode 100644
index 0000000..ecbd470
--- /dev/null
+++ b/extdbms/lib/Views/dbms/dashboard/latest_service.php
@@ -0,0 +1,43 @@
+
+
+
+ 서비스코드
+ 업체명
+ 구분
+ 장비번호
+ 스위치정보
+ IP정보
+ CS
+ 등록자
+ 비고
+
+
+
+ entities as $entity): ?>
+ entity = $entity ?>
+
+ = $entity->getServiceCode() ?>
+
+ = $this->clients[$entity->getServiceCode()]->getTitle() ?>
+
+ = $entity->service_line ?>
+
+ = $entity->getServiceCode() ?>
+
+
+ = $entity->service_sw ?>
+
+ = $entity->service_ip ?>
+
+ = $this->vpcs[$entity->getServiceCode()] ?>
+ /
+ = $this->kcss[$entity->getServiceCode()] ?>
+
+ = !$this->members[$entity->getMemberCode()] ? "" : $this->members[$entity->getMemberCode()]->getTitle() ?>
+
+ = $this->helper->truncateString($entity->service_note, 20) ?>
+
+
+
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/dashboard/topboard.php b/extdbms/lib/Views/dbms/dashboard/topboard.php
new file mode 100644
index 0000000..bb1378b
--- /dev/null
+++ b/extdbms/lib/Views/dbms/dashboard/topboard.php
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
= $this->newServices ?>
+
최근 = $this->day ?>일간 신규서비스스 대수
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
= $this->unPayments ?>
+
금일 기준 미납 서버
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/dashboard/totalcount.php b/extdbms/lib/Views/dbms/dashboard/totalcount.php
new file mode 100644
index 0000000..3390bbc
--- /dev/null
+++ b/extdbms/lib/Views/dbms/dashboard/totalcount.php
@@ -0,0 +1,69 @@
+
+
+
+
+ 고객명
+ 일반
+ 방어
+ 전용
+ 대체
+ 테스트
+ 합계
+
+
+ 도쿄
+ 치바
+ 도쿄
+ 치바
+ 도쿄
+ 치바
+ 도쿄
+ 치바
+ 도쿄
+ 치바
+ 합계
+ 도쿄
+ 치바
+ 합계
+
+
+
+ totalcount as $company => $service) { ?>
+
+ = $company ?>
+ $location) { ?>
+ = $location['Tokyo']; ?>
+ = $location['Chiba']; ?>
+
+ = $service['test']['Tokyo'] + $service['test']['Chiba']; ?>
+ = $this->summary[$company]['Tokyo'] - $service['test']['Tokyo']; ?>
+ = $this->summary[$company]['Chiba'] - $service['test']['Chiba']; ?>
+ = $this->summary[$company]['Tokyo'] - $service['test']['Tokyo'] + $this->summary[$company]['Chiba'] - $service['test']['Chiba']; ?>
+
+
+
+
+
+ 총합계
+ siteInfo['totalcount_types'] as $type) { ?>
+ = $this->summary[$type]['Tokyo']; ?>
+ = $this->summary[$type]['Chiba']; ?>
+
+ = $this->summary['test']['Tokyo'] + $this->summary['test']['Chiba']; ?>
+ = $this->total['Tokyo'] - $this->summary['test']['Tokyo']; ?>
+ = $this->total['Chiba'] - $this->summary['test']['Chiba']; ?>
+ = $this->total['Tokyo'] - $this->summary['test']['Tokyo'] + $this->total['Chiba'] - $this->summary['test']['Chiba']; ?>
+
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/defence/index.php b/extdbms/lib/Views/dbms/defence/index.php
new file mode 100644
index 0000000..8d1ea03
--- /dev/null
+++ b/extdbms/lib/Views/dbms/defence/index.php
@@ -0,0 +1,127 @@
+
+
+ entities as $entity) { ?>
+ getZone() ?>
+ '">= $zone ?>
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/gearlist/index.php b/extdbms/lib/Views/dbms/gearlist/index.php
new file mode 100644
index 0000000..2dbf1d6
--- /dev/null
+++ b/extdbms/lib/Views/dbms/gearlist/index.php
@@ -0,0 +1,35 @@
+* CPU 명칭 : 싱글 코어 = 1개 코어 / 듀얼 코어 = 2개 코어 / 트리플 코어 = 3개 코어 / 쿼드 코어(Q) = 4개 코어 / 헥사 코어(H) = 6개 코어 / 옥타 코어(O) = 8개 코어 / 도데카(D) = 12개 코어 / 헥사데시멀 코어 = 16개코어
+* 도쿄 회선 + 1U상면비 : 60만원 (50+10) / 치바 회선 + 1U상면비 : 40만원 (30+10)
+* HDD : 1단위당 일회성 10만원 / 메모리 : 2G당 1회성 5만원 / 방어서비스 : CS방어 40만원 , BL상시 60만원 , CS-Pre상시 300만원 , CF방어 도메인당 40만원 , 인증방어 사이트당 80만원(+유동CS4개 기본)
+
+
+
+ 구분
+ 장비사양
+ CPU모델명
+ 임대가격
+ 전체서버
+ 임대중
+ 사용가능
+ 포맷보류
+
+
+
+ entities as $entity) {
+ ?>
+
+ = $entity->getProcess() ?>
+ = $entity->getSpec() ?>
+ = $entity->getCPUName() ?>
+ = $entity->getPrice() ?> 만원
+ = $entity->all ?> 대
+ = $entity->use ?> 대
+
+ = $entity->empty ?> 대
+
+ = $entity->format ?> 대
+
+
+
+
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/navigator/index.php b/extdbms/lib/Views/dbms/navigator/index.php
new file mode 100644
index 0000000..de8b994
--- /dev/null
+++ b/extdbms/lib/Views/dbms/navigator/index.php
@@ -0,0 +1,120 @@
+
+
+
+
+
+ CODE
+ NAME
+ SERVER
+ IP
+ SW
+ NOTE
+ TEL
+ MAIL
+
+
+
+ entities as $entity) { ?>
+
+ = $entity->getClientCode() ?>
+ = $this->clients[$entity->getClientCode()]->getTitle() ?>
+ = $entity->getServerCode() ?>
+ = $entity->service_ip ?>
+ = $entity->service_os ?>
+ = $entity->service_sw ?>
+ = $this->clients[$entity->getClientCode()]->getPhone() ?>
+ = $this->clients[$entity->getClientCode()]->getEmail() ?>
+
+
+
+
+
+
= $this->pagination->render(DBMS_SITE_URL . "/usableServerList.ser", ['ip' => $this->ip, 'curPage' => $this->curPage, 'perPage' => $this->perPage]) ?>
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/server/index.php b/extdbms/lib/Views/dbms/server/index.php
new file mode 100644
index 0000000..040a1e7
--- /dev/null
+++ b/extdbms/lib/Views/dbms/server/index.php
@@ -0,0 +1,42 @@
+client) { ?>
+
고객명 : = $this->client->getTitle() ?> / 쿠폰발급대상 : = count($this->servers) ?> 대 / 전체 남은 수량 : = $this->total_coupon; ?> 개
+
+
+
+
+
+
+ No
+ 서비스코드
+ 장비명
+ 서버IP
+ 서비스개시일
+ 회선종류
+ 쿠폰 누적수
+ 쿠폰 잔량수
+ 쿠폰 사용수
+ 사용
+
+
+
+
+ servers as $server) { ?>
+ servers) - $i; ?>
+
+ = $num ?>
+ = $server->getServiceCode() ?>
+ = $server->getServerCode() ?>
+ = $server->server_ip ?>
+ = $server->server_open_date ?>
+ = $server->server_line ?>
+ = $server->getCoupon() + $server->getUsedCoupon() ?>
+ = $server->getCoupon() ?>
+ = $server->getUsedCoupon() ?>
+ ">= !$server->getCoupon() ? "사용완료" : "사용하기" ?>
+
+
+
+
+
+
+
= $this->pagination->render(DBMS_SITE_URL . "/IdcCouponUseMK.cup", ['client_code' => $this->client ? $this->client->getClientCode() : "", 'mkid' => $this->member ? $this->member->getPK() : "", 'curPage' => $this->curPage, 'perPage' => $this->perPage]) ?>
\ No newline at end of file
diff --git a/extdbms/lib/Views/dbms/service/extra.php b/extdbms/lib/Views/dbms/service/extra.php
new file mode 100644
index 0000000..8a8bf33
--- /dev/null
+++ b/extdbms/lib/Views/dbms/service/extra.php
@@ -0,0 +1,35 @@
+
+
+
+
+ 고객명
+ 장비명
+ IP
+ 사용OS
+ 위치
+
+
+
+ entities as $key => $entity) { ?>
+
+ = $this->clients[$entity->getClientCode()]->getTitle() ?>
+ = $entity->getServerCode() ?>
+ = $entity->service_ip ?>
+ = $entity->service_os ?>
+ = $entity->service_sw ?>
+
+
+
+
+
= $this->pagination->render("/dbms/service/extra/adddb_code/", ['adddb_code' => $this->adddb_code, 'curPage' => $this->curPage, 'perPage' => $this->perPage]) ?>
\ No newline at end of file
diff --git a/extdbms/public/.htaccess b/extdbms/public/.htaccess
new file mode 100644
index 0000000..f47adc9
--- /dev/null
+++ b/extdbms/public/.htaccess
@@ -0,0 +1,49 @@
+# Disable directory browsing
+Options -Indexes
+
+# ----------------------------------------------------------------------
+# Rewrite engine
+# ----------------------------------------------------------------------
+
+# Turning on the rewrite engine is necessary for the following rules and features.
+# FollowSymLinks must be enabled for this to work.
+
+ Options +FollowSymlinks
+ RewriteEngine On
+
+ # If you installed CodeIgniter in a subfolder, you will need to
+ # change the following line to match the subfolder you need.
+ # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
+ # RewriteBase /
+
+ # Redirect Trailing Slashes...
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_URI} (.+)/$
+ RewriteRule ^ %1 [L,R=301]
+
+ # Rewrite "www.example.com -> example.com"
+ RewriteCond %{HTTPS} !=on
+ RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
+ RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
+
+ # Checks to see if the user is attempting to access a valid file,
+ # such as an image or css document, if this isn't true it sends the
+ # request to the front controller, index.php
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]
+
+ # Ensure Authorization header is passed along
+ RewriteCond %{HTTP:Authorization} .
+ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+
+
+
+ # If we don't have mod_rewrite installed, all 404's
+ # can be sent to index.php, and everything works as normal.
+ ErrorDocument 404 index.php
+
+
+# Disable server signature start
+ServerSignature Off
+# Disable server signature end
\ No newline at end of file
diff --git a/extdbms/public/index.php b/extdbms/public/index.php
new file mode 100644
index 0000000..8cf449c
--- /dev/null
+++ b/extdbms/public/index.php
@@ -0,0 +1,14 @@
+run();
+} catch (\Exception $e) {
+ echo $e->getMessage();
+}
diff --git a/extdbms/writeable/sessions/sess_54njbi3pdr7stgl03virsn2b98 b/extdbms/writeable/sessions/sess_54njbi3pdr7stgl03virsn2b98
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_9uce8cqp2agj10ifisl3lufv1r b/extdbms/writeable/sessions/sess_9uce8cqp2agj10ifisl3lufv1r
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_b530e6at32uds221gtkk7hrkg4 b/extdbms/writeable/sessions/sess_b530e6at32uds221gtkk7hrkg4
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_es99c3k1lbdl7a36ilges1dost b/extdbms/writeable/sessions/sess_es99c3k1lbdl7a36ilges1dost
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_fk66sqthdb1jnvkund91147m1m b/extdbms/writeable/sessions/sess_fk66sqthdb1jnvkund91147m1m
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_ovk2gdohqefm1jcu0mo3l6ispo b/extdbms/writeable/sessions/sess_ovk2gdohqefm1jcu0mo3l6ispo
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_rh3ij5nvog6tdrk8cpkseouqfa b/extdbms/writeable/sessions/sess_rh3ij5nvog6tdrk8cpkseouqfa
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_sb8t3rsj1qeqcalgb9fcul4ors b/extdbms/writeable/sessions/sess_sb8t3rsj1qeqcalgb9fcul4ors
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_sp47p0rdh6fsm882vumtgadf9o b/extdbms/writeable/sessions/sess_sp47p0rdh6fsm882vumtgadf9o
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_uk8n9c9m06dgjh4u2tovtoqdb2 b/extdbms/writeable/sessions/sess_uk8n9c9m06dgjh4u2tovtoqdb2
new file mode 100644
index 0000000..e69de29
diff --git a/extdbms/writeable/sessions/sess_v0cfugmiu9m8c6tn4o15v0bs37 b/extdbms/writeable/sessions/sess_v0cfugmiu9m8c6tn4o15v0bs37
new file mode 100644
index 0000000..b74b0ff
--- /dev/null
+++ b/extdbms/writeable/sessions/sess_v0cfugmiu9m8c6tn4o15v0bs37
@@ -0,0 +1 @@
+flash|a:1:{s:5:"error";a:1:{s:7:"message";s:94:"실패포인트 값이 정의되지 않았거나, 포인트값은 1 이상이어야 합니다.";}}
\ No newline at end of file