diff --git a/README.md b/README.md index 5b66ca2b..0fb8b98b 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ Click link to download Goto Discussionif you want another Payment Gateway +Some documentation + ## System Requirements Most current web servers with PHP & MySQL installed will be capable of running PHPNuxBill @@ -30,7 +32,7 @@ Most current web servers with PHP & MySQL installed will be capable of running P Minimum Requirements - Linux or Windows OS -- PHP Version 7.0+ +- PHP Version 7.2+ - Both PDO & MySQLi Support - GD2 Image Library - CURL support @@ -42,17 +44,51 @@ The problem with windows is hard to set cronjob, better Linux ## Installation -- Rename **pages_template** to **pages** -- Rename **config.sample.php** to **config.php** and make it writeable (chmod 777) -- make writeable folder **ui/cache/** and **ui/compiled** -- Open web and run installation -- set cronjobs or scheduller for **system/cron.php** -- make **config.php** unwriteable (chmod 644) +### Git Clone +clone this repository or download zip or release -See [WIKI](https://github.com/hotspotbilling/phpnuxbill/wiki/Instalation) +1. Rename **pages_template** to **pages** +2. Rename **config.sample.php** to **config.php** and make it writeable (chmod 777) +3. make writeable folder **ui/cache/** and **ui/compiled** +4. Open web and run installation +5. set [cronjob](https://github.com/hotspotbilling/phpnuxbill/wiki/Cron-Jobs) or scheduller for **system/cron.php** +6. make **config.php** unwriteable (chmod 644) -baca [WIKI](https://github.com/hotspotbilling/phpnuxbill/wiki/Instalation) +### Composer install + +Go to directory you want to install +Install Composer in your system + +```bash +# Debian/Ubuntu +sudo apt install composer +# Centos/Redhat +sudo yum install composer +``` + +install on curent directory + +```bash +composer create-project hotspotbilling/phpnuxbill . +``` + +install on new directory + +```bash +composer create-project hotspotbilling/phpnuxbill phpnuxbill +``` + +## Manual Installation + +1. Download project from [Master Branch](https://github.com/hotspotbilling/phpnuxbill/archive/refs/heads/master.zip) or from [Release](https://github.com/hotspotbilling/phpnuxbill/releases) +2. unzip and upload it to server +3. Rename **pages_template** to **pages** +4. Rename **config.sample.php** to **config.php** and make it writeable (chmod 777) +5. make writeable folder **ui/cache/** and **ui/compiled** +6. Open web and run installation +7. set [cronjob](https://github.com/hotspotbilling/phpnuxbill/wiki/Cron-Jobs) or scheduller for **system/cron.php** +8. make **config.php** unwriteable (chmod 644) ## UPDGRADE @@ -60,9 +96,12 @@ for old version, below Version 6, backup **system/config.php**, delete all file for version 6 above, just replace all files, using filezilla can choose overwrite if different file size or time. +or git pull if you use git clone + ## RADIUS system Still on development + ## Paid Support Start from Rp 500.000 or $50 diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..6efbb598 --- /dev/null +++ b/composer.json @@ -0,0 +1,16 @@ +{ + "name": "hotspotbilling/phpnuxbill", + "type": "template", + "description": "PHPNuxBill a Hotspot Billing Software.", + "keywords": ["template"], + "homepage": "https://github.com/hotspotbilling/phpnuxbill", + "license": "MIT", + "authors": [ + { + "name": "ibnux", + "email": "me@ibnux.net", + "homepage": "https://ibnux.net", + "role": "Developer" + } + ] +} diff --git a/system/autoload/App.php b/system/autoload/App.php index cac41db2..8f9c7edd 100644 --- a/system/autoload/App.php +++ b/system/autoload/App.php @@ -3,7 +3,7 @@ * PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/) **/ -Class App{ +class App{ public static function _run(){ return true; } diff --git a/system/autoload/File.php b/system/autoload/File.php new file mode 100644 index 00000000..d704f240 --- /dev/null +++ b/system/autoload/File.php @@ -0,0 +1,56 @@ +"; + $files = scandir($from); + print_r($files); + foreach ($files as $file) { + if (is_file($from . $file) && !in_array($file, $exclude)) { + if (file_exists($to . $file)) unlink($to . $file); + rename($from . $file, $to . $file); + echo "rename($from$file, $to$file);
"; + } else if (is_dir($from . $file) && !in_array($file, ['.', '..'])) { + if (!file_exists($to . $file)) { + echo "mkdir($to$file);;
"; + mkdir($to . $file); + } + echo "File::copyFolder($from$file, $to$file);
"; + File::copyFolder($from . $file . DIRECTORY_SEPARATOR, $to . $file . DIRECTORY_SEPARATOR); + } + } + } + + public static function deleteFolder($path) + { + $files = scandir($path); + foreach ($files as $file) { + if (is_file($path . $file)) { + echo "unlink($path$file);
"; + unlink($path . $file); + } else if (is_dir($path . $file) && !in_array($file, ['.', '..'])) { + File::deleteFolder($path . $file . DIRECTORY_SEPARATOR); + echo "rmdir($path$file);
"; + rmdir($path . $file); + } + } + echo "rmdir($path);
"; + rmdir($path); + } + + + /** + * file path fixer + * + * @access public + * @param string $path + * @return string + */ + public static function pathFixer($path) + { + return str_replace("/", DIRECTORY_SEPARATOR, $path); + } +} diff --git a/system/autoload/Lang.php b/system/autoload/Lang.php index f5e08e60..dc9292f6 100644 --- a/system/autoload/Lang.php +++ b/system/autoload/Lang.php @@ -8,4 +8,8 @@ class Lang { public static function T($var) { return Lang($var); } + + public static function htmlspecialchars($var) { + return htmlspecialchars($var); + } } diff --git a/system/autoload/Message.php b/system/autoload/Message.php new file mode 100644 index 00000000..0606f42c --- /dev/null +++ b/system/autoload/Message.php @@ -0,0 +1,58 @@ + 5 + && !empty($textExpired) && in_array($via, ['sms', 'wa']) + ) { + $msg = str_replace('[[name]]', "*$name*", $textExpired); + $msg = str_replace('[[package]]', "*$package*", $msg); + if ($via == 'sms') { + Message::sendSMS($phone, $msg); + } else if ($via == 'wa') { + Message::sendWhatsapp($phone, $msg); + } + } + } + +} diff --git a/system/autoload/Package.php b/system/autoload/Package.php index 53c87a46..19c0b087 100644 --- a/system/autoload/Package.php +++ b/system/autoload/Package.php @@ -51,8 +51,8 @@ class Package if ($b) { if (!$_c['radius_mode']) { $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); - Mikrotik::removeHotspotUser($client,$c['username']); - Mikrotik::addHotspotUser($client,$p,$c); + Mikrotik::removeHotspotUser($client, $c['username']); + Mikrotik::addHotspotUser($client, $p, $c); } $b->customer_id = $id_customer; @@ -84,7 +84,7 @@ class Package } else { if (!$_c['radius_mode']) { $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); - Mikrotik::addHotspotUser($client,$p,$c); + Mikrotik::addHotspotUser($client, $p, $c); } $d = ORM::for_table('tbl_user_recharges')->create(); @@ -115,7 +115,7 @@ class Package $t->type = "Hotspot"; $t->save(); } - sendTelegram("#u$c[username] #buy #Hotspot \n" . $p['name_plan'] . + Message::sendTelegram("#u$c[username] #buy #Hotspot \n" . $p['name_plan'] . "\nRouter: " . $router_name . "\nGateway: " . $gateway . "\nChannel: " . $channel . @@ -125,8 +125,8 @@ class Package if ($b) { if (!$_c['radius_mode']) { $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); - Mikrotik::removePpoeUser($client,$c['username']); - Mikrotik::addPpoeUser($client,$p,$c); + Mikrotik::removePpoeUser($client, $c['username']); + Mikrotik::addPpoeUser($client, $p, $c); } $b->customer_id = $id_customer; @@ -158,7 +158,7 @@ class Package } else { if (!$_c['radius_mode']) { $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); - Mikrotik::addPpoeUser($client,$p,$c); + Mikrotik::addPpoeUser($client, $p, $c); } $d = ORM::for_table('tbl_user_recharges')->create(); @@ -189,7 +189,7 @@ class Package $t->type = "PPPOE"; $t->save(); } - sendTelegram("#u$c[username] #buy #PPPOE \n" . $p['name_plan'] . + Message::sendTelegram("#u$c[username] #buy #PPPOE \n" . $p['name_plan'] . "\nRouter: " . $router_name . "\nGateway: " . $gateway . "\nChannel: " . $channel . @@ -198,7 +198,7 @@ class Package $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one(); - sendWhatsapp($c['username'], "*$_c[CompanyName]*\n" . + $msg = "*$_c[CompanyName]*\n" . "$_c[address]\n" . "$_c[phone]\n" . "\n\n" . @@ -214,7 +214,13 @@ class Package "$_L[Created_On] :\n*" . date($_c['date_format'], strtotime($in['recharged_on'])) . " $in[time]*\n" . "$_L[Expires_On] :\n*" . date($_c['date_format'], strtotime($in['expiration'])) . " $in[time]*\n" . "\n\n" . - "$_c[note]"); + "$_c[note]"; + + if ($_c['user_notification_payment'] == 'sms') { + Message::sendSMS($c['phonenumber'], $msg); + } else if ($_c['user_notification_payment'] == 'wa') { + Message::sendWhatsapp($c['phonenumber'], $msg); + } return true; } } diff --git a/system/autoload/Validator.php b/system/autoload/Validator.php index 4cc364d4..e7d46039 100644 --- a/system/autoload/Validator.php +++ b/system/autoload/Validator.php @@ -1,12 +1,14 @@ = $max) return false; + private static function numberBetween($integer, $max = null, $min = 0) + { + if (is_numeric($min) && $integer <= $min) return false; + if (is_numeric($max) && $integer >= $max) return false; return true; } @@ -51,8 +55,9 @@ class Validator{ * @param array $exclude * @return bool */ - public static function Email($string, $exclude=""){ - if(self::textHit($string, $exclude)) return false; + public static function Email($string, $exclude = "") + { + if (self::textHit($string, $exclude)) return false; return (bool)preg_match("/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])(([a-z0-9-])*([a-z0-9]))+(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i", $string); } @@ -63,8 +68,9 @@ class Validator{ * @param strin $string * @return bool */ - public static function Url($string, $exclude=""){ - if(self::textHit($string, $exclude)) return false; + public static function Url($string, $exclude = "") + { + if (self::textHit($string, $exclude)) return false; return (bool)preg_match("/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i", $string); } @@ -75,7 +81,8 @@ class Validator{ * @param string $string * @return void */ - public static function Ip($string){ + public static function Ip($string) + { return (bool)preg_match("/^(1?\d{1,2}|2([0-4]\d|5[0-5]))(\.(1?\d{1,2}|2([0-4]\d|5[0-5]))){3}$/", $string); } @@ -88,9 +95,10 @@ class Validator{ * @param int $min * @return bool */ - public static function Number($integer, $max=null, $min=0){ - if(preg_match("/^\-?\+?[0-9e1-9]+$/",$integer)){ - if(!self::numberBetween($integer, $max, $min)) return false; + public static function Number($integer, $max = null, $min = 0) + { + if (preg_match("/^\-?\+?[0-9e1-9]+$/", $integer)) { + if (!self::numberBetween($integer, $max, $min)) return false; return true; } return false; @@ -103,8 +111,9 @@ class Validator{ * @param int $integer * @return bool */ - public static function UnsignedNumber($integer){ - return (bool)preg_match("/^\+?[0-9]+$/",$integer); + public static function UnsignedNumber($integer) + { + return (bool)preg_match("/^\+?[0-9]+$/", $integer); } /** @@ -114,8 +123,9 @@ class Validator{ * @param string $string * @return bool */ - public static function Float($string){ - return (bool)($string==strval(floatval($string)))? true : false; + public static function Float($string) + { + return (bool)($string == strval(floatval($string))) ? true : false; } /** @@ -125,7 +135,8 @@ class Validator{ * @param string $string * @return void */ - public static function Alpha($string){ + public static function Alpha($string) + { return (bool)preg_match("/^[a-zA-Z]+$/", $string); } @@ -136,7 +147,8 @@ class Validator{ * @param string $string * @return void */ - public static function AlphaNumeric($string){ + public static function AlphaNumeric($string) + { return (bool)preg_match("/^[0-9a-zA-Z]+$/", $string); } @@ -148,7 +160,8 @@ class Validator{ * @param array $allowed * @return void */ - public static function Chars($string, $allowed=array("a-z")){ + public static function Chars($string, $allowed = array("a-z")) + { return (bool)preg_match("/^[" . implode("", $allowed) . "]+$/", $string); } @@ -161,9 +174,10 @@ class Validator{ * @param int $min * @return bool */ - public static function Length($string, $max=null, $min=0){ + public static function Length($string, $max = null, $min = 0) + { $length = strlen($string); - if(!self::numberBetween($length, $max, $min)) return false; + if (!self::numberBetween($length, $max, $min)) return false; return true; } @@ -174,7 +188,8 @@ class Validator{ * @param string $string * @return void */ - public static function HexColor($string){ + public static function HexColor($string) + { return (bool)preg_match("/^(#)?([0-9a-f]{1,2}){3}$/i", $string); } @@ -191,7 +206,8 @@ class Validator{ * @param string $string * @return bool */ - public static function Date($string){ + public static function Date($string) + { $date = date('Y', strtotime($string)); return ($date == "1970" || $date == '') ? false : true; } @@ -204,9 +220,10 @@ class Validator{ * @param int $age * @return bool */ - public static function OlderThan($string, $age){ + public static function OlderThan($string, $age) + { $date = date('Y', strtotime($string)); - if($date == "1970" || $date == '') return false; + if ($date == "1970" || $date == '') return false; return (date('Y') - $date) > $age ? true : false; } @@ -217,7 +234,8 @@ class Validator{ * @param string $string * @return bool */ - public static function Xml($string){ + public static function Xml($string) + { $Xml = @simplexml_load_string($string); return ($Xml === false) ? false : true; } @@ -231,7 +249,8 @@ class Validator{ * @param int $min * @return bool */ - public static function FilesizeBetween($file, $max=null, $min=0){ + public static function FilesizeBetween($file, $max = null, $min = 0) + { $filesize = filesize($file); return self::numberBetween($filesize, $max, $min); } @@ -247,10 +266,11 @@ class Validator{ * @param int $min_height * @return void */ - public static function ImageSizeBetween($image, $max_width="", $min_width=0, $max_height="", $min_height=0){ + public static function ImageSizeBetween($image, $max_width = "", $min_width = 0, $max_height = "", $min_height = 0) + { $size = getimagesize($image); - if(!self::numberBetween($size[0], $max_width, $min_width)) return false; - if(!self::numberBetween($size[1], $max_height, $min_height)) return false; + if (!self::numberBetween($size[0], $max_width, $min_width)) return false; + if (!self::numberBetween($size[1], $max_height, $min_height)) return false; return true; } @@ -261,8 +281,10 @@ class Validator{ * @param string $phone * @return bool */ - public static function Phone($phone){ - $formats = array( '###-###-####', + public static function Phone($phone) + { + $formats = array( + '###-###-####', '####-###-###', '(###) ###-###', '####-####-####', @@ -271,9 +293,10 @@ class Validator{ '###-###-###', '#####-###-###', '##########', - '####-##-##-##'); + '####-##-##-##' + ); $format = trim(preg_replace("/[0-9]/", "#", $phone)); return (bool)in_array($format, $formats); } -} \ No newline at end of file +} diff --git a/system/boot.php b/system/boot.php index 01c4d67c..2b55909b 100644 --- a/system/boot.php +++ b/system/boot.php @@ -228,40 +228,6 @@ function alphanumeric($str, $tambahan = "") return preg_replace("/[^a-zA-Z0-9" . $tambahan . "]+/", "", $str); } - -function sendTelegram($txt) -{ - global $config; - run_hook('send_telegram'); #HOOK - if (!empty($config['telegram_bot']) && !empty($config['telegram_target_id'])) { - file_get_contents('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $config['telegram_target_id'] . '&text=' . urlencode($txt)); - } -} - - -function sendSMS($phone, $txt) -{ - 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); - file_get_contents($smsurl); - } -} - -function sendWhatsapp($phone, $txt) -{ - global $config; - run_hook('send_whatsapp'); #HOOK - if (!empty($config['wa_url'])) { - $waurl = str_replace('[number]', urlencode($phone), $config['wa_url']); - $waurl = str_replace('[text]', urlencode($txt), $waurl); - file_get_contents($waurl); - } -} - - function time_elapsed_string($datetime, $full = false) { $now = new DateTime; diff --git a/system/controllers/customers.php b/system/controllers/customers.php index 8f412fed..21ea411f 100644 --- a/system/controllers/customers.php +++ b/system/controllers/customers.php @@ -79,6 +79,7 @@ switch ($action) { try { $d->delete(); } catch (Exception $e) { + } catch(Throwable $e){ } try { $c->delete(); @@ -88,10 +89,12 @@ switch ($action) { try { $d->delete(); } catch (Exception $e) { + } catch(Throwable $e){ } try { $c->delete(); } catch (Exception $e) { + } catch(Throwable $e){ } } diff --git a/system/controllers/pluginmanager.php b/system/controllers/pluginmanager.php new file mode 100644 index 00000000..d160c01f --- /dev/null +++ b/system/controllers/pluginmanager.php @@ -0,0 +1,124 @@ +assign('_title', $_L['Plugin Manager']); +$ui->assign('_system_menu', 'settings'); + +$plugin_repository = 'https://hotspotbilling.github.io/Plugin-Repository/repository.json'; + +$action = $routes['1']; +$admin = Admin::_info(); +$ui->assign('_admin', $admin); + + +if ($admin['user_type'] != 'Admin') { + r2(U . "dashboard", 'e', $_L['Do_Not_Access']); +} + +$cache = File::pathFixer('system/cache/plugin_repository.json'); +if (file_exists($cache) && time() - filemtime($cache) > (24 * 60 * 60)) { + $json = json_decode(file_get_contents($cache), true); +} else { + $data = file_get_contents($plugin_repository); + file_put_contents($cache, $data); + $json = json_decode($data, true); +} + +switch ($action) { + + case 'install': + if(!is_writeable(File::pathFixer('system/cache/'))){ + r2(U . "pluginmanager", 'e', 'Folder system/cache/ is not writable'); + } + if(!is_writeable(File::pathFixer('system/plugin/'))){ + r2(U . "pluginmanager", 'e', 'Folder system/plugin/ is not writable'); + } + set_time_limit(-1); + $tipe = $routes['2']; + $plugin = $routes['3']; + $file = File::pathFixer('system/cache/') . $plugin . '.zip'; + if (file_exists($file)) unlink($file); + if ($tipe == 'plugin') { + foreach ($json['plugins'] as $plg) { + if ($plg['id'] == $plugin) { + $fp = fopen($file, 'w+'); + $ch = curl_init($plg['github'].'/archive/refs/heads/master.zip'); + curl_setopt($ch, CURLOPT_POST, 0); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); + curl_setopt($ch, CURLOPT_TIMEOUT, 15); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_exec($ch); + curl_close($ch); + fclose($fp); + + $zip = new ZipArchive(); + $zip->open($file); + $zip->extractTo(File::pathFixer('system/cache/')); + $zip->close(); + $folder = File::pathFixer('system/cache/' . $plugin.'-main/'); + if(!file_exists($folder)){ + $folder = File::pathFixer('system/cache/' . $plugin.'-master/'); + } + if(!file_exists($folder)){ + r2(U . "pluginmanager", 'e', 'Extracted Folder is unknown'); + } + File::copyFolder($folder, File::pathFixer('system/plugin/'), ['README.md','LICENSE']); + File::deleteFolder($folder); + unlink($file); + r2(U . "pluginmanager", 's', 'Plugin '.$plugin.' has been installed'); + break; + } + } + break; + } else if ($tipe == 'payment') { + foreach ($json['payment_gateway'] as $plg) { + if ($plg['id'] == $plugin) { + $fp = fopen($file, 'w+'); + $ch = curl_init($plg['github'].'/archive/refs/heads/master.zip'); + curl_setopt($ch, CURLOPT_POST, 0); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); + curl_setopt($ch, CURLOPT_TIMEOUT, 15); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_exec($ch); + curl_close($ch); + fclose($fp); + + $zip = new ZipArchive(); + $zip->open($file); + $zip->extractTo(File::pathFixer('system/cache/')); + $zip->close(); + $folder = File::pathFixer('system/cache/' . $plugin.'-main/'); + if(!file_exists($folder)){ + $folder = File::pathFixer('system/cache/' . $plugin.'-master/'); + } + if(!file_exists($folder)){ + r2(U . "pluginmanager", 'e', 'Extracted Folder is unknown'); + } + File::copyFolder($folder, File::pathFixer('system/paymentgateway/'), ['README.md','LICENSE']); + File::deleteFolder($folder); + unlink($file); + r2(U . "paymentgateway", 's', 'Payment Gateway '.$plugin.' has been installed'); + break; + } + } + break; + } + default: + if (class_exists('ZipArchive')) { + $zipExt = true; + } else { + $zipExt = false; + } + $ui->assign('zipExt', $zipExt); + $ui->assign('plugins', $json['plugins']); + $ui->assign('pgs', $json['payment_gateway']); + $ui->display('plugin-manager.tpl'); +} diff --git a/system/controllers/prepaid.php b/system/controllers/prepaid.php index 90fe7b93..4aa267a1 100644 --- a/system/controllers/prepaid.php +++ b/system/controllers/prepaid.php @@ -169,7 +169,7 @@ switch ($action) { $t->type = "Hotspot"; $t->save(); } - sendTelegram( "$admin[fullname] #Recharge Voucher #Hotspot for #u$c[username]\n".$p['name_plan']. + Message::sendTelegram( "$admin[fullname] #Recharge Voucher #Hotspot for #u$c[username]\n".$p['name_plan']. "\nRouter: ".$server. "\nPrice: ".$p['price']); } else { @@ -241,7 +241,7 @@ switch ($action) { $t->type = "PPPOE"; $t->save(); } - sendTelegram( "$admin[fullname] #Recharge Voucher #PPPOE for #u$c[username]\n".$p['name_plan']. + Message::sendTelegram( "$admin[fullname] #Recharge Voucher #PPPOE for #u$c[username]\n".$p['name_plan']. "\nRouter: ".$server. "\nPrice: ".$p['price']); } @@ -249,7 +249,7 @@ switch ($action) { $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one(); $ui->assign('in', $in); - sendWhatsapp($c['username'], "*$config[CompanyName]*\n". + $msg = "*$config[CompanyName]*\n". "$config[address]\n". "$config[phone]\n". "\n\n". @@ -265,8 +265,13 @@ switch ($action) { "$_L[Created_On] :\n*".date($config['date_format'], strtotime($in['recharged_on']))." $in[time]*\n". "$_L[Expires_On] :\n*".date($config['date_format'], strtotime($in['expiration']))." $in[time]*\n". "\n\n". - "$config[note]"); + "$config[note]"; + if ($_c['user_notification_payment'] == 'sms') { + Message::sendSMS($c['phonenumber'], $msg); + } else if ($_c['user_notification_payment'] == 'wa') { + Message::sendWhatsapp($c['phonenumber'], $msg); + } $ui->assign('date', $date_now); $ui->display('invoice.tpl'); @@ -631,7 +636,7 @@ switch ($action) { $v1->user = $c['username']; $v1->save(); - sendTelegram( "$admin[fullname] #Refill #Voucher #Hotspot for #u$c[username]\n".$p['name_plan']. + Message::sendTelegram( "$admin[fullname] #Refill #Voucher #Hotspot for #u$c[username]\n".$p['name_plan']. "\nCode: ".$code. "\nRouter: ".$v1['routers']. "\nPrice: ".$p['price']); @@ -709,7 +714,7 @@ switch ($action) { $v1->save(); - sendTelegram( "$admin[fullname] Refill #Voucher #PPPOE for #u$c[username]\n".$p['name_plan']. + Message::sendTelegram( "$admin[fullname] Refill #Voucher #PPPOE for #u$c[username]\n".$p['name_plan']. "\nCode: ".$code. "\nRouter: ".$v1['routers']. "\nPrice: ".$p['price']); @@ -718,7 +723,7 @@ switch ($action) { $ui->assign('in', $in); - sendWhatsapp($c['username'], "*$config[CompanyName]*\n". + $msg = "*$config[CompanyName]*\n". "$config[address]\n". "$config[phone]\n". "\n\n". @@ -734,8 +739,13 @@ switch ($action) { "$_L[Created_On] :\n*".date($config['date_format'], strtotime($in['recharged_on']))." $in[time]*\n". "$_L[Expires_On] :\n*".date($config['date_format'], strtotime($in['expiration']))." $in[time]*\n". "\n\n". - "$config[note]"); + "$config[note]"; + if ($_c['user_notification_payment'] == 'sms') { + Message::sendSMS($c['phonenumber'], $msg); + } else if ($_c['user_notification_payment'] == 'wa') { + Message::sendWhatsapp($c['phonenumber'], $msg); + } $ui->assign('date', $date_now); $ui->display('invoice.tpl'); } else { diff --git a/system/controllers/register.php b/system/controllers/register.php index 8a8c11ac..13aeb2c9 100644 --- a/system/controllers/register.php +++ b/system/controllers/register.php @@ -132,7 +132,7 @@ switch ($do) { }else{ $otp = rand(100000,999999); file_put_contents($otpPath, $otp); - sendSMS($username,$config['CompanyName']."\nYour Verification code are: $otp"); + Message::sendSMS($username,$config['CompanyName']."\nYour Verification code are: $otp"); $ui->assign('username', $username); $ui->assign('notify', '
@@ -100,6 +100,38 @@ +
{Lang::T('User Notification')}
+
+
+ +
+ +

{Lang::T('User will get notification when package expired')}

+
+
+
+ +
+ +

{Lang::T('[[name]] will be replaced with Customer Name. [[package]] will be replaced with Package name.')}

+
+
+
+ +
+ +

{Lang::T('User will get invoice notification when buy package or package refilled')}

+
+
+
Tawk.to Chat Widget
@@ -119,7 +151,7 @@ add dst-host=*.tawk.to
- + {$_L['You_can_use_html_tag']}
diff --git a/ui/ui/bandwidth.tpl b/ui/ui/bandwidth.tpl index 166ab486..25ec3fe6 100644 --- a/ui/ui/bandwidth.tpl +++ b/ui/ui/bandwidth.tpl @@ -41,7 +41,7 @@ {$ds['rate_up']} {$ds['rate_up_unit']} {$_L['Edit']} - {$_L['Delete']} + {$_L['Delete']} {/foreach} diff --git a/ui/ui/customers.tpl b/ui/ui/customers.tpl index 7ede1915..c3d1ae07 100644 --- a/ui/ui/customers.tpl +++ b/ui/ui/customers.tpl @@ -45,7 +45,7 @@ {$_L['Recharge']} {$_L['Edit']} - {$_L['Delete']} + {$_L['Delete']} {/foreach} diff --git a/ui/ui/plugin-manager.tpl b/ui/ui/plugin-manager.tpl new file mode 100644 index 00000000..55d8217e --- /dev/null +++ b/ui/ui/plugin-manager.tpl @@ -0,0 +1,63 @@ +{include file="sections/header.tpl"} +
+
+
+
{Lang::T('Plugin')}
+
+ {foreach $plugins as $plugin} +
+
+
+

{$plugin['name']}

+
+
{$plugin['description']}
@{$plugin['author']} Last update: {$plugin['last_update']}
+ +
+
+ {/foreach} +
+
+
+
{Lang::T('Payment Gateway')}
+
+ {foreach $pgs as $pg} +
+
+
+

{$pg['name']}

+
+
{$pg['description']}
@{$plugin['author']} Last update: {$plugin['last_update']}
+ +
+
+ {/foreach} +
+
+
+{include file="sections/footer.tpl"} \ No newline at end of file diff --git a/ui/ui/sections/header.tpl b/ui/ui/sections/header.tpl index 8fb9c858..d19ee779 100644 --- a/ui/ui/sections/header.tpl +++ b/ui/ui/sections/header.tpl @@ -163,7 +163,7 @@ {$_MENU_AFTER_REPORTS} {/if} {if $_admin['user_type'] eq 'Admin'} -
  • +
  • {$_L['Network']} @@ -215,6 +215,8 @@ href="{$_url}settings/users">{$_L['Administrator_Users']}
  • {$_L['Backup_Restore']}
  • +
  • {Lang::T('Plugin Manager')}
  • {$_MENU_SETTINGS} @@ -240,9 +242,9 @@

    - {$_title} + {$_title}

    - {if isset($notify)}{$notify}{/if} \ No newline at end of file +{if isset($notify)}{$notify}{/if} \ No newline at end of file diff --git a/ui/ui/sections/user-footer.tpl b/ui/ui/sections/user-footer.tpl index 67c1dfc9..80701398 100644 --- a/ui/ui/sections/user-footer.tpl +++ b/ui/ui/sections/user-footer.tpl @@ -1,15 +1,14 @@ -
    - -
    -{if isset($_c['CompanyFooter'])} -
    - {$_c['CompanyFooter']} -
    -{else} - -{/if} + +
    + {if isset($_c['CompanyFooter'])} +
    + {$_c['CompanyFooter']} +
    + {else} + + {/if}
    diff --git a/ui/ui/users.tpl b/ui/ui/users.tpl index 0be15f64..4f42fd32 100644 --- a/ui/ui/users.tpl +++ b/ui/ui/users.tpl @@ -49,7 +49,7 @@ class="btn btn-warning btn-sm">{$_L['Edit']} {if ($_admin['username']) neq ($ds['username'])} {$_L['Delete']} + class="btn btn-danger btn-sm" onclick="confirm('{$_L['Delete']}?')">{$_L['Delete']} {/if} diff --git a/ui/ui/voucher.tpl b/ui/ui/voucher.tpl index c989fcc3..a8678450 100644 --- a/ui/ui/voucher.tpl +++ b/ui/ui/voucher.tpl @@ -61,7 +61,7 @@ {if $ds['user'] eq '0'} - {else} {$ds['user']} {/if} {$_L['Delete']} + class="btn btn-danger btn-sm" onclick="confirm('{$_L['Delete']}?')">{$_L['Delete']} {/foreach} diff --git a/version.json b/version.json index f5b39cc1..e8592d2c 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "2022.12.14" + "version": "2023.3.6" } \ No newline at end of file