Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
de85d30a9e | |||
82904b9302 | |||
face1dfa57 | |||
7e5a718ba8 | |||
c2fffdab88 | |||
9578006e11 | |||
828ad7f880 | |||
ed4bd4861a | |||
b64e841bde | |||
efdb0fc6bc | |||
0b5c24239d | |||
a5971bfff3 | |||
aac8306d7b | |||
721ef32e12 | |||
67e383375e | |||
4434e7d217 | |||
fc6cd59ea0 | |||
608c9e5b6f | |||
d494df3321 | |||
9ec0148800 | |||
deb6cceeb9 | |||
210178be84 | |||
063ae834bc | |||
4c65248823 | |||
c417fe63e2 | |||
6ca5054fe8 | |||
0bcac10eec | |||
ada529ce97 | |||
8e55330bcb | |||
eca40e0faf | |||
8e1d608e5f | |||
50b4db1723 | |||
b3e97ecf6d | |||
a85e9ee95a | |||
fa154b007f | |||
3b9c5d16f8 | |||
dd7f9dc94e | |||
2a9b50e015 | |||
1c0ff671a5 | |||
bd48bb0591 | |||
278def959b | |||
5a47da013b | |||
282bf6190c | |||
2f1ee0cfbf | |||
5783ea05f9 | |||
5ca81ea92e | |||
6496f49df6 | |||
7d3afa091f | |||
cc68770f51 |
@ -2,6 +2,11 @@
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## 2024.8.1
|
||||
|
||||
- Show Bandwidth Plan in the customer dashboard
|
||||
- Show
|
||||
|
||||
## 2024.7.23
|
||||
|
||||
- add Voucher Used Date
|
||||
|
@ -1,16 +1,18 @@
|
||||
<?php
|
||||
$db_host = "localhost"; # Database Host
|
||||
$db_port = ""; # Database Port. Keep it blank if you are un sure.
|
||||
$db_user = "root"; # Database Username
|
||||
$db_password = ""; # Database Password
|
||||
$db_name = "phpnuxbill"; # Database Name
|
||||
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$baseDir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
|
||||
define('APP_URL', $protocol . $host . $baseDir);
|
||||
#Please include http and do not use trailing slash after the url. For example use in this format- http://www.example.com Or http://www.example.com/finance
|
||||
|
||||
$_app_stage = 'Live'; # Do not change this
|
||||
|
||||
$db_host = "localhost"; # Database Host
|
||||
$db_port = ""; # Database Port. Keep it blank if you are un sure.
|
||||
$db_user = "root"; # Database Username
|
||||
$db_pass = ""; # Database Password
|
||||
$db_name = "phpnuxbill"; # Database Name
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
8
init.php
8
init.php
@ -67,10 +67,14 @@ require_once $root_path . File::pathFixer('system/orm.php');
|
||||
require_once $root_path . File::pathFixer('system/autoload/PEAR2/Autoload.php');
|
||||
include $root_path . File::pathFixer('system/autoload/Hookers.php');
|
||||
|
||||
if(!empty($db_password)){
|
||||
if($db_password != null && ($db_pass == null || empty($db_pass))){
|
||||
// compability for old version
|
||||
$db_pass = $db_password;
|
||||
}
|
||||
if($db_pass != null){
|
||||
// compability for old version
|
||||
$db_password = $db_pass;
|
||||
}
|
||||
ORM::configure("mysql:host=$db_host;dbname=$db_name");
|
||||
ORM::configure('username', $db_user);
|
||||
ORM::configure('password', $db_pass);
|
||||
@ -329,7 +333,7 @@ function _alert($text, $type = 'success', $url = "home", $time = 3)
|
||||
|
||||
|
||||
if (!isset($api_secret)) {
|
||||
$api_secret = $db_password;
|
||||
$api_secret = $db_pass;
|
||||
}
|
||||
|
||||
function displayMaintenanceMessage(): void
|
||||
|
@ -70,13 +70,13 @@ CREATE TABLE `tbl_payment_gateway` (
|
||||
`id` int NOT NULL,
|
||||
`username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`gateway` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'xendit | midtrans',
|
||||
`gateway_trx_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`gateway_trx_id` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`plan_id` int NOT NULL,
|
||||
`plan_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`routers_id` int NOT NULL,
|
||||
`routers` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`price` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`pg_url_payment` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`pg_url_payment` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`payment_method` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`payment_channel` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`pg_request` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
|
||||
|
@ -42,20 +42,20 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="dbhost">Database Host</label>
|
||||
<input type="text" class="form-control" id="dbhost" name="dbhost">
|
||||
<input type="text" class="form-control" id="dbhost" required name="dbhost">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="dbuser">Database Username</label>
|
||||
<input type="text" class="form-control" id="dbuser" name="dbuser">
|
||||
<input type="text" class="form-control" id="dbuser" required name="dbuser">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="dbpass">Database Password</label>
|
||||
<input type="text" class="form-control" id="dbpass" name="dbpass">
|
||||
<input type="text" class="form-control" id="dbpass" required name="dbpass">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="dbname">Database Name</label>
|
||||
<input type="text" class="form-control" id="dbname" name="dbname">
|
||||
<input type="text" class="form-control" id="dbname" required name="dbname">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -9,14 +9,14 @@
|
||||
$appurl = $_POST['appurl'];
|
||||
$db_host = $_POST['dbhost'];
|
||||
$db_user = $_POST['dbuser'];
|
||||
$db_password = $_POST['dbpass'];
|
||||
$db_pass = $_POST['dbpass'];
|
||||
$db_name = $_POST['dbname'];
|
||||
$cn = '0';
|
||||
try {
|
||||
$dbh = new pdo(
|
||||
"mysql:host=$db_host;dbname=$db_name",
|
||||
"$db_user",
|
||||
"$db_password",
|
||||
"$db_pass",
|
||||
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
);
|
||||
$cn = '1';
|
||||
@ -39,13 +39,13 @@ $_app_stage = "Live";
|
||||
// Database PHPNuxBill
|
||||
$db_host = "' . $db_host . '";
|
||||
$db_user = "' . $db_user . '";
|
||||
$db_pass = "' . $db_password . '";
|
||||
$db_pass = "' . $db_pass . '";
|
||||
$db_name = "' . $db_name . '";
|
||||
|
||||
// Database Radius
|
||||
$radius_host = "' . $db_host . '";
|
||||
$radius_user = "' . $db_user . '";
|
||||
$radius_pass = "' . $db_password . '";
|
||||
$radius_pass = "' . $db_pass . '";
|
||||
$radius_name = "' . $db_name . '";
|
||||
|
||||
if($_app_stage!="Live"){
|
||||
@ -70,7 +70,7 @@ $_app_stage = "Live";
|
||||
// Database PHPNuxBill
|
||||
$db_host = "' . $db_host . '";
|
||||
$db_user = "' . $db_user . '";
|
||||
$db_pass = "' . $db_password . '";
|
||||
$db_pass = "' . $db_pass . '";
|
||||
$db_name = "' . $db_name . '";
|
||||
|
||||
if($_app_stage!="Live"){
|
||||
|
@ -26,7 +26,7 @@
|
||||
try{
|
||||
$dbh = new pdo( "mysql:host=$db_host;dbname=$db_name",
|
||||
"$db_user",
|
||||
"$db_password",
|
||||
"$db_pass",
|
||||
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
|
||||
|
||||
echo "CREATE TABLE `tbl_payment_gateway` (
|
||||
|
@ -11,35 +11,64 @@ class Admin
|
||||
|
||||
public static function getID()
|
||||
{
|
||||
global $db_password;
|
||||
if (isset($_SESSION['aid'])) {
|
||||
global $db_pass, $config;
|
||||
$enable_session_timeout = $config['enable_session_timeout'];
|
||||
if ($enable_session_timeout) {
|
||||
$timeout = 60;
|
||||
if ($config['session_timeout_duration']) {
|
||||
$timeout = intval($config['session_timeout_duration']);
|
||||
}
|
||||
$session_timeout_duration = $timeout * 60; // Convert minutes to seconds
|
||||
}
|
||||
|
||||
if (isset($_SESSION['aid']) && isset($_SESSION['aid_expiration']) && $_SESSION['aid_expiration'] > time()) {
|
||||
return $_SESSION['aid'];
|
||||
} else if (isset($_COOKIE['aid'])) {
|
||||
} elseif ($enable_session_timeout && isset($_SESSION['aid']) && isset($_SESSION['aid_expiration']) && $_SESSION['aid_expiration'] <= time()) {
|
||||
self::removeCookie();
|
||||
session_destroy();
|
||||
_alert(Lang::T('Session has expired. Please log in again.'), 'danger', "admin");
|
||||
return 0;
|
||||
}
|
||||
// Check if cookie is set and valid
|
||||
elseif (isset($_COOKIE['aid'])) {
|
||||
// id.time.sha1
|
||||
$tmp = explode('.', $_COOKIE['aid']);
|
||||
if (sha1($tmp[0] . '.' . $tmp[1] . '.' . $db_password) == $tmp[2]) {
|
||||
if (sha1($tmp[0] . '.' . $tmp[1] . '.' . $db_pass) == $tmp[2]) {
|
||||
if (time() - $tmp[1] < 86400 * 7) {
|
||||
$_SESSION['aid'] = $tmp[0];
|
||||
if ($enable_session_timeout) {
|
||||
$_SESSION['aid_expiration'] = time() + $session_timeout_duration;
|
||||
}
|
||||
return $tmp[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function setCookie($aid)
|
||||
{
|
||||
global $db_password;
|
||||
global $db_pass, $config;
|
||||
$enable_session_timeout = $config['enable_session_timeout'];
|
||||
if (isset($aid)) {
|
||||
$time = time();
|
||||
$token = $aid . '.' . $time . '.' . sha1($aid . '.' . $time . '.' . $db_password);
|
||||
$token = $aid . '.' . $time . '.' . sha1($aid . '.' . $time . '.' . $db_pass);
|
||||
setcookie('aid', $token, time() + 86400 * 7);
|
||||
$_SESSION['aid'] = $aid;
|
||||
if ($enable_session_timeout) {
|
||||
$timeout = 60;
|
||||
if ($config['session_timeout_duration']) {
|
||||
$timeout = intval($config['session_timeout_duration']);
|
||||
}
|
||||
$session_timeout_duration = $timeout * 60; // Convert minutes to seconds
|
||||
$_SESSION['aid_expiration'] = $time + $session_timeout_duration;
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public static function removeCookie()
|
||||
{
|
||||
if (isset($_COOKIE['aid'])) {
|
||||
|
@ -11,7 +11,7 @@ class Lang
|
||||
public static function T($key)
|
||||
{
|
||||
global $_L, $lan_file, $config;
|
||||
if(is_array($_SESSION['Lang'])){
|
||||
if (is_array($_SESSION['Lang'])) {
|
||||
$_L = array_merge($_L, $_SESSION['Lang']);
|
||||
}
|
||||
$key = preg_replace('/\s+/', ' ', $key);
|
||||
@ -124,20 +124,20 @@ class Lang
|
||||
}
|
||||
}
|
||||
$when = "";
|
||||
if(time()>strtotime($datetime)){
|
||||
if (time() > strtotime($datetime)) {
|
||||
$when = Lang::T('ago');
|
||||
}else{
|
||||
} else {
|
||||
$when = '';
|
||||
}
|
||||
if (!$full)
|
||||
$string = array_slice($string, 0, 1);
|
||||
if($string){
|
||||
if(empty($when)){
|
||||
return '<b>'. implode(', ', $string) .'</b>';
|
||||
}else{
|
||||
return implode(', ', $string) .' '. $when;
|
||||
if ($string) {
|
||||
if (empty($when)) {
|
||||
return '<b>' . implode(', ', $string) . '</b>';
|
||||
} else {
|
||||
return implode(', ', $string) . ' ' . $when;
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
return Lang::T('just now');
|
||||
}
|
||||
}
|
||||
@ -245,16 +245,30 @@ class Lang
|
||||
return $txt;
|
||||
}
|
||||
|
||||
public static function maskText($text){
|
||||
public static function maskText($text)
|
||||
{
|
||||
$len = strlen($text);
|
||||
if($len < 3){
|
||||
if ($len < 3) {
|
||||
return "***";
|
||||
}else if($len<5){
|
||||
return substr($text,0,1)."***".substr($text,-1,1);
|
||||
}else if($len<8){
|
||||
return substr($text,0,2)."***".substr($text,-2,2);
|
||||
}else{
|
||||
return substr($text,0,4)."******".substr($text,-3,3);
|
||||
} else if ($len < 5) {
|
||||
return substr($text, 0, 1) . "***" . substr($text, -1, 1);
|
||||
} else if ($len < 8) {
|
||||
return substr($text, 0, 2) . "***" . substr($text, -2, 2);
|
||||
} else {
|
||||
return substr($text, 0, 4) . "******" . substr($text, -3, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// echo Json array to text
|
||||
public static function jsonArray2text($array, $start = '', $result = '')
|
||||
{
|
||||
foreach ($array as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$result .= self::jsonArray2text($v, "$start$k.", '');
|
||||
} else {
|
||||
$result .= "$start$k = " . strval($v) . "\n";
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class Package
|
||||
*/
|
||||
public static function rechargeUser($id_customer, $router_name, $plan_id, $gateway, $channel, $note = '')
|
||||
{
|
||||
global $config, $admin, $c, $p, $b, $t, $d, $zero, $trx, $_app_stage;
|
||||
global $config, $admin, $c, $p, $b, $t, $d, $zero, $trx, $_app_stage, $isChangePlan;
|
||||
$date_now = date("Y-m-d H:i:s");
|
||||
$date_only = date("Y-m-d");
|
||||
$time_only = date("H:i:s");
|
||||
@ -29,21 +29,26 @@ class Package
|
||||
$isVoucher = false;
|
||||
$c = [];
|
||||
|
||||
if ($trx && $trx['status'] == 2) {
|
||||
// if its already paid, return it
|
||||
return;
|
||||
}
|
||||
|
||||
if ($id_customer == '' or $router_name == '' or $plan_id == '') {
|
||||
return false;
|
||||
}
|
||||
if(trim($gateway) == 'Voucher' && $id_customer == 0){
|
||||
if (trim($gateway) == 'Voucher' && $id_customer == 0) {
|
||||
$isVoucher = true;
|
||||
}
|
||||
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $plan_id)->find_one();
|
||||
|
||||
if(!$isVoucher){
|
||||
if (!$isVoucher) {
|
||||
$c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
|
||||
if ($c['status'] != 'Active') {
|
||||
_alert(Lang::T('This account status') . ' : ' . Lang::T($c['status']), 'danger', "");
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
$c = [
|
||||
'fullname' => $gateway,
|
||||
'email' => '',
|
||||
@ -82,7 +87,7 @@ class Package
|
||||
// if customer has attribute Expired Date use it
|
||||
$day_exp = User::getAttribute("Expired Date", $c['id']);
|
||||
if (!$day_exp) {
|
||||
// if customer no attribute Expired Date use plan expired date
|
||||
// if customer no attribute Expired Date use plan expired date
|
||||
$day_exp = 20;
|
||||
if ($p['prepaid'] == 'no') {
|
||||
$day_exp = $p['expired_date'];
|
||||
@ -142,6 +147,8 @@ class Package
|
||||
Message::sendSMS($c['phonenumber'], $textInvoice);
|
||||
} else if ($config['user_notification_payment'] == 'wa') {
|
||||
Message::sendWhatsapp($c['phonenumber'], $textInvoice);
|
||||
} else if ($config['user_notification_payment'] == 'email') {
|
||||
Message::sendEmail($c['email'], '[' . $config['CompanyName'] . '] ' . Lang::T("Invoice") . ' ' . $inv ,$textInvoice);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -173,9 +180,9 @@ class Package
|
||||
# because 1 customer can have 1 PPPOE and 1 Hotspot Plan in mikrotik
|
||||
//->where('prepaid', $p['prepaid'])
|
||||
->left_outer_join('tbl_plans', array('tbl_plans.id', '=', 'tbl_user_recharges.plan_id'));
|
||||
if($isVoucher){
|
||||
if ($isVoucher) {
|
||||
$query->where('username', $c['username']);
|
||||
}else{
|
||||
} else {
|
||||
$query->where('customer_id', $id_customer);
|
||||
}
|
||||
$b = $query->find_one();
|
||||
@ -209,13 +216,10 @@ class Package
|
||||
$date_exp = $datetime[0];
|
||||
$time = $datetime[1];
|
||||
}
|
||||
$isChangePlan = false;
|
||||
|
||||
if ($b) {
|
||||
// plan exists
|
||||
if ($plan_id != $b['plan_id']) {
|
||||
$isChangePlan = true;
|
||||
}
|
||||
$lastExpired = Lang::dateAndTimeFormat($b['expiration'], $b['time']);
|
||||
$isChangePlan = false;
|
||||
if ($config['extend_expiry'] != 'no') {
|
||||
if ($b['namebp'] == $p['name_plan'] && $b['status'] == 'on') {
|
||||
// if it same internet plan, expired will extend
|
||||
@ -237,20 +241,42 @@ class Package
|
||||
$date_exp = $datetime[0];
|
||||
$time = $datetime[1];
|
||||
}
|
||||
} else {
|
||||
$isChangePlan = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isChangePlan || $b['status'] == 'off') {
|
||||
$dvc = Package::getDevice($p);
|
||||
if ($_app_stage != 'demo') {
|
||||
//if ($b['status'] == 'on') {
|
||||
$dvc = Package::getDevice($p);
|
||||
if ($_app_stage != 'demo') {
|
||||
try {
|
||||
if (file_exists($dvc)) {
|
||||
require_once $dvc;
|
||||
(new $p['device'])->add_customer($c, $p);
|
||||
} else {
|
||||
new Exception(Lang::T("Devices Not Found"));
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
Message::sendTelegram(
|
||||
"Sistem Error. When activate Package. You need to sync manually\n" .
|
||||
"Router: $router_name\n" .
|
||||
"Customer: u$c[username]\n" .
|
||||
"Plan: p$p[name_plan]\n" .
|
||||
$e->getMessage() . "\n" .
|
||||
$e->getTraceAsString()
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
Message::sendTelegram(
|
||||
"Sistem Error. When activate Package. You need to sync manually\n" .
|
||||
"Router: $router_name\n" .
|
||||
"Customer: u$c[username]\n" .
|
||||
"Plan: p$p[name_plan]\n" .
|
||||
$e->getMessage() . "\n" .
|
||||
$e->getTraceAsString()
|
||||
);
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
$b->customer_id = $id_customer;
|
||||
$b->username = $c['username'];
|
||||
@ -322,17 +348,39 @@ class Package
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nLast Expired: $lastExpired" .
|
||||
"\nNew Expired: " . Lang::dateAndTimeFormat($date_exp, $time).
|
||||
"\nPrice: " . Lang::moneyFormat($p['price'] + $add_cost) .
|
||||
"\nNote:\n" . $note);
|
||||
} else {
|
||||
// active plan not exists
|
||||
$dvc = Package::getDevice($p);
|
||||
if ($_app_stage != 'demo') {
|
||||
if (file_exists($dvc)) {
|
||||
require_once $dvc;
|
||||
(new $p['device'])->add_customer($c, $p);
|
||||
} else {
|
||||
new Exception(Lang::T("Devices Not Found"));
|
||||
try {
|
||||
if (file_exists($dvc)) {
|
||||
require_once $dvc;
|
||||
(new $p['device'])->add_customer($c, $p);
|
||||
} else {
|
||||
new Exception(Lang::T("Devices Not Found"));
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
Message::sendTelegram(
|
||||
"Sistem Error. When activate Package. You need to sync manually\n" .
|
||||
"Router: $router_name\n" .
|
||||
"Customer: u$c[username]\n" .
|
||||
"Plan: p$p[name_plan]\n" .
|
||||
$e->getMessage() . "\n" .
|
||||
$e->getTraceAsString()
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
Message::sendTelegram(
|
||||
"Sistem Error. When activate Package. You need to sync manually\n" .
|
||||
"Router: $router_name\n" .
|
||||
"Customer: u$c[username]\n" .
|
||||
"Plan: p$p[name_plan]\n" .
|
||||
$e->getMessage() . "\n" .
|
||||
$e->getTraceAsString()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,6 +462,7 @@ class Package
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nExpired: " . Lang::dateAndTimeFormat($date_exp, $time).
|
||||
"\nPrice: " . Lang::moneyFormat($p['price'] + $add_cost) .
|
||||
"\nNote:\n" . $note);
|
||||
}
|
||||
@ -558,10 +607,10 @@ class Package
|
||||
public static function getDevice($plan)
|
||||
{
|
||||
global $DEVICE_PATH;
|
||||
if($plan === false){
|
||||
if ($plan === false) {
|
||||
return "none";
|
||||
}
|
||||
if(!isset($plan['device'])){
|
||||
if (!isset($plan['device'])) {
|
||||
return "none";
|
||||
}
|
||||
if (!empty($plan['device'])) {
|
||||
|
@ -10,13 +10,13 @@ class User
|
||||
{
|
||||
public static function getID()
|
||||
{
|
||||
global $db_password;
|
||||
global $db_pass;
|
||||
if (isset($_SESSION['uid']) && !empty($_SESSION['uid'])) {
|
||||
return $_SESSION['uid'];
|
||||
} else if (isset($_COOKIE['uid'])) {
|
||||
// id.time.sha1
|
||||
$tmp = explode('.', $_COOKIE['uid']);
|
||||
if (sha1($tmp[0] . '.' . $tmp[1] . '.' . $db_password) == $tmp[2]) {
|
||||
if (sha1($tmp[0] . '.' . $tmp[1] . '.' . $db_pass) == $tmp[2]) {
|
||||
if (time() - $tmp[1] < 86400 * 30) {
|
||||
$_SESSION['uid'] = $tmp[0];
|
||||
return $tmp[0];
|
||||
@ -159,10 +159,10 @@ class User
|
||||
|
||||
public static function setCookie($uid)
|
||||
{
|
||||
global $db_password;
|
||||
global $db_pass;
|
||||
if (isset($uid)) {
|
||||
$time = time();
|
||||
setcookie('uid', $uid . '.' . $time . '.' . sha1($uid . '.' . $time . '.' . $db_password), time() + 86400 * 30);
|
||||
setcookie('uid', $uid . '.' . $time . '.' . sha1($uid . '.' . $time . '.' . $db_pass), time() + 86400 * 30);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,13 +205,14 @@ class User
|
||||
->select('tbl_user_recharges.id', 'id')
|
||||
->selects([
|
||||
'customer_id', 'username', 'plan_id', 'namebp', 'recharged_on', 'recharged_time', 'expiration', 'time',
|
||||
'status', 'method', 'plan_type',
|
||||
'status', 'method', 'plan_type', 'name_bw',
|
||||
['tbl_user_recharges.routers', 'routers'],
|
||||
['tbl_user_recharges.type', 'type'],
|
||||
'admin_id', 'prepaid'
|
||||
])
|
||||
->where('customer_id', $id)
|
||||
->left_outer_join('tbl_plans', array('tbl_plans.id', '=', 'tbl_user_recharges.plan_id'))
|
||||
->left_outer_join('tbl_bandwidth', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))
|
||||
->find_many();
|
||||
return $d;
|
||||
}
|
||||
|
@ -149,8 +149,8 @@ switch ($action) {
|
||||
mkdir($otpPath);
|
||||
touch($otpPath . 'index.html');
|
||||
}
|
||||
$otpFile = $otpPath . sha1($username . $db_password) . ".txt";
|
||||
$phoneFile = $otpPath . sha1($username . $db_password) . "_phone.txt";
|
||||
$otpFile = $otpPath . sha1($username . $db_pass) . ".txt";
|
||||
$phoneFile = $otpPath . sha1($username . $db_pass) . "_phone.txt";
|
||||
|
||||
// expired 10 minutes
|
||||
if (file_exists($otpFile) && time() - filemtime($otpFile) < 1200) {
|
||||
@ -189,8 +189,8 @@ switch ($action) {
|
||||
}
|
||||
|
||||
if (!empty($config['sms_url'])) {
|
||||
$otpFile = $otpPath . sha1($username . $db_password) . ".txt";
|
||||
$phoneFile = $otpPath . sha1($username . $db_password) . "_phone.txt";
|
||||
$otpFile = $otpPath . sha1($username . $db_pass) . ".txt";
|
||||
$phoneFile = $otpPath . sha1($username . $db_pass) . "_phone.txt";
|
||||
|
||||
// Check if OTP file exists
|
||||
if (!file_exists($otpFile)) {
|
||||
|
@ -21,21 +21,26 @@ switch ($action) {
|
||||
$p = ORM::for_table('tbl_plans')->find_one($bill['plan_id']);
|
||||
$dvc = Package::getDevice($p);
|
||||
if ($_app_stage != 'demo') {
|
||||
if (file_exists($dvc)) {
|
||||
require_once $dvc;
|
||||
if ((new $p['device'])->online_customer($user, $bill['routers'])) {
|
||||
die('<a href="' . U . 'home&mikrotik=logout&id=' . $bill['id'] . '" onclick="return confirm(\'' . Lang::T('Disconnect Internet?') . '\')" class="btn btn-success btn-xs btn-block">' . Lang::T('You are Online, Logout?') . '</a>');
|
||||
} else {
|
||||
if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'])) {
|
||||
die('<a href="' . U . 'home&mikrotik=login&id=' . $bill['id'] . '" onclick="return confirm(\'' . Lang::T('Connect to Internet?') . '\')" class="btn btn-danger btn-xs btn-block">' . Lang::T('Not Online, Login now?') . '</a>');
|
||||
try{
|
||||
if (file_exists($dvc)) {
|
||||
require_once $dvc;
|
||||
if ((new $p['device'])->online_customer($user, $bill['routers'])) {
|
||||
die('<a href="' . U . 'home&mikrotik=logout&id=' . $bill['id'] . '" onclick="return confirm(\'' . Lang::T('Disconnect Internet?') . '\')" class="btn btn-success btn-xs btn-block">' . Lang::T('You are Online, Logout?') . '</a>');
|
||||
} else {
|
||||
die(Lang::T('-'));
|
||||
if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'])) {
|
||||
die('<a href="' . U . 'home&mikrotik=login&id=' . $bill['id'] . '" onclick="return confirm(\'' . Lang::T('Connect to Internet?') . '\')" class="btn btn-danger btn-xs btn-block">' . Lang::T('Not Online, Login now?') . '</a>');
|
||||
} else {
|
||||
die(Lang::T('-'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die(Lang::T('-'));
|
||||
}
|
||||
} else {
|
||||
new Exception(Lang::T("Devices Not Found"));
|
||||
}catch (Exception $e) {
|
||||
die(Lang::T('Failed to connect to device'));
|
||||
}
|
||||
}
|
||||
die(Lang::T('-'));
|
||||
} else {
|
||||
die('--');
|
||||
}
|
||||
|
@ -432,6 +432,47 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send welcome message
|
||||
if (isset($_POST['send_welcome_message']) && $_POST['send_welcome_message'] == true) {
|
||||
$welcomeMessage = Lang::getNotifText('welcome_message');
|
||||
$welcomeMessage = str_replace('[[company_name]]', $config['CompanyName'], $welcomeMessage);
|
||||
$welcomeMessage = str_replace('[[name]]', $d['fullname'], $welcomeMessage);
|
||||
$welcomeMessage = str_replace('[[username]]', $d['username'], $welcomeMessage);
|
||||
$welcomeMessage = str_replace('[[password]]', $d['password'], $welcomeMessage);
|
||||
$welcomeMessage = str_replace('[[url]]', APP_URL . '/index.php?_route=login', $welcomeMessage);
|
||||
|
||||
$emailSubject = "Welcome to " . $config['CompanyName'];
|
||||
|
||||
$channels = [
|
||||
'sms' => [
|
||||
'enabled' => isset($_POST['sms']),
|
||||
'method' => 'sendSMS',
|
||||
'args' => [$d['phonenumber'], $welcomeMessage]
|
||||
],
|
||||
'whatsapp' => [
|
||||
'enabled' => isset($_POST['wa']) && $_POST['wa'] == 'wa',
|
||||
'method' => 'sendWhatsapp',
|
||||
'args' => [$d['phonenumber'], $welcomeMessage]
|
||||
],
|
||||
'email' => [
|
||||
'enabled' => isset($_POST['email']),
|
||||
'method' => 'Message::sendEmail',
|
||||
'args' => [$d['email'], $emailSubject, $welcomeMessage, $d['email']]
|
||||
]
|
||||
];
|
||||
|
||||
foreach ($channels as $channel => $message) {
|
||||
if ($message['enabled']) {
|
||||
try {
|
||||
call_user_func_array($message['method'], $message['args']);
|
||||
} catch (Exception $e) {
|
||||
// Log the error and handle the failure
|
||||
_log("Failed to send welcome message via $channel: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r2(U . 'customers/list', 's', Lang::T('Account Created Successfully'));
|
||||
} else {
|
||||
r2(U . 'customers/add', 'e', $msg);
|
||||
|
@ -55,6 +55,11 @@ if ($imonth == '') {
|
||||
}
|
||||
$ui->assign('imonth', $imonth);
|
||||
|
||||
if ($config['enable_balance'] == 'yes'){
|
||||
$cb = ORM::for_table('tbl_customers')->whereGte('balance', 0)->sum('balance');
|
||||
$ui->assign('cb', $cb);
|
||||
}
|
||||
|
||||
$u_act = ORM::for_table('tbl_user_recharges')->where('status', 'on')->count();
|
||||
if (empty($u_act)) {
|
||||
$u_act = '0';
|
||||
|
@ -94,8 +94,37 @@ if (_post('send') == 'balance') {
|
||||
}
|
||||
r2(U . 'home', 'w', Lang::T('Your friend do not have active package'));
|
||||
}
|
||||
$_bill = User::_billing();
|
||||
$ui->assign('_bills', $_bill);
|
||||
|
||||
$ui->assign('_bills', User::_billing());
|
||||
// Sync plan to router
|
||||
if (isset($_GET['sync']) && !empty($_GET['sync'])) {
|
||||
foreach ($_bill as $tur) {
|
||||
if($tur['status'] == 'on'){
|
||||
$p = ORM::for_table('tbl_plans')->findOne($tur['plan_id']);
|
||||
if ($p) {
|
||||
$c = ORM::for_table('tbl_customers')->findOne($tur['customer_id']);
|
||||
if ($c) {
|
||||
$dvc = Package::getDevice($p);
|
||||
if ($_app_stage != 'demo') {
|
||||
if (file_exists($dvc)) {
|
||||
require_once $dvc;
|
||||
(new $p['device'])->add_customer($c, $p);
|
||||
} else {
|
||||
new Exception(Lang::T("Devices Not Found"));
|
||||
}
|
||||
}
|
||||
$log .= "DONE : $ptur[namebp], $tur[type], $tur[routers]<br>";
|
||||
} else {
|
||||
$log .= "Customer NOT FOUND : $tur[namebp], $tur[type], $tur[routers]<br>";
|
||||
}
|
||||
} else {
|
||||
$log .= "PLAN NOT FOUND : $tur[namebp], $tur[type], $tur[routers]<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
r2(U . 'home', 's', $log);
|
||||
}
|
||||
|
||||
if (isset($_GET['recharge']) && !empty($_GET['recharge'])) {
|
||||
if ($user['status'] != 'Active') {
|
||||
|
@ -103,7 +103,7 @@ switch ($action) {
|
||||
r2(U . "order/package", 'w', Lang::T("Payment not found"));
|
||||
}
|
||||
// jika url kosong, balikin ke buy, kecuali cancel
|
||||
if (empty($trx['pg_url_payment']) && $routes['3'] != 'cancel') {
|
||||
if ($trx['status'] == 1 && empty($trx['pg_url_payment']) && $routes['3'] != 'cancel') {
|
||||
r2(U . "order/buy/" . (($trx['routers_id'] == 0) ? $trx['routers'] : $trx['routers_id']) . '/' . $trx['plan_id'], 'w', Lang::T("Checking payment"));
|
||||
}
|
||||
if ($routes['3'] == 'check') {
|
||||
@ -345,7 +345,11 @@ switch ($action) {
|
||||
$tax_rate = $tax_rate_setting;
|
||||
}
|
||||
$plan = ORM::for_table('tbl_plans')->find_one($routes['3']);
|
||||
$tax = Package::tax($plan['price'], $tax_rate);
|
||||
$add_cost = 0;
|
||||
if ($router['name'] != 'balance') {
|
||||
list($bills, $add_cost) = User::getBills($id_customer);
|
||||
}
|
||||
$tax = Package::tax($plan['price'] + $add_cost, $tax_rate);
|
||||
$pgs = array_values(explode(',', $config['payment_gateway']));
|
||||
if (count($pgs) == 0) {
|
||||
sendTelegram("Payment Gateway not set, please set it in Settings");
|
||||
@ -359,6 +363,8 @@ switch ($action) {
|
||||
}
|
||||
$ui->assign('route2', $routes[2]);
|
||||
$ui->assign('route3', $routes[3]);
|
||||
$ui->assign('add_cost', $add_cost);
|
||||
$ui->assign('bills', $bills);
|
||||
$ui->assign('plan', $plan);
|
||||
$ui->display('user-selectGateway.tpl');
|
||||
break;
|
||||
@ -454,7 +460,6 @@ switch ($action) {
|
||||
} else {
|
||||
$d->price = ($plan['price'] + $add_cost + $tax);
|
||||
}
|
||||
//$d->price = ($plan['price'] + $add_cost);
|
||||
$d->created_date = date('Y-m-d H:i:s');
|
||||
$d->status = 1;
|
||||
$d->save();
|
||||
|
@ -19,6 +19,36 @@ if ($action == 'delete') {
|
||||
r2(U . 'paymentgateway', 's', Lang::T('Payment Gateway Deleted'));
|
||||
}
|
||||
|
||||
if ($action == 'audit') {
|
||||
$pg = alphanumeric($routes[2]);
|
||||
$q = alphanumeric(_req('q'),'-._ ');
|
||||
$query = ORM::for_table('tbl_payment_gateway')->order_by_desc("id");
|
||||
$query->selects('id', 'username', 'gateway', 'gateway_trx_id', 'plan_id', 'plan_name', 'routers_id', 'routers', 'price', 'pg_url_payment', 'payment_method', 'payment_channel', 'expired_date', 'created_date', 'paid_date', 'trx_invoice', 'status');
|
||||
$query->where('gateway', $pg);
|
||||
if(!empty($q)) {
|
||||
$query->whereRaw("(gateway_trx_id LIKE '%$q%' OR username LIKE '%$q%' OR routers LIKE '%$q%' OR plan_name LIKE '%$q%')");
|
||||
$append_url = 'q='. urlencode($q);
|
||||
}
|
||||
$pgs = Paginator::findMany($query, ["search" => $search], 50, $append_url);
|
||||
|
||||
$ui->assign('_title', 'Payment Gateway Audit');
|
||||
$ui->assign('pgs', $pgs);
|
||||
$ui->assign('pg', $pg);
|
||||
$ui->assign('q', $q);
|
||||
$ui->display('paymentgateway-audit.tpl');
|
||||
die();
|
||||
}
|
||||
|
||||
if ($action == 'auditview') {
|
||||
$pg = alphanumeric($routes[2]);
|
||||
|
||||
$d = ORM::for_table('tbl_payment_gateway')->find_one($pg);
|
||||
$ui->assign('_title', 'Payment Gateway Audit View');
|
||||
$ui->assign('pg', $d);
|
||||
$ui->display('paymentgateway-audit-view.tpl');
|
||||
die();
|
||||
}
|
||||
|
||||
if (_post('save') == 'actives') {
|
||||
$pgs = '';
|
||||
if(is_array($_POST['pgs'])){
|
||||
|
@ -38,7 +38,7 @@ switch ($action) {
|
||||
r2(U . "pluginmanager", 's', 'Refresh success');
|
||||
break;
|
||||
case 'dlinstall':
|
||||
if($_app_stage == 'demo'){
|
||||
if ($_app_stage == 'demo') {
|
||||
r2(U . "pluginmanager", 'e', 'Demo Mode cannot install as it Security risk');
|
||||
}
|
||||
if (!is_writeable($CACHE_PATH)) {
|
||||
@ -62,27 +62,46 @@ switch ($action) {
|
||||
$zip->open($_FILES['zip_plugin']['tmp_name']);
|
||||
$zip->extractTo($cache);
|
||||
$zip->close();
|
||||
$plugin = basename($_FILES['zip_plugin']['name']);
|
||||
unlink($_FILES['zip_plugin']['tmp_name']);
|
||||
$success = 0;
|
||||
//moving
|
||||
if (file_exists($cache . 'plugin')) {
|
||||
File::copyFolder($cache . 'plugin' . DIRECTORY_SEPARATOR, $PLUGIN_PATH . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if (file_exists($cache . 'paymentgateway')) {
|
||||
File::copyFolder($cache . 'paymentgateway' . DIRECTORY_SEPARATOR, $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if (file_exists($cache . 'theme')) {
|
||||
File::copyFolder($cache . 'theme' . DIRECTORY_SEPARATOR, $UI_PATH . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if (file_exists($cache . 'device')) {
|
||||
File::copyFolder($cache . 'device' . DIRECTORY_SEPARATOR, $DEVICE_PATH . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if ($success == 0) {
|
||||
// old plugin and theme using this
|
||||
$check = strtolower($ghUrl);
|
||||
if (strpos($check, 'plugin') !== false) {
|
||||
File::copyFolder($folder, $PLUGIN_PATH . DIRECTORY_SEPARATOR);
|
||||
} else if (strpos($check, 'payment') !== false) {
|
||||
File::copyFolder($folder, $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR);
|
||||
} else if (strpos($check, 'theme') !== false) {
|
||||
rename($folder, $UI_PATH . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $plugin);
|
||||
} else if (strpos($check, 'device') !== false) {
|
||||
File::copyFolder($folder, $DEVICE_PATH . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
}
|
||||
//Cleaning
|
||||
File::deleteFolder($cache);
|
||||
r2(U . "pluginmanager", 's', 'Installation success');
|
||||
} else if (_post('gh_url', '') != '') {
|
||||
$ghUrl = _post('gh_url', '');
|
||||
if(!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$ghUrl = str_replace('https://github.com', 'https://'.$config['github_username'].':'.$config['github_token'].'@github.com', $ghUrl);
|
||||
if (!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$ghUrl = str_replace('https://github.com', 'https://' . $config['github_username'] . ':' . $config['github_token'] . '@github.com', $ghUrl);
|
||||
}
|
||||
$plugin = basename($ghUrl);
|
||||
$file = $cache . $plugin . '.zip';
|
||||
@ -102,17 +121,38 @@ switch ($action) {
|
||||
$zip->extractTo($cache);
|
||||
$zip->close();
|
||||
$folder = $cache . DIRECTORY_SEPARATOR . $plugin . '-main' . DIRECTORY_SEPARATOR;
|
||||
if(!file_exists($folder)) {
|
||||
$folder = $cache . DIRECTORY_SEPARATOR . $plugin . '-master' . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
$success = 0;
|
||||
if (file_exists($folder . 'plugin')) {
|
||||
File::copyFolder($folder . 'plugin' . DIRECTORY_SEPARATOR, $PLUGIN_PATH . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if (file_exists($folder . 'paymentgateway')) {
|
||||
File::copyFolder($folder . 'paymentgateway' . DIRECTORY_SEPARATOR, $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if (file_exists($folder . 'theme')) {
|
||||
File::copyFolder($folder . 'theme' . DIRECTORY_SEPARATOR, $UI_PATH . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if (file_exists($folder . 'device')) {
|
||||
File::copyFolder($folder . 'device' . DIRECTORY_SEPARATOR, $DEVICE_PATH . DIRECTORY_SEPARATOR);
|
||||
$success++;
|
||||
}
|
||||
if ($success == 0) {
|
||||
// old plugin and theme using this
|
||||
$check = strtolower($ghUrl);
|
||||
if (strpos($check, 'plugin') !== false) {
|
||||
File::copyFolder($folder, $PLUGIN_PATH . DIRECTORY_SEPARATOR);
|
||||
} else if (strpos($check, 'payment') !== false) {
|
||||
File::copyFolder($folder, $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR);
|
||||
} else if (strpos($check, 'theme') !== false) {
|
||||
rename($folder, $UI_PATH . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $plugin);
|
||||
} else if (strpos($check, 'device') !== false) {
|
||||
File::copyFolder($folder, $DEVICE_PATH . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
}
|
||||
File::deleteFolder($cache);
|
||||
r2(U . "pluginmanager", 's', 'Installation success');
|
||||
@ -135,8 +175,8 @@ switch ($action) {
|
||||
if ($tipe == 'plugin') {
|
||||
foreach ($json['plugins'] as $plg) {
|
||||
if ($plg['id'] == $plugin) {
|
||||
if(!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$plg['github'] = str_replace('https://github.com', 'https://'.$config['github_username'].':'.$config['github_token'].'@github.com', $plg['github']);
|
||||
if (!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$plg['github'] = str_replace('https://github.com', 'https://' . $config['github_username'] . ':' . $config['github_token'] . '@github.com', $plg['github']);
|
||||
}
|
||||
$fp = fopen($file, 'w+');
|
||||
$ch = curl_init($plg['github'] . '/archive/refs/heads/master.zip');
|
||||
@ -186,8 +226,8 @@ switch ($action) {
|
||||
if ($tipe == 'plugin') {
|
||||
foreach ($json['plugins'] as $plg) {
|
||||
if ($plg['id'] == $plugin) {
|
||||
if(!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$plg['github'] = str_replace('https://github.com', 'https://'.$config['github_username'].':'.$config['github_token'].'@github.com', $plg['github']);
|
||||
if (!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$plg['github'] = str_replace('https://github.com', 'https://' . $config['github_username'] . ':' . $config['github_token'] . '@github.com', $plg['github']);
|
||||
}
|
||||
$fp = fopen($file, 'w+');
|
||||
$ch = curl_init($plg['github'] . '/archive/refs/heads/master.zip');
|
||||
@ -223,8 +263,8 @@ switch ($action) {
|
||||
} else if ($tipe == 'payment') {
|
||||
foreach ($json['payment_gateway'] as $plg) {
|
||||
if ($plg['id'] == $plugin) {
|
||||
if(!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$plg['github'] = str_replace('https://github.com', 'https://'.$config['github_username'].':'.$config['github_token'].'@github.com', $plg['github']);
|
||||
if (!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$plg['github'] = str_replace('https://github.com', 'https://' . $config['github_username'] . ':' . $config['github_token'] . '@github.com', $plg['github']);
|
||||
}
|
||||
$fp = fopen($file, 'w+');
|
||||
$ch = curl_init($plg['github'] . '/archive/refs/heads/master.zip');
|
||||
@ -257,6 +297,43 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if ($tipe == 'device') {
|
||||
foreach ($json['devices'] as $d) {
|
||||
if ($d['id'] == $plugin) {
|
||||
if (!empty($config['github_token']) && !empty($config['github_username'])) {
|
||||
$d['github'] = str_replace('https://github.com', 'https://' . $config['github_username'] . ':' . $config['github_token'] . '@github.com', $d['github']);
|
||||
}
|
||||
$fp = fopen($file, 'w+');
|
||||
$ch = curl_init($d['github'] . '/archive/refs/heads/master.zip');
|
||||
curl_setopt($ch, CURLOPT_POST, 0);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($file);
|
||||
$zip->extractTo($CACHE_PATH);
|
||||
$zip->close();
|
||||
$folder = $CACHE_PATH . File::pathFixer('/' . $plugin . '-main/');
|
||||
if (!file_exists($folder)) {
|
||||
$folder = $CACHE_PATH . File::pathFixer('/' . $plugin . '-master/');
|
||||
}
|
||||
if (!file_exists($folder)) {
|
||||
r2(U . "pluginmanager", 'e', 'Extracted Folder is unknown');
|
||||
}
|
||||
File::copyFolder($folder, $DEVICE_PATH . DIRECTORY_SEPARATOR, ['README.md', 'LICENSE']);
|
||||
File::deleteFolder($folder);
|
||||
unlink($file);
|
||||
r2(U . "paymentgateway", 's', 'Payment Gateway ' . $plugin . ' has been installed');
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (class_exists('ZipArchive')) {
|
||||
|
@ -46,7 +46,7 @@ switch ($do) {
|
||||
}
|
||||
|
||||
if (!empty($config['sms_url'])) {
|
||||
$otpPath .= sha1($username . $db_password) . ".txt";
|
||||
$otpPath .= sha1($username . $db_pass) . ".txt";
|
||||
run_hook('validate_otp'); #HOOK
|
||||
//expired 10 minutes
|
||||
if (file_exists($otpPath) && time() - filemtime($otpPath) > 1200) {
|
||||
@ -122,7 +122,7 @@ switch ($do) {
|
||||
mkdir($otpPath);
|
||||
touch($otpPath . 'index.html');
|
||||
}
|
||||
$otpPath .= sha1($username . $db_password) . ".txt";
|
||||
$otpPath .= sha1($username . $db_pass) . ".txt";
|
||||
//expired 10 minutes
|
||||
if (file_exists($otpPath) && time() - filemtime($otpPath) < 1200) {
|
||||
$ui->assign('username', $username);
|
||||
|
@ -155,7 +155,9 @@ switch ($action) {
|
||||
die();
|
||||
}
|
||||
}
|
||||
// Save all settings including tax system
|
||||
// Save all settings including tax system
|
||||
$enable_session_timeout = isset($_POST['enable_session_timeout']) ? 1 : 0;
|
||||
$_POST['enable_session_timeout'] = $enable_session_timeout;
|
||||
foreach ($_POST as $key => $value) {
|
||||
$d = ORM::for_table('tbl_appconfig')->where('setting', $key)->find_one();
|
||||
if ($d) {
|
||||
@ -699,7 +701,7 @@ switch ($action) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
$dbc = new mysqli($db_host, $db_user, $db_password, $db_name);
|
||||
$dbc = new mysqli($db_host, $db_user, $db_pass, $db_name);
|
||||
if ($result = $dbc->query('SHOW TABLE STATUS')) {
|
||||
$tables = array();
|
||||
while ($row = $result->fetch_array()) {
|
||||
|
@ -29,6 +29,7 @@ class MikrotikPppoe
|
||||
|
||||
function add_customer($customer, $plan)
|
||||
{
|
||||
global $isChangePlan;
|
||||
$mikrotik = $this->info($plan['routers']);
|
||||
$client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
//check if customer exists
|
||||
@ -51,7 +52,9 @@ class MikrotikPppoe
|
||||
$setRequest->setArgument('password', $pass);
|
||||
$client->sendSync($setRequest);
|
||||
//disconnect then
|
||||
//$this->removePpoeActive($client, $customer['username']);
|
||||
if(isset($isChangePlan) && $isChangePlan){
|
||||
$this->removePpoeActive($client, $customer['username']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,14 +28,56 @@ class Radius
|
||||
|
||||
function add_customer($customer, $plan)
|
||||
{
|
||||
$b = ORM::for_table('tbl_user_recharges')
|
||||
->where('customer_id', $customer['id'])
|
||||
->where('plan_id', $plan['id'])
|
||||
->where('status', 'on')
|
||||
->findMany();
|
||||
$p = ORM::for_table('tbl_plans')
|
||||
->where('id', $plan['id'])
|
||||
->findOne();
|
||||
|
||||
if($b){
|
||||
$this->customerAddPlan($customer, $plan, $b['expiration'] . ' ' . $b['time']);
|
||||
$date_only = date("Y-m-d");
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
// if customer has attribute Expired Date use it
|
||||
$day_exp = User::getAttribute("Expired Date", $customer['id']);
|
||||
if (!$day_exp) {
|
||||
// if customer no attribute Expired Date use plan expired date
|
||||
$day_exp = 20;
|
||||
if ($p['prepaid'] == 'no') {
|
||||
$day_exp = $p['expired_date'];
|
||||
}
|
||||
if (empty($day_exp)) {
|
||||
$day_exp = 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($p['validity_unit'] == 'Months') {
|
||||
$date_exp = date("Y-m-d", strtotime('+' . $p['validity'] . ' month'));
|
||||
} else if ($p['validity_unit'] == 'Period') {
|
||||
$date_tmp = date("Y-m-$day_exp", strtotime('+' . $p['validity'] . ' month'));
|
||||
$dt1 = new DateTime("$date_only");
|
||||
$dt2 = new DateTime("$date_tmp");
|
||||
$diff = $dt2->diff($dt1);
|
||||
$sum = $diff->format("%a"); // => 453
|
||||
if ($sum >= 35 * $p['validity']) {
|
||||
$date_exp = date("Y-m-$day_exp", strtotime('+0 month'));
|
||||
} else {
|
||||
$date_exp = date("Y-m-$day_exp", strtotime('+' . $p['validity'] . ' month'));
|
||||
};
|
||||
$time = date("23:59:00");
|
||||
} else if ($p['validity_unit'] == 'Days') {
|
||||
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime('+' . $p['validity'] . ' day')));
|
||||
$date_exp = $datetime[0];
|
||||
$time = $datetime[1];
|
||||
} else if ($p['validity_unit'] == 'Hrs') {
|
||||
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime('+' . $p['validity'] . ' hour')));
|
||||
$date_exp = $datetime[0];
|
||||
$time = $datetime[1];
|
||||
} else if ($p['validity_unit'] == 'Mins') {
|
||||
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime('+' . $p['validity'] . ' minute')));
|
||||
$date_exp = $datetime[0];
|
||||
$time = $datetime[1];
|
||||
}
|
||||
|
||||
if ($p) {
|
||||
$this->customerAddPlan($customer, $plan, $date_exp . ' ' . $time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +150,7 @@ class Radius
|
||||
function remove_plan($plan)
|
||||
{
|
||||
// Delete Plan
|
||||
$this->getTablePackage()->where_equal('plan_id', "plan_" . $plan['id'])->delete_many();
|
||||
$this->getTablePackage()->where_equal('plan_id', $plan['id'])->delete_many();
|
||||
// Reset User Plan
|
||||
$c = $this->getTableUserPackage()->where_equal('groupname', "plan_" . $plan['id'])->findMany();
|
||||
if ($c) {
|
||||
@ -219,16 +261,23 @@ class Radius
|
||||
/**
|
||||
* When add a plan to Customer, use this
|
||||
*/
|
||||
public function customerAddPlan($customer, $plan, $expired = null)
|
||||
public function customerAddPlan($customer, $plan, $expired = '')
|
||||
{
|
||||
global $config;
|
||||
if ($this->customerUpsert($customer, $plan)) {
|
||||
$p = $this->getTableUserPackage()->where_equal('username', $customer['username'])->findOne();
|
||||
if ($p) {
|
||||
// if exists
|
||||
// session timeout [it reset everyday, am still making my research] we can use it for something like 1H/Day - since it reset daily, and Max-All-Session clear everything
|
||||
//$this->delAtribute($customer['username'], 'Session-Timeout', 3600); // 3600 = 1 hour
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-All-Session', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-Volume', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-Data', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Mikrotik-Rate-Limit', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'WISPr-Session-Terminate-Time', 'username', $customer['username']);
|
||||
//$this->delAtribute($this->getTableCustomer(), 'Ascend-Data-Rate', 'username', $customer['username']);
|
||||
//we are removing the below in the next two updates, some users may have that attribute, it will remove them before we remove it
|
||||
$this->delAtribute($this->getTableCustomer(), 'access-period', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-Volume', 'username', $customer['username']);
|
||||
$p->groupname = "plan_" . $plan['id'];
|
||||
$p->save();
|
||||
} else {
|
||||
@ -238,53 +287,63 @@ class Radius
|
||||
$p->priority = 1;
|
||||
$p->save();
|
||||
}
|
||||
|
||||
|
||||
$this->addBandwidth($customer, $plan);
|
||||
|
||||
if ($plan['type'] == 'Hotspot' && $plan['typebp'] == "Limited") {
|
||||
if ($plan['limit_type'] == "Time_Limit") {
|
||||
if ($plan['time_unit'] == 'Hrs')
|
||||
$timelimit = $plan['time_limit'] * 60 * 60;
|
||||
else
|
||||
$timelimit = $plan['time_limit'] * 60;
|
||||
// session timeout [it reset everyday, am still making my research] we can use it for something like 1H/Day - since it reset daily, and Max-All-Session clear everything
|
||||
//$this->upsertCustomer($customer['username'], 'Session-Timeout', 3600); // 3600 = 1 hour
|
||||
$this->upsertCustomer($customer['username'], 'Max-All-Session', $timelimit);
|
||||
$this->upsertCustomer($customer['username'], 'Expire-After', $timelimit);
|
||||
} else if ($plan['limit_type'] == "Data_Limit") {
|
||||
if ($plan['data_unit'] == 'GB')
|
||||
$datalimit = $plan['data_limit'] . "000000000";
|
||||
else
|
||||
$datalimit = $plan['data_limit'] . "000000";
|
||||
//$this->upsertCustomer($customer['username'], 'Max-Volume', $datalimit);
|
||||
// Mikrotik Spesific
|
||||
$this->upsertCustomer($customer['username'], 'Max-Data', $datalimit);
|
||||
//$this->upsertCustomer($customer['username'], 'Mikrotik-Total-Limit', $datalimit);
|
||||
} else if ($plan['limit_type'] == "Both_Limit") {
|
||||
if ($plan['time_unit'] == 'Hrs')
|
||||
$timelimit = $plan['time_limit'] * 60 * 60;
|
||||
else
|
||||
$timelimit = $plan['time_limit'] * 60;
|
||||
// session timeout [it reset everyday, am still making my research] we can use it for something like 1H/Day - since it reset daily, and Max-All-Session clear everything
|
||||
//$this->upsertCustomer($customer['username'], 'Session-Timeout', 3600); // 3600 = 1 hour
|
||||
$this->upsertCustomer($customer['username'], 'Max-All-Session', $timelimit);
|
||||
if ($plan['data_unit'] == 'GB')
|
||||
$datalimit = $plan['data_limit'] . "000000000";
|
||||
else
|
||||
$datalimit = $plan['data_limit'] . "000000";
|
||||
//$this->upsertCustomer($customer['username'], 'Max-Volume', $datalimit);
|
||||
$this->upsertCustomer($customer['username'], 'Max-All-Session', $timelimit);
|
||||
// Mikrotik Spesific
|
||||
$this->upsertCustomer($customer['username'], 'Max-Data', $datalimit);
|
||||
//$this->upsertCustomer($customer['username'], 'Mikrotik-Total-Limit', $datalimit);
|
||||
}
|
||||
} else {
|
||||
//$this->delAtribute($this->getTableCustomer(), 'Max-Volume', 'username', $customer['username']);
|
||||
// session timeout [it reset everyday, am still making my research] we can use it for something like 1H/Day - since it reset daily, and Max-All-Session clear everything
|
||||
//$this->delAtribute($customer['username'], 'Session-Timeout', 3600); // 3600 = 1 hour
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-All-Session', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-Data', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Mikrotik-Rate-Limit', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'WISPr-Session-Terminate-Time', 'username', $customer['username']);
|
||||
//we are removing the below in the next two updates, some users may have that attribute, it will remove them before we remove it
|
||||
$this->delAtribute($this->getTableCustomer(), 'access-period', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-Volume', 'username', $customer['username']);
|
||||
}
|
||||
|
||||
$this->disconnectCustomer($customer['username']);
|
||||
$this->getTableAcct()->where_equal('username', $customer['username'])->delete_many();
|
||||
|
||||
|
||||
// expired user
|
||||
if ($expired != null) {
|
||||
//$this->upsertCustomer($customer['username'], 'access-period', strtotime($expired) - time());
|
||||
$this->upsertCustomer($customer['username'], 'Max-All-Session', strtotime($expired) - time());
|
||||
$this->upsertCustomer($customer['username'], 'expiration', date('d M Y H:i:s', strtotime($expired)));
|
||||
if ($expired != '') {
|
||||
//extend session time only if the plan are the same
|
||||
if ($plan['plan_id'] == $p['plan_id'] && $config['extend_expiry'] != 'no') {
|
||||
// session timeout [it reset everyday, am still making my research] we can use it for something like 1H/Day - since it reset daily, and Max-All-Session clear everything
|
||||
//$this->upsertCustomer($customer['username'], 'Session-Timeout', 3600); // 3600 = 1 hour
|
||||
$this->upsertCustomer($customer['username'], 'Max-All-Session', strtotime($expired) - time());
|
||||
$this->upsertCustomer($customer['username'], 'Expiration', date('d M Y H:i:s', strtotime($expired)));
|
||||
}
|
||||
// Mikrotik Spesific
|
||||
$this->upsertCustomer(
|
||||
$customer['username'],
|
||||
@ -293,8 +352,11 @@ class Radius
|
||||
);
|
||||
} else {
|
||||
$this->delAtribute($this->getTableCustomer(), 'Max-All-Session', 'username', $customer['username']);
|
||||
//$this->delAtribute($this->getTableCustomer(), 'access-period', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'expiration', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Expiration', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'Mikrotik-Rate-Limit', 'username', $customer['username']);
|
||||
$this->delAtribute($this->getTableCustomer(), 'WISPr-Session-Terminate-Time', 'username', $customer['username']);
|
||||
//we are removing the below in the next two updates, some users may have that attribute, it will remove them before we remove it
|
||||
$this->delAtribute($this->getTableCustomer(), 'access-period', 'username', $customer['username']);
|
||||
}
|
||||
|
||||
if ($plan['type'] == 'PPPOE') {
|
||||
@ -307,7 +369,8 @@ class Radius
|
||||
return false;
|
||||
}
|
||||
|
||||
public function customerUpsert($customer, $plan)
|
||||
|
||||
public function customerUpsert($customer, $plan) //Update or Insert customer plan
|
||||
{
|
||||
if ($plan['type'] == 'PPPOE') {
|
||||
$this->upsertCustomer($customer['username'], 'Cleartext-Password', (empty($customer['pppoe_password'])) ? $customer['password'] : $customer['pppoe_password']);
|
||||
@ -321,9 +384,9 @@ class Radius
|
||||
return true;
|
||||
}
|
||||
|
||||
private function delAtribute($tabel, $attribute, $key, $value)
|
||||
private function delAtribute($table, $attribute, $key, $value)
|
||||
{
|
||||
$r = $tabel->where_equal($key, $value)->whereEqual('attribute', $attribute)->findOne();
|
||||
$r = $table->where_equal($key, $value)->whereEqual('attribute', $attribute)->findOne();
|
||||
if ($r) $r->delete();
|
||||
}
|
||||
|
||||
@ -357,7 +420,8 @@ class Radius
|
||||
$r->attribute = $attr;
|
||||
$r->op = $op;
|
||||
$r->value = $value;
|
||||
return $r->save();
|
||||
$r->save();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* To insert or update existing customer Attribute
|
||||
@ -398,4 +462,31 @@ class Radius
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function addBandwidth($customer, $plan)
|
||||
{
|
||||
$bw = ORM::for_table("tbl_bandwidth")->find_one($plan['id_bw']);
|
||||
$unitdown = ($bw['rate_down_unit'] == 'Kbps') ? 'K' : 'M';
|
||||
$unitup = ($bw['rate_up_unit'] == 'Kbps') ? 'K' : 'M';
|
||||
|
||||
// TODO Burst mode [ 2M/1M 256K/128K 128K/64K 1s 1 64K/32K]
|
||||
|
||||
if (!empty(trim($bw['burst']))) {
|
||||
// burst format: 2M/1M 256K/128K 128K/64K 1s 1 64K/32K
|
||||
$pattern = '/(\d+[KM])\/(\d+[KM]) (\d+[KM])\/(\d+[KM]) (\d+) (\d+) (\d+[KM])\/(\d+[KM])/';
|
||||
preg_match($pattern, $bw['burst'], $matches);
|
||||
if (count($matches) == 9) {
|
||||
|
||||
$burst = $bw['rate_up'] . $unitup . "/" . $bw['rate_down'] . $unitdown . ' ' . $matches[1] . '/' . $matches[2] . ' ' . $matches[3] . '/' . $matches[4] . ' ' . $matches[5] . ' ' . $matches[6] . ' ' . $matches[7] . '/' . $matches[8];
|
||||
$this->upsertCustomer($customer['username'], 'Mikrotik-Rate-Limit', $burst);
|
||||
} else {
|
||||
_log("Unexpected burst format for customer " . $customer['username']);
|
||||
}
|
||||
} else {
|
||||
//$this->upsertCustomer($customer['username'], 'Ascend-Data-Rate', $this->stringToInteger($bw['rate_up'] . $unitup) . "/" . $this->stringToInteger($bw['rate_down'] . $unitdown));
|
||||
$this->upsertCustomer($customer['username'], 'Mikrotik-Rate-Limit', $bw['rate_up'] . $unitup . "/" . $bw['rate_down'] . $unitdown);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -673,5 +673,18 @@
|
||||
"End_Date": "End Date",
|
||||
"New_Version_Notification": "New Version Notification",
|
||||
"Enabled": "Enabled",
|
||||
"This_is_to_notify_you_when_new_updates_is_available": "This is to notify you when new updates is available"
|
||||
"This_is_to_notify_you_when_new_updates_is_available": "This is to notify you when new updates is available",
|
||||
"Enable_Session_Timeout": "Enable Session Timeout",
|
||||
"Logout_Admin_if_not_Available_Online_a_period_of_time": "Logout Admin if not Available\/Online a period of time",
|
||||
"Timeout_Duration": "Timeout Duration",
|
||||
"Enter_the_session_timeout_duration__minutes_": "Enter the session timeout duration (minutes)",
|
||||
"Idle_Timeout__Logout_Admin_if_Idle_for_xx_minutes": "Idle Timeout, Logout Admin if Idle for xx minutes",
|
||||
"Failed_to_create_transaction__please_tell_seller_": "Failed to create transaction, please tell seller.",
|
||||
"paid_off": "paid off",
|
||||
"Sync_account_if_you_failed_login_to_internet": "Sync account if you failed login to internet",
|
||||
"Channel": "Channel",
|
||||
"Payment_Link": "Payment Link",
|
||||
"Created": "Created",
|
||||
"2": "2",
|
||||
"_": "-"
|
||||
}
|
@ -129,5 +129,9 @@
|
||||
"2024.7.24" : [
|
||||
"ALTER TABLE `tbl_voucher` ADD `used_date` DATETIME NULL DEFAULT NULL AFTER `status`;",
|
||||
"UPDATE `tbl_voucher` SET `used_date`=now() WHERE `status`=1;"
|
||||
],
|
||||
"2024.8.1" : [
|
||||
"ALTER TABLE `tbl_payment_gateway` CHANGE `gateway_trx_id` `gateway_trx_id` VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '';",
|
||||
"ALTER TABLE `tbl_payment_gateway` CHANGE `pg_url_payment` `pg_url_payment` VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '';"
|
||||
]
|
||||
}
|
@ -6,5 +6,7 @@
|
||||
"reminder_3_day": "Hello *[[name]]*, \r\nyour internet package *[[package]]* will be expired in 3 days.",
|
||||
"reminder_1_day": "Hello *[[name]]*,\r\n your internet package *[[package]]* will be expired tomorrow.",
|
||||
"invoice_paid": "*[[company_name]]*\r\n[[address]]\r\n[[phone]]\r\n\r\n\r\nINVOICE: *[[invoice]]*\r\nDate : [[date]]\r\n[[payment_gateway]] [[payment_channel]]\r\n\r\n\r\nType : *[[type]]*\r\nPackage : *[[plan_name]]*\r\nPrice : *[[plan_price]]*\r\n\r\nUsername : *[[user_name]]*\r\nPassword : ***********\r\n\r\nExpired : *[[expired_date]]*\r\n\r\n====================\r\n[[footer]]",
|
||||
"invoice_balance": "*[[company_name]]*\r\n[[address]]\r\n[[phone]]\r\n\r\n\r\nINVOICE: *[[invoice]]*\r\nDate : [[date]]\r\n[[payment_gateway]] [[payment_channel]]\r\n\r\n\r\nType : *[[type]]*\r\nPackage : *[[plan_name]]*\r\nPrice : *[[plan_price]]*\r\n\r\n====================\r\n[[footer]]"
|
||||
"invoice_balance": "*[[company_name]]*\r\n[[address]]\r\n[[phone]]\r\n\r\n\r\nINVOICE: *[[invoice]]*\r\nDate : [[date]]\r\n[[payment_gateway]] [[payment_channel]]\r\n\r\n\r\nType : *[[type]]*\r\nPackage : *[[plan_name]]*\r\nPrice : *[[plan_price]]*\r\n\r\n====================\r\n[[footer]]",
|
||||
"welcome_message": "Welcome aboard, [[name]]! \r\nWe're excited to have you as a new [[company]] customer. \r\nYour account is all set up and ready to go.\r\n\r\nHere's a quick overview:\r\n\r\nPortal: [[url]]\r\nYour login is [[Username]]\r\nYour temporary password is [[Password]] (please change this on your first login)\r\n\r\nNeed help? Reach out to our support team at anytime.\r\n\r\nWe're here to ensure you have an amazing experience with our services. Let us know how we can best support you.\r\n\r\nWelcome to the [[company]] family!"
|
||||
|
||||
}
|
||||
|
@ -136,6 +136,22 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Welcome Message')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" id="welcome_message" name="welcome_message"
|
||||
rows="4">{Lang::htmlspecialchars($_json['welcome_message'])}</textarea>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
<b>[[name]]</b> - {Lang::T('will be replaced with Customer Name')}.<br>
|
||||
<b>[[username]]</b> - {Lang::T('will be replaced with Customer username')}.<br>
|
||||
<b>[[password]]</b> - {Lang::T('will be replaced with Customer password')}.<br>
|
||||
<b>[[url]]</b> - {Lang::T('will be replaced with Customer Portal URL')}.<br>
|
||||
<b>[[company]]</b> - {Lang::T('will be replaced with Company Name')}.<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{if $_c['enable_balance'] == 'yes'}
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
|
@ -242,8 +242,8 @@
|
||||
<label class="col-md-2 control-label">{Lang::T('Allow Extend')}</label>
|
||||
<div class="col-md-6">
|
||||
<select name="extend_expired" id="extend_expired" class="form-control text-muted">
|
||||
<option value="0">No</option>
|
||||
<option value="1" {if $_c['extend_expired']}selected="selected" {/if}>Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">Customer can request to extend expirations</p>
|
||||
@ -586,6 +586,24 @@
|
||||
{Lang::T('Miscellaneous')}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Enable Session Timeout')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="enable_session_timeout" value="1" name="enable_session_timeout" {if $_c['enable_session_timeout']==1}checked{/if}>
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('Logout Admin if not Available/Online a period of time')}</p>
|
||||
</div>
|
||||
<div class="form-group" id="timeout_duration_input" style="display: none;">
|
||||
<label class="col-md-2 control-label">{Lang::T('Timeout Duration')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="number" value="{$_c['session_timeout_duration']}" class="form-control" name="session_timeout_duration" id="session_timeout_duration"
|
||||
placeholder="{Lang::T('Enter the session timeout duration (minutes)')}" min="1">
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('Idle Timeout, Logout Admin if Idle for xx minutes')}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('New Version Notification')}</label>
|
||||
<div class="col-md-6">
|
||||
@ -747,7 +765,8 @@
|
||||
<label class="col-md-2 control-label">Github Token</label>
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control" id="github_token" name="github_token"
|
||||
value="{$_c['github_token']}" placeholder="ghp_........">
|
||||
value="{$_c['github_token']}" placeholder="ghp_........"
|
||||
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'">
|
||||
</div>
|
||||
<span class="help-block col-md-4"><a href="https://github.com/settings/tokens/new"
|
||||
target="_blank">Create GitHub personal access token (classic)</a>, only need repo scope</span>
|
||||
@ -785,6 +804,38 @@ add dst-host=*.{$_domain}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var sectionTimeoutCheckbox = document.getElementById('enable_session_timeout');
|
||||
var timeoutDurationInput = document.getElementById('timeout_duration_input');
|
||||
var timeoutDurationField = document.getElementById('session_timeout_duration');
|
||||
|
||||
if (sectionTimeoutCheckbox.checked) {
|
||||
timeoutDurationInput.style.display = 'block';
|
||||
timeoutDurationField.required = true;
|
||||
}
|
||||
|
||||
sectionTimeoutCheckbox.addEventListener('change', function() {
|
||||
if (this.checked) {
|
||||
timeoutDurationInput.style.display = 'block';
|
||||
timeoutDurationField.required = true;
|
||||
} else {
|
||||
timeoutDurationInput.style.display = 'none';
|
||||
timeoutDurationField.required = false;
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector('form').addEventListener('submit', function(event) {
|
||||
if (sectionTimeoutCheckbox.checked && (!timeoutDurationField.value || isNaN(timeoutDurationField.value))) {
|
||||
event.preventDefault();
|
||||
alert('Please enter a valid session timeout duration.');
|
||||
timeoutDurationField.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
function testWa() {
|
||||
var target = prompt("Phone number\nSave First before Test", "");
|
||||
|
@ -103,6 +103,21 @@
|
||||
<div id="map" style="width: '100%'; height: 200px; min-height: 150px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{Lang::T('Send Welcome Message')}</label>
|
||||
<div class="col-md-9">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="send_welcome_message" value="1" name="send_welcome_message">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" id="method" style="display: none;">
|
||||
<label class="col-md-3 control-label">{Lang::T('Method')}</label>
|
||||
<label class="col-md-3 control-label"><input type="checkbox" name="sms" value="1"> {Lang::T('SMS')}</label>
|
||||
<label class="col-md-2 control-label"><input type="checkbox" name="wa" value="1"> {Lang::T('WA')}</label>
|
||||
<label class="col-md-2 control-label"><input type="checkbox" name="email" value="1"> {Lang::T('Email')}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -175,6 +190,38 @@
|
||||
</center>
|
||||
</form>
|
||||
{literal}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var sendWelcomeCheckbox = document.getElementById('send_welcome_message');
|
||||
var methodSection = document.getElementById('method');
|
||||
|
||||
function toggleMethodSection() {
|
||||
if (sendWelcomeCheckbox.checked) {
|
||||
methodSection.style.display = 'block';
|
||||
} else {
|
||||
methodSection.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
toggleMethodSection();
|
||||
|
||||
sendWelcomeCheckbox.addEventListener('change', toggleMethodSection);
|
||||
document.querySelector('form').addEventListener('submit', function(event) {
|
||||
if (sendWelcomeCheckbox.checked) {
|
||||
var methodCheckboxes = methodSection.querySelectorAll('input[type="checkbox"]');
|
||||
var oneChecked = Array.from(methodCheckboxes).some(function(checkbox) {
|
||||
return checkbox.checked;
|
||||
});
|
||||
|
||||
if (!oneChecked) {
|
||||
event.preventDefault();
|
||||
alert('Please choose at least one method.');
|
||||
methodSection.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var customFieldsContainer = document.getElementById('custom-fields-container');
|
||||
|
@ -1,67 +1,64 @@
|
||||
{include file="sections/header.tpl"}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner">
|
||||
<h4><sup>{$_c['currency_code']}</sup>
|
||||
{number_format($iday,0,$_c['dec_point'],$_c['thousands_sep'])}</h4>
|
||||
<p>{Lang::T('Income Today')}</p>
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin', 'Report'])}
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner">
|
||||
<h4 class="text-bold" style="font-size: large;"><sup>{$_c['currency_code']}</sup>
|
||||
{number_format($iday,0,$_c['dec_point'],$_c['thousands_sep'])}</h4>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-clock"></i>
|
||||
</div>
|
||||
<a href="{$_url}reports/by-date" class="small-box-footer">{Lang::T('Income Today')}</a>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-bag"></i>
|
||||
</div>
|
||||
<a href="{$_url}reports/by-date" class="small-box-footer">{Lang::T('View Reports')} <i
|
||||
class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner">
|
||||
<h4><sup>{$_c['currency_code']}</sup>
|
||||
{number_format($imonth,0,$_c['dec_point'],$_c['thousands_sep'])}</h4>
|
||||
|
||||
<p>{Lang::T('Income This Month')}</p>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner">
|
||||
<h4 class="text-bold" style="font-size: large;"><sup>{$_c['currency_code']}</sup>
|
||||
{number_format($imonth,0,$_c['dec_point'],$_c['thousands_sep'])}</h4>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-android-calendar"></i>
|
||||
</div>
|
||||
<a href="{$_url}reports/by-period" class="small-box-footer">{Lang::T('Income This Month')}</a>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-stats-bars"></i>
|
||||
</div>
|
||||
<a href="{$_url}reports/by-period" class="small-box-footer">{Lang::T('View Reports')} <i
|
||||
class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner">
|
||||
<h4>{$u_act}/{$u_all}</h4>
|
||||
|
||||
<p>{Lang::T('Users Active')}</p>
|
||||
<h4 class="text-bold" style="font-size: large;">{$u_act}/{$u_all-$u_act}</h4>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-person"></i>
|
||||
</div>
|
||||
<a href="{$_url}plan/list" class="small-box-footer">{Lang::T('View All')} <i
|
||||
class="fa fa-arrow-circle-right"></i></a>
|
||||
<a href="{$_url}plan/list" class="small-box-footer">{Lang::T('Active')}/{Lang::T('Expired')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner">
|
||||
<h4>{$c_all}</h4>
|
||||
|
||||
<p>{Lang::T('Total Users')}</p>
|
||||
<h4 class="text-bold" style="font-size: large;">{$c_all}</h4>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-users"></i>
|
||||
<i class="ion ion-android-people"></i>
|
||||
</div>
|
||||
<a href="{$_url}customers/list" class="small-box-footer">{Lang::T('View All')} <i
|
||||
class="fa fa-arrow-circle-right"></i></a>
|
||||
<a href="{$_url}customers/list" class="small-box-footer">{Lang::T('Customers')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ol class="breadcrumb">
|
||||
<li>{Lang::dateFormat($start_date)}</li>
|
||||
<li>{Lang::dateFormat($current_date)}</li>
|
||||
{if $_c['enable_balance'] == 'yes' && in_array($_admin['user_type'],['SuperAdmin','Admin', 'Report'])}
|
||||
<li>
|
||||
{Lang::T('Customer Balance')} <sup>{$_c['currency_code']}</sup>
|
||||
<b>{number_format($cb,0,$_c['dec_point'],$_c['thousands_sep'])}</b>
|
||||
</li>
|
||||
{/if}
|
||||
</ol>
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
@ -180,7 +177,8 @@
|
||||
<div class="col-md-5">
|
||||
{if $_c['hide_pg'] != 'yes'}
|
||||
<div class="panel panel-success panel-hovered mb20 activities">
|
||||
<div class="panel-heading">{Lang::T('Payment Gateway')}: {str_replace(',',', ',$_c['payment_gateway'])}</div>
|
||||
<div class="panel-heading">{Lang::T('Payment Gateway')}: {str_replace(',',', ',$_c['payment_gateway'])}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if $_c['hide_aui'] != 'yes'}
|
||||
@ -339,6 +337,9 @@
|
||||
//lets calculate the inactive users as reported
|
||||
var expired = u_all - u_act;
|
||||
var inactive = c_all - u_all;
|
||||
if(inactive < 0){
|
||||
inactive = 0;
|
||||
}
|
||||
// Create the chart data
|
||||
var data = {
|
||||
labels: ['Active Users', 'Expired Users', 'Inactive Users'],
|
||||
|
79
ui/ui/paymentgateway-audit-view.tpl
Normal file
79
ui/ui/paymentgateway-audit-view.tpl
Normal file
@ -0,0 +1,79 @@
|
||||
{include file="sections/header.tpl"}
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-5">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">
|
||||
{$pg['gateway_trx_id']}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="list-group list-group-unbordered">
|
||||
<li class="list-group-item">
|
||||
<b>TRX ID</b> <span class="pull-right"> {$pg['id']} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Invoice')}</b> <span class="pull-right">
|
||||
<a href="{$_url}reports/activation&q={$pg['trx_invoice']}" class="text-black">{$pg['trx_invoice']}</a>
|
||||
</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Status')}</b> <span
|
||||
class="pull-right"> {if $pg['status'] == 1}UNPAID{elseif $pg['status'] == 2}PAID{elseif $pg['status'] == 3}FAILED{else}CANCELED{/if} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Username')}</b>
|
||||
<span class="pull-right"> <a href="{$_url}customers/viewu/{$pg['username']}" class="text-black">{$pg['username']}</a> </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Plan Name')}</b> <span class="pull-right"> {$pg['plan_name']} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Routers')}</b> <span class="pull-right"> {$pg['routers']} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Price')}</b> <span
|
||||
class="pull-right"> {Lang::moneyFormat($pg['price'])} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Payment Link')}</b> <span class="pull-right"> {if $pg['pg_url_payment']}
|
||||
<a href="{$pg['pg_url_payment']}" target="_blank" class="btn btn-xs btn-default"
|
||||
rel="noopener noreferrer">open</a>
|
||||
{/if} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Channel')}</b> <span class="pull-right"> {$pg['payment_method']} -
|
||||
{$pg['payment_channel']} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Created')}</b> <span
|
||||
class="pull-right"> {if $pg['created_date'] != null}{Lang::dateTimeFormat($pg['created_date'])}{/if} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Expired')}</b> <span
|
||||
class="pull-right"> {if $pg['expired_date'] != null}{Lang::dateTimeFormat($pg['expired_date'])}{/if} </span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Paid')}</b> <span
|
||||
class="pull-right"> {if $pg['paid_date'] != null}{Lang::dateTimeFormat($pg['paid_date'])}{/if} </span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">
|
||||
Response when request payment
|
||||
</div>
|
||||
<pre class="panel-body p-1">{if $pg['pg_request'] != null}{Lang::jsonArray2text(json_decode($pg['pg_request'], true))}{/if}</pre>
|
||||
</div>
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">
|
||||
Response when payment PAID
|
||||
</div>
|
||||
<pre class="panel-body p-1">{if $pg['pg_request'] != null}{Lang::jsonArray2text(json_decode($pg['pg_paid_response'], true))}{/if}</pre>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
71
ui/ui/paymentgateway-audit.tpl
Normal file
71
ui/ui/paymentgateway-audit.tpl
Normal file
@ -0,0 +1,71 @@
|
||||
{include file="sections/header.tpl"}
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">
|
||||
{ucwords($pg)}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form id="site-search" method="post" action="{$_url}paymentgateway/audit/{$pg}">
|
||||
<div class="input-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="{Lang::T('Search')}..."
|
||||
value="{$q}">
|
||||
<div class="input-group-btn">
|
||||
<button type="submit" class="btn btn-danger" title="Clear Search Query"
|
||||
href="{$_url}plan/list"><span class="glyphicon glyphicon-search"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>TRX ID</th>
|
||||
<th>PG ID</th>
|
||||
<th>{Lang::T('Username')}</th>
|
||||
<th>{Lang::T('Plan Name')}</th>
|
||||
<th>{Lang::T('Routers')}</th>
|
||||
<th>{Lang::T('Price')}</th>
|
||||
<th>{Lang::T('Payment Link')}</th>
|
||||
<th>{Lang::T('Channel')}</th>
|
||||
<th>{Lang::T('Created')}</th>
|
||||
<th>{Lang::T('Expired')}</th>
|
||||
<th>{Lang::T('Paid')}</th>
|
||||
<th>{Lang::T('Invoice')}</th>
|
||||
<th>{Lang::T('Status')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $pgs as $pg}
|
||||
<tr class="{if $pg['status'] == 1}warning{elseif $pg['status'] == 2}success{else}danger{/if}">
|
||||
<td>{$pg['id']}</td>
|
||||
<td><a href="{$_url}paymentgateway/audit-view/{$pg['id']}"
|
||||
class="text-black">{$pg['gateway_trx_id']}</a></td>
|
||||
<td><a href="{$_url}customers/viewu/{$pg['username']}" class="text-black">{$pg['username']}</a>
|
||||
</td>
|
||||
<td>{$pg['plan_name']}</td>
|
||||
<td>{$pg['routers']}</td>
|
||||
<td>{Lang::moneyFormat($pg['price'])}</td>
|
||||
<td>
|
||||
{if $pg['pg_url_payment']}
|
||||
<a href="{$pg['pg_url_payment']}" target="_blank" class="btn btn-xs btn-default btn-block"
|
||||
rel="noopener noreferrer">open</a>
|
||||
{/if}
|
||||
</td>
|
||||
<td>{$pg['payment_method']} - {$pg['payment_channel']}</td>
|
||||
<td>{if $pg['created_date'] != null}{Lang::dateTimeFormat($pg['created_date'])}{/if}</td>
|
||||
<td>{if $pg['expired_date'] != null}{Lang::dateTimeFormat($pg['expired_date'])}{/if}</td>
|
||||
<td>{if $pg['paid_date'] != null}{Lang::dateTimeFormat($pg['paid_date'])}{/if}</td>
|
||||
<td>{if $pg['trx_invoice']}<a href="{$_url}reports/activation&q={$pg['trx_invoice']}"
|
||||
class="text-black">{$pg['trx_invoice']}</a>{/if}</td>
|
||||
<td>{if $pg['status'] == 1}UNPAID{elseif $pg['status'] == 2}PAID{elseif $pg['status'] == 3}FAILED{else}CANCELED{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{include file="pagination.tpl"}
|
||||
<a href="{$_url}paymentgateway/" class="btn btn-default btn-xs">kembali</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
@ -14,9 +14,19 @@
|
||||
<td><a href="{$_url}paymentgateway/{$pg}"
|
||||
class="btn btn-block btn-{if in_array($pg, $actives)}info{else}default{/if} text-left">{ucwords($pg)}</a>
|
||||
</td>
|
||||
<td width="10"><a href="{$_url}paymentgateway/delete/{$pg}"
|
||||
onclick="return confirm('{Lang::T('Delete')} {$pg}?')" class="btn btn-danger"><i
|
||||
class="glyphicon glyphicon-trash"></i></a></td>
|
||||
<td width="114">
|
||||
<div class="btn-group" role="group" aria-label="...">
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{$_url}paymentgateway/audit/{$pg}"
|
||||
class="btn btn-success text-black">Audit</a>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{$_url}paymentgateway/delete/{$pg}"
|
||||
onclick="return confirm('{Lang::T('Delete')} {$pg}?')"
|
||||
class="btn btn-danger"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
|
@ -30,7 +30,8 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p class="help-block">To download from private/paid repository, <a href="{$_url}settings/app#Github_Authentication">Set your Github Authentication first</a></p>
|
||||
<p class="help-block">To download from private/paid repository, <a href="{$_url}settings/app#Github_Authentication">Set
|
||||
your Github Authentication first</a></p>
|
||||
|
||||
<div class="panel panel-primary panel-hovered">
|
||||
<div class="panel-heading">{Lang::T('Plugin')}
|
||||
@ -53,8 +54,8 @@
|
||||
<center><small><i>@{$plugin['author']} Last update: {$plugin['last_update']}</i></small>
|
||||
</center>
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="{$plugin['url']}" target="_blank" style="color: black;" class="btn btn-primary"><i
|
||||
class="glyphicon glyphicon-globe"></i> Web</a>
|
||||
<a href="{$plugin['url']}" target="_blank" style="color: black;" class="btn btn-{if $plugin['ispaid']}warning{else}primary{/if}"><i
|
||||
class="glyphicon glyphicon-globe"></i> {if $plugin['ispaid']}Buy{else}Web{/if}</a>
|
||||
<a href="{$plugin['github']}" target="_blank" style="color: black;" class="btn btn-info"><i
|
||||
class="glyphicon glyphicon-align-left"></i> Source</a>
|
||||
</div>
|
||||
@ -90,8 +91,11 @@
|
||||
<div class="box-footer ">
|
||||
<center><small><i>@{$pg['author']} Last update: {$pg['last_update']}</i></small></center>
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="{$pg['url']}" target="_blank" style="color: black;" class="btn btn-primary"><i
|
||||
class="glyphicon glyphicon-globe"></i> Web</a>
|
||||
<a href="{$pg['url']}" target="_blank" style="color: black;"
|
||||
class="btn btn-{if $pg['ispaid']}warning{else}primary{/if}"><i
|
||||
class="glyphicon glyphicon-globe"></i>
|
||||
{if $pg['ispaid']}Buy{else}Web{/if}
|
||||
</a>
|
||||
<a href="{$pg['github']}" target="_blank" style="color: black;" class="btn btn-info"><i
|
||||
class="glyphicon glyphicon-align-left"></i> Source</a>
|
||||
<a {if $zipExt } href="{$_url}pluginmanager/install/payment/{$pg['id']}"
|
||||
|
@ -189,9 +189,65 @@
|
||||
.bs-callout-info h4 {
|
||||
color: #1b809e
|
||||
}
|
||||
|
||||
/* Checkbox container */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
/* Hidden checkbox */
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Slider */
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
background-color: white;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked+.slider {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
input:focus+.slider {
|
||||
box-shadow: 0 0 1px #2196F3;
|
||||
}
|
||||
|
||||
input:checked+.slider:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(26px);
|
||||
}
|
||||
</style>
|
||||
{if isset($xheader)}
|
||||
{$xheader}
|
||||
{$xheader}
|
||||
{/if}
|
||||
|
||||
</head>
|
||||
@ -261,80 +317,82 @@
|
||||
</li>
|
||||
{$_MENU_AFTER_DASHBOARD}
|
||||
{if !in_array($_admin['user_type'],['Report'])}
|
||||
<li class="{if in_array($_system_menu, ['customers', 'map'])}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-users"></i> <span>{Lang::T('Customer')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_system_menu eq 'customers' }class="active" {/if}><a
|
||||
href="{$_url}customers">{Lang::T('Lists')}</a></li>
|
||||
<li {if $_system_menu eq 'map' }class="active" {/if}><a
|
||||
href="{$_url}map/customer">{Lang::T('Location')}</a></li>
|
||||
{$_MENU_CUSTOMERS}
|
||||
</ul>
|
||||
</li>
|
||||
{$_MENU_AFTER_CUSTOMERS}
|
||||
<li class="{if $_system_menu eq 'plan'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-ticket"></i> <span>{Lang::T('Services')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}plan/list">{Lang::T('Active Users')}</a></li>
|
||||
{if $_c['disable_voucher'] != 'yes'}
|
||||
<li {if $_routes[1] eq 'voucher' }class="active" {/if}><a
|
||||
href="{$_url}plan/voucher">{Lang::T('Vouchers')}</a></li>
|
||||
<li {if $_routes[1] eq 'refill' }class="active" {/if}><a
|
||||
href="{$_url}plan/refill">{Lang::T('Refill Customer')}</a></li>
|
||||
{/if}
|
||||
<li {if $_routes[1] eq 'recharge' }class="active" {/if}><a
|
||||
href="{$_url}plan/recharge">{Lang::T('Recharge Customer')}</a></li>
|
||||
{if $_c['enable_balance'] == 'yes'}
|
||||
<li {if $_routes[1] eq 'deposit' }class="active" {/if}><a
|
||||
href="{$_url}plan/deposit">{Lang::T('Refill Balance')}</a></li>
|
||||
{/if}
|
||||
{$_MENU_SERVICES}
|
||||
</ul>
|
||||
</li>
|
||||
<li class="{if in_array($_system_menu, ['customers', 'map'])}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-users"></i> <span>{Lang::T('Customer')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_system_menu eq 'customers' }class="active" {/if}><a
|
||||
href="{$_url}customers">{Lang::T('Lists')}</a></li>
|
||||
<li {if $_system_menu eq 'map' }class="active" {/if}><a
|
||||
href="{$_url}map/customer">{Lang::T('Location')}</a></li>
|
||||
{$_MENU_CUSTOMERS}
|
||||
</ul>
|
||||
</li>
|
||||
{$_MENU_AFTER_CUSTOMERS}
|
||||
<li class="{if $_system_menu eq 'plan'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-ticket"></i> <span>{Lang::T('Services')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}plan/list">{Lang::T('Active Users')}</a></li>
|
||||
{if $_c['disable_voucher'] != 'yes'}
|
||||
<li {if $_routes[1] eq 'voucher' }class="active" {/if}><a
|
||||
href="{$_url}plan/voucher">{Lang::T('Vouchers')}</a></li>
|
||||
<li {if $_routes[1] eq 'refill' }class="active" {/if}><a
|
||||
href="{$_url}plan/refill">{Lang::T('Refill Customer')}</a></li>
|
||||
{/if}
|
||||
<li {if $_routes[1] eq 'recharge' }class="active" {/if}><a
|
||||
href="{$_url}plan/recharge">{Lang::T('Recharge Customer')}</a></li>
|
||||
{if $_c['enable_balance'] == 'yes'}
|
||||
<li {if $_routes[1] eq 'deposit' }class="active" {/if}><a
|
||||
href="{$_url}plan/deposit">{Lang::T('Refill Balance')}</a></li>
|
||||
{/if}
|
||||
{$_MENU_SERVICES}
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_AFTER_SERVICES}
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<li class="{if $_system_menu eq 'services'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-cube"></i> <span>{Lang::T('Internet Plan')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'hotspot' }class="active" {/if}><a
|
||||
href="{$_url}services/hotspot">Hotspot</a></li>
|
||||
<li {if $_routes[1] eq 'pppoe' }class="active" {/if}><a
|
||||
href="{$_url}services/pppoe">PPPOE</a></li>
|
||||
<li {if $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}bandwidth/list">{Lang::T('Bandwidth')}</a></li>
|
||||
{if $_c['enable_balance'] == 'yes'}
|
||||
<li {if $_routes[1] eq 'balance' }class="active" {/if}><a
|
||||
href="{$_url}services/balance">{Lang::T('Customer Balance')}</a></li>
|
||||
{/if}
|
||||
{$_MENU_PLANS}
|
||||
</ul>
|
||||
</li>
|
||||
<li class="{if $_system_menu eq 'services'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-cube"></i> <span>{Lang::T('Internet Plan')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'hotspot' }class="active" {/if}><a
|
||||
href="{$_url}services/hotspot">Hotspot</a></li>
|
||||
<li {if $_routes[1] eq 'pppoe' }class="active" {/if}><a
|
||||
href="{$_url}services/pppoe">PPPOE</a></li>
|
||||
<li {if $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}bandwidth/list">{Lang::T('Bandwidth')}</a></li>
|
||||
{if $_c['enable_balance'] == 'yes'}
|
||||
<li {if $_routes[1] eq 'balance' }class="active" {/if}><a
|
||||
href="{$_url}services/balance">{Lang::T('Customer Balance')}</a></li>
|
||||
{/if}
|
||||
{$_MENU_PLANS}
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_AFTER_PLANS}
|
||||
<li class="{if $_system_menu eq 'reports'}active{/if} treeview">
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin', 'Report'])}
|
||||
<a href="#">
|
||||
<i class="ion ion-clipboard"></i> <span>{Lang::T('Reports')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
{/if}
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_system_menu eq 'reports' }class="active" {/if}><a
|
||||
href="{$_url}reports">{Lang::T('Daily Reports')}</a></li>
|
||||
@ -361,64 +419,64 @@
|
||||
</li>
|
||||
{$_MENU_AFTER_MESSAGE}
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<li class="{if $_system_menu eq 'network'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-network"></i> <span>{Lang::T('Network')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[0] eq 'routers' and $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}routers/list">{Lang::T('Routers')}</a></li>
|
||||
<li {if $_routes[0] eq 'pool' and $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}pool/list">{Lang::T('IP Pool')}</a></li>
|
||||
{$_MENU_NETWORK}
|
||||
</ul>
|
||||
</li>
|
||||
{$_MENU_AFTER_NETWORKS}
|
||||
{if $_c['radius_enable']}
|
||||
<li class="{if $_system_menu eq 'radius'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-database"></i> <span>{Lang::T('Radius')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[0] eq 'radius' and $_routes[1] eq 'nas-list' }class="active" {/if}><a
|
||||
href="{$_url}radius/nas-list">{Lang::T('Radius NAS')}</a></li>
|
||||
{$_MENU_RADIUS}
|
||||
</ul>
|
||||
<li class="{if $_system_menu eq 'network'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-network"></i> <span>{Lang::T('Network')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[0] eq 'routers' and $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}routers/list">{Lang::T('Routers')}</a></li>
|
||||
<li {if $_routes[0] eq 'pool' and $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}pool/list">{Lang::T('IP Pool')}</a></li>
|
||||
{$_MENU_NETWORK}
|
||||
</ul>
|
||||
</li>
|
||||
{$_MENU_AFTER_NETWORKS}
|
||||
{if $_c['radius_enable']}
|
||||
<li class="{if $_system_menu eq 'radius'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="fa fa-database"></i> <span>{Lang::T('Radius')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[0] eq 'radius' and $_routes[1] eq 'nas-list' }class="active" {/if}><a
|
||||
href="{$_url}radius/nas-list">{Lang::T('Radius NAS')}</a></li>
|
||||
{$_MENU_RADIUS}
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_AFTER_RADIUS}
|
||||
<li class="{if $_system_menu eq 'pages'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-document"></i> <span>{Lang::T("Static Pages")}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'Order_Voucher' }class="active" {/if}><a
|
||||
href="{$_url}pages/Order_Voucher">{Lang::T('Order Voucher')}</a></li>
|
||||
<li {if $_routes[1] eq 'Voucher' }class="active" {/if}><a
|
||||
href="{$_url}pages/Voucher">{Lang::T('Voucher')} Template</a></li>
|
||||
<li {if $_routes[1] eq 'Announcement' }class="active" {/if}><a
|
||||
href="{$_url}pages/Announcement">{Lang::T('Announcement')}</a></li>
|
||||
<li {if $_routes[1] eq 'Announcement_Customer' }class="active" {/if}><a
|
||||
href="{$_url}pages/Announcement_Customer">{Lang::T('Customer Announcement')}</a>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_AFTER_RADIUS}
|
||||
<li class="{if $_system_menu eq 'pages'}active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-document"></i> <span>{Lang::T("Static Pages")}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'Order_Voucher' }class="active" {/if}><a
|
||||
href="{$_url}pages/Order_Voucher">{Lang::T('Order Voucher')}</a></li>
|
||||
<li {if $_routes[1] eq 'Voucher' }class="active" {/if}><a
|
||||
href="{$_url}pages/Voucher">{Lang::T('Voucher')} Template</a></li>
|
||||
<li {if $_routes[1] eq 'Announcement' }class="active" {/if}><a
|
||||
href="{$_url}pages/Announcement">{Lang::T('Announcement')}</a></li>
|
||||
<li {if $_routes[1] eq 'Announcement_Customer' }class="active" {/if}><a
|
||||
href="{$_url}pages/Announcement_Customer">{Lang::T('Customer Announcement')}</a>
|
||||
</li>
|
||||
<li {if $_routes[1] eq 'Registration_Info' }class="active" {/if}><a
|
||||
href="{$_url}pages/Registration_Info">{Lang::T('Registration Info')}</a></li>
|
||||
<li {if $_routes[1] eq 'Privacy_Policy' }class="active" {/if}><a
|
||||
href="{$_url}pages/Privacy_Policy">{Lang::T('Privacy Policy')}</a></li>
|
||||
<li {if $_routes[1] eq 'Terms_and_Conditions' }class="active" {/if}><a
|
||||
href="{$_url}pages/Terms_and_Conditions">{Lang::T('Terms and Conditions')}</a></li>
|
||||
{$_MENU_PAGES}
|
||||
</ul>
|
||||
</li>
|
||||
<li {if $_routes[1] eq 'Registration_Info' }class="active" {/if}><a
|
||||
href="{$_url}pages/Registration_Info">{Lang::T('Registration Info')}</a></li>
|
||||
<li {if $_routes[1] eq 'Privacy_Policy' }class="active" {/if}><a
|
||||
href="{$_url}pages/Privacy_Policy">{Lang::T('Privacy Policy')}</a></li>
|
||||
<li {if $_routes[1] eq 'Terms_and_Conditions' }class="active" {/if}><a
|
||||
href="{$_url}pages/Terms_and_Conditions">{Lang::T('Terms and Conditions')}</a></li>
|
||||
{$_MENU_PAGES}
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_AFTER_PAGES}
|
||||
<li
|
||||
@ -431,75 +489,76 @@
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<li {if $_routes[1] eq 'app' }class="active" {/if}><a
|
||||
href="{$_url}settings/app">{Lang::T('General Settings')}</a></li>
|
||||
<li {if $_routes[1] eq 'localisation' }class="active" {/if}><a
|
||||
href="{$_url}settings/localisation">{Lang::T('Localisation')}</a></li>
|
||||
<li {if $_routes[1] eq 'maintenance' }class="active" {/if}><a
|
||||
href="{$_url}settings/maintenance">{Lang::T('Maintenance Mode')}</a></li>
|
||||
<li {if $_routes[1] eq 'notifications' }class="active" {/if}><a
|
||||
href="{$_url}settings/notifications">{Lang::T('User Notification')}</a></li>
|
||||
<li {if $_routes[1] eq 'devices' }class="active" {/if}><a
|
||||
href="{$_url}settings/devices">{Lang::T('Devices')}</a></li>
|
||||
<li {if $_routes[1] eq 'app' }class="active" {/if}><a
|
||||
href="{$_url}settings/app">{Lang::T('General Settings')}</a></li>
|
||||
<li {if $_routes[1] eq 'localisation' }class="active" {/if}><a
|
||||
href="{$_url}settings/localisation">{Lang::T('Localisation')}</a></li>
|
||||
<li {if $_routes[1] eq 'maintenance' }class="active" {/if}><a
|
||||
href="{$_url}settings/maintenance">{Lang::T('Maintenance Mode')}</a></li>
|
||||
<li {if $_routes[1] eq 'notifications' }class="active" {/if}><a
|
||||
href="{$_url}settings/notifications">{Lang::T('User Notification')}</a></li>
|
||||
<li {if $_routes[1] eq 'devices' }class="active" {/if}><a
|
||||
href="{$_url}settings/devices">{Lang::T('Devices')}</a></li>
|
||||
{/if}
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin','Agent'])}
|
||||
<li {if $_routes[1] eq 'users' }class="active" {/if}><a
|
||||
href="{$_url}settings/users">{Lang::T('Administrator Users')}</a></li>
|
||||
<li {if $_routes[1] eq 'users' }class="active" {/if}><a
|
||||
href="{$_url}settings/users">{Lang::T('Administrator Users')}</a></li>
|
||||
{/if}
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<li {if $_routes[1] eq 'dbstatus' }class="active" {/if}><a
|
||||
href="{$_url}settings/dbstatus">{Lang::T('Backup/Restore')}</a></li>
|
||||
<li {if $_system_menu eq 'paymentgateway' }class="active" {/if}>
|
||||
<a href="{$_url}paymentgateway">
|
||||
<span class="text">{Lang::T('Payment Gateway')}</span>
|
||||
</a>
|
||||
</li>
|
||||
{$_MENU_SETTINGS}
|
||||
<li {if $_routes[0] eq 'pluginmanager' }class="active" {/if}>
|
||||
<a href="{$_url}pluginmanager"><i class="glyphicon glyphicon-tasks"></i>
|
||||
{Lang::T('Plugin Manager')}</a>
|
||||
</li>
|
||||
<li {if $_routes[1] eq 'dbstatus' }class="active" {/if}><a
|
||||
href="{$_url}settings/dbstatus">{Lang::T('Backup/Restore')}</a></li>
|
||||
<li {if $_system_menu eq 'paymentgateway' }class="active" {/if}>
|
||||
<a href="{$_url}paymentgateway">
|
||||
<span class="text">{Lang::T('Payment Gateway')}</span>
|
||||
</a>
|
||||
</li>
|
||||
{$_MENU_SETTINGS}
|
||||
<li {if $_routes[0] eq 'pluginmanager' }class="active" {/if}>
|
||||
<a href="{$_url}pluginmanager"><i class="glyphicon glyphicon-tasks"></i>
|
||||
{Lang::T('Plugin Manager')}</a>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
</li>
|
||||
{$_MENU_AFTER_SETTINGS}
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<li class="{if $_system_menu eq 'logs' }active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-clock"></i> <span>{Lang::T('Logs')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}logs/phpnuxbill">PhpNuxBill</a></li>
|
||||
{if $_c['radius_enable']}
|
||||
<li {if $_routes[1] eq 'radius' }class="active" {/if}><a
|
||||
href="{$_url}logs/radius">Radius</a>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_LOGS}
|
||||
</ul>
|
||||
</li>
|
||||
<li class="{if $_system_menu eq 'logs' }active{/if} treeview">
|
||||
<a href="#">
|
||||
<i class="ion ion-clock"></i> <span>{Lang::T('Logs')}</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li {if $_routes[1] eq 'list' }class="active" {/if}><a
|
||||
href="{$_url}logs/phpnuxbill">PhpNuxBill</a></li>
|
||||
{if $_c['radius_enable']}
|
||||
<li {if $_routes[1] eq 'radius' }class="active" {/if}><a
|
||||
href="{$_url}logs/radius">Radius</a>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_LOGS}
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_AFTER_LOGS}
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<li {if $_system_menu eq 'community' }class="active" {/if}>
|
||||
<li {if $_system_menu eq 'community' }class="active" {/if}>
|
||||
<a href="{if $_c['docs_clicked'] != 'yes'}{$_url}settings/docs{else}./docs/{/if}">
|
||||
<i class="ion ion-ios-bookmarks"></i>
|
||||
<span class="text">{Lang::T('Documentation')}</span>
|
||||
{if $_c['docs_clicked'] != 'yes'}
|
||||
<span class="pull-right-container"><small class="label pull-right bg-green">New</small></span>
|
||||
{/if}
|
||||
</a>
|
||||
</li>
|
||||
<li {if $_system_menu eq 'community' }class="active" {/if}>
|
||||
<a href="{$_url}community">
|
||||
<i class="ion ion-chatboxes"></i>
|
||||
<span class="text">{Lang::T('Community')}</span>
|
||||
</a>
|
||||
</li>
|
||||
<i class="ion ion-ios-bookmarks"></i>
|
||||
<span class="text">{Lang::T('Documentation')}</span>
|
||||
{if $_c['docs_clicked'] != 'yes'}
|
||||
<span class="pull-right-container"><small
|
||||
class="label pull-right bg-green">New</small></span>
|
||||
{/if}
|
||||
</a>
|
||||
</li>
|
||||
<li {if $_system_menu eq 'community' }class="active" {/if}>
|
||||
<a href="{$_url}community">
|
||||
<i class="ion ion-chatboxes"></i>
|
||||
<span class="text">{Lang::T('Community')}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
{$_MENU_AFTER_COMMUNITY}
|
||||
</ul>
|
||||
@ -507,11 +566,11 @@
|
||||
</aside>
|
||||
|
||||
{if $_c['maintenance_mode'] == 1}
|
||||
<div class="notification-top-bar">
|
||||
<p>{Lang::T('The website is currently in maintenance mode, this means that some or all functionality may be
|
||||
<div class="notification-top-bar">
|
||||
<p>{Lang::T('The website is currently in maintenance mode, this means that some or all functionality may be
|
||||
unavailable to regular users during this time.')}<small> <a
|
||||
href="{$_url}settings/maintenance">{Lang::T('Turn Off')}</a></small></p>
|
||||
</div>
|
||||
href="{$_url}settings/maintenance">{Lang::T('Turn Off')}</a></small></p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="content-wrapper">
|
||||
@ -523,19 +582,19 @@
|
||||
|
||||
<section class="content">
|
||||
{if isset($notify)}
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}error{/if}',
|
||||
title: '{$notify}',
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/if}
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}error{/if}',
|
||||
title: '{$notify}',
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/if}
|
@ -103,7 +103,9 @@
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
})
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -124,15 +124,24 @@
|
||||
{else}
|
||||
{assign var="exp" value=explode(':',$v)}
|
||||
{Lang::moneyFormat($exp[0])}
|
||||
<sup title="{$exp[1]} more times">{$exp[1]}x</sup>
|
||||
{assign var="total" value=$exp[0]+$total}
|
||||
<sup
|
||||
title="{$exp[1]} more times">{if $exp[1]==0}{Lang::T('paid off')}{else}{$exp[1]}x{/if}</sup>
|
||||
{if $exp[1]>0}
|
||||
{assign var="total" value=$exp[0]+$total}
|
||||
{/if}
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
<tr>
|
||||
<td class="small text-success text-uppercase text-normal"><b>{Lang::T('Total')}</b></td>
|
||||
<td class="small mb15"><b>{Lang::moneyFormat($total)}</b></td>
|
||||
<td class="small mb15"><b>
|
||||
{if $total==0}
|
||||
{ucwords(Lang::T('paid off'))}
|
||||
{else}
|
||||
{Lang::moneyFormat($total)}
|
||||
{/if}
|
||||
</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
{/if}
|
||||
@ -166,6 +175,12 @@
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="small text-primary text-uppercase text-normal">{Lang::T('Bandwidth')}</td>
|
||||
<td class="small mb15">
|
||||
{$_bill['name_bw']}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="small text-info text-uppercase text-normal">{Lang::T('Created On')}</td>
|
||||
<td class="small mb15">
|
||||
@ -234,9 +249,14 @@
|
||||
href="{$_url}home&extend={$_bill['id']}&stoken={App::getToken()}"
|
||||
onclick="return confirm('{Text::toHex($_c['extend_confirmation'])}')">{Lang::T('Extend')}</a>
|
||||
{/if}
|
||||
<a class="btn btn-primary pull-right btn-sm"
|
||||
<a class="btn btn-primary pull-right btn-sm"
|
||||
href="{$_url}home&recharge={$_bill['id']}&stoken={App::getToken()}"
|
||||
onclick="return confirm('{Lang::T('Recharge')}?')">{Lang::T('Recharge')}</a>
|
||||
<a class="btn btn-warning text-black pull-right btn-sm"
|
||||
href="{$_url}home&sync={$_bill['id']}&stoken={App::getToken()}"
|
||||
onclick="return confirm('{Lang::T('Sync account if you failed login to internet')}?')"
|
||||
data-toggle="tooltip" data-placement="top" title="{Lang::T('Sync account if you failed login to internet')}"><span
|
||||
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> {Lang::T('Sync')}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -11,8 +11,8 @@
|
||||
<div class="col-md-8">
|
||||
<select name="gateway" id="gateway" class="form-control">
|
||||
{foreach $pgs as $pg}
|
||||
<option value="{$pg}">
|
||||
{ucwords($pg)}</option>
|
||||
<option value="{$pg}">
|
||||
{ucwords($pg)}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
@ -25,44 +25,82 @@
|
||||
<b>{Lang::T('Plan Name')}</b> <span class="pull-right">{$plan['name_plan']}</span>
|
||||
</li>
|
||||
{if $plan['is_radius'] or $plan['routers']}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Location')}</b> <span class="pull-right">{if
|
||||
$plan['is_radius']}Radius{else}{$plan['routers']}{/if}</span>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Location')}</b> <span class="pull-right">{if
|
||||
$plan['is_radius']}Radius{else}{$plan['routers']}
|
||||
{/if}</span>
|
||||
</li>
|
||||
{/if}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Type')}</b> <span class="pull-right">{if $plan['prepaid'] eq
|
||||
'yes'}Prepaid{else}Postpaid{/if}
|
||||
'yes'}Prepaid{else}Postpaid
|
||||
{/if}
|
||||
{$plan['type']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Plan Price')}</b> <span class="pull-right">{if $using eq
|
||||
'zero'}{Lang::moneyFormat(0)}{else}{Lang::moneyFormat($plan['price'])}{/if}</span>
|
||||
'zero'}{Lang::moneyFormat(0)}
|
||||
{else}
|
||||
{Lang::moneyFormat($plan['price'])}
|
||||
{/if}</span>
|
||||
</li>
|
||||
{if $plan['validity']}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Plan Validity')}</b> <span class="pull-right">{$plan['validity']}
|
||||
{$plan['validity_unit']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Plan Validity')}</b> <span class="pull-right">{$plan['validity']}
|
||||
{$plan['validity_unit']}</span>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<center><b>{Lang::T('Summary')}</b></center>
|
||||
<ul class="list-group list-group-unbordered">
|
||||
{if $tax}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Tax')}</b> <span
|
||||
class="pull-right">{Lang::moneyFormat($tax)}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <small>({Lang::T('Plan Price')} + {Lang::T('Tax')})</small><span class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">{Lang::moneyFormat($plan['price']+$tax)}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Tax')}</b> <span class="pull-right">{Lang::moneyFormat($tax)}</span>
|
||||
</li>
|
||||
{if $add_cost>0}
|
||||
{foreach $bills as $k => $v}
|
||||
<li class="list-group-item">
|
||||
<b>{$k}</b> <span class="pull-right">{Lang::moneyFormat($v)}</span>
|
||||
</li>
|
||||
{/foreach}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Additional Cost')}</b> <span
|
||||
class="pull-right">{Lang::moneyFormat($add_cost)}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <small>({Lang::T('Plan Price')}
|
||||
+{Lang::T('Additional Cost')})</small><span class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">{Lang::moneyFormat($plan['price']+$add_cost+$tax)}</span>
|
||||
</li>
|
||||
{else}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <small>({Lang::T('Plan Price')} + {Lang::T('Tax')})</small><span
|
||||
class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">{Lang::moneyFormat($plan['price']+$tax)}</span>
|
||||
</li>
|
||||
{/if}
|
||||
{else}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <span class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">
|
||||
{Lang::moneyFormat($plan['price'])}</span>
|
||||
</li>
|
||||
{if $add_cost>0}
|
||||
{foreach $bills as $k => $v}
|
||||
<li class="list-group-item">
|
||||
<b>{$k}</b> <span class="pull-right">{Lang::moneyFormat($v)}</span>
|
||||
</li>
|
||||
{/foreach}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Additional Cost')}</b> <span
|
||||
class="pull-right">{Lang::moneyFormat($add_cost)}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <small>({Lang::T('Plan Price')}
|
||||
+{Lang::T('Additional Cost')})</small><span class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">{Lang::moneyFormat($plan['price']+$add_cost)}</span>
|
||||
</li>
|
||||
{else}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <span class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">{Lang::moneyFormat($plan['price'])}</span>
|
||||
</li>
|
||||
{/if}
|
||||
{/if}
|
||||
</ul>
|
||||
<center>
|
||||
|
@ -8,6 +8,11 @@
|
||||
session_start();
|
||||
include "config.php";
|
||||
|
||||
if($db_password != null && ($db_pass == null || empty($db_pass))){
|
||||
// compability for old version
|
||||
$db_pass = $db_password;
|
||||
}
|
||||
|
||||
if (empty($update_url)) {
|
||||
$update_url = 'https://github.com/hotspotbilling/phpnuxbill/archive/refs/heads/master.zip';
|
||||
}
|
||||
@ -100,11 +105,10 @@ if (empty($step)) {
|
||||
}
|
||||
} else if ($step == 4) {
|
||||
if (file_exists("system/updates.json")) {
|
||||
require 'config.php';
|
||||
$db = new pdo(
|
||||
"mysql:host=$db_host;dbname=$db_name",
|
||||
$db_user,
|
||||
$db_password,
|
||||
$db_pass,
|
||||
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
);
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "2024.7.25"
|
||||
"version": "2024.8.2"
|
||||
}
|
Reference in New Issue
Block a user