init
This commit is contained in:
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);
|
||||
}
|
||||
|
||||
}
|
||||
199
app/Libraries/Zoom/Interfaces/Request.php
Normal file
199
app/Libraries/Zoom/Interfaces/Request.php
Normal file
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright https://github.com/UsabilityDynamics/zoom-api-php-client/blob/master/LICENSE
|
||||
*/
|
||||
namespace Zoom\Interfaces;
|
||||
|
||||
use Firebase\JWT\JWT;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
|
||||
class Request {
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $apiKey;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $apiSecret;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $apiPoint = 'https://api.zoom.us/v2/';
|
||||
|
||||
/**
|
||||
* Request constructor.
|
||||
* @param $apiKey
|
||||
* @param $apiSecret
|
||||
*/
|
||||
public function __construct( $apiKey, $apiSecret ) {
|
||||
$this->apiKey = $apiKey;
|
||||
|
||||
$this->apiSecret = $apiSecret;
|
||||
|
||||
$this->client = new Client();
|
||||
}
|
||||
|
||||
/**
|
||||
* Headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function headers(): array {
|
||||
return [
|
||||
'Authorization' => 'Bearer ' . $this->generateJWT(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate J W T
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateJWT() {
|
||||
$token = [
|
||||
'iss' => $this->apiKey,
|
||||
'exp' => time() + 60,
|
||||
];
|
||||
|
||||
return JWT::encode($token, $this->apiSecret,'HS256');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get
|
||||
*
|
||||
* @param $method
|
||||
* @param array $fields
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function get($method, $fields = []) {
|
||||
try {
|
||||
$response = $this->client->request('GET', $this->apiPoint . $method, [
|
||||
'query' => $fields,
|
||||
'headers' => $this->headers(),
|
||||
]);
|
||||
|
||||
return $this->result($response);
|
||||
|
||||
} catch (ClientException $e) {
|
||||
|
||||
return (array)json_decode($e->getResponse()->getBody()->getContents());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Post
|
||||
*
|
||||
* @param $method
|
||||
* @param $fields
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function post($method, $fields) {
|
||||
$body = \json_encode($fields, JSON_PRETTY_PRINT);
|
||||
|
||||
try {
|
||||
$response = $this->client->request('POST', $this->apiPoint . $method,
|
||||
['body' => $body, 'headers' => $this->headers()]);
|
||||
|
||||
return $this->result($response);
|
||||
|
||||
} catch (ClientException $e) {
|
||||
|
||||
return (array)json_decode($e->getResponse()->getBody()->getContents());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch
|
||||
*
|
||||
* @param $method
|
||||
* @param $fields
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function patch($method, $fields) {
|
||||
$body = \json_encode($fields, JSON_PRETTY_PRINT);
|
||||
|
||||
try {
|
||||
$response = $this->client->request('PATCH', $this->apiPoint . $method,
|
||||
['body' => $body, 'headers' => $this->headers()]);
|
||||
|
||||
return $this->result($response);
|
||||
|
||||
} catch (ClientException $e) {
|
||||
|
||||
return (array)json_decode($e->getResponse()->getBody()->getContents());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put
|
||||
*
|
||||
* @param $method
|
||||
* @param $fields
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function put($method, $fields) {
|
||||
$body = \json_encode($fields, JSON_PRETTY_PRINT);
|
||||
|
||||
try {
|
||||
$response = $this->client->request('PUT', $this->apiPoint . $method,
|
||||
['body' => $body, 'headers' => $this->headers()]);
|
||||
|
||||
return $this->result($response);
|
||||
|
||||
} catch (ClientException $e) {
|
||||
|
||||
return (array)json_decode($e->getResponse()->getBody()->getContents());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @param $method
|
||||
* @param $fields
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function delete($method, $fields = []) {
|
||||
$body = \json_encode($fields, JSON_PRETTY_PRINT);
|
||||
|
||||
try {
|
||||
$response = $this->client->request('DELETE', $this->apiPoint . $method,
|
||||
['body' => $body, 'headers' => $this->headers()]);
|
||||
|
||||
return $this->result($response);
|
||||
|
||||
} catch (ClientException $e) {
|
||||
|
||||
return (array)json_decode($e->getResponse()->getBody()->getContents());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Result
|
||||
*
|
||||
* @param Response $response
|
||||
* @return mixed
|
||||
*/
|
||||
protected function result(Response $response) {
|
||||
$result = json_decode((string)$response->getBody(), true);
|
||||
|
||||
$result['code'] = $response->getStatusCode();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
21
app/Libraries/Zoom/LICENSE
Normal file
21
app/Libraries/Zoom/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Zoom Video Communications
|
||||
|
||||
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.
|
||||
7
app/Libraries/Zoom/README.md
Normal file
7
app/Libraries/Zoom/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# PHP
|
||||
|
||||
Zoom REST API's using PHP
|
||||
Visit https://zoom.us/developer for more details
|
||||
|
||||
## Support
|
||||
For any questions or issues, please visit our new Community Support Forum at https://devforum.zoom.us/
|
||||
119
app/Libraries/Zoom/ZoomAPI.php
Normal file
119
app/Libraries/Zoom/ZoomAPI.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace Zoom;
|
||||
|
||||
use Zoom\Endpoint\Users;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class ZoomAPI
|
||||
{
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $apiKey = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $apiSecret = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $users = null;
|
||||
|
||||
protected string $accessToken;
|
||||
protected $client;
|
||||
/**
|
||||
* Retorna uma instância única de uma classe.
|
||||
*
|
||||
* @staticvar Singleton $instance A instância única dessa classe.
|
||||
*
|
||||
* @return Singleton A Instância única.
|
||||
*/
|
||||
public function getInstance()
|
||||
{
|
||||
static $users = null;
|
||||
if (null === $users) {
|
||||
$this->users = new Users($this->apiKey, $this->apiSecret);
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom constructor.
|
||||
* @param $apiKey
|
||||
* @param $apiSecret
|
||||
*/
|
||||
public function __construct($apiKey, $apiSecret, $account_id)
|
||||
{
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
|
||||
$this->apiSecret = $apiSecret;
|
||||
|
||||
$client = new Client([
|
||||
'headers' => [
|
||||
'Authorization' => 'Basic ' . base64_encode($this->apiKey . ':' . $this->apiSecret),
|
||||
'Host' => 'zoom.us',
|
||||
],
|
||||
]);
|
||||
$response = $client->request('POST', "https://zoom.us/oauth/token", [
|
||||
'form_params' => [
|
||||
'grant_type' => 'account_credentials',
|
||||
'account_id' => $account_id,
|
||||
],
|
||||
]);
|
||||
$responseBody = json_decode($response->getBody(), true);
|
||||
// print_r($responseBody);
|
||||
// die;
|
||||
$this->accessToken = $responseBody['access_token'];
|
||||
// return $responseBody['access_token'];
|
||||
}
|
||||
public function createMeeting($data)
|
||||
{
|
||||
$now = date("Y-m-d\TH:i", strtotime(date('Y-m-d H:i:s', time())));
|
||||
$postFields = [
|
||||
'topic' => $data['title'],
|
||||
'type' => 2, // Scheduled meeting
|
||||
'start_time' => $now, // Meeting start time in ISO 8601 format
|
||||
'duration' => 60 * 12, // Meeting duration in minutes
|
||||
'timezone' => 'UTC+07',
|
||||
'agenda' => $data['description']
|
||||
];
|
||||
$this->client = new Client([
|
||||
'base_uri' => 'https://api.zoom.us/v2/',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $this->accessToken,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]);
|
||||
try {
|
||||
$response = $this->client->request('POST', 'users/me/meetings', [
|
||||
'json' => $postFields,
|
||||
]);
|
||||
$res = json_decode($response->getBody(), true);
|
||||
return [
|
||||
'status' => true,
|
||||
'data' => $res,
|
||||
];
|
||||
} catch (\Throwable $th) {
|
||||
return [
|
||||
'status' => false,
|
||||
'message' => $th->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
/*Functions for management of users*/
|
||||
|
||||
// public function createUser()
|
||||
// {
|
||||
// $createAUserArray['action'] = 'create';
|
||||
// $createAUserArray['email'] = $_POST['email'];
|
||||
// $createAUserArray['user_info'] = $_POST['user_info'];
|
||||
|
||||
// return $this->users->create($createAUserArray);
|
||||
// }
|
||||
}
|
||||
13
app/Libraries/Zoom/composer.json
Normal file
13
app/Libraries/Zoom/composer.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "zoom/zoom",
|
||||
"description": "Api Zoom",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^7.8",
|
||||
"firebase/php-jwt": "^6.9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {"Zoom\\": ""}
|
||||
}
|
||||
}
|
||||
8
app/Libraries/Zoom/index.php
Normal file
8
app/Libraries/Zoom/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$zoom = new \Zoom\ZoomAPI('AAAAA', 'BBBBB');
|
||||
|
||||
|
||||
var_dump($zoom->createUser() );
|
||||
exit();
|
||||
Reference in New Issue
Block a user