From e79a923290e6b19114d0946549e13ef0a317a0a2 Mon Sep 17 00:00:00 2001 From: mikael-zakaria Date: Fri, 15 Aug 2025 11:38:41 +0700 Subject: [PATCH] First Commit --- .gitignore | 130 +- .../license.txt => LICENSE | 13 +- README.md | 68 + app/.htaccess | 4 +- app/Common.php | 4 +- app/Config/App.php | 413 +- app/Config/Autoload.php | 49 +- app/Config/Boot/development.php | 4 +- app/Config/Boot/production.php | 6 +- app/Config/Boot/testing.php | 8 +- app/Config/CURLRequest.php | 4 +- app/Config/Cache.php | 93 +- app/Config/Constants.php | 15 - app/Config/ContentSecurityPolicy.php | 58 +- app/Config/Cookie.php | 29 +- app/Config/Cors.php | 105 + app/Config/CustomValidation.php | 19 - app/Config/Database.php | 182 +- app/Config/DocTypes.php | 12 +- app/Config/Email.php | 117 +- app/Config/Encryption.php | 49 +- app/Config/Events.php | 11 +- app/Config/Exceptions.php | 66 +- app/Config/Feature.php | 35 +- app/Config/Filters.php | 75 +- app/Config/ForeignCharacters.php | 3 + app/Config/Format.php | 21 +- app/Config/Generators.php | 8 +- app/Config/Honeypot.php | 27 +- app/Config/Images.php | 10 +- app/Config/Kint.php | 38 +- app/Config/Logger.php | 35 +- app/Config/Migrations.php | 23 +- app/Config/Mimes.php | 10 +- app/Config/Modules.php | 31 +- app/Config/Optimize.php | 30 + app/Config/Pager.php | 6 +- app/Config/Paths.php | 20 +- app/Config/Publisher.php | 2 +- app/Config/Routes.php | 78 +- app/Config/Routing.php | 140 + app/Config/Security.php | 49 +- app/Config/Session.php | 127 + app/Config/Toolbar.php | 53 +- app/Config/UserAgents.php | 8 +- app/Config/Validation.php | 29 +- app/Config/View.php | 12 +- app/Controllers/Activities.php | 315 +- app/Controllers/Api.php | 55 + app/Controllers/BaseController.php | 12 +- app/Controllers/Clqms.php | 47 + app/Controllers/Dashboard.php | 4 +- app/Controllers/InvTrans.php | 2 +- app/Controllers/Kanban.php | 249 + app/Controllers/Key.php | 124 + app/Controllers/Lqms.php | 46 + app/Controllers/ProductCatalog.php | 2 +- app/Controllers/ProductTemp.php | 150 + app/Controllers/Products.php | 130 +- app/Controllers/Sites.php | 37 +- app/Controllers/UnitGroup.php | 13 +- app/Filters/Cors.php | 26 + app/Models/ProductTempModel.php | 12 + app/Models/UnitGroupModel.php | 2 +- app/Validation/Usersrules.php | 15 - app/Views/accounts_index.php | 4 +- app/Views/activities_compose.php | 4 +- app/Views/activities_content.php | 18 +- app/Views/activities_count.php | 39 +- app/Views/activities_editor.php | 26 +- app/Views/activities_export_excel.php | 18 +- app/Views/activities_index.php | 142 +- app/Views/activities_newtextarea.php | 2 +- app/Views/activities_servicereport.php | 114 + app/Views/clqms_index.php | 54 + app/Views/components/modal.php | 17 + app/Views/components/offcanvas.php | 13 + app/Views/dashboard_recent_act.php | 8 + app/Views/invtrans_index.php | 15 +- app/Views/kanban_index.php.bak | 180 + app/Views/kb_board_edit.php | 217 + app/Views/kb_card_edit.php | 83 + app/Views/kb_index.php | 27 + app/Views/kb_list_edit.php | 32 + app/Views/kb_view.php | 137 + app/Views/layouts/_sidebar.php | 20 +- app/Views/layouts/form.php | 5 +- app/Views/lqms_index.php | 77 + app/Views/products_export_excel.php | 100 + app/Views/products_index.php | 134 +- app/Views/products_movesite.php | 51 +- app/Views/producttemp_index.php | 140 + app/Views/sites_editor.php | 12 +- app/Views/sites_index.php | 8 +- app/Views/sites_view.php | 8 +- app/Views/unitgroup_index.php | 24 +- builds | 125 + composer.json | 43 + composer.lock | 2087 ++ env | 69 + phpunit.xml.dist | 63 + preload.php | 110 + public/.htaccess | 4 +- public/assets/app.js | 117 - public/assets/bootstrap.bundle.min.js | 7 - public/assets/bootstrap.bundle.min.js.map | 1 - public/assets/crm.js | 7 - .../datatables/dataTables.bootstrap4.min.css | 1 - .../datatables/dataTables.bootstrap4.min.js | 8 - .../datatables/dataTables.responsive.min.js | 30 - .../datatables/jquery.dataTables.min.js | 175 - .../datatables/responsive.dataTables.min.css | 1 - public/assets/favicon.png | Bin 1394 -> 0 bytes public/assets/flatpickr/flatpickr.min.css | 13 - public/assets/flatpickr/flatpickr.min.js | 2 - .../assets/font-awesome-640/css/all.min.css | 9 - .../webfonts/fa-brands-400.ttf | Bin 187208 -> 0 bytes .../webfonts/fa-brands-400.woff2 | Bin 108020 -> 0 bytes .../webfonts/fa-regular-400.ttf | Bin 63952 -> 0 bytes .../webfonts/fa-regular-400.woff2 | Bin 24948 -> 0 bytes .../webfonts/fa-solid-900.ttf | Bin 394628 -> 0 bytes .../webfonts/fa-solid-900.woff2 | Bin 150124 -> 0 bytes .../webfonts/fa-v4compatibility.ttf | Bin 10172 -> 0 bytes .../webfonts/fa-v4compatibility.woff2 | Bin 4564 -> 0 bytes public/assets/font-awesome/css/all.css | 4423 ---- public/assets/font-awesome/css/all.min.css | 5 - public/assets/font-awesome/css/brands.css | 14 - public/assets/font-awesome/css/brands.min.css | 5 - .../assets/font-awesome/css/fontawesome.css | 4390 ---- .../font-awesome/css/fontawesome.min.css | 5 - public/assets/font-awesome/css/regular.css | 15 - .../assets/font-awesome/css/regular.min.css | 5 - public/assets/font-awesome/css/solid.css | 16 - public/assets/font-awesome/css/solid.min.css | 5 - .../assets/font-awesome/css/svg-with-js.css | 371 - .../font-awesome/css/svg-with-js.min.css | 5 - public/assets/font-awesome/css/v4-shims.css | 2166 -- .../assets/font-awesome/css/v4-shims.min.css | 5 - .../assets/font-awesome/less/_animated.less | 19 - .../font-awesome/less/_bordered-pulled.less | 16 - public/assets/font-awesome/less/_core.less | 12 - .../font-awesome/less/_fixed-width.less | 6 - public/assets/font-awesome/less/_icons.less | 1397 - public/assets/font-awesome/less/_larger.less | 27 - public/assets/font-awesome/less/_list.less | 18 - public/assets/font-awesome/less/_mixins.less | 56 - .../font-awesome/less/_rotated-flipped.less | 24 - .../font-awesome/less/_screen-reader.less | 5 - public/assets/font-awesome/less/_shims.less | 2062 -- public/assets/font-awesome/less/_stacked.less | 22 - .../assets/font-awesome/less/_variables.less | 1409 - public/assets/font-awesome/less/brands.less | 22 - .../assets/font-awesome/less/fontawesome.less | 16 - public/assets/font-awesome/less/regular.less | 23 - public/assets/font-awesome/less/solid.less | 24 - public/assets/font-awesome/less/v4-shims.less | 6 - .../assets/font-awesome/scss/_animated.scss | 20 - .../font-awesome/scss/_bordered-pulled.scss | 20 - public/assets/font-awesome/scss/_core.scss | 21 - .../font-awesome/scss/_fixed-width.scss | 6 - public/assets/font-awesome/scss/_icons.scss | 1397 - public/assets/font-awesome/scss/_larger.scss | 23 - public/assets/font-awesome/scss/_list.scss | 18 - public/assets/font-awesome/scss/_mixins.scss | 56 - .../font-awesome/scss/_rotated-flipped.scss | 24 - .../font-awesome/scss/_screen-reader.scss | 5 - public/assets/font-awesome/scss/_shims.scss | 2062 -- public/assets/font-awesome/scss/_stacked.scss | 31 - .../assets/font-awesome/scss/_variables.scss | 1414 - public/assets/font-awesome/scss/brands.scss | 22 - .../assets/font-awesome/scss/fontawesome.scss | 16 - public/assets/font-awesome/scss/regular.scss | 23 - public/assets/font-awesome/scss/solid.scss | 24 - public/assets/font-awesome/scss/v4-shims.scss | 6 - .../font-awesome/webfonts/fa-brands-400.eot | Bin 130906 -> 0 bytes .../font-awesome/webfonts/fa-brands-400.svg | 3496 --- .../font-awesome/webfonts/fa-brands-400.ttf | Bin 130600 -> 0 bytes .../font-awesome/webfonts/fa-brands-400.woff | Bin 88428 -> 0 bytes .../font-awesome/webfonts/fa-brands-400.woff2 | Bin 75336 -> 0 bytes .../font-awesome/webfonts/fa-regular-400.eot | Bin 34394 -> 0 bytes .../font-awesome/webfonts/fa-regular-400.svg | 803 - .../font-awesome/webfonts/fa-regular-400.ttf | Bin 34096 -> 0 bytes .../font-awesome/webfonts/fa-regular-400.woff | Bin 16804 -> 0 bytes .../webfonts/fa-regular-400.woff2 | Bin 13584 -> 0 bytes .../font-awesome/webfonts/fa-solid-900.eot | Bin 192758 -> 0 bytes .../font-awesome/webfonts/fa-solid-900.svg | 4667 ---- .../font-awesome/webfonts/fa-solid-900.ttf | Bin 192472 -> 0 bytes .../font-awesome/webfonts/fa-solid-900.woff | Bin 98384 -> 0 bytes .../font-awesome/webfonts/fa-solid-900.woff2 | Bin 75728 -> 0 bytes public/assets/html2canvas/html2canvas.js | 7830 ------ public/assets/images/bg-01.jpg | Bin 138691 -> 0 bytes public/assets/images/logo.png | Bin 16046 -> 0 bytes public/assets/images/logo_1.png | Bin 16371 -> 0 bytes public/assets/jquery.sparkline.min.js | 5 - public/assets/jquery/jquery.min.js | 2 - public/assets/jquery/jquery.min.map | 1 - public/assets/jspdf/jspdf.umd.min.js | 398 - public/assets/login.css | 58 - public/assets/perfect-scrollbar.jquery.min.js | 2 - .../select2/select2-bootstrap-5-theme.min.css | 1031 - public/assets/select2/select2.min.css | 1 - public/assets/select2/select2.min.js | 2 - public/assets/sidebarmenu.min.js | 1 - public/assets/sticky-kit.min.js | 10 - public/assets/style.css | 21669 ---------------- .../icons/default/icons.min.js | 1 - .../TinyMCE-version-6.6.2/langs/README.md | 3 - .../models/dom/model.min.js | 4 - .../plugins/accordion/plugin.min.js | 4 - .../plugins/advlist/plugin.min.js | 4 - .../plugins/anchor/plugin.min.js | 4 - .../plugins/autolink/plugin.min.js | 4 - .../plugins/autoresize/plugin.min.js | 4 - .../plugins/autosave/plugin.min.js | 4 - .../plugins/charmap/plugin.min.js | 4 - .../plugins/code/plugin.min.js | 4 - .../plugins/codesample/plugin.min.js | 4 - .../plugins/directionality/plugin.min.js | 4 - .../plugins/emoticons/js/emojiimages.js | 1 - .../plugins/emoticons/js/emojiimages.min.js | 3 - .../plugins/emoticons/js/emojis.js | 1 - .../plugins/emoticons/js/emojis.min.js | 2 - .../plugins/emoticons/plugin.min.js | 4 - .../plugins/fullscreen/plugin.min.js | 4 - .../plugins/help/js/i18n/keynav/ar.js | 90 - .../plugins/help/js/i18n/keynav/bg_BG.js | 90 - .../plugins/help/js/i18n/keynav/ca.js | 90 - .../plugins/help/js/i18n/keynav/cs.js | 90 - .../plugins/help/js/i18n/keynav/da.js | 90 - .../plugins/help/js/i18n/keynav/de.js | 90 - .../plugins/help/js/i18n/keynav/el.js | 90 - .../plugins/help/js/i18n/keynav/en.js | 90 - .../plugins/help/js/i18n/keynav/es.js | 90 - .../plugins/help/js/i18n/keynav/eu.js | 90 - .../plugins/help/js/i18n/keynav/fa.js | 90 - .../plugins/help/js/i18n/keynav/fi.js | 90 - .../plugins/help/js/i18n/keynav/fr_FR.js | 90 - .../plugins/help/js/i18n/keynav/he_IL.js | 90 - .../plugins/help/js/i18n/keynav/hi.js | 90 - .../plugins/help/js/i18n/keynav/hr.js | 90 - .../plugins/help/js/i18n/keynav/hu_HU.js | 90 - .../plugins/help/js/i18n/keynav/id.js | 90 - .../plugins/help/js/i18n/keynav/it.js | 90 - .../plugins/help/js/i18n/keynav/ja.js | 90 - .../plugins/help/js/i18n/keynav/kk.js | 90 - .../plugins/help/js/i18n/keynav/ko_KR.js | 90 - .../plugins/help/js/i18n/keynav/ms.js | 90 - .../plugins/help/js/i18n/keynav/nb_NO.js | 90 - .../plugins/help/js/i18n/keynav/nl.js | 90 - .../plugins/help/js/i18n/keynav/pl.js | 90 - .../plugins/help/js/i18n/keynav/pt_BR.js | 90 - .../plugins/help/js/i18n/keynav/pt_PT.js | 90 - .../plugins/help/js/i18n/keynav/ro.js | 90 - .../plugins/help/js/i18n/keynav/ru.js | 90 - .../plugins/help/js/i18n/keynav/sk.js | 90 - .../plugins/help/js/i18n/keynav/sl_SI.js | 90 - .../plugins/help/js/i18n/keynav/sv_SE.js | 90 - .../plugins/help/js/i18n/keynav/th_TH.js | 90 - .../plugins/help/js/i18n/keynav/tr.js | 90 - .../plugins/help/js/i18n/keynav/uk.js | 90 - .../plugins/help/js/i18n/keynav/vi.js | 90 - .../plugins/help/js/i18n/keynav/zh_CN.js | 84 - .../plugins/help/js/i18n/keynav/zh_TW.js | 90 - .../plugins/help/plugin.min.js | 4 - .../plugins/image/plugin.min.js | 4 - .../plugins/importcss/plugin.min.js | 4 - .../plugins/insertdatetime/plugin.min.js | 4 - .../plugins/link/plugin.min.js | 4 - .../plugins/lists/plugin.min.js | 4 - .../plugins/media/plugin.min.js | 4 - .../plugins/nonbreaking/plugin.min.js | 4 - .../plugins/pagebreak/plugin.min.js | 4 - .../plugins/preview/plugin.min.js | 4 - .../plugins/quickbars/plugin.min.js | 4 - .../plugins/save/plugin.min.js | 4 - .../plugins/searchreplace/plugin.min.js | 4 - .../plugins/table/plugin.min.js | 4 - .../plugins/template/plugin.min.js | 4 - .../plugins/visualblocks/plugin.min.js | 4 - .../plugins/visualchars/plugin.min.js | 4 - .../plugins/wordcount/plugin.min.js | 4 - .../skins/content/dark/content.min.css | 1 - .../skins/content/default/content.min.css | 1 - .../skins/content/document/content.min.css | 1 - .../content/tinymce-5-dark/content.min.css | 1 - .../skins/content/tinymce-5/content.min.css | 1 - .../skins/content/writer/content.min.css | 1 - .../ui/oxide-dark/content.inline.min.css | 1 - .../skins/ui/oxide-dark/content.min.css | 1 - .../skins/ui/oxide-dark/skin.min.css | 1 - .../ui/oxide-dark/skin.shadowdom.min.css | 1 - .../skins/ui/oxide/content.inline.min.css | 1 - .../skins/ui/oxide/content.min.css | 1 - .../skins/ui/oxide/skin.min.css | 1 - .../skins/ui/oxide/skin.shadowdom.min.css | 1 - .../ui/tinymce-5-dark/content.inline.min.css | 1 - .../skins/ui/tinymce-5-dark/content.min.css | 1 - .../skins/ui/tinymce-5-dark/skin.min.css | 1 - .../ui/tinymce-5-dark/skin.shadowdom.min.css | 1 - .../skins/ui/tinymce-5/content.inline.min.css | 1 - .../skins/ui/tinymce-5/content.min.css | 1 - .../skins/ui/tinymce-5/skin.min.css | 1 - .../skins/ui/tinymce-5/skin.shadowdom.min.css | 1 - .../themes/silver/theme.min.js | 4 - .../TinyMCE-version-6.6.2/tinymce.d.ts | 3214 --- .../TinyMCE-version-6.6.2/tinymce.min.js | 4 - .../assets/tinymce/icons/default/icons.min.js | 1 - public/assets/tinymce/langs/README.md | 3 - public/assets/tinymce/license.txt | 21 - public/assets/tinymce/models/dom/model.min.js | 4 - .../tinymce/plugins/accordion/plugin.min.js | 4 - .../tinymce/plugins/advlist/plugin.min.js | 4 - .../tinymce/plugins/anchor/plugin.min.js | 4 - .../tinymce/plugins/autolink/plugin.min.js | 4 - .../tinymce/plugins/autoresize/plugin.min.js | 4 - .../tinymce/plugins/autosave/plugin.min.js | 4 - .../tinymce/plugins/charmap/plugin.min.js | 4 - .../assets/tinymce/plugins/code/plugin.min.js | 4 - .../tinymce/plugins/codesample/plugin.min.js | 4 - .../plugins/directionality/plugin.min.js | 4 - .../plugins/emoticons/js/emojiimages.js | 1 - .../plugins/emoticons/js/emojiimages.min.js | 3 - .../tinymce/plugins/emoticons/js/emojis.js | 1 - .../plugins/emoticons/js/emojis.min.js | 2 - .../tinymce/plugins/emoticons/plugin.min.js | 4 - .../tinymce/plugins/fullscreen/plugin.min.js | 4 - .../tinymce/plugins/help/js/i18n/keynav/ar.js | 90 - .../plugins/help/js/i18n/keynav/bg_BG.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/ca.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/cs.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/da.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/de.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/el.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/en.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/es.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/eu.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/fa.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/fi.js | 90 - .../plugins/help/js/i18n/keynav/fr_FR.js | 90 - .../plugins/help/js/i18n/keynav/he_IL.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/hi.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/hr.js | 90 - .../plugins/help/js/i18n/keynav/hu_HU.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/id.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/it.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/ja.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/kk.js | 90 - .../plugins/help/js/i18n/keynav/ko_KR.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/ms.js | 90 - .../plugins/help/js/i18n/keynav/nb_NO.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/nl.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/pl.js | 90 - .../plugins/help/js/i18n/keynav/pt_BR.js | 90 - .../plugins/help/js/i18n/keynav/pt_PT.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/ro.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/ru.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/sk.js | 90 - .../plugins/help/js/i18n/keynav/sl_SI.js | 90 - .../plugins/help/js/i18n/keynav/sv_SE.js | 90 - .../plugins/help/js/i18n/keynav/th_TH.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/tr.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/uk.js | 90 - .../tinymce/plugins/help/js/i18n/keynav/vi.js | 90 - .../plugins/help/js/i18n/keynav/zh_CN.js | 84 - .../plugins/help/js/i18n/keynav/zh_TW.js | 90 - .../assets/tinymce/plugins/help/plugin.min.js | 4 - .../tinymce/plugins/image/plugin.min.js | 4 - .../tinymce/plugins/importcss/plugin.min.js | 4 - .../plugins/insertdatetime/plugin.min.js | 4 - .../assets/tinymce/plugins/link/plugin.min.js | 4 - .../tinymce/plugins/lists/plugin.min.js | 4 - .../tinymce/plugins/media/plugin.min.js | 4 - .../tinymce/plugins/nonbreaking/plugin.min.js | 4 - .../tinymce/plugins/pagebreak/plugin.min.js | 4 - .../tinymce/plugins/preview/plugin.min.js | 4 - .../tinymce/plugins/quickbars/plugin.min.js | 4 - .../assets/tinymce/plugins/save/plugin.min.js | 4 - .../plugins/searchreplace/plugin.min.js | 4 - .../tinymce/plugins/table/plugin.min.js | 4 - .../tinymce/plugins/template/plugin.min.js | 4 - .../plugins/visualblocks/plugin.min.js | 4 - .../tinymce/plugins/visualchars/plugin.min.js | 4 - .../tinymce/plugins/wordcount/plugin.min.js | 4 - .../tinymce/skins/content/dark/content.js | 2 - .../skins/content/dark/content.min.css | 1 - .../tinymce/skins/content/default/content.js | 2 - .../skins/content/default/content.min.css | 1 - .../tinymce/skins/content/document/content.js | 2 - .../skins/content/document/content.min.css | 1 - .../skins/content/tinymce-5-dark/content.js | 2 - .../content/tinymce-5-dark/content.min.css | 1 - .../skins/content/tinymce-5/content.js | 2 - .../skins/content/tinymce-5/content.min.css | 1 - .../tinymce/skins/content/writer/content.js | 2 - .../skins/content/writer/content.min.css | 1 - .../skins/ui/oxide-dark/content.inline.js | 2 - .../ui/oxide-dark/content.inline.min.css | 1 - .../tinymce/skins/ui/oxide-dark/content.js | 2 - .../skins/ui/oxide-dark/content.min.css | 1 - .../tinymce/skins/ui/oxide-dark/skin.js | 2 - .../tinymce/skins/ui/oxide-dark/skin.min.css | 1 - .../skins/ui/oxide-dark/skin.shadowdom.js | 2 - .../ui/oxide-dark/skin.shadowdom.min.css | 1 - .../tinymce/skins/ui/oxide/content.inline.js | 2 - .../skins/ui/oxide/content.inline.min.css | 1 - .../assets/tinymce/skins/ui/oxide/content.js | 2 - .../tinymce/skins/ui/oxide/content.min.css | 1 - public/assets/tinymce/skins/ui/oxide/skin.js | 2 - .../tinymce/skins/ui/oxide/skin.min.css | 1 - .../tinymce/skins/ui/oxide/skin.shadowdom.js | 2 - .../skins/ui/oxide/skin.shadowdom.min.css | 1 - .../skins/ui/tinymce-5-dark/content.inline.js | 2 - .../ui/tinymce-5-dark/content.inline.min.css | 1 - .../skins/ui/tinymce-5-dark/content.js | 2 - .../skins/ui/tinymce-5-dark/content.min.css | 1 - .../tinymce/skins/ui/tinymce-5-dark/skin.js | 2 - .../skins/ui/tinymce-5-dark/skin.min.css | 1 - .../skins/ui/tinymce-5-dark/skin.shadowdom.js | 2 - .../ui/tinymce-5-dark/skin.shadowdom.min.css | 1 - .../skins/ui/tinymce-5/content.inline.js | 2 - .../skins/ui/tinymce-5/content.inline.min.css | 1 - .../tinymce/skins/ui/tinymce-5/content.js | 2 - .../skins/ui/tinymce-5/content.min.css | 1 - .../assets/tinymce/skins/ui/tinymce-5/skin.js | 2 - .../tinymce/skins/ui/tinymce-5/skin.min.css | 1 - .../skins/ui/tinymce-5/skin.shadowdom.js | 2 - .../skins/ui/tinymce-5/skin.shadowdom.min.css | 1 - .../assets/tinymce/themes/silver/theme.min.js | 4 - public/assets/tinymce/tinymce-6_8_2.zip | Bin 894728 -> 0 bytes public/assets/tinymce/tinymce.d.ts | 3238 --- public/assets/tinymce/tinymce.min.js | 4 - public/assets/uppy/dashboard.min.css | 1 - public/assets/uppy/uppy-full.js | 2 - public/assets/uppy/uppy-old.js | 101 - public/assets/uppy/uppy.3.7.0.min.js | 20 - public/assets/uppy/uppy.min.css | 1 - public/assets/waves.min.js | 1 - public/assets/xlsx.mini.min.js | 10 - public/index.php | 66 +- spark | 87 + 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 | 19 + tests/_support/Models/ExampleModel.php | 24 + tests/database/ExampleDatabaseTest.php | 46 + tests/index.html | 11 + tests/session/ExampleSessionTest.php | 17 + tests/unit/HealthTest.php | 49 + writable/.htaccess | 6 + writable/cache/index.html | 11 + writable/debugbar/index.html | 11 + writable/index.html | 11 + writable/logs/index.html | 11 + writable/session/index.html | 11 + writable/uploads/index.html | 11 + 457 files changed, 7255 insertions(+), 77258 deletions(-) rename public/assets/tinymce/TinyMCE-version-6.6.2/license.txt => LICENSE (80%) create mode 100644 README.md create mode 100644 app/Config/Cors.php delete mode 100644 app/Config/CustomValidation.php create mode 100644 app/Config/Optimize.php create mode 100644 app/Config/Routing.php create mode 100644 app/Config/Session.php create mode 100644 app/Controllers/Api.php create mode 100644 app/Controllers/Clqms.php create mode 100644 app/Controllers/Kanban.php create mode 100644 app/Controllers/Key.php create mode 100644 app/Controllers/Lqms.php create mode 100644 app/Controllers/ProductTemp.php create mode 100644 app/Filters/Cors.php create mode 100644 app/Models/ProductTempModel.php delete mode 100644 app/Validation/Usersrules.php create mode 100644 app/Views/activities_servicereport.php create mode 100644 app/Views/clqms_index.php create mode 100644 app/Views/components/modal.php create mode 100644 app/Views/components/offcanvas.php create mode 100644 app/Views/kanban_index.php.bak create mode 100644 app/Views/kb_board_edit.php create mode 100644 app/Views/kb_card_edit.php create mode 100644 app/Views/kb_index.php create mode 100644 app/Views/kb_list_edit.php create mode 100644 app/Views/kb_view.php create mode 100644 app/Views/lqms_index.php create mode 100644 app/Views/products_export_excel.php create mode 100644 app/Views/producttemp_index.php create mode 100644 builds create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 env create mode 100644 phpunit.xml.dist create mode 100644 preload.php delete mode 100644 public/assets/app.js delete mode 100644 public/assets/bootstrap.bundle.min.js delete mode 100644 public/assets/bootstrap.bundle.min.js.map delete mode 100644 public/assets/crm.js delete mode 100644 public/assets/datatables/dataTables.bootstrap4.min.css delete mode 100644 public/assets/datatables/dataTables.bootstrap4.min.js delete mode 100644 public/assets/datatables/dataTables.responsive.min.js delete mode 100644 public/assets/datatables/jquery.dataTables.min.js delete mode 100644 public/assets/datatables/responsive.dataTables.min.css delete mode 100644 public/assets/favicon.png delete mode 100644 public/assets/flatpickr/flatpickr.min.css delete mode 100644 public/assets/flatpickr/flatpickr.min.js delete mode 100644 public/assets/font-awesome-640/css/all.min.css delete mode 100644 public/assets/font-awesome-640/webfonts/fa-brands-400.ttf delete mode 100644 public/assets/font-awesome-640/webfonts/fa-brands-400.woff2 delete mode 100644 public/assets/font-awesome-640/webfonts/fa-regular-400.ttf delete mode 100644 public/assets/font-awesome-640/webfonts/fa-regular-400.woff2 delete mode 100644 public/assets/font-awesome-640/webfonts/fa-solid-900.ttf delete mode 100644 public/assets/font-awesome-640/webfonts/fa-solid-900.woff2 delete mode 100644 public/assets/font-awesome-640/webfonts/fa-v4compatibility.ttf delete mode 100644 public/assets/font-awesome-640/webfonts/fa-v4compatibility.woff2 delete mode 100644 public/assets/font-awesome/css/all.css delete mode 100644 public/assets/font-awesome/css/all.min.css delete mode 100644 public/assets/font-awesome/css/brands.css delete mode 100644 public/assets/font-awesome/css/brands.min.css delete mode 100644 public/assets/font-awesome/css/fontawesome.css delete mode 100644 public/assets/font-awesome/css/fontawesome.min.css delete mode 100644 public/assets/font-awesome/css/regular.css delete mode 100644 public/assets/font-awesome/css/regular.min.css delete mode 100644 public/assets/font-awesome/css/solid.css delete mode 100644 public/assets/font-awesome/css/solid.min.css delete mode 100644 public/assets/font-awesome/css/svg-with-js.css delete mode 100644 public/assets/font-awesome/css/svg-with-js.min.css delete mode 100644 public/assets/font-awesome/css/v4-shims.css delete mode 100644 public/assets/font-awesome/css/v4-shims.min.css delete mode 100644 public/assets/font-awesome/less/_animated.less delete mode 100644 public/assets/font-awesome/less/_bordered-pulled.less delete mode 100644 public/assets/font-awesome/less/_core.less delete mode 100644 public/assets/font-awesome/less/_fixed-width.less delete mode 100644 public/assets/font-awesome/less/_icons.less delete mode 100644 public/assets/font-awesome/less/_larger.less delete mode 100644 public/assets/font-awesome/less/_list.less delete mode 100644 public/assets/font-awesome/less/_mixins.less delete mode 100644 public/assets/font-awesome/less/_rotated-flipped.less delete mode 100644 public/assets/font-awesome/less/_screen-reader.less delete mode 100644 public/assets/font-awesome/less/_shims.less delete mode 100644 public/assets/font-awesome/less/_stacked.less delete mode 100644 public/assets/font-awesome/less/_variables.less delete mode 100644 public/assets/font-awesome/less/brands.less delete mode 100644 public/assets/font-awesome/less/fontawesome.less delete mode 100644 public/assets/font-awesome/less/regular.less delete mode 100644 public/assets/font-awesome/less/solid.less delete mode 100644 public/assets/font-awesome/less/v4-shims.less delete mode 100644 public/assets/font-awesome/scss/_animated.scss delete mode 100644 public/assets/font-awesome/scss/_bordered-pulled.scss delete mode 100644 public/assets/font-awesome/scss/_core.scss delete mode 100644 public/assets/font-awesome/scss/_fixed-width.scss delete mode 100644 public/assets/font-awesome/scss/_icons.scss delete mode 100644 public/assets/font-awesome/scss/_larger.scss delete mode 100644 public/assets/font-awesome/scss/_list.scss delete mode 100644 public/assets/font-awesome/scss/_mixins.scss delete mode 100644 public/assets/font-awesome/scss/_rotated-flipped.scss delete mode 100644 public/assets/font-awesome/scss/_screen-reader.scss delete mode 100644 public/assets/font-awesome/scss/_shims.scss delete mode 100644 public/assets/font-awesome/scss/_stacked.scss delete mode 100644 public/assets/font-awesome/scss/_variables.scss delete mode 100644 public/assets/font-awesome/scss/brands.scss delete mode 100644 public/assets/font-awesome/scss/fontawesome.scss delete mode 100644 public/assets/font-awesome/scss/regular.scss delete mode 100644 public/assets/font-awesome/scss/solid.scss delete mode 100644 public/assets/font-awesome/scss/v4-shims.scss delete mode 100644 public/assets/font-awesome/webfonts/fa-brands-400.eot delete mode 100644 public/assets/font-awesome/webfonts/fa-brands-400.svg delete mode 100644 public/assets/font-awesome/webfonts/fa-brands-400.ttf delete mode 100644 public/assets/font-awesome/webfonts/fa-brands-400.woff delete mode 100644 public/assets/font-awesome/webfonts/fa-brands-400.woff2 delete mode 100644 public/assets/font-awesome/webfonts/fa-regular-400.eot delete mode 100644 public/assets/font-awesome/webfonts/fa-regular-400.svg delete mode 100644 public/assets/font-awesome/webfonts/fa-regular-400.ttf delete mode 100644 public/assets/font-awesome/webfonts/fa-regular-400.woff delete mode 100644 public/assets/font-awesome/webfonts/fa-regular-400.woff2 delete mode 100644 public/assets/font-awesome/webfonts/fa-solid-900.eot delete mode 100644 public/assets/font-awesome/webfonts/fa-solid-900.svg delete mode 100644 public/assets/font-awesome/webfonts/fa-solid-900.ttf delete mode 100644 public/assets/font-awesome/webfonts/fa-solid-900.woff delete mode 100644 public/assets/font-awesome/webfonts/fa-solid-900.woff2 delete mode 100644 public/assets/html2canvas/html2canvas.js delete mode 100644 public/assets/images/bg-01.jpg delete mode 100644 public/assets/images/logo.png delete mode 100644 public/assets/images/logo_1.png delete mode 100644 public/assets/jquery.sparkline.min.js delete mode 100644 public/assets/jquery/jquery.min.js delete mode 100644 public/assets/jquery/jquery.min.map delete mode 100644 public/assets/jspdf/jspdf.umd.min.js delete mode 100644 public/assets/login.css delete mode 100644 public/assets/perfect-scrollbar.jquery.min.js delete mode 100644 public/assets/select2/select2-bootstrap-5-theme.min.css delete mode 100644 public/assets/select2/select2.min.css delete mode 100644 public/assets/select2/select2.min.js delete mode 100644 public/assets/sidebarmenu.min.js delete mode 100644 public/assets/sticky-kit.min.js delete mode 100644 public/assets/style.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/icons/default/icons.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/langs/README.md delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/models/dom/model.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/accordion/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/advlist/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/anchor/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/autolink/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/autoresize/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/autosave/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/charmap/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/code/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/codesample/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/directionality/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/emoticons/js/emojiimages.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/emoticons/js/emojiimages.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/emoticons/js/emojis.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/emoticons/js/emojis.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/emoticons/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/fullscreen/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/ar.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/bg_BG.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/ca.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/cs.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/da.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/de.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/el.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/en.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/es.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/eu.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/fa.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/fi.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/fr_FR.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/he_IL.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/hi.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/hr.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/hu_HU.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/id.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/it.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/ja.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/kk.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/ko_KR.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/ms.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/nb_NO.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/nl.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/pl.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/pt_BR.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/pt_PT.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/ro.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/ru.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/sk.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/sl_SI.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/sv_SE.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/th_TH.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/tr.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/uk.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/vi.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/zh_CN.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/js/i18n/keynav/zh_TW.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/help/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/image/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/importcss/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/insertdatetime/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/link/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/lists/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/media/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/nonbreaking/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/pagebreak/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/preview/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/quickbars/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/save/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/searchreplace/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/table/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/template/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/visualblocks/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/visualchars/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/plugins/wordcount/plugin.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/content/dark/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/content/default/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/content/document/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/content/tinymce-5-dark/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/content/tinymce-5/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/content/writer/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide-dark/content.inline.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide-dark/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide-dark/skin.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide-dark/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide/content.inline.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide/skin.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/oxide/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5-dark/content.inline.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5-dark/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5-dark/skin.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5-dark/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5/content.inline.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5/content.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5/skin.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/skins/ui/tinymce-5/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/themes/silver/theme.min.js delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/tinymce.d.ts delete mode 100644 public/assets/tinymce/TinyMCE-version-6.6.2/tinymce.min.js delete mode 100644 public/assets/tinymce/icons/default/icons.min.js delete mode 100644 public/assets/tinymce/langs/README.md delete mode 100644 public/assets/tinymce/license.txt delete mode 100644 public/assets/tinymce/models/dom/model.min.js delete mode 100644 public/assets/tinymce/plugins/accordion/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/advlist/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/anchor/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/autolink/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/autoresize/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/autosave/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/charmap/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/code/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/codesample/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/directionality/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/emoticons/js/emojiimages.js delete mode 100644 public/assets/tinymce/plugins/emoticons/js/emojiimages.min.js delete mode 100644 public/assets/tinymce/plugins/emoticons/js/emojis.js delete mode 100644 public/assets/tinymce/plugins/emoticons/js/emojis.min.js delete mode 100644 public/assets/tinymce/plugins/emoticons/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/fullscreen/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/ar.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/bg_BG.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/ca.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/cs.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/da.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/de.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/el.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/en.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/es.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/eu.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/fa.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/fi.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/fr_FR.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/he_IL.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/hi.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/hr.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/hu_HU.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/id.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/it.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/ja.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/kk.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/ko_KR.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/ms.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/nb_NO.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/nl.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/pl.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/pt_BR.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/pt_PT.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/ro.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/ru.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/sk.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/sl_SI.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/sv_SE.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/th_TH.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/tr.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/uk.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/vi.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/zh_CN.js delete mode 100644 public/assets/tinymce/plugins/help/js/i18n/keynav/zh_TW.js delete mode 100644 public/assets/tinymce/plugins/help/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/image/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/importcss/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/insertdatetime/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/link/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/lists/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/media/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/nonbreaking/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/pagebreak/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/preview/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/quickbars/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/save/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/searchreplace/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/table/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/template/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/visualblocks/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/visualchars/plugin.min.js delete mode 100644 public/assets/tinymce/plugins/wordcount/plugin.min.js delete mode 100644 public/assets/tinymce/skins/content/dark/content.js delete mode 100644 public/assets/tinymce/skins/content/dark/content.min.css delete mode 100644 public/assets/tinymce/skins/content/default/content.js delete mode 100644 public/assets/tinymce/skins/content/default/content.min.css delete mode 100644 public/assets/tinymce/skins/content/document/content.js delete mode 100644 public/assets/tinymce/skins/content/document/content.min.css delete mode 100644 public/assets/tinymce/skins/content/tinymce-5-dark/content.js delete mode 100644 public/assets/tinymce/skins/content/tinymce-5-dark/content.min.css delete mode 100644 public/assets/tinymce/skins/content/tinymce-5/content.js delete mode 100644 public/assets/tinymce/skins/content/tinymce-5/content.min.css delete mode 100644 public/assets/tinymce/skins/content/writer/content.js delete mode 100644 public/assets/tinymce/skins/content/writer/content.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/content.inline.js delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/content.inline.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/content.js delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/content.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/skin.js delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/skin.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/skin.shadowdom.js delete mode 100644 public/assets/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide/content.inline.js delete mode 100644 public/assets/tinymce/skins/ui/oxide/content.inline.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide/content.js delete mode 100644 public/assets/tinymce/skins/ui/oxide/content.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide/skin.js delete mode 100644 public/assets/tinymce/skins/ui/oxide/skin.min.css delete mode 100644 public/assets/tinymce/skins/ui/oxide/skin.shadowdom.js delete mode 100644 public/assets/tinymce/skins/ui/oxide/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/content.inline.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/content.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/content.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/skin.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/skin.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/content.inline.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/content.inline.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/content.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/content.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/skin.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/skin.min.css delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/skin.shadowdom.js delete mode 100644 public/assets/tinymce/skins/ui/tinymce-5/skin.shadowdom.min.css delete mode 100644 public/assets/tinymce/themes/silver/theme.min.js delete mode 100644 public/assets/tinymce/tinymce-6_8_2.zip delete mode 100644 public/assets/tinymce/tinymce.d.ts delete mode 100644 public/assets/tinymce/tinymce.min.js delete mode 100644 public/assets/uppy/dashboard.min.css delete mode 100644 public/assets/uppy/uppy-full.js delete mode 100644 public/assets/uppy/uppy-old.js delete mode 100644 public/assets/uppy/uppy.3.7.0.min.js delete mode 100644 public/assets/uppy/uppy.min.css delete mode 100644 public/assets/waves.min.js delete mode 100644 public/assets/xlsx.mini.min.js 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/index.html create mode 100644 writable/logs/index.html create mode 100644 writable/session/index.html create mode 100644 writable/uploads/index.html diff --git a/.gitignore b/.gitignore index 4b054e4..87e86b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,126 @@ -/* -!app/ -!public/ -!.gitignore \ No newline at end of file +#------------------------- +# Operating Specific Junk Files +#------------------------- + +# OS X +.DS_Store +.AppleDouble +.LSOverride + +# OS X Thumbnails +._* + +# Windows image file caches +Thumbs.db +ehthumbs.db +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Linux +*~ + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +#------------------------- +# Environment Files +#------------------------- +# These should never be under version control, +# as it poses a security risk. +.env +.vagrant +Vagrantfile + +#------------------------- +# Temporary Files +#------------------------- +writable/cache/* +!writable/cache/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 + +php_errors.log + +#------------------------- +# User Guide Temp Files +#------------------------- +user_guide_src/build/* +user_guide_src/cilexer/build/* +user_guide_src/cilexer/dist/* +user_guide_src/cilexer/pycilexer.egg-info/* + +#------------------------- +# Test Files +#------------------------- +tests/coverage* + +# Don't save phpunit under version control. +phpunit + +#------------------------- +# Composer +#------------------------- +vendor/ + +#------------------------- +# IDE / Development Files +#------------------------- + +# Modules Testing +_modules/* + +# phpenv local config +.php-version + +# Jetbrains editors (PHPStorm, etc) +.idea/ +*.iml + +# NetBeans +/nbproject/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/nbactions.xml +/nb-configuration.xml +/.nb-gradle/ + +# Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache +*.sublime-workspace +*.sublime-project +.phpintel +/api/ + +# Visual Studio Code +.vscode/ + +/results/ +/phpunit*.xml diff --git a/public/assets/tinymce/TinyMCE-version-6.6.2/license.txt b/LICENSE similarity index 80% rename from public/assets/tinymce/TinyMCE-version-6.6.2/license.txt rename to LICENSE index 3a49f66..24728f6 100644 --- a/public/assets/tinymce/TinyMCE-version-6.6.2/license.txt +++ b/LICENSE @@ -1,6 +1,7 @@ -MIT License +The MIT License (MIT) -Copyright (c) 2022 Ephox Corporation DBA Tiny Technologies, Inc. +Copyright (c) 2014-2019 British Columbia Institute of Technology +Copyright (c) 2019-present 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 @@ -9,13 +10,13 @@ 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 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. +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 new file mode 100644 index 0000000..d14b4c9 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# CodeIgniter 4 Application Starter + +## What is CodeIgniter? + +CodeIgniter is a PHP full-stack web framework that is light, fast, flexible and secure. +More information can be found at the [official site](https://codeigniter.com). + +This repository holds a composer-installable app starter. +It has been built from the +[development repository](https://github.com/codeigniter4/CodeIgniter4). + +More information about the plans for version 4 can be found in [CodeIgniter 4](https://forum.codeigniter.com/forumdisplay.php?fid=28) on the forums. + +You can read the [user guide](https://codeigniter.com/user_guide/) +corresponding to the latest version of the framework. + +## Installation & updates + +`composer create-project codeigniter4/appstarter` then `composer update` whenever +there is a new release of the framework. + +When updating, check the release notes to see if there are any changes you might need to apply +to your `app` folder. The affected files can be copied or merged from +`vendor/codeigniter4/framework/app`. + +## Setup + +Copy `env` to `.env` and tailor for your app, specifically the baseURL +and any database settings. + +## Important Change with index.php + +`index.php` is no longer in the root of the project! It has been moved inside the *public* folder, +for better security and separation of components. + +This means that you should configure your web server to "point" to your project's *public* folder, and +not to the project root. A better practice would be to configure a virtual host to point there. A poor practice would be to point your web server to the project root and expect to enter *public/...*, as the rest of your logic and the +framework are exposed. + +**Please** read the user guide for a better explanation of how CI4 works! + +## Repository Management + +We use GitHub issues, in our main repository, to track **BUGS** and to track approved **DEVELOPMENT** work packages. +We use our [forum](http://forum.codeigniter.com) to provide SUPPORT and to discuss +FEATURE REQUESTS. + +This repository is a "distribution" one, built by our release preparation script. +Problems with it can be raised on our forum, or as issues in the main repository. + +## Server Requirements + +PHP version 8.1 or higher is required, with the following extensions installed: + +- [intl](http://php.net/manual/en/intl.requirements.php) +- [mbstring](http://php.net/manual/en/mbstring.installation.php) + +> [!WARNING] +> - The end of life date for PHP 7.4 was November 28, 2022. +> - The end of life date for PHP 8.0 was November 26, 2023. +> - If you are still using PHP 7.4 or 8.0, you should upgrade immediately. +> - The end of life date for PHP 8.1 will be December 31, 2025. + +Additionally, make sure that the following extensions are enabled in your PHP: + +- json (enabled by default - don't turn it off) +- [mysqlnd](http://php.net/manual/en/mysqlnd.install.php) if you plan to use MySQL +- [libcurl](http://php.net/manual/en/curl.requirements.php) if you plan to use the HTTP\CURLRequest library diff --git a/app/.htaccess b/app/.htaccess index f24db0a..3462048 100644 --- a/app/.htaccess +++ b/app/.htaccess @@ -1,6 +1,6 @@ - Require all denied + Require all denied - Deny from all + Deny from all diff --git a/app/Common.php b/app/Common.php index a74d46d..95f5544 100644 --- a/app/Common.php +++ b/app/Common.php @@ -4,12 +4,12 @@ * The goal of this file is to allow developers a location * where they can overwrite core procedural functions and * replace them with their own. This file is loaded during - * the bootstrap process and is called during the frameworks + * the bootstrap process and is called during the framework's * execution. * * This can be looked at as a `master helper` file that is * loaded early on, and may also contain additional functions * that you'd like to use throughout your entire application * - * @see: https://codeigniter4.github.io/CodeIgniter4/ + * @see: https://codeigniter.com/user_guide/extending/common.html */ diff --git a/app/Config/App.php b/app/Config/App.php index bb7efef..b761da7 100644 --- a/app/Config/App.php +++ b/app/Config/App.php @@ -3,7 +3,6 @@ namespace Config; use CodeIgniter\Config\BaseConfig; -use CodeIgniter\Session\Handlers\FileHandler; class App extends BaseConfig { @@ -12,34 +11,36 @@ class App extends BaseConfig * Base Site URL * -------------------------------------------------------------------------- * - * URL to your CodeIgniter root. Typically this will be your base URL, + * URL to your CodeIgniter root. Typically, this will be your base URL, * WITH a trailing slash: * - * http://example.com/ - * - * If this is not set then CodeIgniter will try guess the protocol, domain - * and path to your installation. However, you should always configure this - * explicitly and never rely on auto-guessing, especially in production - * environments. - * - * @var string + * E.g., http://example.com/ */ - //public $baseURL = 'http://localhost:8080/'; - public $baseURL = ''; + public string $baseURL = 'http://localhost:8080/'; + + /** + * Allowed Hostnames in the Site URL other than the hostname in the baseURL. + * If you want to accept multiple Hostnames, set this. + * + * E.g., + * When your site URL ($baseURL) is 'http://example.com/', and your site + * also accepts 'http://media.example.com/' and 'http://accounts.example.com/': + * ['media.example.com', 'accounts.example.com'] + * + * @var list + */ + public array $allowedHostnames = []; /** * -------------------------------------------------------------------------- * Index File * -------------------------------------------------------------------------- * - * Typically this will be your index.php file, unless you've renamed it to - * something else. If you are using mod_rewrite to remove the page set this - * variable so that it is blank. - * - * @var string + * 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 $indexPage = 'index.php'; - public $indexPage = ''; + public string $indexPage = 'index.php'; /** * -------------------------------------------------------------------------- @@ -47,18 +48,40 @@ class App extends BaseConfig * -------------------------------------------------------------------------- * * This item determines which server global should be used to retrieve the - * URI string. The default setting of 'REQUEST_URI' works for most servers. + * 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'] + * '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! - * - * @var string */ - public $uriProtocol = 'REQUEST_URI'; + 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~%.:_\-'; /** * -------------------------------------------------------------------------- @@ -69,10 +92,8 @@ class App extends BaseConfig * 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. - * - * @var string */ - public $defaultLocale = 'en'; + public string $defaultLocale = 'en'; /** * -------------------------------------------------------------------------- @@ -83,10 +104,8 @@ class App extends BaseConfig * language to use based on the value of the Accept-Language header. * * If false, no automatic detection will be performed. - * - * @var bool */ - public $negotiateLocale = false; + public bool $negotiateLocale = false; /** * -------------------------------------------------------------------------- @@ -97,9 +116,11 @@ class App extends BaseConfig * by the application in descending order of priority. If no match is * found, the first locale will be used. * - * @var string[] + * IncomingRequest::setLocale() also uses this list. + * + * @var list */ - public $supportedLocales = ['en']; + public array $supportedLocales = ['en']; /** * -------------------------------------------------------------------------- @@ -109,9 +130,10 @@ class App extends BaseConfig * The default timezone that will be used in your application to display * dates with the date helper, and can be retrieved through app_timezone() * - * @var string + * @see https://www.php.net/manual/en/timezones.php for list of timezones + * supported by PHP. */ - public $appTimezone = 'Asia/Jakarta'; + public string $appTimezone = 'UTC'; /** * -------------------------------------------------------------------------- @@ -122,211 +144,20 @@ class App extends BaseConfig * that require a character set to be provided. * * @see http://php.net/htmlspecialchars for a list of supported charsets. - * - * @var string */ - public $charset = 'UTF-8'; + public string $charset = 'UTF-8'; /** * -------------------------------------------------------------------------- - * URI PROTOCOL + * 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 header will be set. - * - * @var bool + * and the HTTP Strict Transport Security (HSTS) header will be set. */ - public $forceGlobalSecureRequests = false; - - /** - * -------------------------------------------------------------------------- - * Session Driver - * -------------------------------------------------------------------------- - * - * The session storage driver to use: - * - `CodeIgniter\Session\Handlers\FileHandler` - * - `CodeIgniter\Session\Handlers\DatabaseHandler` - * - `CodeIgniter\Session\Handlers\MemcachedHandler` - * - `CodeIgniter\Session\Handlers\RedisHandler` - * - * @var string - */ - public $sessionDriver = FileHandler::class; - - /** - * -------------------------------------------------------------------------- - * Session Cookie Name - * -------------------------------------------------------------------------- - * - * The session cookie name, must contain only [0-9a-z_-] characters - * - * @var string - */ - public $sessionCookieName = 'ci_session'; - - /** - * -------------------------------------------------------------------------- - * Session Expiration - * -------------------------------------------------------------------------- - * - * The number of SECONDS you want the session to last. - * Setting to 0 (zero) means expire when the browser is closed. - * - * @var int - */ - //public $sessionExpiration = 7200; - public $sessionExpiration = 7200; - - /** - * -------------------------------------------------------------------------- - * Session Save Path - * -------------------------------------------------------------------------- - * - * The location to save sessions to and is driver dependent. - * - * For the 'files' driver, it's a path to a writable directory. - * WARNING: Only absolute paths are supported! - * - * For the 'database' driver, it's a table name. - * Please read up the manual for the format with other session drivers. - * - * IMPORTANT: You are REQUIRED to set a valid save path! - * - * @var string - */ - public $sessionSavePath = WRITEPATH . 'session'; - - /** - * -------------------------------------------------------------------------- - * Session Match IP - * -------------------------------------------------------------------------- - * - * Whether to match the user's IP address when reading the session data. - * - * WARNING: If you're using the database driver, don't forget to update - * your session table's PRIMARY KEY when changing this setting. - * - * @var bool - */ - public $sessionMatchIP = false; - - /** - * -------------------------------------------------------------------------- - * Session Time to Update - * -------------------------------------------------------------------------- - * - * How many seconds between CI regenerating the session ID. - * - * @var int - */ - public $sessionTimeToUpdate = 300; - - /** - * -------------------------------------------------------------------------- - * Session Regenerate Destroy - * -------------------------------------------------------------------------- - * - * Whether to destroy session data associated with the old session ID - * when auto-regenerating the session ID. When set to FALSE, the data - * will be later deleted by the garbage collector. - * - * @var bool - */ - public $sessionRegenerateDestroy = false; - - /** - * -------------------------------------------------------------------------- - * Cookie Prefix - * -------------------------------------------------------------------------- - * - * Set a cookie name prefix if you need to avoid collisions. - * - * @var string - * - * @deprecated use Config\Cookie::$prefix property instead. - */ - public $cookiePrefix = ''; - - /** - * -------------------------------------------------------------------------- - * Cookie Domain - * -------------------------------------------------------------------------- - * - * Set to `.your-domain.com` for site-wide cookies. - * - * @var string - * - * @deprecated use Config\Cookie::$domain property instead. - */ - public $cookieDomain = ''; - - /** - * -------------------------------------------------------------------------- - * Cookie Path - * -------------------------------------------------------------------------- - * - * Typically will be a forward slash. - * - * @var string - * - * @deprecated use Config\Cookie::$path property instead. - */ - public $cookiePath = '/'; - - /** - * -------------------------------------------------------------------------- - * Cookie Secure - * -------------------------------------------------------------------------- - * - * Cookie will only be set if a secure HTTPS connection exists. - * - * @var bool - * - * @deprecated use Config\Cookie::$secure property instead. - */ - public $cookieSecure = false; - - /** - * -------------------------------------------------------------------------- - * Cookie HttpOnly - * -------------------------------------------------------------------------- - * - * Cookie will only be accessible via HTTP(S) (no JavaScript). - * - * @var bool - * - * @deprecated use Config\Cookie::$httponly property instead. - */ - public $cookieHTTPOnly = true; - - /** - * -------------------------------------------------------------------------- - * Cookie SameSite - * -------------------------------------------------------------------------- - * - * Configure cookie SameSite setting. Allowed values are: - * - None - * - Lax - * - Strict - * - '' - * - * Alternatively, you can use the constant names: - * - `Cookie::SAMESITE_NONE` - * - `Cookie::SAMESITE_LAX` - * - `Cookie::SAMESITE_STRICT` - * - * Defaults to `Lax` for compatibility with modern browsers. Setting `''` - * (empty string) means default SameSite attribute set by browsers (`Lax`) - * will be set on cookies. If set to `None`, `$cookieSecure` must also be set. - * - * @var string|null - * - * @deprecated use Config\Cookie::$samesite property instead. - */ - public $cookieSameSite = 'Lax'; + public bool $forceGlobalSecureRequests = false; /** * -------------------------------------------------------------------------- @@ -335,117 +166,21 @@ class App extends BaseConfig * * If your server is behind a reverse proxy, you must whitelist the proxy * IP addresses from which CodeIgniter should trust headers such as - * HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify + * X-Forwarded-For or Client-IP in order to properly identify * the visitor's IP address. * - * You can use both an array or a comma-separated list of proxy addresses, - * as well as specifying whole subnets. Here are a few examples: + * You need to set a proxy IP address or IP address with subnets and + * the HTTP header for the client IP address. * - * Comma-separated: '10.0.1.200,192.168.5.0/24' - * Array: ['10.0.1.200', '192.168.5.0/24'] + * Here are some examples: + * [ + * '10.0.1.200' => 'X-Forwarded-For', + * '192.168.5.0/24' => 'X-Real-IP', + * ] * - * @var string|string[] + * @var array */ - public $proxyIPs = ''; - - /** - * -------------------------------------------------------------------------- - * CSRF Token Name - * -------------------------------------------------------------------------- - * - * The token name. - * - * @deprecated Use `Config\Security` $tokenName property instead of using this property. - * - * @var string - */ - public $CSRFTokenName = 'csrf_test_name'; - - /** - * -------------------------------------------------------------------------- - * CSRF Header Name - * -------------------------------------------------------------------------- - * - * The header name. - * - * @deprecated Use `Config\Security` $headerName property instead of using this property. - * - * @var string - */ - public $CSRFHeaderName = 'X-CSRF-TOKEN'; - - /** - * -------------------------------------------------------------------------- - * CSRF Cookie Name - * -------------------------------------------------------------------------- - * - * The cookie name. - * - * @deprecated Use `Config\Security` $cookieName property instead of using this property. - * - * @var string - */ - public $CSRFCookieName = 'csrf_cookie_name'; - - /** - * -------------------------------------------------------------------------- - * CSRF Expire - * -------------------------------------------------------------------------- - * - * The number in seconds the token should expire. - * - * @deprecated Use `Config\Security` $expire property instead of using this property. - * - * @var int - */ - public $CSRFExpire = 7200; - - /** - * -------------------------------------------------------------------------- - * CSRF Regenerate - * -------------------------------------------------------------------------- - * - * Regenerate token on every submission? - * - * @deprecated Use `Config\Security` $regenerate property instead of using this property. - * - * @var bool - */ - public $CSRFRegenerate = true; - - /** - * -------------------------------------------------------------------------- - * CSRF Redirect - * -------------------------------------------------------------------------- - * - * Redirect to previous page with error on failure? - * - * @deprecated Use `Config\Security` $redirect property instead of using this property. - * - * @var bool - */ - public $CSRFRedirect = true; - - /** - * -------------------------------------------------------------------------- - * CSRF SameSite - * -------------------------------------------------------------------------- - * - * Setting for CSRF SameSite cookie token. Allowed values are: - * - None - * - Lax - * - Strict - * - '' - * - * Defaults to `Lax` as recommended in this link: - * - * @see https://portswigger.net/web-security/csrf/samesite-cookies - * - * @deprecated `Config\Cookie` $samesite property is used. - * - * @var string - */ - public $CSRFSameSite = 'Lax'; + public array $proxyIPs = []; /** * -------------------------------------------------------------------------- @@ -462,8 +197,6 @@ class App extends BaseConfig * * @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/ * @see http://www.w3.org/TR/CSP/ - * - * @var bool */ - public $CSPEnabled = false; + public bool $CSPEnabled = false; } diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php index ee27e3b..9a92824 100644 --- a/app/Config/Autoload.php +++ b/app/Config/Autoload.php @@ -13,7 +13,10 @@ use CodeIgniter\Config\AutoloadConfig; * can find the files as needed. * * NOTE: If you use an identical key in $psr4 or $classmap, then - * the values in this file will overwrite the framework's values. + * the values in this file will overwrite the framework's values. + * + * NOTE: This class is required prior to Autoloader instantiation, + * and does not extend BaseConfig. */ class Autoload extends AutoloadConfig { @@ -25,24 +28,17 @@ class Autoload extends AutoloadConfig * their location on the file system. These are used by the autoloader * to locate files the first time they have been instantiated. * - * The '/app' and '/system' directories are already mapped for you. - * you may change the name of the 'App' namespace if you wish, + * The 'Config' (APPPATH . 'Config') and 'CodeIgniter' (SYSTEMPATH) are + * already mapped for you. + * + * You may change the name of the 'App' namespace if you wish, * but this should be done prior to creating any namespaced classes, * else you will need to modify all of those classes for this to work. * - * Prototype: - *``` - * $psr4 = [ - * 'CodeIgniter' => SYSTEMPATH, - * 'App' => APPPATH - * ]; - *``` - * - * @var array + * @var array|string> */ public $psr4 = [ - APP_NAMESPACE => APPPATH, // For custom app namespace - 'Config' => APPPATH . 'Config', + APP_NAMESPACE => APPPATH, ]; /** @@ -56,11 +52,9 @@ class Autoload extends AutoloadConfig * were being autoloaded through a namespace. * * Prototype: - *``` * $classmap = [ * 'MyClass' => '/path/to/class/file.php' * ]; - *``` * * @var array */ @@ -75,13 +69,24 @@ class Autoload extends AutoloadConfig * or for loading functions. * * Prototype: - * ``` - * $files = [ - * '/path/to/my/file.php', - * ]; - * ``` + * $files = [ + * '/path/to/my/file.php', + * ]; * - * @var array + * @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 index 05a8612..a868447 100644 --- a/app/Config/Boot/development.php +++ b/app/Config/Boot/development.php @@ -7,8 +7,10 @@ | In development, we want to show as many errors as possible to help | make sure they don't make it to production. And save us hours of | painful debugging. + | + | If you set 'display_errors' to '1', CI4's detailed error report will show. */ -error_reporting(-1); +error_reporting(E_ALL); ini_set('display_errors', '1'); /* diff --git a/app/Config/Boot/production.php b/app/Config/Boot/production.php index 21d2580..1822cf5 100644 --- a/app/Config/Boot/production.php +++ b/app/Config/Boot/production.php @@ -6,9 +6,13 @@ |-------------------------------------------------------------------------- | Don't show ANY in production environments. Instead, let the system catch | it and display a generic error message. + | + | If you set 'display_errors' to '1', CI4's detailed error report will show. */ +error_reporting(E_ALL & ~E_DEPRECATED); +// If you want to suppress more types of errors. +// error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); ini_set('display_errors', '0'); -error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); /* |-------------------------------------------------------------------------- diff --git a/app/Config/Boot/testing.php b/app/Config/Boot/testing.php index e07a1d4..40b6ca8 100644 --- a/app/Config/Boot/testing.php +++ b/app/Config/Boot/testing.php @@ -1,5 +1,11 @@ + * @var array{storePath?: string, mode?: int} */ - public $file = [ + public array $file = [ 'storePath' => WRITEPATH . 'cache/', 'mode' => 0640, ]; @@ -129,14 +89,15 @@ class Cache extends BaseConfig * ------------------------------------------------------------------------- * 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 + * @var array{host?: string, port?: int, weight?: int, raw?: bool} */ - public $memcached = [ + public array $memcached = [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 1, @@ -147,12 +108,13 @@ class Cache extends BaseConfig * ------------------------------------------------------------------------- * Redis settings * ------------------------------------------------------------------------- + * * Your Redis server can be specified below, if you are using * the Redis or Predis drivers. * - * @var array + * @var array{host?: string, password?: string|null, port?: int, timeout?: int, database?: int} */ - public $redis = [ + public array $redis = [ 'host' => '127.0.0.1', 'password' => null, 'port' => 6379, @@ -168,9 +130,9 @@ class Cache extends BaseConfig * This is an array of cache engine alias' and class names. Only engines * that are listed here are allowed to be used. * - * @var array + * @var array> */ - public $validHandlers = [ + public array $validHandlers = [ 'dummy' => DummyHandler::class, 'file' => FileHandler::class, 'memcached' => MemcachedHandler::class, @@ -178,4 +140,23 @@ class Cache extends BaseConfig '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 index 47b92f8..fb56bb1 100644 --- a/app/Config/Constants.php +++ b/app/Config/Constants.php @@ -77,18 +77,3 @@ defined('EXIT_USER_INPUT') || define('EXIT_USER_INPUT', 7); // invalid u defined('EXIT_DATABASE') || define('EXIT_DATABASE', 8); // database error defined('EXIT__AUTO_MIN') || define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code defined('EXIT__AUTO_MAX') || define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code - -/** - * @deprecated Use \CodeIgniter\Events\Events::PRIORITY_LOW instead. - */ -define('EVENT_PRIORITY_LOW', 200); - -/** - * @deprecated Use \CodeIgniter\Events\Events::PRIORITY_NORMAL instead. - */ -define('EVENT_PRIORITY_NORMAL', 100); - -/** - * @deprecated Use \CodeIgniter\Events\Events::PRIORITY_HIGH instead. - */ -define('EVENT_PRIORITY_HIGH', 10); diff --git a/app/Config/ContentSecurityPolicy.php b/app/Config/ContentSecurityPolicy.php index 0be6163..2ac41a7 100644 --- a/app/Config/ContentSecurityPolicy.php +++ b/app/Config/ContentSecurityPolicy.php @@ -21,58 +21,52 @@ class ContentSecurityPolicy extends BaseConfig /** * Default CSP report context - * - * @var bool */ - public $reportOnly = false; + public bool $reportOnly = false; /** * Specifies a URL where a browser will send reports * when a content security policy is violated. - * - * @var string|null */ - public $reportURI; + public ?string $reportURI = null; /** * Instructs user agents to rewrite URL schemes, changing * HTTP to HTTPS. This directive is for websites with * large numbers of old URLs that need to be rewritten. - * - * @var bool */ - public $upgradeInsecureRequests = false; + public bool $upgradeInsecureRequests = false; // ------------------------------------------------------------------------- // Sources allowed - // Note: once you set a policy to 'none', it cannot be further restricted + // NOTE: once you set a policy to 'none', it cannot be further restricted // ------------------------------------------------------------------------- /** * Will default to self if not overridden * - * @var string|string[]|null + * @var list|string|null */ public $defaultSrc; /** * Lists allowed scripts' URLs. * - * @var string|string[] + * @var list|string */ public $scriptSrc = 'self'; /** * Lists allowed stylesheets' URLs. * - * @var string|string[] + * @var list|string */ public $styleSrc = 'self'; /** * Defines the origins from which images can be loaded. * - * @var string|string[] + * @var list|string */ public $imageSrc = 'self'; @@ -81,14 +75,14 @@ class ContentSecurityPolicy extends BaseConfig * * Will default to self if not overridden * - * @var string|string[]|null + * @var list|string|null */ public $baseURI; /** * Lists the URLs for workers and embedded frame contents * - * @var string|string[] + * @var list|string */ public $childSrc = 'self'; @@ -96,21 +90,21 @@ class ContentSecurityPolicy extends BaseConfig * Limits the origins that you can connect to (via XHR, * WebSockets, and EventSource). * - * @var string|string[] + * @var list|string */ public $connectSrc = 'self'; /** * Specifies the origins that can serve web fonts. * - * @var string|string[] + * @var list|string */ public $fontSrc; /** * Lists valid endpoints for submission from `
` tags. * - * @var string|string[] + * @var list|string */ public $formAction = 'self'; @@ -120,7 +114,7 @@ class ContentSecurityPolicy extends BaseConfig * and `` tags. This directive can't be used in * `` tags and applies only to non-HTML resources. * - * @var string|string[]|null + * @var list|string|null */ public $frameAncestors; @@ -128,61 +122,55 @@ class ContentSecurityPolicy extends BaseConfig * The frame-src directive restricts the URLs which may * be loaded into nested browsing contexts. * - * @var array|string|null + * @var list|string|null */ public $frameSrc; /** * Restricts the origins allowed to deliver video and audio. * - * @var string|string[]|null + * @var list|string|null */ public $mediaSrc; /** * Allows control over Flash and other plugins. * - * @var string|string[] + * @var list|string */ public $objectSrc = 'self'; /** - * @var string|string[]|null + * @var list|string|null */ public $manifestSrc; /** * Limits the kinds of plugins a page may invoke. * - * @var string|string[]|null + * @var list|string|null */ public $pluginTypes; /** * List of actions allowed. * - * @var string|string[]|null + * @var list|string|null */ public $sandbox; /** * Nonce tag for style - * - * @var string */ - public $styleNonceTag = '{csp-style-nonce}'; + public string $styleNonceTag = '{csp-style-nonce}'; /** * Nonce tag for script - * - * @var string */ - public $scriptNonceTag = '{csp-script-nonce}'; + public string $scriptNonceTag = '{csp-script-nonce}'; /** * Replace nonce tag automatically - * - * @var bool */ - public $autoNonce = true; + public bool $autoNonce = true; } diff --git a/app/Config/Cookie.php b/app/Config/Cookie.php index ab31dda..3bad184 100644 --- a/app/Config/Cookie.php +++ b/app/Config/Cookie.php @@ -13,10 +13,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Set a cookie name prefix if you need to avoid collisions. - * - * @var string */ - public $prefix = 'ci4_'; + public string $prefix = ''; /** * -------------------------------------------------------------------------- @@ -37,10 +35,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Typically will be a forward slash. - * - * @var string */ - public $path = '/'; + public string $path = '/'; /** * -------------------------------------------------------------------------- @@ -48,10 +44,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Set to `.your-domain.com` for site-wide cookies. - * - * @var string */ - public $domain = ''; + public string $domain = ''; /** * -------------------------------------------------------------------------- @@ -59,10 +53,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Cookie will only be set if a secure HTTPS connection exists. - * - * @var bool */ - public $secure = false; + public bool $secure = false; /** * -------------------------------------------------------------------------- @@ -70,11 +62,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Cookie will only be accessible via HTTP(S) (no JavaScript). - * - * @var bool */ - //public $httponly = true; - public $httponly = false; + public bool $httponly = true; /** * -------------------------------------------------------------------------- @@ -96,9 +85,9 @@ class Cookie extends BaseConfig * (empty string) means default SameSite attribute set by browsers (`Lax`) * will be set on cookies. If set to `None`, `$secure` must also be set. * - * @var string + * @var ''|'Lax'|'None'|'Strict' */ - public $samesite = 'Lax'; + public string $samesite = 'Lax'; /** * -------------------------------------------------------------------------- @@ -111,10 +100,8 @@ class Cookie extends BaseConfig * If this is set to `true`, cookie names should be compliant of RFC 2616's * list of allowed characters. * - * @var bool - * * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes * @see https://tools.ietf.org/html/rfc2616#section-2.2 */ - public $raw = false; + public bool $raw = false; } diff --git a/app/Config/Cors.php b/app/Config/Cors.php new file mode 100644 index 0000000..2b4edf6 --- /dev/null +++ b/app/Config/Cors.php @@ -0,0 +1,105 @@ +, + * allowedOriginsPatterns: list, + * supportsCredentials: bool, + * allowedHeaders: list, + * exposedHeaders: list, + * allowedMethods: list, + * maxAge: int, + * } + */ + public array $default = [ + /** + * Origins for the `Access-Control-Allow-Origin` header. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + * + * E.g.: + * - ['http://localhost:8080'] + * - ['https://www.example.com'] + */ + 'allowedOrigins' => [], + + /** + * Origin regex patterns for the `Access-Control-Allow-Origin` header. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + * + * NOTE: A pattern specified here is part of a regular expression. It will + * be actually `#\A\z#`. + * + * E.g.: + * - ['https://\w+\.example\.com'] + */ + 'allowedOriginsPatterns' => [], + + /** + * Weather to send the `Access-Control-Allow-Credentials` header. + * + * The Access-Control-Allow-Credentials response header tells browsers whether + * the server allows cross-origin HTTP requests to include credentials. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials + */ + 'supportsCredentials' => false, + + /** + * Set headers to allow. + * + * The Access-Control-Allow-Headers response header is used in response to + * a preflight request which includes the Access-Control-Request-Headers to + * indicate which HTTP headers can be used during the actual request. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers + */ + 'allowedHeaders' => [], + + /** + * Set headers to expose. + * + * The Access-Control-Expose-Headers response header allows a server to + * indicate which response headers should be made available to scripts running + * in the browser, in response to a cross-origin request. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers + */ + 'exposedHeaders' => [], + + /** + * Set methods to allow. + * + * The Access-Control-Allow-Methods response header specifies one or more + * methods allowed when accessing a resource in response to a preflight + * request. + * + * E.g.: + * - ['GET', 'POST', 'PUT', 'DELETE'] + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods + */ + 'allowedMethods' => [], + + /** + * Set how many seconds the results of a preflight request can be cached. + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age + */ + 'maxAge' => 7200, + ]; +} diff --git a/app/Config/CustomValidation.php b/app/Config/CustomValidation.php deleted file mode 100644 index 433d101..0000000 --- a/app/Config/CustomValidation.php +++ /dev/null @@ -1,19 +0,0 @@ -query($sql); - $user = $query->getRow(); - - if(!$user) return false; - - return password_verify($data['password'], $user->password ); - } - -} \ No newline at end of file diff --git a/app/Config/Database.php b/app/Config/Database.php index 00e9916..29f6f4a 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -10,54 +10,159 @@ use CodeIgniter\Database\Config; class Database extends Config { /** - * The directory that holds the Migrations - * and Seeds directories. - * - * @var string + * The directory that holds the Migrations and Seeds directories. */ - public $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR; + public string $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR; /** - * Lets you choose which connection group to - * use if no other is specified. - * - * @var string + * Lets you choose which connection group to use if no other is specified. */ - public $defaultGroup = 'default'; + public string $defaultGroup = 'default'; /** * The default database connection. * - * @var array + * @var array */ - public $default = [ - 'DSN' => '', - 'hostname' => 'localhost', - 'username' => 'root', - 'password' => '', - 'database' => 'crm', - 'DBDriver' => 'MySQLi', - 'DBPrefix' => '', - 'pConnect' => false, - //'DBDebug' => (ENVIRONMENT !== 'production'), - 'DBDebug' => true, - 'charset' => 'utf8', - 'DBCollat' => 'utf8_general_ci', - 'swapPre' => '', - 'encrypt' => false, - 'compress' => false, - 'strictOn' => false, - 'failover' => [], - 'port' => 3306, + public array $default = [ + 'DSN' => '', + 'hostname' => 'localhost', + 'username' => '', + 'password' => '', + 'database' => '', + 'DBDriver' => 'MySQLi', + 'DBPrefix' => '', + 'pConnect' => false, + 'DBDebug' => true, + 'charset' => 'utf8mb4', + 'DBCollat' => 'utf8mb4_general_ci', + 'swapPre' => '', + 'encrypt' => false, + 'compress' => false, + 'strictOn' => false, + 'failover' => [], + 'port' => 3306, + 'numberNative' => false, + 'foundRows' => false, + 'dateFormat' => [ + 'date' => 'Y-m-d', + 'datetime' => 'Y-m-d H:i:s', + 'time' => 'H:i:s', + ], ]; + // /** + // * Sample database connection for SQLite3. + // * + // * @var array + // */ + // public array $default = [ + // 'database' => 'database.db', + // 'DBDriver' => 'SQLite3', + // 'DBPrefix' => '', + // 'DBDebug' => true, + // 'swapPre' => '', + // 'failover' => [], + // 'foreignKeys' => true, + // 'busyTimeout' => 1000, + // 'synchronous' => null, + // 'dateFormat' => [ + // 'date' => 'Y-m-d', + // 'datetime' => 'Y-m-d H:i:s', + // 'time' => 'H:i:s', + // ], + // ]; + + // /** + // * Sample database connection for Postgre. + // * + // * @var array + // */ + // public array $default = [ + // 'DSN' => '', + // 'hostname' => 'localhost', + // 'username' => 'root', + // 'password' => 'root', + // 'database' => 'ci4', + // 'schema' => 'public', + // 'DBDriver' => 'Postgre', + // 'DBPrefix' => '', + // 'pConnect' => false, + // 'DBDebug' => true, + // 'charset' => 'utf8', + // 'swapPre' => '', + // 'failover' => [], + // 'port' => 5432, + // 'dateFormat' => [ + // 'date' => 'Y-m-d', + // 'datetime' => 'Y-m-d H:i:s', + // 'time' => 'H:i:s', + // ], + // ]; + + // /** + // * Sample database connection for SQLSRV. + // * + // * @var array + // */ + // public array $default = [ + // 'DSN' => '', + // 'hostname' => 'localhost', + // 'username' => 'root', + // 'password' => 'root', + // 'database' => 'ci4', + // 'schema' => 'dbo', + // 'DBDriver' => 'SQLSRV', + // 'DBPrefix' => '', + // 'pConnect' => false, + // 'DBDebug' => true, + // 'charset' => 'utf8', + // 'swapPre' => '', + // 'encrypt' => false, + // 'failover' => [], + // 'port' => 1433, + // 'dateFormat' => [ + // 'date' => 'Y-m-d', + // 'datetime' => 'Y-m-d H:i:s', + // 'time' => 'H:i:s', + // ], + // ]; + + // /** + // * Sample database connection for OCI8. + // * + // * You may need the following environment variables: + // * NLS_LANG = 'AMERICAN_AMERICA.UTF8' + // * NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' + // * NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS' + // * NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS' + // * + // * @var array + // */ + // public array $default = [ + // 'DSN' => 'localhost:1521/XEPDB1', + // 'username' => 'root', + // 'password' => 'root', + // 'DBDriver' => 'OCI8', + // 'DBPrefix' => '', + // 'pConnect' => false, + // 'DBDebug' => true, + // 'charset' => 'AL32UTF8', + // 'swapPre' => '', + // 'failover' => [], + // 'dateFormat' => [ + // 'date' => 'Y-m-d', + // 'datetime' => 'Y-m-d H:i:s', + // 'time' => 'H:i:s', + // ], + // ]; + /** - * This database connection is used when - * running PHPUnit database tests. + * This database connection is used when running PHPUnit database tests. * - * @var array + * @var array */ - public $tests = [ + public array $tests = [ 'DSN' => '', 'hostname' => '127.0.0.1', 'username' => '', @@ -66,10 +171,9 @@ class Database extends Config 'DBDriver' => 'SQLite3', 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS 'pConnect' => false, - //'DBDebug' => (ENVIRONMENT !== 'production'), 'DBDebug' => true, 'charset' => 'utf8', - 'DBCollat' => 'utf8_general_ci', + 'DBCollat' => '', 'swapPre' => '', 'encrypt' => false, 'compress' => false, @@ -77,6 +181,12 @@ class Database extends Config 'failover' => [], 'port' => 3306, 'foreignKeys' => true, + 'busyTimeout' => 1000, + 'dateFormat' => [ + 'date' => 'Y-m-d', + 'datetime' => 'Y-m-d H:i:s', + 'time' => 'H:i:s', + ], ]; public function __construct() diff --git a/app/Config/DocTypes.php b/app/Config/DocTypes.php index 6f16693..788d68f 100644 --- a/app/Config/DocTypes.php +++ b/app/Config/DocTypes.php @@ -9,7 +9,7 @@ class DocTypes * * @var array */ - public $list = [ + public array $list = [ 'xhtml11' => '', 'xhtml1-strict' => '', 'xhtml1-trans' => '', @@ -30,4 +30,14 @@ class DocTypes 'xhtml-rdfa-1' => '', 'xhtml-rdfa-2' => '', ]; + + /** + * Whether to remove the solidus (`/`) character for void HTML elements (e.g. ``) + * for HTML5 compatibility. + * + * Set to: + * `true` - to be HTML5 compatible + * `false` - to be XHTML compatible + */ + public bool $html5 = true; } diff --git a/app/Config/Email.php b/app/Config/Email.php index ca9bf7d..4dce650 100644 --- a/app/Config/Email.php +++ b/app/Config/Email.php @@ -6,143 +6,116 @@ use CodeIgniter\Config\BaseConfig; class Email extends BaseConfig { - /** - * @var string - */ - public $fromEmail; - - /** - * @var string - */ - public $fromName; - - /** - * @var string - */ - public $recipients; + public string $fromEmail = ''; + public string $fromName = ''; + public string $recipients = ''; /** * The "user agent" - * - * @var string */ - public $userAgent = 'CodeIgniter'; + public string $userAgent = 'CodeIgniter'; /** * The mail sending protocol: mail, sendmail, smtp - * - * @var string */ - public $protocol = 'smtp'; + public string $protocol = 'mail'; /** * The server path to Sendmail. - * - * @var string */ - //public $mailPath = '/usr/sbin/sendmail'; + public string $mailPath = '/usr/sbin/sendmail'; + + /** + * SMTP Server Hostname + */ + public string $SMTPHost = ''; + + /** + * SMTP Username + */ + public string $SMTPUser = ''; + + /** + * SMTP Password + */ + public string $SMTPPass = ''; + + /** + * SMTP Port + */ + public int $SMTPPort = 25; - public $SMTPHost = 'mail.services.summit.co.id'; - public $SMTPUser = 'noreply@services.summit.co.id'; - public $SMTPPass = 'Summit2020'; - public $SMTPPort = 587; - //public $SMTPCrypto = 'ssl'; - /** * SMTP Timeout (in seconds) - * - * @var int */ - public $SMTPTimeout = 30; + public int $SMTPTimeout = 5; /** * Enable persistent SMTP connections - * - * @var bool */ - public $SMTPKeepAlive = false; + public bool $SMTPKeepAlive = false; /** - * SMTP Encryption. Either tls or ssl + * SMTP Encryption. * - * @var string + * @var string '', 'tls' or 'ssl'. 'tls' will issue a STARTTLS command + * to the server. 'ssl' means implicit SSL. Connection on port + * 465 should set this to ''. */ - + public string $SMTPCrypto = 'tls'; + /** * Enable word-wrap - * - * @var bool */ - public $wordWrap = true; + public bool $wordWrap = true; /** * Character count to wrap at - * - * @var int */ - public $wrapChars = 76; + public int $wrapChars = 76; /** * Type of mail, either 'text' or 'html' - * - * @var string */ - public $mailType = 'html'; + public string $mailType = 'text'; /** * Character set (utf-8, iso-8859-1, etc.) - * - * @var string */ - public $charset = 'UTF-8'; + public string $charset = 'UTF-8'; /** * Whether to validate the email address - * - * @var bool */ - public $validate = false; + public bool $validate = false; /** * Email Priority. 1 = highest. 5 = lowest. 3 = normal - * - * @var int */ - public $priority = 3; + public int $priority = 3; /** * Newline character. (Use “\r\n” to comply with RFC 822) - * - * @var string */ - public $CRLF = "\r\n"; + public string $CRLF = "\r\n"; /** * Newline character. (Use “\r\n” to comply with RFC 822) - * - * @var string */ - public $newline = "\r\n"; + public string $newline = "\r\n"; /** * Enable BCC Batch Mode. - * - * @var bool */ - public $BCCBatchMode = false; + public bool $BCCBatchMode = false; /** * Number of emails in each BCC batch - * - * @var int */ - public $BCCBatchSize = 200; + public int $BCCBatchSize = 200; /** * Enable notify message from server - * - * @var bool */ - //public $DSN = true; - public $DSN = false; + public bool $DSN = false; } diff --git a/app/Config/Encryption.php b/app/Config/Encryption.php index 07b45a0..2834413 100644 --- a/app/Config/Encryption.php +++ b/app/Config/Encryption.php @@ -20,10 +20,8 @@ class Encryption extends BaseConfig * If you use the Encryption class you must set an encryption key (seed). * You need to ensure it is long enough for the cipher and mode you plan to use. * See the user guide for more info. - * - * @var string */ - public $key = ''; + public string $key = ''; /** * -------------------------------------------------------------------------- @@ -35,10 +33,8 @@ class Encryption extends BaseConfig * Available drivers: * - OpenSSL * - Sodium - * - * @var string */ - public $driver = 'OpenSSL'; + public string $driver = 'OpenSSL'; /** * -------------------------------------------------------------------------- @@ -49,10 +45,8 @@ class Encryption extends BaseConfig * before it is encrypted. This value should be greater than zero. * * See the user guide for more information on padding. - * - * @var int */ - public $blockSize = 16; + public int $blockSize = 16; /** * -------------------------------------------------------------------------- @@ -60,8 +54,39 @@ class Encryption extends BaseConfig * -------------------------------------------------------------------------- * * HMAC digest to use, e.g. 'SHA512' or 'SHA256'. Default value is 'SHA512'. - * - * @var string */ - public $digest = 'SHA512'; + public string $digest = 'SHA512'; + + /** + * Whether the cipher-text should be raw. If set to false, then it will be base64 encoded. + * This setting is only used by OpenSSLHandler. + * + * Set to false for CI3 Encryption compatibility. + */ + public bool $rawData = true; + + /** + * Encryption key info. + * This setting is only used by OpenSSLHandler. + * + * Set to 'encryption' for CI3 Encryption compatibility. + */ + public string $encryptKeyInfo = ''; + + /** + * Authentication key info. + * This setting is only used by OpenSSLHandler. + * + * Set to 'authentication' for CI3 Encryption compatibility. + */ + public string $authKeyInfo = ''; + + /** + * Cipher to use. + * This setting is only used by OpenSSLHandler. + * + * Set to 'AES-128-CBC' to decrypt encrypted data that encrypted + * by CI3 Encryption default configuration. + */ + public string $cipher = 'AES-256-CTR'; } diff --git a/app/Config/Events.php b/app/Config/Events.php index 5219f4a..946285b 100644 --- a/app/Config/Events.php +++ b/app/Config/Events.php @@ -4,6 +4,7 @@ namespace Config; use CodeIgniter\Events\Events; use CodeIgniter\Exceptions\FrameworkException; +use CodeIgniter\HotReloader\HotReloader; /* * -------------------------------------------------------------------- @@ -22,7 +23,7 @@ use CodeIgniter\Exceptions\FrameworkException; * Events::on('create', [$myInstance, 'myMethod']); */ -Events::on('pre_system', static function () { +Events::on('pre_system', static function (): void { if (ENVIRONMENT !== 'testing') { if (ini_get('zlib.output_compression')) { throw FrameworkException::forEnabledZlibOutputCompression(); @@ -43,6 +44,12 @@ Events::on('pre_system', static function () { */ if (CI_DEBUG && ! is_cli()) { Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect'); - Services::toolbar()->respond(); + service('toolbar')->respond(); + // Hot Reload route - for framework use on the hot reloader. + if (ENVIRONMENT === 'development') { + service('routes')->get('__hot-reload', static function (): void { + (new HotReloader())->run(); + }); + } } }); diff --git a/app/Config/Exceptions.php b/app/Config/Exceptions.php index 7cbc78a..4e33963 100644 --- a/app/Config/Exceptions.php +++ b/app/Config/Exceptions.php @@ -3,6 +3,10 @@ namespace Config; use CodeIgniter\Config\BaseConfig; +use CodeIgniter\Debug\ExceptionHandler; +use CodeIgniter\Debug\ExceptionHandlerInterface; +use Psr\Log\LogLevel; +use Throwable; /** * Setup how the exception handler works. @@ -17,10 +21,8 @@ class Exceptions extends BaseConfig * through Services::Log. * * Default: true - * - * @var bool */ - public $log = true; + public bool $log = true; /** * -------------------------------------------------------------------------- @@ -29,9 +31,9 @@ class Exceptions extends BaseConfig * Any status codes here will NOT be logged if logging is turned on. * By default, only 404 (Page Not Found) exceptions are ignored. * - * @var array + * @var list */ - public $ignoreCodes = [404]; + public array $ignoreCodes = [404]; /** * -------------------------------------------------------------------------- @@ -41,10 +43,8 @@ class Exceptions extends BaseConfig * directories that hold the views used to generate errors. * * Default: APPPATH.'Views/errors' - * - * @var string */ - public $errorViewPath = APPPATH . 'Views/errors'; + public string $errorViewPath = APPPATH . 'Views/errors'; /** * -------------------------------------------------------------------------- @@ -54,7 +54,53 @@ class Exceptions extends BaseConfig * In order to specify 2 levels, use "/" to separate. * ex. ['server', 'setup/password', 'secret_token'] * - * @var array + * @var list */ - public $sensitiveDataInTrace = []; + public array $sensitiveDataInTrace = []; + + /** + * -------------------------------------------------------------------------- + * WHETHER TO THROW AN EXCEPTION ON DEPRECATED ERRORS + * -------------------------------------------------------------------------- + * If set to `true`, DEPRECATED errors are only logged and no exceptions are + * thrown. This option also works for user deprecations. + */ + public bool $logDeprecations = true; + + /** + * -------------------------------------------------------------------------- + * LOG LEVEL THRESHOLD FOR DEPRECATIONS + * -------------------------------------------------------------------------- + * If `$logDeprecations` is set to `true`, this sets the log level + * to which the deprecation will be logged. This should be one of the log + * levels recognized by PSR-3. + * + * The related `Config\Logger::$threshold` should be adjusted, if needed, + * to capture logging the deprecations. + */ + public string $deprecationLogLevel = LogLevel::WARNING; + + /* + * DEFINE THE HANDLERS USED + * -------------------------------------------------------------------------- + * Given the HTTP status code, returns exception handler that + * should be used to deal with this error. By default, it will run CodeIgniter's + * default handler and display the error information in the expected format + * for CLI, HTTP, or AJAX requests, as determined by is_cli() and the expected + * response format. + * + * Custom handlers can be returned if you want to handle one or more specific + * error codes yourself like: + * + * if (in_array($statusCode, [400, 404, 500])) { + * return new \App\Libraries\MyExceptionHandler(); + * } + * if ($exception instanceOf PageNotFoundException) { + * return new \App\Libraries\MyExceptionHandler(); + * } + */ + public function handler(int $statusCode, Throwable $exception): ExceptionHandlerInterface + { + return new ExceptionHandler($this); + } } diff --git a/app/Config/Feature.php b/app/Config/Feature.php index 4c5ec90..ec1435a 100644 --- a/app/Config/Feature.php +++ b/app/Config/Feature.php @@ -10,23 +10,28 @@ use CodeIgniter\Config\BaseConfig; class Feature extends BaseConfig { /** - * Enable multiple filters for a route or not. - * - * If you enable this: - * - CodeIgniter\CodeIgniter::handleRequest() uses: - * - CodeIgniter\Filters\Filters::enableFilters(), instead of enableFilter() - * - CodeIgniter\CodeIgniter::tryToRouteIt() uses: - * - CodeIgniter\Router\Router::getFilters(), instead of getFilter() - * - CodeIgniter\Router\Router::handle() uses: - * - property $filtersInfo, instead of $filterInfo - * - CodeIgniter\Router\RouteCollection::getFiltersForRoute(), instead of getFilterForRoute() - * - * @var bool + * Use improved new auto routing instead of the legacy version. */ - public $multipleFilters = false; + public bool $autoRoutesImproved = true; /** - * Use improved new auto routing instead of the default legacy version. + * Use filter execution order in 4.4 or before. */ - public bool $autoRoutesImproved = false; + public bool $oldFilterOrder = false; + + /** + * The behavior of `limit(0)` in Query Builder. + * + * If true, `limit(0)` returns all records. (the behavior of 4.4.x or before in version 4.x.) + * If false, `limit(0)` returns no records. (the behavior of 3.1.9 or later in version 3.x.) + */ + public bool $limitZeroAsAll = true; + + /** + * Use strict location negotiation. + * + * By default, the locale is selected based on a loose comparison of the language code (ISO 639-1) + * Enabling strict comparison will also consider the region code (ISO 3166-1 alpha-2). + */ + public bool $strictLocaleNegotiation = false; } diff --git a/app/Config/Filters.php b/app/Config/Filters.php index 1e35b89..1f2e371 100644 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -2,47 +2,86 @@ namespace Config; -use CodeIgniter\Config\BaseConfig; +use CodeIgniter\Config\Filters as BaseFilters; +use CodeIgniter\Filters\Cors; use CodeIgniter\Filters\CSRF; use CodeIgniter\Filters\DebugToolbar; +use CodeIgniter\Filters\ForceHTTPS; use CodeIgniter\Filters\Honeypot; use CodeIgniter\Filters\InvalidChars; +use CodeIgniter\Filters\PageCache; +use CodeIgniter\Filters\PerformanceMetrics; use CodeIgniter\Filters\SecureHeaders; -class Filters extends BaseConfig +class Filters extends BaseFilters { /** * Configures aliases for Filter classes to * make reading things nicer and simpler. * - * @var array + * @var array> + * + * [filter_name => classname] + * or [filter_name => [classname1, classname2, ...]] */ - public $aliases = [ + public array $aliases = [ 'csrf' => CSRF::class, 'toolbar' => DebugToolbar::class, 'honeypot' => Honeypot::class, 'invalidchars' => InvalidChars::class, 'secureheaders' => SecureHeaders::class, - 'auth' => \App\Filters\Auth::class, + 'forcehttps' => ForceHTTPS::class, + 'pagecache' => PageCache::class, + 'performance' => PerformanceMetrics::class, + 'auth' => \App\Filters\Auth::class, + 'cors' => \App\Filters\Cors::class, ]; /** - * List of filter aliases that are always - * applied before and after every request. + * List of special required filters. * - * @var array + * The filters listed here are special. They are applied before and after + * other kinds of filters, and always applied even if a route does not exist. + * + * Filters set by default provide framework functionality. If removed, + * those functions will no longer work. + * + * @see https://codeigniter.com/user_guide/incoming/filters.html#provided-filters + * + * @var array{before: list, after: list} */ - public $globals = [ + public array $required = [ 'before' => [ 'auth' => [ 'except' => [ - 'auth/*' + 'auth/*', 'lqms/*', 'key/*', 'api/*' ]] // 'honeypot', // 'csrf', // 'invalidchars', ], 'after' => [ - 'toolbar', + 'pagecache', // Web Page Caching + 'performance', // Performance Metrics + 'toolbar', // Debug Toolbar + ], + ]; + + /** + * List of filter aliases that are always + * applied before and after every request. + * + * @var array{ + * before: array|string}>|list, + * after: array|string}>|list + * } + */ + public array $globals = [ + 'before' => [ + // 'honeypot', + // 'csrf', + // 'invalidchars', + ], + 'after' => [ // 'honeypot', // 'secureheaders', ], @@ -53,15 +92,15 @@ class Filters extends BaseConfig * particular HTTP method (GET, POST, etc.). * * Example: - * 'post' => ['foo', 'bar'] + * 'POST' => ['foo', 'bar'] * * If you use this, you should disable auto-routing because auto-routing * permits any HTTP method to access a controller. Accessing the controller - * with a method you don’t expect could bypass the filter. + * with a method you don't expect could bypass the filter. * - * @var array + * @var array> */ - public $methods = []; + public array $methods = []; /** * List of filter aliases that should run on any @@ -70,9 +109,7 @@ class Filters extends BaseConfig * Example: * 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']] * - * @var array + * @var array>> */ - public $filters = [ - - ]; + public array $filters = []; } diff --git a/app/Config/ForeignCharacters.php b/app/Config/ForeignCharacters.php index 174ddb1..f1a9572 100644 --- a/app/Config/ForeignCharacters.php +++ b/app/Config/ForeignCharacters.php @@ -4,6 +4,9 @@ namespace Config; use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters; +/** + * @immutable + */ class ForeignCharacters extends BaseForeignCharacters { } diff --git a/app/Config/Format.php b/app/Config/Format.php index d89e408..0d334d7 100644 --- a/app/Config/Format.php +++ b/app/Config/Format.php @@ -3,7 +3,6 @@ namespace Config; use CodeIgniter\Config\BaseConfig; -use CodeIgniter\Format\FormatterInterface; use CodeIgniter\Format\JSONFormatter; use CodeIgniter\Format\XMLFormatter; @@ -22,9 +21,9 @@ class Format extends BaseConfig * These formats are only checked when the data passed to the respond() * method is an array. * - * @var string[] + * @var list */ - public $supportedResponseFormats = [ + public array $supportedResponseFormats = [ 'application/json', 'application/xml', // machine-readable XML 'text/xml', // human-readable XML @@ -41,7 +40,7 @@ class Format extends BaseConfig * * @var array */ - public $formatters = [ + public array $formatters = [ 'application/json' => JSONFormatter::class, 'application/xml' => XMLFormatter::class, 'text/xml' => XMLFormatter::class, @@ -57,21 +56,9 @@ class Format extends BaseConfig * * @var array */ - public $formatterOptions = [ + public array $formatterOptions = [ 'application/json' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, 'application/xml' => 0, 'text/xml' => 0, ]; - - /** - * A Factory method to return the appropriate formatter for the given mime type. - * - * @return FormatterInterface - * - * @deprecated This is an alias of `\CodeIgniter\Format\Format::getFormatter`. Use that instead. - */ - public function getFormatter(string $mime) - { - return Services::format()->getFormatter($mime); - } } diff --git a/app/Config/Generators.php b/app/Config/Generators.php index 11214fd..cc92c7a 100644 --- a/app/Config/Generators.php +++ b/app/Config/Generators.php @@ -23,9 +23,13 @@ class Generators extends BaseConfig * * YOU HAVE BEEN WARNED! * - * @var array + * @var array|string> */ - public $views = [ + public array $views = [ + 'make:cell' => [ + 'class' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php', + 'view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php', + ], 'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php', 'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php', 'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php', diff --git a/app/Config/Honeypot.php b/app/Config/Honeypot.php index 42b5a0d..67ebcb0 100644 --- a/app/Config/Honeypot.php +++ b/app/Config/Honeypot.php @@ -8,36 +8,35 @@ class Honeypot extends BaseConfig { /** * Makes Honeypot visible or not to human - * - * @var bool */ - public $hidden = true; + public bool $hidden = true; /** * Honeypot Label Content - * - * @var string */ - public $label = 'Fill This Field'; + public string $label = 'Fill This Field'; /** * Honeypot Field Name - * - * @var string */ - public $name = 'honeypot'; + public string $name = 'honeypot'; /** * Honeypot HTML Template - * - * @var string */ - public $template = ''; + public string $template = ''; /** * Honeypot container * - * @var string + * If you enabled CSP, you can remove `style="display:none"`. */ - public $container = '
{template}
'; + public string $container = '
{template}
'; + + /** + * The id attribute for Honeypot container tag + * + * Used when CSP is enabled. + */ + public string $containerId = 'hpc'; } diff --git a/app/Config/Images.php b/app/Config/Images.php index 1c15d81..a33ddad 100644 --- a/app/Config/Images.php +++ b/app/Config/Images.php @@ -10,25 +10,21 @@ class Images extends BaseConfig { /** * Default handler used if no other handler is specified. - * - * @var string */ - public $defaultHandler = 'gd'; + public string $defaultHandler = 'gd'; /** * The path to the image library. * Required for ImageMagick, GraphicsMagick, or NetPBM. - * - * @var string */ - public $libraryPath = '/usr/local/bin/convert'; + public string $libraryPath = '/usr/local/bin/convert'; /** * The available handler classes. * * @var array */ - public $handlers = [ + public array $handlers = [ 'gd' => GDHandler::class, 'imagick' => ImageMagickHandler::class, ]; diff --git a/app/Config/Kint.php b/app/Config/Kint.php index b1016ed..931ad47 100644 --- a/app/Config/Kint.php +++ b/app/Config/Kint.php @@ -2,8 +2,9 @@ namespace Config; -use CodeIgniter\Config\BaseConfig; -use Kint\Renderer\Renderer; +use Kint\Parser\ConstructablePluginInterface; +use Kint\Renderer\Rich\TabPluginInterface; +use Kint\Renderer\Rich\ValuePluginInterface; /** * -------------------------------------------------------------------------- @@ -15,7 +16,7 @@ use Kint\Renderer\Renderer; * * @see https://kint-php.github.io/kint/ for details on these settings. */ -class Kint extends BaseConfig +class Kint { /* |-------------------------------------------------------------------------- @@ -23,20 +24,31 @@ class Kint extends BaseConfig |-------------------------------------------------------------------------- */ + /** + * @var list|ConstructablePluginInterface>|null + */ public $plugins; - public $maxDepth = 6; - public $displayCalledFrom = true; - public $expanded = false; + + public int $maxDepth = 6; + public bool $displayCalledFrom = true; + public bool $expanded = false; /* |-------------------------------------------------------------------------- | RichRenderer Settings |-------------------------------------------------------------------------- */ - public $richTheme = 'aante-light.css'; - public $richFolder = false; - public $richSort = Renderer::SORT_FULL; + public string $richTheme = 'aante-light.css'; + public bool $richFolder = false; + + /** + * @var array>|null + */ public $richObjectPlugins; + + /** + * @var array>|null + */ public $richTabPlugins; /* @@ -44,8 +56,8 @@ class Kint extends BaseConfig | CLI Settings |-------------------------------------------------------------------------- */ - public $cliColors = true; - public $cliForceUTF8 = false; - public $cliDetectWidth = true; - public $cliMinWidth = 40; + public bool $cliColors = true; + public bool $cliForceUTF8 = false; + public bool $cliDetectWidth = true; + public int $cliMinWidth = 40; } diff --git a/app/Config/Logger.php b/app/Config/Logger.php index fe389d8..799dc2c 100644 --- a/app/Config/Logger.php +++ b/app/Config/Logger.php @@ -2,8 +2,9 @@ namespace Config; -use CodeIgniter\Log\Handlers\FileHandler; use CodeIgniter\Config\BaseConfig; +use CodeIgniter\Log\Handlers\FileHandler; +use CodeIgniter\Log\Handlers\HandlerInterface; class Logger extends BaseConfig { @@ -36,9 +37,9 @@ class Logger extends BaseConfig * For a live site you'll usually enable Critical or higher (3) to be logged otherwise * your log files will fill up very fast. * - * @var array|int + * @var int|list */ - public $threshold = 4; + public $threshold = (ENVIRONMENT === 'production') ? 4 : 9; /** * -------------------------------------------------------------------------- @@ -47,10 +48,8 @@ class Logger extends BaseConfig * * Each item that is logged has an associated date. You can use PHP date * codes to set your own date formatting - * - * @var string */ - public $dateFormat = 'Y-m-d H:i:s'; + public string $dateFormat = 'Y-m-d H:i:s'; /** * -------------------------------------------------------------------------- @@ -60,7 +59,7 @@ class Logger extends BaseConfig * The logging system supports multiple actions to be taken when something * is logged. This is done by allowing for multiple Handlers, special classes * designed to write the log to their chosen destinations, whether that is - * a file on the server, a cloud-based service, or even taking actions such + * a file on the getServer, a cloud-based service, or even taking actions such * as emailing the dev team. * * Each handler is defined by the class name used for that handler, and it @@ -75,17 +74,15 @@ class Logger extends BaseConfig * Handlers are executed in the order defined in this array, starting with * the handler on top and continuing down. * - * @var array + * @var array, array|string>> */ - public $handlers = [ - + public array $handlers = [ /* * -------------------------------------------------------------------- * File Handler * -------------------------------------------------------------------- */ FileHandler::class => [ - // The log levels that this handler will handle. 'handles' => [ 'critical', @@ -103,7 +100,7 @@ class Logger extends BaseConfig * An extension of 'php' allows for protecting the log files via basic * scripting, when they are to be stored under a publicly accessible directory. * - * Note: Leaving it blank will default to 'log'. + * NOTE: Leaving it blank will default to 'log'. */ 'fileExtension' => '', @@ -141,14 +138,14 @@ class Logger extends BaseConfig * Uncomment this block to use it. */ // 'CodeIgniter\Log\Handlers\ErrorlogHandler' => [ - // /* The log levels this handler can handle. */ - // 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], + // /* The log levels this handler can handle. */ + // 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], // - // /* - // * The message type where the error should go. Can be 0 or 4, or use the - // * class constants: `ErrorlogHandler::TYPE_OS` (0) or `ErrorlogHandler::TYPE_SAPI` (4) - // */ - // 'messageType' => 0, + // /* + // * The message type where the error should go. Can be 0 or 4, or use the + // * class constants: `ErrorlogHandler::TYPE_OS` (0) or `ErrorlogHandler::TYPE_SAPI` (4) + // */ + // 'messageType' => 0, // ], ]; } diff --git a/app/Config/Migrations.php b/app/Config/Migrations.php index 91e80b4..1dec8b9 100644 --- a/app/Config/Migrations.php +++ b/app/Config/Migrations.php @@ -15,10 +15,8 @@ class Migrations extends BaseConfig * * You should enable migrations whenever you intend to do a schema migration * and disable it back when you're done. - * - * @var bool */ - public $enabled = true; + public bool $enabled = true; /** * -------------------------------------------------------------------------- @@ -27,13 +25,9 @@ class Migrations extends BaseConfig * * This is the name of the table that will store the current migrations state. * When migrations runs it will store in a database table which migration - * level the system is at. It then compares the migration level in this - * table to the $config['migration_version'] if they are not the same it - * will migrate up. This must be set. - * - * @var string + * files have already been run. */ - public $table = 'migrations'; + public string $table = 'migrations'; /** * -------------------------------------------------------------------------- @@ -42,14 +36,15 @@ class Migrations extends BaseConfig * * This is the format that will be used when creating new migrations * using the CLI command: - * > php spark migrate:create + * > php spark make:migration * - * Typical formats: + * NOTE: if you set an unsupported format, migration runner will not find + * your migration files. + * + * Supported formats: * - YmdHis_ * - Y-m-d-His_ * - Y_m_d_His_ - * - * @var string */ - public $timestampFormat = 'Y-m-d-His_'; + public string $timestampFormat = 'Y-m-d-His_'; } diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php index 884e76b..c2db734 100644 --- a/app/Config/Mimes.php +++ b/app/Config/Mimes.php @@ -3,8 +3,6 @@ namespace Config; /** - * Mimes - * * This file contains an array of mime types. It is used by the * Upload class to help identify allowed file types. * @@ -21,9 +19,9 @@ class Mimes /** * Map of extensions to mime types. * - * @var array + * @var array|string> */ - public static $mimes = [ + public static array $mimes = [ 'hqx' => [ 'application/mac-binhex40', 'application/mac-binhex', @@ -55,6 +53,8 @@ class Mimes 'lzh' => 'application/octet-stream', 'exe' => [ 'application/octet-stream', + 'application/vnd.microsoft.portable-executable', + 'application/x-dosexec', 'application/x-msdownload', ], 'class' => 'application/octet-stream', @@ -478,6 +478,8 @@ class Mimes 'application/sla', 'application/vnd.ms-pki.stl', 'application/x-navistyle', + 'model/stl', + 'application/octet-stream', ], ]; diff --git a/app/Config/Modules.php b/app/Config/Modules.php index bde4079..9e03fa4 100644 --- a/app/Config/Modules.php +++ b/app/Config/Modules.php @@ -4,6 +4,12 @@ namespace Config; use CodeIgniter\Modules\Modules as BaseModules; +/** + * Modules Configuration. + * + * NOTE: This class is required prior to Autoloader instantiation, + * and does not extend BaseConfig. + */ class Modules extends BaseModules { /** @@ -31,6 +37,29 @@ class Modules extends BaseModules */ public $discoverInComposer = true; + /** + * The Composer package list for Auto-Discovery + * This setting is optional. + * + * E.g.: + * [ + * 'only' => [ + * // List up all packages to auto-discover + * 'codeigniter4/shield', + * ], + * ] + * or + * [ + * 'exclude' => [ + * // List up packages to exclude. + * 'pestphp/pest', + * ], + * ] + * + * @var array{only?: list, exclude?: list} + */ + public $composerPackages = []; + /** * -------------------------------------------------------------------------- * Auto-Discovery Rules @@ -41,7 +70,7 @@ class Modules extends BaseModules * * If it is not listed, only the base application elements will be used. * - * @var string[] + * @var list */ public $aliases = [ 'events', diff --git a/app/Config/Optimize.php b/app/Config/Optimize.php new file mode 100644 index 0000000..481e645 --- /dev/null +++ b/app/Config/Optimize.php @@ -0,0 +1,30 @@ + */ - public $templates = [ + public array $templates = [ 'default_full' => 'CodeIgniter\Pager\Views\default_full', 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', 'default_head' => 'CodeIgniter\Pager\Views\default_head', @@ -32,8 +32,6 @@ class Pager extends BaseConfig * -------------------------------------------------------------------------- * * The default number of results shown in a single page. - * - * @var int */ - public $perPage = 20; + public int $perPage = 20; } diff --git a/app/Config/Paths.php b/app/Config/Paths.php index 1b313a7..d0035fb 100644 --- a/app/Config/Paths.php +++ b/app/Config/Paths.php @@ -22,10 +22,8 @@ class Paths * * This must contain the name of your "system" folder. Include * the path if the folder is not in the same directory as this file. - * - * @var string */ - public $systemDirectory = __DIR__ . '/../../system'; + public string $systemDirectory = __DIR__ . '/../../vendor/codeigniter4/framework/system'; /** * --------------------------------------------------------------- @@ -38,10 +36,8 @@ class Paths * you do, use a full server path. * * @see http://codeigniter.com/user_guide/general/managing_apps.html - * - * @var string */ - public $appDirectory = __DIR__ . '/..'; + public string $appDirectory = __DIR__ . '/..'; /** * --------------------------------------------------------------- @@ -53,10 +49,8 @@ class Paths * need write permission to a single place that can be tucked away * for maximum security, keeping it out of the app and/or * system directories. - * - * @var string */ - public $writableDirectory = __DIR__ . '/../../writable'; + public string $writableDirectory = __DIR__ . '/../../writable'; /** * --------------------------------------------------------------- @@ -64,10 +58,8 @@ class Paths * --------------------------------------------------------------- * * This variable must contain the name of your "tests" directory. - * - * @var string */ - public $testsDirectory = __DIR__ . '/../../tests'; + public string $testsDirectory = __DIR__ . '/../../tests'; /** * --------------------------------------------------------------- @@ -78,8 +70,6 @@ class Paths * contains the view files used by your application. By * default this is in `app/Views`. This value * is used when no value is provided to `Services::renderer()`. - * - * @var string */ - public $viewDirectory = __DIR__ . '/../Views'; + public string $viewDirectory = __DIR__ . '/../Views'; } diff --git a/app/Config/Publisher.php b/app/Config/Publisher.php index 4747511..bf03be1 100644 --- a/app/Config/Publisher.php +++ b/app/Config/Publisher.php @@ -19,7 +19,7 @@ class Publisher extends BasePublisher * result in a PublisherException. Files that do no fit the * pattern will cause copy/merge to fail. * - * @var array + * @var array */ public $restrictions = [ ROOTPATH => '*', diff --git a/app/Config/Routes.php b/app/Config/Routes.php index d937581..8220e7a 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -1,26 +1,23 @@ setDefaultNamespace('App\Controllers'); -$routes->setDefaultController('Dashboard'); -$routes->setDefaultMethod('index'); -$routes->setTranslateURIDashes(false); -$routes->set404Override(); + +// $routes->setDefaultNamespace('App\Controllers'); +// $routes->setDefaultController('Dashboard'); +// $routes->setDefaultMethod('index'); +// $routes->setTranslateURIDashes(false); +// $routes->set404Override(); + // The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps // where controller filters or CSRF protection are bypassed. // If you don't want to define all routes, please use the Auto Routing (Improved). @@ -35,7 +32,6 @@ $routes->set404Override(); // We get a performance increase by specifying the default // route since we don't have to scan directories. - $routes->match(['get','post'], '/auth/login', 'Auth::login'); $routes->match(['get','post'], '/auth/setPass', 'Auth::setPass'); $routes->get( '/auth/logout', 'Auth::logout'); @@ -99,11 +95,18 @@ $routes->match(['get','post'],'/productalias/create', 'ProductAlias::create'); $routes->match(['get','post'],'/productcatalog', 'ProductCatalog::index'); $routes->match(['get','post'],'/productcatalog/edit/(:num)', 'ProductCatalog::edit/$1'); $routes->match(['get','post'],'/productcatalog/create', 'ProductCatalog::create'); +// producttemp +$routes->get('/producttemp', 'ProductTemp::index'); +$routes->get('/producttemp/getdata/(:num)', 'ProductTemp::getdata/$1'); +$routes->post('/producttemp/edit', 'ProductTemp::edit'); +$routes->post('/producttemp/validate', 'ProductTemp::validateItem'); +$routes->post('/producttemp/delete/(:num)', 'ProductTemp::deleteItem/$1'); //unitgroup $routes->match(['get','post'], '/unitgroup/', 'UnitGroup::index'); $routes->match(['get','post'], '/unitgroup/edit/(:num)', 'UnitGroup::edit/$1'); $routes->match(['get','post'], '/unitgroup/create', 'UnitGroup::edit/0'); +$routes->get('/unitgroup/toggle/(:num)', 'UnitGroup::toggle/$1'); // products $routes->match(['get','post'],'/products', 'Products::index'); @@ -115,6 +118,7 @@ $routes->match(['get','post'],'/products/movesite/(:num)', 'Products::movesite/$ $routes->match(['get','post'],'/products/changeowner/(:num)', 'Products::changeowner/$1'); $routes->match(['get','post'],'/products/upgrade/(:num)', 'Products::upgrade/$1'); $routes->post('/products/log/delete', 'Products::productslog_delete'); +$routes->get('/products/export', 'Products::exportdata'); // users $routes->get('/users', 'Users::index'); $routes->get('/users/view/(:num)', 'Users::view/$1'); @@ -144,8 +148,10 @@ $routes->match(['get','post'],'/acttext/create', 'ActText::create'); $routes->match(['get','post'],'/acttext/edit/(:num)', 'ActText::edit/$1'); // activities $routes->match(['get','post'],'/activities/', 'Activities::index'); -$routes->get('/activities/index/getproduct/(:num)', 'Activities::index_getproduct/$1'); +// $routes->get('/activities/index/getproduct/(:num)', 'Activities::index_getproduct/$1'); +$routes->get('/activities/index/getproduct/(:any)/(:any)', 'Activities::index_getproduct/$1/$2'); $routes->get('/activities/detail/(:num)', 'Activities::detail/$1'); +$routes->get('/activities/servicereport/(:num)', 'Activities::servicereport/$1'); $routes->get('/activities/suspend/(:num)', 'Activities::suspend/$1'); $routes->get('/activities/disable/(:num)', 'Activities::disable/$1'); // $routes->get('/activities/delete/(:num)', 'Activities::delete/$1'); @@ -222,6 +228,40 @@ $routes->match(['get','post'],'/invtrans/create', 'InvTrans::edit/0'); $routes->match(['get','post'],'/invtrans/edit/(:any)', 'InvTrans::edit/$1'); $routes->match(['get','post'],'/invtrans/user/(:any)', 'InvTrans::index_user/$1'); $routes->match(['get','post'],'/invtrans/reportusage/', 'InvTrans::reportusage/$1'); + +//LQMS +/* +$routes->match(['get','post'],'/lqms', 'Lqms::index'); +$routes->post('/lqms/postdata', 'Lqms::postdata'); +$routes->get('/lqms/log_clear', 'Lqms::log_clear'); +$routes->get('/lqms/log/delete/(:any)', 'Lqms::log_delete/$1'); +*/ + +/* +// Kanban +$routes->get('/kanban', 'Kanban::index'); +$routes->get('/kanban/view/(:any)', 'Kanban::view/$1'); +$routes->match(['get','post'],'/kanban/board/create/', 'Kanban::board_edit/0'); +$routes->match(['get','post'],'/kanban/board/edit/(:any)', 'Kanban::board_edit/$1'); +$routes->match(['get','post'],'/kanban/list/edit/(:any)', 'Kanban::list_edit/$1'); +$routes->match(['get','post'],'/kanban/card/create/(:any)', 'Kanban::card_edit/$1/0'); +$routes->match(['get','post'],'/kanban/card/edit/(:any)/(:any)', 'Kanban::card_edit/$1/$2'); +$routes->get('/kanban/card/move/(:any)/(:any)', 'Kanban::card_move/$1/$2'); +*/ + +// Key +$routes->group('', ['filter' => 'cors'], function($routes) { + $routes->get('/key/key', 'Key::index'); + $routes->post('/key/data', 'Key::data'); +}); + +// REST API +// $routes->get('/api/getProductList', 'Api::getProductList'); +$routes->get('/api/getProductAlias', 'Api::getProductAlias'); +$routes->get('/api/getProductSites', 'Api::getProductSites'); + +//CLQMS +// $routes->get('/clqms', 'Clqms::index'); // for CLQMS Inst select /* * -------------------------------------------------------------------- * Additional Routing @@ -235,6 +275,6 @@ $routes->match(['get','post'],'/invtrans/reportusage/', 'InvTrans::reportusage/$ * You will have access to the $routes object within that file without * needing to reload it. */ -if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) { - require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; -} +// if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) { +// require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; +// } \ No newline at end of file diff --git a/app/Config/Routing.php b/app/Config/Routing.php new file mode 100644 index 0000000..3005543 --- /dev/null +++ b/app/Config/Routing.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Config; + +use CodeIgniter\Config\Routing as BaseRouting; + +/** + * Routing configuration + */ +class Routing extends BaseRouting +{ + /** + * For Defined Routes. + * An array of files that contain route definitions. + * Route files are read in order, with the first match + * found taking precedence. + * + * Default: APPPATH . 'Config/Routes.php' + * + * @var list + */ + public array $routeFiles = [ + APPPATH . 'Config/Routes.php', + ]; + + /** + * For Defined Routes and Auto Routing. + * The default namespace to use for Controllers when no other + * namespace has been specified. + * + * Default: 'App\Controllers' + */ + public string $defaultNamespace = 'App\Controllers'; + + /** + * For Auto Routing. + * The default controller to use when no other controller has been + * specified. + * + * Default: 'Home' + */ + public string $defaultController = 'Home'; + + /** + * For Defined Routes and Auto Routing. + * The default method to call on the controller when no other + * method has been set in the route. + * + * Default: 'index' + */ + public string $defaultMethod = 'index'; + + /** + * For Auto Routing. + * Whether to translate dashes in URIs for controller/method to underscores. + * Primarily useful when using the auto-routing. + * + * Default: false + */ + public bool $translateURIDashes = false; + + /** + * Sets the class/method that should be called if routing doesn't + * find a match. It can be the controller/method name like: Users::index + * + * This setting is passed to the Router class and handled there. + * + * If you want to use a closure, you will have to set it in the + * routes file by calling: + * + * $routes->set404Override(function() { + * // Do something here + * }); + * + * Example: + * public $override404 = 'App\Errors::show404'; + */ + public ?string $override404 = null; + + /** + * If TRUE, the system will attempt to match the URI against + * Controllers by matching each segment against folders/files + * in APPPATH/Controllers, when a match wasn't found against + * defined routes. + * + * If FALSE, will stop searching and do NO automatic routing. + */ + public bool $autoRoute = false; + + /** + * For Defined Routes. + * If TRUE, will enable the use of the 'prioritize' option + * when defining routes. + * + * Default: false + */ + public bool $prioritize = false; + + /** + * For Defined Routes. + * If TRUE, matched multiple URI segments will be passed as one parameter. + * + * Default: false + */ + public bool $multipleSegmentsOneParam = false; + + /** + * For Auto Routing (Improved). + * Map of URI segments and namespaces. + * + * The key is the first URI segment. The value is the controller namespace. + * E.g., + * [ + * 'blog' => 'Acme\Blog\Controllers', + * ] + * + * @var array + */ + public array $moduleRoutes = []; + + /** + * For Auto Routing (Improved). + * Whether to translate dashes in URIs for controller/method to CamelCase. + * E.g., blog-controller -> BlogController + * + * If you enable this, $translateURIDashes is ignored. + * + * Default: false + */ + public bool $translateUriToCamelCase = true; +} diff --git a/app/Config/Security.php b/app/Config/Security.php index 107bd95..635f8b7 100644 --- a/app/Config/Security.php +++ b/app/Config/Security.php @@ -15,7 +15,7 @@ class Security extends BaseConfig * * @var string 'cookie' or 'session' */ - public $csrfProtection = 'cookie'; + public string $csrfProtection = 'cookie'; /** * -------------------------------------------------------------------------- @@ -23,10 +23,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Randomize the CSRF Token for added security. - * - * @var bool */ - public $tokenRandomize = false; + public bool $tokenRandomize = false; /** * -------------------------------------------------------------------------- @@ -34,10 +32,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Token name for Cross Site Request Forgery protection. - * - * @var string */ - public $tokenName = 'csrf_test_name'; + public string $tokenName = 'csrf_test_name'; /** * -------------------------------------------------------------------------- @@ -45,10 +41,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Header name for Cross Site Request Forgery protection. - * - * @var string */ - public $headerName = 'X-CSRF-TOKEN'; + public string $headerName = 'X-CSRF-TOKEN'; /** * -------------------------------------------------------------------------- @@ -56,10 +50,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Cookie name for Cross Site Request Forgery protection. - * - * @var string */ - public $cookieName = 'csrf_cookie_name'; + public string $cookieName = 'csrf_cookie_name'; /** * -------------------------------------------------------------------------- @@ -69,10 +61,8 @@ class Security extends BaseConfig * Expiration time for Cross Site Request Forgery protection cookie. * * Defaults to two hours (in seconds). - * - * @var int */ - public $expires = 7200; + public int $expires = 7200; /** * -------------------------------------------------------------------------- @@ -80,10 +70,8 @@ class Security extends BaseConfig * -------------------------------------------------------------------------- * * Regenerate CSRF Token on every submission. - * - * @var bool */ - public $regenerate = true; + public bool $regenerate = true; /** * -------------------------------------------------------------------------- @@ -92,26 +80,7 @@ class Security extends BaseConfig * * Redirect to previous page with error on failure. * - * @var bool + * @see https://codeigniter4.github.io/userguide/libraries/security.html#redirection-on-failure */ - public $redirect = true; - - /** - * -------------------------------------------------------------------------- - * CSRF SameSite - * -------------------------------------------------------------------------- - * - * Setting for CSRF SameSite cookie token. - * - * Allowed values are: None - Lax - Strict - ''. - * - * Defaults to `Lax` as recommended in this link: - * - * @see https://portswigger.net/web-security/csrf/samesite-cookies - * - * @var string - * - * @deprecated `Config\Cookie` $samesite property is used. - */ - public $samesite = 'Lax'; + public bool $redirect = (ENVIRONMENT === 'production'); } diff --git a/app/Config/Session.php b/app/Config/Session.php new file mode 100644 index 0000000..6944710 --- /dev/null +++ b/app/Config/Session.php @@ -0,0 +1,127 @@ + + */ + public string $driver = FileHandler::class; + + /** + * -------------------------------------------------------------------------- + * Session Cookie Name + * -------------------------------------------------------------------------- + * + * The session cookie name, must contain only [0-9a-z_-] characters + */ + public string $cookieName = 'ci_session'; + + /** + * -------------------------------------------------------------------------- + * Session Expiration + * -------------------------------------------------------------------------- + * + * The number of SECONDS you want the session to last. + * Setting to 0 (zero) means expire when the browser is closed. + */ + public int $expiration = 7200; + + /** + * -------------------------------------------------------------------------- + * Session Save Path + * -------------------------------------------------------------------------- + * + * The location to save sessions to and is driver dependent. + * + * For the 'files' driver, it's a path to a writable directory. + * WARNING: Only absolute paths are supported! + * + * For the 'database' driver, it's a table name. + * Please read up the manual for the format with other session drivers. + * + * IMPORTANT: You are REQUIRED to set a valid save path! + */ + public string $savePath = WRITEPATH . 'session'; + + /** + * -------------------------------------------------------------------------- + * Session Match IP + * -------------------------------------------------------------------------- + * + * Whether to match the user's IP address when reading the session data. + * + * WARNING: If you're using the database driver, don't forget to update + * your session table's PRIMARY KEY when changing this setting. + */ + public bool $matchIP = false; + + /** + * -------------------------------------------------------------------------- + * Session Time to Update + * -------------------------------------------------------------------------- + * + * How many seconds between CI regenerating the session ID. + */ + public int $timeToUpdate = 300; + + /** + * -------------------------------------------------------------------------- + * Session Regenerate Destroy + * -------------------------------------------------------------------------- + * + * Whether to destroy session data associated with the old session ID + * when auto-regenerating the session ID. When set to FALSE, the data + * will be later deleted by the garbage collector. + */ + public bool $regenerateDestroy = false; + + /** + * -------------------------------------------------------------------------- + * Session Database Group + * -------------------------------------------------------------------------- + * + * DB Group for the database session. + */ + public ?string $DBGroup = null; + + /** + * -------------------------------------------------------------------------- + * Lock Retry Interval (microseconds) + * -------------------------------------------------------------------------- + * + * This is used for RedisHandler. + * + * Time (microseconds) to wait if lock cannot be acquired. + * The default is 100,000 microseconds (= 0.1 seconds). + */ + public int $lockRetryInterval = 100_000; + + /** + * -------------------------------------------------------------------------- + * Lock Max Retries + * -------------------------------------------------------------------------- + * + * This is used for RedisHandler. + * + * Maximum number of lock acquisition attempts. + * The default is 300 times. That is lock timeout is about 30 (0.1 * 300) + * seconds. + */ + public int $lockMaxRetries = 300; +} diff --git a/app/Config/Toolbar.php b/app/Config/Toolbar.php index 7183e13..5a3e504 100644 --- a/app/Config/Toolbar.php +++ b/app/Config/Toolbar.php @@ -31,9 +31,9 @@ class Toolbar extends BaseConfig * List of toolbar collectors that will be called when Debug Toolbar * fires up and collects data from. * - * @var string[] + * @var list */ - public $collectors = [ + public array $collectors = [ Timers::class, Database::class, Logs::class, @@ -49,12 +49,10 @@ class Toolbar extends BaseConfig * Collect Var Data * -------------------------------------------------------------------------- * - * If set to false var data from the views will not be colleted. Usefull to + * If set to false var data from the views will not be collected. Useful to * avoid high memory usage when there are lots of data passed to the view. - * - * @var bool */ - public $collectVarData = true; + public bool $collectVarData = true; /** * -------------------------------------------------------------------------- @@ -64,10 +62,8 @@ class Toolbar extends BaseConfig * `$maxHistory` sets a limit on the number of past requests that are stored, * helping to conserve file space used to store them. You can set it to * 0 (zero) to not have any history stored, or -1 for unlimited history. - * - * @var int */ - public $maxHistory = 20; + public int $maxHistory = 20; /** * -------------------------------------------------------------------------- @@ -76,10 +72,8 @@ class Toolbar extends BaseConfig * * The full path to the the views that are used by the toolbar. * This MUST have a trailing slash. - * - * @var string */ - public $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/'; + public string $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/'; /** * -------------------------------------------------------------------------- @@ -92,8 +86,37 @@ class Toolbar extends BaseConfig * with hundreds of queries. * * `$maxQueries` defines the maximum amount of queries that will be stored. - * - * @var int */ - public $maxQueries = 100; + public int $maxQueries = 100; + + /** + * -------------------------------------------------------------------------- + * Watched Directories + * -------------------------------------------------------------------------- + * + * Contains an array of directories that will be watched for changes and + * used to determine if the hot-reload feature should reload the page or not. + * We restrict the values to keep performance as high as possible. + * + * NOTE: The ROOTPATH will be prepended to all values. + * + * @var list + */ + public array $watchedDirectories = [ + 'app', + ]; + + /** + * -------------------------------------------------------------------------- + * Watched File Extensions + * -------------------------------------------------------------------------- + * + * Contains an array of file extensions that will be watched for changes and + * used to determine if the hot-reload feature should reload the page or not. + * + * @var list + */ + public array $watchedExtensions = [ + 'php', 'css', 'js', 'html', 'svg', 'json', 'env', + ]; } diff --git a/app/Config/UserAgents.php b/app/Config/UserAgents.php index e1dbfa6..fda7374 100644 --- a/app/Config/UserAgents.php +++ b/app/Config/UserAgents.php @@ -23,7 +23,7 @@ class UserAgents extends BaseConfig * * @var array */ - public $platforms = [ + public array $platforms = [ 'windows nt 10.0' => 'Windows 10', 'windows nt 6.3' => 'Windows 8.1', 'windows nt 6.2' => 'Windows 8', @@ -78,7 +78,7 @@ class UserAgents extends BaseConfig * * @var array */ - public $browsers = [ + public array $browsers = [ 'OPR' => 'Opera', 'Flock' => 'Flock', 'Edge' => 'Spartan', @@ -119,7 +119,7 @@ class UserAgents extends BaseConfig * * @var array */ - public $mobiles = [ + public array $mobiles = [ // legacy array, old values commented out 'mobileexplorer' => 'Mobile Explorer', // 'openwave' => 'Open Wave', @@ -228,7 +228,7 @@ class UserAgents extends BaseConfig * * @var array */ - public $robots = [ + public array $robots = [ 'googlebot' => 'Googlebot', 'msnbot' => 'MSNBot', 'baiduspider' => 'Baiduspider', diff --git a/app/Config/Validation.php b/app/Config/Validation.php index 01e2736..6342dbb 100644 --- a/app/Config/Validation.php +++ b/app/Config/Validation.php @@ -3,12 +3,10 @@ namespace Config; use CodeIgniter\Config\BaseConfig; -use CodeIgniter\Validation\CreditCardRules; -use CodeIgniter\Validation\FileRules; -use CodeIgniter\Validation\FormatRules; -use CodeIgniter\Validation\Rules; - -//use Validation\CustomValidation; +use CodeIgniter\Validation\StrictRules\CreditCardRules; +use CodeIgniter\Validation\StrictRules\FileRules; +use CodeIgniter\Validation\StrictRules\FormatRules; +use CodeIgniter\Validation\StrictRules\Rules; class Validation extends BaseConfig { @@ -20,14 +18,13 @@ class Validation extends BaseConfig * Stores the classes that contain the * rules that are available. * - * @var string[] + * @var list */ - public $ruleSets = [ + public array $ruleSets = [ Rules::class, FormatRules::class, FileRules::class, CreditCardRules::class, - CustomValidation::class ]; /** @@ -36,7 +33,7 @@ class Validation extends BaseConfig * * @var array */ - public $templates = [ + public array $templates = [ 'list' => 'CodeIgniter\Validation\Views\list', 'single' => 'CodeIgniter\Validation\Views\single', ]; @@ -44,16 +41,4 @@ class Validation extends BaseConfig // -------------------------------------------------------------------- // Rules // -------------------------------------------------------------------- - public function validateLogin(string $str, string $fields, array $data){ - $email = $data['email']; - - $db = \Config\Database::connect(); - $sql = "SELECT userid, password FROM users WHERE email_1='$email'"; - $query = $db->query($sql); - $user = $query->getRow(); - - if(!$user) return false; - - return password_verify($data['password'], $user->password ); - } } diff --git a/app/Config/View.php b/app/Config/View.php index 78cd547..cf8dd06 100644 --- a/app/Config/View.php +++ b/app/Config/View.php @@ -5,6 +5,10 @@ namespace Config; use CodeIgniter\Config\View as BaseView; use CodeIgniter\View\ViewDecoratorInterface; +/** + * @phpstan-type parser_callable (callable(mixed): mixed) + * @phpstan-type parser_callable_string (callable(mixed): mixed)&string + */ class View extends BaseView { /** @@ -30,7 +34,8 @@ class View extends BaseView * { title|esc(js) } * { created_on|date(Y-m-d)|esc(attr) } * - * @var array + * @var array + * @phpstan-var array */ public $filters = []; @@ -39,7 +44,8 @@ class View extends BaseView * by the core Parser by creating aliases that will be replaced with * any callable. Can be single or tag pair. * - * @var array + * @var array|string> + * @phpstan-var array|parser_callable_string|parser_callable> */ public $plugins = []; @@ -50,7 +56,7 @@ class View extends BaseView * * All classes must implement CodeIgniter\View\ViewDecoratorInterface * - * @var class-string[] + * @var list> */ public array $decorators = []; } diff --git a/app/Controllers/Activities.php b/app/Controllers/Activities.php index 5bdb6fe..d627c09 100644 --- a/app/Controllers/Activities.php +++ b/app/Controllers/Activities.php @@ -15,10 +15,22 @@ class Activities extends Controller { function __construct() { $this->data['medias'] = array('WA'=>'Whatsapp', 'PH'=> 'Phone', 'VB' => 'Verbal', 'LT'=>'Letter', 'CRM'=>'Direct CRM', 'SKP'=>'Skype'); $this->data['actions'] = array('r'=>'Remote', 'p'=> 'Phone', 'o'=>'On site'); - $this->data['userpos'] = array(''=>'ALL', 'IT'=> 'IT', 'IVD'=>'IVD', 'PS'=>'Product Specialist'); + $this -> data['userpos'] = array( + '' => 'ALL', + 'TSO' => 'ALL - TSO', + 'IT' => 'IT', + 'IVD' => 'IVD', + 'IVDT' => 'IVD - Barat', + 'IVDH' => 'IVD - Tengah', + 'IVDR' => 'IVD - Timur', + 'MT' => 'Marketing', + 'PS' => 'Product Specialist', + ); $this->data['stats'] = array('O'=>'Open', 'A'=>'Accepted', 'P'=>'Pending', 'C'=> 'Close', 'S' => 'Suspend', 'D' => 'Disable'); $this->data['actbys'] = array( 'P'=>'Product ( Equipment / System )' , 'V'=> 'Vendor', 'C'=>'Consumables / Reagent', 'O'=>'Other'); $this->data['exports'] = array('P'=>'PDF', 'E'=> 'Excel'); + $this->data['acttypes'] = array(1=>'Incident Report', 2=> 'Change Request', 3=>'Project', 4=>'Support', 5=>'Maintenance', 6=>'Training', 7=>'Refurbish', 9=>'Training Customer/TSO'); + // invtrans $this->data['itx_apprtypes'] = array('W'=>'Warranty', 'U'=> 'User'); $this->data['itx_conditions'] = array('N'=>'New', 'U'=> 'Used', 'R'=>'Refurbished'); @@ -32,7 +44,7 @@ class Activities extends Controller { $data = array(); $db = \Config\Database::connect(); - $sql = "SELECT * FROM sites"; + $sql = "SELECT * FROM sites WHERE enddate IS NULL"; $query = $db->query($sql); $results = $query->getResultArray(); $data['sites'] = $results; @@ -41,7 +53,7 @@ class Activities extends Controller { $query = $db->query($sql); $results = $query->getResultArray(); $data['users'] = $results; - + $sql = "SELECT * FROM productalias"; $query = $db->query($sql); $results = $query->getResultArray(); @@ -54,6 +66,8 @@ class Activities extends Controller { $data['actbys'] = $this->data['actbys']; $data['stats'] = $this->data['stats']; + $data['acttypes'] = $this->data['acttypes']; + $data['actions'] = $this->data['actions']; if( $this->request->getPost('opendate') == '' ){ $opendate = date("Y-m-01"); } else { $opendate = $this->request->getPost('opendate'); } @@ -68,6 +82,8 @@ class Activities extends Controller { $detail_activity = $this->request->getPost('detail_activity'); $productaliasid = $this->request->getPost('productaliasid'); $actbys = $this->request->getPost('actbys'); + $acttypes = $this->request->getPost('acttypes'); + $actions = $this->request->getPost('actions'); if($siteid != '') { $sql = "SELECT p.*, pc.`productname`, p.`productnumber` @@ -91,8 +107,17 @@ class Activities extends Controller { if($sub == 'IT'){ $filterquery .= " and up.userposid in (3,5) "; } if($sub == 'IVD'){ $filterquery .= " and up.userposid in (2,4) "; } if($sub == 'PS'){ $filterquery .= " and up.userposid in (6,14) "; } - if($detail_activity != ''){$filterquery .= " and ad.textvalue LIKE '%$detail_activity%' "; } + if($detail_activity != '') { + $column_detail_activity = ", ad.*"; + $join_detail_activity = " left join actdetail ad on a.actid=ad.actid "; + $filterquery .= " and ad.textvalue LIKE '%$detail_activity%' "; + } else { + $column_detail_activity = ""; + $join_detail_activity = ""; + } if($actbys != ''){$filterquery .= " and a.actby = '$actbys'";} + if($acttypes != ''){$filterquery .= " and a.acttypeid = $acttypes";} + if($actions != ''){$filterquery .= " and a.action = '$actions'";} $areaquery = ''; if($areaid != ''){ $areaquery .= " and a.siteid in ( select siteid from v_siteaccount where areaid='$areaid' ) "; } @@ -113,10 +138,13 @@ class Activities extends Controller { $data['areaid'] = $areaid; $data['detail_activity'] = $detail_activity; $data['actby'] = $actbys; - - $sql = "SELECT s.sitename, pc.productname, v.vendorname ,u.firstname as username,uc.firstname as creator_name, up.userposid, at.fulltext, a.*, ad.* + $data['acttype'] = $acttypes; + $data['action'] = $actions; + + $sql = "SELECT s.sitename, pc.productname, v.vendorname ,u.firstname as username,uc.firstname as creator_name, up.userposid, at.fulltext, a.* + $column_detail_activity FROM `activities` a - left join actdetail ad on a.actid=ad.actid + $join_detail_activity left join sites s on s.siteid=a.siteid left join products p on a.productid=p.productid left join productcatalog pc on pc.catalogid=p.catalogid @@ -133,6 +161,30 @@ class Activities extends Controller { OR ( a.activitystatus='P' $filterquery ) GROUP BY a.actid order by field(a.activitystatus,'O','C','R'), a.closedate desc, a.reportdate desc"; + + // $sql = "SELECT s.sitename, pc.productname, v.vendorname, u.firstname AS username, up.userposid, at.fulltext, a.* + // -- ,ad.* + // FROM + // activities a + // -- LEFT JOIN actdetail ad ON a.actid = ad.actid + // LEFT JOIN sites s ON s.siteid = a.siteid + // LEFT JOIN products p ON a.productid = p.productid + // LEFT JOIN productcatalog pc ON pc.catalogid = p.catalogid + // LEFT JOIN vendors v ON v.vendorid = a.vendorid + // LEFT JOIN productalias pa ON pa.productaliasid = pc.productaliasid + // LEFT JOIN users u ON u.userid = a.userid_owner + // LEFT JOIN userposition up ON up.userposid = u.userposid + // LEFT JOIN acttype at ON at.acttypeid = a.acttypeid + // WHERE ( + // a.closedate BETWEEN '$opendate 00:00:00' AND '$closedate 23:59:59' + // $filterquery $areaquery + // OR ( a.activitystatus in ('O','P') $filterquery $areaquery ) + // ) + // GROUP BY a.actid + // ORDER BY + // FIELD(a.activitystatus, 'O', 'C', 'R'), + // a.closedate DESC, + // a.reportdate DESC;"; //echo "$sql"; $query = $db->query($sql); $result = $query->getResultArray(); @@ -142,12 +194,52 @@ class Activities extends Controller { return view('activities_index', $data); } - public function index_getproduct($siteid=null){ + // public function index_getproduct($siteid=null){ + // $db = \Config\Database::connect(); + // $sql = "SELECT p.*, pc.`productname`, p.`productnumber` + // FROM products p + // LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid` + // WHERE p.siteid=$siteid and productaliasid<>0 order by pc.productname"; + // $query = $db->query($sql); + // $results = $query->getResultArray(); + // $option = ""; + // foreach ($results as $data) { + // $qproductid = $data['productid']; + // $qproductname = $data['productname']; + // $qproductnumber = $data['productnumber']; + // $qproductlocationenddate = $data['locationenddate']; + // if($qproductlocationenddate == NULL){ + // $option .= "\r\n"; + // //$option .= "$qproductid $qproductname $qproductnumber
"; + // } + // } + // //echo "$option"; + // return $option; + // } + + public function index_getproduct($siteid, $productaliasid){ $db = \Config\Database::connect(); - $sql = "SELECT p.*, pc.`productname`, p.`productnumber` - FROM products p - LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid` - WHERE p.siteid=$siteid and productaliasid<>0 order by pc.productname"; + + // Kondisi untuk tiap form + if ($siteid == 'none' && $productaliasid != 'none') { + $query = "WHERE pa.productaliasid=$productaliasid"; + } else if ($siteid != 'none' && $productaliasid == 'none') { + $query = "WHERE p.siteid=$siteid"; + } else { + $query = "WHERE pa.productaliasid=$productaliasid and p.siteid=$siteid"; + } + + $sql = "SELECT p.*, pc.productname FROM productalias pa + LEFT JOIN productcatalog pc ON pa.productaliasid = pc.productaliasid + LEFT JOIN products p ON pc.catalogid = p.catalogid + LEFT JOIN sites s ON p.siteid = s.siteid + $query ORDER BY pc.productname"; + + // Kondisi apabila kedua form kosong + if ($siteid == 'none' && $productaliasid == 'none') { + return ""; + } + $query = $db->query($sql); $results = $query->getResultArray(); $option = ""; @@ -227,7 +319,7 @@ class Activities extends Controller { $sql = " SELECT u.*, c.`productname`, c.catalognumber FROM unitgroup u LEFT JOIN productcatalog c ON u.`catalogid`=c.`catalogid` - WHERE c.productaliasid<>0"; + WHERE c.productaliasid<>0 AND u.`enddate` IS NULL"; $query = $db->query($sql); $results = $query->getResultArray(); $data['unitgroup'] = $results; @@ -281,6 +373,7 @@ class Activities extends Controller { 'acttextid' => $this->request->getVar('acttextid'), 'textvalue' => $this->request->getVar('textvalue') ]; + $actby = $this->request->getVar('actby'); if($actby == 'P') { $data['new_value']['productid'] = $this->request->getVar('productid'); @@ -299,6 +392,20 @@ class Activities extends Controller { if($this->validate($rules)) { $db = \Config\Database::connect(); if($actid == 0) { + + // Cek apakah ada duplikasi data + $exists = $db->table('activities') + ->where('subject', $data['new_value']['subject']) + ->where('siteid', $data['new_value']['siteid']) + ->where('reportdate', $data['new_value']['reportdate']) + ->where('opendate', $data['new_value']['opendate']) + ->where('closedate', $data['new_value']['closedate']) + ->where('userid_creator', $data['new_value']['userid_creator']) + ->get()->getRow(); + if ($exists) { // Jika ada maka Redirect + return redirect()->to('/activities'); + } + // Create Activities $activitiesModel = new ActivitiesModel(); $activitiesModel->set('createdate', 'NOW()', FALSE); @@ -323,7 +430,32 @@ class Activities extends Controller { // update edit $activitiesModel = new ActivitiesModel(); $activitiesModel->update($actid,$data['new_value']); - + + // clear other act by + if($actby == 'P') { // product + $sql = "update activities set vendorid=null where actid='$actid'"; + $query = $db->query($sql); + $sql = "delete from actconsumables where actid='$actid'"; + $query = $db->query($sql); + } elseif($actby == 'V') { // vendor + $sql = "update activities set productid=null where actid='$actid'"; + $query = $db->query($sql); + $sql = "delete from actconsumables where actid='$actid'"; + $query = $db->query($sql); + } elseif($actby == 'C') { // consumables + $sql = "update activities set productid=null where actid='$actid'"; + $query = $db->query($sql); + $sql = "update activities set vendorid=null where actid='$actid'"; + $query = $db->query($sql); + } else { // other + $sql = "update activities set productid=null where actid='$actid'"; + $query = $db->query($sql); + $sql = "update activities set vendorid=null where actid='$actid'"; + $query = $db->query($sql); + $sql = "delete from actconsumables where actid='$actid'"; + $query = $db->query($sql); + } + // Apabila Act Status Diubah Maka Kondisi berikut dijalankan $tb_actstatus_log = $db->table('actstatus_log'); $actstatus_old = $tb_actstatus_log->select('activitystatus')->where('activityid', $actid)->orderBy('logdate', 'DESC')->get()->getRowArray(); @@ -363,7 +495,7 @@ class Activities extends Controller { } } - // actcon + // act by consumables $actconid_delete = $this->request->getVar('actconid_delete'); if($actconid_delete != '') { $actconid_del = explode(' ',$actconid_delete); @@ -448,7 +580,9 @@ class Activities extends Controller { $sql = "SELECT p.*, pc.`productname`, p.`productnumber` FROM products p LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid` - WHERE p.siteid=$siteid and productaliasid<>0 order by pc.productname"; + LEFT JOIN producttype pt ON pt.`producttypeid`= pc.`producttypeid` + WHERE p.siteid=$siteid and productaliasid<>0 + ORDER BY FIELD(pt.producttypeid, 20, 19, 21, 12, 10, 14, 11, 13, 4, 3) DESC, pc.productname"; $query = $db->query($sql); $results = $query->getResultArray(); $data['products'] = $results; @@ -517,7 +651,7 @@ class Activities extends Controller { } } - public function act_content($actid, $filter_email=false) { + public function act_content($actid, $filter_email=false) { // Parameter Ke-2 Untuk Email $db = \Config\Database::connect(); $sql = "select a.*, v.vendorname, v2.vendorname as vendorname_2, u.firstname, u.lastname, atyp.fulltext, atyp.acttypecode, s.sitename, pc.productname, c.firstname as cfname, c.lastname as clname, p.productnumber from activities a @@ -545,12 +679,13 @@ class Activities extends Controller { } $data['stats'] = $this->data['stats']; - $filter_email = $filter_email === true ? ' AND ad.acttextid NOT IN(3) ' : ' '; + // Filter Tidak Menampilkan Internal Note + $filter_internalnote = $filter_email === true ? ' AND ad.acttextid NOT IN(3) ' : ' '; $sql = "SELECT ad.*, ate.`fulltext` AS acttextname FROM actdetail ad LEFT JOIN acttext ate ON ate.`acttextid`=ad.`acttextid` - WHERE ad.actid=$actid $filter_email + WHERE ad.actid=$actid $filter_internalnote -- Filter Email ORDER BY CASE WHEN ad.acttextid = 1 THEN 1 WHEN ad.acttextid = 5 THEN 5 @@ -570,11 +705,23 @@ class Activities extends Controller { $actions = $this->data['actions']; $data['activities'][0]['action'] = $actions[$data['activities'][0]['action']]; } + + $data['itx_purposes'] = $this->data['itx_purposes']; - $sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, u.unit FROM invtrans i + // Filter Email Hanya Menampilkan Replace Saja ke Customers + if ($filter_email === true){ + $sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, u.unit FROM invtrans i LEFT JOIN unitgroup u ON u.`unitgroupid`=i.`unitgroupid` LEFT JOIN productcatalog pc ON pc.`catalogid`=u.`catalogid` - where i.actid='$actid'"; + WHERE i.actid='$actid' AND i.`purpose` IN ('PR', 'PB', 'PU', 'PF') + GROUP BY pc.`catalognumber` ORDER BY i.itxid"; + } else { + $sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, i.`purpose`, u.unit FROM invtrans i + LEFT JOIN unitgroup u ON u.`unitgroupid`=i.`unitgroupid` + LEFT JOIN productcatalog pc ON pc.`catalogid`=u.`catalogid` + WHERE i.actid='$actid'"; + } + $query = $db->query($sql); $result = $query->getResultArray(); $data['invtrans'] = $result; @@ -599,6 +746,57 @@ class Activities extends Controller { return view('activities_detail', $data); } + public function servicereport($actid){ + $db = \Config\Database::connect(); + $data['actid'] = $actid; + + $sql = "select a.*, v.vendorname, v2.vendorname as vendorname_2, u.firstname, u.lastname, atyp.fulltext, + atyp.acttypecode, s.sitename, pc.productname, c.firstname as cfname, c.lastname as clname, p.productnumber + from activities a + left join users u on a.userid_owner=u.userid + left join acttype atyp on a.acttypeid=atyp.acttypeid + left join sites s on a.siteid=s.siteid + left join products p on a.productid=p.productid + left join productcatalog pc on p.catalogid=pc.catalogid + left join vendors v on v.vendorid=pc.vendorid + left join vendors v2 on v2.vendorid=a.vendorid + left join contacts c on a.contactid=c.contactid + where actid='$actid'"; + $query = $db->query($sql); + $result = $query->getResultArray(); + $data['activities'] = $result; + + $sql = "SELECT ad.*, ate.`fulltext` AS acttextname + FROM actdetail ad + LEFT JOIN acttext ate ON ate.`acttextid`=ad.`acttextid` + WHERE ad.actid=$actid + ORDER BY CASE + WHEN ad.acttextid = 1 THEN 1 + WHEN ad.acttextid = 5 THEN 5 + WHEN ad.acttextid = 2 THEN 2 + WHEN ad.acttextid = 3 THEN 3 + WHEN ad.acttextid = 6 THEN 4 + WHEN ad.acttextid = 34 THEN 5 + WHEN ad.acttextid = 4 THEN 99 + ELSE 6 END"; + $query = $db->query($sql); + $result = $query->getResultArray(); + $data['actdetails'] = $result; + + $sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, u.unit, i.purpose FROM invtrans i + LEFT JOIN unitgroup u ON u.`unitgroupid`=i.`unitgroupid` + LEFT JOIN productcatalog pc ON pc.`catalogid`=u.`catalogid` + WHERE i.actid='$actid' AND i.`purpose` IN ('PR', 'PB', 'PU', 'PF') + GROUP BY pc.`catalognumber` ORDER BY i.itxid"; + $query = $db->query($sql); + $result = $query->getResultArray(); + $data['invtrans'] = $result; + + $data['purposes'] = $this->data['itx_purposes']; + + return view('activities_servicereport', $data); + } + public function count(){ $db = \Config\Database::connect(); $opendate = date("Y-m-01"); @@ -610,10 +808,17 @@ class Activities extends Controller { $pos = $this->request->getPost('pos'); $sql_pos = ''; $sql_dept = ''; - if($pos == 'IVD') { $sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4)'; } + + if($pos == 'TSO') { $sql_dept = 'AND u.userdeptid = 1';} + elseif($pos == 'IVD') { $sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4)'; } + elseif($pos == 'IVDR') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4) AND (u.userid = 2 OR u.reportto = 2)'; } //Timur + elseif($pos == 'IVDH') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4) AND (u.userid = 10 OR u.reportto = 10)'; } //Tengah + elseif($pos == 'IVDT') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4) AND (u.userid = 3 OR u.reportto = 3)'; } //Barat elseif($pos == 'IT') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,3,5)'; } elseif($pos == 'PS') {$sql_dept = 'AND u.userdeptid = 2'; $sql_pos = 'AND u.userposid in (6,14)'; } - $sql = "SELECT u.firstname, u.lastname, u.userdeptid, u.userid, + elseif($pos == 'MT') {$sql_dept = 'AND u.userdeptid = 2'; $sql_pos = 'AND u.userposid in (6,14)'; } + + $sql = "SELECT u.firstname, u.lastname, u.userdeptid, u.userid, u.userposid, SUM(CASE WHEN aty.acttypecode='CR' THEN 1 ELSE 0 END) AS CR, SUM(CASE WHEN aty.acttypecode='IR' THEN 1 ELSE 0 END) AS IR, SUM(CASE WHEN aty.acttypecode='MN' THEN 1 ELSE 0 END) AS MN, @@ -760,7 +965,7 @@ class Activities extends Controller { $message = $this->request->getVar('message'); $attachment = $this->request->getVar('attachment'); $attachments = explode(',',$attachment); - + /* $email->setFrom('noreply@services.summit.co.id', 'SUMMIT CRM'); $email->setReplyTo($replyto); $email->setTo(cleanmail($to)); @@ -774,21 +979,53 @@ class Activities extends Controller { $email->attach($attachment); } } - $email->send(); - /* - echo ""; - */ + //$email->set_newline("\r\n"); + //$email->send(); # debugging email CI4 //$email->send(FALSE); + $myfile = fopen("log.txt", "a+") or die("Unable to open file!"); + if ( $email->send(FALSE) ) { + fwrite($myfile, "\nemail sent success"); + } else { + fwrite($myfile, "\n".$email->printDebugger() ); + } + fclose($myfile); + */ $tos = join(",",$to); if(isset($cc)) { $ccs = join(",",$cc); } else { $ccs = ''; } if(isset($bcc)) { $bccs = join(",",$bcc); } else { $bccs = ''; } $sql = "insert into actsend_log (actid, replyto, emailto, emailcc, emailbcc, logdate) values ( '$actid', '$replyto', '$tos', '$ccs', '$bccs', NOW() )"; - //echo "$sql"; $query = $db->query($sql); - //return $email->printDebugger(); + + $data = [ + 'replyto' => $replyto, + 'to' => $tos, + 'cc' => $ccs, + 'bcc' => $bccs, + 'subject' => $subject, + 'message' => $message, + 'attachment' => $attachment, + ]; + $jsonData = json_encode($data); + //print_r($jsonData); + //$url = 'http://localhost/work/phpmailer/server.php'; + $url = 'https://sadewa.services-summit.my.id/server.php'; + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); + curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + if(curl_errno($ch)) { echo 'Curl error: '.curl_error($ch); } + //echo "sending email"; + //echo "$jsonData
"; + //echo "
$response
"; + curl_close($ch); + /* + $myfile = fopen("log.txt", "a+") or die("Unable to open file!"); + fwrite($myfile,$response); + fclose($myfile); + */ return redirect()->to('activities/'); } else { return view('activities_compose', $data); @@ -870,13 +1107,13 @@ class Activities extends Controller { $sql = "select atyp.fulltext, u.firstname, u.lastname, act.subject, act.actid, act.actid_ref, act.acttypeid, act.userid_owner, act.media, act.siteid, s.sitename, act.contactid, act.opendate, act.closedate, act.reportdate, act.productid, act.activitystatus, pc.productname, p.productnumber, act.reportfrom, act.swversion, act.action, act.actby - from activities act - left join users u on act.userid_owner=u.userid - left join sites s on act.siteid=s.siteid - left join acttype atyp on act.acttypeid=atyp.acttypeid - left join products p on act.productid=p.productid - left join productcatalog pc on p.catalogid=pc.catalogid - WHERE act.opendate between '$opendate 00:00:00' and '$closedate 23:59:59' and act.activitystatus='C' $filterquery"; + from activities act + left join users u on act.userid_owner=u.userid + left join sites s on act.siteid=s.siteid + left join acttype atyp on act.acttypeid=atyp.acttypeid + left join products p on act.productid=p.productid + left join productcatalog pc on p.catalogid=pc.catalogid + WHERE act.opendate between '$opendate 00:00:00' and '$closedate 23:59:59' and act.activitystatus='C' $filterquery"; $query = $db->query($sql); $results = $query->getResultArray(); $data['export'] = $results; diff --git a/app/Controllers/Api.php b/app/Controllers/Api.php new file mode 100644 index 0000000..da74d3a --- /dev/null +++ b/app/Controllers/Api.php @@ -0,0 +1,55 @@ +query($sql); + // $data = $query->getResultArray(); + // if(count($data)==0) { $data = array('status' => 'error', 'message' => 'No data found'); } + // else { + // header('Content-Type: application/json'); + // echo json_encode($data); + // } + // } + + public function getProductAlias() { + $db = \Config\Database::connect(); + $sql = "SELECT productaliasid, productaliastext + FROM productalias order by productaliasid"; + $query = $db->query($sql); + $data = $query->getResultArray(); + if(count($data)==0) { $data = array('status' => 'error', 'message' => 'No data found'); } + else { + header('Content-Type: application/json'); + echo json_encode($data); + } + } + + public function getProductSites() { + $db = \Config\Database::connect(); + $sql = "SELECT pc.productaliasid, p.productnumber, s.sitename + FROM products p + LEFT JOIN productcatalog pc on pc.catalogid=p.catalogid + LEFT JOIN sites s on s.siteid=p.siteid + WHERE pc.productaliasid IN (18,19,20,21,60) ORDER BY pc.productaliasid"; + $query = $db->query($sql); + $data = $query->getResultArray(); + if (count($data) === 0) { + return $this->response->setJSON([ + 'status' => 'error', + 'message' => 'No data found' + ]); + } + return $this->response->setJSON($data); + } + +} \ No newline at end of file diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php index 122db5f..689405b 100644 --- a/app/Controllers/BaseController.php +++ b/app/Controllers/BaseController.php @@ -33,12 +33,18 @@ abstract class BaseController extends Controller * class instantiation. These helpers will be available * to all other controllers that extend BaseController. * - * @var array + * @var list */ protected $helpers = []; /** - * Constructor. + * Be sure to declare properties for any property fetch you initialized. + * The creation of dynamic property is deprecated in PHP 8.2. + */ + // protected $session; + + /** + * @return void */ public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { @@ -47,6 +53,6 @@ abstract class BaseController extends Controller // Preload any models, libraries, etc, here. - // E.g.: $this->session = \Config\Services::session(); + // E.g.: $this->session = service('session'); } } diff --git a/app/Controllers/Clqms.php b/app/Controllers/Clqms.php new file mode 100644 index 0000000..bb40d5c --- /dev/null +++ b/app/Controllers/Clqms.php @@ -0,0 +1,47 @@ + 'http://summitcrm.local/api/getProductList', + CURLOPT_URL => 'https://clqms.services-summit.my.id/api/getProductList', + #CURLOPT_URL => 'http://clqms-server.local/api/getProductList', + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'GET', + )); + + $response = curl_exec($curl); + curl_close($curl); + $data = json_decode($response, true); + + return $data; + } + + public function index() { + $db = \Config\Database::connect(); + // get data from clqms + $data['clqms_products'] = $this->getProductList(); + + // query products data from crm + $qproductid = ''; + foreach ($data['clqms_products'] as $qdata) { + $qproductid .= $qdata['productid'].","; + } + $qproductid = rtrim($qproductid,','); + + $sql = "SELECT p.productid, pc.productname, s.`sitename`, p.`productnumber` FROM products p + LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid` + LEFT JOIN sites s ON s.`siteid`=p.`siteid` + WHERE p.productid IN ($qproductid)"; + $query = $db->query($sql); + $data['products'] = $query->getResultArray(); + + return view('clqms_index', $data); + } + +} \ No newline at end of file diff --git a/app/Controllers/Dashboard.php b/app/Controllers/Dashboard.php index 44852b0..cfdad01 100644 --- a/app/Controllers/Dashboard.php +++ b/app/Controllers/Dashboard.php @@ -111,8 +111,8 @@ class Dashboard extends BaseController { where (( a.closedate between '$opendate 00:00:00' and '$closedate 23:59:59') OR ( a.reportdate between '$opendate 00:00:00' and '$closedate 23:59:59') - OR ( a.activitystatus='O') - OR (a.activitystatus = 'P')) + OR ( a.activitystatus='O' and a.opendate >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH)) + OR (a.activitystatus = 'P' and a.opendate >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH))) AND (a.activitystatus <> 'S') order by field(a.activitystatus,'O','C','R'), a.closedate desc, a.reportdate desc"; $query = $db->query($sql); diff --git a/app/Controllers/InvTrans.php b/app/Controllers/InvTrans.php index 98b0862..1d23978 100644 --- a/app/Controllers/InvTrans.php +++ b/app/Controllers/InvTrans.php @@ -116,7 +116,7 @@ class InvTrans extends BaseController { $data['conditions'] = $this->data['itx_conditions']; $sql = "SELECT u.*, c.`productname`, c.catalognumber FROM unitgroup u - LEFT JOIN productcatalog c ON u.`catalogid`=c.`catalogid`"; + LEFT JOIN productcatalog c ON u.`catalogid`=c.`catalogid` WHERE u.`enddate` IS NULL"; $query = $db->query($sql); $results = $query->getResultArray(); $data['unitgroup'] = $results; diff --git a/app/Controllers/Kanban.php b/app/Controllers/Kanban.php new file mode 100644 index 0000000..8a5bd61 --- /dev/null +++ b/app/Controllers/Kanban.php @@ -0,0 +1,249 @@ +data['card_priorities'] = array( 'L' => 'Low', 'M' => 'Medium', 'H'=>'High' ); + } + + public function index() { + $db = \Config\Database::connect(); + $sql = "SELECT b.boardid, b.`boardname` FROM kb_boarduser bu + LEFT JOIN kb_boards b ON bu.`boardid`=b.`boardid` + WHERE bu.`userid`=".$_SESSION['userid']." order by b.createdate desc"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['boards'] = $results; + return view('kb_index',$data); + } + + public function view($boardid) { + $db = \Config\Database::connect(); + // get board data + $sql = "SELECT * FROM kb_boards where boardid=$boardid"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['boards'] = $results; + // lists + $sql = "SELECT * FROM kb_lists where boardid=$boardid order by listindex"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['lists'] = $results; + // cards + $sql = "SELECT u.`firstname`,u.`lastname`, c.* FROM kb_cards c + JOIN users u ON c.`owner_userid`=u.userid + WHERE c.listid IN (SELECT listid FROM kb_lists WHERE boardid='$boardid')"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['cards'] = $results; + $data['card_priorities'] = $this->data['card_priorities']; + return view('kb_view',$data); + } + + public function board_edit($boardid) { + $db = \Config\Database::connect(); + $sql = "select * from users where enddate is null"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['users'] = $results; + $data['boardid'] = $boardid; + if($boardid != 0) { + $sql = "select * from kb_boards where boardid=$boardid"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['boards'] = $results; + $sql = "select * from kb_lists where boardid=$boardid order by listindex"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['lists'] = $results; + $sql = "select userid from kb_boarduser where boardid=$boardid"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['boarduser'] = $results; + } + + if ($this->request->getMethod() === 'post') { + $data = $this->request->getVar(); + $boardid = $data['boardid']; + $boardname = $data['boardname']; + $admin_userid = $data['admin_userid']; + $boarduser = $data['boarduser']; + $nboarduser = implode( ',', $boarduser); + $listid_delete = $data['listid_delete']; + if(isset($data['lists'])) { + $lists = $data['lists']; + $listid = $data['listid']; + } + + $rules = [ + 'boardname' => 'required', + 'admin_userid' => 'required', + 'lists' => 'required' + ]; + + if($this->validate($rules)) { + if($boardid == 0) { + //new board + // board query + $sql = "insert into kb_boards(boardname, admin_userid, createdate) values ( '$boardname', '$admin_userid', NOW() )"; + //echo "
$sql"; + $query = $db->query($sql); + $boardid = $db->insertID(); + //$boardid = "1"; + //echo "
$boardid"; + + // boarduser query + $quser = ''; + foreach($boarduser as $quserid ) { $quser .= "($boardid, $quserid),"; } + $quser = rtrim($quser, ','); + $sql = "insert ignore into kb_boarduser(boardid, userid) values $quser"; + $query = $db->query($sql); + //echo "
$sql"; + + // list query + $qlist = ''; + foreach($lists as $qlistindex => $qlistname) { + $qlistname = $qlistname; + $qlist .= "('$qlistname', $qlistindex, $boardid, NOW()),"; + } + $sql = "insert into kb_lists(listname, listindex, boardid,createdate) values $qlist"; + $sql = rtrim($sql, ','); + //echo "
$sql"; + $query = $db->query($sql); + return view('form_success'); + } else { // edit board + /* + echo "
";
+					print_r($data);
+					echo "
"; + */ + // board query + $sql = "update kb_boards set boardname='$boardname', admin_userid='$admin_userid' where boardid=$boardid "; + //echo "
$sql"; + $query = $db->query($sql); + + // boarduser query + $sql = "delete from kb_boarduser where boardid=$boardid and userid not in ($nboarduser)"; + //echo "
$sql"; + $query = $db->query($sql); + $quser = ''; + foreach($boarduser as $quserid ) { $quser .= "($boardid, $quserid),"; } + $quser = rtrim($quser, ','); + $sql = "insert ignore into kb_boarduser (boardid, userid) values $quser"; + //echo "
$sql"; + $query = $db->query($sql); + + // list query + // delete + if( $data['listid_delete'] != '' ) { + $listid_del = $data['listid_delete']; + $sql = "delete from kb_lists where listid in ($listid_del)"; + //echo "
$sql"; + $query = $db->query($sql); + } + // insert and update + $qlist = ''; + foreach($lists as $qlistindex => $qlistname) { + $qlistid = $listid[$qlistindex]; + if($qlistid == 0) { $qlist .= "('$qlistname', $qlistindex, $boardid, NOW()),"; } + else { + $sql = "update kb_lists set listname='$qlistname', listindex=$qlistindex where listid=$qlistid"; + //echo "
$sql"; + $query = $db->query($sql); + } + } + if($qlist != '') { + $sql = "insert into kb_lists(listname, listindex, boardid,createdate) values $qlist"; + $sql = rtrim($sql, ','); + //echo "
$sql"; + $query = $db->query($sql); + } + return view('form_success'); + } + } else { return view('kb_board_edit', $data); } + } else { + return view('kb_board_edit', $data); + } + } + + public function list_edit($listid) { + $db = \Config\Database::connect(); + $data['listid'] = $listid; + $sql = "select * from kb_lists where listid='$listid'"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['lists'] = $results; + if ($this->request->getMethod() === 'post') { + $data = $this->request->getVar(); + $listname = $data['listname']; + $sql = "update kb_lists set listname='$listname' where listid='$listid'"; + $query = $db->query($sql); + return view('form_success'); + } + return view('kb_list_edit', $data); + } + + public function card_edit($listid, $cardid) { + $db = \Config\Database::connect(); + $data['listid'] = $listid; + $data['cardid'] = $cardid; + $data['card_priorities'] = $this->data['card_priorities']; + + $sql = "select * from users where enddate is null"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['users'] = $results; + + $sql = "select * from kb_lists where boardid=(select boardid from kb_lists where listid=$listid)"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['lists'] = $results; + + if($cardid != 0) { + $sql = "select * from kb_cards where cardid=$cardid"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['cards'] = $results; + } + + if ($this->request->getMethod() === 'post') { + $data = $this->request->getVar(); + $listid = $data['listid']; + $cardid = $data['cardid']; + $cardtext = $data['cardtext']; + $owner_userid = $data['owner_userid']; + $priority = $data['priority']; + $creator_userid = $_SESSION['userid']; + $rules = [ + 'cardtext' => 'required' + ]; + + if($this->validate($rules)) { + if($cardid == 0) { + //new card + $sql = "insert into kb_cards(listid, priority, cardtext, owner_userid, creator_userid, createdate) values ( '$listid', '$priority', '$cardtext', '$owner_userid', '$creator_userid', NOW() )"; + $query = $db->query($sql); + return view('form_success'); + } else { + $sql = "update kb_cards set listid=$listid, priority='$priority', cardtext='$cardtext', owner_userid='$owner_userid' where cardid=$cardid"; + $query = $db->query($sql); + return view('form_success'); + } + } else { + + } + } + return view('kb_card_edit', $data); + } + + public function card_move($listid, $cardid) { + $db = \Config\Database::connect(); + echo "card $cardid, list $listid"; + $sql = "update kb_cards set listid=$listid where cardid=$cardid"; + $query = $db->query($sql); + } +} \ No newline at end of file diff --git a/app/Controllers/Key.php b/app/Controllers/Key.php new file mode 100644 index 0000000..22049f8 --- /dev/null +++ b/app/Controllers/Key.php @@ -0,0 +1,124 @@ +respond([ + 'publicKey' => $publicKey + ]); + } else { + return $this->failNotFound('Public key not found'); + } + } + + public function data() { + $productTempModel = new ProductTempModel; + + $rawData = $this->request->getBody(); + $result = json_decode($rawData, true); + + $encryptedKeyIv = $result['encryptedKeyIv']; + $encryptedKeyIv = base64_decode($encryptedKeyIv); + $encryptedData = $result['encryptedData']; + $clientChecksum = $result['checksum']; + + $privateKeyPath = WRITEPATH . 'key/private_key.pem'; + $privateKey = file_get_contents($privateKeyPath); + $privateKeyResource = openssl_pkey_get_private($privateKey); + + $decryptedMessage = ''; + $result = openssl_private_decrypt($encryptedKeyIv, $decryptedMessage, $privateKeyResource, OPENSSL_PKCS1_OAEP_PADDING); + + if ($result) { + $aesKey = substr($decryptedMessage, 0, 32); + $aesIv = substr($decryptedMessage, 32, 16); + $decryptedBytes = openssl_decrypt($encryptedData, 'aes-256-cbc', $aesKey, 0, $aesIv); + $serverChecksum = hash('sha256', $decryptedBytes); + $decryptedData = json_decode($decryptedBytes, true); + $locationStartDate = $decryptedData['locationstartdate']; + + $warrantyStartDate = DateTime::createFromFormat('Ymd', $locationStartDate); + if ($warrantyStartDate) { + $warrantyEndDate = clone $warrantyStartDate; + $warrantyEndDate->modify('+1 year'); + + $formattedWarrantyEndDate = $warrantyEndDate->format('Y-m-d'); + } else { + $formattedWarrantyEndDate = null; + } + + if ($clientChecksum !== $serverChecksum) { + return $this->fail('Checksum check failed'); + } else { + $logQuery = []; + $db = \Config\Database::connect(); + $db->transStart(); + foreach ($decryptedData['items'] as $value) { + $data = [ + 'productnumber' => $value['productnumber'], + 'productname' => $value['productname'], + 'catalognumber' => $value['catalognumber'], + 'siteid' => 1, + 'locationstartdate' => $locationStartDate, + 'locationenddate' => NULL, + 'installationdate' => NULL, + 'warrantystartdate' => $locationStartDate, + 'warrantyenddate' => $formattedWarrantyEndDate, + 'active' => 'N', + 'owner' => 1, + 'statusservice' => 2, + 'statusparts' => '', + 'userid' => 'SES^' . $decryptedData['userid'], + 'reference' => $decryptedData['reference'], + 'logdate' => $decryptedData['logdate'], + ]; + + if ($productTempModel->save($data)) { + $logQuery[] = [ + 'item' => $value['catalognumber'], + 'status' => 'success', + 'message' => 'Item saved successfully' + ]; + } else { + $errors = $productTempModel->errors(); + $logQuery[] = [ + 'item' => $value['catalognumber'], + 'status' => 'fail', + 'message' => 'Failed to save item', + 'errors' => $errors + ]; + $db->transRollback(); + return $this->response->setJSON([ + 'success' => false, + 'message' => 'Failed to insert all items. Transaction rolled back.', + 'results' => $logQuery + ]); + } + + } + + $db->transCommit(); + return $this->response->setJSON([ + 'success' => true, + 'message' => 'Processing completed', + 'results' => $logQuery + ]); + } + } + } +} \ No newline at end of file diff --git a/app/Controllers/Lqms.php b/app/Controllers/Lqms.php new file mode 100644 index 0000000..ddbff7d --- /dev/null +++ b/app/Controllers/Lqms.php @@ -0,0 +1,46 @@ +query($sql); + $results = $query->getResultArray(); + $data['logs'] = $results; + return view('lqms_index', $data); + } + + public function postData() { + $db = \Config\Database::connect(); + $post = $this->request->getJSON(); + $sql = "insert into lqms_log(message) values(".$db->escape(json_encode($post)).")"; + $query = $db->query($sql); + $data['post'] = $post; + echo "$sql"; + //return $this->respond($data); + /* + echo "
";
+		print_r(json_encode($post));
+		echo "
"; + */ + } + + public function log_clear() { + $db = \Config\Database::connect(); + $sql = "DELETE FROM lqms_log"; + $query = $db->query($sql); + } + + public function log_delete($mesid=null) { + $db = \Config\Database::connect(); + $sql = "DELETE FROM lqms_log where mesid=$mesid"; + $query = $db->query($sql); + } +} \ No newline at end of file diff --git a/app/Controllers/ProductCatalog.php b/app/Controllers/ProductCatalog.php index 7455080..1dbd50c 100644 --- a/app/Controllers/ProductCatalog.php +++ b/app/Controllers/ProductCatalog.php @@ -106,7 +106,7 @@ class ProductCatalog extends Controller { $data['productalias'] = $results; if ($this->request->getMethod() === 'post') { $rules = [ - 'catalognumber' => 'required', + 'catalognumber' => 'required|is_unique[productcatalog.catalognumber]', 'productname' => 'required', 'producttypeid' => 'required', 'vendorid' => 'required' diff --git a/app/Controllers/ProductTemp.php b/app/Controllers/ProductTemp.php new file mode 100644 index 0000000..9dfbb50 --- /dev/null +++ b/app/Controllers/ProductTemp.php @@ -0,0 +1,150 @@ +select('producttemp.*, productcatalog.producttypeid') + ->join('productcatalog', 'producttemp.catalognumber = productcatalog.catalognumber') + ->whereIn('productcatalog.producttypeid', $productTypeIds) + ->where('producttemp.logdate >=', date('Y-m-d', strtotime('-30 days'))) + ->where('producttemp.logdate <=', date('Y-m-d', strtotime('+3 days'))) + ->findAll(); + + $merged_data = []; + foreach ($productTemps as $productTemp) { + $productnumber = $productTemp['productnumber']; + $catalognumber = $productTemp['catalognumber']; + + $duplicates = $productsModel + ->select('products.*, productcatalog.catalognumber') + ->join('productcatalog', 'products.catalogid = productcatalog.catalogid') + ->where('products.productnumber', $productnumber) + ->where('productcatalog.catalognumber', $catalognumber) + ->findAll(); + + if ($duplicates) { + $productTemp['duplicates'] = $duplicates; + } else { + $productTemp['duplicates'] = null; + } + + $merged_data[] = $productTemp; + } + + $data['products'] = $merged_data; + // dd($data); + return view('producttemp_index', $data); + } + + public function getdata($id) { + $model = new ProductTempModel(); + $result = $model->find($id); + + if ($result) { + return $this->response->setJSON($result); + } else { + return $this->response->setStatusCode(404)->setJSON(['error' => 'Data not found']); + } + } + + public function edit() { + $id = $this->request->getPost('edit-productid'); + + $data = [ + 'productnumber' => $this->request->getPost('edit-productnumber'), + 'productname' => $this->request->getPost('edit-productname'), + 'catalognumber' => $this->request->getPost('edit-catalognumber'), + 'locationstartdate' => $this->request->getPost('edit-locationstartdate') ?: null, + 'locationenddate' => $this->request->getPost('edit-locationenddate') ?: null, + 'warrantystartdate' => $this->request->getPost('edit-warrantystartdate') ?: null, + 'warrantyenddate' => $this->request->getPost('edit-warrantyenddate') ?: null, + 'active' => $this->request->getPost('edit-active'), + 'statusservice' => $this->request->getPost('edit-statusservice'), + 'statusparts' => $this->request->getPost('edit-statusparts'), + ]; + // dd($data); + $model = new ProductTempModel(); + $model->update($id, $data); + return redirect()->to('/producttemp')->with('success', 'Product updated'); + } + + public function deleteItem($productid) { + $model = new ProductTempModel(); + $result = $model->find($productid); + if($result) { + $model->delete($productid); + return redirect()->to('/producttemp')->with('success', 'Product deleted'); + } + } + + public function validateItem() { + $productTempModel = new ProductTempModel(); + $productsModel = new ProductsModel(); + $productCatalogModel = new ProductCatalogModel(); + + $productTempId = $this->request->getPost('producttemp-productid'); + $productId = $this->request->getPost('product-productid') ?? null; + + $dataProductTemp = $productTempModel->find($productTempId); + + $catalognumber = $dataProductTemp['catalognumber']; + $productCatalogData = $productCatalogModel->where('catalognumber', $catalognumber)->first(); + + if ($productId) { + if ($productCatalogData) { + $data = [ + 'productnumber' => $dataProductTemp['productnumber'], + // 'productname' => $dataProductTemp['productname'], + 'catalogid' => $productCatalogData['catalogid'], + 'siteid' => $dataProductTemp['siteid'], + 'locationstartdate' => $dataProductTemp['locationstartdate'], + 'locationenddate' => $dataProductTemp['locationenddate'], + 'warrantystartdate' => $dataProductTemp['warrantystartdate'], + 'warrantyenddate' => $dataProductTemp['warrantyenddate'], + 'productowner' => $dataProductTemp['owner'], + ]; + $productsModel->update($productId, $data); + $productTempModel->delete($productTempId); + session()->setFlashdata('success', 'Product updated in product table!'); + } else { + session()->setFlashdata('error', 'Data not exist on Product Catalog table'); + } + } else { + if ($productCatalogData) { + $data = [ + 'productnumber' => $dataProductTemp['productnumber'], + // 'productname' => $dataProductTemp['productname'], + 'catalogid' => $productCatalogData['catalogid'], + 'siteid' => $dataProductTemp['siteid'], + 'locationstartdate' => $dataProductTemp['locationstartdate'], + 'locationenddate' => $dataProductTemp['locationenddate'], + 'warrantystartdate' => $dataProductTemp['warrantystartdate'], + 'warrantyenddate' => $dataProductTemp['warrantyenddate'], + 'productowner' => $dataProductTemp['owner'], + 'createdate' => date('Y-m-d'), + ]; + $productsModel->insert($data); + $productTempModel->delete($productTempId); + session()->setFlashdata('success', 'Product moved to product table!'); + } else { + session()->setFlashdata('error', 'Data not exist on Product Catalog table'); + } + } + + return redirect()->to('/producttemp'); + } +} \ No newline at end of file diff --git a/app/Controllers/Products.php b/app/Controllers/Products.php index 9c984f6..d0a1b40 100644 --- a/app/Controllers/Products.php +++ b/app/Controllers/Products.php @@ -13,6 +13,28 @@ class Products extends BaseController { function __construct() { $this->data['productowners'] = array('S'=>'Summit', 'C'=> 'Customer', 'O' => 'Other'); } + + // Get Data Dari CLQMS untuk MEAN Jumlah Test Selama 6 Bulan + private function getPatresCount($pr_number_link) { + + if ($pr_number_link != "") { + $curl = curl_init(); + + curl_setopt_array($curl, array( + CURLOPT_URL => 'https://clqms.services-summit.my.id/api_service/count_patres'.$pr_number_link, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'GET', + )); + + $response = curl_exec($curl); + curl_close($curl); + $data = json_decode($response, true); + + return $data; + } + + } public function index() { $db = \Config\Database::connect(); @@ -58,11 +80,16 @@ class Products extends BaseController { $where = 0; - $sql = "SELECT p.productid, pc.productname, p.productnumber, p.createdate, s.sitename, pt.producttypeid, pt.texts + $sql = "SELECT p.productid, p.installationdate ,pc.productname, pc.productaliasid, p.productnumber, s.sitename, pt.producttypeid, pt.texts, + z.zonename as city, z2.zonename as prov FROM products p left join productcatalog pc on pc.catalogid=p.catalogid left join producttype pt on pt.producttypeid=pc.producttypeid - left join sites s on s.siteid=p.siteid"; + left join sites s on s.siteid=p.siteid + left join accounts a on a.accountid=s.accountid + left join zones z on z.zoneid=a.zoneid + left join zones z2 on z2.zoneid=z.parentzoneid + "; if($productaliasid != 0) { if($where == 0) { $sql .=" where "; $where++; } @@ -88,10 +115,25 @@ class Products extends BaseController { $sql.= "$sitenamequery"; } + $sql.=" ORDER BY p.installationdate DESC "; + $data['sql']=$sql; $query = $db->query($sql); $results = $query->getResultArray(); $data['products'] = $results; + + // // Untuk CLQMS Patres Count Rata-Rata Bulanan + // $pr_number_link = ""; + // foreach ($data['products'] as $value) { + // // 20 adalah kode TMS-30i + // if ($value['productaliasid'] == '20') { + // $pr_number_link .= "/" . $value['productnumber']; + // } + // } + // if ($pr_number_link != "") { + // $data['testCountCLQMS'] = $this->getPatresCount($pr_number_link); + // } + } return view('products_index', $data); } @@ -138,7 +180,7 @@ class Products extends BaseController { $results = $query->getResultArray(); $data['productcatalog'] = $results; - $sql = "select * from sites"; + $sql = "select * from sites where enddate is null"; $query = $db->query($sql); $results = $query->getResultArray(); $data['sites'] = $results; @@ -222,6 +264,7 @@ class Products extends BaseController { $data['productowners'] = $this->data['productowners']; if ($this->request->getMethod() === 'post') { + $rules = [ 'productid' => 'required', 'siteid' => 'required', @@ -230,24 +273,30 @@ class Products extends BaseController { 'productowner' => 'required', ]; $data['new_value'] = [ + 'productnumb' => $this->request->getVar('productnumb'), + 'productnam' => $this->request->getVar('productnam'), 'productid' => $this->request->getVar('productid'), 'siteid' => $this->request->getVar('siteid'), 'oldlocationenddate' => $this->request->getVar('oldlocationenddate'), 'newlocationstartdate' => $this->request->getVar('newlocationstartdate'), 'productowner' => $this->request->getVar('productowner') ]; + if($this->validate($rules)){ + $productid = $data['new_value']['productid']; $siteid = $data['new_value']['siteid']; $oldlocationenddate = $data['new_value']['oldlocationenddate']; $newlocationstartdate = $data['new_value']['newlocationstartdate']; $productowner = $data['new_value']['productowner']; + // products_log $sql = "INSERT INTO products_log (productid, siteid, catalogid, locationstartdate, locationenddate, installationdate, warrantystartdate, warrantyenddate, productowner, productserviceid, statuspart, logdate ) SELECT productid, siteid,catalogid, locationstartdate, '$oldlocationenddate', installationdate, warrantystartdate, warrantyenddate, productowner, productserviceid, statuspart, NOW() FROM products WHERE productid='$productid'"; $query = $db->query($sql); + // products $sql = "update products set siteid='$siteid', locationstartdate='$newlocationstartdate', productowner='$productowner' where productid='$productid'"; $query = $db->query($sql); @@ -399,4 +448,79 @@ class Products extends BaseController { $query = $db->query($sql); //echo "$sql"; } + + public function exportdata() { + + $db = \Config\Database::connect(); + + $productaliasid = $this->request->getGet('productaliasid'); + $areaid = $this->request->getGet('areaid'); + $producttypeid = $this->request->getGet('producttypeid'); + $sitename = $this->request->getGet('sitename'); + + + $areaquery = ''; + if($areaid != '') { $areaquery = " s.siteid in (select siteid from v_siteaccount where areaid='$areaid') "; } + + $producttypequery = ''; + if($producttypeid != '') { $producttypequery = " pt.producttypeid='$producttypeid' "; } + + $sitenamequery = ''; + if($sitename!= '') { + $sitename = strtolower($sitename); + $sitenamequery= " lower(s.sitename) like '%$sitename%' "; + } + + $where = 0; + + $sql = "SELECT a2.accountname, p.statuspart, ps.productservicetext, p.productid, pc.productname, p.productnumber, pc.catalognumber, pt.texts as type_name, pc.manufacturer, s.sitename, + z.zonename as city, z2.zonename as prov, p.installationdate, p.locationstartdate, p.locationenddate, p.warrantystartdate, p.warrantyenddate + FROM products p + left join productcatalog pc on pc.catalogid=p.catalogid + + -- left join accoun pc2 on pc2.catalogid=p.accountid_productowner + + left join producttype pt on pt.producttypeid=pc.producttypeid + left join productservice ps on ps.productserviceid=p.productserviceid + left join sites s on s.siteid=p.siteid + left join accounts a on a.accountid=s.accountid + left join accounts a2 on a2.accountid=p.accountid_productowner + left join zones z on z.zoneid=a.zoneid + left join zones z2 on z2.zoneid=z.parentzoneid + "; + + if($productaliasid != 0) { + if($where == 0) { $sql .=" where "; $where++; } + else { $sql .=" and "; } + $sql.= "pc.productaliasid='$productaliasid'"; + } + + if($areaquery != '') { + if($where == 0) { $sql .=" where "; $where++; } + else { $sql .=" and "; } + $sql.= "$areaquery"; + } + + if($producttypequery != '') { + if($where == 0) { $sql .=" where "; $where++; } + else { $sql .=" and "; } + $sql.= "$producttypequery"; + } + + if($sitenamequery != '') { + if($where == 0) { $sql .=" where "; $where++; } + else { $sql .=" and "; } + $sql.= "$sitenamequery"; + } + + $sql.=" ORDER BY p.installationdate DESC"; + + $data['sql']=$sql; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['products'] = $results; + + return view('products_export_excel', $data); + + } } \ No newline at end of file diff --git a/app/Controllers/Sites.php b/app/Controllers/Sites.php index 08d6ade..692b632 100644 --- a/app/Controllers/Sites.php +++ b/app/Controllers/Sites.php @@ -32,7 +32,7 @@ class Sites extends BaseController { public function view($siteid = null) { $db = \Config\Database::connect(); - $sql = "SELECT s.`siteid`, s.`sitename`, a.`accountname`, + $sql = "SELECT s.`siteid`, s.`sitename`, a.`accountname`, a.`initial`, concat(u.`firstname`,' ',u.lastname) as marketing, s.createdate FROM sites s LEFT JOIN accounts a ON a.`accountid`=s.`accountid` @@ -64,7 +64,7 @@ class Sites extends BaseController { } //$sql = "SELECT accountid, accountname FROM accounts WHERE parentaccount='0'"; - $sql = "SELECT accountid, accountname FROM accounts"; + $sql = "SELECT accountid, accountname, initial FROM accounts"; $query = $db->query($sql); $results = $query->getResultArray(); $data['accounts'] = $results; @@ -88,6 +88,7 @@ class Sites extends BaseController { 'userid' => $this->request->getVar('userid'), 'userstartdate' => $this->request->getVar('startdate'), ]; + if($this->validate($rules)){ // User yang sudah ada @@ -180,22 +181,24 @@ class Sites extends BaseController { $userid = $results[0]['userid']; $userstartdate = $results[0]['userstartdate']; - // Get Full Name Form User - $sql = "SELECT CONCAT(firstname, ' ', lastname) as fullname FROM users WHERE userid = $userid"; - $query = $db->query($sql); - $results = $query->getResultArray(); - $username = $results[0]['fullname']; - - // Insert Data For Sites Log - $data['log_sites'] = [ - 'siteid' => $site_id, - 'user' => $username, - 'userstartdate' => $userstartdate - ]; - $sitesLogModel = new SitesLogModel(); - $sitesLogModel->set('createdate', 'NOW()', FALSE); - $sitesLogModel->insert($data['log_sites']); + // Kondisi untuk form marketing jika diisi + if ($userid != 0) { + // Get Full Name Form User + $sql = "SELECT CONCAT(firstname, ' ', lastname) as fullname FROM users WHERE userid = $userid"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $username = $results[0]['fullname']; + // Insert Data For Sites Log + $data['log_sites'] = [ + 'siteid' => $site_id, + 'user' => $username, + 'userstartdate' => $userstartdate + ]; + $sitesLogModel = new SitesLogModel(); + $sitesLogModel->set('createdate', 'NOW()', FALSE); + $sitesLogModel->insert($data['log_sites']); + } return view('form_success'); } } else { diff --git a/app/Controllers/UnitGroup.php b/app/Controllers/UnitGroup.php index 772ea7c..64ea279 100644 --- a/app/Controllers/UnitGroup.php +++ b/app/Controllers/UnitGroup.php @@ -53,7 +53,7 @@ class UnitGroup extends BaseController { return view('form_success'); } else { $model = new UnitGroupModel(); - $model->set('createdate', 'NOW()', FALSE); + $model->set('logdate', 'NOW()', FALSE); $model->insert($data['new_value']); return view('form_success'); } @@ -64,4 +64,15 @@ class UnitGroup extends BaseController { } return view('unitgroup_editor', $data); } + + public function toggle($unitgroupid = 0) { + $db = \Config\Database::connect(); + $sql = "update unitgroup set enddate= + case when enddate is not null then null + else NOW() + end + where unitgroupid ='$unitgroupid'"; + if($db->query($sql)) { return view('form_success'); } + else { return view('form_fail'); } + } } \ No newline at end of file diff --git a/app/Filters/Cors.php b/app/Filters/Cors.php new file mode 100644 index 0000000..36947ac --- /dev/null +++ b/app/Filters/Cors.php @@ -0,0 +1,26 @@ +getMethod() === 'options') { + // header('HTTP/1.1 200 OK'); + // exit(); + // } + } + + public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) + { + // No actions required after the request + } +} diff --git a/app/Models/ProductTempModel.php b/app/Models/ProductTempModel.php new file mode 100644 index 0000000..37bfd21 --- /dev/null +++ b/app/Models/ProductTempModel.php @@ -0,0 +1,12 @@ +where('email_1', $data['email'])->first(); - - if (!$user) { return false; } - - return password_verify($data['password'], $user['password']); - } -} \ No newline at end of file diff --git a/app/Views/accounts_index.php b/app/Views/accounts_index.php index 63ac158..7b6ad76 100644 --- a/app/Views/accounts_index.php +++ b/app/Views/accounts_index.php @@ -68,7 +68,7 @@ if(!isset($areaid)) {$areaid = '';}
- + > - + "; +} else { + $purposecolumn = " "; +} + ?> + + +
+
+
+ +
+
+

SERVICE REPORT

+ Report# +
+
+ +
Name Initial Parent Area Create date Name Parent Area Create date
section('content') ?>

+Terimakasih
Salam,
$username

@@ -18,8 +20,6 @@ $offaddress
Phone : $offphone
Email : $email_1

-Terimakasih
-

"; $emailoption = ''; diff --git a/app/Views/activities_content.php b/app/Views/activities_content.php index f96fdb0..8e13ab1 100644 --- a/app/Views/activities_content.php +++ b/app/Views/activities_content.php @@ -18,6 +18,12 @@ $action = $activities[0]['action']; $subject = $activities[0]['subject']; $acttypecode = $activities[0]['acttypecode']; +if(isset($invtrans[0]['purpose'])) { + $purposecolumn = "
Purpose
+ + + + + + + + + + + + + + + +
Customer : Service requested by :
Model : Service Open :
Sw. Version : Service Close :
Serial# :
+
+ + + + + + "; + } + ?> +
Subject :
$acttextname : $textvalue
+ +

Spare Part Usage :

+ + + + + + + + + + + "; + } + ?> +
Catalog# Product Lot# Qty. Unit Purpose
$catalognumber $productname $lotnumber $qty $unit $purpose
+ +
+
+
+ Technical Support +
+
+ Customer +
+
+

+ PT. SUMBERMITRA AGUNGJAYA
+ Gading Bukit Indah Blok H/3, Kelapa Gading Permai, Jakarta 14240
+ Telp : 62-21-4516728, Fax : 62-21-45840240 +

+
+ + \ No newline at end of file diff --git a/app/Views/clqms_index.php b/app/Views/clqms_index.php new file mode 100644 index 0000000..3dcacd5 --- /dev/null +++ b/app/Views/clqms_index.php @@ -0,0 +1,54 @@ +extend('layouts/main.php') ?> + +section('content') ?> + +
+
+
+
+

Product / Instrument List

+
+
+ +
+
+
+
+
+ + + + + + + + "; + } + ?> + +
Site Products
$qproductid $qsitename $qproductname ($qproductnumber)View
+
+
+
+
+
+
+
+endSection() ?> + +section('script') ?> +endSection() ?> \ No newline at end of file diff --git a/app/Views/components/modal.php b/app/Views/components/modal.php new file mode 100644 index 0000000..5640edf --- /dev/null +++ b/app/Views/components/modal.php @@ -0,0 +1,17 @@ + + \ No newline at end of file diff --git a/app/Views/components/offcanvas.php b/app/Views/components/offcanvas.php new file mode 100644 index 0000000..9e904dc --- /dev/null +++ b/app/Views/components/offcanvas.php @@ -0,0 +1,13 @@ + +
+
+
Edit Product
+ +
+
+
+ Fetching data . . . + +
+
+
\ No newline at end of file diff --git a/app/Views/dashboard_recent_act.php b/app/Views/dashboard_recent_act.php index a85aea6..b75fd38 100644 --- a/app/Views/dashboard_recent_act.php +++ b/app/Views/dashboard_recent_act.php @@ -63,6 +63,8 @@ else if($activitystatus == "C") { echo ""; } else if($activitystatus == "R") { echo ""; } else if($activitystatus == "P") { echo ""; } + else if($activitystatus == "S") { echo ""; } + else if($activitystatus == "D") { echo ""; } ?> Open :
Close : @@ -127,6 +129,8 @@ else if($activitystatus == "C") { echo ""; } else if($activitystatus == "R") { echo ""; } else if($activitystatus == "P") { echo ""; } + else if($activitystatus == "S") { echo ""; } + else if($activitystatus == "D") { echo ""; } ?> Open :
Close : @@ -191,6 +195,8 @@ else if($activitystatus == "C") { echo ""; } else if($activitystatus == "R") { echo ""; } else if($activitystatus == "P") { echo ""; } + else if($activitystatus == "S") { echo ""; } + else if($activitystatus == "D") { echo ""; } ?> Open :
Close : @@ -255,6 +261,8 @@ else if($activitystatus == "C") { echo ""; } else if($activitystatus == "R") { echo ""; } else if($activitystatus == "P") { echo ""; } + else if($activitystatus == "S") { echo ""; } + else if($activitystatus == "D") { echo ""; } ?> Open :
Close : diff --git a/app/Views/invtrans_index.php b/app/Views/invtrans_index.php index c4a26aa..b8a9f09 100644 --- a/app/Views/invtrans_index.php +++ b/app/Views/invtrans_index.php @@ -55,6 +55,7 @@
+
@@ -74,10 +75,12 @@ $origin = $data['origin']; $dest = $data['dest']; if($actid != $actid1) { - echo ""; + echo " + + "; $actid1 = $actid; } - echo ""; + echo ""; } ?> @@ -103,6 +106,14 @@ $(function () { }); }); +function exportToExcel() { + var tableElement = document.getElementById("myTable"); + var wb = XLSX.utils.book_new(); + var ws = XLSX.utils.table_to_sheet(tableElement); + XLSX.utils.book_append_sheet(wb, ws, "My Data"); + XLSX.writeFile(wb, "reportTransactions.xlsx"); +} + endSection() ?> \ No newline at end of file diff --git a/app/Views/kanban_index.php.bak b/app/Views/kanban_index.php.bak new file mode 100644 index 0000000..6724cf5 --- /dev/null +++ b/app/Views/kanban_index.php.bak @@ -0,0 +1,180 @@ +extend('layouts/main.php') ?> + +section('content') ?> + + +
+
+
+
+

+ Kanban Board + + +

+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
To-Do
+
+
+
+
+
Low
+
+
+
TOS mengambil data dari alat user
+
+ +
+
+
+
Low
+
+
+
Data apalagi yang akan diambil dan query nya
+
+ +
+
+
+
Low
+
+
+
Buat rest client / aplikasi pengirim data dari masing2 pc
+
+ +
+
+
+
Low
+
+
+
Front-end LQMS
+
+ +
+
+
+
Low
+
+
+
Back-end LQMS
+
+ +
+
+
+
Low
+
+
+
Persiapan infrastruktur / hardware / software
+
+ +
+
+
+
Low
+
+
+
Security
+
+ +
+
+
+
Low
+
+
+
Enkripsi JSON
+
+ +
+
+
+
+
+
+
+
+
In Progress
+
+
+ +
+
+
+
+
+
+
+
Done
+
+
+
+
+
+
+
+
+
+endSection() ?> + +section('script') ?> + + +endSection() ?> \ No newline at end of file diff --git a/app/Views/kb_board_edit.php b/app/Views/kb_board_edit.php new file mode 100644 index 0000000..f992819 --- /dev/null +++ b/app/Views/kb_board_edit.php @@ -0,0 +1,217 @@ +extend('layouts/form.php') ?> + +section('content') ?> + +
+

Board Editor

+
+ +
+ listErrors(); ?> + +
+ + + +
+
Board name
+
+
+
+
Board admin
+
+ +
+
+
+
Board users
+
+ +
+
+

Board List

+ +
+
New List
+
+
+ +
+ +
+
+
+
+
$actid - $subject ($username)
$actid - $subject ($username)
$catalognumber $productname $qty $unit $lotnumber $origin $dest
$catalognumber $productname $qty $unit $lotnumber $origin $dest
+ + + + + + + +
+ + + + +
+ + + +
+endSection() ?> + +section('script') ?> + +endSection() ?> \ No newline at end of file diff --git a/app/Views/kb_card_edit.php b/app/Views/kb_card_edit.php new file mode 100644 index 0000000..e563cdf --- /dev/null +++ b/app/Views/kb_card_edit.php @@ -0,0 +1,83 @@ +extend('layouts/form.php') ?> + +section('content') ?> + +
+

Card Editor

+
+ +
+ listErrors(); ?> + +
+ +
+ +
+
List
+
+ +
+
Priority
+
+ +
+
+
+
Card Owner
+
+ +
+
+
+
Card text
+
+
+ +
+
+endSection() ?> \ No newline at end of file diff --git a/app/Views/kb_index.php b/app/Views/kb_index.php new file mode 100644 index 0000000..8e1bacd --- /dev/null +++ b/app/Views/kb_index.php @@ -0,0 +1,27 @@ +extend('layouts/main.php') ?> + +section('content') ?> +
+
+
+
+

+ Kanban Board +

+
+
+
+ +
+
+
+endSection() ?> \ No newline at end of file diff --git a/app/Views/kb_list_edit.php b/app/Views/kb_list_edit.php new file mode 100644 index 0000000..e2990a2 --- /dev/null +++ b/app/Views/kb_list_edit.php @@ -0,0 +1,32 @@ +extend('layouts/form.php') ?> + +section('content') ?> + +
+

List Editor

+
+ +
+ listErrors(); ?> + +
+ +
+ +
+
List Name
+
+
+ +
+
+endSection() ?> \ No newline at end of file diff --git a/app/Views/kb_view.php b/app/Views/kb_view.php new file mode 100644 index 0000000..8fb6af2 --- /dev/null +++ b/app/Views/kb_view.php @@ -0,0 +1,137 @@ +extend('layouts/main.php') ?> + +section('content') ?> + + + +
+
+
+
+

+ Kanban Board - +

+
+
+ +
+
+ +
+ +
+
+
+
+
+
+ +
+
+
+
+ + +
+
+
+
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+
+
+endSection() ?> + +section('script') ?> + + +endSection() ?> \ No newline at end of file diff --git a/app/Views/layouts/_sidebar.php b/app/Views/layouts/_sidebar.php index 0699ffe..886224d 100644 --- a/app/Views/layouts/_sidebar.php +++ b/app/Views/layouts/_sidebar.php @@ -7,15 +7,16 @@ ?>
  • +
  • +
  • @@ -60,6 +62,7 @@
  • Product Service
  • Product Catalog
  • Product Alias
  • +
  • Product Temp
  • Unit Group
  • Products
  • @@ -121,6 +124,7 @@
  • +
  • get('level') == '4' ) { // PS /* @@ -183,6 +187,7 @@
  • +
  • @@ -213,6 +218,7 @@
  • Bug Count
  • +
  • diff --git a/app/Views/layouts/form.php b/app/Views/layouts/form.php index dd62f2d..dd34dbd 100644 --- a/app/Views/layouts/form.php +++ b/app/Views/layouts/form.php @@ -11,6 +11,7 @@ +