From 8ec1a0ad77e100613c8958d04ab3ba26590084b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=A4=80=ED=9D=A0?= Date: Mon, 28 Apr 2025 19:06:09 +0900 Subject: [PATCH] dbms init...1 --- .gitignore | 38 +- LICENSE | 22 + README.md | 2 +- app/.htaccess | 6 + app/Common.php | 15 + app/Config/App.php | 202 + app/Config/Autoload.php | 94 + app/Config/Boot/development.php | 34 + app/Config/Boot/production.php | 25 + app/Config/Boot/testing.php | 38 + app/Config/CURLRequest.php | 20 + app/Config/Cache.php | 171 + app/Config/Constants.php | 317 + app/Config/ContentSecurityPolicy.php | 176 + app/Config/Cookie.php | 107 + app/Config/Cors.php | 105 + app/Config/Database.php | 201 + app/Config/DocTypes.php | 46 + app/Config/Email.php | 121 + app/Config/Encryption.php | 92 + app/Config/Events.php | 55 + app/Config/Exceptions.php | 106 + app/Config/Feature.php | 29 + app/Config/Filters.php | 109 + app/Config/ForeignCharacters.php | 12 + app/Config/Format.php | 77 + app/Config/Generators.php | 44 + app/Config/Honeypot.php | 42 + app/Config/Images.php | 31 + app/Config/Kint.php | 65 + app/Config/Logger.php | 150 + app/Config/Migrations.php | 50 + app/Config/Mimes.php | 536 ++ app/Config/Modules.php | 84 + app/Config/Optimize.php | 32 + app/Config/Pager.php | 39 + app/Config/Paths.php | 75 + app/Config/Publisher.php | 28 + app/Config/Routes.php | 58 + app/Config/Routing.php | 140 + app/Config/Security.php | 103 + app/Config/Services.php | 41 + app/Config/Session.php | 127 + app/Config/Toolbar.php | 122 + app/Config/UserAgents.php | 252 + app/Config/Validation.php | 44 + app/Config/View.php | 62 + app/Controllers/Admin/AdminController.php | 89 + app/Controllers/Admin/Home.php | 35 + app/Controllers/Admin/MyLogController.php | 60 + app/Controllers/Admin/UserController.php | 59 + app/Controllers/BaseController.php | 58 + app/Controllers/CommonController.php | 607 ++ app/Controllers/Home.php | 11 + app/Controllers/UserController.php | 109 + app/Database/Migrations/.gitkeep | 0 app/Database/Seeds/.gitkeep | 0 app/Database/erp2.sql | 260 + app/Database/erp2.vuerd.json | 5317 +++++++++++++++++ app/Database/update.txt | 42 + app/Entities/CommonEntity.php | 38 + app/Entities/MyLogEntity.php | 18 + app/Entities/UserEntity.php | 24 + app/Entities/UserSNSEntity.php | 43 + app/Filters/.gitkeep | 0 app/Filters/AuthFilter.php | 62 + app/Helpers/.gitkeep | 0 app/Helpers/CommonHelper.php | 298 + app/Helpers/MyLogHelper.php | 74 + app/Helpers/UserHelper.php | 93 + app/Language/.gitkeep | 0 app/Language/en/MyLog.php | 19 + app/Language/en/User.php | 30 + app/Language/en/Validation.php | 4 + app/Libraries/.gitkeep | 0 app/Libraries/CommonLibrary.php | 23 + app/Libraries/MySocket/GoogleSocket/API.php | 128 + app/Libraries/MySocket/GoogleSocket/CURL.php | 171 + .../MySocket/GoogleSocket/GoogleSocket.php | 77 + app/Libraries/MySocket/MySocket.php | 91 + app/Libraries/MySocket/WebSocket.php | 48 + app/Libraries/MyStorage/FileStorage.php | 111 + app/Models/.gitkeep | 0 app/Models/CommonModel.php | 229 + app/Models/MyLogModel.php | 61 + app/Models/UserModel.php | 101 + app/Services/Auth/AuthService.php | 136 + app/Services/Auth/GoogleService.php | 55 + app/Services/Auth/LocalService.php | 42 + app/Services/CommonService.php | 148 + app/Services/MapurlService.php | 51 + app/Services/MyLogService.php | 49 + app/Services/UserService.php | 54 + app/ThirdParty/.gitkeep | 0 app/Traits/FileTrait.php | 62 + app/Traits/ImageTrait.php | 114 + app/Traits/MylogTrait.php | 34 + app/Views/Pagers/bootstrap_full.php | 35 + app/Views/Pagers/bootstrap_simple.php | 17 + app/Views/admin/create.php | 29 + app/Views/admin/index.php | 62 + app/Views/admin/modify.php | 28 + app/Views/admin/view.php | 19 + app/Views/admin/welcome_message.php | 103 + app/Views/errors/cli/error_404.php | 7 + app/Views/errors/cli/error_exception.php | 65 + app/Views/errors/cli/production.php | 5 + app/Views/errors/html/debug.css | 190 + app/Views/errors/html/debug.js | 116 + app/Views/errors/html/error_404.php | 84 + app/Views/errors/html/error_exception.php | 430 ++ app/Views/errors/html/production.php | 25 + app/Views/layouts/admin.php | 30 + app/Views/layouts/admin/bottom.php | 5 + app/Views/layouts/admin/left_menu.php | 14 + app/Views/layouts/admin/left_menu/base.php | 12 + .../layouts/admin/left_menu/cloudflare.php | 26 + app/Views/layouts/admin/left_menu/site.php | 13 + app/Views/layouts/admin/top.php | 50 + app/Views/layouts/empty.php | 30 + app/Views/layouts/front.php | 30 + app/Views/layouts/front/bottom.php | 5 + app/Views/layouts/front/left_menu.php | 2 + app/Views/layouts/front/top.php | 41 + app/Views/login.php | 24 + .../admin/index_content_batchjob.php | 56 + .../templates/admin/index_content_top.php | 23 + app/Views/templates/admin/index_footer.php | 0 app/Views/templates/admin/index_header.php | 13 + .../templates/admin/index_header/dns.php | 79 + app/Views/templates/common/modal_fetch.php | 168 + app/Views/templates/common/modal_iframe.php | 71 + app/Views/templates/download.php | 20 + app/Views/templates/front/index_footer.php | 0 app/Views/templates/front/index_header.php | 87 + app/Views/welcome_message.php | 331 + app/index.html | 11 + builds | 125 + composer.json | 53 + env | 69 + phpunit.xml.dist | 63 + preload.php | 104 + public/.htaccess | 49 + public/css/admin.css | 81 + public/css/admin/form.css | 28 + public/css/admin/index.css | 165 + public/css/admin/left_menu.css | 56 + public/css/admin/member_link.css | 17 + public/css/admin/resizeTable.css | 67 + public/css/common/style.css | 55 + public/css/empty.css | 11 + public/css/front.css | 81 + public/css/front/copyright.css | 29 + public/css/front/form.css | 28 + public/css/front/index.css | 168 + public/css/front/left_menu.css | 56 + public/css/front/login.css | 80 + public/css/front/member_link.css | 17 + public/favicon.ico | Bin 0 -> 5430 bytes public/images/common/com_icon3.png | Bin 0 -> 5005 bytes public/images/common/discord.png | Bin 0 -> 663 bytes public/images/common/excel.png | Bin 0 -> 881 bytes public/images/common/kakaotalk.png | Bin 0 -> 1399 bytes public/images/common/news.png | Bin 0 -> 4746 bytes public/images/common/pdf.png | Bin 0 -> 1392 bytes public/images/common/telegram.png | Bin 0 -> 1763 bytes public/images/common/top.png | Bin 0 -> 2565 bytes public/images/common/top_skype.png | Bin 0 -> 2166 bytes public/index.php | 56 + public/js/admin.js | 73 + public/js/admin/form.js | 119 + public/js/admin/index.js | 33 + public/js/admin/left_menu.js | 13 + public/js/admin/resizeTable.js | 843 +++ public/js/common/product.js | 30 + public/js/empty.js | 6 + public/js/front.js | 93 + public/js/front/index.js | 33 + public/js/front/left_menu.js | 13 + public/robots.txt | 2 + public/tinymce_upload.php | 32 + spark | 84 + tests/.htaccess | 6 + tests/README.md | 118 + .../2020-02-22-222222_example_migration.php | 37 + .../_support/Database/Seeds/ExampleSeeder.php | 41 + tests/_support/Libraries/ConfigReader.php | 17 + tests/_support/Models/ExampleModel.php | 24 + tests/database/ExampleDatabaseTest.php | 46 + tests/index.html | 11 + tests/session/ExampleSessionTest.php | 18 + tests/unit/HealthTest.php | 50 + writable/.htaccess | 12 + writable/cache/index.html | 11 + writable/debugbar/index.html | 11 + writable/excel/index.html | 11 + writable/index.html | 11 + writable/logs/index.html | 11 + writable/uploads/index.html | 11 + 199 files changed, 19093 insertions(+), 21 deletions(-) create mode 100644 LICENSE create mode 100644 app/.htaccess create mode 100644 app/Common.php create mode 100644 app/Config/App.php create mode 100644 app/Config/Autoload.php create mode 100644 app/Config/Boot/development.php create mode 100644 app/Config/Boot/production.php create mode 100644 app/Config/Boot/testing.php create mode 100644 app/Config/CURLRequest.php create mode 100644 app/Config/Cache.php create mode 100644 app/Config/Constants.php create mode 100644 app/Config/ContentSecurityPolicy.php create mode 100644 app/Config/Cookie.php create mode 100644 app/Config/Cors.php create mode 100644 app/Config/Database.php create mode 100644 app/Config/DocTypes.php create mode 100644 app/Config/Email.php create mode 100644 app/Config/Encryption.php create mode 100644 app/Config/Events.php create mode 100644 app/Config/Exceptions.php create mode 100644 app/Config/Feature.php create mode 100644 app/Config/Filters.php create mode 100644 app/Config/ForeignCharacters.php create mode 100644 app/Config/Format.php create mode 100644 app/Config/Generators.php create mode 100644 app/Config/Honeypot.php create mode 100644 app/Config/Images.php create mode 100644 app/Config/Kint.php create mode 100644 app/Config/Logger.php create mode 100644 app/Config/Migrations.php create mode 100644 app/Config/Mimes.php create mode 100644 app/Config/Modules.php create mode 100644 app/Config/Optimize.php create mode 100644 app/Config/Pager.php create mode 100644 app/Config/Paths.php create mode 100644 app/Config/Publisher.php create mode 100644 app/Config/Routes.php create mode 100644 app/Config/Routing.php create mode 100644 app/Config/Security.php create mode 100644 app/Config/Services.php create mode 100644 app/Config/Session.php create mode 100644 app/Config/Toolbar.php create mode 100644 app/Config/UserAgents.php create mode 100644 app/Config/Validation.php create mode 100644 app/Config/View.php create mode 100644 app/Controllers/Admin/AdminController.php create mode 100644 app/Controllers/Admin/Home.php create mode 100644 app/Controllers/Admin/MyLogController.php create mode 100644 app/Controllers/Admin/UserController.php create mode 100644 app/Controllers/BaseController.php create mode 100644 app/Controllers/CommonController.php create mode 100644 app/Controllers/Home.php create mode 100644 app/Controllers/UserController.php create mode 100644 app/Database/Migrations/.gitkeep create mode 100644 app/Database/Seeds/.gitkeep create mode 100644 app/Database/erp2.sql create mode 100644 app/Database/erp2.vuerd.json create mode 100644 app/Database/update.txt create mode 100644 app/Entities/CommonEntity.php create mode 100644 app/Entities/MyLogEntity.php create mode 100644 app/Entities/UserEntity.php create mode 100644 app/Entities/UserSNSEntity.php create mode 100644 app/Filters/.gitkeep create mode 100644 app/Filters/AuthFilter.php create mode 100644 app/Helpers/.gitkeep create mode 100644 app/Helpers/CommonHelper.php create mode 100644 app/Helpers/MyLogHelper.php create mode 100644 app/Helpers/UserHelper.php create mode 100644 app/Language/.gitkeep create mode 100644 app/Language/en/MyLog.php create mode 100644 app/Language/en/User.php create mode 100644 app/Language/en/Validation.php create mode 100644 app/Libraries/.gitkeep create mode 100644 app/Libraries/CommonLibrary.php create mode 100644 app/Libraries/MySocket/GoogleSocket/API.php create mode 100644 app/Libraries/MySocket/GoogleSocket/CURL.php create mode 100644 app/Libraries/MySocket/GoogleSocket/GoogleSocket.php create mode 100644 app/Libraries/MySocket/MySocket.php create mode 100644 app/Libraries/MySocket/WebSocket.php create mode 100644 app/Libraries/MyStorage/FileStorage.php create mode 100644 app/Models/.gitkeep create mode 100644 app/Models/CommonModel.php create mode 100644 app/Models/MyLogModel.php create mode 100644 app/Models/UserModel.php create mode 100644 app/Services/Auth/AuthService.php create mode 100644 app/Services/Auth/GoogleService.php create mode 100644 app/Services/Auth/LocalService.php create mode 100644 app/Services/CommonService.php create mode 100644 app/Services/MapurlService.php create mode 100644 app/Services/MyLogService.php create mode 100644 app/Services/UserService.php create mode 100644 app/ThirdParty/.gitkeep create mode 100644 app/Traits/FileTrait.php create mode 100644 app/Traits/ImageTrait.php create mode 100644 app/Traits/MylogTrait.php create mode 100644 app/Views/Pagers/bootstrap_full.php create mode 100644 app/Views/Pagers/bootstrap_simple.php create mode 100644 app/Views/admin/create.php create mode 100644 app/Views/admin/index.php create mode 100644 app/Views/admin/modify.php create mode 100644 app/Views/admin/view.php create mode 100644 app/Views/admin/welcome_message.php create mode 100644 app/Views/errors/cli/error_404.php create mode 100644 app/Views/errors/cli/error_exception.php create mode 100644 app/Views/errors/cli/production.php create mode 100644 app/Views/errors/html/debug.css create mode 100644 app/Views/errors/html/debug.js create mode 100644 app/Views/errors/html/error_404.php create mode 100644 app/Views/errors/html/error_exception.php create mode 100644 app/Views/errors/html/production.php create mode 100644 app/Views/layouts/admin.php create mode 100644 app/Views/layouts/admin/bottom.php create mode 100644 app/Views/layouts/admin/left_menu.php create mode 100644 app/Views/layouts/admin/left_menu/base.php create mode 100644 app/Views/layouts/admin/left_menu/cloudflare.php create mode 100644 app/Views/layouts/admin/left_menu/site.php create mode 100644 app/Views/layouts/admin/top.php create mode 100644 app/Views/layouts/empty.php create mode 100644 app/Views/layouts/front.php create mode 100644 app/Views/layouts/front/bottom.php create mode 100644 app/Views/layouts/front/left_menu.php create mode 100644 app/Views/layouts/front/top.php create mode 100644 app/Views/login.php create mode 100644 app/Views/templates/admin/index_content_batchjob.php create mode 100644 app/Views/templates/admin/index_content_top.php create mode 100644 app/Views/templates/admin/index_footer.php create mode 100644 app/Views/templates/admin/index_header.php create mode 100644 app/Views/templates/admin/index_header/dns.php create mode 100644 app/Views/templates/common/modal_fetch.php create mode 100644 app/Views/templates/common/modal_iframe.php create mode 100644 app/Views/templates/download.php create mode 100644 app/Views/templates/front/index_footer.php create mode 100644 app/Views/templates/front/index_header.php create mode 100644 app/Views/welcome_message.php create mode 100644 app/index.html create mode 100644 builds create mode 100644 composer.json create mode 100644 env create mode 100644 phpunit.xml.dist create mode 100644 preload.php create mode 100644 public/.htaccess create mode 100644 public/css/admin.css create mode 100644 public/css/admin/form.css create mode 100644 public/css/admin/index.css create mode 100644 public/css/admin/left_menu.css create mode 100644 public/css/admin/member_link.css create mode 100644 public/css/admin/resizeTable.css create mode 100644 public/css/common/style.css create mode 100644 public/css/empty.css create mode 100644 public/css/front.css create mode 100644 public/css/front/copyright.css create mode 100644 public/css/front/form.css create mode 100644 public/css/front/index.css create mode 100644 public/css/front/left_menu.css create mode 100644 public/css/front/login.css create mode 100644 public/css/front/member_link.css create mode 100644 public/favicon.ico create mode 100644 public/images/common/com_icon3.png create mode 100644 public/images/common/discord.png create mode 100644 public/images/common/excel.png create mode 100644 public/images/common/kakaotalk.png create mode 100644 public/images/common/news.png create mode 100644 public/images/common/pdf.png create mode 100644 public/images/common/telegram.png create mode 100644 public/images/common/top.png create mode 100644 public/images/common/top_skype.png create mode 100644 public/index.php create mode 100644 public/js/admin.js create mode 100644 public/js/admin/form.js create mode 100644 public/js/admin/index.js create mode 100644 public/js/admin/left_menu.js create mode 100644 public/js/admin/resizeTable.js create mode 100644 public/js/common/product.js create mode 100644 public/js/empty.js create mode 100644 public/js/front.js create mode 100644 public/js/front/index.js create mode 100644 public/js/front/left_menu.js create mode 100644 public/robots.txt create mode 100644 public/tinymce_upload.php create mode 100644 spark create mode 100644 tests/.htaccess create mode 100644 tests/README.md create mode 100644 tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php create mode 100644 tests/_support/Database/Seeds/ExampleSeeder.php create mode 100644 tests/_support/Libraries/ConfigReader.php create mode 100644 tests/_support/Models/ExampleModel.php create mode 100644 tests/database/ExampleDatabaseTest.php create mode 100644 tests/index.html create mode 100644 tests/session/ExampleSessionTest.php create mode 100644 tests/unit/HealthTest.php create mode 100644 writable/.htaccess create mode 100644 writable/cache/index.html create mode 100644 writable/debugbar/index.html create mode 100644 writable/excel/index.html create mode 100644 writable/index.html create mode 100644 writable/logs/index.html create mode 100644 writable/uploads/index.html diff --git a/.gitignore b/.gitignore index 8fb962b..433946d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,18 @@ -# ---> CodeIgniter -*/config/development -*/logs/log-*.php -!*/logs/index.html -*/cache/* -!system/cache/* -!*/cache/index.html -!*/cache/.htaccess - -user_guide_src/build/* -user_guide_src/cilexer/build/* -user_guide_src/cilexer/dist/* -user_guide_src/cilexer/pycilexer.egg-info/* - -#codeigniter 3 -application/logs/* -!application/logs/index.html -!application/logs/.htaccess -/vendor/ - +#codeigniter4 +.env +composer.lock +vendor/ +public/vendors/ +public/tinymce_uploads/ +writable/caceh/* +!writable/caceh/index.html +writable/logs/* +!writable/logs/index.html +writable/session/* +!writable/session/index.html +writable/uploads/* +!writable/uploads/index.html +writable/debugbar/* +!writable/debugbar/index.html +writable/excel/* +!writable/excel/index.html \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..148e7f7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014-2019 British Columbia Institute of Technology +Copyright (c) 2019-2024 CodeIgniter Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index fd7338f..f5f8ee1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# dbms +# Automation diff --git a/app/.htaccess b/app/.htaccess new file mode 100644 index 0000000..97c65d2 --- /dev/null +++ b/app/.htaccess @@ -0,0 +1,6 @@ + + Require all denied + + + Deny from all + \ No newline at end of file diff --git a/app/Common.php b/app/Common.php new file mode 100644 index 0000000..95f5544 --- /dev/null +++ b/app/Common.php @@ -0,0 +1,15 @@ + + */ + public array $allowedHostnames = []; + + /** + * -------------------------------------------------------------------------- + * Index File + * -------------------------------------------------------------------------- + * + * Typically, this will be your `index.php` file, unless you've renamed it to + * something else. If you have configured your web server to remove this file + * from your site URIs, set this variable to an empty string. + */ + public string $indexPage = 'index.php'; + + /** + * -------------------------------------------------------------------------- + * URI PROTOCOL + * -------------------------------------------------------------------------- + * + * This item determines which server global should be used to retrieve the + * URI string. The default setting of 'REQUEST_URI' works for most servers. + * If your links do not seem to work, try one of the other delicious flavors: + * + * 'REQUEST_URI': Uses $_SERVER['REQUEST_URI'] + * 'QUERY_STRING': Uses $_SERVER['QUERY_STRING'] + * 'PATH_INFO': Uses $_SERVER['PATH_INFO'] + * + * WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! + */ + public string $uriProtocol = 'REQUEST_URI'; + + /* + |-------------------------------------------------------------------------- + | Allowed URL Characters + |-------------------------------------------------------------------------- + | + | This lets you specify which characters are permitted within your URLs. + | When someone tries to submit a URL with disallowed characters they will + | get a warning message. + | + | As a security measure you are STRONGLY encouraged to restrict URLs to + | as few characters as possible. + | + | By default, only these are allowed: `a-z 0-9~%.:_-` + | + | Set an empty string to allow all characters -- but only if you are insane. + | + | The configured value is actually a regular expression character group + | and it will be used as: '/\A[]+\z/iu' + | + | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! + | + */ + public string $permittedURIChars = 'a-z 0-9~%.:_\-'; + + /** + * -------------------------------------------------------------------------- + * Default Locale + * -------------------------------------------------------------------------- + * + * The Locale roughly represents the language and location that your visitor + * is viewing the site from. It affects the language strings and other + * strings (like currency markers, numbers, etc), that your program + * should run under for this request. + */ + public string $defaultLocale = 'en'; + + /** + * -------------------------------------------------------------------------- + * Negotiate Locale + * -------------------------------------------------------------------------- + * + * If true, the current Request object will automatically determine the + * language to use based on the value of the Accept-Language header. + * + * If false, no automatic detection will be performed. + */ + public bool $negotiateLocale = false; + + /** + * -------------------------------------------------------------------------- + * Supported Locales + * -------------------------------------------------------------------------- + * + * If $negotiateLocale is true, this array lists the locales supported + * by the application in descending order of priority. If no match is + * found, the first locale will be used. + * + * IncomingRequest::setLocale() also uses this list. + * + * @var list + */ + public array $supportedLocales = ['en']; + + /** + * -------------------------------------------------------------------------- + * Application Timezone + * -------------------------------------------------------------------------- + * + * The default timezone that will be used in your application to display + * dates with the date helper, and can be retrieved through app_timezone() + * + * @see https://www.php.net/manual/en/timezones.php for list of timezones + * supported by PHP. + */ + public string $appTimezone = 'UTC'; + + /** + * -------------------------------------------------------------------------- + * Default Character Set + * -------------------------------------------------------------------------- + * + * This determines which character set is used by default in various methods + * that require a character set to be provided. + * + * @see http://php.net/htmlspecialchars for a list of supported charsets. + */ + public string $charset = 'UTF-8'; + + /** + * -------------------------------------------------------------------------- + * Force Global Secure Requests + * -------------------------------------------------------------------------- + * + * If true, this will force every request made to this application to be + * made via a secure connection (HTTPS). If the incoming request is not + * secure, the user will be redirected to a secure version of the page + * and the HTTP Strict Transport Security (HSTS) header will be set. + */ + public bool $forceGlobalSecureRequests = false; + + /** + * -------------------------------------------------------------------------- + * Reverse Proxy IPs + * -------------------------------------------------------------------------- + * + * If your server is behind a reverse proxy, you must whitelist the proxy + * IP addresses from which CodeIgniter should trust headers such as + * X-Forwarded-For or Client-IP in order to properly identify + * the visitor's IP address. + * + * You need to set a proxy IP address or IP address with subnets and + * the HTTP header for the client IP address. + * + * Here are some examples: + * [ + * '10.0.1.200' => 'X-Forwarded-For', + * '192.168.5.0/24' => 'X-Real-IP', + * ] + * + * @var array + */ + public array $proxyIPs = []; + + /** + * -------------------------------------------------------------------------- + * Content Security Policy + * -------------------------------------------------------------------------- + * + * Enables the Response's Content Secure Policy to restrict the sources that + * can be used for images, scripts, CSS files, audio, video, etc. If enabled, + * the Response object will populate default values for the policy from the + * `ContentSecurityPolicy.php` file. Controllers can always add to those + * restrictions at run time. + * + * For a better understanding of CSP, see these documents: + * + * @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/ + * @see http://www.w3.org/TR/CSP/ + */ + public bool $CSPEnabled = false; +} diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php new file mode 100644 index 0000000..76cd926 --- /dev/null +++ b/app/Config/Autoload.php @@ -0,0 +1,94 @@ +|string> + */ + public $psr4 = [ + APP_NAMESPACE => APPPATH, + ]; + + /** + * ------------------------------------------------------------------- + * Class Map + * ------------------------------------------------------------------- + * The class map provides a map of class names and their exact + * location on the drive. Classes loaded in this manner will have + * slightly faster performance because they will not have to be + * searched for within one or more directories as they would if they + * were being autoloaded through a namespace. + * + * Prototype: + * $classmap = [ + * 'MyClass' => '/path/to/class/file.php' + * ]; + * + * @var array + */ + public $classmap = []; + + /** + * ------------------------------------------------------------------- + * Files + * ------------------------------------------------------------------- + * The files array provides a list of paths to __non-class__ files + * that will be autoloaded. This can be useful for bootstrap operations + * or for loading functions. + * + * Prototype: + * $files = [ + * '/path/to/my/file.php', + * ]; + * + * @var list + */ + public $files = []; + + /** + * ------------------------------------------------------------------- + * Helpers + * ------------------------------------------------------------------- + * Prototype: + * $helpers = [ + * 'form', + * ]; + * + * @var list + */ + public $helpers = []; +} diff --git a/app/Config/Boot/development.php b/app/Config/Boot/development.php new file mode 100644 index 0000000..a868447 --- /dev/null +++ b/app/Config/Boot/development.php @@ -0,0 +1,34 @@ + + */ + public array $file = [ + 'storePath' => WRITEPATH . 'cache/', + 'mode' => 0640, + ]; + + /** + * ------------------------------------------------------------------------- + * Memcached settings + * ------------------------------------------------------------------------- + * Your Memcached servers can be specified below, if you are using + * the Memcached drivers. + * + * @see https://codeigniter.com/user_guide/libraries/caching.html#memcached + * + * @var array + */ + public array $memcached = [ + 'host' => '127.0.0.1', + 'port' => 11211, + 'weight' => 1, + 'raw' => false, + ]; + + /** + * ------------------------------------------------------------------------- + * Redis settings + * ------------------------------------------------------------------------- + * Your Redis server can be specified below, if you are using + * the Redis or Predis drivers. + * + * @var array + */ + public array $redis = [ + 'host' => '127.0.0.1', + 'password' => null, + 'port' => 6379, + 'timeout' => 0, + 'database' => 0, + ]; + + /** + * -------------------------------------------------------------------------- + * Available Cache Handlers + * -------------------------------------------------------------------------- + * + * This is an array of cache engine alias' and class names. Only engines + * that are listed here are allowed to be used. + * + * @var array> + */ + public array $validHandlers = [ + 'dummy' => DummyHandler::class, + 'file' => FileHandler::class, + 'memcached' => MemcachedHandler::class, + 'predis' => PredisHandler::class, + 'redis' => RedisHandler::class, + 'wincache' => WincacheHandler::class, + ]; + + /** + * -------------------------------------------------------------------------- + * Web Page Caching: Cache Include Query String + * -------------------------------------------------------------------------- + * + * Whether to take the URL query string into consideration when generating + * output cache files. Valid options are: + * + * false = Disabled + * true = Enabled, take all query parameters into account. + * Please be aware that this may result in numerous cache + * files generated for the same page over and over again. + * ['q'] = Enabled, but only take into account the specified list + * of query parameters. + * + * @var bool|list + */ + public $cacheQueryString = false; +} diff --git a/app/Config/Constants.php b/app/Config/Constants.php new file mode 100644 index 0000000..17f4871 --- /dev/null +++ b/app/Config/Constants.php @@ -0,0 +1,317 @@ + "guest", + 'STATUS' => "use", + 'EMPTY' => "", + 'DELIMITER_FILE' => "||", + 'DELIMITER_ROLE' => ",", +]); +define('MESSAGES', [ + 'CREATED' => '생성되었습니다.', + 'UPDATED' => '수정되였습니다.', + 'DELETED' => '삭제되였습니다.', + 'SUCCESS' => '작업이 성공적으로 완료되었습니다.', + 'FAILED' => '작업이 실패하였습니다.', + 'NOT_FOUND' => '데이터가 존재하지 않습니다.', + 'NOT_AUTH' => '권한이 없습니다.', + 'NOT_LOGIN' => '로그인이 필요합니다.', + 'NOT_MATCH' => '데이터가 일치하지 않습니다.', + 'NOT_EMPTY' => '데이터가 비어있습니다.', + 'NOT_UNIQUE' => '중복된 데이터가 존재합니다.', + 'NOT_DELETE' => '삭제할 수 없는 데이터가 존재합니다.', + 'NOT_UPDATE' => '수정할 수 없는 데이터가 존재합니다.', + 'NOT_CREATE' => '생성할 수 없는 데이터가 존재합니다.', + 'NOT_SYNC' => '동기화할 수 없는 데이터가 존재합니다.', + 'NOT_SYNC_RESULT' => '동기화 결과가 실패하였습니다.', + 'NOT_SYNC_SUCCESS' => '동기화 결과가 성공하였습니다.', + 'NOT_SYNC_ERROR' => '동기화 결과가 실패하였습니다.', + 'NOT_SYNC_NOTHING' => '동기화할 데이터가 없습니다.', + 'NOT_SYNC_NOTHING_RESULT' => '동기화 결과가 없습니다.', + 'NOT_SYNC_NOTHING_ERROR' => '동기화 결과가 없습니다.', +]); +//URL +define('URLS', [ + 'LOGIN' => '/user/login', + 'GOOGLE_LOGIN' => '/user/google_login', + 'SIGNUP' => '/user/signup', + 'LOGOUT' => '/user/logout', +]); +//회원ROLE +define('ROLES', [ + 'guest', + 'user', + 'vip', + 'manager', + 'cloudflare', + 'director', + 'master', +]); +//SESSION 관련 +define('SESSION_NAMES', [ + 'RETURN_URL' => "return_url", + 'RETURN_MSG' => "return_message", + 'ISLOGIN' => "islogined", + 'AUTH' => 'auth', +]); +//메신저 관련 +define("MESSENGERS", [ + "skype" => [ + "url" => "//join.skype.com/invite/uKUgXfZThSQC", + "icon" => '스카이프', + "id" => '', + ], + "discord" => [ + "url" => "//discord.gg/k6nQg84N", + "icon" => '디스코드', + "id" => '', + ], + "telegram" => [ + "url" => "//t.me/daemonidc", + "icon" => '텔레그램', + "id" => '@daemonidc', + ], + "kakaotalk" => [ + "url" => "//t.me/daemonidc", + "icon" => '카카오톡', + "id" => '', + ], +]); +//아이콘 및 Sound관련 +define('ICONS', [ + 'LOGO' => '', + 'EXCEL' => '', + 'PDF' => '', + 'GOOGLE' => 'Google', + 'MEMBER' => '', + 'LOGIN' => '', + 'LOGOUT' => '', + 'HOME' => '', + 'MENU' => '', + 'NEW' => '', + 'REPLY' => '', + 'DATABASE' => '', + 'DELETE' => '', + 'REBOOT' => '', + 'RELOAD' => '', + 'SETUP' => '', + 'FLAG' => '', + 'SEARCH' => '', + 'PLAY' => '', + 'CART' => '', + 'CARD' => '', + 'DEPOSIT' => '', + 'DESKTOP' => '', + 'UP' => '', + 'DOWN' => '', + 'LEFT' => '', + 'RIGHT' => '', + 'IMAGE_FILE' => '', + 'CLOUD' => '', + 'SIGNPOST' => '', + 'LOCK' => '', + 'UNLOCK' => '', + 'BOX' => '', + 'BOXS' => '', +]); +//배너관련 +define('TOP_BANNER', [ + 'default' => '', + 'aboutus' => '', + 'member' => '', + 'hosting' => '', + 'serverdevice' => '', + 'service' => '', + 'support' => '', +]); +//소리관련 +define('AUDIOS', [ + 'Alram_GetEmail' => '', +]); +//Layout관련 +define('KEYWORD', '일본IDC 일본서버 일본 서버 일본호스팅 서버호스팅 디도스 공격 해외 호스팅 DDOS 방어 ddos 의뢰 디도스 보안 일본 단독서버 가상서버'); +define('LAYOUTS', [ + 'empty' => [ + 'title' => KEYWORD, + 'path' => 'layouts' . DIRECTORY_SEPARATOR . 'empty', + 'metas' => [ + '', + '', + '', + '', + '', + '', + '', + '', + '', + ], + 'stylesheets' => [ + '', + '', + '', + ], + 'javascripts' => [ + '', + ], + ], + 'front' => [ + 'title' => KEYWORD, + 'path' => 'layouts' . DIRECTORY_SEPARATOR . 'front', + 'topmenus' => ['aboutus', 'hosting', 'service', 'support'], + 'metas' => [ + '', + '', + '', + '', + '', + '', + '', + '', + '', + ], + 'stylesheets' => [ + '', + '', + '', + '', + '', + '', + '', + ], + 'javascripts' => [ + '', + '', + '', + '', + '', + ], + ], + 'admin' => [ + 'title' => '관리자화면', + 'path' => 'layouts' . DIRECTORY_SEPARATOR . 'admin', + 'metas' => [ + '', + '', + '', + '', + '', + '', + '', + '', + '', + ], + 'stylesheets' => [ + '', + '', + '', + '', + '', + '', + '', + ], + 'javascripts' => [ + '', + '', + '', + '', + '', + ], + ], +]); + +//List의 Page당 갯수 +define('DEFAULT_LIST_PERPAGE', $_ENV['LIST_PERPAGE'] ?? $_SERVER['LIST_PERPAGE'] ?? 20); \ No newline at end of file diff --git a/app/Config/ContentSecurityPolicy.php b/app/Config/ContentSecurityPolicy.php new file mode 100644 index 0000000..2ac41a7 --- /dev/null +++ b/app/Config/ContentSecurityPolicy.php @@ -0,0 +1,176 @@ +|string|null + */ + public $defaultSrc; + + /** + * Lists allowed scripts' URLs. + * + * @var list|string + */ + public $scriptSrc = 'self'; + + /** + * Lists allowed stylesheets' URLs. + * + * @var list|string + */ + public $styleSrc = 'self'; + + /** + * Defines the origins from which images can be loaded. + * + * @var list|string + */ + public $imageSrc = 'self'; + + /** + * Restricts the URLs that can appear in a page's `` element. + * + * Will default to self if not overridden + * + * @var list|string|null + */ + public $baseURI; + + /** + * Lists the URLs for workers and embedded frame contents + * + * @var list|string + */ + public $childSrc = 'self'; + + /** + * Limits the origins that you can connect to (via XHR, + * WebSockets, and EventSource). + * + * @var list|string + */ + public $connectSrc = 'self'; + + /** + * Specifies the origins that can serve web fonts. + * + * @var list|string + */ + public $fontSrc; + + /** + * Lists valid endpoints for submission from `
` tags. + * + * @var list|string + */ + public $formAction = 'self'; + + /** + * Specifies the sources that can embed the current page. + * This directive applies to ``, ` + + + + + + + \ No newline at end of file diff --git a/app/Views/templates/download.php b/app/Views/templates/download.php new file mode 100644 index 0000000..3c52984 --- /dev/null +++ b/app/Views/templates/download.php @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + +
$field ?>
\ No newline at end of file diff --git a/app/Views/templates/front/index_footer.php b/app/Views/templates/front/index_footer.php new file mode 100644 index 0000000..e69de29 diff --git a/app/Views/templates/front/index_header.php b/app/Views/templates/front/index_header.php new file mode 100644 index 0000000..e35fef7 --- /dev/null +++ b/app/Views/templates/front/index_header.php @@ -0,0 +1,87 @@ + + \ No newline at end of file diff --git a/app/Views/welcome_message.php b/app/Views/welcome_message.php new file mode 100644 index 0000000..c18eca3 --- /dev/null +++ b/app/Views/welcome_message.php @@ -0,0 +1,331 @@ + + + + + Welcome to CodeIgniter 4! + + + + + + + + + + + +
+ + + +
+ +

Welcome to CodeIgniter

+ +

The small framework with powerful features

+ +
+ +
+ + + +
+ +

About this page

+ +

The page you are looking at is being generated dynamically by CodeIgniter.

+ +

If you would like to edit this page you will find it located at:

+ +
app/Views/welcome_message.php
+ +

The corresponding controller for this page can be found at:

+ +
app/Controllers/Home.php
+ +
+ +
+ +
+ +

Go further

+ +

+ + Learn +

+ +

The User Guide contains an introduction, tutorial, a number of "how to" + guides, and then reference documentation for the components that make up + the framework. Check the User Guide !

+ +

+ + Discuss +

+ +

CodeIgniter is a community-developed open source project, with several + venues for the community members to gather and exchange ideas. View all + the threads on CodeIgniter's forum, or chat on Slack !

+ +

+ + Contribute +

+ +

CodeIgniter is a community driven project and accepts contributions + of code and documentation from the community. Why not + + join us ?

+ +
+ +
+ + + +
+
+ +

Page rendered in {elapsed_time} seconds using {memory_usage} MB of memory.

+ +

Environment:

+ +
+ +
+ +

© CodeIgniter Foundation. CodeIgniter is open source project released under the MIT + open source licence.

+ +
+ +
+ + + + + + + + + diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..69df4e1 --- /dev/null +++ b/app/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/builds b/builds new file mode 100644 index 0000000..cc2ca08 --- /dev/null +++ b/builds @@ -0,0 +1,125 @@ +#!/usr/bin/env php + 'vcs', + 'url' => GITHUB_URL, + ]; + } + + $array['require']['codeigniter4/codeigniter4'] = 'dev-develop'; + unset($array['require']['codeigniter4/framework']); + } else { + unset($array['minimum-stability']); + + if (isset($array['repositories'])) { + foreach ($array['repositories'] as $i => $repository) { + if ($repository['url'] === GITHUB_URL) { + unset($array['repositories'][$i]); + break; + } + } + + if (empty($array['repositories'])) { + unset($array['repositories']); + } + } + + $array['require']['codeigniter4/framework'] = LATEST_RELEASE; + unset($array['require']['codeigniter4/codeigniter4']); + } + + file_put_contents($file, json_encode($array, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL); + + $modified[] = $file; + } else { + echo 'Warning: Unable to decode composer.json! Skipping...' . PHP_EOL; + } + } else { + echo 'Warning: Unable to read composer.json! Skipping...' . PHP_EOL; + } +} + +$files = [ + __DIR__ . DIRECTORY_SEPARATOR . 'app/Config/Paths.php', + __DIR__ . DIRECTORY_SEPARATOR . 'phpunit.xml.dist', + __DIR__ . DIRECTORY_SEPARATOR . 'phpunit.xml', +]; + +foreach ($files as $file) { + if (is_file($file)) { + $contents = file_get_contents($file); + + if ($dev) { + $contents = str_replace('vendor/codeigniter4/framework', 'vendor/codeigniter4/codeigniter4', $contents); + } else { + $contents = str_replace('vendor/codeigniter4/codeigniter4', 'vendor/codeigniter4/framework', $contents); + } + + file_put_contents($file, $contents); + + $modified[] = $file; + } +} + +if ($modified === []) { + echo 'No files modified.' . PHP_EOL; +} else { + echo 'The following files were modified:' . PHP_EOL; + + foreach ($modified as $file) { + echo " * {$file}" . PHP_EOL; + } + + echo 'Run `composer update` to sync changes with your vendor folder.' . PHP_EOL; +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..4d161ea --- /dev/null +++ b/composer.json @@ -0,0 +1,53 @@ +{ + "name": "codeigniter4/appstarter", + "description": "CodeIgniter4 starter app", + "license": "MIT", + "type": "project", + "homepage": "https://codeigniter.com", + "support": { + "forum": "https://forum.codeigniter.com/", + "source": "https://github.com/codeigniter4/CodeIgniter4", + "slack": "https://codeigniterchat.slack.com" + }, + "require": { + "php": "^8.2", + "cloudflare/sdk": "^1.3", + "codeigniter4/framework": "^4.5", + "google/apiclient": "^2.15.0", + "guzzlehttp/guzzle": "^7.9", + "io-developer/php-whois": "^4.1", + "phpoffice/phpspreadsheet": "^1.27", + "symfony/css-selector": "^7.1", + "symfony/dom-crawler": "^7.1", + "tinymce/tinymce": "^7.3", + "twbs/bootstrap": "5.3.3" + }, + "require-dev": { + "fakerphp/faker": "^1.9", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^10.5.16" + }, + "autoload": { + "psr-4": { + "App\\": "app/", + "Config\\": "app/Config/" + }, + "exclude-from-classmap": [ + "**/Database/Migrations/**" + ] + }, + "autoload-dev": { + "psr-4": { + "Tests\\Support\\": "tests/_support" + } + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true, + "process-timeout": 600 + }, + "scripts": { + "test": "phpunit" + } +} diff --git a/env b/env new file mode 100644 index 0000000..f359ec2 --- /dev/null +++ b/env @@ -0,0 +1,69 @@ +#-------------------------------------------------------------------- +# Example Environment Configuration file +# +# This file can be used as a starting point for your own +# custom .env files, and contains most of the possible settings +# available in a default install. +# +# By default, all of the settings are commented out. If you want +# to override the setting, you must un-comment it by removing the '#' +# at the beginning of the line. +#-------------------------------------------------------------------- + +#-------------------------------------------------------------------- +# ENVIRONMENT +#-------------------------------------------------------------------- + +# CI_ENVIRONMENT = production + +#-------------------------------------------------------------------- +# APP +#-------------------------------------------------------------------- + +# app.baseURL = '' +# If you have trouble with `.`, you could also use `_`. +# app_baseURL = '' +# app.forceGlobalSecureRequests = false +# app.CSPEnabled = false + +#-------------------------------------------------------------------- +# DATABASE +#-------------------------------------------------------------------- + +# database.default.hostname = localhost +# database.default.database = ci4 +# database.default.username = root +# database.default.password = root +# database.default.DBDriver = MySQLi +# database.default.DBPrefix = +# database.default.port = 3306 + +# If you use MySQLi as tests, first update the values of Config\Database::$tests. +# database.tests.hostname = localhost +# database.tests.database = ci4_test +# database.tests.username = root +# database.tests.password = root +# database.tests.DBDriver = MySQLi +# database.tests.DBPrefix = +# database.tests.charset = utf8mb4 +# database.tests.DBCollat = utf8mb4_general_ci +# database.tests.port = 3306 + +#-------------------------------------------------------------------- +# ENCRYPTION +#-------------------------------------------------------------------- + +# encryption.key = + +#-------------------------------------------------------------------- +# SESSION +#-------------------------------------------------------------------- + +# session.driver = 'CodeIgniter\Session\Handlers\FileHandler' +# session.savePath = null + +#-------------------------------------------------------------------- +# LOGGER +#-------------------------------------------------------------------- + +# logger.threshold = 4 diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..b408a99 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,63 @@ + + + + + + + + + + + + + ./tests + + + + + + + + + + ./app + + + ./app/Views + ./app/Config/Routes.php + + + + + + + + + + + + + + + diff --git a/preload.php b/preload.php new file mode 100644 index 0000000..75d86f5 --- /dev/null +++ b/preload.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +/* + *--------------------------------------------------------------- + * Sample file for Preloading + *--------------------------------------------------------------- + * See https://www.php.net/manual/en/opcache.preloading.php + * + * How to Use: + * 0. Copy this file to your project root folder. + * 1. Set the $paths property of the preload class below. + * 2. Set opcache.preload in php.ini. + * php.ini: + * opcache.preload=/path/to/preload.php + */ + +// Load the paths config file +require __DIR__ . '/app/Config/Paths.php'; + +// Path to the front controller +define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR); + +class preload +{ + /** + * @var array Paths to preload. + */ + private array $paths = [ + [ + 'include' => __DIR__ . '/vendor/codeigniter4/framework/system', // Change this path if using manual installation + 'exclude' => [ + '/system/bootstrap.php', + // Not needed if you don't use them. + '/system/Database/OCI8/', + '/system/Database/Postgre/', + '/system/Database/SQLite3/', + '/system/Database/SQLSRV/', + // Not needed. + '/system/Database/Seeder.php', + '/system/Test/', + '/system/Language/', + '/system/CLI/', + '/system/Commands/', + '/system/Publisher/', + '/system/ComposerScripts.php', + '/Views/', + // Errors occur. + '/system/Config/Routes.php', + '/system/ThirdParty/', + ], + ], + ]; + + public function __construct() + { + $this->loadAutoloader(); + } + + private function loadAutoloader(): void + { + $paths = new Config\Paths(); + require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'Boot.php'; + + CodeIgniter\Boot::preload($paths); + } + + /** + * Load PHP files. + */ + public function load(): void + { + foreach ($this->paths as $path) { + $directory = new RecursiveDirectoryIterator($path['include']); + $fullTree = new RecursiveIteratorIterator($directory); + $phpFiles = new RegexIterator( + $fullTree, + '/.+((? $file) { + foreach ($path['exclude'] as $exclude) { + if (str_contains($file[0], $exclude)) { + continue 2; + } + } + + require_once $file[0]; + echo 'Loaded: ' . $file[0] . "\n"; + } + } + } +} + +(new preload())->load(); diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..abac3cb --- /dev/null +++ b/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 diff --git a/public/css/admin.css b/public/css/admin.css new file mode 100644 index 0000000..4576f3b --- /dev/null +++ b/public/css/admin.css @@ -0,0 +1,81 @@ +/* ------------------------------------------------------------ + * Name : admin.css + * Desc : Admin StyleSheet + * Created : 2016/9/11 Tri-aBility by Junheum,Choi + * Updated : + ------------------------------------------------------------ */ +* { + margin: 0px; + padding: 0px; + border: 0px; +} + +html, +body { + height: 100%; +} + +div.layout_top { + height: 51px; + margin-bottom: 10px; + border-top: 1px solid gray; + border-bottom: 1px solid gray; + background-color: #e8e9ea; +} + +div.layout_bottom { + height: 51px; + margin-top: 10px; + border-top: 1px solid gray; + border-bottom: 1px solid gray; + background-color: #efefef; + background-color: #e8e9ea; +} + +table.layout_middle { + width: 100%; + /* border: 1px solid blue; */ +} + +table.layout_middle td.layout_left { + vertical-align: top; + /* border: 1px solid red; */ +} + +table.layout_middle td.layout_right { + padding-top: 5px; + padding-left: 23px; + padding-right: 5px; + padding-bottom: 5px; + /* overflow: auto; */ + /* border: 1px solid blue; */ +} + +table.layout_middle td.layout_right div.layout_header { + /*content 헤더라인*/ + height: 55px; + padding-top: 15px; + background-color: #e7e7e7; + border-top: 1px solid gray; + border-left: 1px solid gray; + border-right: 1px solid gray; + border-radius: 15px 15px 0px 0px; +} + +table.layout_middle td.layout_right div.layout_header li.nav-item {} + +table.layout_middle td.layout_right div.layout_footer { + /*content 하단라인*/ + height: 20px; + border-left: 1px solid gray; + border-right: 1px solid gray; + border-bottom: 1px solid gray; + border-radius: 0px 0px 15px 15px; +} + +table.layout_middle td.layout_right div.layout_content { + /*content 부분*/ + padding: 5px; + border-left: 1px solid gray; + border-right: 1px solid gray; +} \ No newline at end of file diff --git a/public/css/admin/form.css b/public/css/admin/form.css new file mode 100644 index 0000000..7440ad5 --- /dev/null +++ b/public/css/admin/form.css @@ -0,0 +1,28 @@ +/* create,modify,view 페이지용 */ +div.action_form { + /* 블록 요소로 변경 */ + margin-left: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + margin-right: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + /* border: 1px solid blue; */ + /* table-layout: fixed; 고정 레이아웃 */ + border-collapse: collapse; + /* 테두리 결합 */ +} + +div.action_form table {} + +div.action_form table th { + background-color: #f0f0f0; +} + +div.action_form table td { + text-align: center; + word-wrap: break-word; + /* 긴 단어 강제 줄바꿈 */ + white-space: normal; + /* 자동 줄바꿈 */ +} + +/* create,modify,view 페이지용 */ \ No newline at end of file diff --git a/public/css/admin/index.css b/public/css/admin/index.css new file mode 100644 index 0000000..9dc021e --- /dev/null +++ b/public/css/admin/index.css @@ -0,0 +1,165 @@ +/* create,modify,view 페이지용 */ +table.action_form { + /* 블록 요소로 변경 */ + margin-left: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + margin-right: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + /* border: 1px solid blue; */ + /* table-layout: fixed; 고정 레이아웃 */ + border-collapse: collapse; + /* 테두리 결합 */ +} + +table.action_form th { + text-align: center; + background-color: #f5f5f5; +} + +table.action_form td { + text-align: center; + word-wrap: break-word; + /* 긴 단어 강제 줄바꿈 */ + white-space: normal; + /* 자동 줄바꿈 */ +} + +/* create,modify,view 페이지용 */ + +/*조건검색*/ +nav.index_top nav.condition { + border-color: 1px solid red; +} + +/*검색*/ +nav.index_top nav.search { + position: relative; + border-color: 1px solid red; +} + +nav.index_top nav.search input[type="text"] { + width: 150px; +} + +/*검색submit*/ +nav.index_top nav.search input[type="submit"] { + font-weight: bold; + width: 70px; + color: white; + background-color: #555555; +} + +/*검색submit*/ +nav.index_top nav.search a.excel { + position: absolute; + top: -5px; + right: -45px; + /* border-color: 1px solid red; */ +} + +/*페이지정보*/ +nav.index_top nav.pageinfo { + font-weight: bold; + /* border-color: 1px solid red; */ +} + +/* Table 부분 */ +table.index_table { + width: 100%; + /* table-layout: fixed; */ + border-collapse: collapse; +} + +table.index_table thead th { + white-space: nowrap; + padding-top: 15px; + padding-bottom: 15px; + font-weight: bold; + border-top: 2px solid black; + border-bottom: 1px solid silver; + background-color: #f5f5f5; + text-align: center; + /* border:1px solid silver; */ +} + +table.index_table thead th.index_head_short_column { + width: 80px; +} + +table.index_table thead th:active { + cursor: grabbing; +} + +table.index_table tbody th { + text-align: center; + /* border:1px solid silver; */ +} + +div.index_batchjob { + padding-top: 15px; + text-align: center; + /* border: 1px solid red; */ +} + +div.index_batchjob ul.nav li.nav-item { + margin-left: 10px; + /* border: 1px solid red; */ +} + +div.index_pagination { + margin-top: 20px; + /* border: 1px solid red; */ +} + +div.index_pagination ul.pagination { + /* border: 1px solid green; */ + width: fit-content; + /* UL의 너비를 내용에 맞춤 */ + margin: 0 auto; + /* 좌우 마진을 자동으로 설정하여 중앙 배치 */ + padding: 0; + list-style: none; + /* 기본 점 스타일 제거 (옵션) */ +} + +/* pager의 template가 default_full일경우 사용 */ +/* div.index_pagination ul.pagination li { + margin-left: 5px; +} + +div.index_pagination ul.pagination li a { + padding: 5px 10px 5px 10px; + font-size: 1.5rem; + color: white; + background-color: #808080; +} + +div.index_pagination ul.pagination li a:hover { + border: 1px solid black; +} + +div.index_pagination ul.pagination li.active a { + color: black; + border: 1px solid #808080; +} */ + +div.index_bottom { + padding-top: 15px; + text-align: center; + word-wrap: break-word; + /* 긴 단어 강제 줄바꿈 */ + white-space: normal; + /* 자동 줄바꿈 */ + /* border: 1px solid red; */ +} + +div.index_bottom div.index_action_form { + margin-top: 20px; + /* border: 1px solid red; */ +} + +div.index_bottom div.index_action_form iframe { + width: 100%; + border: none; + /* border: 1px solid blue; */ +} \ No newline at end of file diff --git a/public/css/admin/left_menu.css b/public/css/admin/left_menu.css new file mode 100644 index 0000000..80ca2aa --- /dev/null +++ b/public/css/admin/left_menu.css @@ -0,0 +1,56 @@ +div#left_menu { + position: fixed; + margin-top: 70px; + z-index: 100; + border: 1px solid silver; +} + +div#left_menu div#menu_button { + position: absolute; + top: -1px; + right: -20px; + width: 20px; + height: 160px; + cursor: pointer; + writing-mode: vertical-rl; + /* 세로로 글자를 출력 */ + text-orientation: upright; + /* 글자가 직립되도록 설정 */ + border-top: 1px solid silver; + border-right: 1px solid silver; + border-bottom: 1px solid silver; + border-radius: 0px 5px 5px 0px; + background-color: #e8e9ea; +} + +div#left_menu div.accordion { + display: none; + width: 20px; +} + +div#left_menu div.accordion div.main { + height: 50px; + padding-top: 15px; + padding-left: 10px; + background-color: white; + border-bottom: 1px solid silver; +} + +div#left_menu div.accordion div.accordion-item { + height: 50px; + padding-top: 15px; + background-color: #eeeeee; + border-bottom: 1px solid silver; +} + +div#left_menu div.accordion div.accordion-item:hover { + background-color: silver; +} + +div#left_menu div.accordion div.accordion-item a { + padding-left: 20px; +} + +div#left_menu div.accordion div.accordion-collapse a { + padding-left: 30px; +} \ No newline at end of file diff --git a/public/css/admin/member_link.css b/public/css/admin/member_link.css new file mode 100644 index 0000000..38ed839 --- /dev/null +++ b/public/css/admin/member_link.css @@ -0,0 +1,17 @@ +nav.top_menu ul.member-link{ + /* border:1px solid red; */ + color:#3a37f3; + padding-right:20px; +} + +nav.top_menu ul.member-link a{ + color:#3a37f3; +} + +nav.top_menu ul.member-link ul.dropdown-menu li:hover{ + background-color: #eaeaea; +} + +nav.top_menu ul.member-link ul.dropdown-menu li a{ + padding-left:10px; +} \ No newline at end of file diff --git a/public/css/admin/resizeTable.css b/public/css/admin/resizeTable.css new file mode 100644 index 0000000..8c4e075 --- /dev/null +++ b/public/css/admin/resizeTable.css @@ -0,0 +1,67 @@ +.rtc-wrapper table.rtc-table { + border-collapse: collapse; + white-space: nowrap; + margin: 0; +} + +.rtc-wrapper table.rtc-table thead, +.rtc-wrapper table.rtc-table tbody, +.rtc-wrapper table.rtc-table tfoot { + margin: 0; +} + +.rtc-wrapper table.rtc-table thead tr, +.rtc-wrapper table.rtc-table tbody tr, +.rtc-wrapper table.rtc-table tfoot tr { + margin: 0; +} + +.rtc-wrapper table.rtc-table thead tr th, +.rtc-wrapper table.rtc-table thead tr td, +.rtc-wrapper table.rtc-table tbody tr th, +.rtc-wrapper table.rtc-table tbody tr td, +.rtc-wrapper table.rtc-table tfoot tr th, +.rtc-wrapper table.rtc-table tfoot tr td { + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.rtc-wrapper table.rtc-table.rtc-table-resizing { + cursor: col-resize; +} + +.rtc-wrapper table.rtc-table.rtc-table-resizing thead, +.rtc-wrapper table.rtc-table.rtc-table-resizing thead > th, +.rtc-wrapper table.rtc-table.rtc-table-resizing thead > th > a { + cursor: col-resize; +} + +.rtc-wrapper table.rtc-table thead tr.invisible, +.rtc-wrapper table.rtc-table thead tr.invisible th { + border: none; + margin: 0; + padding: 0; + height: 0 !important; +} + +.rtc-wrapper .rtc-handle-container { + position: relative; + padding: 0; + margin: 0; + border: 0; +} + +.rtc-wrapper .rtc-handle-container .rtc-handle { + position: absolute; + width: 6.5px; + margin-left: -3.575px; + z-index: 2; + cursor: col-resize; +} + +.rtc-wrapper .rtc-handle-container .rtc-handle:last-of-type { + width: 4.5px; + margin-left: -4.95px; +} \ No newline at end of file diff --git a/public/css/common/style.css b/public/css/common/style.css new file mode 100644 index 0000000..54b28ae --- /dev/null +++ b/public/css/common/style.css @@ -0,0 +1,55 @@ +/* ------------------------------------------------------------ + * Name : admin.css + * Desc : Admin StyleSheet + * Created : 2016/9/11 Tri-aBility by Junheum,Choi + * Updated : + ------------------------------------------------------------ */ +@charset "utf-8"; + +/* user class */ +h1, +h2, +h3, +h4, +h5, +h6, +strong, +th, +.bold { + font-weight: 500; +} + +input[type=text], +input[type=password] { + display: inline-block; + border: 1px solid #ccc; + border-radius: 4px; + box-sizing: border-box; + white-space: nowrap; +} + +select, +textarea, +button { + display: inline-block; + border: 1px solid #ccc; + border-radius: 4px; + box-sizing: border-box; + white-space: nowrap; +} + +a:link { + text-decoration: none; +} + +a:visited { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:active { + text-decoration: underline; +} \ No newline at end of file diff --git a/public/css/empty.css b/public/css/empty.css new file mode 100644 index 0000000..1e4df2e --- /dev/null +++ b/public/css/empty.css @@ -0,0 +1,11 @@ +/* ------------------------------------------------------------ + * Name : admin.css + * Desc : Admin StyleSheet + * Created : 2016/9/11 Tri-aBility by Junheum,Choi + * Updated : + ------------------------------------------------------------ */ +* { + margin: 0px; + padding: 0px; + border: 0px; +} \ No newline at end of file diff --git a/public/css/front.css b/public/css/front.css new file mode 100644 index 0000000..e2255e4 --- /dev/null +++ b/public/css/front.css @@ -0,0 +1,81 @@ +/* ------------------------------------------------------------ + * Name : front.css + * Desc : Admin StyleSheet + * Created : 2016/9/11 Tri-aBility by Junheum,Choi + * Updated : + ------------------------------------------------------------ */ +* { + margin: 0px; + padding: 0px; + border: 0px; +} + +html, +body { + height: 100%; +} + +div.layout_top { + height: 51px; + margin-bottom: 10px; + border-top: 1px solid gray; + border-bottom: 1px solid gray; + background-color: #e8e9ea; +} + +div.layout_bottom { + height: 51px; + margin-top: 10px; + border-top: 1px solid gray; + border-bottom: 1px solid gray; + background-color: #efefef; + background-color: #e8e9ea; +} + +table.layout_middle { + width: 100%; + /* border: 1px solid blue; */ +} + +table.layout_middle td.layout_left { + vertical-align: top; + /* border: 1px solid red; */ +} + +table.layout_middle td.layout_right { + padding-top: 5px; + padding-left: 23px; + padding-right: 5px; + padding-bottom: 5px; + /* overflow: auto; */ + /* border: 1px solid blue; */ +} + +table.layout_middle td.layout_right div.layout_header { + /*content 헤더라인*/ + height: 55px; + padding-top: 15px; + background-color: #e7e7e7; + border-top: 1px solid gray; + border-left: 1px solid gray; + border-right: 1px solid gray; + border-radius: 15px 15px 0px 0px; +} + +table.layout_middle td.layout_right div.layout_header li.nav-item {} + +table.layout_middle td.layout_right div.layout_footer { + /*content 하단라인*/ + height: 20px; + border-left: 1px solid gray; + border-right: 1px solid gray; + border-bottom: 1px solid gray; + border-radius: 0px 0px 15px 15px; +} + +table.layout_middle td.layout_right div.layout_content { + /*content 부분*/ + padding: 5px; + border-left: 1px solid gray; + border-right: 1px solid gray; +} \ No newline at end of file diff --git a/public/css/front/copyright.css b/public/css/front/copyright.css new file mode 100644 index 0000000..45a4a77 --- /dev/null +++ b/public/css/front/copyright.css @@ -0,0 +1,29 @@ +div#copyright{ + width:100%; + height:300px; + padding-top:30px; + padding-bottom:30px; + background-color:#2d2e2e; + color:white; +} + +div#copyright div#content_bottom{ + color:white; + text-align:left; + /* border-left:1px solid silver; + border-right:1px solid silver; */ +} + +div#copyright div#content_bottom .item{ + padding-top:5px; + padding-left:5px; + padding-right:5px; + border-top:1px solid silver; + border-left:1px solid silver; + border-right:1px solid silver; +} + +div#copyright div#content_bottom div.company_info{ + padding:10px; + border:1px solid silver; +} diff --git a/public/css/front/form.css b/public/css/front/form.css new file mode 100644 index 0000000..7440ad5 --- /dev/null +++ b/public/css/front/form.css @@ -0,0 +1,28 @@ +/* create,modify,view 페이지용 */ +div.action_form { + /* 블록 요소로 변경 */ + margin-left: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + margin-right: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + /* border: 1px solid blue; */ + /* table-layout: fixed; 고정 레이아웃 */ + border-collapse: collapse; + /* 테두리 결합 */ +} + +div.action_form table {} + +div.action_form table th { + background-color: #f0f0f0; +} + +div.action_form table td { + text-align: center; + word-wrap: break-word; + /* 긴 단어 강제 줄바꿈 */ + white-space: normal; + /* 자동 줄바꿈 */ +} + +/* create,modify,view 페이지용 */ \ No newline at end of file diff --git a/public/css/front/index.css b/public/css/front/index.css new file mode 100644 index 0000000..8a66b59 --- /dev/null +++ b/public/css/front/index.css @@ -0,0 +1,168 @@ +/* create,modify,view 페이지용 */ +table.action_form { + /* 블록 요소로 변경 */ + margin-left: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + margin-right: auto; + /* 자동 여백을 이용한 가로 가운데 정렬 */ + /* border: 1px solid blue; */ + /* table-layout: fixed; 고정 레이아웃 */ + border-collapse: collapse; + /* 테두리 결합 */ +} + +table.action_form th { + text-align: center; + background-color: #f5f5f5; +} + +table.action_form td { + text-align: center; + word-wrap: break-word; + /* 긴 단어 강제 줄바꿈 */ + white-space: normal; + /* 자동 줄바꿈 */ +} + +/* create,modify,view 페이지용 */ + +/*조건검색*/ +nav.index_top nav.condition { + border-color: 1px solid red; +} + +/*검색*/ +nav.index_top nav.search { + position: relative; + height: 30px; + border-color: 1px solid red; +} + +nav.index_top nav.search input[type="text"] { + width: 200px; + height: 30px; +} + +/*검색submit*/ +nav.index_top nav.search input[type="submit"] { + font-weight: bold; + width: 80px; + height: 30px; + color: white; + background-color: #555555; +} + +/*검색submit*/ +nav.index_top nav.search a.excel { + position: absolute; + top: -9px; + right: -45px; + /* border-color: 1px solid red; */ +} + +/*페이지정보*/ +nav.index_top nav.pageinfo { + font-weight: bold; + /* border-color: 1px solid red; */ +} + +/* Table 부분 */ +table.index_table { + width: 100%; + /* table-layout: fixed; */ + border-collapse: collapse; +} + +table.index_table thead th { + white-space: nowrap; + padding-top: 15px; + padding-bottom: 15px; + font-weight: bold; + border-top: 2px solid black; + border-bottom: 1px solid silver; + background-color: #f5f5f5; + text-align: center; + /* border:1px solid silver; */ +} + +table.index_table thead th.index_head_short_column { + width: 80px; +} + +table.index_table thead th:active { + cursor: grabbing; +} + +table.index_table tbody th { + text-align: center; + /* border:1px solid silver; */ +} + +div.index_batchjob { + padding-top: 15px; + text-align: center; + /* border: 1px solid red; */ +} + +div.index_batchjob ul.nav li.nav-item { + margin-left: 10px; + /* border: 1px solid red; */ +} + +div.index_pagination { + margin-top: 20px; + /* border: 1px solid red; */ +} + +div.index_pagination ul.pagination { + /* border: 1px solid green; */ + width: fit-content; + /* UL의 너비를 내용에 맞춤 */ + margin: 0 auto; + /* 좌우 마진을 자동으로 설정하여 중앙 배치 */ + padding: 0; + list-style: none; + /* 기본 점 스타일 제거 (옵션) */ +} + +/* pager의 template가 default_full일경우 사용 */ +/* div.index_pagination ul.pagination li { + margin-left: 5px; +} + +div.index_pagination ul.pagination li a { + padding: 5px 10px 5px 10px; + font-size: 1.5rem; + color: white; + background-color: #808080; +} + +div.index_pagination ul.pagination li a:hover { + border: 1px solid black; +} + +div.index_pagination ul.pagination li.active a { + color: black; + border: 1px solid #808080; +} */ + +div.index_bottom { + padding-top: 15px; + text-align: center; + word-wrap: break-word; + /* 긴 단어 강제 줄바꿈 */ + white-space: normal; + /* 자동 줄바꿈 */ + /* border: 1px solid red; */ +} + +div.index_bottom div.index_action_form { + margin-top: 20px; + /* border: 1px solid red; */ +} + +div.index_bottom div.index_action_form iframe { + width: 100%; + border: none; + /* border: 1px solid blue; */ +} \ No newline at end of file diff --git a/public/css/front/left_menu.css b/public/css/front/left_menu.css new file mode 100644 index 0000000..cc89e40 --- /dev/null +++ b/public/css/front/left_menu.css @@ -0,0 +1,56 @@ +div#left_menu { + position: fixed; + margin-top: 60px; + z-index: 100; + border: 1px solid silver; +} + +div#left_menu div#menu_button { + position: absolute; + top: -1px; + right: -21px; + width: 20px; + height: 160px; + cursor: pointer; + writing-mode: vertical-rl; + /* 세로로 글자를 출력 */ + text-orientation: upright; + /* 글자가 직립되도록 설정 */ + border-top: 1px solid silver; + border-right: 1px solid silver; + border-bottom: 1px solid silver; + border-radius: 0px 5px 5px 0px; + background-color: #e8e9ea; +} + +div#left_menu div.accordion { + display: none; + width: 20px; +} + +div#left_menu div.accordion div.main { + height: 50px; + padding-top: 15px; + padding-left: 10px; + background-color: white; + border-bottom: 1px solid silver; +} + +div#left_menu div.accordion div.accordion-item { + height: 50px; + padding-top: 15px; + background-color: #eeeeee; + border-bottom: 1px solid silver; +} + +div#left_menu div.accordion div.accordion-item:hover { + background-color: silver; +} + +div#left_menu div.accordion div.accordion-item a { + padding-left: 20px; +} + +div#left_menu div.accordion div.accordion-collapse a { + padding-left: 30px; +} \ No newline at end of file diff --git a/public/css/front/login.css b/public/css/front/login.css new file mode 100644 index 0000000..3f80970 --- /dev/null +++ b/public/css/front/login.css @@ -0,0 +1,80 @@ +.login-page { + background-image: url('/images/login-background.jpg'); + background-size: cover; + background-position: center; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; +} + +.login-content { + background-color: rgba(255, 255, 255, 0.9); + border-radius: 10px; + padding: 40px; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); + width: 400px; +} + +.login-title { + text-align: center; + margin-bottom: 30px; + color: #333; +} + +.input-group { + margin-bottom: 20px; +} + +.input-group label { + display: block; + margin-bottom: 5px; + color: #555; +} + +.input-group input { + width: 100%; + padding: 10px; + border: 1px solid #ddd; + border-radius: 5px; +} + +.btn-login { + width: 100%; + padding: 12px; + background-color: #007bff; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + margin-bottom: 15px; +} + +.login-options { + display: flex; + justify-content: space-between; +} + +.btn-google, +.btn-facebook { + flex: 1; + padding: 10px; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 14px; + text-align: center; + text-decoration: none; +} + +.btn-google { + background-color: #db4437; + color: white; + margin-right: 10px; +} + +.btn-facebook { + background-color: #28a745; + color: white; +} \ No newline at end of file diff --git a/public/css/front/member_link.css b/public/css/front/member_link.css new file mode 100644 index 0000000..38ed839 --- /dev/null +++ b/public/css/front/member_link.css @@ -0,0 +1,17 @@ +nav.top_menu ul.member-link{ + /* border:1px solid red; */ + color:#3a37f3; + padding-right:20px; +} + +nav.top_menu ul.member-link a{ + color:#3a37f3; +} + +nav.top_menu ul.member-link ul.dropdown-menu li:hover{ + background-color: #eaeaea; +} + +nav.top_menu ul.member-link ul.dropdown-menu li a{ + padding-left:10px; +} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7ecfce214cbdbedc15d8348babeff5cd7e720488 GIT binary patch literal 5430 zcmeHL&npB`9Dn5Kuy>cuLGmAPauLohTgugsgTofC9NbV!aa0tgTofgxl%f=?Y?Sh& zWMxI9hibZ5LZ@~9&$;7J-7ai$2=7ByD3A3P1*hfQz|8$LL= zUz~w$;90HjJ=)Ss!V^NuI2Za%(z#lli~7u{+nbyOi;~<-#pGX{K<~tb_C6Lj^YSY9 zuHBEb(bRJ+>$(mjNuamQtlmY!MgdXJjDiJ*`fSvC!*oskp+}sjm(MWyz%r29BW!f*m(x|(w?cOiYFaD0y8pq z9eCfscMhGYa>i@!YdSYJ(-6XZ(W@wc#d9lm1l3S%FF!rC_waiB@V}AM)ez?!Gp$os wgQ-p&yk8A*^lZ5Jw#)Gj@LI_qy{H^P{^jt7C;ag)RHAYMwkN>;6;PJx7hHm1jsO4v literal 0 HcmV?d00001 diff --git a/public/images/common/com_icon3.png b/public/images/common/com_icon3.png new file mode 100644 index 0000000000000000000000000000000000000000..eb662cdeaee19e73456ca27f170837968794acbf GIT binary patch literal 5005 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 literal 0 HcmV?d00001 diff --git a/public/images/common/discord.png b/public/images/common/discord.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2233c03abeed0bf7d3491c9b2d908efc9f96db GIT binary patch literal 663 zcmV;I0%-k-P)s;2ZE2sPe>BNwb)jz%At_<{0o4_zeWRTDvE{-4nM1 zi~vW=Eq)$YmB}Aq40r&1P~Q@;2yCh?sxMHC#f~dCkk`4m#Tzw^mN*IA1?D|Z7uDvK zJE`A!c}H?n32%X{W4Ho51A2k8Kn6IVmQi1?Vpg2Ith@qwM>4D6Zv7qtdVspPQwSW? zU@RAT1@aE175EGM0uHfvGyog&J{}f$Mq$ia4!+&m{&pvTK_?iK)4Kk>2JLuS>LTk;K~(1IUI9z^AzkNFNS+0Xz3`2`)>Y@`;}$o+y!=(hIh!vmq5zb2+6NAARDg z#1^No8fYRpP4XykL^W*5irDdN!H2*y&{yVPalLYuuRHZ z3|s-u0L?(HTC?s0*ML#rr;|4&uSR_jRLi?QYt9;7Q2!-hF2Qj;r(EMAu%LdcakA9Z zwW)Z)WJXij<6JCqI$rI3-&V`3FXy~VmUBZMfpb~02aP!lvI6;>1s;*b3=DjSL74G){)!X^24*%-7srqc=eILsJ%SS@8m{|Jk1fA{H|g}> z&cGlS$HXL7w!2^19TTqj*5~!D2vBYlVVSDT^!gBozR{&_k27@&Ou8Lg91{=D@!Fxf z^7Pxczt7$C-mOlis$9elTFzi84(fjXZo6``)}f&XM8lV`m-*~ z{lMQNFUwsE-`qbWw`F}9%iTP|iinmt;q}c*R_}OrD2C4ovRl=BHQOa+?dF?TRpJgS zeOr6^ecXa1&5tHa56XR6E4t8nF5~$~!CP;6b|@(+&6N)Asd#nCfptb{`T2SKH?3Qq z$g%lH0At$HM>~?l`;?cem5m4Ii=(-k9#U{9(Y4jC(Pf zqQ^u*j=Hp5exBsQNfSSoAKT}Cc<&DOp0{@_y@1Z>5RGi8+5Y_F-Dz{)*|D!IId#MD zjA}ykZ@!{=A9u7YroOM3KHshCJZ#08B zd*0;Z+NB{8ieV{??AHAf{azO~y!6(ZLP*HG5MP(|@z94K9M2eC($zlAv-or` z-beS5V8WmLCH>wY_f5-XJiWAUYlFQb>x@u-tuP!hs@0>N_HiN88L!sDHLo)(`XXzz z{+*8P>iShR*W2~)fk2k2pM@v40s&{vw);7Eo$jrEZ$Ax~O&B~~{an^LB{Ts5L7AAy literal 0 HcmV?d00001 diff --git a/public/images/common/kakaotalk.png b/public/images/common/kakaotalk.png new file mode 100644 index 0000000000000000000000000000000000000000..cf7a87c83a2d7dfce219afc7b6d409bda2036980 GIT binary patch literal 1399 zcmaKqdo+}J7{`C_`_AQ^dFQ>%o3OGX5lRio8coM-#Fz*}218^jQ>!#hS{m=sJ$rV~d7kHcp65BA^Zny_GX4F$ zaIO&-0Dw!p#eq6C`H(20tGpMH**YpLsp$aB=tilJ0oWw~;As>9&V>LN z#A|BLJLGy2^qJ^hfLeL~NU(NjZo$0hPe4z^Q;hOA}zcrZ0v z(6U^t^D_B*kbk%kDDa|Q-;VVRUwRmPjV&u_m-%GR(@HpD?8xj*Yp19{;G z+;Rb8V~NzC!mm^j^NnG1Q~1U?;z=j9(vjh|lKHHgpOemIAi!iEywD7xNQlVfubzz)d1f`$XIHP-2RmuX{Scos7D=CW->Q6lHGlkT z&k~3CaYF-G#zyc!6Lsxpf`>u5Mz({+WMxW^ywwIFJ6n!N1he0c($&Xs3p2#p0znX9ZHZV} zAd43vrXR!e3}K3ZOikdL3VeEqj*CIpdb7f1tSC9V@JnpLe0Z4+qWv119ONs4SSH4> zpBJ;_E9~)YYKaw+xQ%l(54+b)p(y0EoKahWr>Hp^75e@WJv%!)v*+7J-8XPFfqpWt z)|s1b?alB0u&!SpuNy)eq+a5d^lH|JhOLqKda@s*FhrQ=X!qUHt-B>+w;-$5n5Zaa z1E(<5P%eB499aoT9md`rihhNtu1@62l@%Xa@9OU@7Y7B2*C_TD93g{?rGY+StJe`c z<;YyU{0rITHF?27BiX6NwJZboVyR3@;IU)zmyb{HdOa*iy$HF8i(A{g2~6Pl0Fk~b zX)Y=Xm&@g0p?7ce_BA#2hBpg)nuX3U(~eJTBZd_N{i{Uvb;(I1Z{I#2f#I~h9_}Ma z`BSMKis&x&gARU9K)YRCm3qfZjyhA)RBEkOSEv-Os`nGT?|d7ILVJZZPr?$XIclaT z!_&2Fh)&7Ys6NV$C|ws28XO@D57}-V($?0~xnxnn9XNM%OB~{Jesh8*L82L(n3#OM zw$MtXI-~8^+nqh2m7RdfPqb2;mQtZKeo|ZWYIK?WLTuIP{@ilvkZpDT;c7+Xxeevo zKAT_eZ0)L)=7(Q$yOm<@vQX~mdtHA?$q9EP|D;q;mXKv;Ao3aAw!$M{(=*zXp;w0A z-EAsqe$jun1QQC!cf5eIket4I$!`W~ru+l3!7tL(>gA+u>{H>Xoys{b24P_jyM;Ep zpE)i1gc>&wT;M(#py~ARGz*!(jF8B8Q2N1VisoIqI-vDoF pd|C%s{q3Mp#ckZFiH?i^H?w@jUnX{fKAw&N5>G#IrF+!gKLJ(D3{U_7 literal 0 HcmV?d00001 diff --git a/public/images/common/news.png b/public/images/common/news.png new file mode 100644 index 0000000000000000000000000000000000000000..fa77ce2e3fb172694b38dd59da0def06a78def28 GIT binary patch literal 4746 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 literal 0 HcmV?d00001 diff --git a/public/images/common/pdf.png b/public/images/common/pdf.png new file mode 100644 index 0000000000000000000000000000000000000000..bb18a19e9ddaae7307995160ad1c3a74ca74cd44 GIT binary patch literal 1392 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 I&?3|S1F{PgKmY&$ literal 0 HcmV?d00001 diff --git a/public/images/common/top_skype.png b/public/images/common/top_skype.png new file mode 100644 index 0000000000000000000000000000000000000000..90355c0b4791cc6b3ab0d62de8a0479558e17dc3 GIT binary patch literal 2166 zcmbVOX;f2Z8ji9!Age60h=zd5SRuJd$VQ@Mxj@8V*o3l~m|P%`;-AvJnG6eW=}Fp~}6W6%;Y z0~6%R!|@bsC|cr`tc3iNeF8+uu_CG%vvUWUuAw0YWRO~j*2tuC6-~pyEZLEikX+5> zFfho8i&!G20aP}TOmPKCBq9h>0Dwxt<3J+QgTMv}IM5YXvGFl3l|TTg96Z5;#KHjp zNTE_WY|w)VvH>!Q$tDn1xLmnPEtHF(6xIvSWH8^5(}vw)qTyZ0hWbot39~scBCf>>ZwJ$IN0!+sBF>Ur&_a<4%m8Ua%rN155J%up!wbzN5 zb^u#->^U8T?RX;lX#vCi7xZz;mD!p~ntLf@oP1f#t@g}E%_2Phs zq1SC6XghgKOU)EUPGPjMlG~aDuCP~-$1|Y$46h#@fx^hXh-7F|n78~EM-`hGK8#SGkdoo?1m1k5`Sq!|nQIWyu zkDZiKx-UM+s`oY2CH3fbP<5?7ojQ&08QBGdozD%+X|i=19CS1%Htq{wuz2gMF&C6) ztlcz)I-1rzNX9_*H;aag@|j^)RBkk{VWS)aJ$pDjPO*N&0BZzgJtP8puPQ&<)o@lL|7|K^Qx$kw>D zimONGeU0o}(p#T=-u^Hn(mrf@gs{-IB{11MfBlbXB_6?RE5Q}4%^b{_ z+1ivXF{+S39y%3e!ZIA0HF2+q(2aI>pDd&rP^%2@4OwUZ-AyZd`{h4=IVt3y?y_{# z{BZWG%rt|()t2tv=6TZDSIw!#qq?uwY|D~br8Mz>tNRzZzBfI!#k8uX8Qee~p1q>& z&`{d?^>>pg*Q@Vu#E!W=Es|590$x@cYldm+eV1cv2R+Z+K`EAUA2n>HDI+%RVddIB znKSkGZ`ECMQ%-CfY|fcE;Ki%5dBN;msystemDirectory . '/Boot.php'; + +exit(CodeIgniter\Boot::bootWeb($paths)); diff --git a/public/js/admin.js b/public/js/admin.js new file mode 100644 index 0000000..a485a38 --- /dev/null +++ b/public/js/admin.js @@ -0,0 +1,73 @@ +/* ------------------------------------------------------------ + * Name : admin.js + * Desc : Admin Javascrip + * Created : 2016/9/11 Tri-aBility by Junheum,Choi + * Updated : + ------------------------------------------------------------ */ + +function is_NumericKey(evt,obj){ + var charCode = (evt.which) ? evt.which : event.keyCode; + switch(charCode){ + case 48://0 + case 49://1 + case 50://2 + case 51://3 + case 52://4 + case 53://5 + case 54://6 + case 55://7 + case 56://8 + case 57://9 + case 96://KeyPad:0 + case 97://KeyPad:1 + case 98://KeyPad:2 + case 99://KeyPad:3 + case 100://KeyPad:4 + case 101://KeyPad:5 + case 102://KeyPad:6 + case 103://KeyPad:7 + case 104://KeyPad:8 + case 105://KeyPad:9 + break; + default: + alert('숫자만 가능합니다['+charCode+']'); + obj.value = obj.value.substring(0,obj.value.length-1); + break; + } +} +function is_NumericType(data){ + if(!data.match(/^[0-9]+$/)){ + throw (new Error('숫자가 아닌값['+data+']이 있습니다')); + } + return true; +}// +function change_CurrencyFormat(obj,currencies){ + //var currencies = document.getElementsByClassName("currency"); + var total_currency = 0; + for(i=0; i { alert("복사가 완료되었습니다."); }) + .catch(err => { console.log('복사가 오류', err); }) +} \ No newline at end of file diff --git a/public/js/admin/form.js b/public/js/admin/form.js new file mode 100644 index 0000000..0c13ad3 --- /dev/null +++ b/public/js/admin/form.js @@ -0,0 +1,119 @@ +(function() { + //console.log('form.js가 로드되었습니다.'); + + function initializeModalComponents(modal) { + //console.log('모달 컴포넌트 초기화 시작'); + + // 약간의 지연을 주어 모달이 완전히 렌더링되도록 함 + setTimeout(() => { + initializeCalendar(modal); + initializeSelectField(modal); + initializeTinyMCE(modal); + }, 100); + } + + function initializeCalendar(container) { + const calendarInputs = container.querySelectorAll('.calender'); + if (calendarInputs.length > 0) { + //console.log('달력 초기화 시작'); + $(calendarInputs).datepicker({ + changeYear: true, + changeMonth: true, + yearRange: "-10:+0", + dateFormat: "yy-mm-dd" + }); + //console.log('달력 초기화 완료'); + } + } + + function initializeSelectField(container) { + const selectFields = container.querySelectorAll('.select-field'); + if (selectFields.length > 0 && typeof $.fn.select2 !== 'undefined') { + //console.log('선택 필드 초기화 시작'); + $(selectFields).select2({ + theme: "classic", + width: 'style', + dropdownAutoWidth: true, + dropdownParent: $('#index_action_form'), + containerCssClass: 'text-start', // 왼쪽 정렬을 위한 클래스 추가 + dropdownCssClass: 'text-start' // 드롭다운 메뉴도 왼쪽 정렬 + }); + //console.log('선택 필드 초기화 완료'); + } + } + + function initializeTinyMCE(container) { + const textareas = container.querySelectorAll('textarea.tinymce'); + if (textareas.length > 0 && typeof tinymce !== 'undefined') { + //console.log('TinyMCE 초기화 시작'); + tinymce.init({ + selector: textareas, + plugins: ['code', 'image', 'preview', 'table', 'emoticons', 'autoresize'], + height: 600, + automatic_uploads: false, + images_upload_url: '/tinymce_upload.php', + images_upload_handler: function (blobInfo, success, failure) { + var xhr, formData; + xhr = new XMLHttpRequest(); + xhr.withCredentials = false; + xhr.open('POST', '/tinymce_upload.php'); + xhr.onload = function () { + var json; + if (xhr.status != 200) { + failure('HTTP Error: ' + xhr.status); + return; + } + json = JSON.parse(xhr.responseText); + if (!json || typeof json.file_path != 'string') { + failure('Invalid JSON: ' + xhr.responseText); + return; + } + success(json.file_path); + }; + formData = new FormData(); + formData.append('file', blobInfo.blob(), blobInfo.filename()); + xhr.send(formData); + }, + setup: function(editor) { + editor.on('init', function() { + //console.log('TinyMCE 에디터 초기화 완료'); + }); + } + }); + } + } + + // MutationObserver 설정 + const observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'childList') { + const addedNodes = mutation.addedNodes; + for (let i = 0; i < addedNodes.length; i++) { + if (addedNodes[i].nodeType === 1 && addedNodes[i].matches('.modal')) { + //console.log('새로운 모달이 추가되었습니다.'); + initializeModalComponents(addedNodes[i]); + } + } + } + }); + }); + + // 전체 문서에 대해 MutationObserver 시작 + observer.observe(document.body, { childList: true, subtree: true }); + + // 모달 표시 이벤트 리스너 + document.body.addEventListener('shown.bs.modal', function(event) { + //console.log('모달이 표시되었습니다.'); + initializeModalComponents(event.target); + }); + + // 페이지 로드 시 전체 문서에 대해 초기화 실행 + //console.log('페이지 로드 시 초기화 시작'); + initializeModalComponents(document.body); + + // 전역 스코프에 함수 노출 + window.initializeForm = function() { + //console.log('initializeForm 함수가 호출되었습니다.'); + initializeModalComponents(document.body); + }; +})(); \ No newline at end of file diff --git a/public/js/admin/index.js b/public/js/admin/index.js new file mode 100644 index 0000000..a41c934 --- /dev/null +++ b/public/js/admin/index.js @@ -0,0 +1,33 @@ +document.addEventListener('DOMContentLoaded', function() { + //class가 calender인 inputbox용,날짜field용 + if (document.querySelector(".calender")) { + $(".calender").datepicker({ + changeYear: true, + changeMonth: true, + yearRange: "-10:+0", + dateFormat: "yy-mm-dd" + }); + } + if (document.querySelector(".batchjobuids_checkboxs")) { + //id가 batchjobuids_checkbox인 버튼을 클릭시 class가 batchjobuids_checkboxs인 checkbox용 + $('#batchjobuids_checkbox').click(function (event) { + if (this.checked) { + $('.batchjobuids_checkboxs').each(function () { //loop checkbox + $(this).prop('checked', true); //check + }); + } else { + $('.batchjobuids_checkboxs').each(function () { //loop checkbox + $(this).prop('checked', false); //uncheck + }); + } + }); + } + if (document.querySelector(".select-field")) { + //class가 select-field인 SelectBox용 + $(".select-field").select2({ + theme: "classic", + width: 'style', + dropdownAutoWidth: true + }); + } +}); \ No newline at end of file diff --git a/public/js/admin/left_menu.js b/public/js/admin/left_menu.js new file mode 100644 index 0000000..1cfc98e --- /dev/null +++ b/public/js/admin/left_menu.js @@ -0,0 +1,13 @@ +function sideMenuToggle(left_menu) { + $accordion = $("#accordion")[0]; + if (accordion.clientWidth == 0){ + accordion.style.display = "block"; + $("#accordion").css({ "width": '217px' }) + $("#menu_button").html("메뉴닫기"); + } + else { + accordion.style.display = "none"; + $("#accordion").css({"width":'20px'}) + $("#menu_button").html("메뉴열기"); + } +}//toggleMenu \ No newline at end of file diff --git a/public/js/admin/resizeTable.js b/public/js/admin/resizeTable.js new file mode 100644 index 0000000..58a8c6b --- /dev/null +++ b/public/js/admin/resizeTable.js @@ -0,0 +1,843 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.validide_resizableTableColumns = {})); +})(this, (function (exports) { + 'use strict'; + + var ResizableConstants = /** @class */ (function () { + function ResizableConstants() { + } + ResizableConstants.dataPropertyName = 'validide_rtc_data_object'; + ResizableConstants.classes = { + table: 'rtc-table', + wrapper: 'rtc-wrapper', + handleContainer: 'rtc-handle-container', + handle: 'rtc-handle', + tableResizing: 'rtc-table-resizing', + columnResizing: 'rtc-column-resizing', + }; + ResizableConstants.attributes = { + dataResizable: 'data-rtc-resizable', + dataResizableTable: 'data-rtc-resizable-table' + }; + ResizableConstants.data = { + resizable: 'rtcResizable', + resizableTable: 'rtcResizableTable' + }; + ResizableConstants.events = { + pointerDown: ['mousedown', 'touchstart'], + pointerMove: ['mousemove', 'touchmove'], + pointerUp: ['mouseup', 'touchend'], + windowResize: ['resize'], + eventResizeStart: 'eventResizeStart.rtc', + eventResize: 'eventResize.rtc', + eventResizeStop: 'eventResizeStop.rtc' + }; + return ResizableConstants; + }()); + + var WidthsData = /** @class */ (function () { + function WidthsData() { + this.column = 0; + this.table = 0; + } + return WidthsData; + }()); + var PointerData = /** @class */ (function () { + function PointerData() { + this.x = null; + this.isDoubleClick = false; + } + return PointerData; + }()); + var ResizableEventData = /** @class */ (function () { + function ResizableEventData(column, dragHandler) { + this.pointer = new PointerData(); + this.originalWidths = new WidthsData(); + this.newWidths = new WidthsData(); + this.column = column; + this.dragHandler = dragHandler; + } + return ResizableEventData; + }()); + + var Utilities = /** @class */ (function () { + function Utilities() { + } + Utilities.kebabCaseToCamelCase = function (str) { + return str.replace(Utilities.kebabCaseRegex, function (m) { return m[1].toUpperCase(); }); + }; + Utilities.parseStringToType = function (str) { + if (str.length == 0 || Utilities.onlyWhiteSpace.test(str)) + return str; + if (Utilities.trueRegex.test(str)) + return true; + if (Utilities.falseRegex.test(str)) + return false; + if (Utilities.notEmptyOrWhiteSpace.test(str)) { + var temp = +str; + if (!isNaN(temp)) + return temp; + } + return str; + }; + Utilities.regexEscapeRegex = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g; + Utilities.kebabCaseRegex = /(\-\w)/g; + Utilities.trueRegex = /^true$/i; + Utilities.falseRegex = /^false$/i; + Utilities.onlyWhiteSpace = /^\s$/; + Utilities.notEmptyOrWhiteSpace = /\S/; + return Utilities; + }()); + + var UtilitiesDOM = /** @class */ (function () { + function UtilitiesDOM() { + } + UtilitiesDOM.getDataAttributesValues = function (el) { + if (!el) + return null; + var returnValue = {}; + if (el.dataset) { + for (var prop in el.dataset) { + if (el.dataset.hasOwnProperty(prop)) { + returnValue[prop] = Utilities.parseStringToType(el.dataset[prop] || ''); + } + } + } + else { + for (var i = 0; i < el.attributes.length; i++) { + if (!/^data\-/.test(el.attributes[i].name)) + continue; + var name_1 = Utilities.kebabCaseToCamelCase(el.attributes[i].name.replace('data-', '')); + returnValue[name_1] = Utilities.parseStringToType(el.attributes[i].value); + } + } + return returnValue; + }; + return UtilitiesDOM; + }()); + + var ResizableOptions = /** @class */ (function () { + function ResizableOptions(options, element) { + if (options === void 0) { options = null; } + if (element === void 0) { element = null; } + this.resizeFromBody = true; + this.minWidth = 40; + this.maxWidth = null; + this.doubleClickDelay = 500; + this.maxInitialWidthHint = null; + this.store = null; + this.overrideValues(options); + this.overrideValuesFromElement(element); + } + ResizableOptions.prototype.overrideValues = function (options) { + if (options === void 0) { options = null; } + if (!options) + return; + for (var prop in options) { + if (this.hasOwnProperty(prop)) { + this[prop] = options[prop]; + } + } + }; + ResizableOptions.prototype.overrideValuesFromElement = function (element) { + if (element === void 0) { element = null; } + if (!element) + return; + var elementOptions = UtilitiesDOM.getDataAttributesValues(element); + this.overrideValues(elementOptions); + }; + return ResizableOptions; + }()); + + var ResizableTableColumns = /** @class */ (function () { + function ResizableTableColumns(table, options) { + if (typeof table !== 'object' || table === null || table.toString() !== '[object HTMLTableElement]') + throw 'Invalid argument: "table".\nResizableTableColumns requires that the table element is a not null HTMLTableElement object!'; + if (typeof table[ResizableConstants.dataPropertyName] !== 'undefined') + throw "Existing \"".concat(ResizableConstants.dataPropertyName, "\" property.\nTable element already has a '").concat(ResizableConstants.dataPropertyName, "' attached object!"); + this.id = ResizableTableColumns.getInstanceId(); + this.table = table; + this.options = new ResizableOptions(options, table); + this.wrapper = null; + this.ownerDocument = table.ownerDocument; + this.tableHeaders = []; + this.dragHandlesContainer = null; + this.originalWidths = []; + this.eventData = null; + this.lastPointerDown = 0; + this.init(); + this.table[ResizableConstants.dataPropertyName] = this; + } + ResizableTableColumns.prototype.init = function () { + this.validateMarkup(); + this.createHandlerReferences(); + this.wrapTable(); + this.assignTableHeaders(); + this.storeOriginalWidths(); + this.setHeaderWidths(); + this.createDragHandles(); + this.restoreColumnWidths(); + this.checkTableWidth(); + this.syncHandleWidths(); + this.registerWindowResizeHandler(); + }; + ResizableTableColumns.prototype.dispose = function () { + this.destroyDragHandles(); + this.restoreOriginalWidths(); + this.unwrapTable(); + this.onPointerDownRef = null; + this.onPointerMoveRef = null; + this.onPointerUpRef = null; + this.table[ResizableConstants.dataPropertyName] = void (0); + }; + ResizableTableColumns.prototype.validateMarkup = function () { + var theadCount = 0; + var tbodyCount = 0; + var thead = null; + for (var index = 0; index < this.table.childNodes.length; index++) { + var element = this.table.childNodes[index]; + if (element.nodeName === 'THEAD') { + theadCount++; + thead = element; + } + else if (element.nodeName === 'TBODY') { + tbodyCount++; + } + } + if (thead === null || theadCount !== 1) + throw "Markup validation: thead count.\nResizableTableColumns requires that the table element has one(1) table head element. Current count: ".concat(theadCount); + if (tbodyCount !== 1) + throw "Markup validation: tbody count.\nResizableTableColumns requires that the table element has one(1) table body element. Current count: ".concat(tbodyCount); + var theadRowCount = 0; + var firstRow = null; + for (var index = 0; index < thead.childNodes.length; index++) { + var element = thead.childNodes[index]; + if (element.nodeName === 'TR') { + theadRowCount++; + if (firstRow === null) { + firstRow = element; + } + } + } + if (firstRow === null || theadRowCount < 1) + throw "Markup validation: thead row count.\nResizableTableColumns requires that the table head element has at least one(1) table row element. Current count: ".concat(theadRowCount); + var headerCellsCount = 0; + var invalidHeaderCellsCount = 0; + for (var index = 0; index < firstRow.childNodes.length; index++) { + var element = firstRow.childNodes[index]; + if (element.nodeName === 'TH') { + headerCellsCount++; + } + else if (element.nodeName === 'TD') { + invalidHeaderCellsCount++; + } + } + if (headerCellsCount < 1) + throw "Markup validation: thead first row cells count.\nResizableTableColumns requires that the table head's first row element has at least one(1) table header cell element. Current count: ".concat(headerCellsCount); + if (invalidHeaderCellsCount !== 0) + throw "Markup validation: thead first row invalid.\nResizableTableColumns requires that the table head's first row element has no(0) table cell(TD) elements. Current count: ".concat(invalidHeaderCellsCount); + }; + ResizableTableColumns.prototype.wrapTable = function () { + if (this.wrapper) + return; + this.wrapper = this.ownerDocument.createElement('div'); + this.wrapper.classList.add(ResizableConstants.classes.wrapper); + var tableOriginalParent = this.table.parentNode; + tableOriginalParent.insertBefore(this.wrapper, this.table); + tableOriginalParent.removeChild(this.table); + this.wrapper.appendChild(this.table); + this.table.classList.add(ResizableConstants.classes.table); + }; + ResizableTableColumns.prototype.unwrapTable = function () { + this.table.classList.remove(ResizableConstants.classes.table); + if (!this.wrapper) + return; + var tableOriginalParent = this.wrapper.parentNode; + tableOriginalParent.insertBefore(this.table, this.wrapper); + tableOriginalParent.removeChild(this.wrapper); + this.wrapper = null; + }; + ResizableTableColumns.prototype.assignTableHeaders = function () { + var tableHeader; + var firstTableRow; + for (var index = 0; index < this.table.childNodes.length; index++) { + var element = this.table.childNodes[index]; + if (element.nodeName === 'THEAD') { + tableHeader = element; + break; + } + } + if (!tableHeader) + return; + for (var index = 0; index < tableHeader.childNodes.length; index++) { + var element = tableHeader.childNodes[index]; + if (element.nodeName === 'TR') { + firstTableRow = element; + break; + } + } + if (!firstTableRow) + return; + for (var index = 0; index < firstTableRow.childNodes.length; index++) { + var element = firstTableRow.childNodes[index]; + if (element.nodeName === 'TH') { + this.tableHeaders.push(element); + } + } + }; + ResizableTableColumns.prototype.storeOriginalWidths = function () { + var _this = this; + this.tableHeaders + .forEach(function (el) { + _this.originalWidths.push({ + el: el, + detail: el.style.width + }); + }); + this.originalWidths.push({ + el: this.table, + detail: this.table.style.width + }); + }; + ResizableTableColumns.prototype.restoreOriginalWidths = function () { + this.originalWidths + .forEach(function (itm) { + itm.el.style.width = itm.detail; + }); + }; + ResizableTableColumns.prototype.setHeaderWidths = function () { + var _this = this; + this.tableHeaders + .forEach(function (el) { + var width = el.offsetWidth; + var constrainedWidth = _this.constrainWidth(el, width); + if (typeof _this.options.maxInitialWidthHint === 'number') { + constrainedWidth = Math.min(constrainedWidth, _this.options.maxInitialWidthHint); + } + _this.updateWidth(el, constrainedWidth, true, false); + }); + }; + ResizableTableColumns.prototype.constrainWidth = function (el, width) { + var result = width; + result = Math.max(result, this.options.minWidth || -Infinity); + result = Math.min(result, this.options.maxWidth || +Infinity); + return result; + }; + ResizableTableColumns.prototype.createDragHandles = function () { + var _this = this; + var _a; + if (this.dragHandlesContainer != null) + throw 'Drag handlers already created. Call if you wish to recreate them'; + this.dragHandlesContainer = this.ownerDocument.createElement('div'); + (_a = this.wrapper) === null || _a === void 0 ? void 0 : _a.insertBefore(this.dragHandlesContainer, this.table); + this.dragHandlesContainer.classList.add(ResizableConstants.classes.handleContainer); + this.getResizableHeaders() + .forEach(function () { + var _a; + var handler = _this.ownerDocument.createElement('div'); + handler.classList.add(ResizableConstants.classes.handle); + (_a = _this.dragHandlesContainer) === null || _a === void 0 ? void 0 : _a.appendChild(handler); + }); + ResizableConstants.events.pointerDown + .forEach(function (evt, evtIdx) { + var _a; + (_a = _this.dragHandlesContainer) === null || _a === void 0 ? void 0 : _a.addEventListener(evt, _this.onPointerDownRef, false); + }); + }; + ResizableTableColumns.prototype.destroyDragHandles = function () { + var _this = this; + var _a, _b; + if (this.dragHandlesContainer !== null) { + ResizableConstants.events.pointerDown + .forEach(function (evt, evtIdx) { + var _a; + (_a = _this.dragHandlesContainer) === null || _a === void 0 ? void 0 : _a.removeEventListener(evt, _this.onPointerDownRef, false); + }); + (_b = (_a = this.dragHandlesContainer) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(this.dragHandlesContainer); + } + }; + ResizableTableColumns.prototype.getDragHandlers = function () { + var nodes = this.dragHandlesContainer == null + ? null + : this.dragHandlesContainer.querySelectorAll(".".concat(ResizableConstants.classes.handle)); + return nodes + ? Array.prototype.slice.call(nodes).filter(function (el) { return el.nodeName === 'DIV'; }) + : new Array(); + }; + ResizableTableColumns.prototype.restoreColumnWidths = function () { + if (!this.options.store) + return; + var tableId = ResizableTableColumns.generateTableId(this.table); + if (tableId.length === 0) + return; + var data = this.options.store.get(tableId); + if (!data) + return; + this.getResizableHeaders() + .forEach(function (el) { + var width = data.columns[ResizableTableColumns.generateColumnId(el)]; + if (typeof width !== 'undefined') { + ResizableTableColumns.setWidth(el, width); + } + }); + if (typeof data.table !== 'undefined') { + ResizableTableColumns.setWidth(this.table, data.table); + } + }; + ResizableTableColumns.prototype.checkTableWidth = function () { + var _a; + var wrapperWidth = this.wrapper.clientWidth; + var tableWidth = this.table.offsetWidth; + var difference = wrapperWidth - tableWidth; + if (difference <= 0) + return; + var resizableWidth = 0; + var addedWidth = 0; + var headersDetails = []; + this.tableHeaders + .forEach(function (el, idx) { + if (el.hasAttribute(ResizableConstants.attributes.dataResizable)) { + var detail = { + el: el, + detail: el.offsetWidth + }; + headersDetails.push(detail); + resizableWidth += detail.detail; + } + }); + var leftToAdd = 0; + var lastResizableCell = null; + var currentDetail; + while ((currentDetail = headersDetails.shift())) { + leftToAdd = difference - addedWidth; + lastResizableCell = currentDetail.el; + var extraWidth = Math.floor((currentDetail.detail / resizableWidth) * difference); + extraWidth = Math.min(extraWidth, leftToAdd); + var newWidth = this.updateWidth(currentDetail.el, currentDetail.detail + extraWidth, false, true); + addedWidth += (newWidth - currentDetail.detail); + if (addedWidth >= difference) + break; + } + leftToAdd = difference - addedWidth; + if (leftToAdd > 0) { + var lastCell = ((_a = headersDetails[0]) === null || _a === void 0 ? void 0 : _a.el) || lastResizableCell || this.tableHeaders[this.tableHeaders.length - 1]; + var lastCellWidth = lastCell.offsetWidth; + this.updateWidth(lastCell, lastCellWidth, true, true); + } + ResizableTableColumns.setWidth(this.table, wrapperWidth); + }; + ResizableTableColumns.prototype.syncHandleWidths = function () { + var _this = this; + var tableWidth = this.table.clientWidth; + ResizableTableColumns.setWidth(this.dragHandlesContainer, tableWidth); + this.dragHandlesContainer.style.minWidth = "".concat(tableWidth, "px"); + var headers = this.getResizableHeaders(); + this.getDragHandlers() + .forEach(function (el, idx) { + var height = (_this.options.resizeFromBody ? _this.table : _this.table.tHead).clientHeight; + if (idx < headers.length) { + var th = headers[idx]; + var left = th.offsetWidth; + left += ResizableTableColumns.getOffset(th).left; + left -= ResizableTableColumns.getOffset(_this.dragHandlesContainer).left; + el.style.left = "".concat(left, "px"); + el.style.height = "".concat(height, "px"); + } + }); + }; + ResizableTableColumns.prototype.getResizableHeaders = function () { + return this.tableHeaders + .filter(function (el, idx) { + return el.hasAttribute(ResizableConstants.attributes.dataResizable); + }); + }; + ResizableTableColumns.prototype.handlePointerDown = function (event) { + this.handlePointerUp(); + var target = event ? event.target : null; + if (target == null) + return; + if (target.nodeName !== 'DIV' || !target.classList.contains(ResizableConstants.classes.handle)) + return; + if (typeof event.button === 'number' && event.button !== 0) + return; // this is not a left click + var dragHandler = target; + var gripIndex = this.getDragHandlers().indexOf(dragHandler); + var resizableHeaders = this.getResizableHeaders(); + if (gripIndex >= resizableHeaders.length) + return; + var millisecondsNow = (new Date()).getTime(); + var isDoubleClick = (millisecondsNow - this.lastPointerDown) < this.options.doubleClickDelay; + var column = resizableHeaders[gripIndex]; + var columnWidth = column.offsetWidth; + var widths = { + column: columnWidth, + table: this.table.offsetWidth + }; + var eventData = new ResizableEventData(column, dragHandler); + eventData.pointer = { + x: ResizableTableColumns.getPointerX(event), + isDoubleClick: isDoubleClick + }; + eventData.originalWidths = widths; + eventData.newWidths = widths; + this.detachHandlers(); //make sure we do not have extra handlers + this.attachHandlers(); + this.table.classList.add(ResizableConstants.classes.tableResizing); + this.wrapper.classList.add(ResizableConstants.classes.tableResizing); + dragHandler.classList.add(ResizableConstants.classes.columnResizing); + column.classList.add(ResizableConstants.classes.columnResizing); + this.lastPointerDown = millisecondsNow; + this.eventData = eventData; + var eventToDispatch = new CustomEvent(ResizableConstants.events.eventResizeStart, { + detail: { + column: column, + columnWidth: columnWidth, + table: this.table, + tableWidth: this.table.clientWidth + } + }); + this.table.dispatchEvent(eventToDispatch); + event.preventDefault(); + }; + ResizableTableColumns.prototype.handlePointerMove = function (event) { + if (!this.eventData || !event) + return; + var difference = (ResizableTableColumns.getPointerX(event) || 0) - (this.eventData.pointer.x || 0); + if (difference === 0) { + return; + } + var tableWidth = this.eventData.originalWidths.table + difference; + var columnWidth = this.constrainWidth(this.eventData.column, this.eventData.originalWidths.column + difference); + ResizableTableColumns.setWidth(this.table, tableWidth); + ResizableTableColumns.setWidth(this.eventData.column, columnWidth); + this.eventData.newWidths = { + column: columnWidth, + table: tableWidth + }; + var eventToDispatch = new CustomEvent(ResizableConstants.events.eventResize, { + detail: { + column: this.eventData.column, + columnWidth: columnWidth, + table: this.table, + tableWidth: tableWidth + } + }); + this.table.dispatchEvent(eventToDispatch); + }; + ResizableTableColumns.prototype.handlePointerUp = function () { + this.detachHandlers(); + if (!this.eventData) + return; + if (this.eventData.pointer.isDoubleClick) { + this.handleDoubleClick(); + } + this.table.classList.remove(ResizableConstants.classes.tableResizing); + this.wrapper.classList.remove(ResizableConstants.classes.tableResizing); + this.eventData.dragHandler.classList.remove(ResizableConstants.classes.columnResizing); + this.eventData.column.classList.remove(ResizableConstants.classes.columnResizing); + this.checkTableWidth(); + this.syncHandleWidths(); + this.refreshWrapperStyle(); + this.saveColumnWidths(); + var widths = this.eventData.newWidths || this.eventData.originalWidths; + var eventToDispatch = new CustomEvent(ResizableConstants.events.eventResizeStop, { + detail: { + column: this.eventData.column, + columnWidth: widths.column, + table: this.table, + tableWidth: widths.table + } + }); + this.table.dispatchEvent(eventToDispatch); + this.eventData = null; + }; + ResizableTableColumns.prototype.handleDoubleClick = function () { + if (!this.eventData || !this.eventData.column) + return; + var column = this.eventData.column; + var colIndex = this.tableHeaders.indexOf(column); + var maxWidth = 0; + var indicesToSkip = []; + this.tableHeaders + .forEach(function (el, idx) { + if (!el.hasAttribute(ResizableConstants.attributes.dataResizable)) { + indicesToSkip.push(idx); + } + }); + var span = this.ownerDocument.createElement('span'); + span.style.position = 'absolute'; + span.style.left = '-99999px'; + span.style.top = '-99999px'; + span.style.visibility = 'hidden'; + this.ownerDocument.body.appendChild(span); + var rows = this.table.querySelectorAll('tr'); + for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) { + var element = rows[rowIndex]; + var cells = element.querySelectorAll('td, th'); + var currentIndex = 0; + for (var cellIndex = 0; cellIndex < cells.length; cellIndex++) { + var cell = cells[cellIndex]; + var colSpan = 1; + if (cell.hasAttribute('colspan')) { + var colSpanString = cell.getAttribute('colspan') || '1'; + var parsed = parseInt(colSpanString); + if (!isNaN(parsed)) { + colSpan = parsed; + } + else { + colSpan = 1; + } + } + if (indicesToSkip.indexOf(cellIndex) === -1 + && colSpan === 1 + && currentIndex === colIndex) { + maxWidth = Math.max(maxWidth, ResizableTableColumns.getTextWidth(cell, span)); + break; + } + currentIndex += colSpan; + } + } + this.ownerDocument.body.removeChild(span); + var difference = maxWidth - column.offsetWidth; + if (difference === 0) { + return; + } + var tableWidth = this.eventData.originalWidths.table + difference; + var columnWidth = this.constrainWidth(this.eventData.column, this.eventData.originalWidths.column + difference); + ResizableTableColumns.setWidth(this.table, tableWidth); + ResizableTableColumns.setWidth(this.eventData.column, columnWidth); + this.eventData.newWidths = { + column: columnWidth, + table: tableWidth, + }; + var eventToDispatch = new CustomEvent(ResizableConstants.events.eventResize, { + detail: { + column: this.eventData.column, + columnWidth: columnWidth, + table: this.table, + tableWidth: tableWidth + } + }); + this.table.dispatchEvent(eventToDispatch); + this.checkTableWidth(); + this.syncHandleWidths(); + this.saveColumnWidths(); + }; + ResizableTableColumns.prototype.attachHandlers = function () { + var _this = this; + ResizableConstants.events.pointerMove + .forEach(function (evt, evtIdx) { + _this.ownerDocument.addEventListener(evt, _this.onPointerMoveRef, false); + }); + ResizableConstants.events.pointerUp + .forEach(function (evt, evtIdx) { + _this.ownerDocument.addEventListener(evt, _this.onPointerUpRef, false); + }); + }; + ResizableTableColumns.prototype.detachHandlers = function () { + var _this = this; + ResizableConstants.events.pointerMove + .forEach(function (evt, evtIdx) { + _this.ownerDocument.removeEventListener(evt, _this.onPointerMoveRef, false); + }); + ResizableConstants.events.pointerUp + .forEach(function (evt, evtIdx) { + _this.ownerDocument.removeEventListener(evt, _this.onPointerUpRef, false); + }); + }; + ResizableTableColumns.prototype.refreshWrapperStyle = function () { + if (this.wrapper == null) + return; + var original = this.wrapper.style.overflowX; + this.wrapper.style.overflowX = 'hidden'; + this.wrapper.style.overflowX = original; + }; + ResizableTableColumns.prototype.saveColumnWidths = function () { + if (!this.options.store) + return; + var tableId = ResizableTableColumns.generateTableId(this.table); + if (tableId.length === 0) + return; + var data = { + table: this.table.offsetWidth, + columns: {} + }; + this.getResizableHeaders() + .forEach(function (el) { + data.columns[ResizableTableColumns.generateColumnId(el)] = el.offsetWidth; + }); + this.options.store.set(tableId, data); + }; + ResizableTableColumns.prototype.createHandlerReferences = function () { + var _this = this; + if (!this.onPointerDownRef) { + this.onPointerDownRef = ResizableTableColumns.debounce(function (evt) { + _this.handlePointerDown(evt); + }, 100, true); + } + if (!this.onPointerMoveRef) { + this.onPointerMoveRef = ResizableTableColumns.debounce(function (evt) { + _this.handlePointerMove(evt); + }, 5, false); + } + if (!this.onPointerUpRef) { + this.onPointerUpRef = ResizableTableColumns.debounce(function (evt) { + _this.handlePointerUp(); + }, 100, true); + } + }; + ResizableTableColumns.prototype.registerWindowResizeHandler = function () { + var win = this.ownerDocument.defaultView; + if (ResizableTableColumns.windowResizeHandlerRef) + return; + ResizableTableColumns.windowResizeHandlerRef = ResizableTableColumns.debounce(ResizableTableColumns.onWindowResize, 50, false); + ResizableConstants.events.windowResize + .forEach(function (evt, idx) { + win === null || win === void 0 ? void 0 : win.addEventListener(evt, ResizableTableColumns.windowResizeHandlerRef, false); + }); + }; + ResizableTableColumns.prototype.handleWindowResize = function () { + this.checkTableWidth(); + this.syncHandleWidths(); + this.saveColumnWidths(); + }; + ResizableTableColumns.prototype.updateWidth = function (cell, suggestedWidth, skipConstrainCheck, skipTableResize) { + var originalCellWidth = cell.offsetWidth; + var columnWidth = skipConstrainCheck + ? suggestedWidth + : this.constrainWidth(cell, suggestedWidth); + ResizableTableColumns.setWidth(cell, columnWidth); + if (!skipTableResize) { + var difference = columnWidth - originalCellWidth; + var tableWidth = this.table.offsetWidth + difference; + ResizableTableColumns.setWidth(this.table, tableWidth); + } + return columnWidth; + }; + ResizableTableColumns.onWindowResize = function (event) { + var win = event ? event.target : null; + if (win == null) + return; + var tables = win.document.querySelectorAll(".".concat(ResizableConstants.classes.table)); + for (var index = 0; index < tables.length; index++) { + var table = tables[index]; + if (typeof table[ResizableConstants.dataPropertyName] !== 'object') + continue; + table[ResizableConstants.dataPropertyName].handleWindowResize(); + } + }; + ResizableTableColumns.generateColumnId = function (el) { + var columnId = (el.getAttribute(ResizableConstants.attributes.dataResizable) || '') + .trim() + .replace(/\./g, '_'); + return columnId; + }; + ResizableTableColumns.generateTableId = function (table) { + var tableId = (table.getAttribute(ResizableConstants.attributes.dataResizableTable) || '') + .trim() + .replace(/\./g, '_'); + return tableId.length + ? "rtc/".concat(tableId) + : tableId; + }; + ResizableTableColumns.setWidth = function (element, width) { + var strWidth = width.toFixed(2); + strWidth = width > 0 ? strWidth : '0'; + element.style.width = "".concat(strWidth, "px"); + }; + ResizableTableColumns.getInstanceId = function () { + return ResizableTableColumns.instancesCount++; + }; + ResizableTableColumns.getPointerX = function (event) { + if (event.type.indexOf('touch') === 0) { + var tEvent = event; + if (tEvent.touches && tEvent.touches.length) { + return tEvent.touches[0].pageX; + } + if (tEvent.changedTouches && tEvent.changedTouches.length) { + return tEvent.changedTouches[0].pageX; + } + } + return event.pageX; + }; + ResizableTableColumns.getTextWidth = function (contentElement, measurementElement) { + var _a, _b; + if (!contentElement || !measurementElement) + return 0; + var text = ((_a = contentElement.textContent) === null || _a === void 0 ? void 0 : _a.trim().replace(/\s/g, ' ')) + ' '; //add extra space to ensure we are not add the `...` + var styles = (_b = contentElement.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getComputedStyle(contentElement); + ['fontFamily', 'fontSize', 'fontWeight', 'padding', 'border', 'boxSizing'] + .forEach(function (prop) { + measurementElement.style[prop] = styles[prop]; + }); + measurementElement.innerHTML = text; + return measurementElement.offsetWidth; + }; + ResizableTableColumns.getOffset = function (el) { + if (!el) + return { top: 0, left: 0 }; + var rect = el.getBoundingClientRect(); + return { + top: rect.top + el.ownerDocument.body.scrollTop, + left: rect.left + el.ownerDocument.body.scrollLeft + }; + }; + ResizableTableColumns.instancesCount = 0; + ResizableTableColumns.windowResizeHandlerRef = null; + ResizableTableColumns.debounce = function (func, wait, immediate) { + var timeout = null; + var debounced = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var later = function () { + timeout = null; + if (!immediate) { + func.apply(void 0, args); + } + }; + var callNow = immediate && !timeout; + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(later, wait); + if (callNow) { + func.apply(void 0, args); + } + }; + return debounced; + }; + return ResizableTableColumns; + }()); + + exports.PointerData = PointerData; + exports.ResizableConstants = ResizableConstants; + exports.ResizableEventData = ResizableEventData; + exports.ResizableOptions = ResizableOptions; + exports.ResizableTableColumns = ResizableTableColumns; + exports.Utilities = Utilities; + exports.UtilitiesDOM = UtilitiesDOM; + exports.WidthsData = WidthsData; + +})); +(function (window, ResizableTableColumns, undefined) { + var store = window.store && window.store.enabled ? window.store : null; + var els = document.querySelectorAll('table.data'); + for (var index = 0; index < els.length; index++) { + var table = els[index]; + if (table['rtc_data_object']) { + continue; + } + var options = { + store: store + }; + if (table.querySelectorAll('thead > tr').length > 1) { + options.resizeFromBody = false; + } + new ResizableTableColumns(els[index], options); + } +})(window, window.validide_resizableTableColumns.ResizableTableColumns, void (0)); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/public/js/common/product.js b/public/js/common/product.js new file mode 100644 index 0000000..673a2ed --- /dev/null +++ b/public/js/common/product.js @@ -0,0 +1,30 @@ + +function calculator(order_price) { + var parts = Array.from(document.getElementsByClassName("vhost_parts")); + parts.forEach(function(part) { //loop + //console.log(part); + order_price += parseInt((part.getAttribute('cost') - part.getAttribute('sale')) * part.options[part.selectedIndex].value); + document.getElementById('price').value = order_price; + document.getElementById('order_price').textContent = new Intl.NumberFormat().format(order_price); + }); + var current = document.getElementById('paymentday'); + if (!current.selectedIndex) { + alert("결제일을 선택해주세요"); + current.focus(); + return false + } +} +function addDevice(category, key, label) { + var categoryBox = document.getElementById(category + "Box"); + var div = document.createElement("div"); + var checkbox = document.createElement("input"); + checkbox.setAttribute("type", "checkbox"); + checkbox.setAttribute("name", category + '[]'); + checkbox.setAttribute("value", key); + checkbox.setAttribute("checked", true); + checkbox.setAttribute("class", 'device'); + div.appendChild(checkbox); + div.appendChild(document.createTextNode(label)); + // console.log(div); + categoryBox.appendChild(div); +} \ No newline at end of file diff --git a/public/js/empty.js b/public/js/empty.js new file mode 100644 index 0000000..f973e71 --- /dev/null +++ b/public/js/empty.js @@ -0,0 +1,6 @@ +/* ------------------------------------------------------------ + * Name : front.js + * Desc : Front Javascrip + * Created : 2016/9/11 Tri-aBility by Junheum,Choi + * Updated : + ------------------------------------------------------------ */ diff --git a/public/js/front.js b/public/js/front.js new file mode 100644 index 0000000..6bea8a4 --- /dev/null +++ b/public/js/front.js @@ -0,0 +1,93 @@ +/* ------------------------------------------------------------ + * Name : front.js + * Desc : Front Javascrip + * Created : 2016/9/11 Tri-aBility by Junheum,Choi + * Updated : + ------------------------------------------------------------ */ + +function trim(str){ + return this.replace(/(^\s*)|(\s*$)/gi, ""); +}// + +function bookmarksite(title,url) { + if (window.sidebar) // firefox + window.sidebar.addPanel(title, url, ""); + else if(window.opera && window.print){ // opera + var elem = document.createElement('a'); + elem.setAttribute('href',url); + elem.setAttribute('title',title); + elem.setAttribute('rel','sidebar'); + elem.click(); + } + else if(document.all) // ie + window.external.AddFavorite(url, title); +}// + +function captcha_refresh(refresh_url) { + $.ajax({ + type: 'POST', + url: refresh_url, + success: function(data, status, xhr){ + if(data) + $('#captcha_span').html(data); + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log(jqXHR.responseText); + console.log(textStatus+'=>'+errorThrown); + } + });//ajax +}// + +function is_NumericKey(evt,obj){ + var charCode = (evt.which) ? evt.which : event.keyCode; + switch(charCode){ + case 48://0 + case 49://1 + case 50://2 + case 51://3 + case 52://4 + case 53://5 + case 54://6 + case 55://7 + case 56://8 + case 57://9 + case 96://KeyPad:0 + case 97://KeyPad:1 + case 98://KeyPad:2 + case 99://KeyPad:3 + case 100://KeyPad:4 + case 101://KeyPad:5 + case 102://KeyPad:6 + case 103://KeyPad:7 + case 104://KeyPad:8 + case 105://KeyPad:9 + break; + default: + alert('숫자만 가능합니다['+charCode+']'); + obj.value = obj.value.substring(0,obj.value.length-1); + break; + } +} +function is_NumericType(data){ + if(!data.match(/^[0-9]+$/)){ + throw (new Error('숫자가 아닌값['+data+']이 있습니다')); + } + return true; +}// +function change_CurrencyFormat(obj,currencies){ + //var currencies = document.getElementsByClassName("currency"); + var total_currency = 0; + for(i=0; i $fileName + )); +} diff --git a/spark b/spark new file mode 100644 index 0000000..992d044 --- /dev/null +++ b/spark @@ -0,0 +1,84 @@ +#!/usr/bin/env php + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +/* + * -------------------------------------------------------------------- + * CODEIGNITER COMMAND-LINE TOOLS + * -------------------------------------------------------------------- + * The main entry point into the CLI system and allows you to run + * commands and perform maintenance on your application. + */ + +/* + *--------------------------------------------------------------- + * CHECK SERVER API + *--------------------------------------------------------------- + */ + +// Refuse to run when called from php-cgi +if (str_starts_with(PHP_SAPI, 'cgi')) { + exit("The cli tool is not supported when running php-cgi. It needs php-cli to function!\n\n"); +} + +/* + *--------------------------------------------------------------- + * CHECK PHP VERSION + *--------------------------------------------------------------- + */ + +$minPhpVersion = '8.1'; // If you update this, don't forget to update `public/index.php`. +if (version_compare(PHP_VERSION, $minPhpVersion, '<')) { + $message = sprintf( + 'Your PHP version must be %s or higher to run CodeIgniter. Current version: %s', + $minPhpVersion, + PHP_VERSION + ); + + exit($message); +} + +// We want errors to be shown when using it from the CLI. +error_reporting(E_ALL); +ini_set('display_errors', '1'); + +/* + *--------------------------------------------------------------- + * SET THE CURRENT DIRECTORY + *--------------------------------------------------------------- + */ + +// Path to the front controller +define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR); + +// Ensure the current directory is pointing to the front controller's directory +chdir(FCPATH); + +/* + *--------------------------------------------------------------- + * BOOTSTRAP THE APPLICATION + *--------------------------------------------------------------- + * This process sets up the path constants, loads and registers + * our autoloader, along with Composer's, loads our constants + * and fires up an environment-specific bootstrapping. + */ + +// LOAD OUR PATHS CONFIG FILE +// This is the line that might need to be changed, depending on your folder structure. +require FCPATH . '../app/Config/Paths.php'; +// ^^^ Change this line if you move your application folder + +$paths = new Config\Paths(); + +// LOAD THE FRAMEWORK BOOTSTRAP FILE +require $paths->systemDirectory . '/Boot.php'; + +exit(CodeIgniter\Boot::bootSpark($paths)); diff --git a/tests/.htaccess b/tests/.htaccess new file mode 100644 index 0000000..3462048 --- /dev/null +++ b/tests/.htaccess @@ -0,0 +1,6 @@ + + Require all denied + + + Deny from all + diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..fc40e44 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,118 @@ +# Running Application Tests + +This is the quick-start to CodeIgniter testing. Its intent is to describe what +it takes to set up your application and get it ready to run unit tests. +It is not intended to be a full description of the test features that you can +use to test your application. Those details can be found in the documentation. + +## Resources + +* [CodeIgniter 4 User Guide on Testing](https://codeigniter.com/user_guide/testing/index.html) +* [PHPUnit docs](https://phpunit.de/documentation.html) +* [Any tutorials on Unit testing in CI4?](https://forum.codeigniter.com/showthread.php?tid=81830) + +## Requirements + +It is recommended to use the latest version of PHPUnit. At the time of this +writing, we are running version 9.x. Support for this has been built into the +**composer.json** file that ships with CodeIgniter and can easily be installed +via [Composer](https://getcomposer.org/) if you don't already have it installed globally. + +```console +> composer install +``` + +If running under macOS or Linux, you can create a symbolic link to make running tests a touch nicer. + +```console +> ln -s ./vendor/bin/phpunit ./phpunit +``` + +You also need to install [XDebug](https://xdebug.org/docs/install) in order +for code coverage to be calculated successfully. After installing `XDebug`, you must add `xdebug.mode=coverage` in the **php.ini** file to enable code coverage. + +## Setting Up + +A number of the tests use a running database. +In order to set up the database edit the details for the `tests` group in +**app/Config/Database.php** or **.env**. +Make sure that you provide a database engine that is currently running on your machine. +More details on a test database setup are in the +[Testing Your Database](https://codeigniter.com/user_guide/testing/database.html) section of the documentation. + +## Running the tests + +The entire test suite can be run by simply typing one command-line command from the main directory. + +```console +> ./phpunit +``` + +If you are using Windows, use the following command. + +```console +> vendor\bin\phpunit +``` + +You can limit tests to those within a single test directory by specifying the +directory name after phpunit. + +```console +> ./phpunit app/Models +``` + +## Generating Code Coverage + +To generate coverage information, including HTML reports you can view in your browser, +you can use the following command: + +```console +> ./phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m +``` + +This runs all of the tests again collecting information about how many lines, +functions, and files are tested. It also reports the percentage of the code that is covered by tests. +It is collected in two formats: a simple text file that provides an overview as well +as a comprehensive collection of HTML files that show the status of every line of code in the project. + +The text file can be found at **tests/coverage.txt**. +The HTML files can be viewed by opening **tests/coverage/index.html** in your favorite browser. + +## PHPUnit XML Configuration + +The repository has a ``phpunit.xml.dist`` file in the project root that's used for +PHPUnit configuration. This is used to provide a default configuration if you +do not have your own configuration file in the project root. + +The normal practice would be to copy ``phpunit.xml.dist`` to ``phpunit.xml`` +(which is git ignored), and to tailor it as you see fit. +For instance, you might wish to exclude database tests, or automatically generate +HTML code coverage reports. + +## Test Cases + +Every test needs a *test case*, or class that your tests extend. CodeIgniter 4 +provides one class that you may use directly: +* `CodeIgniter\Test\CIUnitTestCase` + +Most of the time you will want to write your own test cases that extend `CIUnitTestCase` +to hold functions and services common to your test suites. + +## Creating Tests + +All tests go in the **tests/** directory. Each test file is a class that extends a +**Test Case** (see above) and contains methods for the individual tests. These method +names must start with the word "test" and should have descriptive names for precisely what +they are testing: +`testUserCanModifyFile()` `testOutputColorMatchesInput()` `testIsLoggedInFailsWithInvalidUser()` + +Writing tests is an art, and there are many resources available to help learn how. +Review the links above and always pay attention to your code coverage. + +### Database Tests + +Tests can include migrating, seeding, and testing against a mock or live database. +Be sure to modify the test case (or create your own) to point to your seed and migrations +and include any additional steps to be run before tests in the `setUp()` method. +See [Testing Your Database](https://codeigniter.com/user_guide/testing/database.html) +for details. diff --git a/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php b/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php new file mode 100644 index 0000000..a73356d --- /dev/null +++ b/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php @@ -0,0 +1,37 @@ +forge->addField('id'); + $this->forge->addField([ + 'name' => ['type' => 'varchar', 'constraint' => 31], + 'uid' => ['type' => 'varchar', 'constraint' => 31], + 'class' => ['type' => 'varchar', 'constraint' => 63], + 'icon' => ['type' => 'varchar', 'constraint' => 31], + 'summary' => ['type' => 'varchar', 'constraint' => 255], + 'created_at' => ['type' => 'datetime', 'null' => true], + 'updated_at' => ['type' => 'datetime', 'null' => true], + 'deleted_at' => ['type' => 'datetime', 'null' => true], + ]); + + $this->forge->addKey('name'); + $this->forge->addKey('uid'); + $this->forge->addKey(['deleted_at', 'id']); + $this->forge->addKey('created_at'); + + $this->forge->createTable('factories'); + } + + public function down(): void + { + $this->forge->dropTable('factories'); + } +} diff --git a/tests/_support/Database/Seeds/ExampleSeeder.php b/tests/_support/Database/Seeds/ExampleSeeder.php new file mode 100644 index 0000000..619fc27 --- /dev/null +++ b/tests/_support/Database/Seeds/ExampleSeeder.php @@ -0,0 +1,41 @@ + 'Test Factory', + 'uid' => 'test001', + 'class' => 'Factories\Tests\NewFactory', + 'icon' => 'fas fa-puzzle-piece', + 'summary' => 'Longer sample text for testing', + ], + [ + 'name' => 'Widget Factory', + 'uid' => 'widget', + 'class' => 'Factories\Tests\WidgetPlant', + 'icon' => 'fas fa-puzzle-piece', + 'summary' => 'Create widgets in your factory', + ], + [ + 'name' => 'Evil Factory', + 'uid' => 'evil-maker', + 'class' => 'Factories\Evil\MyFactory', + 'icon' => 'fas fa-book-dead', + 'summary' => 'Abandon all hope, ye who enter here', + ], + ]; + + $builder = $this->db->table('factories'); + + foreach ($factories as $factory) { + $builder->insert($factory); + } + } +} diff --git a/tests/_support/Libraries/ConfigReader.php b/tests/_support/Libraries/ConfigReader.php new file mode 100644 index 0000000..40d057a --- /dev/null +++ b/tests/_support/Libraries/ConfigReader.php @@ -0,0 +1,17 @@ +findAll(); + + // Make sure the count is as expected + $this->assertCount(3, $objects); + } + + public function testSoftDeleteLeavesRow(): void + { + $model = new ExampleModel(); + $this->setPrivateProperty($model, 'useSoftDeletes', true); + $this->setPrivateProperty($model, 'tempUseSoftDeletes', true); + + /** @var stdClass $object */ + $object = $model->first(); + $model->delete($object->id); + + // The model should no longer find it + $this->assertNull($model->find($object->id)); + + // ... but it should still be in the database + $result = $model->builder()->where('id', $object->id)->get()->getResult(); + + $this->assertCount(1, $result); + } +} diff --git a/tests/index.html b/tests/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/tests/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/tests/session/ExampleSessionTest.php b/tests/session/ExampleSessionTest.php new file mode 100644 index 0000000..6ada0c5 --- /dev/null +++ b/tests/session/ExampleSessionTest.php @@ -0,0 +1,18 @@ +set('logged_in', 123); + $this->assertSame(123, $session->get('logged_in')); + } +} diff --git a/tests/unit/HealthTest.php b/tests/unit/HealthTest.php new file mode 100644 index 0000000..25f229b --- /dev/null +++ b/tests/unit/HealthTest.php @@ -0,0 +1,50 @@ +assertTrue(defined('APPPATH')); + } + + public function testBaseUrlHasBeenSet(): void + { + $validation = Services::validation(); + + $env = false; + + // Check the baseURL in .env + if (is_file(HOMEPATH . '.env')) { + $env = preg_grep('/^app\.baseURL = ./', file(HOMEPATH . '.env')) !== false; + } + + if ($env) { + // BaseURL in .env is a valid URL? + // phpunit.xml.dist sets app.baseURL in $_SERVER + // So if you set app.baseURL in .env, it takes precedence + $config = new App(); + $this->assertTrue( + $validation->check($config->baseURL, 'valid_url'), + 'baseURL "' . $config->baseURL . '" in .env is not valid URL' + ); + } + + // Get the baseURL in app/Config/App.php + // You can't use Config\App, because phpunit.xml.dist sets app.baseURL + $reader = new ConfigReader(); + + // BaseURL in app/Config/App.php is a valid URL? + $this->assertTrue( + $validation->check($reader->baseURL, 'valid_url'), + 'baseURL "' . $reader->baseURL . '" in app/Config/App.php is not valid URL' + ); + } +} diff --git a/writable/.htaccess b/writable/.htaccess new file mode 100644 index 0000000..a94c5b0 --- /dev/null +++ b/writable/.htaccess @@ -0,0 +1,12 @@ + + Require all denied + + + Deny from all + + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.*)$ index.php/$1 [L] + \ No newline at end of file diff --git a/writable/cache/index.html b/writable/cache/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/writable/cache/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/writable/debugbar/index.html b/writable/debugbar/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/writable/debugbar/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/writable/excel/index.html b/writable/excel/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/writable/excel/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/writable/index.html b/writable/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/writable/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/writable/logs/index.html b/writable/logs/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/writable/logs/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/writable/uploads/index.html b/writable/uploads/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/writable/uploads/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + +