diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index ddf5243b..7b218b6f 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -7,6 +7,9 @@ assignees: ibnux
---
+Please Remember, this project is free and open source, and @ibnux don't get any money from this project, and if you post something not a bug, just you dont understand how to install it, you will get blocked from this Repository.
+Post it in Discussion if you don't understand. Except you pay for $50 for support
+
**Describe the bug**
A clear and concise description of what the bug is. Error connecting to router is not a bug, is your router port is not accessable, ask community for help, go to discussion or telegram group
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index bbcbbe7d..b995353c 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -7,6 +7,8 @@ assignees: ''
---
+Please Remember, this project is free and open source, and @ibnux don't get any money from this project, any Feature Request will cost you $50-$5000
+
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 22af409d..f575489a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,52 @@
# CHANGELOG
+## 2024.1.9
+
+- Add Prefix when generate Voucher
+
+## 2024.1.8
+
+- User Expired Order by Expired Date
+
+## 2024.1.2
+
+- Pagination User Expired by @Focuslinkstech
+
+## 2023.12.21
+
+- Modern AdminLTE by @sabtech254
+- Update user-dashboard.tpl by @Focuslinkstech
+
+## 2023.12.19
+
+- Fix Search Customer
+- Disable Registration, Customer just activate voucher Code, and the voucher will be their password
+- Remove all used voucher codes
+
+## 2023.12.18
+
+- Split sms to 160 characters only for Mikrotik Modem
+
+## 2023.12.14
+
+- Can send SMS using Mikrotik with Modem Installed
+- Add Customer Type, so Customer can only show their PPPOE or Hotspot Package or both
+
+## 2023.11.17
+
+- Error details not show in Customer
+
+## 2023.11.15
+
+- Customer Multi Router package
+- Fix edit package, Admin can change Customer to another router
+
+## 2023.11.9
+
+- fix bug variable in cron
+- fix update plan
+
## 2023.10.27
- Backup and restore database
diff --git a/README.md b/README.md
index 3ced30b9..c75bd853 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,13 @@
+[](https://s.id/standwithpalestine)
+
# PHPNuxBill - PHP Mikrotik Billing

-
-
## Feature
- Voucher Generator and Print
+- FreeRadius
- Self registration
- User Balance
- Auto Renewal Package using Balance
@@ -35,7 +36,7 @@ Most current web servers with PHP & MySQL installed will be capable of running P
Minimum Requirements
- Linux or Windows OS
-- PHP Version 7.4
+- Minimum PHP Version 7.4
- Both PDO & MySQLi Support
- PHP-GD2 Image Library
- PHP-CURL
diff --git a/install/radius.sql b/install/radius.sql
index fbe9879d..475da5b6 100644
--- a/install/radius.sql
+++ b/install/radius.sql
@@ -102,6 +102,13 @@ CREATE TABLE `radusergroup` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+DROP TABLE IF EXISTS `nasreload`;
+CREATE TABLE `nasreload` (
+ nasipaddress varchar(15) NOT NULL,
+ reloadtime datetime NOT NULL,
+ PRIMARY KEY (nasipaddress)
+) ENGINE = INNODB;
+
ALTER TABLE `nas`
ADD PRIMARY KEY (`id`),
ADD KEY `nasname` (`nasname`);
diff --git a/system/autoload/Log.php b/system/autoload/Log.php
new file mode 100644
index 00000000..fc61d1c5
--- /dev/null
+++ b/system/autoload/Log.php
@@ -0,0 +1,32 @@
+create();
+ $d->date = date('Y-m-d H:i:s');
+ $d->type = $type;
+ $d->description = $description;
+ $d->userid = $userid;
+ $d->ip = (empty($username)) ? $_SERVER["REMOTE_ADDR"] : $username;
+ $d->save();
+ }
+
+ public static function arrayToText($array, $start = '', $result = '')
+ {
+ foreach ($array as $k => $v) {
+ if (is_array($v)) {
+ $result = Log::arrayToText($v, "$start$k.", $result);
+ } else {
+ $result .= $start.$k ." : ". strval($v) ."\n";
+ }
+ }
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/system/autoload/Message.php b/system/autoload/Message.php
index aab67ed2..3ee749d8 100644
--- a/system/autoload/Message.php
+++ b/system/autoload/Message.php
@@ -24,9 +24,34 @@ class Message
global $config;
run_hook('send_sms'); #HOOK
if (!empty($config['sms_url'])) {
- $smsurl = str_replace('[number]', urlencode($phone), $config['sms_url']);
- $smsurl = str_replace('[text]', urlencode($txt), $smsurl);
- Http::getData($smsurl);
+ if (strlen($config['sms_url']) > 4 && substr($config['sms_url'], 0, 4) != "http") {
+ if (strlen($txt) > 160) {
+ $txts = str_split($txt, 160);
+ foreach ($txts as $txt) {
+ try {
+ $mikrotik = Mikrotik::info($config['sms_url']);
+ $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
+ Mikrotik::sendSMS($client, $phone, $txt);
+ } catch (Exception $e) {
+ // ignore, add to logs
+ _log("Failed to send SMS using Mikrotik.\n" . $e->getMessage(), 'SMS', 0);
+ }
+ }
+ }else{
+ try {
+ $mikrotik = Mikrotik::info($config['sms_url']);
+ $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
+ Mikrotik::sendSMS($client, $phone, $txt);
+ } catch (Exception $e) {
+ // ignore, add to logs
+ _log("Failed to send SMS using Mikrotik.\n" . $e->getMessage(), 'SMS', 0);
+ }
+ }
+ } else {
+ $smsurl = str_replace('[number]', urlencode($phone), $config['sms_url']);
+ $smsurl = str_replace('[text]', urlencode($txt), $smsurl);
+ Http::getData($smsurl);
+ }
}
}
@@ -76,7 +101,8 @@ class Message
return "$via: $msg";
}
- public static function sendInvoice($cust, $trx){
+ public static function sendInvoice($cust, $trx)
+ {
global $config;
$textInvoice = Lang::getNotifText('invoice_paid');
$textInvoice = str_replace('[[company_name]]', $config['CompanyName'], $textInvoice);
diff --git a/system/autoload/Mikrotik.php b/system/autoload/Mikrotik.php
index 8c89a170..b622a3d9 100644
--- a/system/autoload/Mikrotik.php
+++ b/system/autoload/Mikrotik.php
@@ -1,4 +1,5 @@
assign("error_title", "Mikrotik Connection Error");
- // $ui->assign("error_message", "Unable to connect to the router : $ip
" . $e->getMessage() . '
' . $e->getTraceAsString() . ''); - // $ui->display('router-error.tpl'); - // die(); - // } + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $iport = explode(":", $ip); + return new RouterOS\Client($iport[0], $user, $pass, ($iport[1]) ? $iport[1] : null); } public static function isUserLogin($client, $username) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip hotspot active print', RouterOS\Query::where('user', $username) @@ -38,6 +39,10 @@ class Mikrotik public static function logMeIn($client, $user, $pass, $ip, $mac) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $addRequest = new RouterOS\Request('/ip/hotspot/active/login'); $client->sendSync( $addRequest @@ -50,13 +55,17 @@ class Mikrotik public static function logMeOut($client, $user) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip hotspot active print', RouterOS\Query::where('user', $user) ); $id = $client->sendSync($printRequest)->getProperty('.id'); $removeRequest = new RouterOS\Request('/ip/hotspot/active/remove'); - $client( + $client->sendSync( $removeRequest ->setArgument('numbers', $id) ); @@ -64,6 +73,10 @@ class Mikrotik public static function addHotspotPlan($client, $name, $sharedusers, $rate) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $addRequest = new RouterOS\Request('/ip/hotspot/user/profile/add'); $client->sendSync( $addRequest @@ -75,6 +88,10 @@ class Mikrotik public static function setHotspotPlan($client, $name, $sharedusers, $rate) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip hotspot user profile print .proplist=.id', RouterOS\Query::where('name', $name) @@ -84,7 +101,7 @@ class Mikrotik Mikrotik::addHotspotPlan($client, $name, $sharedusers, $rate); } else { $setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set'); - $client( + $client->sendSync( $setRequest ->setArgument('numbers', $profileID) ->setArgument('shared-users', $sharedusers) @@ -95,6 +112,10 @@ class Mikrotik public static function setHotspotExpiredPlan($client, $name, $pool) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip hotspot user profile print .proplist=.id', RouterOS\Query::where('name', $name) @@ -111,7 +132,7 @@ class Mikrotik ); } else { $setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set'); - $client( + $client->sendSync( $setRequest ->setArgument('numbers', $profileID) ->setArgument('shared-users', 3) @@ -123,6 +144,10 @@ class Mikrotik public static function removeHotspotPlan($client, $name) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip hotspot user profile print .proplist=.id', RouterOS\Query::where('name', $name) @@ -130,7 +155,7 @@ class Mikrotik $profileID = $client->sendSync($printRequest)->getProperty('.id'); $removeRequest = new RouterOS\Request('/ip/hotspot/user/profile/remove'); - $client( + $client->sendSync( $removeRequest ->setArgument('numbers', $profileID) ); @@ -138,13 +163,17 @@ class Mikrotik public static function removeHotspotUser($client, $username) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip hotspot user print .proplist=.id', RouterOS\Query::where('name', $username) ); $userID = $client->sendSync($printRequest)->getProperty('.id'); $removeRequest = new RouterOS\Request('/ip/hotspot/user/remove'); - $client( + $client->sendSync( $removeRequest ->setArgument('numbers', $userID) ); @@ -152,6 +181,10 @@ class Mikrotik public static function addHotspotUser($client, $plan, $customer) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $addRequest = new RouterOS\Request('/ip/hotspot/user/add'); if ($plan['typebp'] == "Limited") { if ($plan['limit_type'] == "Time_Limit") { @@ -216,6 +249,10 @@ class Mikrotik public static function setHotspotUser($client, $user, $pass) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request('/ip/hotspot/user/print'); $printRequest->setArgument('.proplist', '.id'); $printRequest->setQuery(RouterOS\Query::where('name', $user)); @@ -229,6 +266,10 @@ class Mikrotik public static function setHotspotUserPackage($client, $user, $plan) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request('/ip/hotspot/user/print'); $printRequest->setArgument('.proplist', '.id'); $printRequest->setQuery(RouterOS\Query::where('name', $user)); @@ -242,6 +283,10 @@ class Mikrotik public static function removeHotspotActiveUser($client, $username) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $onlineRequest = new RouterOS\Request('/ip/hotspot/active/print'); $onlineRequest->setArgument('.proplist', '.id'); $onlineRequest->setQuery(RouterOS\Query::where('user', $username)); @@ -254,7 +299,10 @@ class Mikrotik public static function removePpoeUser($client, $username) { - + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request('/ppp/secret/print'); //$printRequest->setArgument('.proplist', '.id'); $printRequest->setQuery(RouterOS\Query::where('name', $username)); @@ -266,6 +314,10 @@ class Mikrotik public static function addPpoeUser($client, $plan, $customer) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $addRequest = new RouterOS\Request('/ppp/secret/add'); if (!empty($customer['pppoe_password'])) { $pass = $customer['pppoe_password']; @@ -284,6 +336,10 @@ class Mikrotik public static function setPpoeUser($client, $user, $pass) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request('/ppp/secret/print'); $printRequest->setArgument('.proplist', '.id'); $printRequest->setQuery(RouterOS\Query::where('name', $user)); @@ -297,6 +353,10 @@ class Mikrotik public static function setPpoeUserPlan($client, $user, $plan) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request('/ppp/secret/print'); $printRequest->setArgument('.proplist', '.id'); $printRequest->setQuery(RouterOS\Query::where('name', $user)); @@ -310,6 +370,10 @@ class Mikrotik public static function removePpoeActive($client, $username) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $onlineRequest = new RouterOS\Request('/ppp/active/print'); $onlineRequest->setArgument('.proplist', '.id'); $onlineRequest->setQuery(RouterOS\Query::where('name', $username)); @@ -322,6 +386,10 @@ class Mikrotik public static function removePool($client, $name) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip pool print .proplist=.id', RouterOS\Query::where('name', $name) @@ -329,7 +397,7 @@ class Mikrotik $poolID = $client->sendSync($printRequest)->getProperty('.id'); $removeRequest = new RouterOS\Request('/ip/pool/remove'); - $client( + $client->sendSync( $removeRequest ->setArgument('numbers', $poolID) ); @@ -337,6 +405,10 @@ class Mikrotik public static function addPool($client, $name, $ip_address) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $addRequest = new RouterOS\Request('/ip/pool/add'); $client->sendSync( $addRequest @@ -347,6 +419,10 @@ class Mikrotik public static function setPool($client, $name, $ip_address) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ip pool print .proplist=.id', RouterOS\Query::where('name', $name) @@ -357,7 +433,7 @@ class Mikrotik self::addPool($client, $name, $ip_address); } else { $setRequest = new RouterOS\Request('/ip/pool/set'); - $client( + $client->sendSync( $setRequest ->setArgument('numbers', $poolID) ->setArgument('ranges', $ip_address) @@ -368,6 +444,10 @@ class Mikrotik public static function addPpoePlan($client, $name, $pool, $rate) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $addRequest = new RouterOS\Request('/ppp/profile/add'); $client->sendSync( $addRequest @@ -380,6 +460,10 @@ class Mikrotik public static function setPpoePlan($client, $name, $pool, $rate) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ppp profile print .proplist=.id', RouterOS\Query::where('name', $name) @@ -389,7 +473,7 @@ class Mikrotik self::addPpoePlan($client, $name, $pool, $rate); } else { $setRequest = new RouterOS\Request('/ppp/profile/set'); - $client( + $client->sendSync( $setRequest ->setArgument('numbers', $profileID) ->setArgument('local-address', $pool) @@ -401,6 +485,10 @@ class Mikrotik public static function removePpoePlan($client, $name) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $printRequest = new RouterOS\Request( '/ppp profile print .proplist=.id', RouterOS\Query::where('name', $name) @@ -408,9 +496,22 @@ class Mikrotik $profileID = $client->sendSync($printRequest)->getProperty('.id'); $removeRequest = new RouterOS\Request('/ppp/profile/remove'); - $client( + $client->sendSync( $removeRequest ->setArgument('numbers', $profileID) ); } + + public static function sendSMS($client, $to, $message) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $smsRequest = new RouterOS\Request('/tool sms send'); + $smsRequest + ->setArgument('phone-number', $to) + ->setArgument('message', $message); + $client->sendSync($smsRequest); + } } diff --git a/system/autoload/Package.php b/system/autoload/Package.php index df986a7d..c9e670f2 100644 --- a/system/autoload/Package.php +++ b/system/autoload/Package.php @@ -81,7 +81,7 @@ class Package } - $b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one(); + $b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('routers', $router_name)->find_one(); $mikrotik = Mikrotik::info($router_name); if ($p['validity_unit'] == 'Months') { @@ -321,23 +321,64 @@ class Package return true; } - public static function changeTo($username, $plan_id) + public static function changeTo($username, $plan_id, $from_id) { - global $_c; $c = ORM::for_table('tbl_customers')->where('username', $username)->find_one(); $p = ORM::for_table('tbl_plans')->where('id', $plan_id)->where('enabled', '1')->find_one(); - $b = ORM::for_table('tbl_user_recharges')->where('customer_id', $c['id'])->find_one(); - $mikrotik = Mikrotik::info($p['routers']); + $b = ORM::for_table('tbl_user_recharges')->find_one($from_id); + if($p['routers'] == $b['routers'] && $b['routers'] != 'radius'){ + $mikrotik = Mikrotik::info($p['routers']); + }else{ + $mikrotik = Mikrotik::info($b['routers']); + } + // delete first + if ($p['type'] == 'Hotspot') { + if ($b) { + if (!$p['is_radius']) { + $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']); + } + } else { + if (!$p['is_radius']) { + $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']); + } + } + } else { + if ($b) { + if (!$p['is_radius']) { + $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']); + } + } else { + if (!$p['is_radius']) { + $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']); + } + } + } + // call the next mikrotik + if($p['routers'] != $b['routers'] && $p['routers'] != 'radius'){ + $mikrotik = Mikrotik::info($p['routers']); + } if ($p['type'] == 'Hotspot') { if ($b) { if ($p['is_radius']) { Radius::customerAddPlan($c, $p, $b['expiration'].''.$b['time']); }else{ $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 { @@ -345,10 +386,6 @@ class Package Radius::customerAddPlan($c, $p, $b['expiration'].''.$b['time']); }else{ $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); } } @@ -358,10 +395,6 @@ class Package Radius::customerAddPlan($c, $p); }else{ $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 { @@ -369,10 +402,6 @@ class Package Radius::customerAddPlan($c, $p); }else{ $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); } } diff --git a/system/autoload/Radius.php b/system/autoload/Radius.php index d5e9c20a..9bdee13c 100644 --- a/system/autoload/Radius.php +++ b/system/autoload/Radius.php @@ -297,6 +297,10 @@ class Radius public static function disconnectCustomer($username) { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } $nas = Radius::getTableNas()->findMany(); $count = count($nas) * 15; set_time_limit($count); diff --git a/system/autoload/User.php b/system/autoload/User.php index 1520eb9f..85d9a73d 100644 --- a/system/autoload/User.php +++ b/system/autoload/User.php @@ -22,7 +22,7 @@ class User public static function _billing() { $id = $_SESSION['uid']; - $d = ORM::for_table('tbl_user_recharges')->where('customer_id', $id)->find_one(); + $d = ORM::for_table('tbl_user_recharges')->where('customer_id', $id)->find_many(); return $d; } } diff --git a/system/boot.php b/system/boot.php index 586fdcd6..56ed2d60 100644 --- a/system/boot.php +++ b/system/boot.php @@ -116,7 +116,11 @@ try { $ui->setConfigDir(File::pathFixer('ui/conf/')); $ui->setCacheDir(File::pathFixer('ui/cache/')); $ui->assign("error_title", "PHPNuxBill Crash"); - $ui->assign("error_message", $e->getMessage() . '
' . $e->getTraceAsString() . ''); + if (isset($_SESSION['uid'])) { + $ui->assign("error_message", $e->getMessage() . '
' . $e->getTraceAsString() . ''); + } $ui->display('router-error.tpl'); die(); } @@ -219,13 +223,7 @@ function _admin($login = true) function _log($description, $type = '', $userid = '0') { - $d = ORM::for_table('tbl_logs')->create(); - $d->date = date('Y-m-d H:i:s'); - $d->type = $type; - $d->description = $description; - $d->userid = $userid; - $d->ip = $_SERVER["REMOTE_ADDR"]; - $d->save(); + Log::put($type, $description, $userid); } function Lang($key) @@ -341,8 +339,11 @@ try { r2(U . 'dashboard', 'e', 'not found'); } } catch (Exception $e) { - $ui->assign("error_title", "PHPNuxBill Crash"); + if (!isset($_SESSION['aid']) || empty($_SESSION['aid'])) { + r2(U . 'home' , 'e', $e->getMessage()); + } $ui->assign("error_message", $e->getMessage() . '
' . $e->getTraceAsString() . ''); + $ui->assign("error_title", "PHPNuxBill Crash"); $ui->display('router-error.tpl'); die(); } diff --git a/system/controllers/autoload.php b/system/controllers/autoload.php index c3f18c07..d6c81d79 100644 --- a/system/controllers/autoload.php +++ b/system/controllers/autoload.php @@ -66,7 +66,7 @@ switch ($action) { if (empty($s)) { $c = ORM::for_table('tbl_customers')->limit(30)->find_many(); } else { - $c = ORM::for_table('tbl_customers')->where_raw("(`username` LIKE '%$s%' OR `fullname` LIKE '%$s%' OR `phonenumber` LIKE '%$s%' OR `email` LIKE '%$s%')", [$s, $s, $s, $s])->limit(30)->find_many(); + $c = ORM::for_table('tbl_customers')->where_raw("(`username` LIKE '%$s%' OR `fullname` LIKE '%$s%' OR `phonenumber` LIKE '%$s%' OR `email` LIKE '%$s%')")->limit(30)->find_many(); } header('Content-Type: application/json'); foreach ($c as $cust) { diff --git a/system/controllers/autoload_user.php b/system/controllers/autoload_user.php index db48f0dc..8e50773b 100644 --- a/system/controllers/autoload_user.php +++ b/system/controllers/autoload_user.php @@ -12,18 +12,18 @@ _auth(); $action = $routes['1']; $user = User::_info(); -$bill = User::_billing(); switch ($action) { case 'isLogin': + $bill = ORM::for_table('tbl_user_recharges')->where('id', $routes['2'])->where('username', $user['username'])->findOne(); if ($bill['type'] == 'Hotspot' && $bill['status'] == 'on') { $m = Mikrotik::info($bill['routers']); $client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']); if (Mikrotik::isUserLogin($client, $user['username'])) { - die(''.Lang::T('You are Online, Logout?').''); + die(''.Lang::T('You are Online, Logout?').''); } else { if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'])) { - die(''.Lang::T('Not Online, Login now?').''); + die(''.Lang::T('Not Online, Login now?').''); }else{ die(Lang::T('Your account not connected to internet')); } diff --git a/system/controllers/customers.php b/system/controllers/customers.php index 8638a271..74e8440b 100644 --- a/system/controllers/customers.php +++ b/system/controllers/customers.php @@ -32,10 +32,11 @@ switch ($action) { 'service_type' => '%' . $search . '%' ], $search); $d = ORM::for_table('tbl_customers') - ->where_raw("(`username` LIKE '%$search%' OR `fullname` LIKE '%$search%' OR `phonenumber` LIKE '%$search%' OR `email` LIKE '%$search%')", [$search, $search, $search, $search]) + ->where_raw("(`username` LIKE '%$search%' OR `fullname` LIKE '%$search%' OR `phonenumber` LIKE '%$search%' OR `email` LIKE '%$search%')") ->offset($paginator['startpoint']) ->limit($paginator['limit']) - ->order_by_desc('id')->find_many(); + ->order_by_asc('username') + ->find_many(); } else { $paginator = Paginator::build(ORM::for_table('tbl_customers')); $d = ORM::for_table('tbl_customers') @@ -226,7 +227,7 @@ switch ($action) { $password = _post('password'); $pppoe_password = _post('pppoe_password'); $email = _post('email'); - $address = _post('address'); + $address = _post('address'); $phonenumber = _post('phonenumber'); $service_type = _post('service_type'); run_hook('add_customer'); #HOOK diff --git a/system/controllers/dashboard.php b/system/controllers/dashboard.php index fdef3aee..1adbe93a 100644 --- a/system/controllers/dashboard.php +++ b/system/controllers/dashboard.php @@ -57,7 +57,7 @@ $expire = ORM::for_table('tbl_user_recharges') ->where_lte('expiration', $mdate) ->offset($paginator['startpoint']) ->limit($paginator['limit']) - ->order_by_desc('id') + ->order_by_desc('expiration') ->find_many(); // Get the total count of expired records for pagination @@ -67,7 +67,6 @@ $totalCount = ORM::for_table('tbl_user_recharges') // Pass the total count and current page to the paginator $paginator['total_count'] = $totalCount; -$paginator['current_page'] = $paginator['current_page']; // Assign the pagination HTML to the template variable $ui->assign('paginator', $paginator); diff --git a/system/controllers/home.php b/system/controllers/home.php index cbe92eb6..e480b92a 100644 --- a/system/controllers/home.php +++ b/system/controllers/home.php @@ -84,33 +84,35 @@ if (_post('send') == 'balance') { 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')); + r2(U . 'home', 'w', Lang::T('Your friend do not have active package')); } } -//Client Page -$bill = User::_billing(); -$ui->assign('_bill', $bill); +$ui->assign('_bills', User::_billing()); -if(isset($_GET['recharge']) && $_GET['recharge'] == 1){ - $router = ORM::for_table('tbl_routers')->where('name', $bill['routers'])->find_one(); - if ($config['enable_balance'] == 'yes') { - $plan = ORM::for_table('tbl_plans')->find_one($bill['plan_id']); - if($user['balance']>$plan['price']){ - r2(U . "order/pay/$router[id]/$bill[plan_id]", 'e', 'Order Plan'); - }else{ +if (isset($_GET['recharge']) && !empty($_GET['recharge'])) { + $bill = ORM::for_table('tbl_user_recharges')->where('id', $_GET['recharge'])->where('username', $user['username'])->findOne(); + if ($bill) { + $router = ORM::for_table('tbl_routers')->where('name', $bill['routers'])->find_one(); + if ($config['enable_balance'] == 'yes') { + $plan = ORM::for_table('tbl_plans')->find_one($bill['plan_id']); + if ($user['balance'] > $plan['price']) { + r2(U . "order/pay/$router[id]/$bill[plan_id]", 'e', 'Order Plan'); + } else { + r2(U . "order/buy/$router[id]/$bill[plan_id]", 'e', 'Order Plan'); + } + } else { r2(U . "order/buy/$router[id]/$bill[plan_id]", 'e', 'Order Plan'); } - }else{ - r2(U . "order/buy/$router[id]/$bill[plan_id]", 'e', 'Order Plan'); } -}else if(isset($_GET['deactivate']) && $_GET['deactivate'] == 1){ +} else if (isset($_GET['deactivate']) && !empty($_GET['deactivate'])) { + $bill = ORM::for_table('tbl_user_recharges')->where('id', $_GET['deactivate'])->where('username', $user['username'])->findOne(); if ($bill) { $p = ORM::for_table('tbl_plans')->where('id', $bill['plan_id'])->find_one(); - if($p['is_radius']){ + if ($p['is_radius']) { Radius::customerDeactivate($user['username']); - }else{ - try{ + } else { + try { $mikrotik = Mikrotik::info($bill['routers']); $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); if ($bill['type'] == 'Hotspot') { @@ -120,7 +122,7 @@ if(isset($_GET['recharge']) && $_GET['recharge'] == 1){ Mikrotik::removePpoeUser($client, $bill['username']); Mikrotik::removePpoeActive($client, $bill['username']); } - }catch(Exception $e){ + } catch (Exception $e) { //ignore it maybe mikrotik has been deleted } } @@ -128,10 +130,10 @@ if(isset($_GET['recharge']) && $_GET['recharge'] == 1){ $bill->expiration = date('Y-m-d'); $bill->time = date('H:i:s'); $bill->save(); - _log('User ' . $bill['username'] . ' Deactivate '.$bill['namebp'], 'User', $bill['customer_id']); - Message::sendTelegram('User u' . $bill['username'] . ' Deactivate '.$bill['namebp']); - r2(U . 'home', 's', 'Success deactivate '.$bill['namebp']); - }else{ + _log('User ' . $bill['username'] . ' Deactivate ' . $bill['namebp'], 'User', $bill['customer_id']); + Message::sendTelegram('User u' . $bill['username'] . ' Deactivate ' . $bill['namebp']); + r2(U . 'home', 's', 'Success deactivate ' . $bill['namebp']); + } else { r2(U . 'home', 'e', 'No Active Plan'); } } @@ -139,6 +141,7 @@ if(isset($_GET['recharge']) && $_GET['recharge'] == 1){ if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'])) { $ui->assign('nux_mac', $_SESSION['nux-mac']); $ui->assign('nux_ip', $_SESSION['nux-ip']); + $bill = ORM::for_table('tbl_user_recharges')->where('id', $_GET['id'])->where('username', $user['username'])->findOne(); if ($_GET['mikrotik'] == 'login') { $m = Mikrotik::info($bill['routers']); $c = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']); diff --git a/system/controllers/login.php b/system/controllers/login.php index 8a491dd6..e50eb9a9 100644 --- a/system/controllers/login.php +++ b/system/controllers/login.php @@ -42,8 +42,117 @@ switch ($do) { break; + case 'activation': + $voucher = _post('voucher'); + $username = _post('username'); + $v1 = ORM::for_table('tbl_voucher')->where('code', $voucher)->find_one(); + if ($v1) { + // voucher exists, check customer exists or not + $user = ORM::for_table('tbl_customers')->where('username', $username)->find_one(); + if (!$user) { + $d = ORM::for_table('tbl_customers')->create(); + $d->username = alphanumeric($username, "+_."); + $d->password = $voucher; + $d->fullname = ''; + $d->address = ''; + $d->email = ''; + $d->phonenumber = (strlen($username) < 21) ? $username : ''; + if ($d->save()) { + $user = ORM::for_table('tbl_customers')->where('username', $username)->find_one($d->id()); + if (!$user) { + r2(U . 'login', 'e', Lang::T('Voucher activation failed')); + } + } else { + r2(U . 'login', 'e', Lang::T('Voucher activation failed') . '.'); + } + } + if ($v1['status'] == 0) { + $oldPass = $user['password']; + // change customer password to voucher code + $user->password = $voucher; + $user->save(); + // voucher activation + if (Package::rechargeUser($user['id'], $v1['routers'], $v1['id_plan'], "Voucher", $voucher)) { + $v1->status = "1"; + $v1->user = $user['username']; + $v1->save(); + $user->last_login = date('Y-m-d H:i:s'); + $user->save(); + // add customer to mikrotik + if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'])) { + try { + $m = Mikrotik::info($v1['routers']); + $c = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']); + Mikrotik::logMeIn($c, $user['username'], $user['password'], $_SESSION['nux-ip'], $_SESSION['nux-mac']); + if (!empty($config['voucher_redirect'])) { + r2($config['voucher_redirect'], 's', Lang::T("Voucher activation success, you are connected to internet")); + } else { + r2(U . "login", 's', Lang::T("Voucher activation success, you are connected to internet")); + } + } catch (Exception $e) { + if (!empty($config['voucher_redirect'])) { + r2($config['voucher_redirect'], 's', Lang::T("Voucher activation success, now you can login")); + } else { + r2(U . "login", 's', Lang::T("Voucher activation success, now you can login")); + } + } + } + if (!empty($config['voucher_redirect'])) { + r2($config['voucher_redirect'], 's', Lang::T("Voucher activation success, now you can login")); + } else { + r2(U . "login", 's', Lang::T("Voucher activation success, now you can login")); + } + } else { + // if failed to recharge, restore old password + $user->password = $oldPass; + $user->save(); + r2(U . 'login', 'e', Lang::T("Failed to activate voucher")); + } + } else { + // used voucher + // check if voucher used by this username + if ($v1['user'] == $user['username']) { + $user->last_login = date('Y-m-d H:i:s'); + $user->save(); + if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'])) { + try { + $m = Mikrotik::info($v1['routers']); + $c = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']); + Mikrotik::logMeIn($c, $user['username'], $user['password'], $_SESSION['nux-ip'], $_SESSION['nux-mac']); + if (!empty($config['voucher_redirect'])) { + r2($config['voucher_redirect'], 's', Lang::T("Voucher activation success, you are connected to internet")); + } else { + r2(U . "login", 's', Lang::T("Voucher activation success, now you can login")); + } + } catch (Exception $e) { + if (!empty($config['voucher_redirect'])) { + r2($config['voucher_redirect'], 's', Lang::T("Voucher activation success, now you can login")); + } else { + r2(U . "login", 's', Lang::T("Voucher activation success, now you can login")); + } + } + } else { + if (!empty($config['voucher_redirect'])) { + r2($config['voucher_redirect'], 's', Lang::T("Voucher activation success, you are connected to internet")); + } else { + r2(U . "login", 's', Lang::T("Voucher activation success, now you can login")); + } + } + } else { + // voucher used by other customer + r2(U . 'login', 'e', $_L['Voucher_Not_Valid']); + } + } + } else { + _msglog('e', $_L['Invalid_Username_or_Password']); + r2(U . 'login'); + } default: run_hook('customer_view_login'); #HOOK - $ui->display('user-login.tpl'); + if ($config['disable_registration'] == 'yes') { + $ui->display('user-login-noreg.tpl'); + } else { + $ui->display('user-login.tpl'); + } break; } diff --git a/system/controllers/prepaid.php b/system/controllers/prepaid.php index 7509c0d8..ea521c8a 100644 --- a/system/controllers/prepaid.php +++ b/system/controllers/prepaid.php @@ -171,7 +171,7 @@ switch ($action) { $d = ORM::for_table('tbl_user_recharges')->find_one($id); if ($d) { $ui->assign('d', $d); - $p = ORM::for_table('tbl_plans')->where('enabled', '1')->find_many(); + $p = ORM::for_table('tbl_plans')->where('enabled', '1')->where_not_equal('type', 'Balance')->find_many(); $ui->assign('p', $p); run_hook('view_edit_customer_plan'); #HOOK $ui->display('prepaid-edit.tpl'); @@ -219,7 +219,11 @@ switch ($action) { } else { $msg .= $_L['Data_Not_Found'] . '