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 @@ +[![ReadMeSupportPalestine](https://raw.githubusercontent.com/Safouene1/support-palestine-banner/master/banner-project.svg)](https://s.id/standwithpalestine) + # PHPNuxBill - PHP Mikrotik Billing ![PHPNuxBill](install/img/logo.png) -![StandWithPalestine](https://raw.githubusercontent.com/Safouene1/support-palestine-banner/master/StandWithPalestine.svg) - ## 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() . '
'); + }else{ + $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'] . '
'; } - + $p = ORM::for_table('tbl_plans')->where('id', $id_plan)->where('enabled', '1')->find_one(); + if ($d) { + } else { + $msg .= ' Plan Not Found
'; + } if ($msg == '') { run_hook('edit_customer_plan'); #HOOK $d->username = $username; @@ -227,8 +231,13 @@ switch ($action) { //$d->recharged_on = $recharged_on; $d->expiration = $expiration; $d->time = $time; + if($p['is_radius']){ + $d->routers = 'radius'; + }else{ + $d->routers = $p['routers']; + } $d->save(); - Package::changeTo($username, $id_plan); + Package::changeTo($username, $id_plan, $id); _log('[' . $admin['username'] . ']: ' . 'Edit Plan for Customer ' . $d['username'] . ' to [' . $d['plan_name'] . '][' . Lang::moneyFormat($d['price']) . ']', 'Admin', $admin['id']); r2(U . 'prepaid/list', 's', $_L['Updated_Successfully']); } else { @@ -238,7 +247,7 @@ switch ($action) { case 'voucher': $ui->assign('xfooter', ''); - + $ui->assign('_title', $_L['Prepaid_Vouchers']); $code = _post('code'); if ($code != '') { $ui->assign('code', $code); @@ -265,7 +274,7 @@ switch ($action) { break; case 'add-voucher': - + $ui->assign('_title', $_L['Add_Voucher']); $c = ORM::for_table('tbl_customers')->find_many(); $ui->assign('c', $c); $p = ORM::for_table('tbl_plans')->where('enabled', '1')->find_many(); @@ -276,6 +285,18 @@ switch ($action) { $ui->display('voucher-add.tpl'); break; + case 'remove-voucher': + $d = ORM::for_table('tbl_voucher')->where_equal('status', '1')->findMany(); + if ($d) { + $jml = 0; + foreach ($d as $v) { + if(!ORM::for_table('tbl_user_recharges')->where_equal("method",'Voucher - '.$v['code'])->findOne()){ + $v->delete(); + $jml++; + } + } + r2(U . 'prepaid/voucher', 's', "$jml ".$_L['Delete_Successfully']); + } case 'print-voucher': $from_id = _post('from_id'); $planid = _post('planid'); @@ -378,6 +399,8 @@ switch ($action) { case 'voucher-post': $type = _post('type'); $plan = _post('plan'); + $voucher_format = _post('voucher_format'); + $prefix = _post('prefix'); $server = _post('server'); $numbervoucher = _post('numbervoucher'); $lengthcode = _post('lengthcode'); @@ -393,19 +416,31 @@ switch ($action) { $msg .= 'The Length Code must be a number' . '
'; } if ($msg == '') { + if(!empty($prefix)){ + $d = ORM::for_table('tbl_appconfig')->where('setting', 'voucher_prefix')->find_one(); + if ($d) { + $d->value = $prefix; + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = 'voucher_prefix'; + $d->value = $prefix; + $d->save(); + } + } run_hook('create_voucher'); #HOOK for ($i = 0; $i < $numbervoucher; $i++) { $code = strtoupper(substr(md5(time() . rand(10000, 99999)), 0, $lengthcode)); - if ($config['voucher_format'] == 'low') { + if ($voucher_format == 'low') { $code = strtolower($code); - } else if ($config['voucher_format'] == 'rand') { + } else if ($voucher_format == 'rand') { $code = Lang::randomUpLowCase($code); } $d = ORM::for_table('tbl_voucher')->create(); $d->type = $type; $d->routers = $server; $d->id_plan = $plan; - $d->code = $code; + $d->code = $prefix.$code; $d->user = '0'; $d->status = '0'; $d->save(); @@ -442,7 +477,7 @@ switch ($action) { run_hook('refill_customer'); #HOOK if ($v1) { - if (Package::rechargeUser($user['id'], $v1['routers'], $v1['id_plan'], "Refill", "Voucher")) { + if (Package::rechargeUser($user['id'], $v1['routers'], $v1['id_plan'], "Voucher", $code)) { $v1->status = "1"; $v1->user = $user['username']; $v1->save(); diff --git a/system/controllers/settings.php b/system/controllers/settings.php index 989d1514..346d695d 100644 --- a/system/controllers/settings.php +++ b/system/controllers/settings.php @@ -38,8 +38,14 @@ switch ($action) { $themes[] = $file; } } - $php = trim(shell_exec('which php')); - if (empty($php)) { + $r = ORM::for_table('tbl_routers')->find_many(); + $ui->assign('r', $r); + if (function_exists("shell_exec")) { + $php = trim(shell_exec('which php')); + if (empty($php)) { + $php = 'php'; + } + } else { $php = 'php'; } $ui->assign('php', $php); @@ -237,27 +243,7 @@ switch ($action) { break; case 'app-post': - $company = _post('company'); - $footer = _post('footer'); - $enable_balance = _post('enable_balance'); - $allow_balance_transfer = _post('allow_balance_transfer'); - $disable_voucher = _post('disable_voucher'); - $telegram_bot = _post('telegram_bot'); - $telegram_target_id = _post('telegram_target_id'); - $sms_url = _post('sms_url'); - $wa_url = _post('wa_url'); - $minimum_transfer = _post('minimum_transfer'); - $user_notification_expired = _post('user_notification_expired'); - $user_notification_reminder = _post('user_notification_reminder'); - $user_notification_payment = _post('user_notification_payment'); - $address = _post('address'); - $tawkto = _post('tawkto'); - $http_proxy = _post('http_proxy'); - $http_proxyauth = _post('http_proxyauth'); - $radius_enable = _post('radius_enable'); - $radius_client = _post('radius_client'); - $theme = _post('theme'); - $voucher_format = _post('voucher_format'); + $company = _post('CompanyName'); run_hook('save_settings'); #HOOK @@ -273,210 +259,9 @@ switch ($action) { if ($company == '') { r2(U . 'settings/app', 'e', $_L['All_field_is_required']); } else { - $d = ORM::for_table('tbl_appconfig')->where('setting', 'CompanyName')->find_one(); - $d->value = $company; - $d->save(); - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'address')->find_one(); - $d->value = $address; - $d->save(); - - $phone = _post('phone'); - $d = ORM::for_table('tbl_appconfig')->where('setting', 'phone')->find_one(); - $d->value = $phone; - $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', 'theme')->find_one(); - if ($d) { - $d->value = $theme; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'theme'; - $d->value = $theme; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'CompanyFooter')->find_one(); - if ($d) { - $d->value = $footer; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'CompanyFooter'; - $d->value = $footer; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'voucher_format')->find_one(); - if ($d) { - $d->value = $voucher_format; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'voucher_format'; - $d->value = $voucher_format; - $d->save(); - } - $d = ORM::for_table('tbl_appconfig')->where('setting', 'disable_voucher')->find_one(); - if ($d) { - $d->value = $disable_voucher; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'disable_voucher'; - $d->value = $disable_voucher; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'enable_balance')->find_one(); - if ($d) { - $d->value = $enable_balance; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'enable_balance'; - $d->value = $enable_balance; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'allow_balance_transfer')->find_one(); - if ($d) { - $d->value = $allow_balance_transfer; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'allow_balance_transfer'; - $d->value = $allow_balance_transfer; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'minimum_transfer')->find_one(); - if ($d) { - $d->value = $minimum_transfer; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'minimum_transfer'; - $d->value = $minimum_transfer; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'telegram_bot')->find_one(); - if ($d) { - $d->value = $telegram_bot; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'telegram_bot'; - $d->value = $telegram_bot; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'telegram_target_id')->find_one(); - if ($d) { - $d->value = $telegram_target_id; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'telegram_target_id'; - $d->value = $telegram_target_id; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'sms_url')->find_one(); - if ($d) { - $d->value = $sms_url; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'sms_url'; - $d->value = $sms_url; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'wa_url')->find_one(); - if ($d) { - $d->value = $wa_url; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'wa_url'; - $d->value = $wa_url; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'user_notification_expired')->find_one(); - if ($d) { - $d->value = $user_notification_expired; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'user_notification_expired'; - $d->value = $user_notification_expired; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'user_notification_reminder')->find_one(); - if ($d) { - $d->value = $user_notification_reminder; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'user_notification_reminder'; - $d->value = $user_notification_reminder; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'user_notification_payment')->find_one(); - if ($d) { - $d->value = $user_notification_payment; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'user_notification_payment'; - $d->value = $user_notification_payment; - $d->save(); - } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'tawkto')->find_one(); - if ($d) { - $d->value = $tawkto; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'tawkto'; - $d->value = $tawkto; - $d->save(); - } - if ($radius_enable) { try { - Radius::getTableNas()->find_one(1); + Radius::getTableNas()->find_many(); } catch (Exception $e) { $ui->assign("error_title", "RADIUS Error"); $ui->assign("error_message", "Radius table not found.

" . @@ -486,34 +271,20 @@ switch ($action) { die(); } } - - $d = ORM::for_table('tbl_appconfig')->where('setting', 'radius_enable')->find_one(); - if ($d) { - $d->value = $radius_enable; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'radius_enable'; - $d->value = $radius_enable; - $d->save(); + // save all settings + foreach($_POST as $key => $value) { + $d = ORM::for_table('tbl_appconfig')->where('setting', $key)->find_one(); + if ($d) { + $d->value = $value; + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = $key; + $d->value = $value; + $d->save(); + } } - $d = ORM::for_table('tbl_appconfig')->where('setting', 'radius_client')->find_one(); - if ($d) { - $d->value = $radius_client; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'radius_client'; - $d->value = $radius_client; - $d->save(); - } - - $note = _post('note'); - $d = ORM::for_table('tbl_appconfig')->where('setting', 'note')->find_one(); - $d->value = $note; - $d->save(); - _log('[' . $admin['username'] . ']: ' . $_L['Settings_Saved_Successfully'], 'Admin', $admin['id']); r2(U . 'settings/app', 's', $_L['Settings_Saved_Successfully']); diff --git a/system/controllers/voucher.php b/system/controllers/voucher.php index c491430e..747f2766 100644 --- a/system/controllers/voucher.php +++ b/system/controllers/voucher.php @@ -11,8 +11,6 @@ $action = $routes['1']; $user = User::_info(); $ui->assign('_user', $user); -use PEAR2\Net\RouterOS; - require_once 'system/autoload/PEAR2/Autoload.php'; switch ($action) { @@ -27,7 +25,7 @@ switch ($action) { $v1 = ORM::for_table('tbl_voucher')->where('code', $code)->where('status', 0)->find_one(); run_hook('customer_activate_voucher'); #HOOK if ($v1) { - if (Package::rechargeUser($user['id'], $v1['routers'], $v1['id_plan'], "Activation", "Voucher")) { + if (Package::rechargeUser($user['id'], $v1['routers'], $v1['id_plan'], "Voucher", $code)) { $v1->status = "1"; $v1->user = $user['username']; $v1->save(); diff --git a/system/cron.php b/system/cron.php index 869b06e6..98a2d833 100644 --- a/system/cron.php +++ b/system/cron.php @@ -118,7 +118,7 @@ foreach ($d as $ds) { if (empty($p['pool_expired'])) { print_r(Radius::customerDeactivate($c['username'])); } else { - Radius::upsertCustomerAttr($c['username'], 'Framed-Pool', $plan['pool_expired'], ':='); + Radius::upsertCustomerAttr($c['username'], 'Framed-Pool', $p['pool_expired'], ':='); print_r(Radius::disconnectCustomer($c['username'])); } } else { @@ -172,7 +172,7 @@ foreach ($d as $ds) { if (empty($p['pool_expired'])) { print_r(Radius::customerDeactivate($c['username'])); } else { - Radius::upsertCustomerAttr($c['username'], 'Framed-Pool', $plan['pool_expired'], ':='); + Radius::upsertCustomerAttr($c['username'], 'Framed-Pool', $p['pool_expired'], ':='); print_r(Radius::disconnectCustomer($c['username'])); } } else { diff --git a/system/lan/english/common.lan.php b/system/lan/english/common.lan.php index 9bbfa137..acba8dd2 100644 --- a/system/lan/english/common.lan.php +++ b/system/lan/english/common.lan.php @@ -408,3 +408,14 @@ $_L['Change_title_in_user_Plan_order'] = 'Change title in user Plan order'; $_L['Logs'] = 'Logs'; $_L['Voucher_Format'] = 'Voucher Format'; $_L['Resend_To_Customer'] = 'Resend To Customer'; +$_L['Your_friend_do_not_have_active_package'] = 'Your friend do not have active package'; +$_L['Service_Type'] = 'Service Type'; +$_L['Others'] = 'Others'; +$_L['PPPoE'] = 'PPPoE'; +$_L['Hotspot'] = 'Hotspot'; +$_L['Disable_Registration'] = 'Disable Registration'; +$_L['Customer_just_Login_with_Phone_number_and_Voucher_Code_Voucher_will_be_password'] = 'Customer just Login with Phone number and Voucher Code, Voucher will be password'; +$_L['Login__Activate_Voucher'] = 'Login / Activate Voucher'; +$_L['After_Customer_activate_voucher_or_login_customer_will_be_redirected_to_this_url'] = 'After Customer activate voucher or login, customer will be redirected to this url'; +$_L['Voucher_Prefix'] = 'Voucher Prefix'; +$_L['Voucher_activation_success_now_you_can_login'] = 'Voucher activation success, now you can login'; diff --git a/system/lan/indonesia/common.lan.php b/system/lan/indonesia/common.lan.php index f30d36fc..f6a88e37 100644 --- a/system/lan/indonesia/common.lan.php +++ b/system/lan/indonesia/common.lan.php @@ -408,3 +408,7 @@ $_L['Change_title_in_user_Plan_order'] = 'Ubah judul dalam urutan paket pelangga $_L['Logs'] = 'Log'; $_L['Voucher_Format'] = 'Format Voucher'; $_L['Resend_To_Customer'] = 'Kirim Ulang Ke Pelanggan'; +$_L['Service_Type'] = 'Service Type'; +$_L['Others'] = 'Lainnya'; +$_L['PPPoE'] = 'PPPoE'; +$_L['Hotspot'] = 'Hotspot'; \ No newline at end of file diff --git a/system/lan/spanish/common.lan.php b/system/lan/spanish/common.lan.php index 2c13913a..12dcc111 100644 --- a/system/lan/spanish/common.lan.php +++ b/system/lan/spanish/common.lan.php @@ -401,4 +401,8 @@ $_L['Deactivate'] = 'Deactivate'; $_L['Sync'] = 'Sync'; $_L['Failed_to_create_PaymeTrust_transaction'] = 'Failed to create PaymeTrust transaction.'; $_L['Location'] = 'Location'; -$_L['Voucher_Format'] = 'Voucher Format'; \ No newline at end of file +$_L['Voucher_Format'] = 'Voucher Format'; +$_L['Service_Type'] = 'Service Type'; +$_L['Others'] = 'Others'; +$_L['PPPoE'] = 'PPPoE'; +$_L['Hotspot'] = 'Hotspot'; \ No newline at end of file diff --git a/system/lan/turkish/common.lan.php b/system/lan/turkish/common.lan.php index d7d5dd59..c7b5a60b 100755 --- a/system/lan/turkish/common.lan.php +++ b/system/lan/turkish/common.lan.php @@ -378,4 +378,8 @@ $_L['Deactivate'] = 'Deactivate'; $_L['Sync'] = 'Sync'; $_L['Failed_to_create_PaymeTrust_transaction'] = 'Failed to create PaymeTrust transaction.'; $_L['Location'] = 'Location'; -$_L['Voucher_Format'] = 'Voucher Format'; \ No newline at end of file +$_L['Voucher_Format'] = 'Voucher Format'; +$_L['Service_Type'] = 'Service Type'; +$_L['Others'] = 'Others'; +$_L['PPPoE'] = 'PPPoE'; +$_L['Hotspot'] = 'Hotspot'; \ No newline at end of file diff --git a/ui/ui/admin-login.tpl b/ui/ui/admin-login.tpl index 81315094..2587d8f0 100644 --- a/ui/ui/admin-login.tpl +++ b/ui/ui/admin-login.tpl @@ -7,10 +7,9 @@ {$_title} - {$_L['Login']} - - - + + @@ -37,9 +36,6 @@ - - - \ No newline at end of file diff --git a/ui/ui/app-settings.tpl b/ui/ui/app-settings.tpl index 5fb0a3fd..f84b56f5 100644 --- a/ui/ui/app-settings.tpl +++ b/ui/ui/app-settings.tpl @@ -15,7 +15,7 @@
-
{$_L['App_Name_Help_Text']} @@ -34,7 +34,7 @@
-
{Lang::T('Will show below user pages')} @@ -113,6 +113,33 @@

UPPERCASE lowercase RaNdoM

+ {if $_c['disable_voucher'] != 'yes'} +
+ +
+ +
+

+ {Lang::T('Customer just Login with Phone number and Voucher Code, Voucher will be password')} +

+
+
+ +
+ +
+

+ {Lang::T('After Customer activate voucher or login, customer will be redirected to this url')} +

+
+ {/if}
@@ -198,7 +225,7 @@
- +
@@ -225,6 +252,22 @@ replaced.

+
+ +
+ +
+

Must include [text] & [number], it will be + replaced. +

+
You can use WhatsApp in here too. Free Server
diff --git a/ui/ui/community.tpl b/ui/ui/community.tpl index c23242c6..582c654f 100644 --- a/ui/ui/community.tpl +++ b/ui/ui/community.tpl @@ -1,5 +1,8 @@ {include file="sections/header.tpl"} +
+

+
diff --git a/ui/ui/dashboard.tpl b/ui/ui/dashboard.tpl index a063292e..77b45d13 100644 --- a/ui/ui/dashboard.tpl +++ b/ui/ui/dashboard.tpl @@ -119,7 +119,7 @@ {/foreach}
-   {$paginator['contents']} +   {$paginator['contents']}
@@ -150,7 +150,9 @@ $.getJSON("./version.json?" + Math.random(), function(data) { var localVersion = data.version; $('#version').html('Version: ' + localVersion); - $.getJSON("https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/master/version.json?" + Math + $.getJSON( + "https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/master/version.json?" + + Math .random(), function(data) { var latestVersion = data.version; @@ -163,4 +165,4 @@ }); -{include file="sections/footer.tpl"} +{include file="sections/footer.tpl"} \ No newline at end of file diff --git a/ui/ui/logs.tpl b/ui/ui/logs.tpl index 1745db02..43390e40 100644 --- a/ui/ui/logs.tpl +++ b/ui/ui/logs.tpl @@ -44,7 +44,7 @@ {Lang::dateTimeFormat($ds['date'])} {$ds['type']} {$ds['ip']} - {$ds['description']} + {nl2br($ds['description'])} {/foreach} diff --git a/ui/ui/prepaid-edit.tpl b/ui/ui/prepaid-edit.tpl index f7d5d92a..21479973 100644 --- a/ui/ui/prepaid-edit.tpl +++ b/ui/ui/prepaid-edit.tpl @@ -23,7 +23,7 @@ diff --git a/ui/ui/register-otp.tpl b/ui/ui/register-otp.tpl index b6b25aad..ec4fc2fa 100644 --- a/ui/ui/register-otp.tpl +++ b/ui/ui/register-otp.tpl @@ -8,7 +8,8 @@ - + + diff --git a/ui/ui/register-rotp.tpl b/ui/ui/register-rotp.tpl index 7ea3f751..88a5939d 100644 --- a/ui/ui/register-rotp.tpl +++ b/ui/ui/register-rotp.tpl @@ -7,25 +7,13 @@ {$_title} - {$_L['Register']} - - - - - - - - - - - - - + + -
diff --git a/ui/ui/register.tpl b/ui/ui/register.tpl index e7b23c93..4a6a5c78 100644 --- a/ui/ui/register.tpl +++ b/ui/ui/register.tpl @@ -8,7 +8,8 @@ - + + diff --git a/ui/ui/router-error.tpl b/ui/ui/router-error.tpl index 96006450..8d42d9a0 100644 --- a/ui/ui/router-error.tpl +++ b/ui/ui/router-error.tpl @@ -13,8 +13,8 @@ - - + +