Merge branch 'Development' into feature/radius
This commit is contained in:
commit
a67a470a06
10
.gitignore
vendored
10
.gitignore
vendored
@ -20,7 +20,9 @@ system/plugin/ui/*
|
||||
ui/ui_custom/**
|
||||
!ui/ui_custom/index.html
|
||||
!ui/ui_custom/README.md
|
||||
system/uploads/admin.png
|
||||
system/uploads/logo.png
|
||||
system/uploads/user.jpg
|
||||
system/uploads/notifications.json
|
||||
system/uploads/**
|
||||
!system/uploads/*.default.png
|
||||
system/uploads/sms/**
|
||||
!system/uploads/sms/index.html
|
||||
system/uploads/system/**
|
||||
!system/uploads/system/index.html
|
43
CHANGELOG.md
43
CHANGELOG.md
@ -2,6 +2,49 @@
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## 2023.9.15
|
||||
|
||||
- Fix Customer balance header
|
||||
- Deactivate Customer active plan
|
||||
- Sync Customer Plan to Mikrotik
|
||||
- Recharge Customer from Customer Details
|
||||
|
||||
## 2023.9.13
|
||||
|
||||
- add Current balance in notification
|
||||
- Buy Plan for Friend
|
||||
- Recharge Friend plan
|
||||
- Fix recharge Plan
|
||||
- Show Customer active plan in Customer list
|
||||
- Fix Customer counter in dashboard
|
||||
- Show Customer Balance in header
|
||||
- Fix Plugin Manager using Http::Get
|
||||
- Show Some error page when crash
|
||||
## 2023.9.7
|
||||
|
||||
- Fix PPPOE Delete Customer
|
||||
- Remove active Customer before deleting
|
||||
- Show IP and Mac even if it not Hotspot
|
||||
|
||||
## 2023.9.6
|
||||
|
||||
- Expired Pool
|
||||
Customer can be move to expired pool after plan expired by cron
|
||||
- Fix Delete customer
|
||||
- tbl_language removed
|
||||
|
||||
## 2023.9.1.1
|
||||
|
||||
- Fix cronjob Delete customer
|
||||
- Fix reminder text
|
||||
|
||||
## 2023.9.1
|
||||
|
||||
- Critical bug fixes, bug happen when user buy package, expired time will be calculated from last expired, not from when they buy the package
|
||||
- Time not change after user buy package for extending
|
||||
- Add Cancel Button to user dashboard when it show unpaid package
|
||||
- Fix username in user dashboard
|
||||
|
||||
## 2023.8.30
|
||||
|
||||
- Upload Logo from settings
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 178 KiB |
Binary file not shown.
Before Width: | Height: | Size: 48 KiB |
@ -65,22 +65,6 @@ CREATE TABLE
|
||||
|
||||
--
|
||||
|
||||
-- Struktur dari tabel `tbl_language`
|
||||
|
||||
--
|
||||
|
||||
CREATE TABLE
|
||||
`tbl_language` (
|
||||
`id` int(10) NOT NULL,
|
||||
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`folder` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`author` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
|
||||
-- Struktur dari tabel `tbl_logs`
|
||||
|
||||
--
|
||||
@ -174,6 +158,7 @@ CREATE TABLE
|
||||
`shared_users` int(10) DEFAULT NULL,
|
||||
`routers` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`pool` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`pool_expired` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 disabled\r\n'
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
|
||||
|
||||
@ -345,14 +330,6 @@ ALTER TABLE `tbl_customers` ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
|
||||
-- Indeks untuk tabel `tbl_language`
|
||||
|
||||
--
|
||||
|
||||
ALTER TABLE `tbl_language` ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
|
||||
-- Indeks untuk tabel `tbl_logs`
|
||||
|
||||
--
|
||||
@ -466,15 +443,6 @@ ALTER TABLE
|
||||
|
||||
--
|
||||
|
||||
-- AUTO_INCREMENT untuk tabel `tbl_language`
|
||||
|
||||
--
|
||||
|
||||
ALTER TABLE
|
||||
`tbl_language` MODIFY `id` int(10) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
--
|
||||
|
||||
-- AUTO_INCREMENT untuk tabel `tbl_logs`
|
||||
|
||||
--
|
||||
@ -611,38 +579,3 @@ VALUES (
|
||||
'2022-09-06 16:09:50',
|
||||
'2014-06-23 01:43:07'
|
||||
);
|
||||
|
||||
--
|
||||
|
||||
-- Dumping data untuk tabel `tbl_language`
|
||||
|
||||
--
|
||||
|
||||
INSERT INTO
|
||||
`tbl_language` (
|
||||
`id`,
|
||||
`name`,
|
||||
`folder`,
|
||||
`author`
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'Indonesia',
|
||||
'indonesia',
|
||||
'Ismail Marzuqi'
|
||||
), (
|
||||
2,
|
||||
'English',
|
||||
'english',
|
||||
'Ismail Marzuqi'
|
||||
), (
|
||||
3,
|
||||
'Spanish',
|
||||
'spanish',
|
||||
'Luis Hernandez'
|
||||
), (
|
||||
4,
|
||||
'Türkçe',
|
||||
'turkish',
|
||||
'Goktug Bogac Ogel'
|
||||
);
|
@ -19,12 +19,7 @@ class Balance
|
||||
{
|
||||
global $config;
|
||||
if (Balance::min($id_customer, $amount)) {
|
||||
if (Balance::plusByPhone($phoneTarget, $amount)) {
|
||||
return true;
|
||||
} else {
|
||||
Balance::plus($id_customer, $amount);
|
||||
return false;
|
||||
}
|
||||
return Balance::plusByPhone($phoneTarget, $amount);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -2,12 +2,17 @@
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
* using proxy, add this variable in config.php
|
||||
* $http_proxy = '127.0.0.1:3128';
|
||||
* if proxy using authentication, use this parameter
|
||||
* $http_proxyauth = 'user:password';
|
||||
**/
|
||||
|
||||
class Http
|
||||
{
|
||||
public static function getData($url, $headers)
|
||||
public static function getData($url, $headers = [])
|
||||
{
|
||||
global $http_proxy, $http_proxyauth, $admin;
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, 0);
|
||||
@ -15,13 +20,26 @@ class Http
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
if (!empty($http_proxy)) {
|
||||
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
|
||||
if (!empty($http_proxyauth)) {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
|
||||
}
|
||||
}
|
||||
$server_output = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
$error_msg = curl_error($ch);
|
||||
}
|
||||
curl_close($ch);
|
||||
return $server_output;
|
||||
if($admin && $error_msg){
|
||||
r2(U . 'dashboard', 'd', $error_msg);
|
||||
}
|
||||
return ($server_output) ? $server_output : $error_msg;
|
||||
}
|
||||
|
||||
public static function postJsonData($url, $array_post, $headers = [], $basic = null)
|
||||
{
|
||||
global $http_proxy, $http_proxyauth, $admin;
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
@ -30,6 +48,12 @@ class Http
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
|
||||
if (!empty($http_proxy)) {
|
||||
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
|
||||
if (!empty($http_proxyauth)) {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
|
||||
}
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($array_post));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
if (!empty($basic)) {
|
||||
@ -37,13 +61,20 @@ class Http
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$server_output = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
$error_msg = curl_error($ch);
|
||||
}
|
||||
curl_close($ch);
|
||||
return $server_output;
|
||||
if($admin && $error_msg){
|
||||
r2(U . 'dashboard', 'd', $error_msg);
|
||||
}
|
||||
return ($server_output) ? $server_output : $error_msg;
|
||||
}
|
||||
|
||||
|
||||
public static function postData($url, $array_post, $headers = [], $basic = null)
|
||||
{
|
||||
global $http_proxy, $http_proxyauth, $admin;
|
||||
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
@ -52,6 +83,12 @@ class Http
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
|
||||
if (!empty($http_proxy)) {
|
||||
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
|
||||
if (!empty($http_proxyauth)) {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
|
||||
}
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array_post));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
if (!empty($basic)) {
|
||||
@ -59,7 +96,13 @@ class Http
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$server_output = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
$error_msg = curl_error($ch);
|
||||
}
|
||||
curl_close($ch);
|
||||
return $server_output;
|
||||
if($admin && $error_msg){
|
||||
r2(U . 'dashboard', 'd', $error_msg);
|
||||
}
|
||||
return ($server_output) ? $server_output : $error_msg;
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,12 @@ class Lang
|
||||
|
||||
public static function dateTimeFormat($date){
|
||||
global $config;
|
||||
if(strtotime($date) < strtotime("2000-01-01 00:00:00")){
|
||||
return "";
|
||||
}else{
|
||||
return date($config['date_format']. ' H:i', strtotime($date));
|
||||
}
|
||||
}
|
||||
|
||||
public static function dateAndTimeFormat($date, $time){
|
||||
global $config;
|
||||
|
@ -12,7 +12,7 @@ class Message
|
||||
global $config;
|
||||
run_hook('send_telegram'); #HOOK
|
||||
if (!empty($config['telegram_bot']) && !empty($config['telegram_target_id'])) {
|
||||
file_get_contents('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $config['telegram_target_id'] . '&text=' . urlencode($txt));
|
||||
Http::getData('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $config['telegram_target_id'] . '&text=' . urlencode($txt));
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ class Message
|
||||
if (!empty($config['sms_url'])) {
|
||||
$smsurl = str_replace('[number]', urlencode($phone), $config['sms_url']);
|
||||
$smsurl = str_replace('[text]', urlencode($txt), $smsurl);
|
||||
file_get_contents($smsurl);
|
||||
Http::getData($smsurl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ class Message
|
||||
if (!empty($config['wa_url'])) {
|
||||
$waurl = str_replace('[number]', urlencode($phone), $config['wa_url']);
|
||||
$waurl = str_replace('[text]', urlencode($txt), $waurl);
|
||||
file_get_contents($waurl);
|
||||
Http::getData($waurl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,9 +56,10 @@ class Message
|
||||
return "$via: $msg";
|
||||
}
|
||||
|
||||
public static function sendBalanceNotification($phone, $name, $balance, $message, $via)
|
||||
public static function sendBalanceNotification($phone, $name, $balance, $balance_now, $message, $via)
|
||||
{
|
||||
$msg = str_replace('[[name]]', "*$name*", $message);
|
||||
$msg = str_replace('[[current_balance]]', Lang::moneyFormat($balance_now), $msg);
|
||||
$msg = str_replace('[[balance]]', "*" . Lang::moneyFormat($balance) . "*", $msg);
|
||||
if (
|
||||
!empty($phone) && strlen($phone) > 5
|
||||
|
@ -17,7 +17,8 @@ class Mikrotik
|
||||
$iport = explode(":", $ip);
|
||||
return new RouterOS\Client($iport[0], $user, $pass, ($iport[1]) ? $iport[1] : null);
|
||||
} catch (Exception $e) {
|
||||
$ui->assign("error_meesage","Unable to connect to the router.<br>" . $e->getMessage());
|
||||
$ui->assign("error_title", "Mikrotik Connection Error");
|
||||
$ui->assign("error_message", "Unable to connect to the router.<br>" . $e->getMessage());
|
||||
$ui->display('router-error.tpl');
|
||||
die();
|
||||
}
|
||||
@ -72,46 +73,77 @@ class Mikrotik
|
||||
public static function setHotspotPlan($client, $name, $sharedusers, $rate)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ip hotspot user profile print .proplist=name',
|
||||
'/ip hotspot user profile print .proplist=.id',
|
||||
RouterOS\Query::where('name', $name)
|
||||
);
|
||||
$profileName = $client->sendSync($printRequest)->getProperty('name');
|
||||
|
||||
$profileID = $client->sendSync($printRequest)->getProperty('.id');
|
||||
if (empty($profileID)) {
|
||||
Mikrotik::addHotspotPlan($client, $name, $sharedusers, $rate);
|
||||
}else{
|
||||
$setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set');
|
||||
$client(
|
||||
$setRequest
|
||||
->setArgument('numbers', $profileName)
|
||||
->setArgument('numbers', $profileID)
|
||||
->setArgument('shared-users', $sharedusers)
|
||||
->setArgument('rate-limit', $rate)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function setHotspotExpiredPlan($client, $name, $pool)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ip hotspot user profile print .proplist=.id',
|
||||
RouterOS\Query::where('name', $name)
|
||||
);
|
||||
$profileID = $client->sendSync($printRequest)->getProperty('.id');
|
||||
if (empty($profileID)) {
|
||||
$addRequest = new RouterOS\Request('/ip/hotspot/user/profile/add');
|
||||
$client->sendSync(
|
||||
$addRequest
|
||||
->setArgument('name', $name)
|
||||
->setArgument('shared-users', 3)
|
||||
->setArgument('address-pool', $pool)
|
||||
->setArgument('rate-limit', '512K/512K')
|
||||
);
|
||||
}else{
|
||||
$setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set');
|
||||
$client(
|
||||
$setRequest
|
||||
->setArgument('numbers', $profileID)
|
||||
->setArgument('shared-users', 3)
|
||||
->setArgument('address-pool', $pool)
|
||||
->setArgument('rate-limit', '512K/512K')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function removeHotspotPlan($client, $name)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ip hotspot user profile print .proplist=name',
|
||||
'/ip hotspot user profile print .proplist=.id',
|
||||
RouterOS\Query::where('name', $name)
|
||||
);
|
||||
$profileName = $client->sendSync($printRequest)->getProperty('name');
|
||||
$profileID = $client->sendSync($printRequest)->getProperty('.id');
|
||||
|
||||
$removeRequest = new RouterOS\Request('/ip/hotspot/user/profile/remove');
|
||||
$client(
|
||||
$removeRequest
|
||||
->setArgument('numbers', $profileName)
|
||||
->setArgument('numbers', $profileID)
|
||||
);
|
||||
}
|
||||
|
||||
public static function removeHotspotUser($client, $username)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ip hotspot user print .proplist=name',
|
||||
'/ip hotspot user print .proplist=.id',
|
||||
RouterOS\Query::where('name', $username)
|
||||
);
|
||||
$userName = $client->sendSync($printRequest)->getProperty('name');
|
||||
$userID = $client->sendSync($printRequest)->getProperty('.id');
|
||||
$removeRequest = new RouterOS\Request('/ip/hotspot/user/remove');
|
||||
$client(
|
||||
$removeRequest
|
||||
->setArgument('numbers', $userName)
|
||||
->setArgument('numbers', $userID)
|
||||
);
|
||||
}
|
||||
|
||||
@ -179,7 +211,7 @@ class Mikrotik
|
||||
}
|
||||
}
|
||||
|
||||
public static function setHotspotUser($client, $user, $pass, $nuser = null)
|
||||
public static function setHotspotUser($client, $user, $pass)
|
||||
{
|
||||
$printRequest = new RouterOS\Request('/ip/hotspot/user/print');
|
||||
$printRequest->setArgument('.proplist', '.id');
|
||||
@ -192,6 +224,19 @@ class Mikrotik
|
||||
$client->sendSync($setRequest);
|
||||
}
|
||||
|
||||
public static function setHotspotUserPackage($client, $user, $plan)
|
||||
{
|
||||
$printRequest = new RouterOS\Request('/ip/hotspot/user/print');
|
||||
$printRequest->setArgument('.proplist', '.id');
|
||||
$printRequest->setQuery(RouterOS\Query::where('name', $user));
|
||||
$id = $client->sendSync($printRequest)->getProperty('.id');
|
||||
|
||||
$setRequest = new RouterOS\Request('/ip/hotspot/user/set');
|
||||
$setRequest->setArgument('numbers', $id);
|
||||
$setRequest->setArgument('profile', $plan);
|
||||
$client->sendSync($setRequest);
|
||||
}
|
||||
|
||||
public static function removeHotspotActiveUser($client, $username)
|
||||
{
|
||||
$onlineRequest = new RouterOS\Request('/ip/hotspot/active/print');
|
||||
@ -204,32 +249,16 @@ class Mikrotik
|
||||
$client->sendSync($removeRequest);
|
||||
}
|
||||
|
||||
public static function setHotspotLimitUptime($client, $username)
|
||||
{
|
||||
$printRequest = new RouterOS\Request('/ip/hotspot/user/print');
|
||||
$printRequest->setArgument('.proplist', '.id');
|
||||
$printRequest->setQuery(RouterOS\Query::where('name', $username));
|
||||
$id = $client->sendSync($printRequest)->getProperty('.id');
|
||||
|
||||
$setRequest = new RouterOS\Request('/ip/hotspot/user/set');
|
||||
$setRequest->setArgument('numbers', $id);
|
||||
$setRequest->setArgument('limit-uptime', '00:00:05');
|
||||
$client->sendSync($setRequest);
|
||||
}
|
||||
|
||||
public static function removePpoeUser($client, $username)
|
||||
{
|
||||
|
||||
$printRequest = new RouterOS\Request('/ppp/secret/print');
|
||||
$printRequest->setArgument('.proplist', '.id');
|
||||
//$printRequest->setArgument('.proplist', '.id');
|
||||
$printRequest->setQuery(RouterOS\Query::where('name', $username));
|
||||
$id = $client->sendSync($printRequest)->getProperty('.id');
|
||||
|
||||
$removeRequest = new RouterOS\Request('/ppp/secret/remove');
|
||||
$client(
|
||||
$removeRequest
|
||||
->setArgument('numbers', $id)
|
||||
);
|
||||
$removeRequest->setArgument('numbers', $id);
|
||||
$client->sendSync($removeRequest);
|
||||
}
|
||||
|
||||
public static function addPpoeUser($client, $plan, $customer)
|
||||
@ -250,7 +279,7 @@ class Mikrotik
|
||||
);
|
||||
}
|
||||
|
||||
public static function setPpoeUser($client, $user, $pass, $nuser = null)
|
||||
public static function setPpoeUser($client, $user, $pass)
|
||||
{
|
||||
$printRequest = new RouterOS\Request('/ppp/secret/print');
|
||||
$printRequest->setArgument('.proplist', '.id');
|
||||
@ -263,15 +292,16 @@ class Mikrotik
|
||||
$client->sendSync($setRequest);
|
||||
}
|
||||
|
||||
public static function disablePpoeUser($client, $username)
|
||||
public static function setPpoeUserPlan($client, $user, $plan)
|
||||
{
|
||||
$printRequest = new RouterOS\Request('/ppp/secret/print');
|
||||
$printRequest->setArgument('.proplist', '.id');
|
||||
$printRequest->setQuery(RouterOS\Query::where('name', $username));
|
||||
$printRequest->setQuery(RouterOS\Query::where('name', $user));
|
||||
$id = $client->sendSync($printRequest)->getProperty('.id');
|
||||
|
||||
$setRequest = new RouterOS\Request('/ppp/secret/disable');
|
||||
$setRequest = new RouterOS\Request('/ppp/secret/set');
|
||||
$setRequest->setArgument('numbers', $id);
|
||||
$setRequest->setArgument('profile', $plan);
|
||||
$client->sendSync($setRequest);
|
||||
}
|
||||
|
||||
@ -290,15 +320,15 @@ class Mikrotik
|
||||
public static function removePool($client, $name)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ip pool print .proplist=name',
|
||||
'/ip pool print .proplist=.id',
|
||||
RouterOS\Query::where('name', $name)
|
||||
);
|
||||
$poolName = $client->sendSync($printRequest)->getProperty('name');
|
||||
$poolID = $client->sendSync($printRequest)->getProperty('.id');
|
||||
|
||||
$removeRequest = new RouterOS\Request('/ip/pool/remove');
|
||||
$client(
|
||||
$removeRequest
|
||||
->setArgument('numbers', $poolName)
|
||||
->setArgument('numbers', $poolID)
|
||||
);
|
||||
}
|
||||
|
||||
@ -315,18 +345,18 @@ class Mikrotik
|
||||
public static function setPool($client, $name, $ip_address)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ip pool print .proplist=name',
|
||||
'/ip pool print .proplist=.id',
|
||||
RouterOS\Query::where('name', $name)
|
||||
);
|
||||
$poolName = $client->sendSync($printRequest)->getProperty('name');
|
||||
$poolID = $client->sendSync($printRequest)->getProperty('id');
|
||||
|
||||
if (empty($poolName)) {
|
||||
if (empty($poolID)) {
|
||||
self::addPool($client, $name, $ip_address);
|
||||
} else {
|
||||
$setRequest = new RouterOS\Request('/ip/pool/set');
|
||||
$client(
|
||||
$setRequest
|
||||
->setArgument('numbers', $poolName)
|
||||
->setArgument('numbers', $poolID)
|
||||
->setArgument('ranges', $ip_address)
|
||||
);
|
||||
}
|
||||
@ -348,17 +378,17 @@ class Mikrotik
|
||||
public static function setPpoePlan($client, $name, $pool, $rate)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ppp profile print .proplist=name',
|
||||
'/ppp profile print .proplist=.id',
|
||||
RouterOS\Query::where('name', $name)
|
||||
);
|
||||
$profileName = $client->sendSync($printRequest)->getProperty('name');
|
||||
if (empty($profileName)) {
|
||||
$profileID = $client->sendSync($printRequest)->getProperty('.id');
|
||||
if (empty($profileID)) {
|
||||
self::addPpoePlan($client, $name, $pool, $rate);
|
||||
} else {
|
||||
$setRequest = new RouterOS\Request('/ppp/profile/set');
|
||||
$client(
|
||||
$setRequest
|
||||
->setArgument('numbers', $profileName)
|
||||
->setArgument('numbers', $profileID)
|
||||
->setArgument('local-address', $pool)
|
||||
->setArgument('remote-address', $pool)
|
||||
->setArgument('rate-limit', $rate)
|
||||
@ -369,15 +399,15 @@ class Mikrotik
|
||||
public static function removePpoePlan($client, $name)
|
||||
{
|
||||
$printRequest = new RouterOS\Request(
|
||||
'/ppp profile print .proplist=name',
|
||||
'/ppp profile print .proplist=.id',
|
||||
RouterOS\Query::where('name', $name)
|
||||
);
|
||||
$profileName = $client->sendSync($printRequest)->getProperty('name');
|
||||
$profileID = $client->sendSync($printRequest)->getProperty('.id');
|
||||
|
||||
$removeRequest = new RouterOS\Request('/ppp/profile/remove');
|
||||
$client(
|
||||
$removeRequest
|
||||
->setArgument('numbers', $profileName)
|
||||
->setArgument('numbers', $profileID)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,6 @@
|
||||
**/
|
||||
|
||||
|
||||
use PEAR2\Net\RouterOS;
|
||||
|
||||
class Package
|
||||
{
|
||||
/**
|
||||
@ -19,7 +17,7 @@ class Package
|
||||
*/
|
||||
public static function rechargeUser($id_customer, $router_name, $plan_id, $gateway, $channel)
|
||||
{
|
||||
global $_c, $_L, $_notifmsg;
|
||||
global $_c;
|
||||
$date_now = date("Y-m-d H:i:s");
|
||||
$date_only = date("Y-m-d");
|
||||
$time_only = date("H:i:s");
|
||||
@ -49,22 +47,27 @@ class Package
|
||||
$t->type = "Balance";
|
||||
$t->save();
|
||||
|
||||
$balance_before = $c['balance'];
|
||||
Balance::plus($id_customer, $p['price']);
|
||||
$balance = $c['balance'] + $p['price'];
|
||||
|
||||
$textInvoice = Lang::getNotifText('invoice_balance');
|
||||
$textInvoice = str_replace('[[company_name]]', $_c['CompanyName'], $textInvoice);
|
||||
$textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
|
||||
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
|
||||
$textInvoice = str_replace('[[invoice]]', $inv, $textInvoice);
|
||||
$textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_only)) . " " . $time, $textInvoice);
|
||||
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
|
||||
$textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
|
||||
$textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
|
||||
$textInvoice = str_replace('[[type]]', 'Balance', $textInvoice);
|
||||
$textInvoice = str_replace('[[plan_name]]', $p['name_plan'], $textInvoice);
|
||||
$textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($p['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
|
||||
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($p['price']), $textInvoice);
|
||||
$textInvoice = str_replace('[[name]]', $c['fullname'], $textInvoice);
|
||||
$textInvoice = str_replace('[[user_name]]', $c['username'], $textInvoice);
|
||||
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
|
||||
$textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
|
||||
$textInvoice = str_replace('[[balance_before]]', Lang::moneyFormat($balance_before), $textInvoice);
|
||||
$textInvoice = str_replace('[[balance]]', Lang::moneyFormat($balance), $textInvoice);
|
||||
|
||||
if ($_c['user_notification_payment'] == 'sms') {
|
||||
Message::sendSMS($c['phonenumber'], $textInvoice);
|
||||
@ -99,15 +102,19 @@ class Package
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
}
|
||||
|
||||
if ($b['namebp'] == $p['name_plan']) {
|
||||
if ($b['namebp'] == $p['name_plan'] && $b['status'] == 'on') {
|
||||
// if it same internet plan, expired will extend
|
||||
if ($p['validity_unit'] == 'Months') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = $b['time'];
|
||||
} else if ($p['validity_unit'] == 'Days') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' days'));
|
||||
$time = $b['time'];
|
||||
} else if ($p['validity_unit'] == 'Hrs') {
|
||||
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime($b['expiration'] . ' ' . $b['time'] . ' +' . $p['validity'] . ' hours')));
|
||||
$date_exp = $datetime[0];
|
||||
@ -150,7 +157,10 @@ class Package
|
||||
} else {
|
||||
if (!$_c['radius_mode']) {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
}
|
||||
|
||||
@ -196,16 +206,20 @@ class Package
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
|
||||
|
||||
if ($b['namebp'] == $p['name_plan']) {
|
||||
if ($b['namebp'] == $p['name_plan'] && $b['status'] == 'on') {
|
||||
// if it same internet plan, expired will extend
|
||||
if ($p['validity_unit'] == 'Months') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = $b['time'];
|
||||
} else if ($p['validity_unit'] == 'Days') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' days'));
|
||||
$time = $b['time'];
|
||||
} else if ($p['validity_unit'] == 'Hrs') {
|
||||
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime($b['expiration'] . ' ' . $b['time'] . ' +' . $p['validity'] . ' hours')));
|
||||
$date_exp = $datetime[0];
|
||||
@ -250,6 +264,8 @@ class Package
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
|
||||
@ -297,15 +313,16 @@ class Package
|
||||
$textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
|
||||
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
|
||||
$textInvoice = str_replace('[[invoice]]', $in['invoice'], $textInvoice);
|
||||
$textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_now)) . " " . $time, $textInvoice);
|
||||
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
|
||||
$textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
|
||||
$textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
|
||||
$textInvoice = str_replace('[[type]]', $in['type'], $textInvoice);
|
||||
$textInvoice = str_replace('[[plan_name]]', $in['plan_name'], $textInvoice);
|
||||
$textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($in['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
|
||||
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($in['price']), $textInvoice);
|
||||
$textInvoice = str_replace('[[name]]', $c['fullname'], $textInvoice);
|
||||
$textInvoice = str_replace('[[user_name]]', $in['username'], $textInvoice);
|
||||
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
|
||||
$textInvoice = str_replace('[[expired_date]]', date($_c['date_format'], strtotime($in['expiration'])) . " " . $in['time'], $textInvoice);
|
||||
$textInvoice = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($in['expiration'], $in['time']), $textInvoice);
|
||||
$textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
|
||||
|
||||
if ($_c['user_notification_payment'] == 'sms') {
|
||||
@ -329,6 +346,8 @@ class Package
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
}
|
||||
} else {
|
||||
@ -336,6 +355,8 @@ class Package
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
}
|
||||
}
|
||||
@ -345,6 +366,8 @@ class Package
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
} else {
|
||||
@ -352,6 +375,8 @@ class Package
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
}
|
||||
|
136
system/boot.php
136
system/boot.php
@ -4,6 +4,33 @@
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
|
||||
**/
|
||||
|
||||
|
||||
// on some server, it getting error because of slash is backwards
|
||||
function _autoloader($class)
|
||||
{
|
||||
if (strpos($class, '_') !== false) {
|
||||
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
} else {
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('_autoloader');
|
||||
|
||||
function r2($to, $ntype = 'e', $msg = '')
|
||||
{
|
||||
if ($msg == '') {
|
||||
@ -46,33 +73,52 @@ function _get($param, $defvalue = '')
|
||||
return safedata($_GET[$param]);
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
||||
require_once File::pathFixer('system/orm.php');
|
||||
|
||||
require('system/orm.php');
|
||||
|
||||
ORM::configure("mysql:host=$db_host;dbname=$db_name");
|
||||
ORM::configure('username', $db_user);
|
||||
ORM::configure('password', $db_password);
|
||||
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
|
||||
ORM::configure('return_result_sets', true);
|
||||
if ($_app_stage != 'Live') {
|
||||
ORM::configure("mysql:host=$db_host;dbname=$db_name");
|
||||
ORM::configure('username', $db_user);
|
||||
ORM::configure('password', $db_password);
|
||||
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
|
||||
ORM::configure('return_result_sets', true);
|
||||
if ($_app_stage != 'Live') {
|
||||
ORM::configure('logging', true);
|
||||
}
|
||||
}
|
||||
|
||||
$result = ORM::for_table('tbl_appconfig')->find_many();
|
||||
foreach ($result as $value) {
|
||||
$result = ORM::for_table('tbl_appconfig')->find_many();
|
||||
foreach ($result as $value) {
|
||||
$config[$value['setting']] = $value['value'];
|
||||
}
|
||||
}
|
||||
|
||||
date_default_timezone_set($config['timezone']);
|
||||
$_c = $config;
|
||||
date_default_timezone_set($config['timezone']);
|
||||
$_c = $config;
|
||||
|
||||
if ($config['radius_mode']) {
|
||||
// check if proxy setup in database
|
||||
if (empty($http_proxy) && !empty($config['http_proxy'])) {
|
||||
$http_proxy = $config['http_proxy'];
|
||||
if (empty($http_proxyauth) && !empty($config['http_proxyauth'])) {
|
||||
$http_proxyauth = $config['http_proxyauth'];
|
||||
}
|
||||
}
|
||||
if ($config['radius_mode']) {
|
||||
ORM::configure("mysql:host=$radius_host;dbname=$radius_name", null, 'radius');
|
||||
ORM::configure('username', $radius_user, 'radius');
|
||||
ORM::configure('password', $radius_password, 'radius');
|
||||
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'), 'radius');
|
||||
ORM::configure('return_result_sets', true, 'radius');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$ui = new Smarty();
|
||||
$ui->setTemplateDir(['custom' => File::pathFixer('ui/ui_custom/'), 'default' => File::pathFixer('ui/ui/')]);
|
||||
$ui->assign('_url', APP_URL . '/index.php?_route=');
|
||||
$ui->setCompileDir(File::pathFixer('ui/compiled/'));
|
||||
$ui->setConfigDir(File::pathFixer('ui/conf/'));
|
||||
$ui->setCacheDir(File::pathFixer('ui/cache/'));
|
||||
$ui->assign("error_title", "PHPNuxBill Crash");
|
||||
$ui->assign("error_message", $e->getMessage());
|
||||
$ui->display('router-error.tpl');
|
||||
die();
|
||||
}
|
||||
|
||||
function _notify($msg, $type = 'e')
|
||||
@ -81,15 +127,15 @@ function _notify($msg, $type = 'e')
|
||||
$_SESSION['notify'] = $msg;
|
||||
}
|
||||
|
||||
$lan_file = 'system/lan/' . $config['language'] . '/common.lan.php';
|
||||
$lan_file = File::pathFixer('system/lan/' . $config['language'] . '/common.lan.php');
|
||||
require($lan_file);
|
||||
$ui = new Smarty();
|
||||
$ui->setTemplateDir(['custom' => 'ui/ui_custom/', 'default' => 'ui/ui/']);
|
||||
$ui->addTemplateDir('system/paymentgateway/ui/', 'pg');
|
||||
$ui->addTemplateDir('system/plugin/ui/', 'plugin');
|
||||
$ui->setCompileDir('ui/compiled/');
|
||||
$ui->setConfigDir('ui/conf/');
|
||||
$ui->setCacheDir('ui/cache/');
|
||||
$ui->setTemplateDir(['custom' => File::pathFixer('ui/ui_custom/'), 'default' => File::pathFixer('ui/ui/')]);
|
||||
$ui->addTemplateDir(File::pathFixer('system/paymentgateway/ui/'), 'pg');
|
||||
$ui->addTemplateDir(File::pathFixer('system/plugin/ui/'), 'plugin');
|
||||
$ui->setCompileDir(File::pathFixer('ui/compiled/'));
|
||||
$ui->setConfigDir(File::pathFixer('ui/conf/'));
|
||||
$ui->setCacheDir(File::pathFixer('ui/cache/'));
|
||||
$ui->assign('app_url', APP_URL);
|
||||
$ui->assign('_domain', str_replace('www.', '', parse_url(APP_URL, PHP_URL_HOST)));
|
||||
define('U', APP_URL . '/index.php?_route=');
|
||||
@ -129,40 +175,16 @@ if (isset($_SESSION['notify'])) {
|
||||
include "autoload/Hookers.php";
|
||||
|
||||
// notification message
|
||||
if(file_exists("system/uploads/notifications.json")){
|
||||
$_notifmsg =json_decode(file_get_contents('system/uploads/notifications.json'), true);
|
||||
if (file_exists(File::pathFixer("system/uploads/notifications.json"))) {
|
||||
$_notifmsg = json_decode(file_get_contents(File::pathFixer('system/uploads/notifications.json')), true);
|
||||
}
|
||||
$_notifmsg_default = json_decode(file_get_contents('system/uploads/notifications.default.json'), true);
|
||||
$_notifmsg_default = json_decode(file_get_contents(File::pathFixer('system/uploads/notifications.default.json')), true);
|
||||
|
||||
//register all plugin
|
||||
foreach (glob("system/plugin/*.php") as $filename) {
|
||||
foreach (glob(File::pathFixer("system/plugin/*.php")) as $filename) {
|
||||
include $filename;
|
||||
}
|
||||
|
||||
// on some server, it getting error because of slash is backwards
|
||||
function _autoloader($class)
|
||||
{
|
||||
if (strpos($class, '_') !== false) {
|
||||
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
} else {
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('_autoloader');
|
||||
|
||||
function _auth($login = true)
|
||||
{
|
||||
@ -281,8 +303,10 @@ $handler = $routes[0];
|
||||
if ($handler == '') {
|
||||
$handler = 'default';
|
||||
}
|
||||
$sys_render = 'system/controllers/' . $handler . '.php';
|
||||
if (file_exists($sys_render)) {
|
||||
try {
|
||||
|
||||
$sys_render = File::pathFixer('system/controllers/' . $handler . '.php');
|
||||
if (file_exists($sys_render)) {
|
||||
$menus = array();
|
||||
// "name" => $name,
|
||||
// "admin" => $admin,
|
||||
@ -309,6 +333,12 @@ if (file_exists($sys_render)) {
|
||||
}
|
||||
unset($menus, $menu_registered);
|
||||
include($sys_render);
|
||||
} else {
|
||||
} else {
|
||||
r2(U . 'dashboard', 'e', 'not found');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$ui->assign("error_title", "PHPNuxBill Crash");
|
||||
$ui->assign("error_message", $e->getMessage());
|
||||
$ui->display('router-error.tpl');
|
||||
die();
|
||||
}
|
||||
|
@ -36,6 +36,18 @@ switch ($action) {
|
||||
|
||||
$ui->display('autoload.tpl');
|
||||
break;
|
||||
case 'customer_is_active':
|
||||
$d = ORM::for_table('tbl_user_recharges')->where('customer_id', $routes['2'])->findOne();
|
||||
if ($d) {
|
||||
if ($d['status'] == 'on') {
|
||||
die('<span class="label label-success" title="Expired ' . Lang::dateAndTimeFormat($d['expiration'], $d['time']) . '">'.$d['namebp'].'</span>');
|
||||
} else {
|
||||
die('<span class="label label-danger" title="Expired ' . Lang::dateAndTimeFormat($d['expiration'], $d['time']) . '">'.$d['namebp'].'</span>');
|
||||
}
|
||||
} else {
|
||||
die('<span class="label label-danger">•</span>');
|
||||
}
|
||||
break;
|
||||
case 'customer_select2':
|
||||
|
||||
$s = addslashes(_get('s'));
|
||||
|
@ -12,9 +12,6 @@ $action = $routes['1'];
|
||||
$admin = Admin::_info();
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
use PEAR2\Net\RouterOS;
|
||||
|
||||
require_once 'system/autoload/PEAR2/Autoload.php';
|
||||
|
||||
if ($admin['user_type'] != 'Admin' and $admin['user_type'] != 'Sales') {
|
||||
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
|
||||
@ -34,7 +31,8 @@ switch ($action) {
|
||||
->order_by_desc('id')->find_many();
|
||||
} else {
|
||||
$paginator = Paginator::bootstrap('tbl_customers');
|
||||
$d = ORM::for_table('tbl_customers')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$d = ORM::for_table('tbl_customers')
|
||||
->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
}
|
||||
|
||||
$ui->assign('search', htmlspecialchars($search));
|
||||
@ -47,13 +45,67 @@ switch ($action) {
|
||||
run_hook('view_add_customer'); #HOOK
|
||||
$ui->display('customers-add.tpl');
|
||||
break;
|
||||
|
||||
case 'recharge':
|
||||
$id_customer = $routes['2'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
|
||||
if ($b) {
|
||||
$mikrotik = Mikrotik::info($b['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
if (Package::rechargeUser($id_customer, $b['routers'], $b['plan_id'], "Recharge", $admin['fullname'])) {
|
||||
r2(U . 'customers/view/' . $id_customer, 's', 'Success Recharge Customer');
|
||||
} else {
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Customer plan is inactive');
|
||||
}
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
|
||||
case 'deactivate':
|
||||
$id_customer = $routes['2'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
|
||||
if ($b) {
|
||||
$mikrotik = Mikrotik::info($b['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
if ($b['type'] == 'Hotspot') {
|
||||
Mikrotik::removeHotspotUser($client, $b['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $b['username']);
|
||||
} else if ($b['type'] == 'PPPOE') {
|
||||
Mikrotik::removePpoeUser($client, $b['username']);
|
||||
Mikrotik::removePpoeActive($client, $b['username']);
|
||||
}
|
||||
$b->status = 'off';
|
||||
$b->expiration = date('Y-m-d');
|
||||
$b->time = date('H:i:s');
|
||||
$b->save();
|
||||
r2(U . 'customers/view/' . $id_customer, 's', 'Success deactivate customer to Mikrotik');
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
|
||||
break;
|
||||
case 'sync':
|
||||
$id_customer = $routes['2'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('status', 'on')->find_one();
|
||||
if ($b) {
|
||||
$mikrotik = Mikrotik::info($b['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
$c = ORM::for_table('tbl_customers')->find_one($id_customer);
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->where('enabled', '1')->find_one();
|
||||
if ($p) {
|
||||
if ($b['type'] == 'Hotspot') {
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
} else if ($b['type'] == 'PPPOE') {
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 's', 'Success sync customer to Mikrotik');
|
||||
} else {
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Customer plan is inactive');
|
||||
}
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
|
||||
break;
|
||||
case 'viewu':
|
||||
$customer = ORM::for_table('tbl_customers')->where('username', $routes['2'])->find_one();
|
||||
case 'view':
|
||||
$id = $routes['2'];
|
||||
run_hook('view_customer'); #HOOK
|
||||
if(!$customer){
|
||||
if (!$customer) {
|
||||
$customer = ORM::for_table('tbl_customers')->find_one($id);
|
||||
}
|
||||
if ($customer) {
|
||||
@ -81,7 +133,7 @@ switch ($action) {
|
||||
// $ui->assign('paginator', $paginator);
|
||||
$ui->assign('activation', $activation);
|
||||
}
|
||||
$package = ORM::for_table('tbl_user_recharges')->where('username',$customer['username'])->find_one();
|
||||
$package = ORM::for_table('tbl_user_recharges')->where('username', $customer['username'])->find_one();
|
||||
$ui->assign('package', $package);
|
||||
$ui->assign('v', $v);
|
||||
$ui->assign('d', $customer);
|
||||
@ -113,14 +165,14 @@ switch ($action) {
|
||||
if ($c['type'] == 'Hotspot') {
|
||||
if (!$config['radius_mode']) {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotUser($client, $d['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $d['username']);
|
||||
}
|
||||
} else {
|
||||
if (!$config['radius_mode']) {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $d['username']);
|
||||
Mikrotik::removePpoeActive($client, $d['username']);
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
@ -1,13 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
**/
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
**/
|
||||
_admin();
|
||||
$ui->assign('_title', $_L['Dashboard']);
|
||||
$admin = Admin::_info();
|
||||
$ui->assign('_admin', $admin);
|
||||
if(!in_array($admin['user_type'],['Admin','Sales'])){
|
||||
r2(U."home",'e',$_L['Do_Not_Access']);
|
||||
if (!in_array($admin['user_type'], ['Admin', 'Sales'])) {
|
||||
r2(U . "home", 'e', $_L['Do_Not_Access']);
|
||||
}
|
||||
|
||||
$fdate = date('Y-m-01');
|
||||
@ -17,59 +18,67 @@ $first_day_month = date('Y-m-01');
|
||||
$mdate = date('Y-m-d');
|
||||
$month_n = date('n');
|
||||
|
||||
$iday = ORM::for_table('tbl_transactions')->where('recharged_on',$mdate)->sum('price');
|
||||
if($iday == ''){
|
||||
$iday = ORM::for_table('tbl_transactions')->where('recharged_on', $mdate)->sum('price');
|
||||
if ($iday == '') {
|
||||
$iday = '0.00';
|
||||
}
|
||||
$ui->assign('iday',$iday);
|
||||
$ui->assign('iday', $iday);
|
||||
|
||||
$imonth = ORM::for_table('tbl_transactions')->where_gte('recharged_on',$first_day_month)->where_lte('recharged_on',$mdate)->sum('price');
|
||||
if($imonth == ''){
|
||||
$imonth = ORM::for_table('tbl_transactions')->where_gte('recharged_on', $first_day_month)->where_lte('recharged_on', $mdate)->sum('price');
|
||||
if ($imonth == '') {
|
||||
$imonth = '0.00';
|
||||
}
|
||||
$ui->assign('imonth',$imonth);
|
||||
$ui->assign('imonth', $imonth);
|
||||
|
||||
$u_act = ORM::for_table('tbl_user_recharges')->where('status','on')->count();
|
||||
if($u_act == ''){
|
||||
$u_act = ORM::for_table('tbl_user_recharges')->where('status', 'on')->count();
|
||||
if (empty($u_act)) {
|
||||
$u_act = '0';
|
||||
}
|
||||
$ui->assign('u_act',$u_act);
|
||||
$ui->assign('u_act', $u_act);
|
||||
|
||||
$u_all = ORM::for_table('tbl_user_recharges')->count();
|
||||
if($u_all == ''){
|
||||
if (empty($u_all)) {
|
||||
$u_all = '0';
|
||||
}
|
||||
$ui->assign('u_all',$u_all);
|
||||
$ui->assign('u_all', $u_all);
|
||||
|
||||
|
||||
$c_all = ORM::for_table('tbl_customers')->count();
|
||||
if (empty($c_all)) {
|
||||
$c_all = '0';
|
||||
}
|
||||
$ui->assign('c_all', $c_all);
|
||||
|
||||
//user expire
|
||||
$expire = ORM::for_table('tbl_user_recharges')->where('expiration',$mdate)->order_by_desc('id')->find_many();
|
||||
$ui->assign('expire',$expire);
|
||||
$expire = ORM::for_table('tbl_user_recharges')->where('expiration', $mdate)->order_by_desc('id')->find_many();
|
||||
$ui->assign('expire', $expire);
|
||||
|
||||
//activity log
|
||||
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->find_many();
|
||||
$ui->assign('dlog',$dlog);
|
||||
$ui->assign('dlog', $dlog);
|
||||
$log = ORM::for_table('tbl_logs')->count();
|
||||
$ui->assign('log',$log);
|
||||
$ui->assign('log', $log);
|
||||
|
||||
// Count stock
|
||||
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
|
||||
$plans = array();
|
||||
$stocks = array("used"=>0,"unused"=>0);
|
||||
$stocks = array("used" => 0, "unused" => 0);
|
||||
$n = 0;
|
||||
foreach($tmp as $plan){
|
||||
foreach ($tmp as $plan) {
|
||||
$plans[$n]['name_plan'] = $plan['name_plan'];
|
||||
$plans[$n]['unused'] = ORM::for_table('tbl_voucher')
|
||||
->where('id_plan',$plan['id'])
|
||||
->where('status',0)->count();;
|
||||
->where('id_plan', $plan['id'])
|
||||
->where('status', 0)->count();;
|
||||
$stocks["unused"] += $plans[$n]['unused'];
|
||||
$plans[$n]['used'] = ORM::for_table('tbl_voucher')
|
||||
->where('id_plan',$plan['id'])
|
||||
->where('status',1)->count();;
|
||||
->where('id_plan', $plan['id'])
|
||||
->where('status', 1)->count();;
|
||||
$stocks["used"] += $plans[$n]['used'];
|
||||
$n++;
|
||||
}
|
||||
|
||||
$ui->assign('stocks',$stocks);
|
||||
$ui->assign('plans',$plans);
|
||||
$ui->assign('stocks', $stocks);
|
||||
$ui->assign('plans', $plans);
|
||||
|
||||
run_hook('view_dashboard'); #HOOK
|
||||
$ui->display('dashboard.tpl');
|
@ -25,7 +25,7 @@ if (_post('send') == 'balance') {
|
||||
if ($user['balance'] < $balance) {
|
||||
r2(U . 'home', 'd', Lang::T('insufficient balance'));
|
||||
}
|
||||
if (!empty($config['minimum_transfer']) && intval($balance) <= intval($config['minimum_transfer'])) {
|
||||
if (!empty($config['minimum_transfer']) && intval($balance) < intval($config['minimum_transfer'])) {
|
||||
r2(U . 'home', 'd', Lang::T('Minimum Transfer') . ' ' . Lang::moneyFormat($config['minimum_transfer']));
|
||||
}
|
||||
if ($user['username'] == $target['username']) {
|
||||
@ -66,13 +66,23 @@ if (_post('send') == 'balance') {
|
||||
$d->pg_url_payment = 'balance';
|
||||
$d->status = 2;
|
||||
$d->save();
|
||||
Message::sendBalanceNotification($user['phonenumber'], $target['fullname'] . ' (' . $target['username'] . ')', $balance, Lang::getNotifText('balance_send'), $config['user_notification_payment']);
|
||||
Message::sendBalanceNotification($target['phonenumber'], $user['fullname'] . ' (' . $user['username'] . ')', $balance, Lang::getNotifText('balance_received'), $config['user_notification_payment']);
|
||||
Message::sendBalanceNotification($user['phonenumber'], $target['fullname'] . ' (' . $target['username'] . ')', $balance, ($user['balance'] - $balance), Lang::getNotifText('balance_send'), $config['user_notification_payment']);
|
||||
Message::sendBalanceNotification($target['phonenumber'], $user['fullname'] . ' (' . $user['username'] . ')', $balance, ($target['balance'] + $balance), Lang::getNotifText('balance_received'), $config['user_notification_payment']);
|
||||
Message::sendTelegram("#u$user[username] send balance to #u$target[username] \n" . Lang::moneyFormat($balance));
|
||||
r2(U . 'home', 's', Lang::T('Sending balance success'));
|
||||
}
|
||||
} else {
|
||||
r2(U . 'home', 'd', 'Failed, balance is not available');
|
||||
r2(U . 'home', 'd', Lang::T('Failed, balance is not available'));
|
||||
}
|
||||
} else if (_post('send') == 'plan') {
|
||||
$active = ORM::for_table('tbl_user_recharges')
|
||||
->where('username', _post('username'))
|
||||
->find_one();
|
||||
$router = ORM::for_table('tbl_routers')->where('name', $active['routers'])->find_one();
|
||||
if ($router) {
|
||||
r2(U . "order/send/$router[id]/$active[plan_id]&u=" . trim(_post('username')), 's', Lang::T('Review package before recharge'));
|
||||
} else {
|
||||
r2(U . 'package/order', 'w', Lang::T('Your friend do not have active package'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
if (empty($trx)) {
|
||||
r2(U . "order", 'e', Lang::T("Transaction Not found"));
|
||||
r2(U . "order/package", 'e', Lang::T("Transaction Not found"));
|
||||
}
|
||||
$router = ORM::for_table('tbl_routers')->find_one($trx['routers_id']);
|
||||
$plan = ORM::for_table('tbl_plans')->find_one($trx['plan_id']);
|
||||
@ -111,8 +111,8 @@ switch ($action) {
|
||||
$ui->display('user-orderView.tpl');
|
||||
break;
|
||||
case 'pay':
|
||||
if ($_c['enable_balance'] != 'yes'){
|
||||
r2(U . "order", 'e', Lang::T("Balance not enabled"));
|
||||
if ($_c['enable_balance'] != 'yes' && $config['allow_balance_transfer'] != 'yes') {
|
||||
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
|
||||
}
|
||||
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3']);
|
||||
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
|
||||
@ -130,10 +130,91 @@ switch ($action) {
|
||||
"\nRouter: " . $router_name .
|
||||
"\nPrice: " . $p['price']);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
echo "no renewall | plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||
}
|
||||
break;
|
||||
case 'send':
|
||||
if ($_c['enable_balance'] != 'yes') {
|
||||
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
|
||||
}
|
||||
$ui->assign('_title', Lang::T('Buy for friend'));
|
||||
$ui->assign('_system_menu', 'package');
|
||||
$plan = ORM::for_table('tbl_plans')->find_one($routes['3']);
|
||||
if (empty($plan)) {
|
||||
r2(U . "order/package", 'e', Lang::T("Plan Not found"));
|
||||
}
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'plan') {
|
||||
$target = ORM::for_table('tbl_customers')->where('username', _post('username'))->find_one();
|
||||
if (!$target) {
|
||||
r2(U . 'home', 'd', Lang::T('Username not found'));
|
||||
}
|
||||
if ($user['balance'] < $plan['price']) {
|
||||
r2(U . 'home', 'd', Lang::T('insufficient balance'));
|
||||
}
|
||||
if ($user['username'] == $target['username']) {
|
||||
r2(U . "order/pay/$routes[2]/$routes[3]", 's', '^_^ v');
|
||||
}
|
||||
$active = ORM::for_table('tbl_user_recharges')
|
||||
->where('username', _post('username'))
|
||||
->where('status', 'on')
|
||||
->find_one();
|
||||
|
||||
if ($active && $active['plan_id'] != $plan['id']) {
|
||||
r2(U . "order/package", 'e', Lang::T("Target has active plan, different with current plant.")." [ <b>$active[namebp]</b> ]");
|
||||
}
|
||||
if (Package::rechargeUser($target['id'], $plan['routers'], $plan['id'], $user['fullname'], 'Balance')) {
|
||||
// if success, then get the balance
|
||||
Balance::min($user['id'], $plan['price']);
|
||||
//sender
|
||||
$d = ORM::for_table('tbl_payment_gateway')->create();
|
||||
$d->username = $user['username'];
|
||||
$d->gateway = $target['username'];
|
||||
$d->plan_id = $plan['id'];
|
||||
$d->plan_name = $plan['name_plan'];
|
||||
$d->routers_id = $routes['2'];
|
||||
$d->routers = $plan['routers'];
|
||||
$d->price = $plan['price'];
|
||||
$d->payment_method = "Balance";
|
||||
$d->payment_channel = "Send Plan";
|
||||
$d->created_date = date('Y-m-d H:i:s');
|
||||
$d->paid_date = date('Y-m-d H:i:s');
|
||||
$d->expired_date = date('Y-m-d H:i:s');
|
||||
$d->pg_url_payment = 'balance';
|
||||
$d->status = 2;
|
||||
$d->save();
|
||||
$trx_id = $d->id();
|
||||
//receiver
|
||||
$d = ORM::for_table('tbl_payment_gateway')->create();
|
||||
$d->username = $target['username'];
|
||||
$d->gateway = $user['username'];
|
||||
$d->plan_id = $plan['id'];
|
||||
$d->plan_name = $plan['name_plan'];
|
||||
$d->routers_id = $routes['2'];
|
||||
$d->routers = $plan['routers'];
|
||||
$d->price = $plan['price'];
|
||||
$d->payment_method = "Balance";
|
||||
$d->payment_channel = "Received Plan";
|
||||
$d->created_date = date('Y-m-d H:i:s');
|
||||
$d->paid_date = date('Y-m-d H:i:s');
|
||||
$d->expired_date = date('Y-m-d H:i:s');
|
||||
$d->pg_url_payment = 'balance';
|
||||
$d->status = 2;
|
||||
$d->save();
|
||||
r2(U . "order/view/$trx_id", 's', Lang::T("Success to send package"));
|
||||
} else {
|
||||
r2(U . "order/package", 'e', Lang::T("Failed to Send package"));
|
||||
Message::sendTelegram("Send Package with Balance Failed\n\n#u$user[username] #send \n" . $plan['name_plan'] .
|
||||
"\nRouter: " . $plan['routers'] .
|
||||
"\nPrice: " . $plan['price']);
|
||||
}
|
||||
}
|
||||
|
||||
$ui->assign('username', $_GET['u']);
|
||||
$ui->assign('router', $router);
|
||||
$ui->assign('plan', $plan);
|
||||
$ui->display('user-sendPlan.tpl');
|
||||
break;
|
||||
case 'buy':
|
||||
if (strpos($user['email'], '@') === false) {
|
||||
r2(U . 'accounts/profile', 'e', Lang::T("Please enter your email address"));
|
||||
@ -147,9 +228,9 @@ switch ($action) {
|
||||
run_hook('customer_buy_plan'); #HOOK
|
||||
include 'system/paymentgateway/' . $config['payment_gateway'] . '.php';
|
||||
call_user_func($config['payment_gateway'] . '_validate_config');
|
||||
if ($routes['2']>0) {
|
||||
if ($routes['2'] > 0) {
|
||||
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
|
||||
}else{
|
||||
} else {
|
||||
$router['id'] = 0;
|
||||
$router['name'] = 'balance';
|
||||
}
|
||||
@ -205,5 +286,5 @@ switch ($action) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
r2(U . "order/package/", 's','');
|
||||
r2(U . "order/package/", 's', '');
|
||||
}
|
||||
|
@ -21,9 +21,14 @@ if ($admin['user_type'] != 'Admin') {
|
||||
|
||||
$cache = File::pathFixer('system/cache/plugin_repository.json');
|
||||
if (file_exists($cache) && time() - filemtime($cache) < (24 * 60 * 60)) {
|
||||
$json = json_decode(file_get_contents($cache), true);
|
||||
$txt = file_get_contents($cache);
|
||||
$json = json_decode($txt, true);
|
||||
if(empty($json['plugins']) && empty($json['payment_gateway'])){
|
||||
unlink($cache);
|
||||
r2(U . 'dashboard', 'd', $txt);
|
||||
}
|
||||
} else {
|
||||
$data = file_get_contents($plugin_repository);
|
||||
$data = Http::getData($plugin_repository);
|
||||
file_put_contents($cache, $data);
|
||||
$json = json_decode($data, true);
|
||||
}
|
||||
|
@ -15,9 +15,6 @@ if ($admin['user_type'] != 'Admin') {
|
||||
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
|
||||
}
|
||||
|
||||
use PEAR2\Net\RouterOS;
|
||||
|
||||
require_once 'system/autoload/PEAR2/Autoload.php';
|
||||
|
||||
switch ($action) {
|
||||
case 'list':
|
||||
@ -73,6 +70,17 @@ switch ($action) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'sync':
|
||||
$pools = ORM::for_table('tbl_pool')->find_many();
|
||||
$log = '';
|
||||
foreach($pools as $pool){
|
||||
$mikrotik = Mikrotik::info($pool['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::addPool($client, $pool['pool_name'], $pool['range_ip']);
|
||||
$log .= 'DONE: '.$pool['pool_name'].': '.$pool['range_ip'].'<br>';
|
||||
}
|
||||
r2(U . 'pool/list', 's', $log);
|
||||
break;
|
||||
case 'add-post':
|
||||
$name = _post('name');
|
||||
$ip_address = _post('ip_address');
|
||||
|
@ -40,9 +40,31 @@ EOT;
|
||||
require_once 'system/autoload/PEAR2/Autoload.php';
|
||||
|
||||
switch ($action) {
|
||||
case 'sync':
|
||||
set_time_limit(-1);
|
||||
$plans = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
|
||||
echo count($plans);
|
||||
$log = '';
|
||||
$router = '';
|
||||
foreach ($plans as $plan) {
|
||||
if ($router != $plan['routers']) {
|
||||
$mikrotik = Mikrotik::info($plan['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
$router = $plan['routers'];
|
||||
}
|
||||
$p = ORM::for_table('tbl_plans')->findOne($plan['plan_id']);
|
||||
$c = ORM::for_table('tbl_customers')->findOne($plan['customer_id']);
|
||||
if ($plan['type'] == 'Hotspot') {
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
} else if ($plan['type'] == 'PPPOE') {
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
$log .= "DONE : $plan[username], $plan[namebp], $plan[type], $plan[routers]<br>";
|
||||
}
|
||||
r2(U . 'prepaid/list', 's', $log);
|
||||
case 'list':
|
||||
$ui->assign('xfooter', '<script type="text/javascript" src="ui/lib/c/prepaid.js"></script>');
|
||||
|
||||
$ui->assign('_title', $_L['Customers']);
|
||||
$username = _post('username');
|
||||
if ($username != '') {
|
||||
$paginator = Paginator::bootstrap('tbl_user_recharges', 'username', '%' . $username . '%');
|
||||
@ -65,6 +87,9 @@ switch ($action) {
|
||||
$ui->assign('p', $p);
|
||||
$r = ORM::for_table('tbl_routers')->where('enabled', '1')->find_many();
|
||||
$ui->assign('r', $r);
|
||||
if (isset($routes['2']) && !empty($routes['2'])) {
|
||||
$ui->assign('cust', ORM::for_table('tbl_customers')->find_one($routes['2']));
|
||||
}
|
||||
run_hook('view_recharge'); #HOOK
|
||||
$ui->display('recharge.tpl');
|
||||
break;
|
||||
@ -146,14 +171,16 @@ switch ($action) {
|
||||
if ($d['type'] == 'Hotspot') {
|
||||
if (!$config['radius_mode']) {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotUser($client, $d['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $d['username']);
|
||||
}
|
||||
|
||||
$d->delete();
|
||||
} else {
|
||||
if (!$config['radius_mode']) {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removePpoeUser($client, $d['username']);
|
||||
Mikrotik::removePpoeActive($client, $d['username']);
|
||||
}
|
||||
$d->delete();
|
||||
}
|
||||
|
@ -21,6 +21,68 @@ use PEAR2\Net\RouterOS;
|
||||
require_once 'system/autoload/PEAR2/Autoload.php';
|
||||
|
||||
switch ($action) {
|
||||
case 'sync':
|
||||
set_time_limit(-1);
|
||||
if ($routes['2'] == 'hotspot') {
|
||||
$plans = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'Hotspot')->where('tbl_plans.enabled', '1')->find_many();
|
||||
$log = '';
|
||||
$router = '';
|
||||
foreach ($plans as $plan) {
|
||||
if ($router != $plan['routers']) {
|
||||
$mikrotik = Mikrotik::info($plan['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
$router = $plan['routers'];
|
||||
}
|
||||
if ($plan['rate_down_unit'] == 'Kbps') {
|
||||
$unitdown = 'K';
|
||||
} else {
|
||||
$unitdown = 'M';
|
||||
}
|
||||
if ($plan['rate_up_unit'] == 'Kbps') {
|
||||
$unitup = 'K';
|
||||
} else {
|
||||
$unitup = 'M';
|
||||
}
|
||||
$rate = $plan['rate_up'] . $unitup . "/" . $plan['rate_down'] . $unitdown;
|
||||
Mikrotik::addHotspotPlan($client, $plan['name_plan'], $plan['shared_users'], $rate);
|
||||
$log .= "DONE : $plan[name_plan], $plan[shared_users], $rate<br>";
|
||||
if (!empty($plan['pool_expired'])) {
|
||||
Mikrotik::setHotspotExpiredPlan($client, 'EXPIRED NUXBILL ' . $plan['pool_expired'], $plan['pool_expired']);
|
||||
$log .= "DONE Expired : EXPIRED NUXBILL $plan[pool_expired]<br>";
|
||||
}
|
||||
}
|
||||
r2(U . 'services/hotspot', 's', $log);
|
||||
}else if ($routes['2'] == 'pppoe') {
|
||||
$plans = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'PPPOE')->where('tbl_plans.enabled', '1')->find_many();
|
||||
$log = '';
|
||||
$router = '';
|
||||
foreach ($plans as $plan) {
|
||||
if ($router != $plan['routers']) {
|
||||
$mikrotik = Mikrotik::info($plan['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
$router = $plan['routers'];
|
||||
}
|
||||
if ($plan['rate_down_unit'] == 'Kbps') {
|
||||
$unitdown = 'K';
|
||||
} else {
|
||||
$unitdown = 'M';
|
||||
}
|
||||
if ($plan['rate_up_unit'] == 'Kbps') {
|
||||
$unitup = 'K';
|
||||
} else {
|
||||
$unitup = 'M';
|
||||
}
|
||||
$rate = $plan['rate_up'] . $unitup . "/" . $plan['rate_down'] . $unitdown;
|
||||
Mikrotik::addPpoePlan($client, $plan['name_plan'], $plan['pool'], $rate);
|
||||
$log .= "DONE : $plan[name_plan], $plan[pool], $rate<br>";
|
||||
if (!empty($plan['pool_expired'])) {
|
||||
Mikrotik::setPpoePlan($client, 'EXPIRED NUXBILL ' . $plan['pool_expired'], $plan['pool_expired'], '512K/512K');
|
||||
$log .= "DONE Expired : EXPIRED NUXBILL $plan[pool_expired]<br>";
|
||||
}
|
||||
}
|
||||
r2(U . 'services/pppoe', 's', $log);
|
||||
}
|
||||
r2(U . 'services/hotspot', 'w', 'Unknown command');
|
||||
case 'hotspot':
|
||||
$ui->assign('xfooter', '<script type="text/javascript" src="ui/lib/c/hotspot.js"></script>');
|
||||
|
||||
@ -53,10 +115,10 @@ switch ($action) {
|
||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||
if ($d) {
|
||||
$ui->assign('d', $d);
|
||||
$p = ORM::for_table('tbl_pool')->where('routers', $d['routers'])->find_many();
|
||||
$ui->assign('p', $p);
|
||||
$b = ORM::for_table('tbl_bandwidth')->find_many();
|
||||
$ui->assign('b', $b);
|
||||
$r = ORM::for_table('tbl_routers')->find_many();
|
||||
$ui->assign('r', $r);
|
||||
run_hook('view_edit_plan'); #HOOK
|
||||
$ui->display('hotspot-edit.tpl');
|
||||
} else {
|
||||
@ -96,6 +158,7 @@ switch ($action) {
|
||||
$validity = _post('validity');
|
||||
$validity_unit = _post('validity_unit');
|
||||
$routers = _post('routers');
|
||||
$pool_expired = _post('pool_expired');
|
||||
$enabled = _post('enabled');
|
||||
|
||||
$msg = '';
|
||||
@ -134,7 +197,11 @@ switch ($action) {
|
||||
$mikrotik = Mikrotik::info($routers);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::addHotspotPlan($client, $name, $sharedusers, $rate);
|
||||
if (!empty($pool_expired)) {
|
||||
Mikrotik::setHotspotExpiredPlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$d = ORM::for_table('tbl_plans')->create();
|
||||
$d->name_plan = $name;
|
||||
@ -151,6 +218,7 @@ switch ($action) {
|
||||
$d->validity_unit = $validity_unit;
|
||||
$d->shared_users = $sharedusers;
|
||||
$d->routers = $routers;
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->save();
|
||||
|
||||
@ -176,6 +244,7 @@ switch ($action) {
|
||||
$validity = _post('validity');
|
||||
$validity_unit = _post('validity_unit');
|
||||
$routers = _post('routers');
|
||||
$pool_expired = _post('pool_expired');
|
||||
$enabled = _post('enabled');
|
||||
|
||||
$msg = '';
|
||||
@ -213,6 +282,9 @@ switch ($action) {
|
||||
$mikrotik = Mikrotik::info($routers);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::setHotspotPlan($client, $name, $sharedusers, $rate);
|
||||
if (!empty($pool_expired)) {
|
||||
Mikrotik::setHotspotExpiredPlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired);
|
||||
}
|
||||
}
|
||||
|
||||
$d->name_plan = $name;
|
||||
@ -228,6 +300,7 @@ switch ($action) {
|
||||
$d->validity_unit = $validity_unit;
|
||||
$d->shared_users = $sharedusers;
|
||||
$d->routers = $routers;
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->save();
|
||||
|
||||
@ -260,8 +333,6 @@ switch ($action) {
|
||||
$ui->assign('_title', $_L['PPPOE_Plans']);
|
||||
$d = ORM::for_table('tbl_bandwidth')->find_many();
|
||||
$ui->assign('d', $d);
|
||||
$p = ORM::for_table('tbl_pool')->find_many();
|
||||
$ui->assign('p', $p);
|
||||
$r = ORM::for_table('tbl_routers')->find_many();
|
||||
$ui->assign('r', $r);
|
||||
run_hook('view_add_ppoe'); #HOOK
|
||||
@ -274,10 +345,10 @@ switch ($action) {
|
||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||
if ($d) {
|
||||
$ui->assign('d', $d);
|
||||
$p = ORM::for_table('tbl_pool')->where('routers', $d['routers'])->find_many();
|
||||
$ui->assign('p', $p);
|
||||
$b = ORM::for_table('tbl_bandwidth')->find_many();
|
||||
$ui->assign('b', $b);
|
||||
$p = ORM::for_table('tbl_pool')->find_many();
|
||||
$ui->assign('p', $p);
|
||||
$r = ORM::for_table('tbl_routers')->find_many();
|
||||
$ui->assign('r', $r);
|
||||
run_hook('view_edit_ppoe'); #HOOK
|
||||
@ -312,6 +383,7 @@ switch ($action) {
|
||||
$validity_unit = _post('validity_unit');
|
||||
$routers = _post('routers');
|
||||
$pool = _post('pool_name');
|
||||
$pool_expired = _post('pool_expired');
|
||||
$enabled = _post('enabled');
|
||||
|
||||
$msg = '';
|
||||
@ -348,6 +420,9 @@ switch ($action) {
|
||||
$mikrotik = Mikrotik::info($routers);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::addPpoePlan($client, $name, $pool, $rate);
|
||||
if (!empty($pool_expired)) {
|
||||
Mikrotik::setPpoePlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired, '512K/512K');
|
||||
}
|
||||
}
|
||||
|
||||
$d = ORM::for_table('tbl_plans')->create();
|
||||
@ -359,6 +434,7 @@ switch ($action) {
|
||||
$d->validity_unit = $validity_unit;
|
||||
$d->routers = $routers;
|
||||
$d->pool = $pool;
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->save();
|
||||
|
||||
@ -377,6 +453,7 @@ switch ($action) {
|
||||
$validity_unit = _post('validity_unit');
|
||||
$routers = _post('routers');
|
||||
$pool = _post('pool_name');
|
||||
$pool_expired = _post('pool_expired');
|
||||
$enabled = _post('enabled');
|
||||
|
||||
$msg = '';
|
||||
@ -414,6 +491,9 @@ switch ($action) {
|
||||
$mikrotik = Mikrotik::info($routers);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::setPpoePlan($client, $name, $pool, $rate);
|
||||
if (!empty($pool_expired)) {
|
||||
Mikrotik::setPpoePlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired, '512K/512K');
|
||||
}
|
||||
}
|
||||
|
||||
$d->name_plan = $name;
|
||||
@ -423,6 +503,7 @@ switch ($action) {
|
||||
$d->validity_unit = $validity_unit;
|
||||
$d->routers = $routers;
|
||||
$d->pool = $pool;
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->save();
|
||||
|
||||
|
@ -31,8 +31,14 @@ switch ($action) {
|
||||
if ($admin['user_type'] != 'Admin') {
|
||||
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
|
||||
}
|
||||
$lan = ORM::for_table('tbl_language')->find_many();
|
||||
$ui->assign('lan', $lan);
|
||||
$folders = [];
|
||||
$files = scandir('system/lan/');
|
||||
foreach ($files as $file) {
|
||||
if(is_dir('system/lan/'.$file) && !in_array($file,['.','..'])){
|
||||
$folders[] = $file;
|
||||
}
|
||||
}
|
||||
$ui->assign('lan', $folders);
|
||||
|
||||
$timezonelist = Timezone::timezoneList();
|
||||
$ui->assign('tlist', $timezonelist);
|
||||
@ -225,6 +231,8 @@ switch ($action) {
|
||||
$user_notification_payment = _post('user_notification_payment');
|
||||
$address = _post('address');
|
||||
$tawkto = _post('tawkto');
|
||||
$http_proxy = _post('http_proxy');
|
||||
$http_proxyauth = _post('http_proxyauth');
|
||||
$radius_mode = _post('radius_mode') * 1;
|
||||
run_hook('save_settings'); #HOOK
|
||||
|
||||
@ -251,6 +259,28 @@ switch ($action) {
|
||||
$d->save();
|
||||
|
||||
|
||||
$d = ORM::for_table('tbl_appconfig')->where('setting', 'http_proxy')->find_one();
|
||||
if ($d) {
|
||||
$d->value = $http_proxy;
|
||||
$d->save();
|
||||
} else {
|
||||
$d = ORM::for_table('tbl_appconfig')->create();
|
||||
$d->setting = 'http_proxy';
|
||||
$d->value = $http_proxy;
|
||||
$d->save();
|
||||
}
|
||||
|
||||
$d = ORM::for_table('tbl_appconfig')->where('setting', 'http_proxyauth')->find_one();
|
||||
if ($d) {
|
||||
$d->value = $http_proxyauth;
|
||||
$d->save();
|
||||
} else {
|
||||
$d = ORM::for_table('tbl_appconfig')->create();
|
||||
$d->setting = 'http_proxyauth';
|
||||
$d->value = $http_proxyauth;
|
||||
$d->save();
|
||||
}
|
||||
|
||||
$d = ORM::for_table('tbl_appconfig')->where('setting', 'CompanyFooter')->find_one();
|
||||
if ($d) {
|
||||
$d->value = $footer;
|
||||
|
103
system/cron.php
103
system/cron.php
@ -4,10 +4,40 @@
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
**/
|
||||
|
||||
require('../config.php');
|
||||
require('orm.php');
|
||||
// on some server, it getting error because of slash is backwards
|
||||
function _autoloader($class)
|
||||
{
|
||||
if (strpos($class, '_') !== false) {
|
||||
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include __DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
} else {
|
||||
if (file_exists(__DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include __DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
spl_autoload_register('_autoloader');
|
||||
|
||||
|
||||
if(php_sapi_name() !== 'cli'){
|
||||
echo "<pre>";
|
||||
}
|
||||
|
||||
|
||||
require_once '../config.php';
|
||||
require_once 'orm.php';
|
||||
require_once 'autoload/PEAR2/Autoload.php';
|
||||
include "autoload/Hookers.php";
|
||||
|
||||
ORM::configure("mysql:host=$db_host;dbname=$db_name");
|
||||
ORM::configure('username', $db_user);
|
||||
@ -16,49 +46,30 @@ ORM::configure('return_result_sets', true);
|
||||
ORM::configure('logging', true);
|
||||
|
||||
|
||||
include "autoload/Hookers.php";
|
||||
|
||||
// notification message
|
||||
if(file_exists("system/uploads/notifications.json")){
|
||||
$_notifmsg =json_decode(file_get_contents('system/uploads/notifications.json'), true);
|
||||
if (file_exists("uploads/notifications.json")) {
|
||||
$_notifmsg = json_decode(file_get_contents('uploads/notifications.json'), true);
|
||||
}
|
||||
$_notifmsg_default = json_decode(file_get_contents('system/uploads/notifications.default.json'), true);
|
||||
$_notifmsg_default = json_decode(file_get_contents('uploads/notifications.default.json'), true);
|
||||
|
||||
//register all plugin
|
||||
foreach (glob("plugin/*.php") as $filename) {
|
||||
foreach (glob(File::pathFixer("plugin/*.php")) as $filename) {
|
||||
include $filename;
|
||||
}
|
||||
|
||||
// on some server, it getting error because of slash is backwards
|
||||
function _autoloader($class)
|
||||
{
|
||||
if (strpos($class, '_') !== false) {
|
||||
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
} else {
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('_autoloader');
|
||||
|
||||
$result = ORM::for_table('tbl_appconfig')->find_many();
|
||||
foreach ($result as $value) {
|
||||
$config[$value['setting']] = $value['value'];
|
||||
}
|
||||
|
||||
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
|
||||
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
|
||||
$statement = ORM::get_last_statement();
|
||||
$rows = array();
|
||||
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
||||
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
|
||||
}
|
||||
|
||||
$_c = $config;
|
||||
|
||||
date_default_timezone_set($config['timezone']);
|
||||
@ -66,7 +77,7 @@ date_default_timezone_set($config['timezone']);
|
||||
$textExpired = Lang::getNotifText('expired');
|
||||
|
||||
$d = ORM::for_table('tbl_user_recharges')->where('status', 'on')->where_lte('expiration', date("Y-m-d"))->find_many();
|
||||
echo "Found ".count($d)." user(s)\n";
|
||||
echo "Found " . count($d) . " user(s)\n";
|
||||
run_hook('cronjob'); #HOOK
|
||||
|
||||
foreach ($d as $ds) {
|
||||
@ -79,10 +90,15 @@ foreach ($d as $ds) {
|
||||
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
|
||||
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
|
||||
$m = ORM::for_table('tbl_routers')->where('name', $ds['routers'])->find_one();
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||
|
||||
if (!$_c['radius_mode']) {
|
||||
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
|
||||
Mikrotik::setHotspotLimitUptime($client, $c['username']);
|
||||
if(!empty($p['pool_expired'])){
|
||||
Mikrotik::setHotspotUserPackage($client, $c['username'], 'EXPIRED NUXBILL '.$p['pool_expired']);
|
||||
}else{
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
}
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
|
||||
}
|
||||
@ -92,7 +108,6 @@ foreach ($d as $ds) {
|
||||
|
||||
// autorenewal from deposit
|
||||
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
|
||||
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
// if success, then get the balance
|
||||
@ -106,10 +121,10 @@ foreach ($d as $ds) {
|
||||
"\nRouter: " . $router_name .
|
||||
"\nPrice: " . $p['price']);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
echo "no renewall | plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
echo "no renewall | balance $config[enable_balance] auto_renewal $c[auto_renewal]\n";
|
||||
}
|
||||
} else echo " : ACTIVE \r\n";
|
||||
@ -122,10 +137,15 @@ foreach ($d as $ds) {
|
||||
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
|
||||
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
|
||||
$m = ORM::for_table('tbl_routers')->where('name', $ds['routers'])->find_one();
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||
|
||||
if (!$_c['radius_mode']) {
|
||||
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
|
||||
Mikrotik::disablePpoeUser($client, $c['username']);
|
||||
if(!empty($p['pool_expired'])){
|
||||
Mikrotik::setPpoeUserPlan($client, $c['username'], 'EXPIRED NUXBILL '.$p['pool_expired']);
|
||||
}else{
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
}
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
|
||||
}
|
||||
@ -135,12 +155,15 @@ foreach ($d as $ds) {
|
||||
|
||||
// autorenewal from deposit
|
||||
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
|
||||
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
// if success, then get the balance
|
||||
Balance::min($ds['customer_id'], $p['price']);
|
||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||
echo "auto renewall Success\n";
|
||||
} else {
|
||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||
echo "auto renewall Failed\n";
|
||||
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #PPPOE \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nPrice: " . $p['price']);
|
||||
|
@ -7,10 +7,38 @@
|
||||
* 0 7 * * * /usr/bin/php /var/www/system/cron_reminder.php
|
||||
**/
|
||||
|
||||
require('../config.php');
|
||||
require('orm.php');
|
||||
// on some server, it getting error because of slash is backwards
|
||||
function _autoloader($class)
|
||||
{
|
||||
if (strpos($class, '_') !== false) {
|
||||
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
} else {
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
spl_autoload_register('_autoloader');
|
||||
|
||||
if(php_sapi_name() !== 'cli'){
|
||||
echo "<pre>";
|
||||
}
|
||||
|
||||
require_once '../config.php';
|
||||
require_once 'orm.php';
|
||||
require_once 'autoload/PEAR2/Autoload.php';
|
||||
include "autoload/Hookers.php";
|
||||
|
||||
ORM::configure("mysql:host=$db_host;dbname=$db_name");
|
||||
ORM::configure('username', $db_user);
|
||||
@ -18,45 +46,17 @@ ORM::configure('password', $db_password);
|
||||
ORM::configure('return_result_sets', true);
|
||||
ORM::configure('logging', true);
|
||||
|
||||
|
||||
include "autoload/Hookers.php";
|
||||
|
||||
// notification message
|
||||
if(file_exists("system/uploads/notifications.json")){
|
||||
$_notifmsg =json_decode(file_get_contents('system/uploads/notifications.json'), true);
|
||||
if (file_exists("uploads/notifications.json")) {
|
||||
$_notifmsg = json_decode(file_get_contents('uploads/notifications.json'), true);
|
||||
}
|
||||
$_notifmsg_default = json_decode(file_get_contents('system/uploads/notifications.default.json'), true);
|
||||
$_notifmsg_default = json_decode(file_get_contents('uploads/notifications.default.json'), true);
|
||||
|
||||
//register all plugin
|
||||
foreach (glob("plugin/*.php") as $filename) {
|
||||
foreach (glob(File::pathFixer("plugin/*.php")) as $filename) {
|
||||
include $filename;
|
||||
}
|
||||
|
||||
// on some server, it getting error because of slash is backwards
|
||||
function _autoloader($class)
|
||||
{
|
||||
if (strpos($class, '_') !== false) {
|
||||
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
} else {
|
||||
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
|
||||
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
} else {
|
||||
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
|
||||
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
|
||||
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('_autoloader');
|
||||
|
||||
$result = ORM::for_table('tbl_appconfig')->find_many();
|
||||
foreach ($result as $value) {
|
||||
$config[$value['setting']] = $value['value'];
|
||||
@ -69,6 +69,14 @@ $d = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
|
||||
run_hook('cronjob_reminder'); #HOOK
|
||||
|
||||
|
||||
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
|
||||
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
|
||||
$statement = ORM::get_last_statement();
|
||||
$rows = array();
|
||||
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
||||
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
|
||||
}
|
||||
|
||||
|
||||
$day7 = date('Y-m-d', strtotime("+7 day"));
|
||||
$day3 = date('Y-m-d', strtotime("+3 day"));
|
||||
|
@ -385,3 +385,20 @@ $_L['Received_Balance'] = 'Received Balance';
|
||||
$_L['Minimum_Balance_Transfer'] = 'Minimum Balance Transfer';
|
||||
$_L['Minimum_Transfer'] = 'Minimum Transfer';
|
||||
$_L['Company_Logo'] = 'Company Logo';
|
||||
$_L['Expired_IP_Pool'] = 'Expired IP Pool';
|
||||
$_L['Expired_IP_Pool'] = 'Expired IP Pool';
|
||||
$_L['Proxy'] = 'Proxy';
|
||||
$_L['Proxy_Server'] = 'Proxy Server';
|
||||
$_L['Proxy_Server_Login'] = 'Proxy Server Login';
|
||||
$_L['Hotspot_Plan'] = 'Hotspot Plan';
|
||||
$_L['PPPOE_Plan'] = 'PPPOE Plan';
|
||||
$_L['UNKNOWN'] = 'UNKNOWN';
|
||||
$_L['Are_You_Sure'] = 'Are You Sure?';
|
||||
$_L['Success_to_send_package'] = 'Success to send package';
|
||||
$_L['Target_has_active_plan_different_with_current_plant'] = 'Target has active plan, different with current plant.';
|
||||
$_L['Recharge_a_friend'] = 'Recharge a friend';
|
||||
$_L['Buy_for_friend'] = 'Buy for friend';
|
||||
$_L['Buy_this_for_friend_account'] = 'Buy this for friend account?';
|
||||
$_L['Review_package_before_recharge'] = 'Review package before recharge';
|
||||
$_L['Deactivate'] = 'Deactivate';
|
||||
$_L['Sync'] = 'Sync';
|
||||
|
@ -338,3 +338,11 @@ $_L['Country_Code_Phone'] = 'Kode Negara Telepon';
|
||||
$_L['Voucher_activation_menu_will_be_hidden'] = 'Info Pembelian Voucher dan Redeem akan disembunyikan';
|
||||
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Pelanggan dapat topup saldo untuk langganan Internet';
|
||||
$_L['Allow_balance_transfer_between_customers'] = 'Bolehkan transfer saldo antar pelanggan';
|
||||
$_L['Refill_Balance'] = 'Refill Balance';
|
||||
$_L['Balance_Plans'] = 'Balance Plans';
|
||||
$_L['Expired_IP_Pool'] = 'Expired IP Pool';
|
||||
$_L['Company_Logo'] = 'Company Logo';
|
||||
$_L['Disable_Voucher'] = 'Disable Voucher';
|
||||
$_L['Minimum_Balance_Transfer'] = 'Minimum Balance Transfer';
|
||||
$_L['Reminder_Notification'] = 'Reminder Notification';
|
||||
$_L['Invoice_Footer'] = 'Invoice Footer';
|
||||
|
@ -340,4 +340,5 @@ $_L['Invoice'] = 'Invoice';
|
||||
$_L['Country_Code_Phone'] = 'Country Code Phone';
|
||||
$_L['Voucher_activation_menu_will_be_hidden'] = 'Voucher activation menu will be hidden';
|
||||
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Customer can deposit money to buy voucher';
|
||||
$_L['Allow_balance_transfer_between_customers'] = 'Allow balance transfer between customers';
|
||||
$_L['Allow_balance_transfer_between_customers'] = 'Allow balance transfer between customers';$_L['Refill_Balance'] = 'Refill Balance';
|
||||
$_L['Balance_Plans'] = 'Balance Plans';
|
||||
|
@ -7,11 +7,12 @@ if(php_sapi_name() !== 'cli'){
|
||||
die("RUN ON COMMAND LINE ONLY BY RADIUS ENGINE");
|
||||
}
|
||||
|
||||
require(__DIR__.'/../config.php');
|
||||
require(__DIR__.'/orm.php');
|
||||
require_once __DIR__.File::pathFixer('/../config.php');
|
||||
require_once __DIR__.File::pathFixer('orm.php');
|
||||
require_once __DIR__.File::pathFixer('/autoload/PEAR2/Autoload.php');
|
||||
include __DIR__.File::pathFixer("/autoload/Hookers.php");
|
||||
|
||||
use PEAR2\Net\RouterOS;
|
||||
require_once 'autoload/PEAR2/Autoload.php';
|
||||
|
||||
ORM::configure("mysql:host=$db_host;dbname=$db_name");
|
||||
ORM::configure('username', $db_user);
|
||||
|
@ -17,5 +17,9 @@
|
||||
"2023.8.28" : [
|
||||
"ALTER TABLE `tbl_user_recharges` ADD `recharged_time` time NOT NULL DEFAULT '00:00:00' AFTER `recharged_on`;",
|
||||
"ALTER TABLE `tbl_transactions` ADD `recharged_time` time NOT NULL DEFAULT '00:00:00' AFTER `recharged_on`;"
|
||||
],
|
||||
"2023.9.5" : [
|
||||
"DROP TABLE `tbl_language`;",
|
||||
"ALTER TABLE `tbl_plans` ADD `pool_expired` varchar(40) NOT NULL DEFAULT '' AFTER `pool`;"
|
||||
]
|
||||
}
|
@ -45,18 +45,16 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{$_L['Default_Language']}</label>
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" name="lan" id="lan">
|
||||
{foreach $lan as $lans}
|
||||
<option value="{$lans['folder']}" {if $_c['language'] eq $lans['folder']}
|
||||
selected="selected" {/if}>{$lans['name']}</option>
|
||||
<option value="{$lans}" {if $_c['language'] eq $lans}
|
||||
selected="selected" {/if}>{$lans}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<a href="{$_url}settings/language" type="button"
|
||||
class="btn btn-line-success btn-icon-inline"><i
|
||||
class="ion ion-android-add"></i>{$_L['Add_Language']}</a>
|
||||
<div class="col-md-4 help-block">
|
||||
To add new Language, just add the folder, it will automatically detected
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -78,8 +76,8 @@
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="currency_code" name="currency_code"
|
||||
value="{$_c['currency_code']}">
|
||||
<span class="help-block">{$_L['currency_help']}</span>
|
||||
</div>
|
||||
<span class="help-block col-md-4">{$_L['currency_help']}</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Country Code Phone')}</label>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<b>[[type]]</b> is Hotspot/PPPOE.<br>
|
||||
<b>[[plan_name]]</b> Internet Package.<br>
|
||||
<b>[[plan_price]]</b> Internet Package Prices.<br>
|
||||
<b>[[name]]</b> Receiver name.<br>
|
||||
<b>[[user_name]]</b> Username internet.<br>
|
||||
<b>[[user_password]]</b> User password.<br>
|
||||
<b>[[expired_date]]</b> Expired datetime.<br>
|
||||
@ -106,9 +107,12 @@
|
||||
<b>[[type]]</b> is Hotspot/PPPOE.<br>
|
||||
<b>[[plan_name]]</b> Internet Package.<br>
|
||||
<b>[[plan_price]]</b> Internet Package Prices.<br>
|
||||
<b>[[name]]</b> Receiver name.<br>
|
||||
<b>[[user_name]]</b> Username internet.<br>
|
||||
<b>[[user_password]]</b> User password.<br>
|
||||
<b>[[trx_date]]</b> Transaction datetime.<br>
|
||||
<b>[[balance_before]]</b> Balance Before.<br>
|
||||
<b>[[balance]]</b> Balance After.<br>
|
||||
<b>[[footer]]</b> Invoice Footer.
|
||||
</p>
|
||||
</div>
|
||||
@ -122,7 +126,8 @@
|
||||
</div>
|
||||
<p class="col-md-4 help-block">
|
||||
<b>[[name]]</b> Receiver name.<br>
|
||||
<b>[[balance]]</b> how much balance have been send.
|
||||
<b>[[balance]]</b> how much balance have been send.<br>
|
||||
<b>[[current_balance]]</b> Current Balance.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -135,7 +140,8 @@
|
||||
</div>
|
||||
<p class="col-md-4 help-block">
|
||||
<b>[[name]]</b> Sender name.<br>
|
||||
<b>[[balance]]</b> how much balance have been received.
|
||||
<b>[[balance]]</b> how much balance have been received.<br>
|
||||
<b>[[current_balance]]</b> Current Balance.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,7 +24,8 @@
|
||||
<label class="col-md-2 control-label">{Lang::T('Company Logo')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="file" class="form-control" id="logo" name="logo" accept="image/*">
|
||||
<span class="help-block">For PDF Reports | Beset size 1078 x 200 | uploaded image will be autosize</span>
|
||||
<span class="help-block">For PDF Reports | Best size 1078 x 200 | uploaded image will be
|
||||
autosize</span>
|
||||
</div>
|
||||
<span class="help-block col-md-4">
|
||||
<a href="./{$logo}" target="_blank"><img src="./{$logo}" height="48" alt="logo for PDF"></a>
|
||||
@ -135,7 +136,8 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Telegram Bot Token</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="telegram_bot" name="telegram_bot"
|
||||
<input type="password" class="form-control" id="telegram_bot" name="telegram_bot" onmouseleave="this.type = 'password'"
|
||||
onmouseenter="this.type = 'text'"
|
||||
value="{$_c['telegram_bot']}" placeholder="123456:asdasgdkuasghddlashdashldhalskdklasd">
|
||||
</div>
|
||||
</div>
|
||||
@ -270,7 +272,6 @@
|
||||
</div>
|
||||
{Lang::T('Invoice')}
|
||||
</div>
|
||||
<div class="panel-heading"></div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Invoice Footer')}</label>
|
||||
@ -281,6 +282,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
|
||||
class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
{Lang::T('Proxy')}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Proxy Server')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="http_proxy" name="http_proxy"
|
||||
value="{$_c['http_proxy']}" placeholder="127.0.0.1:3128">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Proxy Server Login')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control" id="http_proxyauth" name="http_proxyauth" autocomplete="off"
|
||||
value="{$_c['http_proxyauth']}" placeholder="username:password" onmouseleave="this.type = 'password'"
|
||||
onmouseenter="this.type = 'text'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
<option value=''>{$_L['Select_Pool']}</option>
|
||||
{foreach $d as $ds}
|
||||
<option value="{$ds['pool_name']}">{$ds['pool_name']}</option>
|
||||
{/foreach}
|
@ -1,4 +1,4 @@
|
||||
<option value="">Select Routers</option>
|
||||
<option value=''>{$_L['Select_Routers']}</option>
|
||||
{foreach $d as $ds}
|
||||
<option value="{$ds['name']}">{$ds['name']}</option>
|
||||
{/foreach}
|
@ -1,4 +1,4 @@
|
||||
<option value="">Select Plans</option>
|
||||
{foreach $d as $ds}
|
||||
<option value="{$ds['id']}">{$ds['name_plan']}</option>
|
||||
<option value="{$ds['id']}">{$ds['name_plan']} • {Lang::moneyFormat($ds['price'])}</option>
|
||||
{/foreach}
|
@ -130,7 +130,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="col-sm-6" id="update">
|
||||
<div class="box box-primary box-hovered mb20 activities">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">PHPNUXBILL</h3>
|
||||
@ -142,8 +142,7 @@
|
||||
<div class="box-footer" id="latestVersion">ver</div>
|
||||
<div class="box-footer">
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="./update.php" target="_blank" class="btn btn-success btn-sm btn-block">Install Latest
|
||||
Version</a>
|
||||
<a href="./update.php" class="btn btn-success btn-sm btn-block">Install Latest Version</a>
|
||||
<a href="https://github.com/hotspotbilling/phpnuxbill/archive/refs/heads/master.zip" target="_blank"
|
||||
class="btn btn-warning btn-sm btn-block">Download Latest Version</a>
|
||||
</div>
|
||||
|
@ -84,8 +84,24 @@
|
||||
{$package['routers']} <span class="pull-right">{$package['method']}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/deactivate/{$d['id']}" id="{$d['id']}"
|
||||
class="btn btn-danger btn-block btn-sm" onclick="return confirm('This will deactivate Customer Plan, and make it expired')">{Lang::T('Deactivate')}</a>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/recharge/{$d['id']}" onclick="return confirm('This will extend Customer plan, same as recharge')"
|
||||
class="btn btn-success btn-sm btn-block">{Lang::T('Recharge')}</a>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/sync/{$d['id']}" onclick="return confirm('This will sync Customer to Mikrotik?')"
|
||||
class="btn btn-primary btn-sm btn-block">{Lang::T('Sync')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
<a href="{$_url}prepaid/recharge/{$d['id']}" class="btn btn-success btn-sm btn-block mt-1">{Lang::T('Recharge')}</a><br>
|
||||
{/if}
|
||||
<a href="{$_url}customers/list" class="btn btn-primary btn-sm btn-block mt-1">{Lang::T('Back')}</a><br>
|
||||
</div>
|
||||
|
@ -24,34 +24,37 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-striped">
|
||||
<table class="table table-bordered table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$_L['Manage']}</th>
|
||||
<th>{$_L['Username']}</th>
|
||||
<th>{$_L['Full_Name']}</th>
|
||||
<th>{Lang::T('Balance')}</th>
|
||||
<th>{$_L['Phone_Number']}</th>
|
||||
<th>{$_L['Email']}</th>
|
||||
<th>{$_L['Package']}</th>
|
||||
<th>{$_L['Created_On']}</th>
|
||||
<th>{$_L['Recharge']}</th>
|
||||
<th>{$_L['Manage']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}"
|
||||
class="btn btn-success btn-sm">{Lang::T('View')}</a>
|
||||
</td>
|
||||
<td>{$ds['username']}</td>
|
||||
<td>{$ds['fullname']}</td>
|
||||
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'" style="cursor:pointer;">{$ds['username']}</td>
|
||||
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'" style="cursor: pointer;">{$ds['fullname']}</td>
|
||||
<td>{Lang::moneyFormat($ds['balance'])}</td>
|
||||
<td>{$ds['phonenumber']}</td>
|
||||
<td>{$ds['email']}</td>
|
||||
<td align="center" api-get-text="{$_url}autoload/customer_is_active/{$ds['id']}">
|
||||
<span class="label label-default">•</span>
|
||||
</td>
|
||||
<td>{Lang::dateTimeFormat($ds['created_at'])}</td>
|
||||
<td align="center"><a href="{$_url}prepaid/recharge-user/{$ds['id']}" id="{$ds['id']}"
|
||||
class="btn btn-primary btn-sm">{$_L['Recharge']}</a></td>
|
||||
<td align="center">
|
||||
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
|
||||
class="btn btn-success btn-xs"> {Lang::T('View')} </a>
|
||||
<a href="{$_url}prepaid/recharge/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
|
||||
class="btn btn-primary btn-xs">{$_L['Recharge']}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
|
@ -33,7 +33,7 @@
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner">
|
||||
<h4>{$u_act}</h4>
|
||||
<h4>{$u_act}/{$u_all}</h4>
|
||||
|
||||
<p>{$_L['Users_Active']}</p>
|
||||
</div>
|
||||
@ -47,7 +47,7 @@
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner">
|
||||
<h4>{$u_all}</h4>
|
||||
<h4>{$c_all}</h4>
|
||||
|
||||
<p>{$_L['Total_Users']}</p>
|
||||
</div>
|
||||
|
@ -112,7 +112,8 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}routers/add">{$_L['Router_Name']}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="routers" name="routers" class="form-control select2">
|
||||
<select id="routers" name="routers" required class="form-control select2">
|
||||
<option value=''>{$_L['Select_Routers']}</option>
|
||||
{foreach $r as $rs}
|
||||
<option value="{$rs['name']}">{$rs['name']}</option>
|
||||
{/foreach}
|
||||
@ -120,9 +121,16 @@
|
||||
<p class="help-block">{Lang::T('Cannot be change after saved')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="pool_expired" name="pool_expired" class="form-control select2">
|
||||
<option value=''>{$_L['Select_Pool']}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Save']}</button>
|
||||
Or <a href="{$_url}services/hotspot">{$_L['Cancel']}</a>
|
||||
</div>
|
||||
|
@ -114,9 +114,20 @@
|
||||
<input type="text" class="form-control" id="routers" name="routers" value="{$d['routers']}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="pool_expired" name="pool_expired" class="form-control select2">
|
||||
<option value=''>{$_L['Select_Pool']}</option>
|
||||
{foreach $p as $ps}
|
||||
<option value="{$ps['pool_name']}" {if $d['pool_expired'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Save']}</button>
|
||||
Or <a href="{$_url}services/hotspot">{$_L['Cancel']}</a>
|
||||
</div>
|
||||
|
@ -1,9 +1,15 @@
|
||||
{include file="sections/header.tpl"}
|
||||
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">{$_L['Hotspot_Plans']}</div>
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}services/sync/hotspot"
|
||||
onclick="return confirm('This will sync/send hotspot plan to Mikrotik?')"><span
|
||||
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
|
||||
</div>{$_L['Hotspot_Plans']}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
|
||||
<div class="col-md-8">
|
||||
@ -12,7 +18,8 @@
|
||||
<div class="input-group-addon">
|
||||
<span class="fa fa-search"></span>
|
||||
</div>
|
||||
<input type="text" name="name" class="form-control" placeholder="{$_L['Search_by_Name']}...">
|
||||
<input type="text" name="name" class="form-control"
|
||||
placeholder="{$_L['Search_by_Name']}...">
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-success" type="submit">{$_L['Search']}</button>
|
||||
</div>
|
||||
@ -20,7 +27,8 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="{$_url}services/add" class="btn btn-primary btn-block waves-effect"><i class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
|
||||
<a href="{$_url}services/add" class="btn btn-primary btn-block waves-effect"><i
|
||||
class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
@ -35,12 +43,13 @@
|
||||
<th>{$_L['Data_Limit']}</th>
|
||||
<th>{$_L['Plan_Validity']}</th>
|
||||
<th>{$_L['Routers']}</th>
|
||||
<th>{Lang::T('Expired IP Pool')}</th>
|
||||
<th>{$_L['Manage']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"{/if}>
|
||||
<tr {if $ds['enabled'] != 1}class="danger" title="disabled" {/if}>
|
||||
<td>{$ds['name_plan']}</td>
|
||||
<td>{$ds['typebp']}</td>
|
||||
<td>{$ds['name_bw']}</td>
|
||||
@ -49,9 +58,13 @@
|
||||
<td>{$ds['data_limit']} {$ds['data_unit']}</td>
|
||||
<td>{$ds['validity']} {$ds['validity_unit']}</td>
|
||||
<td>{$ds['routers']}</td>
|
||||
<td>{$ds['pool_expired']}</td>
|
||||
<td>
|
||||
<a href="{$_url}services/edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
|
||||
<a href="{$_url}services/delete/{$ds['id']}" id="{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')" class="btn btn-danger btn-xs">{$_L['Delete']}</a>
|
||||
<a href="{$_url}services/edit/{$ds['id']}"
|
||||
class="btn btn-info btn-xs">{$_L['Edit']}</a>
|
||||
<a href="{$_url}services/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
onclick="return confirm('{$_L['Delete']}?')"
|
||||
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
@ -63,6 +76,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
BIN
ui/ui/images/error.png
Normal file
BIN
ui/ui/images/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 342 KiB |
@ -3,7 +3,14 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">{$_L['Pool']}</div>
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}pool/sync"
|
||||
onclick="return confirm('This will sync/send IP Pool to Mikrotik?')"><span
|
||||
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
|
||||
</div>
|
||||
{$_L['Pool']}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
|
||||
<div class="col-md-8">
|
||||
@ -45,9 +52,9 @@
|
||||
<td>{$ds['range_ip']}</td>
|
||||
<td>{$ds['routers']}</td>
|
||||
<td align="center">
|
||||
<a href="{$_url}pool/edit/{$ds['id']}"
|
||||
class="btn btn-info btn-xs">{$_L['Edit']}</a>
|
||||
<a href="{$_url}pool/delete/{$ds['id']}" id="{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')"
|
||||
<a href="{$_url}pool/edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
|
||||
<a href="{$_url}pool/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
onclick="return confirm('{$_L['Delete']}?')"
|
||||
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -60,7 +60,7 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}routers/add">{$_L['Router_Name']}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="routers" name="routers" class="form-control select2">
|
||||
<select id="routers" name="routers" required class="form-control select2">
|
||||
<option value=''>{$_L['Select_Routers']}</option>
|
||||
{foreach $r as $rs}
|
||||
<option value="{$rs['name']}">{$rs['name']}</option>
|
||||
@ -72,14 +72,21 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{$_L['Pool']}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="pool_name" name="pool_name" class="form-control select2">
|
||||
<select id="pool_name" name="pool_name" required class="form-control select2">
|
||||
<option value=''>{$_L['Select_Pool']}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="pool_expired" name="pool_expired" class="form-control select2">
|
||||
<option value=''>{$_L['Select_Pool']}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<button class="btn btn-primary waves-effect waves-light" type="submit">{$_L['Save']}</button>
|
||||
Or <a href="{$_url}services/pppoe">{$_L['Cancel']}</a>
|
||||
</div>
|
||||
|
@ -60,9 +60,20 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{$_L['Pool']}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="pool_name" name="pool_name" class="form-control select2">
|
||||
<select id="pool_name" name="pool_name" required class="form-control select2">
|
||||
{foreach $p as $ps}
|
||||
<option value="{$ps['pool_name']}" {if $d['pool_name'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
|
||||
<option value="{$ps['pool_name']}" {if $d['pool'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
|
||||
<div class="col-md-6">
|
||||
<select id="pool_expired" name="pool_expired" class="form-control select2">
|
||||
<option value=''>{$_L['Select_Pool']}</option>
|
||||
{foreach $p as $ps}
|
||||
<option value="{$ps['pool_name']}" {if $d['pool_expired'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -1,9 +1,15 @@
|
||||
{include file="sections/header.tpl"}
|
||||
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">{$_L['PPPOE_Plans']}</div>
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}services/sync/pppoe"
|
||||
onclick="return confirm('This will sync/send PPPOE plan to Mikrotik?')"><span
|
||||
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
|
||||
</div>{$_L['PPPOE_Plans']}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
|
||||
<div class="col-md-8">
|
||||
@ -12,7 +18,8 @@
|
||||
<div class="input-group-addon">
|
||||
<span class="fa fa-search"></span>
|
||||
</div>
|
||||
<input type="text" name="name" class="form-control" placeholder="{$_L['Search_by_Name']}...">
|
||||
<input type="text" name="name" class="form-control"
|
||||
placeholder="{$_L['Search_by_Name']}...">
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-success" type="submit">{$_L['Search']}</button>
|
||||
</div>
|
||||
@ -20,7 +27,8 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="{$_url}services/pppoe-add" class="btn btn-primary btn-block waves-effect"><i class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
|
||||
<a href="{$_url}services/pppoe-add" class="btn btn-primary btn-block waves-effect"><i
|
||||
class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
@ -32,22 +40,27 @@
|
||||
<th>{$_L['Plan_Price']}</th>
|
||||
<th>{$_L['Plan_Validity']}</th>
|
||||
<th>{$_L['Pool']}</th>
|
||||
<th>{Lang::T('Expired IP Pool')}</th>
|
||||
<th>{$_L['Routers']}</th>
|
||||
<th>{$_L['Manage']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"{/if}>
|
||||
<tr {if $ds['enabled'] != 1}class="danger" title="disabled" {/if}>
|
||||
<td>{$ds['name_plan']}</td>
|
||||
<td>{$ds['name_bw']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td>{$ds['validity']} {$ds['validity_unit']}</td>
|
||||
<td>{$ds['pool']}</td>
|
||||
<td>{$ds['pool_expired']}</td>
|
||||
<td>{$ds['routers']}</td>
|
||||
<td>
|
||||
<a href="{$_url}services/pppoe-edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
|
||||
<a href="{$_url}services/pppoe-delete/{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')" id="{$ds['id']}" class="btn btn-danger btn-xs">{$_L['Delete']}</a>
|
||||
<a href="{$_url}services/pppoe-edit/{$ds['id']}"
|
||||
class="btn btn-info btn-xs">{$_L['Edit']}</a>
|
||||
<a href="{$_url}services/pppoe-delete/{$ds['id']}"
|
||||
onclick="return confirm('{$_L['Delete']}?')" id="{$ds['id']}"
|
||||
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
@ -58,6 +71,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
@ -28,12 +28,15 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{$_L['Created_On']}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="date" class="form-control" id="recharged_on" name="recharged_on" readonly
|
||||
value="{$d['recharged_on']} {$d['recharged_time']}">
|
||||
<div class="col-md-4">
|
||||
<input type="date" class="form-control" name="expiration" readonly
|
||||
value="{$d['recharged_on']}">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control" placeholder="00:00:00" readonly
|
||||
value="{$d['recharged_time']}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -3,7 +3,13 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">{$_L['Prepaid_User']}</div>
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}prepaid/sync"
|
||||
onclick="return confirm('This will sync/send Caustomer active plan to Mikrotik?')"><span
|
||||
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
|
||||
</div>{$_L['Prepaid_User']}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
|
||||
<div class="col-md-8">
|
||||
@ -41,7 +47,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr>
|
||||
<tr {if $ds['status']=='off'}class="danger" {/if}>
|
||||
<td><a href="{$_url}customers/viewu/{$ds['username']}">{$ds['username']}</a></td>
|
||||
<td>{$ds['namebp']}</td>
|
||||
<td>{$ds['type']}</td>
|
||||
@ -53,6 +59,7 @@
|
||||
<a href="{$_url}prepaid/edit/{$ds['id']}"
|
||||
class="btn btn-warning btn-xs">{$_L['Edit']}</a>
|
||||
<a href="{$_url}prepaid/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
onclick="return confirm('{$_L['Delete']}?')"
|
||||
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,15 +1,19 @@
|
||||
{include file="sections/header.tpl"}
|
||||
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{$_L['Recharge_Account']}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/recharge-post" >
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/recharge-post">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{$_L['Select_Account']}</label>
|
||||
<div class="col-md-6">
|
||||
<select id="personSelect" class="form-control select2" name="id_customer" style="width: 100%" data-placeholder="{$_L['Select_Customer']}...">
|
||||
<select {if $cust}{else}id="personSelect"{/if} class="form-control select2"
|
||||
name="id_customer" style="width: 100%" data-placeholder="{$_L['Select_Customer']}...">
|
||||
{if $cust}
|
||||
<option value="{$cust['id']}">{$cust['username']} • {$cust['fullname']} • {$cust['email']}</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -40,7 +44,8 @@
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Recharge']}</button>
|
||||
<button class="btn btn-success waves-effect waves-light"
|
||||
type="submit">{$_L['Recharge']}</button>
|
||||
Or <a href="{$_url}customers/list">{$_L['Cancel']}</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -48,6 +53,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>Router Error - PHPNuxBill</title>
|
||||
<title>Error - PHPNuxBill</title>
|
||||
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
|
||||
|
||||
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
|
||||
@ -32,27 +32,45 @@
|
||||
|
||||
<body class="hold-transition skin-blue">
|
||||
<div class="container">
|
||||
<section class="content-header">
|
||||
<h1 class="text-center">
|
||||
Router Error
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-3"></div>
|
||||
<div class="col-md-6">
|
||||
<div class="alert alert-danger text-center">
|
||||
{$error_meesage}
|
||||
<div class="col-md-3">
|
||||
<img src="./ui/ui/images/error.png" class="img-responsive hidden-sm hidden-xs">
|
||||
</div>
|
||||
<a href="javascript::history.back()" onclick="history.back()" class="btn btn-warning btn-block">back</a>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-danger box-solid text-center">
|
||||
|
||||
<section class="content-header">
|
||||
<h1 class="text-center">
|
||||
{$error_title}
|
||||
</h1>
|
||||
</section>
|
||||
<div class="box-title" style="font-size:xx-large; color:red">
|
||||
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="box-body" style="font-size: larger;">
|
||||
<br><br>
|
||||
{$error_message}
|
||||
<br><br><br>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="./update.php?step=4" class="btn btn-info btn-sm btn-block">Update Database</a>
|
||||
<a href="{$_url}community#update" class="btn btn-primary btn-sm btn-block">Update
|
||||
PHPNuxBill</a>
|
||||
</div>
|
||||
<br><br>
|
||||
<a href="javascript::history.back()" onclick="history.back()"
|
||||
class="btn btn-warning btn-block">back</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<img src="./ui/ui/images/error.png" class="img-responsive hidden-md hidden-lg">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="footer text-center">
|
||||
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener"
|
||||
target="_blank">iBNuX</a>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
@ -42,7 +42,8 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{$_L['Router_Secret']}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="password" name="password">
|
||||
<input type="text" class="form-control" id="password" name="password"
|
||||
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -48,6 +48,7 @@ $(document).ready(function(){
|
||||
cache: false,
|
||||
success: function(msg){
|
||||
$("#pool_name").html(msg);
|
||||
$("#pool_expired").html(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -22,6 +22,17 @@
|
||||
$(document).ready(function() {
|
||||
$('.select2').select2({theme: "bootstrap"});
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
$('.select2tag').select2({theme: "bootstrap", tags: true});
|
||||
});
|
||||
|
||||
var listAtts = document.querySelectorAll(`[api-get-text]`);
|
||||
listAtts.forEach(function(el) {
|
||||
$.get(el.getAttribute('api-get-text'), function(data) {
|
||||
el.innerHTML = data;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/literal}
|
||||
|
||||
|
@ -241,8 +241,8 @@
|
||||
href="{$_url}settings/notifications">{Lang::T('User Notification')}</a></li>
|
||||
<li {if $_routes[1] eq 'users'}class="active" {/if}><a
|
||||
href="{$_url}settings/users">{$_L['Administrator_Users']}</a></li>
|
||||
<li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
|
||||
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li>
|
||||
{* <li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
|
||||
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li> *}
|
||||
<li {if $_routes[0] eq 'pluginmanager'}class="active" {/if}>
|
||||
<a href="{$_url}pluginmanager">{Lang::T('Plugin Manager')}</a>
|
||||
</li>
|
||||
|
@ -6,23 +6,25 @@
|
||||
</footer>
|
||||
{else}
|
||||
<footer class="main-footer">
|
||||
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener" target="_blank">iBNuX</a>, Theme by <a href="https://adminlte.io/" rel="nofollow noreferrer noopener" target="_blank">AdminLTE</a>
|
||||
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener"
|
||||
target="_blank">iBNuX</a>, Theme by <a href="https://adminlte.io/" rel="nofollow noreferrer noopener"
|
||||
target="_blank">AdminLTE</a>
|
||||
</footer>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="ui/ui/scripts/jquery.min.js"></script>
|
||||
<script src="ui/ui/scripts/bootstrap.min.js"></script>
|
||||
<script src="ui/ui/scripts/adminlte.min.js"></script>
|
||||
<script src="ui/ui/scripts/jquery.min.js"></script>
|
||||
<script src="ui/ui/scripts/bootstrap.min.js"></script>
|
||||
<script src="ui/ui/scripts/adminlte.min.js"></script>
|
||||
|
||||
<script src="ui/ui/scripts/plugins/select2.min.js"></script>
|
||||
<script src="ui/ui/scripts/custom.js"></script>
|
||||
<script src="ui/ui/scripts/plugins/select2.min.js"></script>
|
||||
<script src="ui/ui/scripts/custom.js"></script>
|
||||
|
||||
{if isset($xfooter)}
|
||||
{if isset($xfooter)}
|
||||
{$xfooter}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{if $_c['tawkto'] != ''}
|
||||
{if $_c['tawkto'] != ''}
|
||||
<!--Start of Tawk.to Script-->
|
||||
<script type="text/javascript">
|
||||
var Tawk_API = Tawk_API || {},
|
||||
@ -38,8 +40,19 @@
|
||||
})();
|
||||
</script>
|
||||
<!--End of Tawk.to Script-->
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
</body>
|
||||
{literal}
|
||||
<script>
|
||||
var listAtts = document.querySelectorAll(`[api-get-text]`);
|
||||
listAtts.forEach(function(el) {
|
||||
$.get(el.getAttribute('api-get-text'), function(data) {
|
||||
el.innerHTML = data;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/literal}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -27,6 +27,16 @@
|
||||
color: red;
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.content-wrapper {
|
||||
margin-top: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{if isset($xheader)}
|
||||
@ -37,8 +47,7 @@
|
||||
|
||||
<body class="hold-transition skin-blue sidebar-mini">
|
||||
<div class="wrapper">
|
||||
|
||||
<header class="main-header">
|
||||
<header class="main-header" style="position:fixed; width: 100%">
|
||||
<a href="{$_url}home" class="logo">
|
||||
<span class="logo-mini"><b>N</b>uX</span>
|
||||
<span class="logo-lg">{$_c['CompanyName']}</span>
|
||||
@ -48,20 +57,23 @@
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
</a>
|
||||
<div class="navbar-custom-menu">
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown user user-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
{if $_c['enable_balance'] == 'yes'}
|
||||
<span style="color: whitesmoke;">{Lang::moneyFormat($_user['balance'])}</span>
|
||||
{else}
|
||||
<span>{$_user['fullname']}</span>
|
||||
{/if}
|
||||
<img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1"
|
||||
onerror="this.src='system/uploads/user.default.jpg'"
|
||||
class="user-image" alt="User Image">
|
||||
<span class="hidden-xs">{$_user['fullname']}</span>
|
||||
onerror="this.src='system/uploads/user.default.jpg'" class="user-image"
|
||||
alt="User Image">
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="user-header">
|
||||
<img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1"
|
||||
onerror="this.src='system/uploads/user.default.jpg'"
|
||||
class="img-circle" alt="User Image">
|
||||
onerror="this.src='system/uploads/user.default.jpg'" class="img-circle"
|
||||
alt="User Image">
|
||||
|
||||
<p>
|
||||
{$_user['fullname']}
|
||||
@ -94,7 +106,7 @@
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<aside class="main-sidebar">
|
||||
<aside class="main-sidebar" style="position:fixed;">
|
||||
<section class="sidebar">
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
<li {if $_system_menu eq 'home'}class="active" {/if}>
|
||||
|
@ -12,8 +12,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{Lang::T('expired')}</td>
|
||||
<td>{date({$_c['date_format']}, strtotime($unpaid['expired_date']))}
|
||||
{date('H:i', strtotime($unpaid['expired_date']))} </td>
|
||||
<td>{Lang::dateTimeFormat($unpaid['expired_date'])} </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{$_L['Plan_Name']}</td>
|
||||
@ -30,12 +29,24 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="box-footer p-2">
|
||||
<a class="btn btn-danger btn-block btn-sm" href="{$_url}order/view/{$unpaid['id']}">
|
||||
<div class="btn-group btn-group-justified mb15">
|
||||
<div class="btn-group">
|
||||
<a href="{$_url}order/view/{$unpaid['id']}/cancel" class="btn btn-danger btn-sm"
|
||||
onclick="return confirm('{Lang::T('Cancel it?')}')">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
{Lang::T('Cancel')}
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-success btn-block btn-sm" href="{$_url}order/view/{$unpaid['id']}">
|
||||
<span class="icon"><i class="ion ion-card"></i></span>
|
||||
<span>{Lang::T('PAY NOW')}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="box box-info box-solid">
|
||||
<div class="box-header">
|
||||
@ -54,7 +65,7 @@
|
||||
<table class="table table-bordered table-striped table-bordered table-hover">
|
||||
<tr>
|
||||
<td class="small text-success text-uppercase text-normal">{$_L['Username']}</td>
|
||||
<td class="small mb15">{$_bill['username']}</td>
|
||||
<td class="small mb15">{$_user['username']}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="small text-success text-uppercase text-normal">{$_L['Password']}</td>
|
||||
@ -93,7 +104,6 @@
|
||||
{if $_bill['time'] ne ''}{Lang::dateAndTimeFormat($_bill['expiration'],$_bill['time'])}{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{if $_bill['type'] == 'Hotspot' && $_bill['status'] == 'on'}
|
||||
{if $nux_ip}
|
||||
<tr>
|
||||
<td class="small text-primary text-uppercase text-normal">{Lang::T('Current IP')}</td>
|
||||
@ -106,6 +116,7 @@
|
||||
<td class="small mb15">{$nux_mac}</td>
|
||||
</tr>
|
||||
{/if}
|
||||
{if $_bill['type'] == 'Hotspot' && $_bill['status'] == 'on'}
|
||||
<tr>
|
||||
<td class="small text-primary text-uppercase text-normal">{Lang::T('Login Status')}</td>
|
||||
<td class="small mb15" id="login_status">
|
||||
@ -156,7 +167,7 @@
|
||||
</div>
|
||||
<div class="form-group col-sm-2" align="center">
|
||||
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send"
|
||||
value="balance"><i class="glyphicon glyphicon-send"></i></button>
|
||||
onclick="return confirm('{Lang::T("Are You Sure?")}')" value="balance"><i class="glyphicon glyphicon-send"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -172,6 +183,23 @@
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="box-header">
|
||||
<h4 class="box-title">{Lang::T("Recharge a friend")}</h4>
|
||||
</div>
|
||||
<div class="box-body p-0">
|
||||
<form method="post" role="form" action="{$_url}home">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10">
|
||||
<input type="text" id="username" name="username" class="form-control" required
|
||||
placeholder="{$_L['Username']}">
|
||||
</div>
|
||||
<div class="form-group col-sm-2" align="center">
|
||||
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send"
|
||||
onclick="return confirm('{Lang::T("Are You Sure?")}')" value="plan"><i class="glyphicon glyphicon-send"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<br>
|
||||
|
@ -70,10 +70,10 @@
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified mb15">
|
||||
<div class="btn-group">
|
||||
<button type="submit" class="btn btn-primary">{$_L['Login']}</button>
|
||||
<a href="{$_url}register" class="btn btn-success">{$_L['Register']}</a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a href="{$_url}register" class="btn btn-success">{$_L['Register']}</a>
|
||||
<button type="submit" class="btn btn-primary">{$_L['Login']}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -33,10 +33,6 @@
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box box-solid box-success">
|
||||
<div class="box-header text-center text-bold">{Lang::T('Balance')} {Lang::moneyFormat($_user['balance'])}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{foreach $routers as $router}
|
||||
<div class="box box-solid box-info">
|
||||
@ -47,7 +43,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
{if count($plans_hotspot)>0}
|
||||
<div class="box-header">Hotspot</div>
|
||||
<div class="box-header">{Lang::T('Hotspot Plan')}</div>
|
||||
<div class="box-body row">
|
||||
{foreach $plans_hotspot as $plan}
|
||||
{if $router['name'] eq $plan['routers']}
|
||||
@ -83,6 +79,11 @@
|
||||
class="btn btn-sm btn-block btn-success">{Lang::T('Pay With Balance')}</a>
|
||||
{/if}
|
||||
</div>
|
||||
{if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && $_user['balance']>=$plan['price']}
|
||||
<a href="{$_url}order/send/{$router['id']}/{$plan['id']}"
|
||||
onclick="return confirm('{Lang::T('Buy this for friend account?')}')"
|
||||
class="btn btn-sm btn-block btn-primary">{Lang::T('Buy for friend')}</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -91,7 +92,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
{if count($plans_pppoe)>0}
|
||||
<div class="box-header text-sm">PPPOE</div>
|
||||
<div class="box-header text-sm">{Lang::T('PPPOE Plan')}</div>
|
||||
<div class="box-body row">
|
||||
{foreach $plans_pppoe as $plan}
|
||||
{if $router['name'] eq $plan['routers']}
|
||||
@ -127,6 +128,11 @@
|
||||
class="btn btn-sm btn-block btn-success">{Lang::T('Pay With Balance')}</a>
|
||||
{/if}
|
||||
</div>
|
||||
{if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && $_user['balance']>=$plan['price']}
|
||||
<a href="{$_url}order/send/{$router['id']}/{$plan['id']}"
|
||||
onclick="return confirm('{Lang::T('Buy this for friend account?')}')"
|
||||
class="btn btn-sm btn-block btn-primary">{Lang::T('Buy for friend')}</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
43
ui/ui/user-sendPlan.tpl
Normal file
43
ui/ui/user-sendPlan.tpl
Normal file
@ -0,0 +1,43 @@
|
||||
{include file="sections/user-header.tpl"}
|
||||
<!-- user-orderView -->
|
||||
<div class="row">
|
||||
<div class="col-md-3"></div>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-solid box-default">
|
||||
<div class="box-header">{$plan['name_plan']}</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{Lang::T('Type')}</td>
|
||||
<td>{$plan['type']}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{Lang::T('Price')}</td>
|
||||
<td>{Lang::moneyFormat($plan['price'])}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{Lang::T('Validity')}</td>
|
||||
<td>{$plan['validity']} {$plan['validity_unit']}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<form method="post" onsubmit="return askConfirm()" role="form">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-9">
|
||||
<input type="text" id="username" name="username" class="form-control" required value="{$username}"
|
||||
placeholder="{$_L['Username']}">
|
||||
</div>
|
||||
<div class="form-group col-sm-3" align="center">
|
||||
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send" onclick="return confirm('{Lang::T("Are You Sure?")}')"
|
||||
value="plan"><i class="glyphicon glyphicon-send"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="sections/user-footer.tpl"}
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "2023.8.30"
|
||||
"version": "2023.9.15"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user