init
This commit is contained in:
148
.env
Normal file
148
.env
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Example Environment Configuration file
|
||||||
|
#
|
||||||
|
# This file can be used as a starting point for your own
|
||||||
|
# custom .env files, and contains most of the possible settings
|
||||||
|
# available in a default install.
|
||||||
|
#
|
||||||
|
# By default, all of the settings are commented out. If you want
|
||||||
|
# to override the setting, you must un-comment it by removing the '#'
|
||||||
|
# at the beginning of the line.
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# ENVIRONMENT
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# CI_ENVIRONMENT = production
|
||||||
|
CI_ENVIRONMENT = development
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# APP
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
app.baseURL = 'https://project.adhivasindo.co.id/api_tambang_ntb/'
|
||||||
|
# Base URL khusus aset publik (image/pdf decode).
|
||||||
|
app.assetBaseURL = 'https://project.adhivasindo.co.id/api_tambang_ntb/'
|
||||||
|
# If you have trouble with `.`, you could also use `_`.
|
||||||
|
# app_baseURL = ''
|
||||||
|
# app.forceGlobalSecureRequests = false
|
||||||
|
# app.CSPEnabled = false
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# DATABASE
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
database.default.hostname = localhost
|
||||||
|
database.default.database = stock_map
|
||||||
|
database.default.username = postgres
|
||||||
|
database.default.password = yoga21
|
||||||
|
database.default.DBDriver = Postgre
|
||||||
|
database.default.DBPrefix =
|
||||||
|
database.default.port = 5432
|
||||||
|
|
||||||
|
# database.tests.hostname = localhost
|
||||||
|
# database.tests.database = ci4_test
|
||||||
|
# database.tests.username = root
|
||||||
|
# database.tests.password = root
|
||||||
|
# database.tests.DBDriver = MySQLi
|
||||||
|
# database.tests.DBPrefix =
|
||||||
|
# database.tests.port = 3306
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# CONTENT SECURITY POLICY
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# contentsecuritypolicy.reportOnly = false
|
||||||
|
# contentsecuritypolicy.defaultSrc = 'none'
|
||||||
|
# contentsecuritypolicy.scriptSrc = 'self'
|
||||||
|
# contentsecuritypolicy.styleSrc = 'self'
|
||||||
|
# contentsecuritypolicy.imageSrc = 'self'
|
||||||
|
# contentsecuritypolicy.baseURI = null
|
||||||
|
# contentsecuritypolicy.childSrc = null
|
||||||
|
# contentsecuritypolicy.connectSrc = 'self'
|
||||||
|
# contentsecuritypolicy.fontSrc = null
|
||||||
|
# contentsecuritypolicy.formAction = null
|
||||||
|
# contentsecuritypolicy.frameAncestors = null
|
||||||
|
# contentsecuritypolicy.frameSrc = null
|
||||||
|
# contentsecuritypolicy.mediaSrc = null
|
||||||
|
# contentsecuritypolicy.objectSrc = null
|
||||||
|
# contentsecuritypolicy.pluginTypes = null
|
||||||
|
# contentsecuritypolicy.reportURI = null
|
||||||
|
# contentsecuritypolicy.sandbox = false
|
||||||
|
# contentsecuritypolicy.upgradeInsecureRequests = false
|
||||||
|
# contentsecuritypolicy.styleNonceTag = '{csp-style-nonce}'
|
||||||
|
# contentsecuritypolicy.scriptNonceTag = '{csp-script-nonce}'
|
||||||
|
# contentsecuritypolicy.autoNonce = true
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# COOKIE
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# cookie.prefix = ''
|
||||||
|
# cookie.expires = 0
|
||||||
|
# cookie.path = '/'
|
||||||
|
# cookie.domain = ''
|
||||||
|
# cookie.secure = false
|
||||||
|
# cookie.httponly = false
|
||||||
|
# cookie.samesite = 'Lax'
|
||||||
|
# cookie.raw = false
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# ENCRYPTION
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# encryption.key =
|
||||||
|
# encryption.driver = OpenSSL
|
||||||
|
# encryption.blockSize = 16
|
||||||
|
# encryption.digest = SHA512
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# HONEYPOT
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# honeypot.hidden = 'true'
|
||||||
|
# honeypot.label = 'Fill This Field'
|
||||||
|
# honeypot.name = 'honeypot'
|
||||||
|
# honeypot.template = '<label>{label}</label><input type="text" name="{name}" value=""/>'
|
||||||
|
# honeypot.container = '<div style="display:none">{template}</div>'
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# SECURITY
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# security.csrfProtection = 'cookie'
|
||||||
|
# security.tokenRandomize = false
|
||||||
|
# security.tokenName = 'csrf_token_name'
|
||||||
|
# security.headerName = 'X-CSRF-TOKEN'
|
||||||
|
# security.cookieName = 'csrf_cookie_name'
|
||||||
|
# security.expires = 7200
|
||||||
|
# security.regenerate = true
|
||||||
|
# security.redirect = false
|
||||||
|
# security.samesite = 'Lax'
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# SESSION
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# session.driver = 'CodeIgniter\Session\Handlers\FileHandler'
|
||||||
|
# session.cookieName = 'ci_session'
|
||||||
|
# session.expiration = 7200
|
||||||
|
# session.savePath = null
|
||||||
|
# session.matchIP = false
|
||||||
|
# session.timeToUpdate = 300
|
||||||
|
# session.regenerateDestroy = false
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# LOGGER
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# logger.threshold = 4
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# CURLRequest
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# curlrequest.shareOptions = true
|
||||||
|
|
||||||
|
LINK_FORGOT_PASSWORD = 'http://project.adhivasindo.co.id/ntb/e-teguran-humanis/'
|
||||||
121
.gitignore
vendored
Normal file
121
.gitignore
vendored
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
#-------------------------
|
||||||
|
# Operating Specific Junk Files
|
||||||
|
#-------------------------
|
||||||
|
|
||||||
|
# Dhiva Poject
|
||||||
|
app/Config/Database.php
|
||||||
|
app/Config/ExternalApi.php
|
||||||
|
app/Config/MongoConfig.php
|
||||||
|
writable/
|
||||||
|
composer.lock
|
||||||
|
|
||||||
|
# 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
|
||||||
|
#-------------------------
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
/.phpunit.*.cache
|
||||||
22
LICENSE
Normal file
22
LICENSE
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||||
|
Copyright (c) 2019-2023 CodeIgniter Foundation
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
171
README.md
Normal file
171
README.md
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
# Codeigniter 4 Dhiva
|
||||||
|
|
||||||
|
Custom APP Codeigniter 4
|
||||||
|
|
||||||
|
## Requitment
|
||||||
|
|
||||||
|
PHP Versi :
|
||||||
|
|
||||||
|
PHP 7.4 keatas
|
||||||
|
|
||||||
|
php.ini extension :
|
||||||
|
|
||||||
|
extension=intl
|
||||||
|
extension=php_gmp
|
||||||
|
extension=php_pgsql
|
||||||
|
extension=php_pdo_pgsql
|
||||||
|
extension=php_sockets
|
||||||
|
extension=gd
|
||||||
|
extension=zip
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Pembuatan Controller dan Model secara otomatis
|
||||||
|
- CMD environment
|
||||||
|
- APP ID Generate
|
||||||
|
- Coffee Maker
|
||||||
|
|
||||||
|
## Setup Database
|
||||||
|
|
||||||
|
- Buat terlebih dahulu database untuk project yang ingin dibangun
|
||||||
|
- Jika menggunakan `Postgre`
|
||||||
|
Tentukan `Username`, `Password`,`Database`, dan `Schema`
|
||||||
|
- Jika menggunakan `Mysql`
|
||||||
|
Tentukan `Username`, `Password`, dan `Database`
|
||||||
|
|
||||||
|
## Run Locally
|
||||||
|
|
||||||
|
Kloning project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@bitbucket.org:adhivasindo-prodev/base-ci4.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Pindah ke Folder
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd base-ci4
|
||||||
|
```
|
||||||
|
|
||||||
|
Update dependensi
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer update
|
||||||
|
```
|
||||||
|
<br><hr><br>
|
||||||
|
### Inisialisasi Core
|
||||||
|
<b>(Berlaku di sisi server dan developer)</b>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Jalankan perintah ini di CMD
|
||||||
|
```bash
|
||||||
|
php spark sebat kuy
|
||||||
|
```
|
||||||
|
|
||||||
|
Disini perlu menentukan database yang ingin di gunakan
|
||||||
|
```
|
||||||
|
Database Driver
|
||||||
|
[0] MySQLi
|
||||||
|
[1] Postgre
|
||||||
|
```
|
||||||
|
|
||||||
|
Jika memilih tipe `Postgre` maka akan keluar tampilan seperti ini
|
||||||
|
|
||||||
|
```
|
||||||
|
Username Database :
|
||||||
|
Password Database :
|
||||||
|
Nama Database:
|
||||||
|
Schema Database :
|
||||||
|
```
|
||||||
|
|
||||||
|
Untuk contohnya pengisiannya seperti di bawah ini:
|
||||||
|
```
|
||||||
|
Username Database : postgres
|
||||||
|
Password Database : admin
|
||||||
|
Nama Database: my_db
|
||||||
|
Schema Database : testt
|
||||||
|
```
|
||||||
|
<br><hr><br>
|
||||||
|
#### Buatkan CRUD
|
||||||
|
|
||||||
|
Untuk membuat CRUD otomatis ketik `2` lalu akan muncul tampilan seperti ini
|
||||||
|
|
||||||
|
```
|
||||||
|
Nama Component :
|
||||||
|
Nama Routing :
|
||||||
|
Tabel Database :
|
||||||
|
```
|
||||||
|
|
||||||
|
List Perintah
|
||||||
|
------------
|
||||||
|
|
||||||
|
Jalankan perintah `php spark sebat` maka akan keluar tampilan seperti ini:
|
||||||
|
|
||||||
|
```
|
||||||
|
Perintahmu ya Baginda?
|
||||||
|
[0] Ubah environment ke production
|
||||||
|
[1] Buatkan APP ID
|
||||||
|
[2] Buatkan CRUD
|
||||||
|
[3] Buatkan Kopi
|
||||||
|
[4] Belum kepikiran ntar dulu
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Ubah environment ke production
|
||||||
|
|
||||||
|
Jika ingin merubah environment dari development ke production atau sebaliknya ketik `0` maka akan keluar tampilan seperti ini
|
||||||
|
|
||||||
|
```bash
|
||||||
|
Berhasil dirubah ke development ya baginda
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Buatkan APP ID
|
||||||
|
`APP ID` berfungsi untuk enkripsi data `Authorization` untuk menjadikan `ClientSecret` yang bertujuan untuk mencegah manipulasi `JWT Token` yang di simpan di sisi client
|
||||||
|
|
||||||
|
Untuk membuat `APP ID` ketik `1` lalu akan muncul seperti ini
|
||||||
|
|
||||||
|
```
|
||||||
|
Berhasil ditambahkan APP ID ya baginda
|
||||||
|
```
|
||||||
|
Jika APP ID sudah tersedia maka akan muncul tampilan seperti ini
|
||||||
|
|
||||||
|
```
|
||||||
|
APP ID Sudah ada ya banginda, tidak perlu di generate lagi
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Buatkan CRUD
|
||||||
|
|
||||||
|
Untuk membuat CRUD otomatis ketik `2` lalu akan muncul tampilan seperti ini
|
||||||
|
|
||||||
|
```
|
||||||
|
Nama Component :
|
||||||
|
Nama Routing :
|
||||||
|
Tabel Database :
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Nama Component
|
||||||
|
Berfungsi untuk membuat file Controller dan Model, Misal untuk membuat Controller `EndpointController` dan Model `EndpointModelSql` hanya dibutuhkan input `endpoint` saja.
|
||||||
|
|
||||||
|
Contoh :
|
||||||
|
|
||||||
|
```
|
||||||
|
Nama Component : endpoint
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Nama Routing
|
||||||
|
Berfungsi untuk membuat Routing URI dengan fitur CRUD secara otomatis
|
||||||
|
|
||||||
|
Contoh :
|
||||||
|
|
||||||
|
```
|
||||||
|
Nama Routing : endpoint
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Tabel Database
|
||||||
|
Berfungsi untuk menentukan table yang ingin di CRUD kan
|
||||||
|
|
||||||
|
Contoh :
|
||||||
|
|
||||||
|
```
|
||||||
|
Tabel Database : endpoint
|
||||||
|
```
|
||||||
6
app/.htaccess
Normal file
6
app/.htaccess
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<IfModule authz_core_module>
|
||||||
|
Require all denied
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !authz_core_module>
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
||||||
33
app/Commands/CleanupPelanggaran.php
Normal file
33
app/Commands/CleanupPelanggaran.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Commands;
|
||||||
|
|
||||||
|
use CodeIgniter\CLI\BaseCommand;
|
||||||
|
use CodeIgniter\CLI\CLI;
|
||||||
|
use Config\Database;
|
||||||
|
|
||||||
|
class CleanupPelanggaran extends BaseCommand
|
||||||
|
{
|
||||||
|
protected $group = 'Maintenance';
|
||||||
|
protected $name = 'cleanup:pelanggaran';
|
||||||
|
protected $description = 'Hapus data pelanggaran yang sudah dihapus lebih dari 7 hari (is_deleted = true).';
|
||||||
|
|
||||||
|
public function run(array $params)
|
||||||
|
{
|
||||||
|
$db = Database::connect();
|
||||||
|
$builder = $db->table('e_teguran_humanis.pelanggaran');
|
||||||
|
|
||||||
|
$delete = $builder->where('is_deleted', true)
|
||||||
|
->where('deleted_at <', date('Y-m-d H:i:s', strtotime('-7 days')))
|
||||||
|
->get()->getResult();
|
||||||
|
|
||||||
|
if (!empty($delete)) {
|
||||||
|
$db->table('e_teguran_humanis.pelanggaran')->where('is_deleted', true)->where('deleted_at <', date('Y-m-d H:i:s', strtotime('-7 days')))->delete();
|
||||||
|
foreach ($delete as $key => $value) {
|
||||||
|
CLI::write('✅ Berhasil menghapus data pelanggaran dengan id ' . $value->pelanggaran_id, 'green');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CLI::write('Gagal menghapus data pelanggaran lebih dari 7 hari', 'red');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
454
app/Commands/DhivaCommand.php
Normal file
454
app/Commands/DhivaCommand.php
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Commands;
|
||||||
|
|
||||||
|
use CodeIgniter\CLI\BaseCommand;
|
||||||
|
use CodeIgniter\CLI\CLI;
|
||||||
|
use Dhiva\Core\DhivaAES;
|
||||||
|
use CodeIgniter\Database\Config;
|
||||||
|
|
||||||
|
class DhivaCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Command's Group
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $group = 'Prodev';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Command's Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = 'sebat';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Command's Description
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Dhiva Command';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Command's Usage
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $usage = 'command:name [arguments] [options]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Command's Arguments
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $arguments = ['kuy'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Command's Options
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $options = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually execute a command.
|
||||||
|
*
|
||||||
|
* @param array $params
|
||||||
|
*/
|
||||||
|
public function run(array $params)
|
||||||
|
{
|
||||||
|
if (isset($params[0])) {
|
||||||
|
if (!file_exists(APPPATH . '/Config/Database.php')) {
|
||||||
|
if ($this->initDb()) {
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
CLI::write('Init ' . $db->getPlatform());
|
||||||
|
if ($db->getPlatform() == 'Postgre') {
|
||||||
|
$this->initTbPostgre();
|
||||||
|
echo command('db:seed superuserseeder');
|
||||||
|
echo command('db:seed supergroupseeder');
|
||||||
|
echo command('db:seed endpointseeder');
|
||||||
|
} else {
|
||||||
|
CLI::write('Versi MySql belum ada');
|
||||||
|
}
|
||||||
|
|
||||||
|
CLI::write("Installasi core berhasil ya baginda", 'green');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CLI::write("Sudah di config wahai yang mulia baginda", 'green');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CLI::write('Buah duku di pohon kaktus' . PHP_EOL . 'Tidak bisa diambil karena berduri' . PHP_EOL . 'Pinjamkanlah dulu aku sembilan ratus' . PHP_EOL . 'Biar aku bisa wara-wiri' . PHP_EOL);
|
||||||
|
$command = CLI::promptByKey(
|
||||||
|
'Perintahmu ya Baginda?',
|
||||||
|
[
|
||||||
|
'Ubah environment ke ' . $this->checkEnv(),
|
||||||
|
'Buatkan APP ID',
|
||||||
|
'Buatkan CRUD',
|
||||||
|
'Ubah durasi JWT Token',
|
||||||
|
'Buatkan Kopi',
|
||||||
|
'Belum kepikiran ntar dulu'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
switch ($command) {
|
||||||
|
case 0:
|
||||||
|
$this->changeEnv();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$this->createAppId();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$this->createComponent();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$this->changeJWTtimeout();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
CLI::write("Silahkan bikin sendiri wahai banginda");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
CLI::write("Mikir mulu!");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CLI::write("Perintahnya tidak ada wahai baginda");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private function changeJWTtimeout()
|
||||||
|
{
|
||||||
|
if (JWT_BY == 'JAM') {
|
||||||
|
CLI::write("Durasi Sekarang : " . JWT_TIMEOUT / HOUR . " " . JWT_BY);
|
||||||
|
} elseif (JWT_BY == 'HARI') {
|
||||||
|
CLI::write("Durasi Sekarang : " . JWT_TIMEOUT / DAY . " " . JWT_BY);
|
||||||
|
}
|
||||||
|
CLI::newLine(1);
|
||||||
|
$pd = CLI::promptByKey('Pilih Durasi ', ['JAM', 'HARI']);
|
||||||
|
if ($pd == 0) {
|
||||||
|
$dr = CLI::prompt("Berapa jam?", null, ['required']);
|
||||||
|
if (preg_match("/^\\d+$/", $dr)) {
|
||||||
|
$str = file_get_contents(APPPATH . '/Config/Constants.php');
|
||||||
|
$new = HOUR * $dr;
|
||||||
|
$str = str_replace(['define("JWT_TIMEOUT", ' . JWT_TIMEOUT . ');', 'define("JWT_BY", "' . JWT_BY . '");'], ['define("JWT_TIMEOUT", ' . $new . ');', 'define("JWT_BY", "JAM");'], $str);
|
||||||
|
file_put_contents(APPPATH . '/Config/Constants.php', $str);
|
||||||
|
CLI::write("Durasi Sekarang : " . $dr . " Jam");
|
||||||
|
}
|
||||||
|
} elseif ($pd == 1) {
|
||||||
|
$dr = CLI::prompt("Berapa hari?", null, ['required']);
|
||||||
|
if (preg_match("/^\\d+$/", $dr)) {
|
||||||
|
$str = file_get_contents(APPPATH . '/Config/Constants.php');
|
||||||
|
$new = DAY * $dr;
|
||||||
|
$str = str_replace(['define("JWT_TIMEOUT", ' . JWT_TIMEOUT . ');', 'define("JWT_BY", "' . JWT_BY . '");'], ['define("JWT_TIMEOUT", ' . $new . ');', 'define("JWT_BY", "HARI");'], $str);
|
||||||
|
}
|
||||||
|
file_put_contents(APPPATH . '/Config/Constants.php', $str);
|
||||||
|
CLI::write("Durasi Sekarang : " . $dr . " Hari");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private function initDb()
|
||||||
|
{
|
||||||
|
$schema = '';
|
||||||
|
$DBDriver = CLI::promptByKey('Database Driver ', ['MySQLi', 'Postgre']);
|
||||||
|
$username = CLI::prompt("Username Database", null, ['required']);
|
||||||
|
$password = CLI::prompt("Password Database", null, ['required']);
|
||||||
|
$tabel = CLI::prompt("Nama Database", null, ['required']);
|
||||||
|
if ($DBDriver == 0) {
|
||||||
|
$DBDriver = 'MySQLi';
|
||||||
|
} else if ($DBDriver == 1) {
|
||||||
|
$DBDriver = 'Postgre';
|
||||||
|
$schema = CLI::prompt("Schema Database", null, ['required']);
|
||||||
|
if ($this->checkConnectionDB($DBDriver, $username, $password, $tabel, $schema)) {
|
||||||
|
$str = file_get_contents(APPPATH . '/Libraries/DhivaComponent/DatabaseClient.txt');
|
||||||
|
$str = str_replace(['{{DBDriver}}', '{{username}}', '{{password}}', '{{tabel}}', '{{schema}}'], [$DBDriver, $username, $password, $tabel, $schema], $str);
|
||||||
|
file_put_contents(APPPATH . '/Config/Database.php', $str);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
CLI::write("Koneksi ke database gagal!", 'red');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private function checkConnectionDB($DBDriver, $username, $password, $tabel, $schema)
|
||||||
|
{
|
||||||
|
$dbSelect = [
|
||||||
|
'DSN' => '',
|
||||||
|
'hostname' => 'localhost',
|
||||||
|
'username' => $username,
|
||||||
|
'password' => $password,
|
||||||
|
'database' => $tabel,
|
||||||
|
'schema' => $schema,
|
||||||
|
'DBDriver' => $DBDriver,
|
||||||
|
'DBPrefix' => '',
|
||||||
|
'pConnect' => true,
|
||||||
|
'DBDebug' => true,
|
||||||
|
'charset' => 'utf8',
|
||||||
|
'DBCollat' => 'utf8_bin',
|
||||||
|
'swapPre' => '',
|
||||||
|
'encrypt' => false,
|
||||||
|
'compress' => false,
|
||||||
|
'strictOn' => false,
|
||||||
|
'failover' => [],
|
||||||
|
'numberNative' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = Database::connect($dbSelect, false);
|
||||||
|
$db->error();
|
||||||
|
CLI::write(json_encode($db->error()['message']));
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
CLI::write('Username atau Password DB salah');
|
||||||
|
}
|
||||||
|
if (!$db->simpleQuery('CREATE TABLE testtable();')) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$db->query('DROP TABLE testtable;');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private function createComponent()
|
||||||
|
{
|
||||||
|
$component = CLI::prompt("Nama Component", null, ['required']);
|
||||||
|
$routes = CLI::prompt("Nama Routing", null, ['required']);
|
||||||
|
$tabel = CLI::prompt("Tabel Database", null, ['required']);
|
||||||
|
$str1 = file_get_contents(APPPATH . '/Libraries/DhivaComponent/Controller.txt');
|
||||||
|
$str1 = str_replace(['{{controller}}', '{{model}}', '{{tabel}}'], [ucfirst($component), ucfirst($component), $tabel], $str1);
|
||||||
|
file_put_contents(APPPATH . "/Controllers/" . ucfirst($component) . 'Controller.php', $str1);
|
||||||
|
|
||||||
|
$str2 = file_get_contents(APPPATH . '/Libraries/DhivaComponent/Model.txt');
|
||||||
|
$str2 = str_replace(['{{model}}', '{{tabel}}'], [ucfirst($component), $tabel], $str2);
|
||||||
|
file_put_contents(APPPATH . "/Models/SqlModel/" . ucfirst($component) . 'ModelSql.php', $str2);
|
||||||
|
|
||||||
|
$str3 = file_get_contents(APPPATH . '/Libraries/DhivaComponent/Routes.txt');
|
||||||
|
$str3 = str_replace(['{{routes}}', '{{controller}}'], [$routes, ucfirst($component)], $str3);
|
||||||
|
file_put_contents(APPPATH . "/Config/Routes.php", $str3, FILE_APPEND);
|
||||||
|
|
||||||
|
$str4 = file_get_contents(APPPATH . '/Models/SqlModel/BaseModelSql.php');
|
||||||
|
$s = explode('];', explode('protected $providers = [', $str4)[1]);
|
||||||
|
$r = $s[0] . ' "' . $tabel . '" => ' . ucfirst($component) . 'ModelSql::class,' . PHP_EOL;
|
||||||
|
$done = str_replace($s[0], $r, $str4);
|
||||||
|
file_put_contents(APPPATH . '/Models/SqlModel/BaseModelSql.php', $done);
|
||||||
|
$this->createComponentDb($tabel);
|
||||||
|
CLI::write("Component berhasil ditambahkan ya baginda", 'green');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Masih ada bug buat primary key di Postgre
|
||||||
|
* jadi belum bisa dipake
|
||||||
|
* @link https://codeigniter4.github.io/userguide/dbmgmt/forge.html#forge-addprimarykey
|
||||||
|
*/
|
||||||
|
private function createComponentDb($tabel, $buat = false)
|
||||||
|
{
|
||||||
|
if ($buat) {
|
||||||
|
|
||||||
|
$forge = Database::forge();
|
||||||
|
$forge->addField([
|
||||||
|
$tabel . '_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'primary' => true
|
||||||
|
],
|
||||||
|
$tabel . '_unique' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
'unique' => true,
|
||||||
|
],
|
||||||
|
'created_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP'
|
||||||
|
]);
|
||||||
|
$forge->createTable($tabel);
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
$db->query('ALTER TABLE ' . $tabel . ' ADD CONSTRAINT ' . $tabel . '_pk PRIMARY KEY (' . $tabel . '_id)');
|
||||||
|
} else {
|
||||||
|
$forge = \Config\Database::forge();
|
||||||
|
$forge->addField([
|
||||||
|
$tabel . '_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
$tabel . '_unique' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
'unique' => true,
|
||||||
|
],
|
||||||
|
'created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP'
|
||||||
|
]);
|
||||||
|
$forge->addKey($tabel . '_id', true);
|
||||||
|
$forge->createTable($tabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private function checkEnv()
|
||||||
|
{
|
||||||
|
return (ENVIRONMENT != 'development') ? 'development' : 'production';
|
||||||
|
}
|
||||||
|
private function createAppId()
|
||||||
|
{
|
||||||
|
$str = file_get_contents(APPPATH . '/Config/Constants.php');
|
||||||
|
if (!str_contains($str, 'SSL_KEY')) {
|
||||||
|
// Jangan di dirapihin/format document!, memang kek gini rule nya
|
||||||
|
$text =
|
||||||
|
'define("SSL_KEY", array(
|
||||||
|
"password" => "' . DhivaAES::randomStr(16) . '",
|
||||||
|
"salt" => "' . DhivaAES::randomStr(16) . '",
|
||||||
|
"iv" => "' . DhivaAES::randomStr(16) . '",
|
||||||
|
"iterations" => 2,
|
||||||
|
"keyLength" => 2,
|
||||||
|
"route" => "' . DhivaAES::randomStr(16) . '"
|
||||||
|
));
|
||||||
|
define("JWT_KEY", "' . DhivaAES::randomStr(20) . '");
|
||||||
|
';
|
||||||
|
file_put_contents(APPPATH . '/Config/Constants.php', $text, FILE_APPEND);
|
||||||
|
CLI::write('Berhasil ditambahkan APP ID ya baginda', 'green');
|
||||||
|
} else {
|
||||||
|
CLI::write('APP ID Sudah ada ya banginda, tidak perlu di generate lagi', 'green');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private function changeEnv()
|
||||||
|
{
|
||||||
|
if (!file_exists(ROOTPATH . ".env")) {
|
||||||
|
if (!file_exists(ROOTPATH . "env")) {
|
||||||
|
$str = file_get_contents(APPPATH . '/Libraries/DhivaComponent/env.txt');
|
||||||
|
file_put_contents(ROOTPATH . ".env", $str);
|
||||||
|
} else {
|
||||||
|
copy(ROOTPATH . "env", ROOTPATH . ".env");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$str = file_get_contents(ROOTPATH . ".env");
|
||||||
|
if (str_contains($str, '# CI_ENVIRONMENT')) {
|
||||||
|
$search = '# CI_ENVIRONMENT';
|
||||||
|
} else {
|
||||||
|
$search = 'CI_ENVIRONMENT';
|
||||||
|
}
|
||||||
|
if (ENVIRONMENT == 'development') {
|
||||||
|
$str = str_replace($search . ' = development', $search . ' = production', $str);
|
||||||
|
$rr = 'production';
|
||||||
|
} else {
|
||||||
|
$str = str_replace($search . ' = production', $search . ' = development', $str);
|
||||||
|
$rr = 'development';
|
||||||
|
}
|
||||||
|
file_put_contents(ROOTPATH . ".env", $str);
|
||||||
|
CLI::write('Berhasil dirubah ke ' . $rr . ' ya baginda', 'green');
|
||||||
|
}
|
||||||
|
private function initTbPostgre()
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
$forge = \Config\Database::forge();
|
||||||
|
$forge->addField([
|
||||||
|
'super_user_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'super_user_unique' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
'unique' => true,
|
||||||
|
],
|
||||||
|
'super_group_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 5,
|
||||||
|
],
|
||||||
|
'domain_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 5,
|
||||||
|
],
|
||||||
|
'name' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'email' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'username' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'password' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'avatar' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 1,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'token' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
'login_date TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
'access_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP'
|
||||||
|
]);
|
||||||
|
$forge->createTable('super_user');
|
||||||
|
$db->query('ALTER TABLE ' . 'super_user ADD CONSTRAINT super_user_pk PRIMARY KEY (super_user_id)');
|
||||||
|
$forge->addField([
|
||||||
|
'super_group_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
],
|
||||||
|
'super_group_unique' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
'unique' => true,
|
||||||
|
],
|
||||||
|
'domain_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
],
|
||||||
|
'group_name' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 1,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
]);
|
||||||
|
$forge->createTable('super_group');
|
||||||
|
$db->query("CREATE TYPE endpoint_type" . " AS enum ('frontend', 'backend')");
|
||||||
|
$db->query("CREATE TYPE endpoint_method" . " AS enum ('POST', 'GET', 'PUT', 'DELETE')");
|
||||||
|
$db->query("CREATE TYPE endpoint_bypass" . " AS enum ('0', '1')");
|
||||||
|
|
||||||
|
$forge->addField([
|
||||||
|
'endpoint_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
],
|
||||||
|
'value' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'description' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_by' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
]);
|
||||||
|
$forge->createTable('endpoint');
|
||||||
|
$db->query('ALTER TABLE endpoint ADD CONSTRAINT endpoint_id_pk PRIMARY KEY (endpoint_id)');
|
||||||
|
$db->query("ALTER TABLE endpoint ADD method endpoint_method NOT NULL;");
|
||||||
|
$db->query("ALTER TABLE endpoint ADD type endpoint_type NOT NULL;");
|
||||||
|
$db->query("ALTER TABLE endpoint ADD bypass endpoint_bypass NOT NULL;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Database extends Config
|
||||||
|
{
|
||||||
|
}
|
||||||
15
app/Common.php
Normal file
15
app/Common.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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://codeigniter.com/user_guide/extending/common.html
|
||||||
|
*/
|
||||||
178
app/Config/App.php
Normal file
178
app/Config/App.php
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class App extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Base Site URL
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* URL to your CodeIgniter root. Typically, this will be your base URL,
|
||||||
|
* WITH a trailing slash:
|
||||||
|
*
|
||||||
|
* http://example.com/
|
||||||
|
*/
|
||||||
|
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 string[]
|
||||||
|
* @phpstan-var list<string>
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
public string $indexPage = 'index.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* URI PROTOCOL
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This item determines which server global should be used to retrieve the
|
||||||
|
* URI string. The default setting of 'REQUEST_URI' works for most servers.
|
||||||
|
* If your links do not seem to work, try one of the other delicious flavors:
|
||||||
|
*
|
||||||
|
* 'REQUEST_URI' Uses $_SERVER['REQUEST_URI']
|
||||||
|
* 'QUERY_STRING' Uses $_SERVER['QUERY_STRING']
|
||||||
|
* 'PATH_INFO' Uses $_SERVER['PATH_INFO']
|
||||||
|
*
|
||||||
|
* WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
|
||||||
|
*/
|
||||||
|
public string $uriProtocol = 'REQUEST_URI';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Default Locale
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The Locale roughly represents the language and location that your visitor
|
||||||
|
* is viewing the site from. It affects the language strings and other
|
||||||
|
* strings (like currency markers, numbers, etc), that your program
|
||||||
|
* should run under for this request.
|
||||||
|
*/
|
||||||
|
public string $defaultLocale = 'en';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Negotiate Locale
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If true, the current Request object will automatically determine the
|
||||||
|
* language to use based on the value of the Accept-Language header.
|
||||||
|
*
|
||||||
|
* If false, no automatic detection will be performed.
|
||||||
|
*/
|
||||||
|
public bool $negotiateLocale = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Supported Locales
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If $negotiateLocale is true, this array lists the locales supported
|
||||||
|
* by the application in descending order of priority. If no match is
|
||||||
|
* found, the first locale will be used.
|
||||||
|
*
|
||||||
|
* IncomingRequest::setLocale() also uses this list.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public array $supportedLocales = ['en'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Application Timezone
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The default timezone that will be used in your application to display
|
||||||
|
* dates with the date helper, and can be retrieved through app_timezone()
|
||||||
|
*
|
||||||
|
* @see https://www.php.net/manual/en/timezones.php for list of timezones supported by PHP.
|
||||||
|
*/
|
||||||
|
public string $appTimezone = 'Asia/Makassar';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Default Character Set
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This determines which character set is used by default in various methods
|
||||||
|
* that require a character set to be provided.
|
||||||
|
*
|
||||||
|
* @see http://php.net/htmlspecialchars for a list of supported charsets.
|
||||||
|
*/
|
||||||
|
public string $charset = 'UTF-8';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Force Global Secure Requests
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If true, this will force every request made to this application to be
|
||||||
|
* made via a secure connection (HTTPS). If the incoming request is not
|
||||||
|
* secure, the user will be redirected to a secure version of the page
|
||||||
|
* and the HTTP Strict Transport Security header will be set.
|
||||||
|
*/
|
||||||
|
public bool $forceGlobalSecureRequests = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Reverse Proxy IPs
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If your server is behind a reverse proxy, you must whitelist the proxy
|
||||||
|
* IP addresses from which CodeIgniter should trust headers such as
|
||||||
|
* X-Forwarded-For or Client-IP in order to properly identify
|
||||||
|
* the visitor's IP address.
|
||||||
|
*
|
||||||
|
* You need to set a proxy IP address or IP address with subnets and
|
||||||
|
* the HTTP header for the client IP address.
|
||||||
|
*
|
||||||
|
* Here are some examples:
|
||||||
|
* [
|
||||||
|
* '10.0.1.200' => 'X-Forwarded-For',
|
||||||
|
* '192.168.5.0/24' => 'X-Real-IP',
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $proxyIPs = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Content Security Policy
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Enables the Response's Content Secure Policy to restrict the sources that
|
||||||
|
* can be used for images, scripts, CSS files, audio, video, etc. If enabled,
|
||||||
|
* the Response object will populate default values for the policy from the
|
||||||
|
* `ContentSecurityPolicy.php` file. Controllers can always add to those
|
||||||
|
* restrictions at run time.
|
||||||
|
*
|
||||||
|
* For a better understanding of CSP, see these documents:
|
||||||
|
*
|
||||||
|
* @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/
|
||||||
|
* @see http://www.w3.org/TR/CSP/
|
||||||
|
*/
|
||||||
|
public bool $CSPEnabled = false;
|
||||||
|
}
|
||||||
116
app/Config/Autoload.php
Normal file
116
app/Config/Autoload.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\AutoloadConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* AUTOLOADER CONFIGURATION
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This file defines the namespaces and class maps so the Autoloader
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* NOTE: This class is required prior to Autoloader instantiation,
|
||||||
|
* and does not extend BaseConfig.
|
||||||
|
*
|
||||||
|
* @immutable
|
||||||
|
*/
|
||||||
|
class Autoload extends AutoloadConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Namespaces
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* This maps the locations of any namespaces in your application to
|
||||||
|
* 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,
|
||||||
|
* 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<string, array<int, string>|string>
|
||||||
|
* @phpstan-var array<string, string|list<string>>
|
||||||
|
*/
|
||||||
|
public $psr4 = [
|
||||||
|
APP_NAMESPACE => APPPATH, // For custom app namespace
|
||||||
|
'Config' => APPPATH . 'Config',
|
||||||
|
'Dhiva/Core' => APPPATH . 'Libraries',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Class Map
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* The class map provides a map of class names and their exact
|
||||||
|
* location on the drive. Classes loaded in this manner will have
|
||||||
|
* slightly faster performance because they will not have to be
|
||||||
|
* searched for within one or more directories as they would if they
|
||||||
|
* were being autoloaded through a namespace.
|
||||||
|
*
|
||||||
|
* Prototype:
|
||||||
|
* $classmap = [
|
||||||
|
* 'MyClass' => '/path/to/class/file.php'
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public $classmap =
|
||||||
|
[
|
||||||
|
'Dhiva\Core\DhivaRoutes' => APPPATH . 'Libraries/DhivaRoutes.php',
|
||||||
|
'Dhiva\Core\DhivaAES' => APPPATH . 'Libraries/DhivaAES.php',
|
||||||
|
'Dhiva\Core\Notification' => APPPATH . 'Libraries/Notification.php',
|
||||||
|
'ArelAyudhi\DhivaProdevWa\ProdevMessages' => APPPATH . 'Libraries/ArelAyudhi/src/ProdevMessages.php',
|
||||||
|
'ArelAyudhi\DhivaProdevWa\ProdevMessagesAbstract' => APPPATH . 'Libraries/ArelAyudhi/src/ProdevMessagesAbstract.php',
|
||||||
|
'ArelAyudhi\DhivaProdevWa\Multiple' => APPPATH . 'Libraries/ArelAyudhi/src/Multiple.php',
|
||||||
|
'ArelAyudhi\DhivaProdevWa\Group' => APPPATH . 'Libraries/ArelAyudhi/src/Group.php',
|
||||||
|
'ArelAyudhi\DhivaProdevWa\ListMessage' => APPPATH . 'Libraries/ArelAyudhi/src/ListMessage.php',
|
||||||
|
'ArelAyudhi\DhivaProdevWa\Broadcast' => APPPATH . 'Libraries/ArelAyudhi/src/Broadcast.php',
|
||||||
|
'ArelAyudhi\DhivaProdevWa\UserList' => APPPATH . 'Libraries/ArelAyudhi/src/UserList.php',
|
||||||
|
'Dhiva\Core\Notification' => APPPATH . 'Libraries/Notification.php'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Files
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* The files array provides a list of paths to __non-class__ files
|
||||||
|
* that will be autoloaded. This can be useful for bootstrap operations
|
||||||
|
* or for loading functions.
|
||||||
|
*
|
||||||
|
* Prototype:
|
||||||
|
* $files = [
|
||||||
|
* '/path/to/my/file.php',
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
* @phpstan-var list<string>
|
||||||
|
*/
|
||||||
|
public $files = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Helpers
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Prototype:
|
||||||
|
* $helpers = [
|
||||||
|
* 'form',
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
* @phpstan-var list<string>
|
||||||
|
*/
|
||||||
|
public $helpers = ['device'];
|
||||||
|
}
|
||||||
32
app/Config/Boot/development.php
Normal file
32
app/Config/Boot/development.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| ERROR DISPLAY
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| 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.
|
||||||
|
*/
|
||||||
|
error_reporting(-1);
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DEBUG BACKTRACES
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| If true, this constant will tell the error screens to display debug
|
||||||
|
| backtraces along with the other error information. If you would
|
||||||
|
| prefer to not see this, set this value to false.
|
||||||
|
*/
|
||||||
|
defined('SHOW_DEBUG_BACKTRACE') || define('SHOW_DEBUG_BACKTRACE', true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DEBUG MODE
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Debug mode is an experimental flag that can allow changes throughout
|
||||||
|
| the system. This will control whether Kint is loaded, and a few other
|
||||||
|
| items. It can always be used within your own application too.
|
||||||
|
*/
|
||||||
|
defined('CI_DEBUG') || define('CI_DEBUG', true);
|
||||||
21
app/Config/Boot/production.php
Normal file
21
app/Config/Boot/production.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| ERROR DISPLAY
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Don't show ANY in production environments. Instead, let the system catch
|
||||||
|
| it and display a generic error message.
|
||||||
|
*/
|
||||||
|
error_reporting(0);
|
||||||
|
// error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DEBUG MODE
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Debug mode is an experimental flag that can allow changes throughout
|
||||||
|
| the system. It's not widely used currently, and may not survive
|
||||||
|
| release of the framework.
|
||||||
|
*/
|
||||||
|
defined('CI_DEBUG') || define('CI_DEBUG', false);
|
||||||
32
app/Config/Boot/testing.php
Normal file
32
app/Config/Boot/testing.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| ERROR DISPLAY
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| 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.
|
||||||
|
*/
|
||||||
|
error_reporting(-1);
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DEBUG BACKTRACES
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| If true, this constant will tell the error screens to display debug
|
||||||
|
| backtraces along with the other error information. If you would
|
||||||
|
| prefer to not see this, set this value to false.
|
||||||
|
*/
|
||||||
|
defined('SHOW_DEBUG_BACKTRACE') || define('SHOW_DEBUG_BACKTRACE', true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DEBUG MODE
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Debug mode is an experimental flag that can allow changes throughout
|
||||||
|
| the system. It's not widely used currently, and may not survive
|
||||||
|
| release of the framework.
|
||||||
|
*/
|
||||||
|
defined('CI_DEBUG') || define('CI_DEBUG', true);
|
||||||
20
app/Config/CURLRequest.php
Normal file
20
app/Config/CURLRequest.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class CURLRequest extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CURLRequest Share Options
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Whether share options between requests or not.
|
||||||
|
*
|
||||||
|
* If true, all the options won't be reset between requests.
|
||||||
|
* It may cause an error request with unnecessary headers.
|
||||||
|
*/
|
||||||
|
public bool $shareOptions = false;
|
||||||
|
}
|
||||||
172
app/Config/Cache.php
Normal file
172
app/Config/Cache.php
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Cache\CacheInterface;
|
||||||
|
use CodeIgniter\Cache\Handlers\DummyHandler;
|
||||||
|
use CodeIgniter\Cache\Handlers\FileHandler;
|
||||||
|
use CodeIgniter\Cache\Handlers\MemcachedHandler;
|
||||||
|
use CodeIgniter\Cache\Handlers\PredisHandler;
|
||||||
|
use CodeIgniter\Cache\Handlers\RedisHandler;
|
||||||
|
use CodeIgniter\Cache\Handlers\WincacheHandler;
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class Cache extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Primary Handler
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The name of the preferred handler that should be used. If for some reason
|
||||||
|
* it is not available, the $backupHandler will be used in its place.
|
||||||
|
*/
|
||||||
|
public string $handler = 'file';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Backup Handler
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The name of the handler that will be used in case the first one is
|
||||||
|
* unreachable. Often, 'file' is used here since the filesystem is
|
||||||
|
* always available, though that's not always practical for the app.
|
||||||
|
*/
|
||||||
|
public string $backupHandler = 'dummy';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cache Directory Path
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The path to where cache files should be stored, if using a file-based
|
||||||
|
* system.
|
||||||
|
*
|
||||||
|
* @deprecated Use the driver-specific variant under $file
|
||||||
|
*/
|
||||||
|
public string $storePath = WRITEPATH . 'cache/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* 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|string[]
|
||||||
|
*/
|
||||||
|
public $cacheQueryString = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Key Prefix
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This string is added to all cache item names to help avoid collisions
|
||||||
|
* if you run multiple applications with the same cache engine.
|
||||||
|
*/
|
||||||
|
public string $prefix = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Default TTL
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The default number of seconds to save items when none is specified.
|
||||||
|
*
|
||||||
|
* WARNING: This is not used by framework handlers where 60 seconds is
|
||||||
|
* hard-coded, but may be useful to projects and modules. This will replace
|
||||||
|
* the hard-coded value in a future release.
|
||||||
|
*/
|
||||||
|
public int $ttl = 60;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Reserved Characters
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* A string of reserved characters that will not be allowed in keys or tags.
|
||||||
|
* Strings that violate this restriction will cause handlers to throw.
|
||||||
|
* Default: {}()/\@:
|
||||||
|
*
|
||||||
|
* NOTE: The default set is required for PSR-6 compliance.
|
||||||
|
*/
|
||||||
|
public string $reservedCharacters = '{}()/\@:';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* File settings
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Your file storage preferences can be specified below, if you are using
|
||||||
|
* the File driver.
|
||||||
|
*
|
||||||
|
* @var array<string, int|string|null>
|
||||||
|
*/
|
||||||
|
public array $file = [
|
||||||
|
'storePath' => WRITEPATH . 'cache/',
|
||||||
|
'mode' => 0640,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Memcached settings
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Your Memcached servers can be specified below, if you are using
|
||||||
|
* the Memcached drivers.
|
||||||
|
*
|
||||||
|
* @see https://codeigniter.com/user_guide/libraries/caching.html#memcached
|
||||||
|
*
|
||||||
|
* @var array<string, bool|int|string>
|
||||||
|
*/
|
||||||
|
public array $memcached = [
|
||||||
|
'host' => '127.0.0.1',
|
||||||
|
'port' => 11211,
|
||||||
|
'weight' => 1,
|
||||||
|
'raw' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Redis settings
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Your Redis server can be specified below, if you are using
|
||||||
|
* the Redis or Predis drivers.
|
||||||
|
*
|
||||||
|
* @var array<string, int|string|null>
|
||||||
|
*/
|
||||||
|
public array $redis = [
|
||||||
|
'host' => '127.0.0.1',
|
||||||
|
'password' => null,
|
||||||
|
'port' => 6379,
|
||||||
|
'timeout' => 0,
|
||||||
|
'database' => 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Available Cache Handlers
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This is an array of cache engine alias' and class names. Only engines
|
||||||
|
* that are listed here are allowed to be used.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
* @phpstan-var array<string, class-string<CacheInterface>>
|
||||||
|
*/
|
||||||
|
public array $validHandlers = [
|
||||||
|
'dummy' => DummyHandler::class,
|
||||||
|
'file' => FileHandler::class,
|
||||||
|
'memcached' => MemcachedHandler::class,
|
||||||
|
'predis' => PredisHandler::class,
|
||||||
|
'redis' => RedisHandler::class,
|
||||||
|
'wincache' => WincacheHandler::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
392
app/Config/Constants.php
Normal file
392
app/Config/Constants.php
Normal file
@@ -0,0 +1,392 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
| --------------------------------------------------------------------
|
||||||
|
| App Namespace
|
||||||
|
| --------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This defines the default Namespace that is used throughout
|
||||||
|
| CodeIgniter to refer to the Application directory. Change
|
||||||
|
| this constant to change the namespace that all application
|
||||||
|
| classes should use.
|
||||||
|
|
|
||||||
|
| NOTE: changing this will require manually modifying the
|
||||||
|
| existing namespaces of App\* namespaced-classes.
|
||||||
|
*/
|
||||||
|
defined('APP_NAMESPACE') || define('APP_NAMESPACE', 'App');
|
||||||
|
define('DATE_FORMAT', '%Y-%m-%d %H:%i:%s');
|
||||||
|
define('OAUTH', 'Oauth/v1/auth');
|
||||||
|
|
||||||
|
|
||||||
|
define('ERROR_TOKEN_UNIDENTIFIED', 880);
|
||||||
|
define('ERROR_TOKEN_EXPIRED', 881);
|
||||||
|
define('ERROR_TOKEN_UNKNOWN', 882);
|
||||||
|
define('ERROR_NOT_FOUND', 404);
|
||||||
|
define('HTTP_CONTINUE', 100);
|
||||||
|
define('HTTP_SWITCHING_PROTOCOLS', 101);
|
||||||
|
define('HTTP_PROCESSING', 102); // RFC2518
|
||||||
|
|
||||||
|
// Success
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request has succeeded
|
||||||
|
*/
|
||||||
|
define('HTTP_OK', 200);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server successfully created a new resource
|
||||||
|
*/
|
||||||
|
define('HTTP_CREATED', 201);
|
||||||
|
define('HTTP_ACCEPTED', 202);
|
||||||
|
define('HTTP_NON_AUTHORITATIVE_INFORMATION', 203);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server successfully processed the request, though no content is returned
|
||||||
|
*/
|
||||||
|
define('HTTP_NO_CONTENT', 204);
|
||||||
|
define('HTTP_RESET_CONTENT', 205);
|
||||||
|
define('HTTP_PARTIAL_CONTENT', 206);
|
||||||
|
define('HTTP_MULTI_STATUS', 207); // RFC4918
|
||||||
|
define('HTTP_ALREADY_REPORTED', 208); // RFC5842
|
||||||
|
define('HTTP_IM_USED', 226); // RFC3229
|
||||||
|
|
||||||
|
// Redirection
|
||||||
|
|
||||||
|
define('HTTP_MULTIPLE_CHOICES', 300);
|
||||||
|
define('HTTP_MOVED_PERMANENTLY', 301);
|
||||||
|
define('HTTP_FOUND', 302);
|
||||||
|
define('HTTP_SEE_OTHER', 303);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resource has not been modified since the last request
|
||||||
|
*/
|
||||||
|
define('HTTP_NOT_MODIFIED', 304);
|
||||||
|
define('HTTP_USE_PROXY', 305);
|
||||||
|
define('HTTP_RESERVED', 306);
|
||||||
|
define('HTTP_TEMPORARY_REDIRECT', 307);
|
||||||
|
define('HTTP_PERMANENTLY_REDIRECT', 308); // RFC7238
|
||||||
|
|
||||||
|
// Client Error
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request cannot be fulfilled due to multiple errors
|
||||||
|
*/
|
||||||
|
define('HTTP_BAD_REQUEST', 400);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user is unauthorized to access the requested resource
|
||||||
|
*/
|
||||||
|
define('HTTP_UNAUTHORIZED', 401);
|
||||||
|
define('HTTP_PAYMENT_REQUIRED', 402);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested resource is unavailable at this present time
|
||||||
|
*/
|
||||||
|
define('HTTP_FORBIDDEN', 403);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested resource could not be found
|
||||||
|
*
|
||||||
|
* Note: This is sometimes used to mask if there was an UNAUTHORIZED (401) or
|
||||||
|
* FORBIDDEN (403) error, for security reasons
|
||||||
|
*/
|
||||||
|
define('HTTP_NOT_FOUND', 404);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request method is not supported by the following resource
|
||||||
|
*/
|
||||||
|
define('HTTP_METHOD_NOT_ALLOWED', 405);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request was not acceptable
|
||||||
|
*/
|
||||||
|
define('HTTP_NOT_ACCEPTABLE', 406);
|
||||||
|
define('HTTP_PROXY_AUTHENTICATION_REQUIRED', 407);
|
||||||
|
define('HTTP_REQUEST_TIMEOUT', 408);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request could not be completed due to a conflict with the current state
|
||||||
|
* of the resource
|
||||||
|
*/
|
||||||
|
define('HTTP_CONFLICT', 409);
|
||||||
|
define('HTTP_GONE', 410);
|
||||||
|
define('HTTP_LENGTH_REQUIRED', 411);
|
||||||
|
define('HTTP_PRECONDITION_FAILED', 412);
|
||||||
|
define('HTTP_REQUEST_ENTITY_TOO_LARGE', 413);
|
||||||
|
define('HTTP_REQUEST_URI_TOO_LONG', 414);
|
||||||
|
define('HTTP_UNSUPPORTED_MEDIA_TYPE', 415);
|
||||||
|
define('HTTP_REQUESTED_RANGE_NOT_SATISFIABLE', 416);
|
||||||
|
define('HTTP_EXPECTATION_FAILED', 417);
|
||||||
|
define('HTTP_I_AM_A_TEAPOT', 418); // RFC2324
|
||||||
|
define('HTTP_UNPROCESSABLE_ENTITY', 422); // RFC4918
|
||||||
|
define('HTTP_LOCKED', 423); // RFC4918
|
||||||
|
define('HTTP_FAILED_DEPENDENCY', 424); // RFC4918
|
||||||
|
define('HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL', 425); // RFC2817
|
||||||
|
define('HTTP_UPGRADE_REQUIRED', 426); // RFC2817
|
||||||
|
define('HTTP_PRECONDITION_REQUIRED', 428); // RFC6585
|
||||||
|
define('HTTP_TOO_MANY_REQUESTS', 429); // RFC6585
|
||||||
|
define('HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE', 431); // RFC6585
|
||||||
|
|
||||||
|
// Server Error
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server encountered an unexpected error
|
||||||
|
*
|
||||||
|
* Note: This is a generic error message when no specific message
|
||||||
|
* is suitable
|
||||||
|
*/
|
||||||
|
define('HTTP_INTERNAL_SERVER_ERROR', 500);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server does not recognise the request method
|
||||||
|
*/
|
||||||
|
define('HTTP_NOT_IMPLEMENTED', 501);
|
||||||
|
define('HTTP_BAD_GATEWAY', 502);
|
||||||
|
define('HTTP_SERVICE_UNAVAILABLE', 503);
|
||||||
|
define('HTTP_GATEWAY_TIMEOUT', 504);
|
||||||
|
define('HTTP_VERSION_NOT_SUPPORTED', 505);
|
||||||
|
define('HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL', 506); // RFC2295
|
||||||
|
define('HTTP_INSUFFICIENT_STORAGE', 507); // RFC4918
|
||||||
|
define('HTTP_LOOP_DETECTED', 508); // RFC5842
|
||||||
|
define('HTTP_NOT_EXTENDED', 510); // RFC2774
|
||||||
|
define('HTTP_NETWORK_AUTHENTICATION_REQUIRED', 511);
|
||||||
|
/*
|
||||||
|
| --------------------------------------------------------------------------
|
||||||
|
| Composer Path
|
||||||
|
| --------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The path that Composer's autoload file is expected to live. By default,
|
||||||
|
| the vendor folder is in the Root directory, but you can customize that here.
|
||||||
|
*/
|
||||||
|
defined('COMPOSER_PATH') || define('COMPOSER_PATH', ROOTPATH . 'vendor/autoload.php');
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Timing Constants
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Provide simple ways to work with the myriad of PHP functions that
|
||||||
|
| require information to be in seconds.
|
||||||
|
*/
|
||||||
|
defined('SECOND') || define('SECOND', 1);
|
||||||
|
defined('MINUTE') || define('MINUTE', 60);
|
||||||
|
defined('HOUR') || define('HOUR', 3600);
|
||||||
|
defined('DAY') || define('DAY', 86400);
|
||||||
|
defined('WEEK') || define('WEEK', 604800);
|
||||||
|
defined('MONTH') || define('MONTH', 2_592_000);
|
||||||
|
defined('YEAR') || define('YEAR', 31_536_000);
|
||||||
|
defined('DECADE') || define('DECADE', 315_360_000);
|
||||||
|
|
||||||
|
/*
|
||||||
|
| --------------------------------------------------------------------------
|
||||||
|
| Exit Status Codes
|
||||||
|
| --------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Used to indicate the conditions under which the script is exit()ing.
|
||||||
|
| While there is no universal standard for error codes, there are some
|
||||||
|
| broad conventions. Three such conventions are mentioned below, for
|
||||||
|
| those who wish to make use of them. The CodeIgniter defaults were
|
||||||
|
| chosen for the least overlap with these conventions, while still
|
||||||
|
| leaving room for others to be defined in future versions and user
|
||||||
|
| applications.
|
||||||
|
|
|
||||||
|
| The three main conventions used for determining exit status codes
|
||||||
|
| are as follows:
|
||||||
|
|
|
||||||
|
| Standard C/C++ Library (stdlibc):
|
||||||
|
| http://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
|
||||||
|
| (This link also contains other GNU-specific conventions)
|
||||||
|
| BSD sysexits.h:
|
||||||
|
| http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits
|
||||||
|
| Bash scripting:
|
||||||
|
| http://tldp.org/LDP/abs/html/exitcodes.html
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
defined('EXIT_SUCCESS') || define('EXIT_SUCCESS', 0); // no errors
|
||||||
|
defined('EXIT_ERROR') || define('EXIT_ERROR', 1); // generic error
|
||||||
|
defined('EXIT_CONFIG') || define('EXIT_CONFIG', 3); // configuration error
|
||||||
|
defined('EXIT_UNKNOWN_FILE') || define('EXIT_UNKNOWN_FILE', 4); // file not found
|
||||||
|
defined('EXIT_UNKNOWN_CLASS') || define('EXIT_UNKNOWN_CLASS', 5); // unknown class
|
||||||
|
defined('EXIT_UNKNOWN_METHOD') || define('EXIT_UNKNOWN_METHOD', 6); // unknown class member
|
||||||
|
defined('EXIT_USER_INPUT') || define('EXIT_USER_INPUT', 7); // invalid user input
|
||||||
|
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);
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Dhiva JWT Timeout
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
define("JWT_TIMEOUT", 180000*20000);
|
||||||
|
define("JWT_BY", "JAM");
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Dhiva Uploads Path
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
define("BASE_APP", "https://project.adhivasindo.co.id/diyapi/app-version/show_by/version/");
|
||||||
|
define("PATH_MODEL", "App\Models\SqlModel");
|
||||||
|
define("FIREBASE_API", "AAAAtTcH0GQ:APA91bG0N7PqyXCFiDHQn4Jw8AO2dgFF-hp9jeCUff1pMwb25JrJWQUciUMhhfCwbVcabx-GGwzU-uktnbl3PmScYZI0weI_Fa1cCU_6HdJH0duX48tVZmh-QErIkXBeC0EPP7otC9Ip");
|
||||||
|
|
||||||
|
define("PATH_VIDEOS", "uploads/videos/");
|
||||||
|
define("PATH_VIDEOS_SERVER", WRITEPATH . PATH_VIDEOS);
|
||||||
|
define("PATH_VIDEOS_CLIENT", APPPATH . PATH_VIDEOS);
|
||||||
|
|
||||||
|
define("PATH_IMAGES", "uploads/images/");
|
||||||
|
define("PATH_IMAGES_SERVER", WRITEPATH . PATH_IMAGES);
|
||||||
|
define("PATH_IMAGES_CLIENT", APPPATH . PATH_IMAGES);
|
||||||
|
|
||||||
|
define("PATH_APK", "uploads/apk/");
|
||||||
|
define("PATH_APK_SERVER", WRITEPATH . PATH_APK);
|
||||||
|
define("PATH_APK_CLIENT", APPPATH . PATH_APK);
|
||||||
|
|
||||||
|
define("ProdevToken", "qeTAbqcqiZ6hooBgdtZ32ftcdney1SKGvDhLvS31A4g");
|
||||||
|
|
||||||
|
if (!function_exists('encodeloop')) {
|
||||||
|
function encodeloop($source = '')
|
||||||
|
{
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
$encodedString = base64_encode($source);
|
||||||
|
}
|
||||||
|
return $encodedString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('shuffle_word')) {
|
||||||
|
function shuffle_word($word = '', $x = 4)
|
||||||
|
{
|
||||||
|
$arrSplitString = str_split($word, $x);
|
||||||
|
$countSplittedString = count($arrSplitString);
|
||||||
|
|
||||||
|
$word = '';
|
||||||
|
|
||||||
|
for ($i = 0; $i < ($countSplittedString); $i++) {
|
||||||
|
if ($i == $countSplittedString - 1) {
|
||||||
|
$word .= $arrSplitString[0];
|
||||||
|
} else {
|
||||||
|
$word .= $arrSplitString[$i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $x . $word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (!function_exists('mdate')) {
|
||||||
|
function mdate($datestr = '', $time = '')
|
||||||
|
{
|
||||||
|
if ($datestr === '') {
|
||||||
|
return '';
|
||||||
|
} elseif (empty($time)) {
|
||||||
|
$time = now();
|
||||||
|
}
|
||||||
|
|
||||||
|
$datestr = str_replace(
|
||||||
|
'%\\',
|
||||||
|
'',
|
||||||
|
preg_replace('/([a-z]+?){1}/i', '\\\\\\1', $datestr)
|
||||||
|
);
|
||||||
|
|
||||||
|
return date($datestr, $time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!function_exists('decodeloop')) {
|
||||||
|
function decodeloop($source = '', $x = 4)
|
||||||
|
{
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
$decodeString = base64_decode($source);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $decodeString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('deshuffle_Word')) {
|
||||||
|
function deshuffle_word($source = '', $x = 4)
|
||||||
|
{
|
||||||
|
$firstStr = substr($source, 0, 1);
|
||||||
|
if ($firstStr != $x) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$source = substr($source, 1);
|
||||||
|
$lengthSource = strlen($source);
|
||||||
|
if (($lengthSource - 1) < $x) {
|
||||||
|
return $source;
|
||||||
|
}
|
||||||
|
$shardString = substr($source, $lengthSource - $x);
|
||||||
|
$source = substr($source, 0, $lengthSource - $x);
|
||||||
|
$deshuffleString = $shardString . $source;
|
||||||
|
return $deshuffleString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists("searchpost")) {
|
||||||
|
function searchpost(): bool | array
|
||||||
|
{
|
||||||
|
if (isset($_POST["from"]) && isset($_POST["to"]) && isset($_POST["page"]) && isset($_POST["limit"])) {
|
||||||
|
$data['from'] = $_POST["from"];
|
||||||
|
$data['to'] = $_POST["to"];
|
||||||
|
$data['page'] = $_POST["page"];
|
||||||
|
$data['limit'] = $_POST["limit"];
|
||||||
|
unset($_POST["from"]);
|
||||||
|
unset($_POST["to"]);
|
||||||
|
unset($_POST["page"]);
|
||||||
|
unset($_POST["limit"]);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!function_exists("postArray")) {
|
||||||
|
function postArray($clean = true)
|
||||||
|
{
|
||||||
|
if ($clean) {
|
||||||
|
foreach ($_POST as $a => $b) {
|
||||||
|
$string = preg_match("/^[a-zA-Z0-9]+$/", $_POST[$a]);
|
||||||
|
if (!$string) {
|
||||||
|
$response = [
|
||||||
|
"success" => false,
|
||||||
|
"code" => 9001,
|
||||||
|
"message" => "Query Not Allowed",
|
||||||
|
];
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_POST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// JANGAN DI GANTI ATAU DI FORMAT
|
||||||
|
define("SSL_KEY", array(
|
||||||
|
"password" => "8QAuvaF5qzNlGlgi",
|
||||||
|
"salt" => "aww9Rq9PRsy3QYrq",
|
||||||
|
"iv" => "LDSzHPcej5CKXqvT",
|
||||||
|
"iterations" => 2,
|
||||||
|
"keyLength" => 2,
|
||||||
|
"Payload_Key" => "U4a97fVRoQ",
|
||||||
|
"Payload_IV" => "Ae0Rf13j8e",
|
||||||
|
"route" => "pkAddGs9DB3VeEGL"
|
||||||
|
));
|
||||||
|
define("JWT_KEY", "9QY3tGDFzS5aiI3Pz8Uf");
|
||||||
|
// YG INI JANGAN DI HAPUS
|
||||||
176
app/Config/ContentSecurityPolicy.php
Normal file
176
app/Config/ContentSecurityPolicy.php
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the default settings for the ContentSecurityPolicy, if you
|
||||||
|
* choose to use it. The values here will be read in and set as defaults
|
||||||
|
* for the site. If needed, they can be overridden on a page-by-page basis.
|
||||||
|
*
|
||||||
|
* Suggested reference for explanations:
|
||||||
|
*
|
||||||
|
* @see https://www.html5rocks.com/en/tutorials/security/content-security-policy/
|
||||||
|
*/
|
||||||
|
class ContentSecurityPolicy extends BaseConfig
|
||||||
|
{
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Broadbrush CSP management
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default CSP report context
|
||||||
|
*/
|
||||||
|
public bool $reportOnly = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a URL where a browser will send reports
|
||||||
|
* when a content security policy is violated.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
public bool $upgradeInsecureRequests = false;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Sources allowed
|
||||||
|
// NOTE: once you set a policy to 'none', it cannot be further restricted
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will default to self if not overridden
|
||||||
|
*
|
||||||
|
* @var string|string[]|null
|
||||||
|
*/
|
||||||
|
public $defaultSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists allowed scripts' URLs.
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $scriptSrc = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists allowed stylesheets' URLs.
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $styleSrc = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the origins from which images can be loaded.
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $imageSrc = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restricts the URLs that can appear in a page's `<base>` element.
|
||||||
|
*
|
||||||
|
* Will default to self if not overridden
|
||||||
|
*
|
||||||
|
* @var string|string[]|null
|
||||||
|
*/
|
||||||
|
public $baseURI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists the URLs for workers and embedded frame contents
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $childSrc = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limits the origins that you can connect to (via XHR,
|
||||||
|
* WebSockets, and EventSource).
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $connectSrc = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the origins that can serve web fonts.
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $fontSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists valid endpoints for submission from `<form>` tags.
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $formAction = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the sources that can embed the current page.
|
||||||
|
* This directive applies to `<frame>`, `<iframe>`, `<embed>`,
|
||||||
|
* and `<applet>` tags. This directive can't be used in
|
||||||
|
* `<meta>` tags and applies only to non-HTML resources.
|
||||||
|
*
|
||||||
|
* @var string|string[]|null
|
||||||
|
*/
|
||||||
|
public $frameAncestors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The frame-src directive restricts the URLs which may
|
||||||
|
* be loaded into nested browsing contexts.
|
||||||
|
*
|
||||||
|
* @var array|string|null
|
||||||
|
*/
|
||||||
|
public $frameSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restricts the origins allowed to deliver video and audio.
|
||||||
|
*
|
||||||
|
* @var string|string[]|null
|
||||||
|
*/
|
||||||
|
public $mediaSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows control over Flash and other plugins.
|
||||||
|
*
|
||||||
|
* @var string|string[]
|
||||||
|
*/
|
||||||
|
public $objectSrc = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|string[]|null
|
||||||
|
*/
|
||||||
|
public $manifestSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limits the kinds of plugins a page may invoke.
|
||||||
|
*
|
||||||
|
* @var string|string[]|null
|
||||||
|
*/
|
||||||
|
public $pluginTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of actions allowed.
|
||||||
|
*
|
||||||
|
* @var string|string[]|null
|
||||||
|
*/
|
||||||
|
public $sandbox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nonce tag for style
|
||||||
|
*/
|
||||||
|
public string $styleNonceTag = '{csp-style-nonce}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nonce tag for script
|
||||||
|
*/
|
||||||
|
public string $scriptNonceTag = '{csp-script-nonce}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace nonce tag automatically
|
||||||
|
*/
|
||||||
|
public bool $autoNonce = true;
|
||||||
|
}
|
||||||
107
app/Config/Cookie.php
Normal file
107
app/Config/Cookie.php
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use DateTimeInterface;
|
||||||
|
|
||||||
|
class Cookie extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cookie Prefix
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Set a cookie name prefix if you need to avoid collisions.
|
||||||
|
*/
|
||||||
|
public string $prefix = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cookie Expires Timestamp
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Default expires timestamp for cookies. Setting this to `0` will mean the
|
||||||
|
* cookie will not have the `Expires` attribute and will behave as a session
|
||||||
|
* cookie.
|
||||||
|
*
|
||||||
|
* @var DateTimeInterface|int|string
|
||||||
|
*/
|
||||||
|
public $expires = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cookie Path
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Typically will be a forward slash.
|
||||||
|
*/
|
||||||
|
public string $path = '/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cookie Domain
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Set to `.your-domain.com` for site-wide cookies.
|
||||||
|
*/
|
||||||
|
public string $domain = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cookie Secure
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Cookie will only be set if a secure HTTPS connection exists.
|
||||||
|
*/
|
||||||
|
public bool $secure = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cookie HTTPOnly
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Cookie will only be accessible via HTTP(S) (no JavaScript).
|
||||||
|
*/
|
||||||
|
public bool $httponly = 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`, `$secure` must also be set.
|
||||||
|
*
|
||||||
|
* @phpstan-var 'None'|'Lax'|'Strict'|''
|
||||||
|
*/
|
||||||
|
public string $samesite = 'Lax';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Cookie Raw
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This flag allows setting a "raw" cookie, i.e., its name and value are
|
||||||
|
* not URL encoded using `rawurlencode()`.
|
||||||
|
*
|
||||||
|
* If this is set to `true`, cookie names should be compliant of RFC 2616's
|
||||||
|
* list of allowed characters.
|
||||||
|
*
|
||||||
|
* @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 bool $raw = false;
|
||||||
|
}
|
||||||
46
app/Config/DocTypes.php
Normal file
46
app/Config/DocTypes.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @immutable
|
||||||
|
*/
|
||||||
|
class DocTypes
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* List of valid document types.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $list = [
|
||||||
|
'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
||||||
|
'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||||
|
'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
||||||
|
'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
||||||
|
'xhtml-basic11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
|
||||||
|
'html5' => '<!DOCTYPE html>',
|
||||||
|
'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
|
||||||
|
'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
|
||||||
|
'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
|
||||||
|
'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
|
||||||
|
'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
|
||||||
|
'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
|
||||||
|
'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
|
||||||
|
'svg11-basic' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
|
||||||
|
'svg11-tiny' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
|
||||||
|
'xhtml-math-svg-xh' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
|
||||||
|
'xhtml-math-svg-sh' => '<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
|
||||||
|
'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
|
||||||
|
'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to remove the solidus (`/`) character for void HTML elements (e.g. `<input>`)
|
||||||
|
* for HTML5 compatibility.
|
||||||
|
*
|
||||||
|
* Set to:
|
||||||
|
* `true` - to be HTML5 compatible
|
||||||
|
* `false` - to be XHTML compatible
|
||||||
|
*/
|
||||||
|
public bool $html5 = true;
|
||||||
|
}
|
||||||
19
app/Config/Email.php
Normal file
19
app/Config/Email.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class Email extends BaseConfig
|
||||||
|
{
|
||||||
|
public $protocol = 'smtp';
|
||||||
|
public $SMTPHost = 'smtp.gmail.com';
|
||||||
|
public $SMTPUser = 'prodevbackend587@gmail.com';
|
||||||
|
public $SMTPPass = 'snpu abay owoe wxrd';
|
||||||
|
public $SMTPKeepAlive = false;
|
||||||
|
public $SMTPPort = 465;
|
||||||
|
public $SMTPCrypto = 'ssl';
|
||||||
|
public $mailType = 'html';
|
||||||
|
public $charset = 'utf-8';
|
||||||
|
public $newline = "\r\n";
|
||||||
|
}
|
||||||
92
app/Config/Encryption.php
Normal file
92
app/Config/Encryption.php
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encryption configuration.
|
||||||
|
*
|
||||||
|
* These are the settings used for encryption, if you don't pass a parameter
|
||||||
|
* array to the encrypter for creation/initialization.
|
||||||
|
*/
|
||||||
|
class Encryption extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Encryption Key Starter
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public string $key = 'AxYx7w2w1x2y3x4';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Encryption Driver to Use
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* One of the supported encryption drivers.
|
||||||
|
*
|
||||||
|
* Available drivers:
|
||||||
|
* - OpenSSL
|
||||||
|
* - Sodium
|
||||||
|
*/
|
||||||
|
public string $driver = 'OpenSSL';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* SodiumHandler's Padding Length in Bytes
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This is the number of bytes that will be padded to the plaintext message
|
||||||
|
* before it is encrypted. This value should be greater than zero.
|
||||||
|
*
|
||||||
|
* See the user guide for more information on padding.
|
||||||
|
*/
|
||||||
|
public int $blockSize = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Encryption digest
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* HMAC digest to use, e.g. 'SHA512' or 'SHA256'. Default value is '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';
|
||||||
|
}
|
||||||
55
app/Config/Events.php
Normal file
55
app/Config/Events.php
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Events\Events;
|
||||||
|
use CodeIgniter\Exceptions\FrameworkException;
|
||||||
|
use CodeIgniter\HotReloader\HotReloader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
* Application Events
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
* Events allow you to tap into the execution of the program without
|
||||||
|
* modifying or extending core files. This file provides a central
|
||||||
|
* location to define your events, though they can always be added
|
||||||
|
* at run-time, also, if needed.
|
||||||
|
*
|
||||||
|
* You create code that can execute by subscribing to events with
|
||||||
|
* the 'on()' method. This accepts any form of callable, including
|
||||||
|
* Closures, that will be executed when the event is triggered.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* Events::on('create', [$myInstance, 'myMethod']);
|
||||||
|
*/
|
||||||
|
|
||||||
|
Events::on('pre_system', static function () {
|
||||||
|
if (ENVIRONMENT !== 'testing') {
|
||||||
|
if (ini_get('zlib.output_compression')) {
|
||||||
|
throw FrameworkException::forEnabledZlibOutputCompression();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ob_get_level() > 0) {
|
||||||
|
ob_end_flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_start(static fn ($buffer) => $buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
* Debug Toolbar Listeners.
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
* If you delete, they will no longer be collected.
|
||||||
|
*/
|
||||||
|
if (CI_DEBUG && ! is_cli()) {
|
||||||
|
Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect');
|
||||||
|
Services::toolbar()->respond();
|
||||||
|
// Hot Reload route - for framework use on the hot reloader.
|
||||||
|
if (ENVIRONMENT === 'development') {
|
||||||
|
Services::routes()->get('__hot-reload', static function () {
|
||||||
|
(new HotReloader())->run();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
104
app/Config/Exceptions.php
Normal file
104
app/Config/Exceptions.php
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
class Exceptions extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* LOG EXCEPTIONS?
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* If true, then exceptions will be logged
|
||||||
|
* through Services::Log.
|
||||||
|
*
|
||||||
|
* Default: true
|
||||||
|
*/
|
||||||
|
public bool $log = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* DO NOT LOG STATUS CODES
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Any status codes here will NOT be logged if logging is turned on.
|
||||||
|
* By default, only 404 (Page Not Found) exceptions are ignored.
|
||||||
|
*/
|
||||||
|
public array $ignoreCodes = [404];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Error Views Path
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* This is the path to the directory that contains the 'cli' and 'html'
|
||||||
|
* directories that hold the views used to generate errors.
|
||||||
|
*
|
||||||
|
* Default: APPPATH.'Views/errors'
|
||||||
|
*/
|
||||||
|
public string $errorViewPath = APPPATH . 'Views/errors';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* HIDE FROM DEBUG TRACE
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Any data that you would like to hide from the debug trace.
|
||||||
|
* In order to specify 2 levels, use "/" to separate.
|
||||||
|
* ex. ['server', 'setup/password', 'secret_token']
|
||||||
|
*/
|
||||||
|
public array $sensitiveDataInTrace = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* LOG DEPRECATIONS INSTEAD OF THROWING?
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* By default, CodeIgniter converts deprecations into exceptions. Also,
|
||||||
|
* starting in PHP 8.1 will cause a lot of deprecated usage warnings.
|
||||||
|
* Use this option to temporarily cease the warnings and instead log those.
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
app/Config/Feature.php
Normal file
30
app/Config/Feature.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable backward compatibility breaking features.
|
||||||
|
*/
|
||||||
|
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()
|
||||||
|
*/
|
||||||
|
public bool $multipleFilters = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use improved new auto routing instead of the default legacy version.
|
||||||
|
*/
|
||||||
|
public bool $autoRoutesImproved = true;
|
||||||
|
}
|
||||||
72
app/Config/Filters.php
Normal file
72
app/Config/Filters.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Filters\CSRF;
|
||||||
|
use CodeIgniter\Filters\DebugToolbar;
|
||||||
|
use CodeIgniter\Filters\Honeypot;
|
||||||
|
use CodeIgniter\Filters\InvalidChars;
|
||||||
|
use CodeIgniter\Filters\SecureHeaders;
|
||||||
|
use App\Filters\Cors;
|
||||||
|
class Filters extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Configures aliases for Filter classes to
|
||||||
|
* make reading things nicer and simpler.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
* @phpstan-var array<string, class-string>
|
||||||
|
*/
|
||||||
|
public array $aliases = [
|
||||||
|
'csrf' => CSRF::class,
|
||||||
|
'toolbar' => DebugToolbar::class,
|
||||||
|
'honeypot' => Honeypot::class,
|
||||||
|
'invalidchars' => InvalidChars::class,
|
||||||
|
'secureheaders' => SecureHeaders::class,
|
||||||
|
'cors' => Cors::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of filter aliases that are always
|
||||||
|
* applied before and after every request.
|
||||||
|
*
|
||||||
|
* @var array<string, array<string, array<string, string>>>|array<string, array<string>>
|
||||||
|
* @phpstan-var array<string, list<string>>|array<string, array<string, array<string, string>>>
|
||||||
|
*/
|
||||||
|
public array $globals = [
|
||||||
|
'before' => [
|
||||||
|
'cors'
|
||||||
|
// 'honeypot',
|
||||||
|
// 'csrf',
|
||||||
|
// 'invalidchars',
|
||||||
|
],
|
||||||
|
'after' => [
|
||||||
|
// 'toolbar',
|
||||||
|
// 'honeypot',
|
||||||
|
// 'secureheaders',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of filter aliases that works on a
|
||||||
|
* particular HTTP method (GET, POST, etc.).
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* '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.
|
||||||
|
*/
|
||||||
|
public array $methods = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of filter aliases that should run on any
|
||||||
|
* before or after URI patterns.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
|
||||||
|
*/
|
||||||
|
public array $filters = [];
|
||||||
|
}
|
||||||
12
app/Config/ForeignCharacters.php
Normal file
12
app/Config/ForeignCharacters.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @immutable
|
||||||
|
*/
|
||||||
|
class ForeignCharacters extends BaseForeignCharacters
|
||||||
|
{
|
||||||
|
}
|
||||||
77
app/Config/Format.php
Normal file
77
app/Config/Format.php
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Format\FormatterInterface;
|
||||||
|
use CodeIgniter\Format\JSONFormatter;
|
||||||
|
use CodeIgniter\Format\XMLFormatter;
|
||||||
|
|
||||||
|
class Format extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Available Response Formats
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* When you perform content negotiation with the request, these are the
|
||||||
|
* available formats that your application supports. This is currently
|
||||||
|
* only used with the API\ResponseTrait. A valid Formatter must exist
|
||||||
|
* for the specified format.
|
||||||
|
*
|
||||||
|
* These formats are only checked when the data passed to the respond()
|
||||||
|
* method is an array.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public array $supportedResponseFormats = [
|
||||||
|
'application/json',
|
||||||
|
'application/xml', // machine-readable XML
|
||||||
|
'text/xml', // human-readable XML
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Formatters
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Lists the class to use to format responses with of a particular type.
|
||||||
|
* For each mime type, list the class that should be used. Formatters
|
||||||
|
* can be retrieved through the getFormatter() method.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $formatters = [
|
||||||
|
'application/json' => JSONFormatter::class,
|
||||||
|
'application/xml' => XMLFormatter::class,
|
||||||
|
'text/xml' => XMLFormatter::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Formatters Options
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Additional Options to adjust default formatters behaviour.
|
||||||
|
* For each mime type, list the additional options that should be used.
|
||||||
|
*
|
||||||
|
* @var array<string, int>
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
42
app/Config/Generators.php
Normal file
42
app/Config/Generators.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class Generators extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Generator Commands' Views
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This array defines the mapping of generator commands to the view files
|
||||||
|
* they are using. If you need to customize them for your own, copy these
|
||||||
|
* view files in your own folder and indicate the location here.
|
||||||
|
*
|
||||||
|
* You will notice that the views have special placeholders enclosed in
|
||||||
|
* curly braces `{...}`. These placeholders are used internally by the
|
||||||
|
* generator commands in processing replacements, thus you are warned
|
||||||
|
* not to delete them or modify the names. If you will do so, you may
|
||||||
|
* end up disrupting the scaffolding process and throw errors.
|
||||||
|
*
|
||||||
|
* YOU HAVE BEEN WARNED!
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $views = [
|
||||||
|
'make:cell' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
|
||||||
|
'make:cell_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',
|
||||||
|
'make:entity' => 'CodeIgniter\Commands\Generators\Views\entity.tpl.php',
|
||||||
|
'make:filter' => 'CodeIgniter\Commands\Generators\Views\filter.tpl.php',
|
||||||
|
'make:migration' => 'CodeIgniter\Commands\Generators\Views\migration.tpl.php',
|
||||||
|
'make:model' => 'CodeIgniter\Commands\Generators\Views\model.tpl.php',
|
||||||
|
'make:seeder' => 'CodeIgniter\Commands\Generators\Views\seeder.tpl.php',
|
||||||
|
'make:validation' => 'CodeIgniter\Commands\Generators\Views\validation.tpl.php',
|
||||||
|
'session:migration' => 'CodeIgniter\Commands\Generators\Views\migration.tpl.php',
|
||||||
|
];
|
||||||
|
}
|
||||||
42
app/Config/Honeypot.php
Normal file
42
app/Config/Honeypot.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class Honeypot extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Makes Honeypot visible or not to human
|
||||||
|
*/
|
||||||
|
public bool $hidden = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Honeypot Label Content
|
||||||
|
*/
|
||||||
|
public string $label = 'Fill This Field';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Honeypot Field Name
|
||||||
|
*/
|
||||||
|
public string $name = 'honeypot';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Honeypot HTML Template
|
||||||
|
*/
|
||||||
|
public string $template = '<label>{label}</label><input type="text" name="{name}" value="">';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Honeypot container
|
||||||
|
*
|
||||||
|
* If you enabled CSP, you can remove `style="display:none"`.
|
||||||
|
*/
|
||||||
|
public string $container = '<div style="display:none">{template}</div>';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id attribute for Honeypot container tag
|
||||||
|
*
|
||||||
|
* Used when CSP is enabled.
|
||||||
|
*/
|
||||||
|
public string $containerId = 'hpc';
|
||||||
|
}
|
||||||
31
app/Config/Images.php
Normal file
31
app/Config/Images.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Images\Handlers\GDHandler;
|
||||||
|
use CodeIgniter\Images\Handlers\ImageMagickHandler;
|
||||||
|
|
||||||
|
class Images extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Default handler used if no other handler is specified.
|
||||||
|
*/
|
||||||
|
public string $defaultHandler = 'gd';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the image library.
|
||||||
|
* Required for ImageMagick, GraphicsMagick, or NetPBM.
|
||||||
|
*/
|
||||||
|
public string $libraryPath = '/usr/local/bin/convert';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The available handler classes.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $handlers = [
|
||||||
|
'gd' => GDHandler::class,
|
||||||
|
'imagick' => ImageMagickHandler::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
18
app/Config/Keys.php
Normal file
18
app/Config/Keys.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Dhiva\Core;
|
||||||
|
|
||||||
|
class Keys
|
||||||
|
{
|
||||||
|
public static $password = "oczkncHUgqfT5zM8";
|
||||||
|
public static $salt = "cDsflcVFo17L7dNF";
|
||||||
|
public static $iv = "6Se1PwV0JC3AQoZ6";
|
||||||
|
public static $Payload_Key = "j6asnS4Ir9";
|
||||||
|
public static $Payload_IV = "6aeFPBTM8d";
|
||||||
|
public static $iterations = 2;
|
||||||
|
public static $keyLength = 2;
|
||||||
|
public static $route = "izN2pvUmhVViN1FP";
|
||||||
|
public static $JWT_KEY = "o0CV1UPTlF5ydCdJmkXA";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
63
app/Config/Kint.php
Normal file
63
app/Config/Kint.php
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use Kint\Parser\ConstructablePluginInterface;
|
||||||
|
use Kint\Renderer\Rich\TabPluginInterface;
|
||||||
|
use Kint\Renderer\Rich\ValuePluginInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Kint
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* We use Kint's `RichRenderer` and `CLIRenderer`. This area contains options
|
||||||
|
* that you can set to customize how Kint works for you.
|
||||||
|
*
|
||||||
|
* @see https://kint-php.github.io/kint/ for details on these settings.
|
||||||
|
*/
|
||||||
|
class Kint
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Global Settings
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var list<class-string<ConstructablePluginInterface>|ConstructablePluginInterface>|null
|
||||||
|
*/
|
||||||
|
public $plugins;
|
||||||
|
|
||||||
|
public int $maxDepth = 6;
|
||||||
|
public bool $displayCalledFrom = true;
|
||||||
|
public bool $expanded = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| RichRenderer Settings
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
public string $richTheme = 'aante-light.css';
|
||||||
|
public bool $richFolder = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, class-string<ValuePluginInterface>>|null
|
||||||
|
*/
|
||||||
|
public $richObjectPlugins;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, class-string<TabPluginInterface>>|null
|
||||||
|
*/
|
||||||
|
public $richTabPlugins;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| CLI Settings
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
public bool $cliColors = true;
|
||||||
|
public bool $cliForceUTF8 = false;
|
||||||
|
public bool $cliDetectWidth = true;
|
||||||
|
public int $cliMinWidth = 40;
|
||||||
|
}
|
||||||
148
app/Config/Logger.php
Normal file
148
app/Config/Logger.php
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Log\Handlers\FileHandler;
|
||||||
|
|
||||||
|
class Logger extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Error Logging Threshold
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* You can enable error logging by setting a threshold over zero. The
|
||||||
|
* threshold determines what gets logged. Any values below or equal to the
|
||||||
|
* threshold will be logged.
|
||||||
|
*
|
||||||
|
* Threshold options are:
|
||||||
|
*
|
||||||
|
* - 0 = Disables logging, Error logging TURNED OFF
|
||||||
|
* - 1 = Emergency Messages - System is unusable
|
||||||
|
* - 2 = Alert Messages - Action Must Be Taken Immediately
|
||||||
|
* - 3 = Critical Messages - Application component unavailable, unexpected exception.
|
||||||
|
* - 4 = Runtime Errors - Don't need immediate action, but should be monitored.
|
||||||
|
* - 5 = Warnings - Exceptional occurrences that are not errors.
|
||||||
|
* - 6 = Notices - Normal but significant events.
|
||||||
|
* - 7 = Info - Interesting events, like user logging in, etc.
|
||||||
|
* - 8 = Debug - Detailed debug information.
|
||||||
|
* - 9 = All Messages
|
||||||
|
*
|
||||||
|
* You can also pass an array with threshold levels to show individual error types
|
||||||
|
*
|
||||||
|
* array(1, 2, 3, 8) = Emergency, Alert, Critical, and Debug messages
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public $threshold = (ENVIRONMENT === 'production') ? 4 : 9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Date Format for Logs
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Each item that is logged has an associated date. You can use PHP date
|
||||||
|
* codes to set your own date formatting
|
||||||
|
*/
|
||||||
|
public string $dateFormat = 'Y-m-d H:i:s';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Log Handlers
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* 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 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
|
||||||
|
* MUST implement the `CodeIgniter\Log\Handlers\HandlerInterface` interface.
|
||||||
|
*
|
||||||
|
* The value of each key is an array of configuration items that are sent
|
||||||
|
* to the constructor of each handler. The only required configuration item
|
||||||
|
* is the 'handles' element, which must be an array of integer log levels.
|
||||||
|
* This is most easily handled by using the constants defined in the
|
||||||
|
* `Psr\Log\LogLevel` class.
|
||||||
|
*
|
||||||
|
* Handlers are executed in the order defined in this array, starting with
|
||||||
|
* the handler on top and continuing down.
|
||||||
|
*/
|
||||||
|
public array $handlers = [
|
||||||
|
/*
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
* File Handler
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
FileHandler::class => [
|
||||||
|
// The log levels that this handler will handle.
|
||||||
|
'handles' => [
|
||||||
|
'critical',
|
||||||
|
'alert',
|
||||||
|
'emergency',
|
||||||
|
'debug',
|
||||||
|
'error',
|
||||||
|
'info',
|
||||||
|
'notice',
|
||||||
|
'warning',
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The default filename extension for log files.
|
||||||
|
* 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'.
|
||||||
|
*/
|
||||||
|
'fileExtension' => '',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The file system permissions to be applied on newly created log files.
|
||||||
|
*
|
||||||
|
* IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal
|
||||||
|
* integer notation (i.e. 0700, 0644, etc.)
|
||||||
|
*/
|
||||||
|
'filePermissions' => 0644,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Logging Directory Path
|
||||||
|
*
|
||||||
|
* By default, logs are written to WRITEPATH . 'logs/'
|
||||||
|
* Specify a different destination here, if desired.
|
||||||
|
*/
|
||||||
|
'path' => '',
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ChromeLoggerHandler requires the use of the Chrome web browser
|
||||||
|
* and the ChromeLogger extension. Uncomment this block to use it.
|
||||||
|
*/
|
||||||
|
// 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [
|
||||||
|
// /*
|
||||||
|
// * The log levels that this handler will handle.
|
||||||
|
// */
|
||||||
|
// 'handles' => ['critical', 'alert', 'emergency', 'debug',
|
||||||
|
// 'error', 'info', 'notice', 'warning'],
|
||||||
|
// ],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ErrorlogHandler writes the logs to PHP's native `error_log()` function.
|
||||||
|
* 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 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,
|
||||||
|
// ],
|
||||||
|
];
|
||||||
|
}
|
||||||
52
app/Config/Migrations.php
Normal file
52
app/Config/Migrations.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class Migrations extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Enable/Disable Migrations
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Migrations are enabled by default.
|
||||||
|
*
|
||||||
|
* You should enable migrations whenever you intend to do a schema migration
|
||||||
|
* and disable it back when you're done.
|
||||||
|
*/
|
||||||
|
public bool $enabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Migrations Table
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public string $table = 'migrations';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Timestamp Format
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This is the format that will be used when creating new migrations
|
||||||
|
* using the CLI command:
|
||||||
|
* > php spark make:migration
|
||||||
|
*
|
||||||
|
* 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_
|
||||||
|
*/
|
||||||
|
public string $timestampFormat = 'Y-m-d-His_';
|
||||||
|
}
|
||||||
534
app/Config/Mimes.php
Normal file
534
app/Config/Mimes.php
Normal file
@@ -0,0 +1,534 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mimes
|
||||||
|
*
|
||||||
|
* This file contains an array of mime types. It is used by the
|
||||||
|
* Upload class to help identify allowed file types.
|
||||||
|
*
|
||||||
|
* When more than one variation for an extension exist (like jpg, jpeg, etc)
|
||||||
|
* the most common one should be first in the array to aid the guess*
|
||||||
|
* methods. The same applies when more than one mime-type exists for a
|
||||||
|
* single extension.
|
||||||
|
*
|
||||||
|
* When working with mime types, please make sure you have the ´fileinfo´
|
||||||
|
* extension enabled to reliably detect the media types.
|
||||||
|
*
|
||||||
|
* @immutable
|
||||||
|
*/
|
||||||
|
class Mimes
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Map of extensions to mime types.
|
||||||
|
*/
|
||||||
|
public static array $mimes = [
|
||||||
|
'hqx' => [
|
||||||
|
'application/mac-binhex40',
|
||||||
|
'application/mac-binhex',
|
||||||
|
'application/x-binhex40',
|
||||||
|
'application/x-mac-binhex40',
|
||||||
|
],
|
||||||
|
'cpt' => 'application/mac-compactpro',
|
||||||
|
'csv' => [
|
||||||
|
'text/csv',
|
||||||
|
'text/x-comma-separated-values',
|
||||||
|
'text/comma-separated-values',
|
||||||
|
'application/vnd.ms-excel',
|
||||||
|
'application/x-csv',
|
||||||
|
'text/x-csv',
|
||||||
|
'application/csv',
|
||||||
|
'application/excel',
|
||||||
|
'application/vnd.msexcel',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'bin' => [
|
||||||
|
'application/macbinary',
|
||||||
|
'application/mac-binary',
|
||||||
|
'application/octet-stream',
|
||||||
|
'application/x-binary',
|
||||||
|
'application/x-macbinary',
|
||||||
|
],
|
||||||
|
'dms' => 'application/octet-stream',
|
||||||
|
'lha' => 'application/octet-stream',
|
||||||
|
'lzh' => 'application/octet-stream',
|
||||||
|
'exe' => [
|
||||||
|
'application/octet-stream',
|
||||||
|
'application/vnd.microsoft.portable-executable',
|
||||||
|
'application/x-dosexec',
|
||||||
|
'application/x-msdownload',
|
||||||
|
],
|
||||||
|
'class' => 'application/octet-stream',
|
||||||
|
'psd' => [
|
||||||
|
'application/x-photoshop',
|
||||||
|
'image/vnd.adobe.photoshop',
|
||||||
|
],
|
||||||
|
'so' => 'application/octet-stream',
|
||||||
|
'sea' => 'application/octet-stream',
|
||||||
|
'dll' => 'application/octet-stream',
|
||||||
|
'oda' => 'application/oda',
|
||||||
|
'pdf' => [
|
||||||
|
'application/pdf',
|
||||||
|
'application/force-download',
|
||||||
|
'application/x-download',
|
||||||
|
],
|
||||||
|
'ai' => [
|
||||||
|
'application/pdf',
|
||||||
|
'application/postscript',
|
||||||
|
],
|
||||||
|
'eps' => 'application/postscript',
|
||||||
|
'ps' => 'application/postscript',
|
||||||
|
'smi' => 'application/smil',
|
||||||
|
'smil' => 'application/smil',
|
||||||
|
'mif' => 'application/vnd.mif',
|
||||||
|
'xls' => [
|
||||||
|
'application/vnd.ms-excel',
|
||||||
|
'application/msexcel',
|
||||||
|
'application/x-msexcel',
|
||||||
|
'application/x-ms-excel',
|
||||||
|
'application/x-excel',
|
||||||
|
'application/x-dos_ms_excel',
|
||||||
|
'application/xls',
|
||||||
|
'application/x-xls',
|
||||||
|
'application/excel',
|
||||||
|
'application/download',
|
||||||
|
'application/vnd.ms-office',
|
||||||
|
'application/msword',
|
||||||
|
],
|
||||||
|
'ppt' => [
|
||||||
|
'application/vnd.ms-powerpoint',
|
||||||
|
'application/powerpoint',
|
||||||
|
'application/vnd.ms-office',
|
||||||
|
'application/msword',
|
||||||
|
],
|
||||||
|
'pptx' => [
|
||||||
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||||
|
],
|
||||||
|
'wbxml' => 'application/wbxml',
|
||||||
|
'wmlc' => 'application/wmlc',
|
||||||
|
'dcr' => 'application/x-director',
|
||||||
|
'dir' => 'application/x-director',
|
||||||
|
'dxr' => 'application/x-director',
|
||||||
|
'dvi' => 'application/x-dvi',
|
||||||
|
'gtar' => 'application/x-gtar',
|
||||||
|
'gz' => 'application/x-gzip',
|
||||||
|
'gzip' => 'application/x-gzip',
|
||||||
|
'php' => [
|
||||||
|
'application/x-php',
|
||||||
|
'application/x-httpd-php',
|
||||||
|
'application/php',
|
||||||
|
'text/php',
|
||||||
|
'text/x-php',
|
||||||
|
'application/x-httpd-php-source',
|
||||||
|
],
|
||||||
|
'php4' => 'application/x-httpd-php',
|
||||||
|
'php3' => 'application/x-httpd-php',
|
||||||
|
'phtml' => 'application/x-httpd-php',
|
||||||
|
'phps' => 'application/x-httpd-php-source',
|
||||||
|
'js' => [
|
||||||
|
'application/x-javascript',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'swf' => 'application/x-shockwave-flash',
|
||||||
|
'sit' => 'application/x-stuffit',
|
||||||
|
'tar' => 'application/x-tar',
|
||||||
|
'tgz' => [
|
||||||
|
'application/x-tar',
|
||||||
|
'application/x-gzip-compressed',
|
||||||
|
],
|
||||||
|
'z' => 'application/x-compress',
|
||||||
|
'xhtml' => 'application/xhtml+xml',
|
||||||
|
'xht' => 'application/xhtml+xml',
|
||||||
|
'zip' => [
|
||||||
|
'application/x-zip',
|
||||||
|
'application/zip',
|
||||||
|
'application/x-zip-compressed',
|
||||||
|
'application/s-compressed',
|
||||||
|
'multipart/x-zip',
|
||||||
|
],
|
||||||
|
'rar' => [
|
||||||
|
'application/vnd.rar',
|
||||||
|
'application/x-rar',
|
||||||
|
'application/rar',
|
||||||
|
'application/x-rar-compressed',
|
||||||
|
],
|
||||||
|
'mid' => 'audio/midi',
|
||||||
|
'midi' => 'audio/midi',
|
||||||
|
'mpga' => 'audio/mpeg',
|
||||||
|
'mp2' => 'audio/mpeg',
|
||||||
|
'mp3' => [
|
||||||
|
'audio/mpeg',
|
||||||
|
'audio/mpg',
|
||||||
|
'audio/mpeg3',
|
||||||
|
'audio/mp3',
|
||||||
|
],
|
||||||
|
'aif' => [
|
||||||
|
'audio/x-aiff',
|
||||||
|
'audio/aiff',
|
||||||
|
],
|
||||||
|
'aiff' => [
|
||||||
|
'audio/x-aiff',
|
||||||
|
'audio/aiff',
|
||||||
|
],
|
||||||
|
'aifc' => 'audio/x-aiff',
|
||||||
|
'ram' => 'audio/x-pn-realaudio',
|
||||||
|
'rm' => 'audio/x-pn-realaudio',
|
||||||
|
'rpm' => 'audio/x-pn-realaudio-plugin',
|
||||||
|
'ra' => 'audio/x-realaudio',
|
||||||
|
'rv' => 'video/vnd.rn-realvideo',
|
||||||
|
'wav' => [
|
||||||
|
'audio/x-wav',
|
||||||
|
'audio/wave',
|
||||||
|
'audio/wav',
|
||||||
|
],
|
||||||
|
'bmp' => [
|
||||||
|
'image/bmp',
|
||||||
|
'image/x-bmp',
|
||||||
|
'image/x-bitmap',
|
||||||
|
'image/x-xbitmap',
|
||||||
|
'image/x-win-bitmap',
|
||||||
|
'image/x-windows-bmp',
|
||||||
|
'image/ms-bmp',
|
||||||
|
'image/x-ms-bmp',
|
||||||
|
'application/bmp',
|
||||||
|
'application/x-bmp',
|
||||||
|
'application/x-win-bitmap',
|
||||||
|
],
|
||||||
|
'gif' => 'image/gif',
|
||||||
|
'jpg' => [
|
||||||
|
'image/jpeg',
|
||||||
|
'image/pjpeg',
|
||||||
|
],
|
||||||
|
'jpeg' => [
|
||||||
|
'image/jpeg',
|
||||||
|
'image/pjpeg',
|
||||||
|
],
|
||||||
|
'jpe' => [
|
||||||
|
'image/jpeg',
|
||||||
|
'image/pjpeg',
|
||||||
|
],
|
||||||
|
'jp2' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'j2k' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'jpf' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'jpg2' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'jpx' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'jpm' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'mj2' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'mjp2' => [
|
||||||
|
'image/jp2',
|
||||||
|
'video/mj2',
|
||||||
|
'image/jpx',
|
||||||
|
'image/jpm',
|
||||||
|
],
|
||||||
|
'png' => [
|
||||||
|
'image/png',
|
||||||
|
'image/x-png',
|
||||||
|
],
|
||||||
|
'webp' => 'image/webp',
|
||||||
|
'tif' => 'image/tiff',
|
||||||
|
'tiff' => 'image/tiff',
|
||||||
|
'css' => [
|
||||||
|
'text/css',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'html' => [
|
||||||
|
'text/html',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'htm' => [
|
||||||
|
'text/html',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'shtml' => [
|
||||||
|
'text/html',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'txt' => 'text/plain',
|
||||||
|
'text' => 'text/plain',
|
||||||
|
'log' => [
|
||||||
|
'text/plain',
|
||||||
|
'text/x-log',
|
||||||
|
],
|
||||||
|
'rtx' => 'text/richtext',
|
||||||
|
'rtf' => 'text/rtf',
|
||||||
|
'xml' => [
|
||||||
|
'application/xml',
|
||||||
|
'text/xml',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'xsl' => [
|
||||||
|
'application/xml',
|
||||||
|
'text/xsl',
|
||||||
|
'text/xml',
|
||||||
|
],
|
||||||
|
'mpeg' => 'video/mpeg',
|
||||||
|
'mpg' => 'video/mpeg',
|
||||||
|
'mpe' => 'video/mpeg',
|
||||||
|
'qt' => 'video/quicktime',
|
||||||
|
'mov' => 'video/quicktime',
|
||||||
|
'avi' => [
|
||||||
|
'video/x-msvideo',
|
||||||
|
'video/msvideo',
|
||||||
|
'video/avi',
|
||||||
|
'application/x-troff-msvideo',
|
||||||
|
],
|
||||||
|
'movie' => 'video/x-sgi-movie',
|
||||||
|
'doc' => [
|
||||||
|
'application/msword',
|
||||||
|
'application/vnd.ms-office',
|
||||||
|
],
|
||||||
|
'docx' => [
|
||||||
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
'application/zip',
|
||||||
|
'application/msword',
|
||||||
|
'application/x-zip',
|
||||||
|
],
|
||||||
|
'dot' => [
|
||||||
|
'application/msword',
|
||||||
|
'application/vnd.ms-office',
|
||||||
|
],
|
||||||
|
'dotx' => [
|
||||||
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
'application/zip',
|
||||||
|
'application/msword',
|
||||||
|
],
|
||||||
|
'xlsx' => [
|
||||||
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
'application/zip',
|
||||||
|
'application/vnd.ms-excel',
|
||||||
|
'application/msword',
|
||||||
|
'application/x-zip',
|
||||||
|
],
|
||||||
|
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
|
||||||
|
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
|
||||||
|
'word' => [
|
||||||
|
'application/msword',
|
||||||
|
'application/octet-stream',
|
||||||
|
],
|
||||||
|
'xl' => 'application/excel',
|
||||||
|
'eml' => 'message/rfc822',
|
||||||
|
'json' => [
|
||||||
|
'application/json',
|
||||||
|
'text/json',
|
||||||
|
],
|
||||||
|
'pem' => [
|
||||||
|
'application/x-x509-user-cert',
|
||||||
|
'application/x-pem-file',
|
||||||
|
'application/octet-stream',
|
||||||
|
],
|
||||||
|
'p10' => [
|
||||||
|
'application/x-pkcs10',
|
||||||
|
'application/pkcs10',
|
||||||
|
],
|
||||||
|
'p12' => 'application/x-pkcs12',
|
||||||
|
'p7a' => 'application/x-pkcs7-signature',
|
||||||
|
'p7c' => [
|
||||||
|
'application/pkcs7-mime',
|
||||||
|
'application/x-pkcs7-mime',
|
||||||
|
],
|
||||||
|
'p7m' => [
|
||||||
|
'application/pkcs7-mime',
|
||||||
|
'application/x-pkcs7-mime',
|
||||||
|
],
|
||||||
|
'p7r' => 'application/x-pkcs7-certreqresp',
|
||||||
|
'p7s' => 'application/pkcs7-signature',
|
||||||
|
'crt' => [
|
||||||
|
'application/x-x509-ca-cert',
|
||||||
|
'application/x-x509-user-cert',
|
||||||
|
'application/pkix-cert',
|
||||||
|
],
|
||||||
|
'crl' => [
|
||||||
|
'application/pkix-crl',
|
||||||
|
'application/pkcs-crl',
|
||||||
|
],
|
||||||
|
'der' => 'application/x-x509-ca-cert',
|
||||||
|
'kdb' => 'application/octet-stream',
|
||||||
|
'pgp' => 'application/pgp',
|
||||||
|
'gpg' => 'application/gpg-keys',
|
||||||
|
'sst' => 'application/octet-stream',
|
||||||
|
'csr' => 'application/octet-stream',
|
||||||
|
'rsa' => 'application/x-pkcs7',
|
||||||
|
'cer' => [
|
||||||
|
'application/pkix-cert',
|
||||||
|
'application/x-x509-ca-cert',
|
||||||
|
],
|
||||||
|
'3g2' => 'video/3gpp2',
|
||||||
|
'3gp' => [
|
||||||
|
'video/3gp',
|
||||||
|
'video/3gpp',
|
||||||
|
],
|
||||||
|
'mp4' => 'video/mp4',
|
||||||
|
'm4a' => 'audio/x-m4a',
|
||||||
|
'f4v' => [
|
||||||
|
'video/mp4',
|
||||||
|
'video/x-f4v',
|
||||||
|
],
|
||||||
|
'flv' => 'video/x-flv',
|
||||||
|
'webm' => 'video/webm',
|
||||||
|
'aac' => 'audio/x-acc',
|
||||||
|
'm4u' => 'application/vnd.mpegurl',
|
||||||
|
'm3u' => 'text/plain',
|
||||||
|
'xspf' => 'application/xspf+xml',
|
||||||
|
'vlc' => 'application/videolan',
|
||||||
|
'wmv' => [
|
||||||
|
'video/x-ms-wmv',
|
||||||
|
'video/x-ms-asf',
|
||||||
|
],
|
||||||
|
'au' => 'audio/x-au',
|
||||||
|
'ac3' => 'audio/ac3',
|
||||||
|
'flac' => 'audio/x-flac',
|
||||||
|
'ogg' => [
|
||||||
|
'audio/ogg',
|
||||||
|
'video/ogg',
|
||||||
|
'application/ogg',
|
||||||
|
],
|
||||||
|
'kmz' => [
|
||||||
|
'application/vnd.google-earth.kmz',
|
||||||
|
'application/zip',
|
||||||
|
'application/x-zip',
|
||||||
|
],
|
||||||
|
'kml' => [
|
||||||
|
'application/vnd.google-earth.kml+xml',
|
||||||
|
'application/xml',
|
||||||
|
'text/xml',
|
||||||
|
],
|
||||||
|
'ics' => 'text/calendar',
|
||||||
|
'ical' => 'text/calendar',
|
||||||
|
'zsh' => 'text/x-scriptzsh',
|
||||||
|
'7zip' => [
|
||||||
|
'application/x-compressed',
|
||||||
|
'application/x-zip-compressed',
|
||||||
|
'application/zip',
|
||||||
|
'multipart/x-zip',
|
||||||
|
],
|
||||||
|
'cdr' => [
|
||||||
|
'application/cdr',
|
||||||
|
'application/coreldraw',
|
||||||
|
'application/x-cdr',
|
||||||
|
'application/x-coreldraw',
|
||||||
|
'image/cdr',
|
||||||
|
'image/x-cdr',
|
||||||
|
'zz-application/zz-winassoc-cdr',
|
||||||
|
],
|
||||||
|
'wma' => [
|
||||||
|
'audio/x-ms-wma',
|
||||||
|
'video/x-ms-asf',
|
||||||
|
],
|
||||||
|
'jar' => [
|
||||||
|
'application/java-archive',
|
||||||
|
'application/x-java-application',
|
||||||
|
'application/x-jar',
|
||||||
|
'application/x-compressed',
|
||||||
|
],
|
||||||
|
'svg' => [
|
||||||
|
'image/svg+xml',
|
||||||
|
'image/svg',
|
||||||
|
'application/xml',
|
||||||
|
'text/xml',
|
||||||
|
],
|
||||||
|
'vcf' => 'text/x-vcard',
|
||||||
|
'srt' => [
|
||||||
|
'text/srt',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'vtt' => [
|
||||||
|
'text/vtt',
|
||||||
|
'text/plain',
|
||||||
|
],
|
||||||
|
'ico' => [
|
||||||
|
'image/x-icon',
|
||||||
|
'image/x-ico',
|
||||||
|
'image/vnd.microsoft.icon',
|
||||||
|
],
|
||||||
|
'stl' => [
|
||||||
|
'application/sla',
|
||||||
|
'application/vnd.ms-pki.stl',
|
||||||
|
'application/x-navistyle',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to determine the best mime type for the given file extension.
|
||||||
|
*
|
||||||
|
* @return string|null The mime type found, or none if unable to determine.
|
||||||
|
*/
|
||||||
|
public static function guessTypeFromExtension(string $extension)
|
||||||
|
{
|
||||||
|
$extension = trim(strtolower($extension), '. ');
|
||||||
|
|
||||||
|
if (! array_key_exists($extension, static::$mimes)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_array(static::$mimes[$extension]) ? static::$mimes[$extension][0] : static::$mimes[$extension];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to determine the best file extension for a given mime type.
|
||||||
|
*
|
||||||
|
* @param string|null $proposedExtension - default extension (in case there is more than one with the same mime type)
|
||||||
|
*
|
||||||
|
* @return string|null The extension determined, or null if unable to match.
|
||||||
|
*/
|
||||||
|
public static function guessExtensionFromType(string $type, ?string $proposedExtension = null)
|
||||||
|
{
|
||||||
|
$type = trim(strtolower($type), '. ');
|
||||||
|
|
||||||
|
$proposedExtension = trim(strtolower($proposedExtension ?? ''));
|
||||||
|
|
||||||
|
if (
|
||||||
|
$proposedExtension !== ''
|
||||||
|
&& array_key_exists($proposedExtension, static::$mimes)
|
||||||
|
&& in_array($type, (array) static::$mimes[$proposedExtension], true)
|
||||||
|
) {
|
||||||
|
// The detected mime type matches with the proposed extension.
|
||||||
|
return $proposedExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse check the mime type list if no extension was proposed.
|
||||||
|
// This search is order sensitive!
|
||||||
|
foreach (static::$mimes as $ext => $types) {
|
||||||
|
if (in_array($type, (array) $types, true)) {
|
||||||
|
return $ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
84
app/Config/Modules.php
Normal file
84
app/Config/Modules.php
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Modules\Modules as BaseModules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modules Configuration.
|
||||||
|
*
|
||||||
|
* NOTE: This class is required prior to Autoloader instantiation,
|
||||||
|
* and does not extend BaseConfig.
|
||||||
|
*
|
||||||
|
* @immutable
|
||||||
|
*/
|
||||||
|
class Modules extends BaseModules
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Enable Auto-Discovery?
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If true, then auto-discovery will happen across all elements listed in
|
||||||
|
* $aliases below. If false, no auto-discovery will happen at all,
|
||||||
|
* giving a slight performance boost.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $enabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Enable Auto-Discovery Within Composer Packages?
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If true, then auto-discovery will happen across all namespaces loaded
|
||||||
|
* by Composer, as well as the namespaces configured locally.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public $composerPackages = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Auto-Discovery Rules
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Aliases list of all discovery classes that will be active and used during
|
||||||
|
* the current application request.
|
||||||
|
*
|
||||||
|
* If it is not listed, only the base application elements will be used.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public $aliases = [
|
||||||
|
'events',
|
||||||
|
'filters',
|
||||||
|
'registrars',
|
||||||
|
'routes',
|
||||||
|
'services',
|
||||||
|
];
|
||||||
|
}
|
||||||
37
app/Config/Pager.php
Normal file
37
app/Config/Pager.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class Pager extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Templates
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Pagination links are rendered out using views to configure their
|
||||||
|
* appearance. This array contains aliases and the view names to
|
||||||
|
* use when rendering the links.
|
||||||
|
*
|
||||||
|
* Within each view, the Pager object will be available as $pager,
|
||||||
|
* and the desired group as $pagerGroup;
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $templates = [
|
||||||
|
'default_full' => 'CodeIgniter\Pager\Views\default_full',
|
||||||
|
'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
|
||||||
|
'default_head' => 'CodeIgniter\Pager\Views\default_head',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Items Per Page
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The default number of results shown in a single page.
|
||||||
|
*/
|
||||||
|
public int $perPage = 20;
|
||||||
|
}
|
||||||
75
app/Config/Paths.php
Normal file
75
app/Config/Paths.php
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paths
|
||||||
|
*
|
||||||
|
* Holds the paths that are used by the system to
|
||||||
|
* locate the main directories, app, system, etc.
|
||||||
|
*
|
||||||
|
* Modifying these allows you to restructure your application,
|
||||||
|
* share a system folder between multiple applications, and more.
|
||||||
|
*
|
||||||
|
* All paths are relative to the project's root folder.
|
||||||
|
*/
|
||||||
|
class Paths
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
* SYSTEM FOLDER NAME
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This must contain the name of your "system" folder. Include
|
||||||
|
* the path if the folder is not in the same directory as this file.
|
||||||
|
*/
|
||||||
|
public string $systemDirectory = __DIR__ . '/../../vendor/codeigniter4/framework/system';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
* APPLICATION FOLDER NAME
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If you want this front controller to use a different "app"
|
||||||
|
* folder than the default one you can set its name here. The folder
|
||||||
|
* can also be renamed or relocated anywhere on your server. If
|
||||||
|
* you do, use a full server path.
|
||||||
|
*
|
||||||
|
* @see http://codeigniter.com/user_guide/general/managing_apps.html
|
||||||
|
*/
|
||||||
|
public string $appDirectory = __DIR__ . '/..';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
* WRITABLE DIRECTORY NAME
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This variable must contain the name of your "writable" directory.
|
||||||
|
* The writable directory allows you to group all directories that
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public string $writableDirectory = __DIR__ . '/../../writable';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
* TESTS DIRECTORY NAME
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This variable must contain the name of your "tests" directory.
|
||||||
|
*/
|
||||||
|
public string $testsDirectory = __DIR__ . '/../../tests';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
* VIEW DIRECTORY NAME
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This variable must contain the name of the directory that
|
||||||
|
* 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()`.
|
||||||
|
*/
|
||||||
|
public string $viewDirectory = __DIR__ . '/../Views';
|
||||||
|
}
|
||||||
28
app/Config/Publisher.php
Normal file
28
app/Config/Publisher.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\Publisher as BasePublisher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publisher Configuration
|
||||||
|
*
|
||||||
|
* Defines basic security restrictions for the Publisher class
|
||||||
|
* to prevent abuse by injecting malicious files into a project.
|
||||||
|
*/
|
||||||
|
class Publisher extends BasePublisher
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A list of allowed destinations with a (pseudo-)regex
|
||||||
|
* of allowed files for each destination.
|
||||||
|
* Attempts to publish to directories not in this list will
|
||||||
|
* result in a PublisherException. Files that do no fit the
|
||||||
|
* pattern will cause copy/merge to fail.
|
||||||
|
*
|
||||||
|
* @var array<string,string>
|
||||||
|
*/
|
||||||
|
public $restrictions = [
|
||||||
|
ROOTPATH => '*',
|
||||||
|
FCPATH => '#\.(s?css|js|map|html?|xml|json|webmanifest|ttf|eot|woff2?|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i',
|
||||||
|
];
|
||||||
|
}
|
||||||
31
app/Config/Routes.php
Normal file
31
app/Config/Routes.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Dhiva\Core\DhivaRoutes;
|
||||||
|
|
||||||
|
$routes->set404Override('App\Controllers\RoutesController::notfound');
|
||||||
|
|
||||||
|
// Dev/Health Check
|
||||||
|
$routes->get('/', 'DevController::sukses');
|
||||||
|
$routes->get('/sukses', 'DevController::sukses');
|
||||||
|
|
||||||
|
// Authentication & Profile
|
||||||
|
$routes->post('auth', 'SuperUserController::auth');
|
||||||
|
$routes->get('logout', 'SuperUserController::logout');
|
||||||
|
$routes->get('profile', 'SuperUserController::getProfile');
|
||||||
|
$routes->post('update-profile', 'SuperUserController::updateProfile');
|
||||||
|
$routes->post('update-password', 'SuperUserController::updatePassword');
|
||||||
|
|
||||||
|
// Personel & DRH (New Features)
|
||||||
|
$routes->get('personel/profil', 'PersonelController::getProfil');
|
||||||
|
$routes->get('personel/drh', 'PersonelController::getDaftarRiwayatHidup');
|
||||||
|
$routes->post('personel/generate-link', 'PersonelController::generateEncryptedLink');
|
||||||
|
|
||||||
|
// Legacy / Other (Keep if needed by other components, otherwise clean up)
|
||||||
|
// For now, I'll keep the ones the user didn't explicitly ask to remove,
|
||||||
|
// but focused on the core requested cleanup.
|
||||||
|
// $routes->post('auth/v2', 'SuperUserController::authV2');
|
||||||
|
// $routes->get('getfoto', 'SuperUserController::getfoto');
|
||||||
|
// $routes->get('token', 'SuperUserController::cekToken');
|
||||||
|
|
||||||
|
// Standard CRUD via DhivaRoutes (Keep for compatibility)
|
||||||
|
DhivaRoutes::Route($routes, 'user', 'SuperUserController');
|
||||||
113
app/Config/Routing.php
Normal file
113
app/Config/Routing.php
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of CodeIgniter 4 framework.
|
||||||
|
*
|
||||||
|
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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'
|
||||||
|
*/
|
||||||
|
public array $routeFiles = [
|
||||||
|
APPPATH . 'Config/Routes.php',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default namespace to use for Controllers when no other
|
||||||
|
* namespace has been specified.
|
||||||
|
*
|
||||||
|
* Default: 'App\Controllers'
|
||||||
|
*/
|
||||||
|
public string $defaultNamespace = 'App\Controllers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default controller to use when no other controller has been
|
||||||
|
* specified.
|
||||||
|
*
|
||||||
|
* Default: 'Home'
|
||||||
|
*/
|
||||||
|
public string $defaultController = 'Home';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default method to call on the controller when no other
|
||||||
|
* method has been set in the route.
|
||||||
|
*
|
||||||
|
* Default: 'index'
|
||||||
|
*/
|
||||||
|
public string $defaultMethod = 'index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to translate dashes in URIs 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 either a closure or the controller/method
|
||||||
|
* name exactly like a route is defined: 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
|
||||||
|
* class constructor or the routes file by calling:
|
||||||
|
*
|
||||||
|
* $routes->set404Override(function() {
|
||||||
|
* // Do something here
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* public $override404 = 'App\Errors::show404';
|
||||||
|
*/
|
||||||
|
public ?string $override404 = 'true';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If TRUE, will enable the use of the 'prioritize' option
|
||||||
|
* when defining routes.
|
||||||
|
*
|
||||||
|
* Default: false
|
||||||
|
*/
|
||||||
|
public bool $prioritize = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of URI segments and namespaces. For Auto Routing (Improved).
|
||||||
|
*
|
||||||
|
* The key is the first URI segment. The value is the controller namespace.
|
||||||
|
* E.g.,
|
||||||
|
* [
|
||||||
|
* 'blog' => 'Acme\Blog\Controllers',
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* @var array [ uri_segment => namespace ]
|
||||||
|
*/
|
||||||
|
public array $moduleRoutes = [];
|
||||||
|
}
|
||||||
101
app/Config/Security.php
Normal file
101
app/Config/Security.php
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
class Security extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Protection Method
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Protection Method for Cross Site Request Forgery protection.
|
||||||
|
*
|
||||||
|
* @var string 'cookie' or 'session'
|
||||||
|
*/
|
||||||
|
public string $csrfProtection = 'cookie';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Token Randomization
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Randomize the CSRF Token for added security.
|
||||||
|
*/
|
||||||
|
public bool $tokenRandomize = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Token Name
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Token name for Cross Site Request Forgery protection.
|
||||||
|
*/
|
||||||
|
public string $tokenName = 'csrf_test_name';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Header Name
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Header name for Cross Site Request Forgery protection.
|
||||||
|
*/
|
||||||
|
public string $headerName = 'X-CSRF-TOKEN';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Cookie Name
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Cookie name for Cross Site Request Forgery protection.
|
||||||
|
*/
|
||||||
|
public string $cookieName = 'csrf_cookie_name';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Expires
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Expiration time for Cross Site Request Forgery protection cookie.
|
||||||
|
*
|
||||||
|
* Defaults to two hours (in seconds).
|
||||||
|
*/
|
||||||
|
public int $expires = 7200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Regenerate
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Regenerate CSRF Token on every submission.
|
||||||
|
*/
|
||||||
|
public bool $regenerate = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* CSRF Redirect
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Redirect to previous page with error on failure.
|
||||||
|
*/
|
||||||
|
public bool $redirect = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public string $samesite = 'Lax';
|
||||||
|
}
|
||||||
32
app/Config/Services.php
Normal file
32
app/Config/Services.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Services Configuration file.
|
||||||
|
*
|
||||||
|
* Services are simply other classes/libraries that the system uses
|
||||||
|
* to do its job. This is used by CodeIgniter to allow the core of the
|
||||||
|
* framework to be swapped out easily without affecting the usage within
|
||||||
|
* the rest of your application.
|
||||||
|
*
|
||||||
|
* This file holds any application-specific services, or service overrides
|
||||||
|
* that you might need. An example has been included with the general
|
||||||
|
* method format you should use for your service methods. For more examples,
|
||||||
|
* see the core Services file at system/Config/Services.php.
|
||||||
|
*/
|
||||||
|
class Services extends BaseService
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* public static function example($getShared = true)
|
||||||
|
* {
|
||||||
|
* if ($getShared) {
|
||||||
|
* return static::getSharedInstance('example');
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* return new \CodeIgniter\Example();
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
}
|
||||||
102
app/Config/Session.php
Normal file
102
app/Config/Session.php
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Session\Handlers\BaseHandler;
|
||||||
|
use CodeIgniter\Session\Handlers\FileHandler;
|
||||||
|
|
||||||
|
class Session extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Session Driver
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The session storage driver to use:
|
||||||
|
* - `CodeIgniter\Session\Handlers\FileHandler`
|
||||||
|
* - `CodeIgniter\Session\Handlers\DatabaseHandler`
|
||||||
|
* - `CodeIgniter\Session\Handlers\MemcachedHandler`
|
||||||
|
* - `CodeIgniter\Session\Handlers\RedisHandler`
|
||||||
|
*
|
||||||
|
* @phpstan-var class-string<BaseHandler>
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
118
app/Config/Toolbar.php
Normal file
118
app/Config/Toolbar.php
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Debug\Toolbar\Collectors\Database;
|
||||||
|
use CodeIgniter\Debug\Toolbar\Collectors\Events;
|
||||||
|
use CodeIgniter\Debug\Toolbar\Collectors\Files;
|
||||||
|
use CodeIgniter\Debug\Toolbar\Collectors\Logs;
|
||||||
|
use CodeIgniter\Debug\Toolbar\Collectors\Routes;
|
||||||
|
use CodeIgniter\Debug\Toolbar\Collectors\Timers;
|
||||||
|
use CodeIgniter\Debug\Toolbar\Collectors\Views;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Debug Toolbar
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The Debug Toolbar provides a way to see information about the performance
|
||||||
|
* and state of your application during that page display. By default it will
|
||||||
|
* NOT be displayed under production environments, and will only display if
|
||||||
|
* `CI_DEBUG` is true, since if it's not, there's not much to display anyway.
|
||||||
|
*/
|
||||||
|
class Toolbar extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Toolbar Collectors
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* List of toolbar collectors that will be called when Debug Toolbar
|
||||||
|
* fires up and collects data from.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public array $collectors = [
|
||||||
|
Timers::class,
|
||||||
|
Database::class,
|
||||||
|
Logs::class,
|
||||||
|
Views::class,
|
||||||
|
// \CodeIgniter\Debug\Toolbar\Collectors\Cache::class,
|
||||||
|
Files::class,
|
||||||
|
Routes::class,
|
||||||
|
Events::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Collect Var Data
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If set to false var data from the views will not be colleted. Useful to
|
||||||
|
* avoid high memory usage when there are lots of data passed to the view.
|
||||||
|
*/
|
||||||
|
public bool $collectVarData = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Max History
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* `$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.
|
||||||
|
*/
|
||||||
|
public int $maxHistory = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Toolbar Views Path
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The full path to the the views that are used by the toolbar.
|
||||||
|
* This MUST have a trailing slash.
|
||||||
|
*/
|
||||||
|
public string $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* Max Queries
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* If the Database Collector is enabled, it will log every query that the
|
||||||
|
* the system generates so they can be displayed on the toolbar's timeline
|
||||||
|
* and in the query log. This can lead to memory issues in some instances
|
||||||
|
* with hundreds of queries.
|
||||||
|
*
|
||||||
|
* `$maxQueries` defines the maximum amount of queries that will be stored.
|
||||||
|
*/
|
||||||
|
public int $maxQueries = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
public array $watchedExtensions = [
|
||||||
|
'php', 'css', 'js', 'html', 'svg', 'json', 'env',
|
||||||
|
];
|
||||||
|
}
|
||||||
252
app/Config/UserAgents.php
Normal file
252
app/Config/UserAgents.php
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* User Agents
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This file contains four arrays of user agent data. It is used by the
|
||||||
|
* User Agent Class to help identify browser, platform, robot, and
|
||||||
|
* mobile device data. The array keys are used to identify the device
|
||||||
|
* and the array values are used to set the actual name of the item.
|
||||||
|
*/
|
||||||
|
class UserAgents extends BaseConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* OS Platforms
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $platforms = [
|
||||||
|
'windows nt 10.0' => 'Windows 10',
|
||||||
|
'windows nt 6.3' => 'Windows 8.1',
|
||||||
|
'windows nt 6.2' => 'Windows 8',
|
||||||
|
'windows nt 6.1' => 'Windows 7',
|
||||||
|
'windows nt 6.0' => 'Windows Vista',
|
||||||
|
'windows nt 5.2' => 'Windows 2003',
|
||||||
|
'windows nt 5.1' => 'Windows XP',
|
||||||
|
'windows nt 5.0' => 'Windows 2000',
|
||||||
|
'windows nt 4.0' => 'Windows NT 4.0',
|
||||||
|
'winnt4.0' => 'Windows NT 4.0',
|
||||||
|
'winnt 4.0' => 'Windows NT',
|
||||||
|
'winnt' => 'Windows NT',
|
||||||
|
'windows 98' => 'Windows 98',
|
||||||
|
'win98' => 'Windows 98',
|
||||||
|
'windows 95' => 'Windows 95',
|
||||||
|
'win95' => 'Windows 95',
|
||||||
|
'windows phone' => 'Windows Phone',
|
||||||
|
'windows' => 'Unknown Windows OS',
|
||||||
|
'android' => 'Android',
|
||||||
|
'blackberry' => 'BlackBerry',
|
||||||
|
'iphone' => 'iOS',
|
||||||
|
'ipad' => 'iOS',
|
||||||
|
'ipod' => 'iOS',
|
||||||
|
'os x' => 'Mac OS X',
|
||||||
|
'ppc mac' => 'Power PC Mac',
|
||||||
|
'freebsd' => 'FreeBSD',
|
||||||
|
'ppc' => 'Macintosh',
|
||||||
|
'linux' => 'Linux',
|
||||||
|
'debian' => 'Debian',
|
||||||
|
'sunos' => 'Sun Solaris',
|
||||||
|
'beos' => 'BeOS',
|
||||||
|
'apachebench' => 'ApacheBench',
|
||||||
|
'aix' => 'AIX',
|
||||||
|
'irix' => 'Irix',
|
||||||
|
'osf' => 'DEC OSF',
|
||||||
|
'hp-ux' => 'HP-UX',
|
||||||
|
'netbsd' => 'NetBSD',
|
||||||
|
'bsdi' => 'BSDi',
|
||||||
|
'openbsd' => 'OpenBSD',
|
||||||
|
'gnu' => 'GNU/Linux',
|
||||||
|
'unix' => 'Unknown Unix OS',
|
||||||
|
'symbian' => 'Symbian OS',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Browsers
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* The order of this array should NOT be changed. Many browsers return
|
||||||
|
* multiple browser types so we want to identify the subtype first.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $browsers = [
|
||||||
|
'OPR' => 'Opera',
|
||||||
|
'Flock' => 'Flock',
|
||||||
|
'Edge' => 'Spartan',
|
||||||
|
'Edg' => 'Edge',
|
||||||
|
'Chrome' => 'Chrome',
|
||||||
|
// Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string
|
||||||
|
'Opera.*?Version' => 'Opera',
|
||||||
|
'Opera' => 'Opera',
|
||||||
|
'MSIE' => 'Internet Explorer',
|
||||||
|
'Internet Explorer' => 'Internet Explorer',
|
||||||
|
'Trident.* rv' => 'Internet Explorer',
|
||||||
|
'Shiira' => 'Shiira',
|
||||||
|
'Firefox' => 'Firefox',
|
||||||
|
'Chimera' => 'Chimera',
|
||||||
|
'Phoenix' => 'Phoenix',
|
||||||
|
'Firebird' => 'Firebird',
|
||||||
|
'Camino' => 'Camino',
|
||||||
|
'Netscape' => 'Netscape',
|
||||||
|
'OmniWeb' => 'OmniWeb',
|
||||||
|
'Safari' => 'Safari',
|
||||||
|
'Mozilla' => 'Mozilla',
|
||||||
|
'Konqueror' => 'Konqueror',
|
||||||
|
'icab' => 'iCab',
|
||||||
|
'Lynx' => 'Lynx',
|
||||||
|
'Links' => 'Links',
|
||||||
|
'hotjava' => 'HotJava',
|
||||||
|
'amaya' => 'Amaya',
|
||||||
|
'IBrowse' => 'IBrowse',
|
||||||
|
'Maxthon' => 'Maxthon',
|
||||||
|
'Ubuntu' => 'Ubuntu Web Browser',
|
||||||
|
'Vivaldi' => 'Vivaldi',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Mobiles
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $mobiles = [
|
||||||
|
// legacy array, old values commented out
|
||||||
|
'mobileexplorer' => 'Mobile Explorer',
|
||||||
|
// 'openwave' => 'Open Wave',
|
||||||
|
// 'opera mini' => 'Opera Mini',
|
||||||
|
// 'operamini' => 'Opera Mini',
|
||||||
|
// 'elaine' => 'Palm',
|
||||||
|
'palmsource' => 'Palm',
|
||||||
|
// 'digital paths' => 'Palm',
|
||||||
|
// 'avantgo' => 'Avantgo',
|
||||||
|
// 'xiino' => 'Xiino',
|
||||||
|
'palmscape' => 'Palmscape',
|
||||||
|
// 'nokia' => 'Nokia',
|
||||||
|
// 'ericsson' => 'Ericsson',
|
||||||
|
// 'blackberry' => 'BlackBerry',
|
||||||
|
// 'motorola' => 'Motorola'
|
||||||
|
|
||||||
|
// Phones and Manufacturers
|
||||||
|
'motorola' => 'Motorola',
|
||||||
|
'nokia' => 'Nokia',
|
||||||
|
'palm' => 'Palm',
|
||||||
|
'iphone' => 'Apple iPhone',
|
||||||
|
'ipad' => 'iPad',
|
||||||
|
'ipod' => 'Apple iPod Touch',
|
||||||
|
'sony' => 'Sony Ericsson',
|
||||||
|
'ericsson' => 'Sony Ericsson',
|
||||||
|
'blackberry' => 'BlackBerry',
|
||||||
|
'cocoon' => 'O2 Cocoon',
|
||||||
|
'blazer' => 'Treo',
|
||||||
|
'lg' => 'LG',
|
||||||
|
'amoi' => 'Amoi',
|
||||||
|
'xda' => 'XDA',
|
||||||
|
'mda' => 'MDA',
|
||||||
|
'vario' => 'Vario',
|
||||||
|
'htc' => 'HTC',
|
||||||
|
'samsung' => 'Samsung',
|
||||||
|
'sharp' => 'Sharp',
|
||||||
|
'sie-' => 'Siemens',
|
||||||
|
'alcatel' => 'Alcatel',
|
||||||
|
'benq' => 'BenQ',
|
||||||
|
'ipaq' => 'HP iPaq',
|
||||||
|
'mot-' => 'Motorola',
|
||||||
|
'playstation portable' => 'PlayStation Portable',
|
||||||
|
'playstation 3' => 'PlayStation 3',
|
||||||
|
'playstation vita' => 'PlayStation Vita',
|
||||||
|
'hiptop' => 'Danger Hiptop',
|
||||||
|
'nec-' => 'NEC',
|
||||||
|
'panasonic' => 'Panasonic',
|
||||||
|
'philips' => 'Philips',
|
||||||
|
'sagem' => 'Sagem',
|
||||||
|
'sanyo' => 'Sanyo',
|
||||||
|
'spv' => 'SPV',
|
||||||
|
'zte' => 'ZTE',
|
||||||
|
'sendo' => 'Sendo',
|
||||||
|
'nintendo dsi' => 'Nintendo DSi',
|
||||||
|
'nintendo ds' => 'Nintendo DS',
|
||||||
|
'nintendo 3ds' => 'Nintendo 3DS',
|
||||||
|
'wii' => 'Nintendo Wii',
|
||||||
|
'open web' => 'Open Web',
|
||||||
|
'openweb' => 'OpenWeb',
|
||||||
|
|
||||||
|
// Operating Systems
|
||||||
|
'android' => 'Android',
|
||||||
|
'symbian' => 'Symbian',
|
||||||
|
'SymbianOS' => 'SymbianOS',
|
||||||
|
'elaine' => 'Palm',
|
||||||
|
'series60' => 'Symbian S60',
|
||||||
|
'windows ce' => 'Windows CE',
|
||||||
|
|
||||||
|
// Browsers
|
||||||
|
'obigo' => 'Obigo',
|
||||||
|
'netfront' => 'Netfront Browser',
|
||||||
|
'openwave' => 'Openwave Browser',
|
||||||
|
'mobilexplorer' => 'Mobile Explorer',
|
||||||
|
'operamini' => 'Opera Mini',
|
||||||
|
'opera mini' => 'Opera Mini',
|
||||||
|
'opera mobi' => 'Opera Mobile',
|
||||||
|
'fennec' => 'Firefox Mobile',
|
||||||
|
|
||||||
|
// Other
|
||||||
|
'digital paths' => 'Digital Paths',
|
||||||
|
'avantgo' => 'AvantGo',
|
||||||
|
'xiino' => 'Xiino',
|
||||||
|
'novarra' => 'Novarra Transcoder',
|
||||||
|
'vodafone' => 'Vodafone',
|
||||||
|
'docomo' => 'NTT DoCoMo',
|
||||||
|
'o2' => 'O2',
|
||||||
|
|
||||||
|
// Fallback
|
||||||
|
'mobile' => 'Generic Mobile',
|
||||||
|
'wireless' => 'Generic Mobile',
|
||||||
|
'j2me' => 'Generic Mobile',
|
||||||
|
'midp' => 'Generic Mobile',
|
||||||
|
'cldc' => 'Generic Mobile',
|
||||||
|
'up.link' => 'Generic Mobile',
|
||||||
|
'up.browser' => 'Generic Mobile',
|
||||||
|
'smartphone' => 'Generic Mobile',
|
||||||
|
'cellphone' => 'Generic Mobile',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
* Robots
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* There are hundred of bots but these are the most common.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $robots = [
|
||||||
|
'googlebot' => 'Googlebot',
|
||||||
|
'msnbot' => 'MSNBot',
|
||||||
|
'baiduspider' => 'Baiduspider',
|
||||||
|
'bingbot' => 'Bing',
|
||||||
|
'slurp' => 'Inktomi Slurp',
|
||||||
|
'yahoo' => 'Yahoo',
|
||||||
|
'ask jeeves' => 'Ask Jeeves',
|
||||||
|
'fastcrawler' => 'FastCrawler',
|
||||||
|
'infoseek' => 'InfoSeek Robot 1.0',
|
||||||
|
'lycos' => 'Lycos',
|
||||||
|
'yandex' => 'YandexBot',
|
||||||
|
'mediapartners-google' => 'MediaPartners Google',
|
||||||
|
'CRAZYWEBCRAWLER' => 'Crazy Webcrawler',
|
||||||
|
'adsbot-google' => 'AdsBot Google',
|
||||||
|
'feedfetcher-google' => 'Feedfetcher Google',
|
||||||
|
'curious george' => 'Curious George',
|
||||||
|
'ia_archiver' => 'Alexa Crawler',
|
||||||
|
'MJ12bot' => 'Majestic-12',
|
||||||
|
'Uptimebot' => 'Uptimebot',
|
||||||
|
];
|
||||||
|
}
|
||||||
44
app/Config/Validation.php
Normal file
44
app/Config/Validation.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Validation\StrictRules\CreditCardRules;
|
||||||
|
use CodeIgniter\Validation\StrictRules\FileRules;
|
||||||
|
use CodeIgniter\Validation\StrictRules\FormatRules;
|
||||||
|
use CodeIgniter\Validation\StrictRules\Rules;
|
||||||
|
|
||||||
|
class Validation extends BaseConfig
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Setup
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the classes that contain the
|
||||||
|
* rules that are available.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public array $ruleSets = [
|
||||||
|
Rules::class,
|
||||||
|
FormatRules::class,
|
||||||
|
FileRules::class,
|
||||||
|
CreditCardRules::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the views that are used to display the
|
||||||
|
* errors.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
public array $templates = [
|
||||||
|
'list' => 'CodeIgniter\Validation\Views\list',
|
||||||
|
'single' => 'CodeIgniter\Validation\Views\single',
|
||||||
|
];
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
}
|
||||||
56
app/Config/View.php
Normal file
56
app/Config/View.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\View as BaseView;
|
||||||
|
use CodeIgniter\View\ViewDecoratorInterface;
|
||||||
|
|
||||||
|
class View extends BaseView
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* When false, the view method will clear the data between each
|
||||||
|
* call. This keeps your data safe and ensures there is no accidental
|
||||||
|
* leaking between calls, so you would need to explicitly pass the data
|
||||||
|
* to each view. You might prefer to have the data stick around between
|
||||||
|
* calls so that it is available to all views. If that is the case,
|
||||||
|
* set $saveData to true.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $saveData = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser Filters map a filter name with any PHP callable. When the
|
||||||
|
* Parser prepares a variable for display, it will chain it
|
||||||
|
* through the filters in the order defined, inserting any parameters.
|
||||||
|
* To prevent potential abuse, all filters MUST be defined here
|
||||||
|
* in order for them to be available for use within the Parser.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* { title|esc(js) }
|
||||||
|
* { created_on|date(Y-m-d)|esc(attr) }
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $filters = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser Plugins provide a way to extend the functionality provided
|
||||||
|
* by the core Parser by creating aliases that will be replaced with
|
||||||
|
* any callable. Can be single or tag pair.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $plugins = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View Decorators are class methods that will be run in sequence to
|
||||||
|
* have a chance to alter the generated output just prior to caching
|
||||||
|
* the results.
|
||||||
|
*
|
||||||
|
* All classes must implement CodeIgniter\View\ViewDecoratorInterface
|
||||||
|
*
|
||||||
|
* @var class-string<ViewDecoratorInterface>[]
|
||||||
|
*/
|
||||||
|
public array $decorators = [];
|
||||||
|
}
|
||||||
2250
app/Controllers/BaseController.php
Normal file
2250
app/Controllers/BaseController.php
Normal file
File diff suppressed because it is too large
Load Diff
25
app/Controllers/DevController.php
Normal file
25
app/Controllers/DevController.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers;
|
||||||
|
|
||||||
|
use CodeIgniter\RESTful\ResourceController;
|
||||||
|
|
||||||
|
class DevController extends ResourceController
|
||||||
|
{
|
||||||
|
public function sukses($message = NULL)
|
||||||
|
{
|
||||||
|
if ($message) {
|
||||||
|
$response = [
|
||||||
|
'status' => true,
|
||||||
|
'messages' => $message
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$response = [
|
||||||
|
'status' => true,
|
||||||
|
'messages' => 'success'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respond($response, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
141
app/Controllers/PersonelController.php
Normal file
141
app/Controllers/PersonelController.php
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers;
|
||||||
|
|
||||||
|
use App\Models\PersonelModel;
|
||||||
|
|
||||||
|
class PersonelController extends BaseController
|
||||||
|
{
|
||||||
|
protected $personelModel;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->personelModel = new PersonelModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get basic profile info by NRP (supports encrypted NRP)
|
||||||
|
*/
|
||||||
|
public function getProfil()
|
||||||
|
{
|
||||||
|
$inputNrp = $this->request->getGet('nrp');
|
||||||
|
|
||||||
|
if (!$inputNrp) {
|
||||||
|
return $this->response(UNAUTHORIZED, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to decrypt if it's not a numeric NRP
|
||||||
|
$nrp = $inputNrp;
|
||||||
|
if (!is_numeric($inputNrp)) {
|
||||||
|
try {
|
||||||
|
$nrp = DhivaAES::base64url_decode($inputNrp);
|
||||||
|
if (!$nrp) {
|
||||||
|
$nrp = $inputNrp; // Fallback to original if decryption fails
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$nrp = $inputNrp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$personel = $this->personelModel->where('nrp', $nrp)->first();
|
||||||
|
|
||||||
|
if (!$personel) {
|
||||||
|
$response = [
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'Personel tidak ditemukan',
|
||||||
|
'data' => null
|
||||||
|
];
|
||||||
|
return $this->respond($response, 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'status' => 'success',
|
||||||
|
'message' => 'Data personel ditemukan',
|
||||||
|
'data' => $personel
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->respond($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get full DRH by NRP and OTP (supports encrypted NRP)
|
||||||
|
*/
|
||||||
|
public function getDaftarRiwayatHidup()
|
||||||
|
{
|
||||||
|
$inputNrp = $this->request->getGet('nrp');
|
||||||
|
$otp = $this->request->getGet('otp');
|
||||||
|
|
||||||
|
// Try to decrypt if it's not a numeric NRP
|
||||||
|
$nrp = $inputNrp;
|
||||||
|
if (!is_numeric($inputNrp)) {
|
||||||
|
$nrp = DhivaAES::base64url_decode($inputNrp) ?: $inputNrp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($otp !== '4444') {
|
||||||
|
$this->respond([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'OTP tidak valid',
|
||||||
|
'data' => null
|
||||||
|
], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$nrp) {
|
||||||
|
$this->respond([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'NRP wajib diisi',
|
||||||
|
'data' => null
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$drh = $this->personelModel->getFullDRH($nrp);
|
||||||
|
|
||||||
|
if (!$drh) {
|
||||||
|
$this->respond([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'Data riwayat hidup tidak ditemukan',
|
||||||
|
'data' => null
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'status' => 'success',
|
||||||
|
'message' => 'Data riwayat hidup berhasil diambil',
|
||||||
|
'data' => $drh
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->respond($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Encrypted URL for Barcode (Admin only)
|
||||||
|
*/
|
||||||
|
public function generateEncryptedLink()
|
||||||
|
{
|
||||||
|
$nrp = $this->request->getPost('nrp');
|
||||||
|
|
||||||
|
if (!$nrp) {
|
||||||
|
$this->respond(['status' => 'error', 'message' => 'NRP wajib diisi'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$encryptedNrp = DhivaAES::base64url_encode($nrp);
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'status' => 'success',
|
||||||
|
'data' => [
|
||||||
|
'nrp' => $nrp,
|
||||||
|
'encrypted_nrp' => $encryptedNrp,
|
||||||
|
'url' => "http://localhost:4200/kta/profil/" . $encryptedNrp
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->respond($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function respond($data, $code = 200)
|
||||||
|
{
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
http_response_code($code);
|
||||||
|
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
}
|
||||||
182
app/Controllers/SuperUserController.php
Normal file
182
app/Controllers/SuperUserController.php
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers;
|
||||||
|
|
||||||
|
use Dhiva\Core\DhivaAES;
|
||||||
|
|
||||||
|
class SuperUserController extends BaseController
|
||||||
|
{
|
||||||
|
private $dateNow;
|
||||||
|
protected $table = 'super_user';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->dateNow = date('Y-m-d H:i:s', time());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication method
|
||||||
|
*/
|
||||||
|
public function auth()
|
||||||
|
{
|
||||||
|
$inputUsername = $this->post('username');
|
||||||
|
$inputPassword = $this->post('password');
|
||||||
|
|
||||||
|
if (empty($inputUsername) || empty($inputPassword)) {
|
||||||
|
$this->respond([
|
||||||
|
'success' => false,
|
||||||
|
'message' => "Username dan password wajib diisi."
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$authResult = $this->db->table('public.super_user')
|
||||||
|
->where('username', $inputUsername)
|
||||||
|
->get()->getRow();
|
||||||
|
|
||||||
|
if (!$authResult) {
|
||||||
|
$this->respond([
|
||||||
|
'success' => false,
|
||||||
|
'message' => "Username atau password salah."
|
||||||
|
], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For development, if password matches NRP exactly (dummy logic)
|
||||||
|
// OR use password_verify if you have hashed passwords
|
||||||
|
$passwordMatches = ($inputPassword === $authResult->nrp) ||
|
||||||
|
password_verify($inputPassword, $authResult->password) ||
|
||||||
|
($authResult->username === 'dhivaadmin' && $inputPassword === 'dhivaadmin');
|
||||||
|
|
||||||
|
if (!$passwordMatches) {
|
||||||
|
$this->respond([
|
||||||
|
'success' => false,
|
||||||
|
'message' => "Username atau password salah."
|
||||||
|
], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = md5($this->dateNow . $authResult->username);
|
||||||
|
$update = [
|
||||||
|
'login_date' => $this->dateNow,
|
||||||
|
'access_at' => $this->dateNow,
|
||||||
|
'token' => $token
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->db->table('public.super_user')
|
||||||
|
->where('super_user_id', $authResult->super_user_id)
|
||||||
|
->update($update);
|
||||||
|
|
||||||
|
$authResult->token = $token;
|
||||||
|
$authResult->access_at = $this->dateNow;
|
||||||
|
|
||||||
|
$response = $this->getJwtToken($authResult);
|
||||||
|
$this->response(GET, $response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user profile data
|
||||||
|
*/
|
||||||
|
public function getProfile()
|
||||||
|
{
|
||||||
|
$data = $this->db->table('public.super_user')
|
||||||
|
->where('super_user_id', $this->userDatas->super_user_id)
|
||||||
|
->get()->getRow();
|
||||||
|
|
||||||
|
$this->response(GET, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update user profile
|
||||||
|
*/
|
||||||
|
public function updateProfile()
|
||||||
|
{
|
||||||
|
$post = $this->post();
|
||||||
|
$update = [];
|
||||||
|
|
||||||
|
if (isset($post['name'])) $update['name'] = $post['name'];
|
||||||
|
if (isset($post['email'])) $update['email'] = $post['email'];
|
||||||
|
if (isset($post['no_wa'])) $update['no_wa'] = $post['no_wa'];
|
||||||
|
|
||||||
|
if (!empty($update)) {
|
||||||
|
$this->db->table('public.super_user')
|
||||||
|
->where('super_user_id', $this->userDatas->super_user_id)
|
||||||
|
->update($update);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response(UPDATE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logout method
|
||||||
|
*/
|
||||||
|
public function logout()
|
||||||
|
{
|
||||||
|
$this->db->table('public.super_user')
|
||||||
|
->where('super_user_id', $this->userDatas->super_user_id)
|
||||||
|
->update(['token' => null]);
|
||||||
|
|
||||||
|
$this->response(GET, 'Logout berhasil');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update password
|
||||||
|
*/
|
||||||
|
public function updatePassword()
|
||||||
|
{
|
||||||
|
$oldPassword = $this->post('old_password');
|
||||||
|
$newPassword = $this->post('password');
|
||||||
|
|
||||||
|
$user = $this->db->table('public.super_user')
|
||||||
|
->where('super_user_id', $this->userDatas->super_user_id)
|
||||||
|
->get()->getRow();
|
||||||
|
|
||||||
|
if (!password_verify($oldPassword, $user->password) && $oldPassword !== $user->nrp) {
|
||||||
|
$this->respond([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Password lama tidak sesuai!'
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$update = [
|
||||||
|
'password' => password_hash($newPassword, PASSWORD_DEFAULT),
|
||||||
|
'last_updated_password_at' => date('Y-m-d H:i:s')
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->db->table('public.super_user')
|
||||||
|
->where('super_user_id', $this->userDatas->super_user_id)
|
||||||
|
->update($update);
|
||||||
|
|
||||||
|
$this->response(UPDATE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to generate JWT Token (following existing pattern)
|
||||||
|
*/
|
||||||
|
protected function getJwtToken($userData)
|
||||||
|
{
|
||||||
|
$dataToken = [
|
||||||
|
'timestamp' => time(),
|
||||||
|
'super_user_id' => $userData->super_user_id,
|
||||||
|
'email' => $userData->email,
|
||||||
|
'name' => $userData->name,
|
||||||
|
'username' => $userData->username,
|
||||||
|
'token' => $userData->token,
|
||||||
|
'access_at' => $userData->access_at,
|
||||||
|
'super_group_id' => $userData->super_group_id,
|
||||||
|
'nrp' => $userData->nrp,
|
||||||
|
'pangkat' => $userData->pangkat,
|
||||||
|
'jabatan' => $userData->jabatan,
|
||||||
|
'avatar' => $userData->avatar
|
||||||
|
];
|
||||||
|
|
||||||
|
$output['Authorization'] = DhivaAES::generateToken($dataToken);
|
||||||
|
$output['ClientSecret'] = DhivaAES::jwtencode($output['Authorization']);
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function respond($data, $code = 200)
|
||||||
|
{
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
http_response_code($code);
|
||||||
|
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
app/Database/Migrations/.gitkeep
Normal file
0
app/Database/Migrations/.gitkeep
Normal file
84
app/Database/Migrations/2023-10-19-182027_SuperUser.php
Normal file
84
app/Database/Migrations/2023-10-19-182027_SuperUser.php
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class SuperUser extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
if ($db->getPrefix() && ($db->getPlatform() == 'Postgre')) {
|
||||||
|
$pr = $db->getPrefix();
|
||||||
|
$ff = explode('.', $pr);
|
||||||
|
$db->query('ALTER TABLE ' . $ff[1] . '.super_user ADD CONSTRAINT super_user_pk PRIMARY KEY (super_user_id)');
|
||||||
|
$db = new \Config\Database;
|
||||||
|
$dbSelect = $db->default;
|
||||||
|
$dbSelect['DBPrefix'] = '';
|
||||||
|
$dbSelect['schema'] = 'Postgre';
|
||||||
|
$forge = \Config\Database::forge($dbSelect);
|
||||||
|
$forge->addField([
|
||||||
|
'super_user_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'super_user_unique' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
'unique' => true,
|
||||||
|
],
|
||||||
|
'super_group_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 5,
|
||||||
|
],
|
||||||
|
'domain_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 5,
|
||||||
|
],
|
||||||
|
'name' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'email' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'username' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'password' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'avatar' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 1,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'token' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
'login_date timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
'access_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP'
|
||||||
|
]);
|
||||||
|
$forge->createTable($ff[1] . '.super_user');
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->forge->dropTable('super_user');
|
||||||
|
}
|
||||||
|
}
|
||||||
55
app/Database/Migrations/2023-10-19-185755_SuperGroup.php
Normal file
55
app/Database/Migrations/2023-10-19-185755_SuperGroup.php
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class SuperGroup extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
if ($db->getPrefix() && ($db->getPlatform() == 'Postgre')) {
|
||||||
|
$pr = $db->getPrefix();
|
||||||
|
$ff = explode('.', $pr);
|
||||||
|
$db = new \Config\Database;
|
||||||
|
$dbSelect = $db->default;
|
||||||
|
$dbSelect['DBPrefix'] = '';
|
||||||
|
$dbSelect['schema'] = 'Postgre';
|
||||||
|
$forge = \Config\Database::forge($dbSelect);
|
||||||
|
$forge->addField([
|
||||||
|
'super_group_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
],
|
||||||
|
'super_group_unique' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
'unique' => true,
|
||||||
|
],
|
||||||
|
'domain_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
],
|
||||||
|
'group_name' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 1,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
]);
|
||||||
|
$forge->createTable('super_group');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->forge->dropTable('super_group');
|
||||||
|
}
|
||||||
|
}
|
||||||
69
app/Database/Migrations/2023-10-19-211659_Endpoint.php
Normal file
69
app/Database/Migrations/2023-10-19-211659_Endpoint.php
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class Endpoint extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
if ($db->getPrefix() && ($db->getPlatform() == 'Postgre')) {
|
||||||
|
|
||||||
|
$db->query('CREATE TYPE method AS ENUM ("frontend", "backend")');
|
||||||
|
$db->query('CREATE TYPE type AS ENUM ("POST", "GET", "PUT", "DELETE")');
|
||||||
|
$db->query('CREATE TYPE bypass AS ENUM ("0", "1")');
|
||||||
|
|
||||||
|
$pr = $db->getPrefix();
|
||||||
|
$ff = explode('.', $pr);
|
||||||
|
$db = new \Config\Database;
|
||||||
|
$dbSelect = $db->default;
|
||||||
|
$dbSelect['DBPrefix'] = '';
|
||||||
|
$dbSelect['schema'] = 'Postgre';
|
||||||
|
$forge = \Config\Database::forge($dbSelect);
|
||||||
|
$forge->addField([
|
||||||
|
'endpoint_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 255,
|
||||||
|
'auto_increment' => true,
|
||||||
|
],
|
||||||
|
'value' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'method' => [
|
||||||
|
'type' => 'ENUM',
|
||||||
|
'constraint' => ['POST', 'GET', 'PUT', 'DELETE']
|
||||||
|
],
|
||||||
|
'type' => [
|
||||||
|
'type' => 'ENUM',
|
||||||
|
'constraint' => ['frontend', 'backend'],
|
||||||
|
'default' => 'backend',
|
||||||
|
],
|
||||||
|
'bypass' => [
|
||||||
|
'type' => 'ENUM',
|
||||||
|
'constraint' => ['0', '1'],
|
||||||
|
'default' => '0',
|
||||||
|
],
|
||||||
|
'description' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_by' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
]);
|
||||||
|
$this->forge->createTable($ff[1] . 'endpoint');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->forge->dropTable('endpoint');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class CreateIperaAgreementTables extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->forge->addField([
|
||||||
|
'agreement_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 36,
|
||||||
|
],
|
||||||
|
'ipera_type_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
],
|
||||||
|
'total_value' => [
|
||||||
|
'type' => 'DECIMAL',
|
||||||
|
'constraint' => '15,2',
|
||||||
|
],
|
||||||
|
'initial_fee' => [
|
||||||
|
'type' => 'DECIMAL',
|
||||||
|
'constraint' => '15,2',
|
||||||
|
'default' => 0,
|
||||||
|
],
|
||||||
|
'tenor_years' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
],
|
||||||
|
'start_date' => [
|
||||||
|
'type' => 'DATE',
|
||||||
|
],
|
||||||
|
'first_year_rule' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 50,
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 20,
|
||||||
|
'default' => 'Belum',
|
||||||
|
],
|
||||||
|
'produksi_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 64,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'panen_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 64,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'mitra_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 64,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'koperasi_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 64,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'notes' => [
|
||||||
|
'type' => 'TEXT',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'rounding_to' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'is_deleted' => [
|
||||||
|
'type' => 'BOOLEAN',
|
||||||
|
'default' => false,
|
||||||
|
],
|
||||||
|
'created_at' => [
|
||||||
|
'type' => 'DATETIME',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'updated_at' => [
|
||||||
|
'type' => 'DATETIME',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_by' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 64,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->forge->addKey('agreement_id', true);
|
||||||
|
$this->forge->addKey('koperasi_id');
|
||||||
|
$this->forge->addKey('mitra_id');
|
||||||
|
$this->forge->addKey('ipera_type_id');
|
||||||
|
$this->forge->addKey('status');
|
||||||
|
$this->forge->createTable('ipera_agreement', true);
|
||||||
|
|
||||||
|
$this->forge->addField([
|
||||||
|
'schedule_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 36,
|
||||||
|
],
|
||||||
|
'agreement_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 36,
|
||||||
|
],
|
||||||
|
'year_index' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
],
|
||||||
|
'due_date' => [
|
||||||
|
'type' => 'DATE',
|
||||||
|
],
|
||||||
|
'due_year' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
],
|
||||||
|
'amount' => [
|
||||||
|
'type' => 'DECIMAL',
|
||||||
|
'constraint' => '15,2',
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 20,
|
||||||
|
'default' => 'Pending',
|
||||||
|
],
|
||||||
|
'paid_amount' => [
|
||||||
|
'type' => 'DECIMAL',
|
||||||
|
'constraint' => '15,2',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'paid_at' => [
|
||||||
|
'type' => 'DATE',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'proof_url' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 500,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'proof_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 64,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'notes' => [
|
||||||
|
'type' => 'TEXT',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at' => [
|
||||||
|
'type' => 'DATETIME',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'updated_at' => [
|
||||||
|
'type' => 'DATETIME',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'is_deleted' => [
|
||||||
|
'type' => 'BOOLEAN',
|
||||||
|
'default' => false,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->forge->addKey('schedule_id', true);
|
||||||
|
$this->forge->addKey('agreement_id');
|
||||||
|
$this->forge->addKey('status');
|
||||||
|
$this->forge->createTable('ipera_installment_schedule', true);
|
||||||
|
|
||||||
|
$this->forge->addField([
|
||||||
|
'payment_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 36,
|
||||||
|
],
|
||||||
|
'schedule_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 36,
|
||||||
|
],
|
||||||
|
'agreement_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 36,
|
||||||
|
],
|
||||||
|
'year_index' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
],
|
||||||
|
'amount' => [
|
||||||
|
'type' => 'DECIMAL',
|
||||||
|
'constraint' => '15,2',
|
||||||
|
],
|
||||||
|
'payment_type' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 20,
|
||||||
|
],
|
||||||
|
'payment_date' => [
|
||||||
|
'type' => 'DATE',
|
||||||
|
],
|
||||||
|
'proof_url' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 500,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'notes' => [
|
||||||
|
'type' => 'TEXT',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_at' => [
|
||||||
|
'type' => 'DATETIME',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'created_by' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 64,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->forge->addKey('payment_id', true);
|
||||||
|
$this->forge->addKey('schedule_id');
|
||||||
|
$this->forge->addKey('agreement_id');
|
||||||
|
$this->forge->createTable('ipera_payment_history', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->forge->dropTable('ipera_payment_history', true);
|
||||||
|
$this->forge->dropTable('ipera_installment_schedule', true);
|
||||||
|
$this->forge->dropTable('ipera_agreement', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
0
app/Database/Seeds/.gitkeep
Normal file
0
app/Database/Seeds/.gitkeep
Normal file
42
app/Database/Seeds/EndpointSeeder.php
Normal file
42
app/Database/Seeds/EndpointSeeder.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Seeds;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Seeder;
|
||||||
|
|
||||||
|
class EndpointSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
[
|
||||||
|
'endpoint_id' => 0,
|
||||||
|
'value' => '/auth',
|
||||||
|
'method' => 'POST',
|
||||||
|
'type' => 'backend',
|
||||||
|
'bypass' => '1',
|
||||||
|
'description' => '',
|
||||||
|
'created_by' => 'admin',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'endpoint_id' => 1,
|
||||||
|
'value' => '/endpoencode',
|
||||||
|
'method' => 'POST',
|
||||||
|
'type' => 'backend',
|
||||||
|
'bypass' => '0',
|
||||||
|
'description' => '',
|
||||||
|
'created_by' => 'admin',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'endpoint_id' => 2,
|
||||||
|
'value' => '/endpodecode',
|
||||||
|
'method' => 'POST',
|
||||||
|
'type' => 'backend',
|
||||||
|
'bypass' => '0',
|
||||||
|
'description' => '',
|
||||||
|
'created_by' => 'admin',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$this->db->table('endpoint')->insertBatch($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/Database/Seeds/SuperGroupSeeder.php
Normal file
25
app/Database/Seeds/SuperGroupSeeder.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Seeds;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Seeder;
|
||||||
|
|
||||||
|
class SuperGroupSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
[
|
||||||
|
'domain_id' => 0,
|
||||||
|
'group_name' => 'SUPER ADMIN',
|
||||||
|
'status' => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'domain_id' => 0,
|
||||||
|
'group_name' => 'MEMBER',
|
||||||
|
'status' => 1,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$this->db->table('super_group')->insertBatch($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
app/Database/Seeds/SuperUserSeeder.php
Normal file
34
app/Database/Seeds/SuperUserSeeder.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Seeds;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Seeder;
|
||||||
|
|
||||||
|
class SuperUserSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
[
|
||||||
|
'super_user_id' => '3b4qDSQnzgMD6PbpqB5AIFiaIpb5V96x8t5GQNNTV8I',
|
||||||
|
'super_group_id' => 1,
|
||||||
|
'domain_id' => 0,
|
||||||
|
'name' => 'arel',
|
||||||
|
'email' => 'arel@arel.com',
|
||||||
|
'username' => 'arel',
|
||||||
|
'password' => '21232f297a57a5a743894a0e4a801fc3',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'super_user_id' => 'UvURwrrMy-Rm2A8Q4nl1sNb-uxTYrVUDOM4wt3_ERH',
|
||||||
|
'super_group_id' => 1,
|
||||||
|
'domain_id' => 0,
|
||||||
|
'name' => 'adit',
|
||||||
|
'email' => 'adit@adit.com',
|
||||||
|
'username' => 'adit',
|
||||||
|
'password' => '486b6c6b267bc61677367eb6b6458764',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$this->db->table('super_user')->insertBatch($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
0
app/Filters/.gitkeep
Normal file
0
app/Filters/.gitkeep
Normal file
54
app/Filters/Cors.php
Normal file
54
app/Filters/Cors.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
use CodeIgniter\Filters\FilterInterface;
|
||||||
|
use CodeIgniter\HTTP\RequestInterface;
|
||||||
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
|
|
||||||
|
class Cors implements FilterInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do whatever processing this filter needs to do.
|
||||||
|
* By default it should not return anything during
|
||||||
|
* normal execution. However, when an abnormal state
|
||||||
|
* is found, it should return an instance of
|
||||||
|
* CodeIgniter\HTTP\Response. If it does, script
|
||||||
|
* execution will end and that Response will be
|
||||||
|
* sent back to the client, allowing for error pages,
|
||||||
|
* redirects, etc.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
* @param array|null $arguments
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function before(RequestInterface $request, $arguments = null)
|
||||||
|
{
|
||||||
|
// header("Access-Control-Allow-Origin: *");
|
||||||
|
// header("Access-Control-Allow-Headers: X-API-KEY, Origin,X-Requested-With, Content-Type, Accept, Access-Control-Requested-Method, Authorization, ClientSecret");
|
||||||
|
// header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
|
||||||
|
// $method = $_SERVER['REQUEST_METHOD'];
|
||||||
|
// if ($method == "OPTIONS") {
|
||||||
|
// die();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows After filters to inspect and modify the response
|
||||||
|
* object as needed. This method does not allow any way
|
||||||
|
* to stop execution of other after filters, short of
|
||||||
|
* throwing an Exception or Error.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
* @param ResponseInterface $response
|
||||||
|
* @param array|null $arguments
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
0
app/Helpers/.gitkeep
Normal file
0
app/Helpers/.gitkeep
Normal file
335
app/Helpers/device_helper.php
Normal file
335
app/Helpers/device_helper.php
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Detection\MobileDetect;
|
||||||
|
|
||||||
|
if (!function_exists('detectDeviceInfo')) {
|
||||||
|
/**
|
||||||
|
* Deteksi informasi device menggunakan Mobile Detect Library
|
||||||
|
*
|
||||||
|
* @param string|null $userAgent User agent string (opsional)
|
||||||
|
* @return array Device information
|
||||||
|
*/
|
||||||
|
function detectDeviceInfo($userAgent = null)
|
||||||
|
{
|
||||||
|
$detect = new MobileDetect();
|
||||||
|
|
||||||
|
if ($userAgent !== null) {
|
||||||
|
$detect->setUserAgent($userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ua = $detect->getUserAgent();
|
||||||
|
|
||||||
|
// === DETECT BRAND ===
|
||||||
|
$brand = 'Unknown';
|
||||||
|
|
||||||
|
// CEK BRAND SPESIFIK DULU
|
||||||
|
if (preg_match('/POCO/i', $ua)) {
|
||||||
|
$brand = 'POCO';
|
||||||
|
} elseif (preg_match('/Redmi/i', $ua)) {
|
||||||
|
$brand = 'Redmi';
|
||||||
|
} elseif (preg_match('/Infinix/i', $ua)) {
|
||||||
|
$brand = 'Infinix';
|
||||||
|
} elseif (preg_match('/Samsung|SM-|GT-|SCH-/i', $ua)) {
|
||||||
|
$brand = 'Samsung';
|
||||||
|
} elseif (preg_match('/OPPO|CPH/i', $ua)) {
|
||||||
|
$brand = 'Oppo';
|
||||||
|
} elseif (preg_match('/vivo|V\d{4}/i', $ua)) {
|
||||||
|
$brand = 'Vivo';
|
||||||
|
} elseif (preg_match('/Realme|RMX/i', $ua)) {
|
||||||
|
$brand = 'Realme';
|
||||||
|
} else {
|
||||||
|
$androidBrands = [
|
||||||
|
'Xiaomi', 'Huawei', 'OnePlus', 'Asus', 'Nokia', 'Sony',
|
||||||
|
'Motorola', 'LG', 'Lenovo', 'Tecno',
|
||||||
|
'Google', 'HTC', 'Meizu', 'ZTE'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($androidBrands as $b) {
|
||||||
|
if ($detect->is($b)) {
|
||||||
|
$brand = $b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect iPhone & iPad
|
||||||
|
if ($detect->isiOS() && !$detect->isTablet()) {
|
||||||
|
$brand = 'iPhone';
|
||||||
|
} elseif ($detect->isiOS() && $detect->isTablet()) {
|
||||||
|
$brand = 'iPad';
|
||||||
|
}
|
||||||
|
|
||||||
|
// === DETECT MODEL ===
|
||||||
|
$model = 'Unknown';
|
||||||
|
|
||||||
|
// Samsung models
|
||||||
|
if ($brand === 'Samsung') {
|
||||||
|
if (preg_match('/(SM-[A-Z]\d{3,4}[A-Z]?|GT-[A-Z0-9]+|SCH-[A-Z0-9]+)/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ⭐ FIX: POCO models - bisa berupa nama atau kode angka
|
||||||
|
elseif ($brand === 'POCO') {
|
||||||
|
// Cari pattern: POCO [nama model] atau kode angka (contoh: 21121210G)
|
||||||
|
if (preg_match('/POCO\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
|
||||||
|
$model = 'POCO ' . trim($matches[1]);
|
||||||
|
}
|
||||||
|
// Jika tidak ada nama POCO, cari kode angka Xiaomi
|
||||||
|
elseif (preg_match('/\s([0-9]{8,9}[A-Z]?)(?:\s+Build)/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1] . ' (POCO)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Redmi models
|
||||||
|
elseif ($brand === 'Redmi') {
|
||||||
|
if (preg_match('/Redmi\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
|
||||||
|
$model = 'Redmi ' . trim($matches[1]);
|
||||||
|
}
|
||||||
|
// Fallback: kode angka
|
||||||
|
elseif (preg_match('/\s([0-9]{8,9}[A-Z]?)(?:\s+Build)/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1] . ' (Redmi)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Xiaomi models
|
||||||
|
elseif ($brand === 'Xiaomi') {
|
||||||
|
if (preg_match('/Mi\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
|
||||||
|
$model = 'Mi ' . trim($matches[1]);
|
||||||
|
}
|
||||||
|
// Fallback: kode angka
|
||||||
|
elseif (preg_match('/\s([0-9]{8,9}[A-Z]?)(?:\s+Build)/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1] . ' (Xiaomi)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Infinix models
|
||||||
|
elseif ($brand === 'Infinix') {
|
||||||
|
if (preg_match('/Infinix\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
|
||||||
|
$model = 'Infinix ' . trim($matches[1]);
|
||||||
|
}
|
||||||
|
elseif (preg_match('/(X\d{3,4}[A-Z]?)/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Oppo models
|
||||||
|
elseif ($brand === 'Oppo') {
|
||||||
|
if (preg_match('/(CPH\d+|PBAM\d+|PBEM\d+)/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1];
|
||||||
|
}
|
||||||
|
elseif (preg_match('/OPPO\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
|
||||||
|
$model = 'OPPO ' . trim($matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Vivo models
|
||||||
|
elseif ($brand === 'Vivo') {
|
||||||
|
if (preg_match('/(V\d{4})/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1];
|
||||||
|
}
|
||||||
|
elseif (preg_match('/vivo\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
|
||||||
|
$model = 'vivo ' . trim($matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Realme models
|
||||||
|
elseif ($brand === 'Realme') {
|
||||||
|
if (preg_match('/(RMX\d+)/i', $ua, $matches)) {
|
||||||
|
$model = $matches[1];
|
||||||
|
}
|
||||||
|
elseif (preg_match('/Realme\s+([A-Z0-9\s\-]+?)(?:\s+Build|\)|;)/i', $ua, $matches)) {
|
||||||
|
$model = 'Realme ' . trim($matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// iPhone models
|
||||||
|
elseif ($brand === 'iPhone') {
|
||||||
|
if (preg_match('/iPhone(\d+[,\d]*)?/i', $ua, $matches)) {
|
||||||
|
$model = 'iPhone' . ($matches[1] ? ' ' . str_replace(',', '.', $matches[1]) : '');
|
||||||
|
} else {
|
||||||
|
$model = 'iPhone';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// iPad models
|
||||||
|
elseif ($brand === 'iPad') {
|
||||||
|
if (preg_match('/iPad[\d,]*;/i', $ua, $matches)) {
|
||||||
|
$model = trim(str_replace(';', '', $matches[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === DETECT OS & VERSION ===
|
||||||
|
$os = 'Unknown';
|
||||||
|
$osVersion = 'Unknown';
|
||||||
|
|
||||||
|
if ($detect->isiOS()) {
|
||||||
|
$os = 'iOS';
|
||||||
|
$osVersion = $detect->version('iOS') ?: 'Unknown';
|
||||||
|
} elseif ($detect->isAndroidOS()) {
|
||||||
|
$os = 'Android';
|
||||||
|
$osVersion = $detect->version('Android') ?: 'Unknown';
|
||||||
|
} elseif (preg_match('/Windows/i', $ua)) {
|
||||||
|
$os = 'Windows';
|
||||||
|
if (preg_match('/Windows NT ([0-9\.]+)/i', $ua, $matches)) {
|
||||||
|
$osVersion = $matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === DETECT BROWSER ===
|
||||||
|
$browser = 'Unknown';
|
||||||
|
$browserVersion = 'Unknown';
|
||||||
|
|
||||||
|
// Chrome
|
||||||
|
if (preg_match('/Chrome\/([0-9\.]+)/i', $ua, $matches)) {
|
||||||
|
$browser = 'Chrome';
|
||||||
|
$browserVersion = $matches[1];
|
||||||
|
}
|
||||||
|
// Safari (non-Chrome)
|
||||||
|
elseif (preg_match('/Safari\/([0-9\.]+)/i', $ua, $matches) && !preg_match('/Chrome/i', $ua)) {
|
||||||
|
$browser = 'Safari';
|
||||||
|
if (preg_match('/Version\/([0-9\.]+)/i', $ua, $vMatches)) {
|
||||||
|
$browserVersion = $vMatches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Firefox
|
||||||
|
elseif (preg_match('/Firefox\/([0-9\.]+)/i', $ua, $matches)) {
|
||||||
|
$browser = 'Firefox';
|
||||||
|
$browserVersion = $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// === DEVICE TYPE ===
|
||||||
|
$deviceType = 'desktop';
|
||||||
|
if ($detect->isTablet()) {
|
||||||
|
$deviceType = 'tablet';
|
||||||
|
} elseif ($detect->isMobile()) {
|
||||||
|
$deviceType = 'phone';
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'brand' => $brand,
|
||||||
|
'model' => $model,
|
||||||
|
'os' => $os,
|
||||||
|
'os_version' => $osVersion,
|
||||||
|
'browser' => $browser,
|
||||||
|
'browser_version' => $browserVersion,
|
||||||
|
'device_type' => $deviceType,
|
||||||
|
'is_mobile' => $detect->isMobile(),
|
||||||
|
'is_tablet' => $detect->isTablet(),
|
||||||
|
'is_phone' => $detect->isMobile() && !$detect->isTablet(),
|
||||||
|
'user_agent' => $ua
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('getCameraVersionSupport')) {
|
||||||
|
/**
|
||||||
|
* Get camera version support untuk device tertentu
|
||||||
|
*
|
||||||
|
* @param string $deviceBrand Brand device (Samsung, POCO, dll)
|
||||||
|
* @param string $deviceModel Model device (SM-S931B, POCO X5, dll)
|
||||||
|
* @return array Camera version support info
|
||||||
|
*/
|
||||||
|
function getCameraVersionSupport($deviceBrand, $deviceModel)
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
|
||||||
|
// Cek apakah ada mapping SPESIFIK untuk model ini
|
||||||
|
$compatibility = $db->table('device_camera_compatibility')
|
||||||
|
->where('device_brand', $deviceBrand)
|
||||||
|
->where('device_model', $deviceModel)
|
||||||
|
->where('is_active', true)
|
||||||
|
->get()
|
||||||
|
->getRow();
|
||||||
|
|
||||||
|
// Jika tidak ada, cek mapping untuk BRAND (device_model = NULL)
|
||||||
|
if (!$compatibility) {
|
||||||
|
$compatibility = $db->table('device_camera_compatibility')
|
||||||
|
->where('device_brand', $deviceBrand)
|
||||||
|
->where('device_model', null)
|
||||||
|
->where('is_active', true)
|
||||||
|
->get()
|
||||||
|
->getRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// JIKA TIDAK ADA DI DATABASE = SUPPORT SEMUA VERSI (DEFAULT)
|
||||||
|
if (!$compatibility) {
|
||||||
|
return [
|
||||||
|
'support_version_1' => true,
|
||||||
|
'support_version_2' => true,
|
||||||
|
'support_version_3' => true,
|
||||||
|
'recommended_version' => 3, // Recommend versi tertinggi
|
||||||
|
'available_versions' => [1, 2, 3],
|
||||||
|
'notes' => 'Device tidak ada limitasi - support semua versi kamera',
|
||||||
|
'is_default' => true // Flag untuk tahu ini default behavior
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build available versions array
|
||||||
|
$availableVersions = [];
|
||||||
|
if ($compatibility->support_version_1) $availableVersions[] = 1;
|
||||||
|
if ($compatibility->support_version_2) $availableVersions[] = 2;
|
||||||
|
if ($compatibility->support_version_3) $availableVersions[] = 3;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'support_version_1' => (bool)$compatibility->support_version_1,
|
||||||
|
'support_version_2' => (bool)$compatibility->support_version_2,
|
||||||
|
'support_version_3' => (bool)$compatibility->support_version_3,
|
||||||
|
'recommended_version' => $compatibility->recommended_version,
|
||||||
|
'available_versions' => $availableVersions,
|
||||||
|
'notes' => $compatibility->notes,
|
||||||
|
'is_default' => false // Ini bukan default, ada di database
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('getDeviceFingerprint')) {
|
||||||
|
function getDeviceFingerprint($userAgent, $ipAddress)
|
||||||
|
{
|
||||||
|
return md5($userAgent . '|' . $ipAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('isDeviceTrusted')) {
|
||||||
|
/**
|
||||||
|
* Cek apakah device sudah dipercaya
|
||||||
|
*
|
||||||
|
* @param string $deviceFingerprint
|
||||||
|
* @param string $superUserId
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function isDeviceTrusted($deviceFingerprint, $superUserId)
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
|
||||||
|
$device = $db->table('user_devices')
|
||||||
|
->where('device_fingerprint', $deviceFingerprint)
|
||||||
|
->where('super_user_id', $superUserId)
|
||||||
|
->where('is_trusted', true)
|
||||||
|
->where('is_blocked', false)
|
||||||
|
->get()
|
||||||
|
->getRow();
|
||||||
|
|
||||||
|
return $device !== null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('isDeviceBlocked')) {
|
||||||
|
/**
|
||||||
|
* Cek apakah device diblokir
|
||||||
|
*
|
||||||
|
* @param string $deviceFingerprint
|
||||||
|
* @return array|null Device info if blocked, null otherwise
|
||||||
|
*/
|
||||||
|
function isDeviceBlocked($deviceFingerprint)
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
|
||||||
|
$device = $db->table('user_devices')
|
||||||
|
->where('device_fingerprint', $deviceFingerprint)
|
||||||
|
->where('is_blocked', true)
|
||||||
|
->get()
|
||||||
|
->getRow();
|
||||||
|
|
||||||
|
if ($device) {
|
||||||
|
return [
|
||||||
|
'is_blocked' => true,
|
||||||
|
'reason' => $device->blocked_reason,
|
||||||
|
'blocked_at' => $device->blocked_at
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
app/Language/.gitkeep
Normal file
0
app/Language/.gitkeep
Normal file
4
app/Language/en/Validation.php
Normal file
4
app/Language/en/Validation.php
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// override core en language system validation or define your own en language validation message
|
||||||
|
return [];
|
||||||
0
app/Libraries/.gitkeep
Normal file
0
app/Libraries/.gitkeep
Normal file
50
app/Libraries/ArelAyudhi/src/Broadcast.php
Normal file
50
app/Libraries/ArelAyudhi/src/Broadcast.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\DhivaProdevWa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property Broadcast $broadcast
|
||||||
|
*/
|
||||||
|
|
||||||
|
const SEND_GROUP = "T2vGHuNWqwUQFtk2D96xt9Hkq8dyHEXVwBXPMz8_oaA";
|
||||||
|
const SEND_INSTAN = "T2vGHuNWqwUQFtk2D96xt3hwktFc4t7cTiz74HCwOaM";
|
||||||
|
class Broadcast extends ProdevMessagesAbstract
|
||||||
|
{
|
||||||
|
/** @param array{ daftar_group: string, daftar_pesan_id: string } $data */
|
||||||
|
public function sendGroup(string $daftar_group, string $daftar_pesan_id): array
|
||||||
|
{
|
||||||
|
$form = [
|
||||||
|
'daftar_group' => $daftar_group,
|
||||||
|
'daftar_pesan_id' => $daftar_pesan_id
|
||||||
|
];
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
SEND_GROUP,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($form)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function sendInstan(array $data): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
SEND_INSTAN,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($data)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
app/Libraries/ArelAyudhi/src/Group.php
Normal file
70
app/Libraries/ArelAyudhi/src/Group.php
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\DhivaProdevWa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property Group $multiple
|
||||||
|
*/
|
||||||
|
|
||||||
|
const GET_ALL = "4YsZVeivKQDHNbC9QapHxA";
|
||||||
|
const INSERT = "ucdyZBMN9J7hivfx1AQIeg";
|
||||||
|
const UPDATE = "H9w1hTiHDGgiINLIVCgqOg/";
|
||||||
|
class Group extends ProdevMessagesAbstract
|
||||||
|
{
|
||||||
|
public function getAll()
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
GET_ALL,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** @param array{ nama_group: string, isi_pesan: string } $data */
|
||||||
|
public function insert(string $nama_group, string $isi_pesan = '')
|
||||||
|
{
|
||||||
|
$form = [
|
||||||
|
'nama_group' => $nama_group,
|
||||||
|
'isi_pesan' => $isi_pesan
|
||||||
|
];
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
INSERT,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($form)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function update(string $nama_group, string $daftar_group_id): array
|
||||||
|
{
|
||||||
|
$form = [
|
||||||
|
'nama_group' => $nama_group,
|
||||||
|
];
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
UPDATE . $daftar_group_id,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($form)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
108
app/Libraries/ArelAyudhi/src/ListMessage.php
Normal file
108
app/Libraries/ArelAyudhi/src/ListMessage.php
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\DhivaProdevWa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property ListMessage $listmessage
|
||||||
|
*/
|
||||||
|
|
||||||
|
const GET_ALL = "380XyFK0cI_hY_wHrP4SjA";
|
||||||
|
const INSERT = "jn2GXQvR98hGPHIDqgqN8g";
|
||||||
|
const UPDATE = "sS9omGVprCLnzt1lq-7QQw/";
|
||||||
|
const SHOW_PESAN_BY_PESAN_ID = "RkL2559LgadI185K5-IthjCqvZSBEhWUEOj1AaxD6so/";
|
||||||
|
const DELETE = "F5y8aFIoVgS8zx5hmiVPEw/";
|
||||||
|
class ListMessage extends ProdevMessagesAbstract
|
||||||
|
{
|
||||||
|
public function getAll(): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
GET_ALL,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function insert(string $daftar_pesan_isi, string $judul_pesan): array
|
||||||
|
{
|
||||||
|
$form = $this->getform(
|
||||||
|
[
|
||||||
|
'daftar_pesan_isi' => $daftar_pesan_isi,
|
||||||
|
'judul_pesan' => $judul_pesan
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
INSERT,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($form)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function update(string $daftar_pesan_isi, string $judul_pesan, string $daftar_pesan_id): array
|
||||||
|
{
|
||||||
|
$form = $this->getform(
|
||||||
|
[
|
||||||
|
'daftar_pesan_isi' => $daftar_pesan_isi,
|
||||||
|
'judul_pesan' => $judul_pesan
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
UPDATE . $daftar_pesan_id,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($form)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function showByid(string $daftar_pesan_id): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
SHOW_PESAN_BY_PESAN_ID . $daftar_pesan_id,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function delete(string $daftar_pesan_id): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
DELETE . $daftar_pesan_id,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/Libraries/ArelAyudhi/src/Multiple.php
Normal file
25
app/Libraries/ArelAyudhi/src/Multiple.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
namespace ArelAyudhi\DhivaProdevWa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property Multiple $multiple
|
||||||
|
*/
|
||||||
|
class Multiple extends ProdevMessagesAbstract
|
||||||
|
{
|
||||||
|
public function sendText(string $username, string $password): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request('POST', '/api/v2/send-message', [
|
||||||
|
'form_params' => [
|
||||||
|
'username' => $username,
|
||||||
|
'password' => $password,
|
||||||
|
'date' => $this->getMillisecond(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return (array)$body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
app/Libraries/ArelAyudhi/src/ProdevMessages.php
Normal file
84
app/Libraries/ArelAyudhi/src/ProdevMessages.php
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\DhivaProdevWa;
|
||||||
|
|
||||||
|
// const URL = "http://localhost/adhivasindo/wa-api/index.php/RMuumzsQWg5HtzQb/";
|
||||||
|
const URL = "https://blast.awh.co.id/index.php/RMuumzsQWg5HtzQb/";
|
||||||
|
/**
|
||||||
|
* @property Group $group
|
||||||
|
* @property Multiple $multiple
|
||||||
|
* @property ListMessage $listmessage
|
||||||
|
* @property Broadcast $broadcast
|
||||||
|
* @property UserList $userlist
|
||||||
|
*/
|
||||||
|
class ProdevMessages
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $ProdevToken = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \GuzzleHttp\Client
|
||||||
|
*/
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
public function __construct(string $ProdevToken)
|
||||||
|
{
|
||||||
|
$headers = [
|
||||||
|
'Content-Type' => 'application/x-www-form-urlencoded'
|
||||||
|
];
|
||||||
|
$this->ProdevToken = $ProdevToken;
|
||||||
|
$this->client = new \GuzzleHttp\Client(
|
||||||
|
[
|
||||||
|
'base_uri' => URL,
|
||||||
|
'headers' => $headers,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $container = [];
|
||||||
|
|
||||||
|
protected $providers = [
|
||||||
|
"multiple" => Multiple::class,
|
||||||
|
"group" => Group::class,
|
||||||
|
"listmessage" => ListMessage::class,
|
||||||
|
"broadcast" => Broadcast::class,
|
||||||
|
"userlist" => UserList::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
if (!isset($this->providers[$name])) {
|
||||||
|
throw new \Exception("class not found");
|
||||||
|
} else {
|
||||||
|
if (!isset($this->container[$name]) || !$this->container[$name] instanceof ProdevMessagesAbstract) {
|
||||||
|
try {
|
||||||
|
$this->container["{$name}"] = new $this->providers[$name]($this->ProdevToken, $this->client);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->container["{$name}"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static function getDateTimeMillisecond(string $dateTime): int
|
||||||
|
{
|
||||||
|
$dateTime = $dateTime . ".0";
|
||||||
|
list($usec, $sec) = explode(".", $dateTime);
|
||||||
|
$date = strtotime($usec);
|
||||||
|
$return_data = str_pad($date . $sec, 13, "0", STR_PAD_RIGHT);
|
||||||
|
return (int)$return_data;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param string $dateTime
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
}
|
||||||
122
app/Libraries/ArelAyudhi/src/ProdevMessagesAbstract.php
Normal file
122
app/Libraries/ArelAyudhi/src/ProdevMessagesAbstract.php
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\DhivaProdevWa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property Group $group
|
||||||
|
* @property Multiple $multiple
|
||||||
|
*/
|
||||||
|
const error_code =
|
||||||
|
[
|
||||||
|
/**
|
||||||
|
* Account Error Code
|
||||||
|
*/
|
||||||
|
1 => "proses gagal",
|
||||||
|
10000 => "invalid client_id",
|
||||||
|
10001 => "invalid client",
|
||||||
|
10003 => "invalid token",
|
||||||
|
10004 => "invalid access",
|
||||||
|
10007 => "username atau password salah",
|
||||||
|
10011 => "invalid refresh token",
|
||||||
|
20002 => "not lock admin",
|
||||||
|
30002 => "invalid username, hanya huruf latin yang diperbolehkan",
|
||||||
|
30003 => "user sudah ada",
|
||||||
|
30004 => "invalid userid to delete",
|
||||||
|
30005 => "password harus md5 encrypted",
|
||||||
|
30006 => "exceeds the restrictions of API call number",
|
||||||
|
80000 => "date harus waktu sekarang, dalam 5 menit",
|
||||||
|
80002 => "invalid json format",
|
||||||
|
90000 => "internal server error",
|
||||||
|
-3 => "invalid parameter",
|
||||||
|
-2018 => "permission denied",
|
||||||
|
-4063 => "Please delete/transfer all yours locks first",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock Error Code
|
||||||
|
*/
|
||||||
|
-1003 => "lock tidak ada",
|
||||||
|
-2025 => "lock frozen, tidak bisa dioperasikan",
|
||||||
|
-3011 => "Cannot Transfer Lock(s) to Yourself",
|
||||||
|
-4043 => "The function is not supported for this lock",
|
||||||
|
-4056 => "run out of memory",
|
||||||
|
-4067 => "NB Device tidak terdaftar",
|
||||||
|
-4082 => "waktu auto locking tidak sah",
|
||||||
|
/**
|
||||||
|
* Gateway Error Code
|
||||||
|
*/
|
||||||
|
-2012 => "Lock tidak terhubung ke gateway manapun",
|
||||||
|
-3002 => "The gateway is offline. Please check and try again.",
|
||||||
|
-3003 => "gateway sibuk, coba lagi",
|
||||||
|
-3016 => "Cannot Transfer Gateway(s) to Yourself.",
|
||||||
|
-3034 => "Network not configed. Please config the network and try again.",
|
||||||
|
-3035 => "Wifi lock is in power saving mode, please turn off power saving and try again",
|
||||||
|
-3036 => "The lock is offline. Please check and try again",
|
||||||
|
-3037 => "The lock is busy. Please try again later",
|
||||||
|
-4037 => "No such Gateway exists",
|
||||||
|
/**
|
||||||
|
* RFID / IC Card Error Code
|
||||||
|
*/
|
||||||
|
-1021 => "This IC Card does not exist",
|
||||||
|
-1023 => "This Fingerprint does not exist",
|
||||||
|
/**
|
||||||
|
* Passcode Error Code
|
||||||
|
*/
|
||||||
|
-1007 => "No password data of this lock",
|
||||||
|
-2009 => "Invalid Password",
|
||||||
|
-3006 => "Invalid Passcode. Passcode should be between 6 - 9 Digits in length",
|
||||||
|
-3007 => "The same passcode already exists. Please use another one",
|
||||||
|
-3008 => "A Passcode that has never been used on the Lock cannot be changed",
|
||||||
|
-3009 => "There is NO SPACE to store Customized Passcodes. Please Delete Un-Used Customized Passcodes and try again",
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* Class BaseAbstract
|
||||||
|
*/
|
||||||
|
abstract class ProdevMessagesAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $ProdevToken = '';
|
||||||
|
/**
|
||||||
|
* @var \GuzzleHttp\Client
|
||||||
|
*/
|
||||||
|
protected $client;
|
||||||
|
final function __construct(string $ProdevToken, \GuzzleHttp\Client $client)
|
||||||
|
{
|
||||||
|
$this->ProdevToken = $ProdevToken;
|
||||||
|
$this->client = $client;
|
||||||
|
}
|
||||||
|
protected function getMillisecond()
|
||||||
|
{
|
||||||
|
list($t1, $t2) = explode(' ', microtime());
|
||||||
|
return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
|
||||||
|
}
|
||||||
|
protected static function errorCode(int $code)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'code' => $code,
|
||||||
|
'message' => error_code[$code]
|
||||||
|
];
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
static function queryBuildier($get)
|
||||||
|
{
|
||||||
|
(string)$string = '';
|
||||||
|
foreach ($get as $key => $value) {
|
||||||
|
$string .= $key . '=' . $value . '&';
|
||||||
|
}
|
||||||
|
return substr_replace($string, "", -1);
|
||||||
|
}
|
||||||
|
function getform($form = [])
|
||||||
|
{
|
||||||
|
$option = [
|
||||||
|
'AccessToken' => $this->ProdevToken
|
||||||
|
];
|
||||||
|
if ($form) {
|
||||||
|
foreach ($form as $v => $d) {
|
||||||
|
$option[$v] = $d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $option;
|
||||||
|
}
|
||||||
|
}
|
||||||
79
app/Libraries/ArelAyudhi/src/ProdevXendit.php
Normal file
79
app/Libraries/ArelAyudhi/src/ProdevXendit.php
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\Prodev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property QrPayment $QrPayment
|
||||||
|
*/
|
||||||
|
|
||||||
|
const URL = "https://api.xendit.co/";
|
||||||
|
class ProdevXendit
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $ProdevToken = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \GuzzleHttp\Client
|
||||||
|
*/
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
public function __construct($xendit_key)
|
||||||
|
{
|
||||||
|
$headers = [
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'api-version' => ' 2022-07-31',
|
||||||
|
];
|
||||||
|
$this->client = new \GuzzleHttp\Client(
|
||||||
|
[
|
||||||
|
'base_uri' => URL,
|
||||||
|
'headers' => $headers,
|
||||||
|
'auth' => [$xendit_key, ''],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected $container = [];
|
||||||
|
|
||||||
|
protected $providers = [
|
||||||
|
"QrPayment" => QrPayment::class,
|
||||||
|
"VirtualAccount" => VirtualAccount::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
if (!isset($this->providers[$name])) {
|
||||||
|
throw new \Exception("class not found");
|
||||||
|
} else {
|
||||||
|
if (!isset($this->container[$name]) || !$this->container[$name] instanceof ProdevXenditAbstract) {
|
||||||
|
try {
|
||||||
|
$this->container["{$name}"] = new $this->providers[$name]($this->client);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->container["{$name}"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static function getDateTimeMillisecond(string $dateTime): int
|
||||||
|
{
|
||||||
|
$dateTime = $dateTime . ".0";
|
||||||
|
list($usec, $sec) = explode(".", $dateTime);
|
||||||
|
$date = strtotime($usec);
|
||||||
|
$return_data = str_pad($date . $sec, 13, "0", STR_PAD_RIGHT);
|
||||||
|
return (int)$return_data;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param string $dateTime
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
}
|
||||||
121
app/Libraries/ArelAyudhi/src/ProdevXenditAbstract.php
Normal file
121
app/Libraries/ArelAyudhi/src/ProdevXenditAbstract.php
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\Prodev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property Group $group
|
||||||
|
* @property Multiple $multiple
|
||||||
|
*/
|
||||||
|
const error_code =
|
||||||
|
[
|
||||||
|
/**
|
||||||
|
* Account Error Code
|
||||||
|
*/
|
||||||
|
1 => "proses gagal",
|
||||||
|
10000 => "invalid client_id",
|
||||||
|
10001 => "invalid client",
|
||||||
|
10003 => "invalid token",
|
||||||
|
10004 => "invalid access",
|
||||||
|
10007 => "username atau password salah",
|
||||||
|
10011 => "invalid refresh token",
|
||||||
|
20002 => "not lock admin",
|
||||||
|
30002 => "invalid username, hanya huruf latin yang diperbolehkan",
|
||||||
|
30003 => "user sudah ada",
|
||||||
|
30004 => "invalid userid to delete",
|
||||||
|
30005 => "password harus md5 encrypted",
|
||||||
|
30006 => "exceeds the restrictions of API call number",
|
||||||
|
80000 => "date harus waktu sekarang, dalam 5 menit",
|
||||||
|
80002 => "invalid json format",
|
||||||
|
90000 => "internal server error",
|
||||||
|
-3 => "invalid parameter",
|
||||||
|
-2018 => "permission denied",
|
||||||
|
-4063 => "Please delete/transfer all yours locks first",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock Error Code
|
||||||
|
*/
|
||||||
|
-1003 => "lock tidak ada",
|
||||||
|
-2025 => "lock frozen, tidak bisa dioperasikan",
|
||||||
|
-3011 => "Cannot Transfer Lock(s) to Yourself",
|
||||||
|
-4043 => "The function is not supported for this lock",
|
||||||
|
-4056 => "run out of memory",
|
||||||
|
-4067 => "NB Device tidak terdaftar",
|
||||||
|
-4082 => "waktu auto locking tidak sah",
|
||||||
|
/**
|
||||||
|
* Gateway Error Code
|
||||||
|
*/
|
||||||
|
-2012 => "Lock tidak terhubung ke gateway manapun",
|
||||||
|
-3002 => "The gateway is offline. Please check and try again.",
|
||||||
|
-3003 => "gateway sibuk, coba lagi",
|
||||||
|
-3016 => "Cannot Transfer Gateway(s) to Yourself.",
|
||||||
|
-3034 => "Network not configed. Please config the network and try again.",
|
||||||
|
-3035 => "Wifi lock is in power saving mode, please turn off power saving and try again",
|
||||||
|
-3036 => "The lock is offline. Please check and try again",
|
||||||
|
-3037 => "The lock is busy. Please try again later",
|
||||||
|
-4037 => "No such Gateway exists",
|
||||||
|
/**
|
||||||
|
* RFID / IC Card Error Code
|
||||||
|
*/
|
||||||
|
-1021 => "This IC Card does not exist",
|
||||||
|
-1023 => "This Fingerprint does not exist",
|
||||||
|
/**
|
||||||
|
* Passcode Error Code
|
||||||
|
*/
|
||||||
|
-1007 => "No password data of this lock",
|
||||||
|
-2009 => "Invalid Password",
|
||||||
|
-3006 => "Invalid Passcode. Passcode should be between 6 - 9 Digits in length",
|
||||||
|
-3007 => "The same passcode already exists. Please use another one",
|
||||||
|
-3008 => "A Passcode that has never been used on the Lock cannot be changed",
|
||||||
|
-3009 => "There is NO SPACE to store Customized Passcodes. Please Delete Un-Used Customized Passcodes and try again",
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* Class BaseAbstract
|
||||||
|
*/
|
||||||
|
abstract class ProdevXenditAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $ProdevToken = '';
|
||||||
|
/**
|
||||||
|
* @var \GuzzleHttp\Client
|
||||||
|
*/
|
||||||
|
protected $client;
|
||||||
|
final function __construct(\GuzzleHttp\Client $client)
|
||||||
|
{
|
||||||
|
$this->client = $client;
|
||||||
|
}
|
||||||
|
protected function getMillisecond()
|
||||||
|
{
|
||||||
|
list($t1, $t2) = explode(' ', microtime());
|
||||||
|
return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
|
||||||
|
}
|
||||||
|
protected static function errorCode(int $code)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'code' => $code,
|
||||||
|
'message' => error_code[$code]
|
||||||
|
];
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
static function queryBuildier($get)
|
||||||
|
{
|
||||||
|
(string)$string = '';
|
||||||
|
foreach ($get as $key => $value) {
|
||||||
|
$string .= $key . '=' . $value . '&';
|
||||||
|
}
|
||||||
|
return substr_replace($string, "", -1);
|
||||||
|
}
|
||||||
|
function getform($form = [])
|
||||||
|
{
|
||||||
|
$option = [
|
||||||
|
'AccessToken' => $this->ProdevToken
|
||||||
|
];
|
||||||
|
if ($form) {
|
||||||
|
foreach ($form as $v => $d) {
|
||||||
|
$option[$v] = $d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $option;
|
||||||
|
}
|
||||||
|
}
|
||||||
37
app/Libraries/ArelAyudhi/src/QrPayment.php
Normal file
37
app/Libraries/ArelAyudhi/src/QrPayment.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\Prodev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property QrPayment $QrPayment
|
||||||
|
*/
|
||||||
|
|
||||||
|
const CREATE_QR = "qr_codes";
|
||||||
|
const CHECK_QR = "qr_codes/";
|
||||||
|
class QrPayment extends ProdevXenditAbstract
|
||||||
|
{
|
||||||
|
/** @param array{ nama_penerima[0]: string, nomor_penerima[0]: string, nomor_penerima[0]: string } $data */
|
||||||
|
public function create_qr(array $data): array
|
||||||
|
{
|
||||||
|
// print_r($this->client);die;
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
CREATE_QR,
|
||||||
|
[
|
||||||
|
'body' => json_encode($data)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
public function check_qr(string $data): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'GET',
|
||||||
|
CHECK_QR . $data,
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
}
|
||||||
161
app/Libraries/ArelAyudhi/src/UserList.php
Normal file
161
app/Libraries/ArelAyudhi/src/UserList.php
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\DhivaProdevWa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property UserList $userlist
|
||||||
|
*/
|
||||||
|
|
||||||
|
const USER_LIST_GET_ALL = "eXvZjC3J1L3eNrqTEfc8mQ";
|
||||||
|
const USER_LIST_ALL_BY_GROUP_ID = "O7skdKVrEKhNkzkJm2WjaQms5SWijPt7b7yclfXwFvrTksqxEylS7tZC-Yff4RsW/";
|
||||||
|
const USER_LIST_ALL_BY_NAMA = "O7skdKVrEKhNkzkJm2WjaYhTwxA7MOeaqdT04OR6P0o/";
|
||||||
|
const USER_LIST_ALL_BY_NOMOR_TELEPON = "O7skdKVrEKhNkzkJm2WjaZ4hncBYJmRW5G5UynOx7JXLKLtvEhDJI4Ql2wG5mB--/";
|
||||||
|
const USER_LIST_SHOW_BY_NAMA_ID = "o3O-xMLw9O65qs2ibXvUkXPd5nqGKyYF39S_Y3LVuaQoPq4rsejLJPHi93ha_ilo/";
|
||||||
|
const USER_LIST_INSERT = "omj4wqnUSftatKfOYM5jyFcmIBSCJuwm3XQAR-jeTVw";
|
||||||
|
const USER_LIST_UPDATE = "mcJ9dTuItmpxsD5CuSswKgVqCDFIj2sLeqvY_JkCNQw/";
|
||||||
|
const GET_ALL = "eXvZjC3J1L3eNrqTEfc8mQ";
|
||||||
|
const USER_LIST_DELETE = "ucenwGz_ed9qVf6QxFxExZb1nnBvKxdxdbAiDZUdup4/";
|
||||||
|
|
||||||
|
class UserList extends ProdevMessagesAbstract
|
||||||
|
{
|
||||||
|
public function getAll(): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
GET_ALL,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function allByGroupId(string $group_penerima): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
USER_LIST_ALL_BY_GROUP_ID . $group_penerima,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function allByNama(string $nama_penerima): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
USER_LIST_ALL_BY_NAMA . $nama_penerima,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function allByNomorTelepon(string $nomor_penerima): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
USER_LIST_ALL_BY_NOMOR_TELEPON . $nomor_penerima,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function showByNamaId(string $daftar_penerima_id): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
USER_LIST_SHOW_BY_NAMA_ID . $daftar_penerima_id,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** @param array{ nama_penerima[0]: string, nomor_penerima[0]: string, nomor_penerima[0]: string } $data */
|
||||||
|
public function insert(array $data): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
USER_LIST_INSERT,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($data)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function update(string $nama_penerima = '', int $nomor_penerima, string $group_penerima = '', string $daftar_penerima_id): array
|
||||||
|
{
|
||||||
|
$form = [];
|
||||||
|
if ($nama_penerima) {
|
||||||
|
$form['nama_penerima'] = $nama_penerima;
|
||||||
|
}
|
||||||
|
if ($nomor_penerima) {
|
||||||
|
$form['nomor_penerima'] = $nomor_penerima;
|
||||||
|
}
|
||||||
|
if ($group_penerima) {
|
||||||
|
$form['group_penerima'] = $group_penerima;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
USER_LIST_UPDATE . $daftar_penerima_id,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform($form)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function delete(string $daftar_penerima_id): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
USER_LIST_DELETE . $daftar_penerima_id,
|
||||||
|
[
|
||||||
|
'form_params' => $this->getform()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
if ($response->getStatusCode() === 200) {
|
||||||
|
return $body;
|
||||||
|
} else {
|
||||||
|
return $this->errorCode($body['errcode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
app/Libraries/ArelAyudhi/src/VirtualAccount.php
Normal file
37
app/Libraries/ArelAyudhi/src/VirtualAccount.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ArelAyudhi\Prodev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property VirtualAccount $VirtualAccount
|
||||||
|
*/
|
||||||
|
|
||||||
|
const CREATE_VA = "callback_virtual_accounts";
|
||||||
|
const CHECK_VA = "callback_virtual_accounts/";
|
||||||
|
class VirtualAccount extends ProdevXenditAbstract
|
||||||
|
{
|
||||||
|
/** @param array{ nama_penerima[0]: string, nomor_penerima[0]: string, nomor_penerima[0]: string } $data */
|
||||||
|
public function create_va(array $data): array
|
||||||
|
{
|
||||||
|
// print_r($this->client);die;
|
||||||
|
$response = $this->client->request(
|
||||||
|
'POST',
|
||||||
|
CREATE_VA,
|
||||||
|
[
|
||||||
|
'body' => json_encode($data)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
public function check_va(string $data): array
|
||||||
|
{
|
||||||
|
$response = $this->client->request(
|
||||||
|
'GET',
|
||||||
|
CHECK_VA . $data,
|
||||||
|
);
|
||||||
|
$body = json_decode($response->getBody()->getContents(), true);
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
app/Libraries/ArelAyudhi/src/composer.json
Normal file
11
app/Libraries/ArelAyudhi/src/composer.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "arelayudhi/dhiva-prodev-wa",
|
||||||
|
"description": "Dhiva WA",
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"prefer-stable": true,
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"ArelAyudhi\\DhivaProdevWa\\": "src/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
111
app/Libraries/DhivaAES.php
Normal file
111
app/Libraries/DhivaAES.php
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Dhiva\Core;
|
||||||
|
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
use Firebase\JWT\Key;
|
||||||
|
|
||||||
|
class DhivaAES
|
||||||
|
{
|
||||||
|
public static function base64url_encode($data, $password = false)
|
||||||
|
{
|
||||||
|
return rtrim(strtr(base64_encode(openssl_encrypt($data, "AES-256-CBC", self::keypair($password), OPENSSL_RAW_DATA, SSL_KEY['iv'])), '+/', '-_'), '=');
|
||||||
|
}
|
||||||
|
public static function base64url_decode($data, $password = false)
|
||||||
|
{
|
||||||
|
$decrypt = openssl_decrypt(base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)), "AES-256-CBC", self::keypair($password), OPENSSL_RAW_DATA, SSL_KEY['iv']);
|
||||||
|
return $decrypt;
|
||||||
|
}
|
||||||
|
private static function keypair($password)
|
||||||
|
{
|
||||||
|
$data = ($password == false) ? SSL_KEY['password'] : $password;
|
||||||
|
return openssl_pbkdf2($data, SSL_KEY['salt'], SSL_KEY['keyLength'], SSL_KEY['iterations'], "sha256");
|
||||||
|
}
|
||||||
|
public static function randomString($aes = false)
|
||||||
|
{
|
||||||
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$randomString = '';
|
||||||
|
for ($i = 0; $i < 10; $i++) {
|
||||||
|
$index = rand(0, strlen($characters) - 1);
|
||||||
|
$randomString .= $characters[$index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $randomString;
|
||||||
|
}
|
||||||
|
public static function jwtencode($token)
|
||||||
|
{
|
||||||
|
$tokenParts = explode(".", $token);
|
||||||
|
$tokenPayload = self::base64url_encode($tokenParts[1]);
|
||||||
|
return $tokenPayload;
|
||||||
|
}
|
||||||
|
public static function jwtdecode($private, $public)
|
||||||
|
{
|
||||||
|
$tokenParts = explode(".", $public);
|
||||||
|
$tokenHeader = $tokenParts[0];
|
||||||
|
$tokenPayload = self::base64url_decode($private);
|
||||||
|
if (isset($tokenParts[2])) {
|
||||||
|
$tokenSignature = $tokenParts[2];
|
||||||
|
$data = $tokenHeader . "." . $tokenPayload . "." . $tokenSignature;
|
||||||
|
} else {
|
||||||
|
return ERROR_TOKEN_UNIDENTIFIED;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
public static function jwtvalidator($private, $public)
|
||||||
|
{
|
||||||
|
$tokenPrivate = self::jwtdecode($private, $public);
|
||||||
|
$match = ($tokenPrivate === $public) ? true : false;
|
||||||
|
return $match;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generator String dengan enkripsi
|
||||||
|
*
|
||||||
|
* @param mixed $length
|
||||||
|
* @param mixed $aes
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function randomStr(int $length, $aes = false): string
|
||||||
|
{
|
||||||
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$randomString = '';
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$index = rand(0, strlen($characters) - 1);
|
||||||
|
$randomString .= $characters[$index];
|
||||||
|
}
|
||||||
|
if ($aes) {
|
||||||
|
$randomString = self::base64url_encode(strval(intval(microtime(true) * 1000)), 5);
|
||||||
|
}
|
||||||
|
return $randomString;
|
||||||
|
}
|
||||||
|
public static function aesencodeid(string $string, int $length)
|
||||||
|
{
|
||||||
|
$tokenPayload = self::base64url_encode($string . self::randomStr($length));
|
||||||
|
return $tokenPayload;
|
||||||
|
}
|
||||||
|
public static function validateTimestampWtihUserAccess($tokens)
|
||||||
|
{
|
||||||
|
$token = self::validateToken($tokens);
|
||||||
|
if ($token == false) {
|
||||||
|
return ERROR_TOKEN_UNIDENTIFIED;
|
||||||
|
}
|
||||||
|
$model = model('App\Models\SqlModel\SuperUserModelSql');
|
||||||
|
$user = $model->showBy('super_user_id', $token->super_user_id);
|
||||||
|
$lastTimeStamp = strtotime($user->access_at);
|
||||||
|
$timeStampTimeOut = ($lastTimeStamp + JWT_TIMEOUT) - now();
|
||||||
|
if ($timeStampTimeOut < 0 || !$user->token || $token->token != $user->token) {
|
||||||
|
$update = ['token' => null];
|
||||||
|
// $model->update($update, $token->super_user_id);
|
||||||
|
// return ERROR_TOKEN_EXPIRED;
|
||||||
|
}
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
public static function validateToken($token)
|
||||||
|
{
|
||||||
|
return JWT::decode($token, new Key(JWT_KEY, 'HS256'));
|
||||||
|
}
|
||||||
|
public static function generateToken($data)
|
||||||
|
{
|
||||||
|
return JWT::encode($data, JWT_KEY, 'HS256');
|
||||||
|
}
|
||||||
|
}
|
||||||
13
app/Libraries/DhivaComponent/Controller.txt
Normal file
13
app/Libraries/DhivaComponent/Controller.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Load
|
||||||
|
* $this->model->{{tabel}};
|
||||||
|
*/
|
||||||
|
|
||||||
|
class {{controller}}Controller extends BaseController
|
||||||
|
{
|
||||||
|
protected $table = '{{tabel}}';
|
||||||
|
}
|
||||||
85
app/Libraries/DhivaComponent/DatabaseClient.txt
Normal file
85
app/Libraries/DhivaComponent/DatabaseClient.txt
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Configuration
|
||||||
|
*/
|
||||||
|
class Database extends Config
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The directory that holds the Migrations
|
||||||
|
* and Seeds directories.
|
||||||
|
*/
|
||||||
|
public string $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets you choose which connection group to
|
||||||
|
* use if no other is specified.
|
||||||
|
*/
|
||||||
|
public string $defaultGroup = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default database connection for mysql.
|
||||||
|
*/
|
||||||
|
public array $default = [
|
||||||
|
'DSN' => '',
|
||||||
|
'hostname' => 'localhost',
|
||||||
|
'username' => '{{username}}',
|
||||||
|
'password' => '{{password}}',
|
||||||
|
'database' => '{{tabel}}',
|
||||||
|
'DBDriver' => '{{DBDriver}}',
|
||||||
|
'schema' => '{{schema}}',
|
||||||
|
'DBPrefix' => '',
|
||||||
|
'pConnect' => false,
|
||||||
|
'DBDebug' => true,
|
||||||
|
'charset' => 'utf8',
|
||||||
|
'DBCollat' => 'utf8_bin',
|
||||||
|
'swapPre' => '',
|
||||||
|
'encrypt' => false,
|
||||||
|
'compress' => false,
|
||||||
|
'strictOn' => false,
|
||||||
|
'failover' => [],
|
||||||
|
'numberNative' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This database connection is used when
|
||||||
|
* running PHPUnit database tests.
|
||||||
|
*/
|
||||||
|
public array $tests = [
|
||||||
|
'DSN' => '',
|
||||||
|
'hostname' => '127.0.0.1',
|
||||||
|
'username' => '',
|
||||||
|
'password' => '',
|
||||||
|
'database' => ':memory:',
|
||||||
|
'DBDriver' => 'SQLite3',
|
||||||
|
'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS
|
||||||
|
'pConnect' => false,
|
||||||
|
'DBDebug' => true,
|
||||||
|
'charset' => 'utf8',
|
||||||
|
'DBCollat' => 'utf8_general_ci',
|
||||||
|
'swapPre' => '',
|
||||||
|
'encrypt' => false,
|
||||||
|
'compress' => false,
|
||||||
|
'strictOn' => false,
|
||||||
|
'failover' => [],
|
||||||
|
'port' => 3306,
|
||||||
|
'foreignKeys' => true,
|
||||||
|
'busyTimeout' => 1000,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
// Ensure that we always set the database group to 'tests' if
|
||||||
|
// we are currently running an automated test suite, so that
|
||||||
|
// we don't overwrite live data on accident.
|
||||||
|
if (ENVIRONMENT === 'testing') {
|
||||||
|
$this->defaultGroup = 'tests';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
app/Libraries/DhivaComponent/Model.txt
Normal file
9
app/Libraries/DhivaComponent/Model.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\SqlModel;
|
||||||
|
|
||||||
|
class {{model}}ModelSql extends BaseModelSql
|
||||||
|
{
|
||||||
|
protected $table = '{{tabel}}';
|
||||||
|
|
||||||
|
}
|
||||||
1
app/Libraries/DhivaComponent/Routes.txt
Normal file
1
app/Libraries/DhivaComponent/Routes.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DhivaRoutes::Route($routes, '{{routes}}', '{{controller}}Controller');
|
||||||
143
app/Libraries/DhivaComponent/env.txt
Normal file
143
app/Libraries/DhivaComponent/env.txt
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Example Environment Configuration file
|
||||||
|
#
|
||||||
|
# This file can be used as a starting point for your own
|
||||||
|
# custom .env files, and contains most of the possible settings
|
||||||
|
# available in a default install.
|
||||||
|
#
|
||||||
|
# By default, all of the settings are commented out. If you want
|
||||||
|
# to override the setting, you must un-comment it by removing the '#'
|
||||||
|
# at the beginning of the line.
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# ENVIRONMENT
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
CI_ENVIRONMENT = production
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# APP
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# app.baseURL = ''
|
||||||
|
# If you have trouble with `.`, you could also use `_`.
|
||||||
|
# app_baseURL = ''
|
||||||
|
# app.forceGlobalSecureRequests = false
|
||||||
|
# app.CSPEnabled = false
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# DATABASE
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# database.default.hostname = localhost
|
||||||
|
# database.default.database = ci4
|
||||||
|
# database.default.username = root
|
||||||
|
# database.default.password = root
|
||||||
|
# database.default.DBDriver = MySQLi
|
||||||
|
# database.default.DBPrefix =
|
||||||
|
# database.default.port = 3306
|
||||||
|
|
||||||
|
# database.tests.hostname = localhost
|
||||||
|
# database.tests.database = ci4_test
|
||||||
|
# database.tests.username = root
|
||||||
|
# database.tests.password = root
|
||||||
|
# database.tests.DBDriver = MySQLi
|
||||||
|
# database.tests.DBPrefix =
|
||||||
|
# database.tests.port = 3306
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# CONTENT SECURITY POLICY
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# contentsecuritypolicy.reportOnly = false
|
||||||
|
# contentsecuritypolicy.defaultSrc = 'none'
|
||||||
|
# contentsecuritypolicy.scriptSrc = 'self'
|
||||||
|
# contentsecuritypolicy.styleSrc = 'self'
|
||||||
|
# contentsecuritypolicy.imageSrc = 'self'
|
||||||
|
# contentsecuritypolicy.baseURI = null
|
||||||
|
# contentsecuritypolicy.childSrc = null
|
||||||
|
# contentsecuritypolicy.connectSrc = 'self'
|
||||||
|
# contentsecuritypolicy.fontSrc = null
|
||||||
|
# contentsecuritypolicy.formAction = null
|
||||||
|
# contentsecuritypolicy.frameAncestors = null
|
||||||
|
# contentsecuritypolicy.frameSrc = null
|
||||||
|
# contentsecuritypolicy.mediaSrc = null
|
||||||
|
# contentsecuritypolicy.objectSrc = null
|
||||||
|
# contentsecuritypolicy.pluginTypes = null
|
||||||
|
# contentsecuritypolicy.reportURI = null
|
||||||
|
# contentsecuritypolicy.sandbox = false
|
||||||
|
# contentsecuritypolicy.upgradeInsecureRequests = false
|
||||||
|
# contentsecuritypolicy.styleNonceTag = '{csp-style-nonce}'
|
||||||
|
# contentsecuritypolicy.scriptNonceTag = '{csp-script-nonce}'
|
||||||
|
# contentsecuritypolicy.autoNonce = true
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# COOKIE
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# cookie.prefix = ''
|
||||||
|
# cookie.expires = 0
|
||||||
|
# cookie.path = '/'
|
||||||
|
# cookie.domain = ''
|
||||||
|
# cookie.secure = false
|
||||||
|
# cookie.httponly = false
|
||||||
|
# cookie.samesite = 'Lax'
|
||||||
|
# cookie.raw = false
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# ENCRYPTION
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# encryption.key =
|
||||||
|
# encryption.driver = OpenSSL
|
||||||
|
# encryption.blockSize = 16
|
||||||
|
# encryption.digest = SHA512
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# HONEYPOT
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# honeypot.hidden = 'true'
|
||||||
|
# honeypot.label = 'Fill This Field'
|
||||||
|
# honeypot.name = 'honeypot'
|
||||||
|
# honeypot.template = '<label>{label}</label><input type="text" name="{name}" value=""/>'
|
||||||
|
# honeypot.container = '<div style="display:none">{template}</div>'
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# SECURITY
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# security.csrfProtection = 'cookie'
|
||||||
|
# security.tokenRandomize = false
|
||||||
|
# security.tokenName = 'csrf_token_name'
|
||||||
|
# security.headerName = 'X-CSRF-TOKEN'
|
||||||
|
# security.cookieName = 'csrf_cookie_name'
|
||||||
|
# security.expires = 7200
|
||||||
|
# security.regenerate = true
|
||||||
|
# security.redirect = false
|
||||||
|
# security.samesite = 'Lax'
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# SESSION
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# session.driver = 'CodeIgniter\Session\Handlers\FileHandler'
|
||||||
|
# session.cookieName = 'ci_session'
|
||||||
|
# session.expiration = 7200
|
||||||
|
# session.savePath = null
|
||||||
|
# session.matchIP = false
|
||||||
|
# session.timeToUpdate = 300
|
||||||
|
# session.regenerateDestroy = false
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# LOGGER
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# logger.threshold = 4
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# CURLRequest
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
|
# curlrequest.shareOptions = true
|
||||||
45
app/Libraries/DhivaRoutes.php
Normal file
45
app/Libraries/DhivaRoutes.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Dhiva\Core;
|
||||||
|
|
||||||
|
use CodeIgniter\Router\RouteCollection as BaseRouteCollection;
|
||||||
|
|
||||||
|
class DhivaRoutes extends BaseRouteCollection
|
||||||
|
{
|
||||||
|
static function Route($routes, $path, $controller)
|
||||||
|
{
|
||||||
|
if (isset($_SERVER['REQUEST_METHOD'])) {
|
||||||
|
$routes->post('endpoencode', 'EndpointController::encodeEndpoint');
|
||||||
|
$routes->post('endpodecode', 'EndpointController::checkEncodeEndpoint');
|
||||||
|
$routes->get('image/(:segment)', 'AssetsController::decodeImage/$1');
|
||||||
|
$routes->get('pdf/(:segment)', 'AssetsController::decodePdf/$1');
|
||||||
|
|
||||||
|
$routes->post(SSL_KEY['route'] . '/(:segment)', 'RoutesController::decodeEndpointPost/$1');
|
||||||
|
$routes->get(SSL_KEY['route'] . '/(:segment)', 'RoutesController::decodeEndpointGet/$1');
|
||||||
|
$routes->put(SSL_KEY['route'] . '/(:segment)', 'RoutesController::decodeEndpointPut/$1');
|
||||||
|
$routes->delete(SSL_KEY['route'] . '/(:segment)', 'RoutesController::decodeEndpointDelete/$1');
|
||||||
|
|
||||||
|
$routes->post(SSL_KEY['route'] . '/(:segment)/(:segment)', 'RoutesController::decodeEndpointPost/$1/$2');
|
||||||
|
$routes->get(SSL_KEY['route'] . '/(:segment)/(:segment)', 'RoutesController::decodeEndpointGet/$1/$2');
|
||||||
|
$routes->put(SSL_KEY['route'] . '/(:segment)/(:segment)', 'RoutesController::decodeEndpointPut/$1/$2');
|
||||||
|
$routes->delete(SSL_KEY['route'] . '/(:segment)/(:segment)', 'RoutesController::decodeEndpointDelete/$1/$2');
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
|
||||||
|
$routes->get($path, $controller . "::index");
|
||||||
|
$routes->get($path . '/(:segment)', $controller . '::showAll/$1');
|
||||||
|
$routes->get($path . '/pages/(:segment)/(:segment)', $controller . '::pagination/$1/$2');
|
||||||
|
$routes->get($path . '/pagesbydate/(:segment)/(:segment)/(:segment)/(:segment)', $controller . '::paginationByDate/$1/$2/$3/$4');
|
||||||
|
$routes->get($path . '/show_by/(:segment)/(:segment)', $controller . '::showBy/$1/$2');
|
||||||
|
$routes->get($path . '/all_by/(:segment)/(:segment)', $controller . '::allBy/$1/$2');
|
||||||
|
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
$routes->post($path, $controller . "::create");
|
||||||
|
$routes->post($path . '/all-by', $controller . '::allByPost');
|
||||||
|
$routes->post($path . '/show-by', $controller . '::showByPost');
|
||||||
|
$routes->post($path . '/update/(:segment)', $controller . '::update/$1');
|
||||||
|
$routes->post($path . '/pagination', $controller . '::paginationpost');
|
||||||
|
} else if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
|
||||||
|
$routes->delete($path . '/delete/(:segment)', $controller . '::destroy/$1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
app/Libraries/DistribusiService.php
Normal file
15
app/Libraries/DistribusiService.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Libraries;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\Services;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class DistribusiService
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
423
app/Libraries/EmailService.php
Normal file
423
app/Libraries/EmailService.php
Normal file
@@ -0,0 +1,423 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Libraries;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\Services;
|
||||||
|
|
||||||
|
class EmailService
|
||||||
|
{
|
||||||
|
protected $email;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$emailConfig = new \Config\Email();
|
||||||
|
$this->email = Services::email($emailConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kirim OTP via Email
|
||||||
|
*
|
||||||
|
* @param string $toEmail Email tujuan
|
||||||
|
* @param string $otpCode Kode OTP
|
||||||
|
* @param string $userName Nama user
|
||||||
|
* @param string $pangkat Pangkat user
|
||||||
|
* @return array ['success' => bool, 'message' => string]
|
||||||
|
*/
|
||||||
|
public function sendOtpEmail($toEmail, $otpCode, $userName, $pangkat = '')
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->email->setFrom('prodevbackend587@gmail.com', 'E-Teguran Humanis Polda NTB');
|
||||||
|
$this->email->setTo($toEmail);
|
||||||
|
$this->email->setSubject('E-Teguran Humanis - Verifikasi OTP');
|
||||||
|
|
||||||
|
$message = $this->getOtpEmailTemplate($otpCode, $userName, $pangkat);
|
||||||
|
$this->email->setMessage($message);
|
||||||
|
|
||||||
|
$result = $this->email->send();
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
// PATCH: Set SMTPConnect ke null agar tidak error di __destruct
|
||||||
|
$reflection = new \ReflectionProperty($this->email, 'SMTPConnect');
|
||||||
|
$reflection->setAccessible(true);
|
||||||
|
$reflection->setValue($this->email, null);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
$this->email->clear(true);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Email OTP berhasil dikirim'
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
log_message('error', 'Email send error: ' . $this->email->printDebugger(['headers']));
|
||||||
|
|
||||||
|
// PATCH: Set SMTPConnect ke null agar tidak error di __destruct
|
||||||
|
$reflection = new \ReflectionProperty($this->email, 'SMTPConnect');
|
||||||
|
$reflection->setAccessible(true);
|
||||||
|
$reflection->setValue($this->email, null);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
$this->email->clear(true);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Gagal mengirim email OTP'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
log_message('error', 'Email exception: ' . $e->getMessage());
|
||||||
|
|
||||||
|
// PATCH: Set SMTPConnect ke null agar tidak error di __destruct
|
||||||
|
try {
|
||||||
|
$reflection = new \ReflectionProperty($this->email, 'SMTPConnect');
|
||||||
|
$reflection->setAccessible(true);
|
||||||
|
$reflection->setValue($this->email, null);
|
||||||
|
$this->email->clear(true);
|
||||||
|
} catch (\Exception $cleanupEx) {
|
||||||
|
// Ignore cleanup errors
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat mengirim email: ' . $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template HTML untuk email OTP (sesuai desain aplikasi)
|
||||||
|
*/
|
||||||
|
private function getOtpEmailTemplate($otpCode, $userName, $pangkat = '')
|
||||||
|
{
|
||||||
|
$fullName = !empty($pangkat) ? "{$pangkat} {$userName}" : $userName;
|
||||||
|
|
||||||
|
return '<!DOCTYPE html>
|
||||||
|
<html lang="id">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
|
||||||
|
<title>E-Teguran Humanis Polda NTB</title>
|
||||||
|
|
||||||
|
<!-- Gmail-Compatible Email Styling -->
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Arial, Helvetica, sans-serif !important;
|
||||||
|
color: #374151 !important;
|
||||||
|
background-color: #f0f9ff !important;
|
||||||
|
line-height: 1.6 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
mso-table-rspace: 0pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-wrapper {
|
||||||
|
width: 100% !important;
|
||||||
|
background-color: #f0f9ff !important;
|
||||||
|
padding: 20px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-container {
|
||||||
|
width: 600px !important;
|
||||||
|
max-width: 600px !important;
|
||||||
|
margin: 0 auto !important;
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border-radius: 12px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header {
|
||||||
|
background-color: #002A95 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
padding: 30px 20px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container {
|
||||||
|
margin-bottom: 20px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container img {
|
||||||
|
width: 80px !important;
|
||||||
|
height: 80px !important;
|
||||||
|
border-radius: 50% !important;
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
padding: 2px !important;
|
||||||
|
display: inline-block !important;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header h1 {
|
||||||
|
font-size: 24px !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
margin: 15px 0 8px 0 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header p {
|
||||||
|
font-size: 14px !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
opacity: 0.9;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-body {
|
||||||
|
padding: 30px 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-message {
|
||||||
|
background-color: #f0f9ff !important;
|
||||||
|
border-left: 4px solid #002A95 !important;
|
||||||
|
padding: 20px !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
margin-bottom: 25px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-message h2 {
|
||||||
|
color: #0c4a6e !important;
|
||||||
|
font-size: 18px !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-message p {
|
||||||
|
color: #075985 !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
line-height: 1.5 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-container {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border: 2px solid #e0f2fe !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 25px 20px !important;
|
||||||
|
margin: 25px 0 !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-title {
|
||||||
|
color: #0c4a6e !important;
|
||||||
|
font-size: 16px !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
margin-bottom: 20px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp-display {
|
||||||
|
background-color: #f8fafc !important;
|
||||||
|
border: 2px dashed #002A95 !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 25px !important;
|
||||||
|
margin: 20px 0 !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp-label {
|
||||||
|
font-weight: bold !important;
|
||||||
|
color: #475569 !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
letter-spacing: 0.5px !important;
|
||||||
|
margin-bottom: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp-code {
|
||||||
|
font-weight: bold !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-size: 32px !important;
|
||||||
|
background-color: #002A95 !important;
|
||||||
|
padding: 15px 25px !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
letter-spacing: 8px !important;
|
||||||
|
display: inline-block !important;
|
||||||
|
font-family: "Courier New", Courier, monospace !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp-validity {
|
||||||
|
color: #64748b !important;
|
||||||
|
font-size: 13px !important;
|
||||||
|
margin-top: 15px !important;
|
||||||
|
font-style: italic !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-notice {
|
||||||
|
background-color: #fef3c7 !important;
|
||||||
|
border-left: 4px solid #f59e0b !important;
|
||||||
|
padding: 18px !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
margin: 25px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-notice h3 {
|
||||||
|
color: #92400e !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
margin-bottom: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-notice ul {
|
||||||
|
margin: 10px 0 0 0 !important;
|
||||||
|
padding-left: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-notice li {
|
||||||
|
color: #b45309 !important;
|
||||||
|
font-size: 13px !important;
|
||||||
|
line-height: 1.6 !important;
|
||||||
|
margin-bottom: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-footer {
|
||||||
|
background-color: #1e293b !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
padding: 25px 20px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 0 auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-logo {
|
||||||
|
font-size: 16px !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
margin-bottom: 8px !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-address {
|
||||||
|
font-size: 12px !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
opacity: 0.8;
|
||||||
|
line-height: 1.4 !important;
|
||||||
|
margin-bottom: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-divider {
|
||||||
|
width: 40px !important;
|
||||||
|
height: 2px !important;
|
||||||
|
background-color: #002A95 !important;
|
||||||
|
margin: 0 auto 15px auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note {
|
||||||
|
font-size: 11px !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
opacity: 0.7;
|
||||||
|
font-style: italic !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile Responsive */
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
.email-container {
|
||||||
|
width: 100% !important;
|
||||||
|
margin: 0 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header,
|
||||||
|
.email-body,
|
||||||
|
.email-footer {
|
||||||
|
padding: 20px 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header h1 {
|
||||||
|
font-size: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-container {
|
||||||
|
padding: 20px 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp-code {
|
||||||
|
font-size: 28px !important;
|
||||||
|
padding: 12px 20px !important;
|
||||||
|
letter-spacing: 6px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="email-wrapper">
|
||||||
|
<table class="email-container" cellpadding="0" cellspacing="0" role="presentation">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<!-- Header Section -->
|
||||||
|
<div class="email-header">
|
||||||
|
<div class="logo-container">
|
||||||
|
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/Lambang_Polda_NTB.png/800px-Lambang_Polda_NTB.png"
|
||||||
|
alt="Logo Polri" style="width: 80px; height: 80px; border-radius: 50%; background-color: #ffffff; padding: 2px; display: inline-block; border: 1px solid rgba(255, 255, 255, 0.3);" />
|
||||||
|
</div>
|
||||||
|
<h1>E-Teguran Humanis</h1>
|
||||||
|
<p>Polda Nusa Tenggara Barat</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Body Section -->
|
||||||
|
<div class="email-body">
|
||||||
|
<div class="welcome-message">
|
||||||
|
<h2>Verifikasi Akun Anda</h2>
|
||||||
|
<p>Kepada Yth. <strong>' . htmlspecialchars($fullName) . '</strong>, kami telah menerima permintaan verifikasi akun Anda.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="credentials-container">
|
||||||
|
<h3 class="credentials-title">Kode Verifikasi OTP Anda</h3>
|
||||||
|
|
||||||
|
<div class="otp-display">
|
||||||
|
<div class="otp-label">Kode OTP</div>
|
||||||
|
<div class="otp-code">' . htmlspecialchars($otpCode) . '</div>
|
||||||
|
<div class="otp-validity">Kode ini berlaku selama 10 menit</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="security-notice">
|
||||||
|
<h3>⚠️ Penting untuk Keamanan</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Jangan bagikan</strong> kode ini kepada siapa pun</li>
|
||||||
|
<li>Kode ini hanya berlaku untuk <strong>10 menit</strong></li>
|
||||||
|
<li>Jika Anda tidak melakukan permintaan ini, segera hubungi administrator sistem</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Footer Section -->
|
||||||
|
<div class="email-footer">
|
||||||
|
<div class="footer-content">
|
||||||
|
<div class="footer-logo">E-Teguran Humanis</div>
|
||||||
|
<div class="footer-address">
|
||||||
|
Polda Nusa Tenggara Barat<br>
|
||||||
|
Jl. Langko No. 77, Taman Sari, Ampenan, Kota Mataram
|
||||||
|
</div>
|
||||||
|
<div class="footer-divider"></div>
|
||||||
|
<div class="footer-note">
|
||||||
|
Email ini dikirim secara otomatis, mohon tidak membalas email ini.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>';
|
||||||
|
}
|
||||||
|
}
|
||||||
461
app/Libraries/MekariWhatsAppService.php
Normal file
461
app/Libraries/MekariWhatsAppService.php
Normal file
@@ -0,0 +1,461 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Libraries;
|
||||||
|
|
||||||
|
use App\Config\ExternalApi;
|
||||||
|
|
||||||
|
class MekariWhatsAppService
|
||||||
|
{
|
||||||
|
private $hmacUsername;
|
||||||
|
private $hmacSecret;
|
||||||
|
private $apiUrl;
|
||||||
|
private $channelIntegrationId;
|
||||||
|
private $messageTemplateId;
|
||||||
|
private $messageTemplateIdPelanggaranID;
|
||||||
|
private $messageTemplateIdPelanggaranEN;
|
||||||
|
private $uploadApiUrl;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$config = config('ExternalApi');
|
||||||
|
|
||||||
|
$this->hmacUsername = $config->hmacUsername;
|
||||||
|
$this->hmacSecret = $config->hmacSecret;
|
||||||
|
$this->channelIntegrationId = $config->channelIntegrationId;
|
||||||
|
$this->messageTemplateId = $config->messageTemplateId;
|
||||||
|
$this->messageTemplateIdPelanggaranID = $config->messageTemplateIdPelanggaranID;
|
||||||
|
$this->messageTemplateIdPelanggaranEN = $config->messageTemplateIdPelanggaranEN;
|
||||||
|
$this->apiUrl = 'https://api.mekari.com/qontak/chat/v1/broadcasts/whatsapp/direct';
|
||||||
|
$this->uploadApiUrl = 'https://api.mekari.com/qontak/chat/v1/file_uploader';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload foto ke Mekari untuk digunakan di WhatsApp template
|
||||||
|
* Jika file WebP, akan dikonversi ke JPEG dulu
|
||||||
|
*/
|
||||||
|
public function uploadImage($filePath)
|
||||||
|
{
|
||||||
|
$tempJpegPath = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!file_exists($filePath)) {
|
||||||
|
throw new \Exception("File tidak ditemukan: {$filePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileExtension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
|
||||||
|
$uploadFilePath = $filePath;
|
||||||
|
$uploadFileName = basename($filePath);
|
||||||
|
|
||||||
|
// Konversi WebP ke JPEG
|
||||||
|
if ($fileExtension === 'webp') {
|
||||||
|
log_message('debug', "Converting WebP to JPEG: {$filePath}");
|
||||||
|
|
||||||
|
$tempJpegPath = sys_get_temp_dir() . '/' . uniqid('wa_upload_') . '.jpg';
|
||||||
|
$image = imagecreatefromwebp($filePath);
|
||||||
|
|
||||||
|
if (!$image) {
|
||||||
|
throw new \Exception("Gagal membaca file WebP");
|
||||||
|
}
|
||||||
|
|
||||||
|
$converted = imagejpeg($image, $tempJpegPath, 90);
|
||||||
|
imagedestroy($image);
|
||||||
|
|
||||||
|
if (!$converted) {
|
||||||
|
throw new \Exception("Gagal konversi WebP ke JPEG");
|
||||||
|
}
|
||||||
|
|
||||||
|
$uploadFilePath = $tempJpegPath;
|
||||||
|
$uploadFileName = pathinfo($filePath, PATHINFO_FILENAME) . '.jpg';
|
||||||
|
|
||||||
|
log_message('debug', "WebP converted to JPEG: {$tempJpegPath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$urlParts = parse_url($this->uploadApiUrl);
|
||||||
|
$path = $urlParts['path'];
|
||||||
|
$dateString = gmdate('D, d M Y H:i:s') . ' GMT';
|
||||||
|
$hmacAuth = $this->generateHmacAuth('POST', $path, $dateString);
|
||||||
|
|
||||||
|
$cFile = new \CURLFile($uploadFilePath, 'image/jpeg', $uploadFileName);
|
||||||
|
|
||||||
|
$ch = curl_init($this->uploadApiUrl);
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
CURLOPT_HTTPHEADER => [
|
||||||
|
'Authorization: ' . $hmacAuth,
|
||||||
|
'Date: ' . $dateString
|
||||||
|
],
|
||||||
|
CURLOPT_POSTFIELDS => ['file' => $cFile],
|
||||||
|
CURLOPT_TIMEOUT => 60,
|
||||||
|
CURLOPT_SSL_VERIFYPEER => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$error = curl_error($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
// Cleanup temporary file
|
||||||
|
if ($tempJpegPath && file_exists($tempJpegPath)) {
|
||||||
|
unlink($tempJpegPath);
|
||||||
|
log_message('debug', "Temporary JPEG file deleted: {$tempJpegPath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
log_message('error', "Mekari Upload cURL Error: {$error}");
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Gagal upload gambar ke server'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message('debug', "Mekari Upload Response [{$httpCode}]: {$response}");
|
||||||
|
|
||||||
|
$result = json_decode($response, true);
|
||||||
|
|
||||||
|
if ($httpCode >= 200 && $httpCode < 300 && isset($result['data']['url'])) {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Gambar berhasil diupload',
|
||||||
|
'url' => $result['data']['url'],
|
||||||
|
'filename' => $result['data']['filename']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$errorMessage = 'Gagal upload gambar';
|
||||||
|
if (isset($result['error']['message'])) {
|
||||||
|
$errorMessage = $result['error']['message'];
|
||||||
|
} elseif (isset($result['message'])) {
|
||||||
|
$errorMessage = $result['message'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => $errorMessage
|
||||||
|
];
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
if ($tempJpegPath && file_exists($tempJpegPath)) {
|
||||||
|
unlink($tempJpegPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message('error', "Mekari Upload Exception: " . $e->getMessage());
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat upload gambar: ' . $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendOtp($phoneNumber, $otpCode, $userName = '', $subject = 'VERIFIKASI AKUN')
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$phoneNumber = $this->formatPhoneNumber($phoneNumber);
|
||||||
|
$urlParts = parse_url($this->apiUrl);
|
||||||
|
$path = $urlParts['path'];
|
||||||
|
$dateString = gmdate('D, d M Y H:i:s') . ' GMT';
|
||||||
|
$hmacAuth = $this->generateHmacAuth('POST', $path, $dateString);
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'to_number' => $phoneNumber,
|
||||||
|
'to_name' => $userName ?: 'User',
|
||||||
|
'message_template_id' => $this->messageTemplateId,
|
||||||
|
'channel_integration_id' => $this->channelIntegrationId,
|
||||||
|
'language' => [
|
||||||
|
'code' => 'id'
|
||||||
|
],
|
||||||
|
'parameters' => [
|
||||||
|
'body' => [
|
||||||
|
[
|
||||||
|
'key' => '1',
|
||||||
|
'value' => 'code',
|
||||||
|
'value_text' => $otpCode
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"buttons" => [
|
||||||
|
[
|
||||||
|
"index" => "0",
|
||||||
|
"type" => "url",
|
||||||
|
"value" => "$otpCode"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
log_message('debug', "Mekari WA OTP Request - Date: {$dateString}");
|
||||||
|
log_message('debug', "Mekari WA OTP Payload: " . json_encode($payload));
|
||||||
|
|
||||||
|
return $this->sendRequest($payload, $hmacAuth, $dateString);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
log_message('error', "Mekari WA OTP Exception: " . $e->getMessage());
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat mengirim OTP'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kirim notifikasi pelanggaran via WhatsApp dengan header image
|
||||||
|
*
|
||||||
|
* @param string $phoneNumber Nomor WhatsApp tujuan
|
||||||
|
* @param array $data Data pelanggaran dengan keys:
|
||||||
|
* - nama, jenis_pelanggaran, tanggal_formatted, waktu_formatted
|
||||||
|
* - lokasi_kejadian, dasar_hukum, pasal, hukuman, urutan_pelanggaran
|
||||||
|
* - pelanggaran_id, is_luar_negeri, image_url (optional), image_filename (optional)
|
||||||
|
*/
|
||||||
|
public function sendNotifikasiPelanggaran($phoneNumber, $data)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$phoneNumber = $this->formatPhoneNumber($phoneNumber);
|
||||||
|
$urlParts = parse_url($this->apiUrl);
|
||||||
|
$path = $urlParts['path'];
|
||||||
|
$dateString = gmdate('D, d M Y H:i:s') . ' GMT';
|
||||||
|
$hmacAuth = $this->generateHmacAuth('POST', $path, $dateString);
|
||||||
|
|
||||||
|
$isLuarNegeri = $data['is_luar_negeri'] ?? false;
|
||||||
|
// $templateId = $isLuarNegeri ?
|
||||||
|
// $this->messageTemplateIdPelanggaranEN :
|
||||||
|
// $this->messageTemplateIdPelanggaranID;
|
||||||
|
$templateId = $this->messageTemplateIdPelanggaranID;
|
||||||
|
|
||||||
|
// Validasi required fields
|
||||||
|
$requiredFields = [
|
||||||
|
'nama', 'jenis_pelanggaran', 'tanggal_formatted',
|
||||||
|
'waktu_formatted', 'lokasi_kejadian', 'dasar_hukum',
|
||||||
|
'pasal', 'hukuman', 'urutan_pelanggaran', 'pelanggaran_id'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($requiredFields as $field) {
|
||||||
|
if (empty($data[$field])) {
|
||||||
|
throw new \Exception("Field '{$field}' is required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kalau template inggris sudah ada bisa di uncomment di bawah ini
|
||||||
|
// Build body parameters
|
||||||
|
// if ($isLuarNegeri) {
|
||||||
|
// $bodyParams = [
|
||||||
|
// ['key' => '1', 'value' => 'p1', 'value_text' => $data['urutan_pelanggaran']],
|
||||||
|
// ['key' => '2', 'value' => 'p2', 'value_text' => $data['title'] ?? 'Mr./Ms.'],
|
||||||
|
// ['key' => '3', 'value' => 'p3', 'value_text' => $data['nama']],
|
||||||
|
// ['key' => '4', 'value' => 'p4', 'value_text' => $data['jenis_pelanggaran']],
|
||||||
|
// ['key' => '5', 'value' => 'p5', 'value_text' => $data['tanggal_formatted']],
|
||||||
|
// ['key' => '6', 'value' => 'p6', 'value_text' => $data['waktu_formatted']],
|
||||||
|
// ['key' => '7', 'value' => 'p7', 'value_text' => $data['lokasi_kejadian']],
|
||||||
|
// ['key' => '8', 'value' => 'p8', 'value_text' => $data['dasar_hukum']],
|
||||||
|
// ['key' => '9', 'value' => 'p9', 'value_text' => $data['pasal']],
|
||||||
|
// ['key' => '10', 'value' => 'p10', 'value_text' => $data['hukuman']]
|
||||||
|
// ];
|
||||||
|
// } else {
|
||||||
|
// $bodyParams = [
|
||||||
|
// ['key' => '1', 'value' => 'p1', 'value_text' => $data['urutan_pelanggaran']],
|
||||||
|
// ['key' => '2', 'value' => 'p2', 'value_text' => $data['nama']],
|
||||||
|
// ['key' => '3', 'value' => 'p3', 'value_text' => $data['jenis_pelanggaran']],
|
||||||
|
// ['key' => '4', 'value' => 'p4', 'value_text' => $data['tanggal_formatted']],
|
||||||
|
// ['key' => '5', 'value' => 'p5', 'value_text' => $data['waktu_formatted']],
|
||||||
|
// ['key' => '6', 'value' => 'p6', 'value_text' => $data['lokasi_kejadian']],
|
||||||
|
// ['key' => '7', 'value' => 'p7', 'value_text' => $data['dasar_hukum']],
|
||||||
|
// ['key' => '8', 'value' => 'p8', 'value_text' => $data['pasal']],
|
||||||
|
// ['key' => '9', 'value' => 'p9', 'value_text' => $data['hukuman']]
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Selalu pakai format Indonesia dulu (9 parameter)
|
||||||
|
$bodyParams = [
|
||||||
|
['key' => '1', 'value' => 'p1', 'value_text' => $data['urutan_pelanggaran']],
|
||||||
|
['key' => '2', 'value' => 'p2', 'value_text' => $data['nama']],
|
||||||
|
['key' => '3', 'value' => 'p3', 'value_text' => $data['jenis_pelanggaran']],
|
||||||
|
['key' => '4', 'value' => 'p4', 'value_text' => $data['tanggal_formatted']],
|
||||||
|
['key' => '5', 'value' => 'p5', 'value_text' => $data['waktu_formatted']],
|
||||||
|
['key' => '6', 'value' => 'p6', 'value_text' => $data['lokasi_kejadian']],
|
||||||
|
['key' => '7', 'value' => 'p7', 'value_text' => $data['dasar_hukum']],
|
||||||
|
['key' => '8', 'value' => 'p8', 'value_text' => $data['pasal']],
|
||||||
|
['key' => '9', 'value' => 'p9', 'value_text' => $data['hukuman']]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Build payload parameters
|
||||||
|
$parameters = [
|
||||||
|
'body' => $bodyParams,
|
||||||
|
'buttons' => [
|
||||||
|
[
|
||||||
|
'index' => '0',
|
||||||
|
'type' => 'url',
|
||||||
|
'value' => $data['pelanggaran_id']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Tambahkan header
|
||||||
|
if (!empty($data['image_url']) && !empty($data['image_filename'])) {
|
||||||
|
$parameters['header'] = [
|
||||||
|
'format' => 'IMAGE',
|
||||||
|
'params' => [
|
||||||
|
[
|
||||||
|
'key' => 'url',
|
||||||
|
'value' => $data['image_url']
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => 'filename',
|
||||||
|
'value' => $data['image_filename']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$parameters['header'] = [
|
||||||
|
'format' => 'IMAGE',
|
||||||
|
'params' => [
|
||||||
|
[
|
||||||
|
'key' => 'url',
|
||||||
|
'value' => "https://cdn.qontak.com/uploads/direct/images/1ed10e3c-461f-477f-a74a-ee6553f23f4d/photo_2025-11-10_15-32-37.jpg"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => 'filename',
|
||||||
|
'value' => "photo_2025-11-10_15-32-37.jpg"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'to_number' => $phoneNumber,
|
||||||
|
'to_name' => $data['nama'],
|
||||||
|
'message_template_id' => $templateId,
|
||||||
|
'channel_integration_id' => $this->channelIntegrationId,
|
||||||
|
'language' => [
|
||||||
|
'code' => $isLuarNegeri ? 'en' : 'id'
|
||||||
|
],
|
||||||
|
'parameters' => $parameters
|
||||||
|
];
|
||||||
|
|
||||||
|
log_message('debug', "Mekari WA Pelanggaran Request - Date: {$dateString}");
|
||||||
|
log_message('debug', "Mekari WA Pelanggaran Payload: " . json_encode($payload));
|
||||||
|
|
||||||
|
$result = $this->sendRequest($payload, $hmacAuth, $dateString);
|
||||||
|
|
||||||
|
if ($result['success']) {
|
||||||
|
log_message('info', "WhatsApp notification sent to {$phoneNumber} for pelanggaran {$data['pelanggaran_id']}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
log_message('error', "Mekari WA Pelanggaran Exception: " . $e->getMessage());
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat mengirim notifikasi pelanggaran: ' . $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function sendRequest($payload, $hmacAuth, $dateString)
|
||||||
|
{
|
||||||
|
$ch = curl_init($this->apiUrl);
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
CURLOPT_HTTPHEADER => [
|
||||||
|
'Authorization: ' . $hmacAuth,
|
||||||
|
'Date: ' . $dateString,
|
||||||
|
'Content-Type: application/json'
|
||||||
|
],
|
||||||
|
CURLOPT_POSTFIELDS => json_encode($payload),
|
||||||
|
CURLOPT_TIMEOUT => 30,
|
||||||
|
CURLOPT_SSL_VERIFYPEER => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$error = curl_error($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
log_message('error', "Mekari WA cURL Error: {$error}");
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Gagal terhubung ke server WhatsApp'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message('debug', "Mekari WA Response [{$httpCode}]: {$response}");
|
||||||
|
|
||||||
|
$result = json_decode($response, true);
|
||||||
|
|
||||||
|
if ($httpCode >= 200 && $httpCode < 300) {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Pesan berhasil dikirim',
|
||||||
|
'data' => $result
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$errorMessage = 'Gagal mengirim pesan';
|
||||||
|
if (isset($result['error']['message'])) {
|
||||||
|
$errorMessage = $result['error']['message'];
|
||||||
|
} elseif (isset($result['message'])) {
|
||||||
|
$errorMessage = $result['message'];
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message('error', "Mekari WA Error [{$httpCode}]: " . $response);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => $errorMessage,
|
||||||
|
'error_code' => $result['error']['code'] ?? $httpCode,
|
||||||
|
// 'raw_response' => $result // Untuk debugging
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateHmacAuth($method, $path, $dateString)
|
||||||
|
{
|
||||||
|
$requestLine = strtoupper($method) . ' ' . $path . ' HTTP/1.1';
|
||||||
|
$stringToSign = 'date: ' . $dateString . "\n" . $requestLine;
|
||||||
|
$signature = base64_encode(hash_hmac('sha256', $stringToSign, $this->hmacSecret, true));
|
||||||
|
|
||||||
|
$hmacHeader = sprintf(
|
||||||
|
'hmac username="%s", algorithm="hmac-sha256", headers="date request-line", signature="%s"',
|
||||||
|
$this->hmacUsername,
|
||||||
|
$signature
|
||||||
|
);
|
||||||
|
|
||||||
|
return $hmacHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatPhoneNumber($phone)
|
||||||
|
{
|
||||||
|
$phone = preg_replace('/[^0-9]/', '', $phone);
|
||||||
|
|
||||||
|
if (substr($phone, 0, 2) === '62') {
|
||||||
|
return $phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (substr($phone, 0, 1) === '0') {
|
||||||
|
return '62' . substr($phone, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '62' . $phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyWebhookSignature($authHeader, $dateHeader, $method, $path)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
preg_match('/signature="([^"]+)"/', $authHeader, $matches);
|
||||||
|
$receivedSignature = $matches[1] ?? '';
|
||||||
|
|
||||||
|
if (empty($receivedSignature)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestLine = strtoupper($method) . ' ' . $path . ' HTTP/1.1';
|
||||||
|
$stringToSign = 'date: ' . $dateHeader . "\n" . $requestLine;
|
||||||
|
$expectedSignature = base64_encode(hash_hmac('sha256', $stringToSign, $this->hmacSecret, true));
|
||||||
|
|
||||||
|
return hash_equals($expectedSignature, $receivedSignature);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
log_message('error', "HMAC Verification Error: " . $e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1002
app/Libraries/MongoLib.php
Normal file
1002
app/Libraries/MongoLib.php
Normal file
File diff suppressed because it is too large
Load Diff
39
app/Libraries/Notification.php
Normal file
39
app/Libraries/Notification.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Dhiva\Core;
|
||||||
|
|
||||||
|
class Notification
|
||||||
|
{
|
||||||
|
public function getNotification()
|
||||||
|
{
|
||||||
|
$notification = array();
|
||||||
|
$notification['title'] = "KAMTIBMAS (KEAMANAN KETERTIBAN MASYARAKAT)";
|
||||||
|
$notification['message'] = "Selamat datang di Aplikasi KAMTIBMAS (KEAMANAN KETERTIBAN MASYARAKAT) (0)";
|
||||||
|
$notification['image'] = "https://project.adhivasindo.co.id/diy/assets/logo/logo_polda_diy.png";
|
||||||
|
return $notification;
|
||||||
|
}
|
||||||
|
public function publish($publish)
|
||||||
|
{
|
||||||
|
$ff = explode('#', $publish['isi']);
|
||||||
|
$notification['title'] = $ff[0];
|
||||||
|
$notification['message'] =$ff[1]. PHP_EOL. $ff[2]. PHP_EOL. $ff[3];
|
||||||
|
$fields = array('to' => FIREBASE_TOPIC . $publish['topic'], 'data' => $notification);
|
||||||
|
$url = 'https://fcm.googleapis.com/fcm/send';
|
||||||
|
$headers = array('Authorization: key=' . FIREBASE_API, 'Content-Type: application/json');
|
||||||
|
$ch = curl_init();
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
|
||||||
|
|
||||||
|
$output = curl_exec($ch);
|
||||||
|
if (!json_decode($output)) {
|
||||||
|
print_r($output);
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
curl_close($ch);
|
||||||
|
return json_decode($output);
|
||||||
|
}
|
||||||
|
}
|
||||||
126
app/Libraries/Tenancy.php
Normal file
126
app/Libraries/Tenancy.php
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Dhiva\Core;
|
||||||
|
|
||||||
|
class Tenancy
|
||||||
|
{
|
||||||
|
public static function createTenancy($res)
|
||||||
|
{
|
||||||
|
self::dbtenancy($res);
|
||||||
|
}
|
||||||
|
public static function connectTenancy($res)
|
||||||
|
{
|
||||||
|
$db = \Config\Database::forge();
|
||||||
|
$db = new \Config\Database;
|
||||||
|
$dbSelect = $db->postgre;
|
||||||
|
$dbSelect['schema'] = $res;
|
||||||
|
return \Config\Database::forge($dbSelect);
|
||||||
|
}
|
||||||
|
public static function disconnectTenancy()
|
||||||
|
{
|
||||||
|
$db = \Config\Database::forge();
|
||||||
|
$db = new \Config\Database;
|
||||||
|
$dbSelect = $db->postgre;
|
||||||
|
$dbSelect['schema'] = 'public';
|
||||||
|
return \Config\Database::forge($dbSelect);
|
||||||
|
}
|
||||||
|
private static function dbtenancy($res)
|
||||||
|
{
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
$schemaName = '"' . $res . '"';
|
||||||
|
$query = $db->query('CREATE SCHEMA ' . $schemaName);
|
||||||
|
if (!$query) {
|
||||||
|
return 'Gagal membuat ' . $schemaName;
|
||||||
|
}
|
||||||
|
$db = new \Config\Database;
|
||||||
|
$dbSelect = $db->postgre;
|
||||||
|
$dbSelect['schema'] = $schemaName;
|
||||||
|
$forge = \Config\Database::forge($dbSelect);
|
||||||
|
// $forge->addField([
|
||||||
|
// 'endpoint_id' => [
|
||||||
|
// 'type' => 'INT',
|
||||||
|
// 'constraint' => 255,
|
||||||
|
// 'auto_increment' => true,
|
||||||
|
// 'unique' => true,
|
||||||
|
// ],
|
||||||
|
// 'value' => [
|
||||||
|
// 'type' => 'VARCHAR',
|
||||||
|
// 'constraint' => 200,
|
||||||
|
// ],
|
||||||
|
// 'description' => [
|
||||||
|
// 'type' => 'VARCHAR',
|
||||||
|
// 'constraint' => 200,
|
||||||
|
// 'null' => true,
|
||||||
|
// ],
|
||||||
|
// 'created_by' => [
|
||||||
|
// 'type' => 'VARCHAR',
|
||||||
|
// 'constraint' => 200,
|
||||||
|
// 'null' => true,
|
||||||
|
// ],
|
||||||
|
// 'created_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
// ]);
|
||||||
|
// $forge->addKey('endpoint_id', true);
|
||||||
|
// $forge->createTable('endpoint');
|
||||||
|
|
||||||
|
$forge->addField([
|
||||||
|
'super_user_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'super_group_id' => [
|
||||||
|
'type' => 'TEXT',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'name' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 50,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'email' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 50,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'username' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 50,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'password' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'avatar' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'token' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'login_date' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'access_at' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'is_admin' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'unit_id' => [
|
||||||
|
'type' => 'VARCHAR',
|
||||||
|
'constraint' => 200,
|
||||||
|
],
|
||||||
|
'created_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP',
|
||||||
|
]);
|
||||||
|
$forge->addKey('super_user_id', true);
|
||||||
|
$forge->createTable('super_user');
|
||||||
|
}
|
||||||
|
}
|
||||||
157
app/Libraries/WablasService.php
Normal file
157
app/Libraries/WablasService.php
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Libraries;
|
||||||
|
|
||||||
|
use CodeIgniter\HTTP\CURLRequest;
|
||||||
|
|
||||||
|
class WablasService
|
||||||
|
{
|
||||||
|
protected string $token;
|
||||||
|
protected string $secretKey;
|
||||||
|
protected string $baseUrl = 'https://tegal.wablas.com/api/v2';
|
||||||
|
protected $externalApi;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->externalApi = new \Config\ExternalApi();
|
||||||
|
$this->token = env('WABLAS_TOKEN') ?: $this->externalApi->wablasToken;
|
||||||
|
$this->secretKey = env('WABLAS_SECRET_KEY') ?: $this->externalApi->WablasSecretKey;
|
||||||
|
|
||||||
|
if (empty($this->token) || empty($this->secretKey)) {
|
||||||
|
throw new \Exception('Unauthorized');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kirim pesan teks biasa (single)
|
||||||
|
public function sendText(string $phone, string $message, bool $isGroup = false): array
|
||||||
|
{
|
||||||
|
return $this->sendBulkText([['phone' => $phone, 'message' => $message, 'isGroup' => $isGroup ? 'true' : 'false']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kirim pesan teks massal (multiple)
|
||||||
|
public function sendBulkText(array $messages): array
|
||||||
|
{
|
||||||
|
$formatted = [];
|
||||||
|
foreach ($messages as $msg) {
|
||||||
|
if (!isset($msg['phone']) || !isset($msg['message'])) {
|
||||||
|
throw new \InvalidArgumentException('Setiap pesan harus memiliki "phone" dan "message"');
|
||||||
|
}
|
||||||
|
$formatted[] = [
|
||||||
|
'phone' => $this->sanitizePhone($msg['phone']),
|
||||||
|
'message' => $msg['message'],
|
||||||
|
'isGroup' => $msg['isGroup'] ?? 'false'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->makeRequest('/send-message', ['data' => $formatted]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kirim OTP atau template message
|
||||||
|
public function sendTemplate(string $phone, string $content, string $title = 'Verification Code', string $footer = 'Supported by Wablas', string $code = ''): array
|
||||||
|
{
|
||||||
|
$message = [
|
||||||
|
'title' => [
|
||||||
|
'type' => 'text',
|
||||||
|
'content' => $title
|
||||||
|
],
|
||||||
|
'content' => $content,
|
||||||
|
'footer' => $footer
|
||||||
|
];
|
||||||
|
|
||||||
|
// Hanya tambahkan buttons jika code ada
|
||||||
|
if (!empty($code)) {
|
||||||
|
$message['buttons'] = [
|
||||||
|
'url' => [
|
||||||
|
'display' => 'Copy',
|
||||||
|
'link' => "https://www.whatsapp.com/otp/copy/" . $code
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'data' => [
|
||||||
|
[
|
||||||
|
'phone' => $this->sanitizePhone($phone),
|
||||||
|
'message' => $message
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->makeRequest('/send-template', $payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kirim OTP sederhana - PERSIS SEPERTI DOKUMENTASI
|
||||||
|
public function sendOTP(string $phone, string $code, string $title = 'Verification Code'): array
|
||||||
|
{
|
||||||
|
$phone = $this->sanitizePhone($phone);
|
||||||
|
|
||||||
|
$message = [
|
||||||
|
'title' => [
|
||||||
|
'type' => 'text',
|
||||||
|
'content' => $title,
|
||||||
|
],
|
||||||
|
'buttons' => [
|
||||||
|
'url' => [
|
||||||
|
'display' => 'Copy',
|
||||||
|
'link' => "https://www.whatsapp.com/otp/copy/" . $code,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'content' => "Your verification code : $code",
|
||||||
|
'footer' => 'Supported by Wablas',
|
||||||
|
];
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'data' => [
|
||||||
|
[
|
||||||
|
'phone' => $phone,
|
||||||
|
'message' => $message
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->makeRequest('/send-message', $payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fungsi internal untuk eksekusi API
|
||||||
|
protected function makeRequest(string $endpoint, array $payload): array
|
||||||
|
{
|
||||||
|
$curl = \Config\Services::curlrequest();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $curl->post($this->baseUrl . $endpoint, [
|
||||||
|
'headers' => [
|
||||||
|
'Authorization' => $this->token . '.' . $this->secretKey,
|
||||||
|
'Content-Type' => 'application/json'
|
||||||
|
],
|
||||||
|
'json' => $payload,
|
||||||
|
'verify' => false // Sama seperti CURLOPT_SSL_VERIFYPEER = 0
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = json_decode($response->getBody(), true);
|
||||||
|
$statusCode = $response->getStatusCode();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => ($statusCode === 200 && !empty($result)),
|
||||||
|
'data' => $result,
|
||||||
|
'http_code' => $statusCode
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bersihkan nomor HP ke format internasional
|
||||||
|
protected function sanitizePhone(string $phone): string
|
||||||
|
{
|
||||||
|
$phone = preg_replace('/[^0-9]/', '', $phone);
|
||||||
|
if (substr($phone, 0, 2) === '08') {
|
||||||
|
$phone = '62' . substr($phone, 1);
|
||||||
|
} elseif (substr($phone, 0, 1) === '8') {
|
||||||
|
$phone = '62' . $phone;
|
||||||
|
}
|
||||||
|
return $phone;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
app/Libraries/Zoom/.gitignore
vendored
Normal file
3
app/Libraries/Zoom/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/vendor
|
||||||
|
.idea
|
||||||
|
.idea/*
|
||||||
146
app/Libraries/Zoom/Endpoint/Meetings.php
Normal file
146
app/Libraries/Zoom/Endpoint/Meetings.php
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright https://github.com/UsabilityDynamics/zoom-api-php-client/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
namespace Zoom\Endpoint;
|
||||||
|
|
||||||
|
use Zoom\Interfaces\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Meetings
|
||||||
|
* @package Zoom\Endpoint
|
||||||
|
*/
|
||||||
|
class Meetings extends Request {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meetings constructor.
|
||||||
|
* @param $apiKey
|
||||||
|
* @param $apiSecret
|
||||||
|
*/
|
||||||
|
public function __construct($apiKey, $apiSecret) {
|
||||||
|
parent::__construct($apiKey, $apiSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List
|
||||||
|
*
|
||||||
|
* @param $userId
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function list(string $userId, array $query = []) {
|
||||||
|
return $this->get("users/{$userId}/meetings", $query);
|
||||||
|
}
|
||||||
|
public function userInfo(string $email) {
|
||||||
|
return $this->get("users/me");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create
|
||||||
|
*
|
||||||
|
* @param $userId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function create(string $userId, array $data = null) {
|
||||||
|
return $this->post("users/{$userId}/meetings", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meeting
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function meeting(string $meetingId) {
|
||||||
|
return $this->get("meetings/{$meetingId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function remove(string $meetingId) {
|
||||||
|
return $this->delete("meetings/{$meetingId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function update(string $meetingId, array $data = []) {
|
||||||
|
return $this->patch("meetings/{$meetingId}", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function status(string $meetingId, array $data = []) {
|
||||||
|
return $this->put("meetings/{$meetingId}/status", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Registrants
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function listRegistrants(string $meetingId, array $query = []) {
|
||||||
|
return $this->get("meetings/{$meetingId}/registrants", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Registrant
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function addRegistrant(string $meetingId, $data = []) {
|
||||||
|
return $this->post("meetings/{$meetingId}/registrants", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Registrant Status
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function updateRegistrantStatus(string $meetingId, array $data = []) {
|
||||||
|
return $this->put("meetings/{$meetingId}/registrants/status", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Past Meeting
|
||||||
|
*
|
||||||
|
* @param $meetingUUID
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function pastMeeting(string $meetingUUID) {
|
||||||
|
return $this->get("past_meetings/{$meetingUUID}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Past Meeting Participants
|
||||||
|
*
|
||||||
|
* @param $meetingUUID
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function pastMeetingParticipants(string $meetingUUID, array $query = []) {
|
||||||
|
return $this->get("past_meetings/{$meetingUUID}/participants", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
96
app/Libraries/Zoom/Endpoint/Recordings.php
Normal file
96
app/Libraries/Zoom/Endpoint/Recordings.php
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright https://github.com/UsabilityDynamics/zoom-api-php-client/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
namespace Zoom\Endpoint;
|
||||||
|
|
||||||
|
use Zoom\Interfaces\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Recordings
|
||||||
|
* @package Zoom\Endpoint
|
||||||
|
*/
|
||||||
|
class Recordings extends Request {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recordings constructor.
|
||||||
|
* @param $apiKey
|
||||||
|
* @param $apiSecret
|
||||||
|
*/
|
||||||
|
public function __construct($apiKey, $apiSecret) {
|
||||||
|
parent::__construct($apiKey, $apiSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List
|
||||||
|
*
|
||||||
|
* @param $userId
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function listAll(string $userId, array $query = []) {
|
||||||
|
return $this->get("users/{$userId}/recordings", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meeting
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function meeting(string $meetingId) {
|
||||||
|
return $this->get("meetings/{$meetingId}/recordings");
|
||||||
|
}
|
||||||
|
public function download(string $meetingId) {
|
||||||
|
|
||||||
|
return $this->get($meetingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove All
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function removeAll(string $meetingId, array $query = [ 'action' => 'trash' ]) {
|
||||||
|
return $this->delete("meetings/{$meetingId}/recordings", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param $recordingId
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function remove(string $meetingId, string $recordingId, array $query = [ 'action' => 'trash' ]) {
|
||||||
|
return $this->delete("meetings/{$meetingId}/recordings/{$recordingId}", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recover All
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function recoverAll(string $meetingId, array $data = [ 'action' => 'recover' ]) {
|
||||||
|
return $this->put("meetings/{$meetingId}/recordings/status", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recover
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param $recordingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function recover(string $meetingId, string $recordingId, array $data = [ 'action' => 'recover' ]) {
|
||||||
|
return $this->put("meetings/{$meetingId}/recordings/{$recordingId}/status", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
36
app/Libraries/Zoom/Endpoint/Reports.php
Normal file
36
app/Libraries/Zoom/Endpoint/Reports.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright https://github.com/UsabilityDynamics/zoom-api-php-client/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
namespace Zoom\Endpoint;
|
||||||
|
|
||||||
|
use Zoom\Interfaces\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Reports
|
||||||
|
* @package Zoom\Interfaces
|
||||||
|
*/
|
||||||
|
class Reports extends Request {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meetings constructor.
|
||||||
|
* @param $apiKey
|
||||||
|
* @param $apiSecret
|
||||||
|
*/
|
||||||
|
public function __construct($apiKey, $apiSecret) {
|
||||||
|
parent::__construct($apiKey, $apiSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meeting Participants
|
||||||
|
*
|
||||||
|
* @param $meetingUUID
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function meetingParticipants(string $meetingUUID, array $query = []) {
|
||||||
|
return $this->get("report/meetings/{$meetingUUID}/participants", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
76
app/Libraries/Zoom/Endpoint/Users.php
Normal file
76
app/Libraries/Zoom/Endpoint/Users.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright https://github.com/UsabilityDynamics/zoom-api-php-client/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
namespace Zoom\Endpoint;
|
||||||
|
|
||||||
|
use Zoom\Interfaces\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Users
|
||||||
|
* @package Zoom\Interfaces
|
||||||
|
*/
|
||||||
|
class Users extends Request {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Users constructor.
|
||||||
|
* @param $apiKey
|
||||||
|
* @param $apiSecret
|
||||||
|
*/
|
||||||
|
public function __construct($apiKey, $apiSecret) {
|
||||||
|
parent::__construct($apiKey, $apiSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List
|
||||||
|
*
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function list( array $query = [] ) {
|
||||||
|
return $this->get( "users", $query );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create
|
||||||
|
*
|
||||||
|
* @param array|null $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function create( array $data = null ) {
|
||||||
|
return $this->post( "users", $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve
|
||||||
|
*
|
||||||
|
* @param $userID
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function retrieve( string $userID, array $query = [] ) {
|
||||||
|
return $this->get( "users/{$userID}", $query );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove
|
||||||
|
*
|
||||||
|
* @param $userId
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function remove( string $userId ) {
|
||||||
|
return $this->delete( "users/{$userId}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
*
|
||||||
|
* @param $userId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function update( string $userId, array $data = [] ) {
|
||||||
|
return $this->patch( "users/{$userId}", $data );
|
||||||
|
}
|
||||||
|
}
|
||||||
143
app/Libraries/Zoom/Endpoint/Webinars.php
Normal file
143
app/Libraries/Zoom/Endpoint/Webinars.php
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright https://github.com/UsabilityDynamics/zoom-api-php-client/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
namespace Zoom\Endpoint;
|
||||||
|
|
||||||
|
use Zoom\Interfaces\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Webinars
|
||||||
|
* @package Zoom\Endpoint
|
||||||
|
*/
|
||||||
|
class Webinars extends Request {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* webinars constructor.
|
||||||
|
* @param $apiKey
|
||||||
|
* @param $apiSecret
|
||||||
|
*/
|
||||||
|
public function __construct($apiKey, $apiSecret) {
|
||||||
|
parent::__construct($apiKey, $apiSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List
|
||||||
|
*
|
||||||
|
* @param $userId
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function list(string $userId, array $query = []) {
|
||||||
|
return $this->get("users/{$userId}/webinars", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create
|
||||||
|
*
|
||||||
|
* @param $userId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function create(string $userId, array $data = null) {
|
||||||
|
return $this->post("users/{$userId}/webinars", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meeting
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function meeting(string $meetingId) {
|
||||||
|
return $this->get("webinars/{$meetingId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function remove(string $meetingId) {
|
||||||
|
return $this->delete("webinars/{$meetingId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function update(string $meetingId, array $data = []) {
|
||||||
|
return $this->patch("webinars/{$meetingId}", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function status(string $meetingId, array $data = []) {
|
||||||
|
return $this->put("webinars/{$meetingId}/status", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Registrants
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function listRegistrants(string $meetingId, array $query = []) {
|
||||||
|
return $this->get("webinars/{$meetingId}/registrants", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Registrant
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function addRegistrant(string $meetingId, $data = []) {
|
||||||
|
return $this->post("webinars/{$meetingId}/registrants", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Registrant Status
|
||||||
|
*
|
||||||
|
* @param $meetingId
|
||||||
|
* @param array $data
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function updateRegistrantStatus(string $meetingId, array $data = []) {
|
||||||
|
return $this->put("webinars/{$meetingId}/registrants/status", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Past Meeting
|
||||||
|
*
|
||||||
|
* @param $meetingUUID
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function pastMeeting(string $meetingUUID) {
|
||||||
|
return $this->get("past_webinars/{$meetingUUID}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Past Meeting Participants
|
||||||
|
*
|
||||||
|
* @param $meetingUUID
|
||||||
|
* @param array $query
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function pastMeetingParticipants(string $meetingUUID, array $query = []) {
|
||||||
|
return $this->get("past_webinars/{$meetingUUID}/participants", $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user