Compare commits

...

51 Commits

Author SHA1 Message Date
56bcbd810e 2023.9.20 2023-09-20 14:32:53 +07:00
c3fd8536eb if not exists, copy 2023-09-20 14:27:15 +07:00
6acc342b26 Privacy and ToC not hidden 2023-09-18 15:07:08 +07:00
e59bf71230 Add Privacy Policy and Terms of Condition 2023-09-18 15:03:25 +07:00
b98d0b230d click to view customer from voucher list 2023-09-18 13:56:11 +07:00
00cc448230 change password view 2023-09-18 13:55:52 +07:00
58d5ca7040 change recharge link 2023-09-18 13:35:27 +07:00
e88c678f2f Merge branch 'Development' 2023-09-15 15:25:36 +07:00
eca64ef81e add hide password 2023-09-15 15:16:47 +07:00
3c711115ec remove sample 2023-09-15 14:17:04 +07:00
d4bffaf220 Sync Active Plan 2023-09-15 14:15:43 +07:00
f69885d358 sync hotspot to mikrotik 2023-09-15 14:03:23 +07:00
50ab20e68e sync pppoe to mikrotik 2023-09-15 14:03:16 +07:00
e494570807 sync pool to Mikrotik 2023-09-15 13:34:56 +07:00
b0cb79eeac 2023.9.15 2023-09-15 12:13:12 +07:00
95a8eaeadb recharge customer from profile 2023-09-15 11:57:07 +07:00
aab2282e78 red is off 2023-09-15 11:56:52 +07:00
609cf4b69d Sync Customer to mikrotik 2023-09-15 11:33:46 +07:00
84cd66ea9a add recharge link 2023-09-15 11:33:06 +07:00
3142e93d52 Fix Balance Header 2023-09-15 09:25:55 +07:00
6102637d7b Fix checking package 2023-09-14 17:03:27 +07:00
c754338599 hide backup 2023-09-14 14:28:44 +07:00
a85ccf06fa check error Database 2023-09-14 13:53:28 +07:00
e64527cee2 Show some error page when crash 2023-09-14 13:45:35 +07:00
fc5aa083a1 2023.9.13 2023-09-13 17:31:47 +07:00
53eb817de4 Add Balance to notification 2023-09-13 16:23:51 +07:00
309bbc0059 fix customer count 2023-09-13 15:50:20 +07:00
5fc2190f4a show customer package instead active only 2023-09-13 15:50:12 +07:00
f292da9d8d send package to friend 2023-09-13 15:38:56 +07:00
28fcabd1fd Balance on Top 2023-09-13 14:04:13 +07:00
4bbb98fb98 check if connection error 2023-09-13 10:07:58 +07:00
ee2e67f490 add proxy to connection 2023-09-13 10:00:26 +07:00
e3ec8b18fa Remove User before Remove Active User 2023-09-13 09:37:05 +07:00
f396d7183b add name to invoice notification 2023-09-11 16:26:41 +07:00
b5ddf37649 using Http::getData instead file_get_contents 2023-09-11 14:26:58 +07:00
c57bbeace3 show user active 2023-09-07 10:54:20 +07:00
eeae60d88e show mac and IP 2023-09-07 09:42:28 +07:00
14ed0236d0 Remove active user Before remove user 2023-09-07 09:35:00 +07:00
3833afb3be Fix delete PPPOE 2023-09-07 09:20:31 +07:00
593ca31f18 pool_expired in SQL Instalation 2023-09-06 11:52:09 +07:00
7cc8d6f5e3 delete debug script 2023-09-06 11:25:13 +07:00
11a2fb8fc0 2023.9.6 2023-09-06 10:57:54 +07:00
537623130c Fix expired pool in pppoe 2023-09-06 10:55:28 +07:00
910be1946b Fix cron can move plan 2023-09-06 10:48:52 +07:00
e23abc1377 move user to expired profile when expired if set 2023-09-06 10:02:31 +07:00
b912dd05d0 Set expired plan 2023-09-05 17:06:43 +07:00
5c9a0d8ea6 Expired IP Pool Hotspot/PPPOE 2023-09-05 16:40:23 +07:00
b7eca582a6 Not using tbl_language anymore 2023-09-05 15:25:41 +07:00
b460e862e8 fix git ignore 2023-09-01 16:43:53 +07:00
a33705c0c4 Fix Text Cron 2023-09-01 14:03:02 +07:00
183a5ab242 Fix Reminder text 2023-09-01 13:56:14 +07:00
71 changed files with 1824 additions and 829 deletions

10
.gitignore vendored
View File

@ -20,7 +20,9 @@ system/plugin/ui/*
ui/ui_custom/**
!ui/ui_custom/index.html
!ui/ui_custom/README.md
system/uploads/admin.png
system/uploads/logo.png
system/uploads/user.jpg
system/uploads/notifications.json
system/uploads/**
!system/uploads/*.default.png
system/uploads/sms/**
!system/uploads/sms/index.html
system/uploads/system/**
!system/uploads/system/index.html

View File

@ -2,9 +2,42 @@
# CHANGELOG
## 2023.9.20
- Fix Customer balance header
- Deactivate Customer active plan
- Sync Customer Plan to Mikrotik
- Recharge Customer from Customer Details
- Add Privacy Policy and Terms and Conditions Pages
## 2023.9.13
- add Current balance in notification
- Buy Plan for Friend
- Recharge Friend plan
- Fix recharge Plan
- Show Customer active plan in Customer list
- Fix Customer counter in dashboard
- Show Customer Balance in header
- Fix Plugin Manager using Http::Get
- Show Some error page when crash
## 2023.9.7
- Fix PPPOE Delete Customer
- Remove active Customer before deleting
- Show IP and Mac even if it not Hotspot
## 2023.9.6
- Expired Pool
Customer can be move to expired pool after plan expired by cron
- Fix Delete customer
- tbl_language removed
## 2023.9.1.1
- Fix cronjob Delete customer
- Fix reminder text
## 2023.9.1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View File

@ -65,22 +65,6 @@ CREATE TABLE
--
-- Struktur dari tabel `tbl_language`
--
CREATE TABLE
`tbl_language` (
`id` int(10) NOT NULL,
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`folder` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`author` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
-- --------------------------------------------------------
--
-- Struktur dari tabel `tbl_logs`
--
@ -174,6 +158,7 @@ CREATE TABLE
`shared_users` int(10) DEFAULT NULL,
`routers` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`pool` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`pool_expired` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 disabled\r\n'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
@ -345,14 +330,6 @@ ALTER TABLE `tbl_customers` ADD PRIMARY KEY (`id`);
--
-- Indeks untuk tabel `tbl_language`
--
ALTER TABLE `tbl_language` ADD PRIMARY KEY (`id`);
--
-- Indeks untuk tabel `tbl_logs`
--
@ -466,15 +443,6 @@ ALTER TABLE
--
-- AUTO_INCREMENT untuk tabel `tbl_language`
--
ALTER TABLE
`tbl_language` MODIFY `id` int(10) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT untuk tabel `tbl_logs`
--
@ -610,39 +578,4 @@ VALUES (
'Active',
'2022-09-06 16:09:50',
'2014-06-23 01:43:07'
);
--
-- Dumping data untuk tabel `tbl_language`
--
INSERT INTO
`tbl_language` (
`id`,
`name`,
`folder`,
`author`
)
VALUES (
1,
'Indonesia',
'indonesia',
'Ismail Marzuqi'
), (
2,
'English',
'english',
'Ismail Marzuqi'
), (
3,
'Spanish',
'spanish',
'Luis Hernandez'
), (
4,
'Türkçe',
'turkish',
'Goktug Bogac Ogel'
);

View File

@ -0,0 +1,62 @@
<h1>Privacy Policy for PHPNuxBill</h1>
<p>At PHPNuxBill, accessible from https://github.com/hotspotbilling/phpnuxbill, one of our main priorities is the
privacy of our visitors. This Privacy Policy document contains types of information that is collected and recorded
by PHPNuxBill and how we use it.</p>
<p>If you have additional questions or require more information about our Privacy Policy, do not hesitate to contact us.
</p>
<h2>Log Files</h2>
<p>PHPNuxBill follows a standard procedure of using log files. These files log visitors when they visit websites. All
hosting companies do this and a part of hosting services' analytics. The information collected by log files include
internet protocol (IP) addresses, browser type, Internet Service Provider (ISP), date and time stamp, referring/exit
pages, and possibly the number of clicks. These are not linked to any information that is personally identifiable.
The purpose of the information is for analyzing trends, administering the site, tracking users' movement on the
website, and gathering demographic information. Our Privacy Policy was created with the help of the <a
href="https://www.privacypolicyonline.com/privacy-policy-generator/">Privacy Policy Generator</a>.</p>
<h2>Privacy Policies</h2>
<P>You may consult this list to find the Privacy Policy for each of the advertising partners of PHPNuxBill.</p>
<p>Third-party ad servers or ad networks uses technologies like cookies, JavaScript, or Web Beacons that are used in
their respective advertisements and links that appear on PHPNuxBill, which are sent directly to users' browser. They
automatically receive your IP address when this occurs. These technologies are used to measure the effectiveness of
their advertising campaigns and/or to personalize the advertising content that you see on websites that you visit.
</p>
<p>Note that PHPNuxBill has no access to or control over these cookies that are used by third-party advertisers.</p>
<h2>Third Party Privacy Policies</h2>
<p>PHPNuxBill's Privacy Policy does not apply to other advertisers or websites. Thus, we are advising you to consult the
respective Privacy Policies of these third-party ad servers for more detailed information. It may include their
practices and instructions about how to opt-out of certain options. </p>
<p>You can choose to disable cookies through your individual browser options. To know more detailed information about
cookie management with specific web browsers, it can be found at the browsers' respective websites. What Are
Cookies?</p>
<h2>Children's Information</h2>
<p>Another part of our priority is adding protection for children while using the internet. We encourage parents and
guardians to observe, participate in, and/or monitor and guide their online activity.</p>
<p>PHPNuxBill does not knowingly collect any Personal Identifiable Information from children under the age of 13. If you
think that your child provided this kind of information on our website, we strongly encourage you to contact us
immediately and we will do our best efforts to promptly remove such information from our records.</p>
<h2>Online Privacy Policy Only</h2>
<p>This Privacy Policy applies only to our online activities and is valid for visitors to our website with regards to
the information that they shared and/or collect in PHPNuxBill. This policy is not applicable to any information
collected offline or via channels other than this website.</p>
<h2>Consent</h2>
<p>By using our website, you hereby consent to our Privacy Policy and agree to its Terms and Conditions.</p>

View File

@ -0,0 +1,119 @@
<h2><strong>Terms and Conditions</strong></h2>
<p>Welcome to PHPNuxBill!</p>
<p>These terms and conditions outline the rules and regulations for the use of PHPNuxBill's Website, located at https://github.com/hotspotbilling/phpnuxbill.</p>
<p>By accessing this website we assume you accept these terms and conditions. Do not continue to use PHPNuxBill if you do not agree to take all of the terms and conditions stated on this page.</p>
<p>The following terminology applies to these Terms and Conditions, Privacy Statement and Disclaimer Notice and all Agreements: "Client", "You" and "Your" refers to you, the person log on this website and compliant to the Companys terms and conditions. "The Company", "Ourselves", "We", "Our" and "Us", refers to our Company. "Party", "Parties", or "Us", refers to both the Client and ourselves. All terms refer to the offer, acceptance and consideration of payment necessary to undertake the process of our assistance to the Client in the most appropriate manner for the express purpose of meeting the Clients needs in respect of provision of the Companys stated services, in accordance with and subject to, prevailing law of Netherlands. Any use of the above terminology or other words in the singular, plural, capitalization and/or he/she or they, are taken as interchangeable and therefore as referring to same. Our Terms and Conditions were created with the help of the <a href="https://www.privacypolicyonline.com/terms-conditions-generator/">Terms & Conditions Generator</a>.</p>
<h3><strong>Cookies</strong></h3>
<p>We employ the use of cookies. By accessing PHPNuxBill, you agreed to use cookies in agreement with the PHPNuxBill's Privacy Policy.</p>
<p>Most interactive websites use cookies to let us retrieve the user's details for each visit. Cookies are used by our website to enable the functionality of certain areas to make it easier for people visiting our website. Some of our affiliate/advertising partners may also use cookies.</p>
<h3><strong>License</strong></h3>
<p>Unless otherwise stated, PHPNuxBill and/or its licensors own the intellectual property rights for all material on PHPNuxBill. All intellectual property rights are reserved. You may access this from PHPNuxBill for your own personal use subjected to restrictions set in these terms and conditions.</p>
<p>You must not:</p>
<ul>
<li>Republish material from PHPNuxBill</li>
<li>Sell, rent or sub-license material from PHPNuxBill</li>
<li>Reproduce, duplicate or copy material from PHPNuxBill</li>
<li>Redistribute content from PHPNuxBill</li>
</ul>
<p>This Agreement shall begin on the date hereof.</p>
<p>Parts of this website offer an opportunity for users to post and exchange opinions and information in certain areas of the website. PHPNuxBill does not filter, edit, publish or review Comments prior to their presence on the website. Comments do not reflect the views and opinions of PHPNuxBill,its agents and/or affiliates. Comments reflect the views and opinions of the person who post their views and opinions. To the extent permitted by applicable laws, PHPNuxBill shall not be liable for the Comments or for any liability, damages or expenses caused and/or suffered as a result of any use of and/or posting of and/or appearance of the Comments on this website.</p>
<p>PHPNuxBill reserves the right to monitor all Comments and to remove any Comments which can be considered inappropriate, offensive or causes breach of these Terms and Conditions.</p>
<p>You warrant and represent that:</p>
<ul>
<li>You are entitled to post the Comments on our website and have all necessary licenses and consents to do so;</li>
<li>The Comments do not invade any intellectual property right, including without limitation copyright, patent or trademark of any third party;</li>
<li>The Comments do not contain any defamatory, libelous, offensive, indecent or otherwise unlawful material which is an invasion of privacy</li>
<li>The Comments will not be used to solicit or promote business or custom or present commercial activities or unlawful activity.</li>
</ul>
<p>You hereby grant PHPNuxBill a non-exclusive license to use, reproduce, edit and authorize others to use, reproduce and edit any of your Comments in any and all forms, formats or media.</p>
<h3><strong>Hyperlinking to our Content</strong></h3>
<p>The following organizations may link to our Website without prior written approval:</p>
<ul>
<li>Government agencies;</li>
<li>Search engines;</li>
<li>News organizations;</li>
<li>Online directory distributors may link to our Website in the same manner as they hyperlink to the Websites of other listed businesses; and</li>
<li>System wide Accredited Businesses except soliciting non-profit organizations, charity shopping malls, and charity fundraising groups which may not hyperlink to our Web site.</li>
</ul>
<p>These organizations may link to our home page, to publications or to other Website information so long as the link: (a) is not in any way deceptive; (b) does not falsely imply sponsorship, endorsement or approval of the linking party and its products and/or services; and (c) fits within the context of the linking party's site.</p>
<p>We may consider and approve other link requests from the following types of organizations:</p>
<ul>
<li>commonly-known consumer and/or business information sources;</li>
<li>dot.com community sites;</li>
<li>associations or other groups representing charities;</li>
<li>online directory distributors;</li>
<li>internet portals;</li>
<li>accounting, law and consulting firms; and</li>
<li>educational institutions and trade associations.</li>
</ul>
<p>We will approve link requests from these organizations if we decide that: (a) the link would not make us look unfavorably to ourselves or to our accredited businesses; (b) the organization does not have any negative records with us; (c) the benefit to us from the visibility of the hyperlink compensates the absence of PHPNuxBill; and (d) the link is in the context of general resource information.</p>
<p>These organizations may link to our home page so long as the link: (a) is not in any way deceptive; (b) does not falsely imply sponsorship, endorsement or approval of the linking party and its products or services; and (c) fits within the context of the linking party's site.</p>
<p>If you are one of the organizations listed in paragraph 2 above and are interested in linking to our website, you must inform us by sending an e-mail to PHPNuxBill. Please include your name, your organization name, contact information as well as the URL of your site, a list of any URLs from which you intend to link to our Website, and a list of the URLs on our site to which you would like to link. Wait 2-3 weeks for a response.</p>
<p>Approved organizations may hyperlink to our Website as follows:</p>
<ul>
<li>By use of our corporate name; or</li>
<li>By use of the uniform resource locator being linked to; or</li>
<li>By use of any other description of our Website being linked to that makes sense within the context and format of content on the linking party's site.</li>
</ul>
<p>No use of PHPNuxBill's logo or other artwork will be allowed for linking absent a trademark license agreement.</p>
<h3><strong>iFrames</strong></h3>
<p>Without prior approval and written permission, you may not create frames around our Webpages that alter in any way the visual presentation or appearance of our Website.</p>
<h3><strong>Content Liability</strong></h3>
<p>We shall not be hold responsible for any content that appears on your Website. You agree to protect and defend us against all claims that is rising on your Website. No link(s) should appear on any Website that may be interpreted as libelous, obscene or criminal, or which infringes, otherwise violates, or advocates the infringement or other violation of, any third party rights.</p>
<h3><strong>Reservation of Rights</strong></h3>
<p>We reserve the right to request that you remove all links or any particular link to our Website. You approve to immediately remove all links to our Website upon request. We also reserve the right to amen these terms and conditions and it's linking policy at any time. By continuously linking to our Website, you agree to be bound to and follow these linking terms and conditions.</p>
<h3><strong>Removal of links from our website</strong></h3>
<p>If you find any link on our Website that is offensive for any reason, you are free to contact and inform us any moment. We will consider requests to remove links but we are not obligated to or so or to respond to you directly.</p>
<p>We do not ensure that the information on this website is correct, we do not warrant its completeness or accuracy; nor do we promise to ensure that the website remains available or that the material on the website is kept up to date.</p>
<h3><strong>Disclaimer</strong></h3>
<p>To the maximum extent permitted by applicable law, we exclude all representations, warranties and conditions relating to our website and the use of this website. Nothing in this disclaimer will:</p>
<ul>
<li>limit or exclude our or your liability for death or personal injury;</li>
<li>limit or exclude our or your liability for fraud or fraudulent misrepresentation;</li>
<li>limit any of our or your liabilities in any way that is not permitted under applicable law; or</li>
<li>exclude any of our or your liabilities that may not be excluded under applicable law.</li>
</ul>
<p>The limitations and prohibitions of liability set in this Section and elsewhere in this disclaimer: (a) are subject to the preceding paragraph; and (b) govern all liabilities arising under the disclaimer, including liabilities arising in contract, in tort and for breach of statutory duty.</p>
<p>As long as the website and the information and services on the website are provided free of charge, we will not be liable for any loss or damage of any nature.</p>

View File

@ -19,12 +19,7 @@ class Balance
{
global $config;
if (Balance::min($id_customer, $amount)) {
if (Balance::plusByPhone($phoneTarget, $amount)) {
return true;
} else {
Balance::plus($id_customer, $amount);
return false;
}
return Balance::plusByPhone($phoneTarget, $amount);
} else {
return false;
}

View File

@ -2,12 +2,17 @@
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
* using proxy, add this variable in config.php
* $http_proxy = '127.0.0.1:3128';
* if proxy using authentication, use this parameter
* $http_proxyauth = 'user:password';
**/
class Http
{
public static function getData($url, $headers)
public static function getData($url, $headers = [])
{
global $http_proxy, $http_proxyauth, $admin;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 0);
@ -15,13 +20,26 @@ class Http
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if (!empty($http_proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
if (!empty($http_proxyauth)) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
}
}
$server_output = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
curl_close($ch);
return $server_output;
if($admin && $error_msg){
r2(U . 'dashboard', 'd', $error_msg);
}
return ($server_output) ? $server_output : $error_msg;
}
public static function postJsonData($url, $array_post, $headers = [], $basic = null)
{
global $http_proxy, $http_proxyauth, $admin;
$headers[] = 'Content-Type: application/json';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@ -30,6 +48,12 @@ class Http
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
if (!empty($http_proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
if (!empty($http_proxyauth)) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
}
}
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($array_post));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if (!empty($basic)) {
@ -37,13 +61,20 @@ class Http
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
curl_close($ch);
return $server_output;
if($admin && $error_msg){
r2(U . 'dashboard', 'd', $error_msg);
}
return ($server_output) ? $server_output : $error_msg;
}
public static function postData($url, $array_post, $headers = [], $basic = null)
{
global $http_proxy, $http_proxyauth, $admin;
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@ -52,6 +83,12 @@ class Http
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
if (!empty($http_proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
if (!empty($http_proxyauth)) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
}
}
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array_post));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if (!empty($basic)) {
@ -59,7 +96,13 @@ class Http
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
curl_close($ch);
return $server_output;
if($admin && $error_msg){
r2(U . 'dashboard', 'd', $error_msg);
}
return ($server_output) ? $server_output : $error_msg;
}
}

View File

@ -12,7 +12,7 @@ class Message
global $config;
run_hook('send_telegram'); #HOOK
if (!empty($config['telegram_bot']) && !empty($config['telegram_target_id'])) {
file_get_contents('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $config['telegram_target_id'] . '&text=' . urlencode($txt));
Http::getData('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $config['telegram_target_id'] . '&text=' . urlencode($txt));
}
}
@ -24,7 +24,7 @@ class Message
if (!empty($config['sms_url'])) {
$smsurl = str_replace('[number]', urlencode($phone), $config['sms_url']);
$smsurl = str_replace('[text]', urlencode($txt), $smsurl);
file_get_contents($smsurl);
Http::getData($smsurl);
}
}
@ -35,7 +35,7 @@ class Message
if (!empty($config['wa_url'])) {
$waurl = str_replace('[number]', urlencode($phone), $config['wa_url']);
$waurl = str_replace('[text]', urlencode($txt), $waurl);
file_get_contents($waurl);
Http::getData($waurl);
}
}
@ -56,9 +56,10 @@ class Message
return "$via: $msg";
}
public static function sendBalanceNotification($phone, $name, $balance, $message, $via)
public static function sendBalanceNotification($phone, $name, $balance, $balance_now, $message, $via)
{
$msg = str_replace('[[name]]', "*$name*", $message);
$msg = str_replace('[[current_balance]]', Lang::moneyFormat($balance_now), $msg);
$msg = str_replace('[[balance]]', "*" . Lang::moneyFormat($balance) . "*", $msg);
if (
!empty($phone) && strlen($phone) > 5

View File

@ -17,7 +17,8 @@ class Mikrotik
$iport = explode(":", $ip);
return new RouterOS\Client($iport[0], $user, $pass, ($iport[1]) ? $iport[1] : null);
} catch (Exception $e) {
$ui->assign("error_meesage","Unable to connect to the router.<br>" . $e->getMessage());
$ui->assign("error_title", "Mikrotik Connection Error");
$ui->assign("error_message", "Unable to connect to the router.<br>" . $e->getMessage());
$ui->display('router-error.tpl');
die();
}
@ -72,46 +73,77 @@ class Mikrotik
public static function setHotspotPlan($client, $name, $sharedusers, $rate)
{
$printRequest = new RouterOS\Request(
'/ip hotspot user profile print .proplist=name',
'/ip hotspot user profile print .proplist=.id',
RouterOS\Query::where('name', $name)
);
$profileName = $client->sendSync($printRequest)->getProperty('name');
$profileID = $client->sendSync($printRequest)->getProperty('.id');
if (empty($profileID)) {
Mikrotik::addHotspotPlan($client, $name, $sharedusers, $rate);
}else{
$setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set');
$client(
$setRequest
->setArgument('numbers', $profileID)
->setArgument('shared-users', $sharedusers)
->setArgument('rate-limit', $rate)
);
}
}
$setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set');
$client(
$setRequest
->setArgument('numbers', $profileName)
->setArgument('shared-users', $sharedusers)
->setArgument('rate-limit', $rate)
public static function setHotspotExpiredPlan($client, $name, $pool)
{
$printRequest = new RouterOS\Request(
'/ip hotspot user profile print .proplist=.id',
RouterOS\Query::where('name', $name)
);
$profileID = $client->sendSync($printRequest)->getProperty('.id');
if (empty($profileID)) {
$addRequest = new RouterOS\Request('/ip/hotspot/user/profile/add');
$client->sendSync(
$addRequest
->setArgument('name', $name)
->setArgument('shared-users', 3)
->setArgument('address-pool', $pool)
->setArgument('rate-limit', '512K/512K')
);
}else{
$setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set');
$client(
$setRequest
->setArgument('numbers', $profileID)
->setArgument('shared-users', 3)
->setArgument('address-pool', $pool)
->setArgument('rate-limit', '512K/512K')
);
}
}
public static function removeHotspotPlan($client, $name)
{
$printRequest = new RouterOS\Request(
'/ip hotspot user profile print .proplist=name',
'/ip hotspot user profile print .proplist=.id',
RouterOS\Query::where('name', $name)
);
$profileName = $client->sendSync($printRequest)->getProperty('name');
$profileID = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ip/hotspot/user/profile/remove');
$client(
$removeRequest
->setArgument('numbers', $profileName)
->setArgument('numbers', $profileID)
);
}
public static function removeHotspotUser($client, $username)
{
$printRequest = new RouterOS\Request(
'/ip hotspot user print .proplist=name',
'/ip hotspot user print .proplist=.id',
RouterOS\Query::where('name', $username)
);
$userName = $client->sendSync($printRequest)->getProperty('name');
$userID = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ip/hotspot/user/remove');
$client(
$removeRequest
->setArgument('numbers', $userName)
->setArgument('numbers', $userID)
);
}
@ -179,7 +211,7 @@ class Mikrotik
}
}
public static function setHotspotUser($client, $user, $pass, $nuser = null)
public static function setHotspotUser($client, $user, $pass)
{
$printRequest = new RouterOS\Request('/ip/hotspot/user/print');
$printRequest->setArgument('.proplist', '.id');
@ -192,6 +224,19 @@ class Mikrotik
$client->sendSync($setRequest);
}
public static function setHotspotUserPackage($client, $user, $plan)
{
$printRequest = new RouterOS\Request('/ip/hotspot/user/print');
$printRequest->setArgument('.proplist', '.id');
$printRequest->setQuery(RouterOS\Query::where('name', $user));
$id = $client->sendSync($printRequest)->getProperty('.id');
$setRequest = new RouterOS\Request('/ip/hotspot/user/set');
$setRequest->setArgument('numbers', $id);
$setRequest->setArgument('profile', $plan);
$client->sendSync($setRequest);
}
public static function removeHotspotActiveUser($client, $username)
{
$onlineRequest = new RouterOS\Request('/ip/hotspot/active/print');
@ -204,32 +249,16 @@ class Mikrotik
$client->sendSync($removeRequest);
}
public static function setHotspotLimitUptime($client, $username)
{
$printRequest = new RouterOS\Request('/ip/hotspot/user/print');
$printRequest->setArgument('.proplist', '.id');
$printRequest->setQuery(RouterOS\Query::where('name', $username));
$id = $client->sendSync($printRequest)->getProperty('.id');
$setRequest = new RouterOS\Request('/ip/hotspot/user/set');
$setRequest->setArgument('numbers', $id);
$setRequest->setArgument('limit-uptime', '00:00:05');
$client->sendSync($setRequest);
}
public static function removePpoeUser($client, $username)
{
$printRequest = new RouterOS\Request('/ppp/secret/print');
$printRequest->setArgument('.proplist', '.id');
$printRequest->setQuery(RouterOS\Query::where('name', $username));
$id = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ppp/secret/remove');
$client(
$removeRequest
->setArgument('numbers', $id)
);
$printRequest = new RouterOS\Request('/ppp/secret/print');
//$printRequest->setArgument('.proplist', '.id');
$printRequest->setQuery(RouterOS\Query::where('name', $username));
$id = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ppp/secret/remove');
$removeRequest->setArgument('numbers', $id);
$client->sendSync($removeRequest);
}
public static function addPpoeUser($client, $plan, $customer)
@ -250,7 +279,7 @@ class Mikrotik
);
}
public static function setPpoeUser($client, $user, $pass, $nuser = null)
public static function setPpoeUser($client, $user, $pass)
{
$printRequest = new RouterOS\Request('/ppp/secret/print');
$printRequest->setArgument('.proplist', '.id');
@ -263,15 +292,16 @@ class Mikrotik
$client->sendSync($setRequest);
}
public static function disablePpoeUser($client, $username)
public static function setPpoeUserPlan($client, $user, $plan)
{
$printRequest = new RouterOS\Request('/ppp/secret/print');
$printRequest->setArgument('.proplist', '.id');
$printRequest->setQuery(RouterOS\Query::where('name', $username));
$printRequest->setQuery(RouterOS\Query::where('name', $user));
$id = $client->sendSync($printRequest)->getProperty('.id');
$setRequest = new RouterOS\Request('/ppp/secret/disable');
$setRequest = new RouterOS\Request('/ppp/secret/set');
$setRequest->setArgument('numbers', $id);
$setRequest->setArgument('profile', $plan);
$client->sendSync($setRequest);
}
@ -290,15 +320,15 @@ class Mikrotik
public static function removePool($client, $name)
{
$printRequest = new RouterOS\Request(
'/ip pool print .proplist=name',
'/ip pool print .proplist=.id',
RouterOS\Query::where('name', $name)
);
$poolName = $client->sendSync($printRequest)->getProperty('name');
$poolID = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ip/pool/remove');
$client(
$removeRequest
->setArgument('numbers', $poolName)
->setArgument('numbers', $poolID)
);
}
@ -315,18 +345,18 @@ class Mikrotik
public static function setPool($client, $name, $ip_address)
{
$printRequest = new RouterOS\Request(
'/ip pool print .proplist=name',
'/ip pool print .proplist=.id',
RouterOS\Query::where('name', $name)
);
$poolName = $client->sendSync($printRequest)->getProperty('name');
$poolID = $client->sendSync($printRequest)->getProperty('id');
if (empty($poolName)) {
if (empty($poolID)) {
self::addPool($client, $name, $ip_address);
} else {
$setRequest = new RouterOS\Request('/ip/pool/set');
$client(
$setRequest
->setArgument('numbers', $poolName)
->setArgument('numbers', $poolID)
->setArgument('ranges', $ip_address)
);
}
@ -348,17 +378,17 @@ class Mikrotik
public static function setPpoePlan($client, $name, $pool, $rate)
{
$printRequest = new RouterOS\Request(
'/ppp profile print .proplist=name',
'/ppp profile print .proplist=.id',
RouterOS\Query::where('name', $name)
);
$profileName = $client->sendSync($printRequest)->getProperty('name');
if (empty($profileName)) {
$profileID = $client->sendSync($printRequest)->getProperty('.id');
if (empty($profileID)) {
self::addPpoePlan($client, $name, $pool, $rate);
} else {
$setRequest = new RouterOS\Request('/ppp/profile/set');
$client(
$setRequest
->setArgument('numbers', $profileName)
->setArgument('numbers', $profileID)
->setArgument('local-address', $pool)
->setArgument('remote-address', $pool)
->setArgument('rate-limit', $rate)
@ -369,15 +399,15 @@ class Mikrotik
public static function removePpoePlan($client, $name)
{
$printRequest = new RouterOS\Request(
'/ppp profile print .proplist=name',
'/ppp profile print .proplist=.id',
RouterOS\Query::where('name', $name)
);
$profileName = $client->sendSync($printRequest)->getProperty('name');
$profileID = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ppp/profile/remove');
$client(
$removeRequest
->setArgument('numbers', $profileName)
->setArgument('numbers', $profileID)
);
}
}

View File

@ -5,8 +5,6 @@
**/
use PEAR2\Net\RouterOS;
class Package
{
/**
@ -49,22 +47,27 @@ class Package
$t->type = "Balance";
$t->save();
$balance_before = $c['balance'];
Balance::plus($id_customer, $p['price']);
$balance = $c['balance'] + $p['price'];
$textInvoice = Lang::getNotifText('invoice_balance');
$textInvoice = str_replace('[[company_name]]', $_c['CompanyName'], $textInvoice);
$textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
$textInvoice = str_replace('[[invoice]]', $inv, $textInvoice);
$textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_only)) . " " . $time, $textInvoice);
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
$textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
$textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
$textInvoice = str_replace('[[type]]', 'Balance', $textInvoice);
$textInvoice = str_replace('[[plan_name]]', $p['name_plan'], $textInvoice);
$textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($p['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($p['price']), $textInvoice);
$textInvoice = str_replace('[[name]]', $c['fullname'], $textInvoice);
$textInvoice = str_replace('[[user_name]]', $c['username'], $textInvoice);
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
$textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
$textInvoice = str_replace('[[balance_before]]', Lang::moneyFormat($balance_before), $textInvoice);
$textInvoice = str_replace('[[balance]]', Lang::moneyFormat($balance), $textInvoice);
if ($_c['user_notification_payment'] == 'sms') {
Message::sendSMS($c['phonenumber'], $textInvoice);
@ -99,6 +102,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
@ -106,8 +111,10 @@ class Package
// if it same internet plan, expired will extend
if ($p['validity_unit'] == 'Months') {
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
$time = $b['time'];
} else if ($p['validity_unit'] == 'Days') {
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' days'));
$time = $b['time'];
} else if ($p['validity_unit'] == 'Hrs') {
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime($b['expiration'] . ' ' . $b['time'] . ' +' . $p['validity'] . ' hours')));
$date_exp = $datetime[0];
@ -150,7 +157,10 @@ class Package
} else {
if (!$_c['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
@ -196,6 +206,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
@ -252,6 +264,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
@ -299,15 +313,16 @@ class Package
$textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
$textInvoice = str_replace('[[invoice]]', $in['invoice'], $textInvoice);
$textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_now)) . " " . $time, $textInvoice);
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
$textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
$textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
$textInvoice = str_replace('[[type]]', $in['type'], $textInvoice);
$textInvoice = str_replace('[[plan_name]]', $in['plan_name'], $textInvoice);
$textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($in['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($in['price']), $textInvoice);
$textInvoice = str_replace('[[name]]', $c['fullname'], $textInvoice);
$textInvoice = str_replace('[[user_name]]', $in['username'], $textInvoice);
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
$textInvoice = str_replace('[[expired_date]]', date($_c['date_format'], strtotime($in['expiration'])) . " " . $in['time'], $textInvoice);
$textInvoice = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($in['expiration'], $in['time']), $textInvoice);
$textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
if ($_c['user_notification_payment'] == 'sms') {
@ -331,6 +346,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
} else {
@ -338,6 +355,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
}
@ -347,6 +366,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
} else {
@ -354,6 +375,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
}

View File

@ -4,6 +4,33 @@
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/
// on some server, it getting error because of slash is backwards
function _autoloader($class)
{
if (strpos($class, '_') !== false) {
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
} else {
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
}
}
spl_autoload_register('_autoloader');
function r2($to, $ntype = 'e', $msg = '')
{
if ($msg == '') {
@ -46,33 +73,52 @@ function _get($param, $defvalue = '')
return safedata($_GET[$param]);
}
}
try {
require_once File::pathFixer('system/orm.php');
require('system/orm.php');
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
ORM::configure('password', $db_password);
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
ORM::configure('return_result_sets', true);
if ($_app_stage != 'Live') {
ORM::configure('logging', true);
}
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
ORM::configure('password', $db_password);
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
ORM::configure('return_result_sets', true);
if ($_app_stage != 'Live') {
ORM::configure('logging', true);
}
$result = ORM::for_table('tbl_appconfig')->find_many();
foreach ($result as $value) {
$config[$value['setting']] = $value['value'];
}
$result = ORM::for_table('tbl_appconfig')->find_many();
foreach ($result as $value) {
$config[$value['setting']] = $value['value'];
}
date_default_timezone_set($config['timezone']);
$_c = $config;
date_default_timezone_set($config['timezone']);
$_c = $config;
if ($config['radius_mode']) {
ORM::configure("mysql:host=$radius_host;dbname=$radius_name", null, 'radius');
ORM::configure('username', $radius_user, 'radius');
ORM::configure('password', $radius_password, 'radius');
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'), 'radius');
ORM::configure('return_result_sets', true, 'radius');
// check if proxy setup in database
if (empty($http_proxy) && !empty($config['http_proxy'])) {
$http_proxy = $config['http_proxy'];
if (empty($http_proxyauth) && !empty($config['http_proxyauth'])) {
$http_proxyauth = $config['http_proxyauth'];
}
}
if ($config['radius_mode']) {
ORM::configure("mysql:host=$radius_host;dbname=$radius_name", null, 'radius');
ORM::configure('username', $radius_user, 'radius');
ORM::configure('password', $radius_password, 'radius');
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'), 'radius');
ORM::configure('return_result_sets', true, 'radius');
}
} catch (Exception $e) {
$ui = new Smarty();
$ui->setTemplateDir(['custom' => File::pathFixer('ui/ui_custom/'), 'default' => File::pathFixer('ui/ui/')]);
$ui->assign('_url', APP_URL . '/index.php?_route=');
$ui->setCompileDir(File::pathFixer('ui/compiled/'));
$ui->setConfigDir(File::pathFixer('ui/conf/'));
$ui->setCacheDir(File::pathFixer('ui/cache/'));
$ui->assign("error_title", "PHPNuxBill Crash");
$ui->assign("error_message", $e->getMessage());
$ui->display('router-error.tpl');
die();
}
function _notify($msg, $type = 'e')
@ -81,15 +127,15 @@ function _notify($msg, $type = 'e')
$_SESSION['notify'] = $msg;
}
$lan_file = 'system/lan/' . $config['language'] . '/common.lan.php';
$lan_file = File::pathFixer('system/lan/' . $config['language'] . '/common.lan.php');
require($lan_file);
$ui = new Smarty();
$ui->setTemplateDir(['custom' => 'ui/ui_custom/', 'default' => 'ui/ui/']);
$ui->addTemplateDir('system/paymentgateway/ui/', 'pg');
$ui->addTemplateDir('system/plugin/ui/', 'plugin');
$ui->setCompileDir('ui/compiled/');
$ui->setConfigDir('ui/conf/');
$ui->setCacheDir('ui/cache/');
$ui->setTemplateDir(['custom' => File::pathFixer('ui/ui_custom/'), 'default' => File::pathFixer('ui/ui/')]);
$ui->addTemplateDir(File::pathFixer('system/paymentgateway/ui/'), 'pg');
$ui->addTemplateDir(File::pathFixer('system/plugin/ui/'), 'plugin');
$ui->setCompileDir(File::pathFixer('ui/compiled/'));
$ui->setConfigDir(File::pathFixer('ui/conf/'));
$ui->setCacheDir(File::pathFixer('ui/cache/'));
$ui->assign('app_url', APP_URL);
$ui->assign('_domain', str_replace('www.', '', parse_url(APP_URL, PHP_URL_HOST)));
define('U', APP_URL . '/index.php?_route=');
@ -129,40 +175,16 @@ if (isset($_SESSION['notify'])) {
include "autoload/Hookers.php";
// notification message
if(file_exists("system/uploads/notifications.json")){
$_notifmsg =json_decode(file_get_contents('system/uploads/notifications.json'), true);
if (file_exists(File::pathFixer("system/uploads/notifications.json"))) {
$_notifmsg = json_decode(file_get_contents(File::pathFixer('system/uploads/notifications.json')), true);
}
$_notifmsg_default = json_decode(file_get_contents('system/uploads/notifications.default.json'), true);
$_notifmsg_default = json_decode(file_get_contents(File::pathFixer('system/uploads/notifications.default.json')), true);
//register all plugin
foreach (glob("system/plugin/*.php") as $filename) {
foreach (glob(File::pathFixer("system/plugin/*.php")) as $filename) {
include $filename;
}
// on some server, it getting error because of slash is backwards
function _autoloader($class)
{
if (strpos($class, '_') !== false) {
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
} else {
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
}
}
spl_autoload_register('_autoloader');
function _auth($login = true)
{
@ -281,34 +303,42 @@ $handler = $routes[0];
if ($handler == '') {
$handler = 'default';
}
$sys_render = 'system/controllers/' . $handler . '.php';
if (file_exists($sys_render)) {
$menus = array();
// "name" => $name,
// "admin" => $admin,
// "position" => $position,
// "function" => $function
$ui->assign('_system_menu', $routes[0]);
foreach ($menu_registered as $menu) {
if ($menu['admin'] && _admin(false)) {
$menus[$menu['position']] .= '<li' . (($routes[1] == $menu['function']) ? ' class="active"' : '') . '><a href="' . U . 'plugin/' . $menu['function'] . '">';
if (!empty($menu['icon'])) {
$menus[$menu['position']] .= '<i class="' . $menu['icon'] . '"></i>';
try {
$sys_render = File::pathFixer('system/controllers/' . $handler . '.php');
if (file_exists($sys_render)) {
$menus = array();
// "name" => $name,
// "admin" => $admin,
// "position" => $position,
// "function" => $function
$ui->assign('_system_menu', $routes[0]);
foreach ($menu_registered as $menu) {
if ($menu['admin'] && _admin(false)) {
$menus[$menu['position']] .= '<li' . (($routes[1] == $menu['function']) ? ' class="active"' : '') . '><a href="' . U . 'plugin/' . $menu['function'] . '">';
if (!empty($menu['icon'])) {
$menus[$menu['position']] .= '<i class="' . $menu['icon'] . '"></i>';
}
$menus[$menu['position']] .= '<span class="text">' . $menu['name'] . '</span></a></li>';
} else if (!$menu['admin'] && _auth(false)) {
$menus[$menu['position']] .= '<li' . (($routes[1] == $menu['function']) ? ' class="active"' : '') . '><a href="' . U . 'plugin/' . $menu['function'] . '">';
if (!empty($menu['icon'])) {
$menus[$menu['position']] .= '<i class="' . $menu['icon'] . '"></i>';
}
$menus[$menu['position']] .= '<span class="text">' . $menu['name'] . '</span></a></li>';
}
$menus[$menu['position']] .= '<span class="text">' . $menu['name'] . '</span></a></li>';
} else if (!$menu['admin'] && _auth(false)) {
$menus[$menu['position']] .= '<li' . (($routes[1] == $menu['function']) ? ' class="active"' : '') . '><a href="' . U . 'plugin/' . $menu['function'] . '">';
if (!empty($menu['icon'])) {
$menus[$menu['position']] .= '<i class="' . $menu['icon'] . '"></i>';
}
$menus[$menu['position']] .= '<span class="text">' . $menu['name'] . '</span></a></li>';
}
foreach ($menus as $k => $v) {
$ui->assign('_MENU_' . $k, $v);
}
unset($menus, $menu_registered);
include($sys_render);
} else {
r2(U . 'dashboard', 'e', 'not found');
}
foreach ($menus as $k => $v) {
$ui->assign('_MENU_' . $k, $v);
}
unset($menus, $menu_registered);
include($sys_render);
} else {
r2(U . 'dashboard', 'e', 'not found');
} catch (Exception $e) {
$ui->assign("error_title", "PHPNuxBill Crash");
$ui->assign("error_message", $e->getMessage());
$ui->display('router-error.tpl');
die();
}

View File

@ -36,6 +36,18 @@ switch ($action) {
$ui->display('autoload.tpl');
break;
case 'customer_is_active':
$d = ORM::for_table('tbl_user_recharges')->where('customer_id', $routes['2'])->findOne();
if ($d) {
if ($d['status'] == 'on') {
die('<span class="label label-success" title="Expired ' . Lang::dateAndTimeFormat($d['expiration'], $d['time']) . '">'.$d['namebp'].'</span>');
} else {
die('<span class="label label-danger" title="Expired ' . Lang::dateAndTimeFormat($d['expiration'], $d['time']) . '">'.$d['namebp'].'</span>');
}
} else {
die('<span class="label label-danger">&bull;</span>');
}
break;
case 'customer_select2':
$s = addslashes(_get('s'));

View File

@ -12,9 +12,6 @@ $action = $routes['1'];
$admin = Admin::_info();
$ui->assign('_admin', $admin);
use PEAR2\Net\RouterOS;
require_once 'system/autoload/PEAR2/Autoload.php';
if ($admin['user_type'] != 'Admin' and $admin['user_type'] != 'Sales') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
@ -34,7 +31,8 @@ switch ($action) {
->order_by_desc('id')->find_many();
} else {
$paginator = Paginator::bootstrap('tbl_customers');
$d = ORM::for_table('tbl_customers')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
$d = ORM::for_table('tbl_customers')
->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
}
$ui->assign('search', htmlspecialchars($search));
@ -47,13 +45,67 @@ switch ($action) {
run_hook('view_add_customer'); #HOOK
$ui->display('customers-add.tpl');
break;
case 'recharge':
$id_customer = $routes['2'];
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
if ($b) {
$mikrotik = Mikrotik::info($b['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
if (Package::rechargeUser($id_customer, $b['routers'], $b['plan_id'], "Recharge", $admin['fullname'])) {
r2(U . 'customers/view/' . $id_customer, 's', 'Success Recharge Customer');
} else {
r2(U . 'customers/view/' . $id_customer, 'e', 'Customer plan is inactive');
}
}
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
case 'deactivate':
$id_customer = $routes['2'];
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
if ($b) {
$mikrotik = Mikrotik::info($b['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
if ($b['type'] == 'Hotspot') {
Mikrotik::removeHotspotUser($client, $b['username']);
Mikrotik::removeHotspotActiveUser($client, $b['username']);
} else if ($b['type'] == 'PPPOE') {
Mikrotik::removePpoeUser($client, $b['username']);
Mikrotik::removePpoeActive($client, $b['username']);
}
$b->status = 'off';
$b->expiration = date('Y-m-d');
$b->time = date('H:i:s');
$b->save();
r2(U . 'customers/view/' . $id_customer, 's', 'Success deactivate customer to Mikrotik');
}
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
break;
case 'sync':
$id_customer = $routes['2'];
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('status', 'on')->find_one();
if ($b) {
$mikrotik = Mikrotik::info($b['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
$c = ORM::for_table('tbl_customers')->find_one($id_customer);
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->where('enabled', '1')->find_one();
if ($p) {
if ($b['type'] == 'Hotspot') {
Mikrotik::addHotspotUser($client, $p, $c);
} else if ($b['type'] == 'PPPOE') {
Mikrotik::addPpoeUser($client, $p, $c);
}
r2(U . 'customers/view/' . $id_customer, 's', 'Success sync customer to Mikrotik');
} else {
r2(U . 'customers/view/' . $id_customer, 'e', 'Customer plan is inactive');
}
}
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
break;
case 'viewu':
$customer = ORM::for_table('tbl_customers')->where('username', $routes['2'])->find_one();
case 'view':
$id = $routes['2'];
run_hook('view_customer'); #HOOK
if(!$customer){
if (!$customer) {
$customer = ORM::for_table('tbl_customers')->find_one($id);
}
if ($customer) {
@ -81,7 +133,7 @@ switch ($action) {
// $ui->assign('paginator', $paginator);
$ui->assign('activation', $activation);
}
$package = ORM::for_table('tbl_user_recharges')->where('username',$customer['username'])->find_one();
$package = ORM::for_table('tbl_user_recharges')->where('username', $customer['username'])->find_one();
$ui->assign('package', $package);
$ui->assign('v', $v);
$ui->assign('d', $customer);
@ -113,14 +165,14 @@ switch ($action) {
if ($c['type'] == 'Hotspot') {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removeHotspotUser($client, $d['username']);
Mikrotik::removeHotspotActiveUser($client, $d['username']);
}
} else {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::removePpoeUser($client, $d['username']);
Mikrotik::removePpoeActive($client, $d['username']);
}
}
try {

View File

@ -1,13 +1,14 @@
<?php
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/
_admin();
$ui->assign('_title', $_L['Dashboard']);
$admin = Admin::_info();
$ui->assign('_admin', $admin);
if(!in_array($admin['user_type'],['Admin','Sales'])){
r2(U."home",'e',$_L['Do_Not_Access']);
if (!in_array($admin['user_type'], ['Admin', 'Sales'])) {
r2(U . "home", 'e', $_L['Do_Not_Access']);
}
$fdate = date('Y-m-01');
@ -17,59 +18,67 @@ $first_day_month = date('Y-m-01');
$mdate = date('Y-m-d');
$month_n = date('n');
$iday = ORM::for_table('tbl_transactions')->where('recharged_on',$mdate)->sum('price');
if($iday == ''){
$iday = ORM::for_table('tbl_transactions')->where('recharged_on', $mdate)->sum('price');
if ($iday == '') {
$iday = '0.00';
}
$ui->assign('iday',$iday);
$ui->assign('iday', $iday);
$imonth = ORM::for_table('tbl_transactions')->where_gte('recharged_on',$first_day_month)->where_lte('recharged_on',$mdate)->sum('price');
if($imonth == ''){
$imonth = ORM::for_table('tbl_transactions')->where_gte('recharged_on', $first_day_month)->where_lte('recharged_on', $mdate)->sum('price');
if ($imonth == '') {
$imonth = '0.00';
}
$ui->assign('imonth',$imonth);
$ui->assign('imonth', $imonth);
$u_act = ORM::for_table('tbl_user_recharges')->where('status','on')->count();
if($u_act == ''){
$u_act = ORM::for_table('tbl_user_recharges')->where('status', 'on')->count();
if (empty($u_act)) {
$u_act = '0';
}
$ui->assign('u_act',$u_act);
$ui->assign('u_act', $u_act);
$u_all = ORM::for_table('tbl_user_recharges')->count();
if($u_all == ''){
if (empty($u_all)) {
$u_all = '0';
}
$ui->assign('u_all',$u_all);
$ui->assign('u_all', $u_all);
$c_all = ORM::for_table('tbl_customers')->count();
if (empty($c_all)) {
$c_all = '0';
}
$ui->assign('c_all', $c_all);
//user expire
$expire = ORM::for_table('tbl_user_recharges')->where('expiration',$mdate)->order_by_desc('id')->find_many();
$ui->assign('expire',$expire);
$expire = ORM::for_table('tbl_user_recharges')->where('expiration', $mdate)->order_by_desc('id')->find_many();
$ui->assign('expire', $expire);
//activity log
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->find_many();
$ui->assign('dlog',$dlog);
$ui->assign('dlog', $dlog);
$log = ORM::for_table('tbl_logs')->count();
$ui->assign('log',$log);
$ui->assign('log', $log);
// Count stock
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
$plans = array();
$stocks = array("used"=>0,"unused"=>0);
$stocks = array("used" => 0, "unused" => 0);
$n = 0;
foreach($tmp as $plan){
foreach ($tmp as $plan) {
$plans[$n]['name_plan'] = $plan['name_plan'];
$plans[$n]['unused'] = ORM::for_table('tbl_voucher')
->where('id_plan',$plan['id'])
->where('status',0)->count();;
->where('id_plan', $plan['id'])
->where('status', 0)->count();;
$stocks["unused"] += $plans[$n]['unused'];
$plans[$n]['used'] = ORM::for_table('tbl_voucher')
->where('id_plan',$plan['id'])
->where('status',1)->count();;
->where('id_plan', $plan['id'])
->where('status', 1)->count();;
$stocks["used"] += $plans[$n]['used'];
$n++;
}
$ui->assign('stocks',$stocks);
$ui->assign('plans',$plans);
$ui->assign('stocks', $stocks);
$ui->assign('plans', $plans);
run_hook('view_dashboard'); #HOOK
$ui->display('dashboard.tpl');
$ui->display('dashboard.tpl');

View File

@ -25,7 +25,7 @@ if (_post('send') == 'balance') {
if ($user['balance'] < $balance) {
r2(U . 'home', 'd', Lang::T('insufficient balance'));
}
if (!empty($config['minimum_transfer']) && intval($balance) <= intval($config['minimum_transfer'])) {
if (!empty($config['minimum_transfer']) && intval($balance) < intval($config['minimum_transfer'])) {
r2(U . 'home', 'd', Lang::T('Minimum Transfer') . ' ' . Lang::moneyFormat($config['minimum_transfer']));
}
if ($user['username'] == $target['username']) {
@ -66,13 +66,23 @@ if (_post('send') == 'balance') {
$d->pg_url_payment = 'balance';
$d->status = 2;
$d->save();
Message::sendBalanceNotification($user['phonenumber'], $target['fullname'] . ' (' . $target['username'] . ')', $balance, Lang::getNotifText('balance_send'), $config['user_notification_payment']);
Message::sendBalanceNotification($target['phonenumber'], $user['fullname'] . ' (' . $user['username'] . ')', $balance, Lang::getNotifText('balance_received'), $config['user_notification_payment']);
Message::sendBalanceNotification($user['phonenumber'], $target['fullname'] . ' (' . $target['username'] . ')', $balance, ($user['balance'] - $balance), Lang::getNotifText('balance_send'), $config['user_notification_payment']);
Message::sendBalanceNotification($target['phonenumber'], $user['fullname'] . ' (' . $user['username'] . ')', $balance, ($target['balance'] + $balance), Lang::getNotifText('balance_received'), $config['user_notification_payment']);
Message::sendTelegram("#u$user[username] send balance to #u$target[username] \n" . Lang::moneyFormat($balance));
r2(U . 'home', 's', Lang::T('Sending balance success'));
}
} else {
r2(U . 'home', 'd', 'Failed, balance is not available');
r2(U . 'home', 'd', Lang::T('Failed, balance is not available'));
}
} else if (_post('send') == 'plan') {
$active = ORM::for_table('tbl_user_recharges')
->where('username', _post('username'))
->find_one();
$router = ORM::for_table('tbl_routers')->where('name', $active['routers'])->find_one();
if ($router) {
r2(U . "order/send/$router[id]/$active[plan_id]&u=" . trim(_post('username')), 's', Lang::T('Review package before recharge'));
} else {
r2(U . 'package/order', 'w', Lang::T('Your friend do not have active package'));
}
}

View File

@ -98,7 +98,7 @@ switch ($action) {
}
}
if (empty($trx)) {
r2(U . "order", 'e', Lang::T("Transaction Not found"));
r2(U . "order/package", 'e', Lang::T("Transaction Not found"));
}
$router = ORM::for_table('tbl_routers')->find_one($trx['routers_id']);
$plan = ORM::for_table('tbl_plans')->find_one($trx['plan_id']);
@ -111,8 +111,8 @@ switch ($action) {
$ui->display('user-orderView.tpl');
break;
case 'pay':
if ($_c['enable_balance'] != 'yes'){
r2(U . "order", 'e', Lang::T("Balance not enabled"));
if ($_c['enable_balance'] != 'yes' && $config['allow_balance_transfer'] != 'yes') {
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
}
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3']);
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
@ -130,10 +130,91 @@ switch ($action) {
"\nRouter: " . $router_name .
"\nPrice: " . $p['price']);
}
}else{
} else {
echo "no renewall | plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
}
break;
case 'send':
if ($_c['enable_balance'] != 'yes') {
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
}
$ui->assign('_title', Lang::T('Buy for friend'));
$ui->assign('_system_menu', 'package');
$plan = ORM::for_table('tbl_plans')->find_one($routes['3']);
if (empty($plan)) {
r2(U . "order/package", 'e', Lang::T("Plan Not found"));
}
if (isset($_POST['send']) && $_POST['send'] == 'plan') {
$target = ORM::for_table('tbl_customers')->where('username', _post('username'))->find_one();
if (!$target) {
r2(U . 'home', 'd', Lang::T('Username not found'));
}
if ($user['balance'] < $plan['price']) {
r2(U . 'home', 'd', Lang::T('insufficient balance'));
}
if ($user['username'] == $target['username']) {
r2(U . "order/pay/$routes[2]/$routes[3]", 's', '^_^ v');
}
$active = ORM::for_table('tbl_user_recharges')
->where('username', _post('username'))
->where('status', 'on')
->find_one();
if ($active && $active['plan_id'] != $plan['id']) {
r2(U . "order/package", 'e', Lang::T("Target has active plan, different with current plant.")." [ <b>$active[namebp]</b> ]");
}
if (Package::rechargeUser($target['id'], $plan['routers'], $plan['id'], $user['fullname'], 'Balance')) {
// if success, then get the balance
Balance::min($user['id'], $plan['price']);
//sender
$d = ORM::for_table('tbl_payment_gateway')->create();
$d->username = $user['username'];
$d->gateway = $target['username'];
$d->plan_id = $plan['id'];
$d->plan_name = $plan['name_plan'];
$d->routers_id = $routes['2'];
$d->routers = $plan['routers'];
$d->price = $plan['price'];
$d->payment_method = "Balance";
$d->payment_channel = "Send Plan";
$d->created_date = date('Y-m-d H:i:s');
$d->paid_date = date('Y-m-d H:i:s');
$d->expired_date = date('Y-m-d H:i:s');
$d->pg_url_payment = 'balance';
$d->status = 2;
$d->save();
$trx_id = $d->id();
//receiver
$d = ORM::for_table('tbl_payment_gateway')->create();
$d->username = $target['username'];
$d->gateway = $user['username'];
$d->plan_id = $plan['id'];
$d->plan_name = $plan['name_plan'];
$d->routers_id = $routes['2'];
$d->routers = $plan['routers'];
$d->price = $plan['price'];
$d->payment_method = "Balance";
$d->payment_channel = "Received Plan";
$d->created_date = date('Y-m-d H:i:s');
$d->paid_date = date('Y-m-d H:i:s');
$d->expired_date = date('Y-m-d H:i:s');
$d->pg_url_payment = 'balance';
$d->status = 2;
$d->save();
r2(U . "order/view/$trx_id", 's', Lang::T("Success to send package"));
} else {
r2(U . "order/package", 'e', Lang::T("Failed to Send package"));
Message::sendTelegram("Send Package with Balance Failed\n\n#u$user[username] #send \n" . $plan['name_plan'] .
"\nRouter: " . $plan['routers'] .
"\nPrice: " . $plan['price']);
}
}
$ui->assign('username', $_GET['u']);
$ui->assign('router', $router);
$ui->assign('plan', $plan);
$ui->display('user-sendPlan.tpl');
break;
case 'buy':
if (strpos($user['email'], '@') === false) {
r2(U . 'accounts/profile', 'e', Lang::T("Please enter your email address"));
@ -147,9 +228,9 @@ switch ($action) {
run_hook('customer_buy_plan'); #HOOK
include 'system/paymentgateway/' . $config['payment_gateway'] . '.php';
call_user_func($config['payment_gateway'] . '_validate_config');
if ($routes['2']>0) {
if ($routes['2'] > 0) {
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
}else{
} else {
$router['id'] = 0;
$router['name'] = 'balance';
}
@ -205,5 +286,5 @@ switch ($action) {
}
break;
default:
r2(U . "order/package/", 's','');
r2(U . "order/package/", 's', '');
}

View File

@ -11,21 +11,31 @@ $admin = Admin::_info();
$ui->assign('_admin', $admin);
if(strpos($action,"-post")===false){
$path = __DIR__."/../../pages/".str_replace(".","",$action).".html";
$path = "pages/".str_replace(".","",$action).".html";
//echo $path;
run_hook('view_edit_pages'); #HOOK
if(!file_exists($path)){
$temp = "pages_template/".str_replace(".","",$action).".html";
if(file_exists($temp)){
if(!copy($temp, $path)){
touch($path);
}
}else{
touch($path);
}
}
if(file_exists($path)){
$html = file_get_contents($path);
$ui->assign("htmls",str_replace(["<div","</div>"],"",$html));
$ui->assign("writeable",is_writable($path));
$ui->assign("pageHeader",$action);
$ui->assign("pageHeader",str_replace('_', ' ', $action));
$ui->assign("PageFile",$action);
$ui->display('page-edit.tpl');
}else
$ui->display('a404.tpl');
}else{
$action = str_replace("-post","",$action);
$path = __DIR__."/../../pages/".str_replace(".","",$action).".html";
$path = "pages/".str_replace(".","",$action).".html";
if(file_exists($path)){
$html = _post("html");
run_hook('save_pages'); #HOOK

View File

@ -21,9 +21,14 @@ if ($admin['user_type'] != 'Admin') {
$cache = File::pathFixer('system/cache/plugin_repository.json');
if (file_exists($cache) && time() - filemtime($cache) < (24 * 60 * 60)) {
$json = json_decode(file_get_contents($cache), true);
$txt = file_get_contents($cache);
$json = json_decode($txt, true);
if(empty($json['plugins']) && empty($json['payment_gateway'])){
unlink($cache);
r2(U . 'dashboard', 'd', $txt);
}
} else {
$data = file_get_contents($plugin_repository);
$data = Http::getData($plugin_repository);
file_put_contents($cache, $data);
$json = json_decode($data, true);
}

View File

@ -15,9 +15,6 @@ if ($admin['user_type'] != 'Admin') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
}
use PEAR2\Net\RouterOS;
require_once 'system/autoload/PEAR2/Autoload.php';
switch ($action) {
case 'list':
@ -73,6 +70,17 @@ switch ($action) {
}
break;
case 'sync':
$pools = ORM::for_table('tbl_pool')->find_many();
$log = '';
foreach($pools as $pool){
$mikrotik = Mikrotik::info($pool['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addPool($client, $pool['pool_name'], $pool['range_ip']);
$log .= 'DONE: '.$pool['pool_name'].': '.$pool['range_ip'].'<br>';
}
r2(U . 'pool/list', 's', $log);
break;
case 'add-post':
$name = _post('name');
$ip_address = _post('ip_address');

View File

@ -40,9 +40,31 @@ EOT;
require_once 'system/autoload/PEAR2/Autoload.php';
switch ($action) {
case 'sync':
set_time_limit(-1);
$plans = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
echo count($plans);
$log = '';
$router = '';
foreach ($plans as $plan) {
if ($router != $plan['routers']) {
$mikrotik = Mikrotik::info($plan['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
$router = $plan['routers'];
}
$p = ORM::for_table('tbl_plans')->findOne($plan['plan_id']);
$c = ORM::for_table('tbl_customers')->findOne($plan['customer_id']);
if ($plan['type'] == 'Hotspot') {
Mikrotik::addHotspotUser($client, $p, $c);
} else if ($plan['type'] == 'PPPOE') {
Mikrotik::addPpoeUser($client, $p, $c);
}
$log .= "DONE : $plan[username], $plan[namebp], $plan[type], $plan[routers]<br>";
}
r2(U . 'prepaid/list', 's', $log);
case 'list':
$ui->assign('xfooter', '<script type="text/javascript" src="ui/lib/c/prepaid.js"></script>');
$ui->assign('_title', $_L['Customers']);
$username = _post('username');
if ($username != '') {
$paginator = Paginator::bootstrap('tbl_user_recharges', 'username', '%' . $username . '%');
@ -65,6 +87,9 @@ switch ($action) {
$ui->assign('p', $p);
$r = ORM::for_table('tbl_routers')->where('enabled', '1')->find_many();
$ui->assign('r', $r);
if (isset($routes['2']) && !empty($routes['2'])) {
$ui->assign('cust', ORM::for_table('tbl_customers')->find_one($routes['2']));
}
run_hook('view_recharge'); #HOOK
$ui->display('recharge.tpl');
break;
@ -146,14 +171,16 @@ switch ($action) {
if ($d['type'] == 'Hotspot') {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removeHotspotUser($client, $d['username']);
Mikrotik::removeHotspotActiveUser($client, $d['username']);
}
$d->delete();
} else {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $d['username']);
Mikrotik::removePpoeActive($client, $d['username']);
}
$d->delete();
}

View File

@ -21,6 +21,68 @@ use PEAR2\Net\RouterOS;
require_once 'system/autoload/PEAR2/Autoload.php';
switch ($action) {
case 'sync':
set_time_limit(-1);
if ($routes['2'] == 'hotspot') {
$plans = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'Hotspot')->where('tbl_plans.enabled', '1')->find_many();
$log = '';
$router = '';
foreach ($plans as $plan) {
if ($router != $plan['routers']) {
$mikrotik = Mikrotik::info($plan['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
$router = $plan['routers'];
}
if ($plan['rate_down_unit'] == 'Kbps') {
$unitdown = 'K';
} else {
$unitdown = 'M';
}
if ($plan['rate_up_unit'] == 'Kbps') {
$unitup = 'K';
} else {
$unitup = 'M';
}
$rate = $plan['rate_up'] . $unitup . "/" . $plan['rate_down'] . $unitdown;
Mikrotik::addHotspotPlan($client, $plan['name_plan'], $plan['shared_users'], $rate);
$log .= "DONE : $plan[name_plan], $plan[shared_users], $rate<br>";
if (!empty($plan['pool_expired'])) {
Mikrotik::setHotspotExpiredPlan($client, 'EXPIRED NUXBILL ' . $plan['pool_expired'], $plan['pool_expired']);
$log .= "DONE Expired : EXPIRED NUXBILL $plan[pool_expired]<br>";
}
}
r2(U . 'services/hotspot', 's', $log);
}else if ($routes['2'] == 'pppoe') {
$plans = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'PPPOE')->where('tbl_plans.enabled', '1')->find_many();
$log = '';
$router = '';
foreach ($plans as $plan) {
if ($router != $plan['routers']) {
$mikrotik = Mikrotik::info($plan['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
$router = $plan['routers'];
}
if ($plan['rate_down_unit'] == 'Kbps') {
$unitdown = 'K';
} else {
$unitdown = 'M';
}
if ($plan['rate_up_unit'] == 'Kbps') {
$unitup = 'K';
} else {
$unitup = 'M';
}
$rate = $plan['rate_up'] . $unitup . "/" . $plan['rate_down'] . $unitdown;
Mikrotik::addPpoePlan($client, $plan['name_plan'], $plan['pool'], $rate);
$log .= "DONE : $plan[name_plan], $plan[pool], $rate<br>";
if (!empty($plan['pool_expired'])) {
Mikrotik::setPpoePlan($client, 'EXPIRED NUXBILL ' . $plan['pool_expired'], $plan['pool_expired'], '512K/512K');
$log .= "DONE Expired : EXPIRED NUXBILL $plan[pool_expired]<br>";
}
}
r2(U . 'services/pppoe', 's', $log);
}
r2(U . 'services/hotspot', 'w', 'Unknown command');
case 'hotspot':
$ui->assign('xfooter', '<script type="text/javascript" src="ui/lib/c/hotspot.js"></script>');
@ -53,10 +115,10 @@ switch ($action) {
$d = ORM::for_table('tbl_plans')->find_one($id);
if ($d) {
$ui->assign('d', $d);
$p = ORM::for_table('tbl_pool')->where('routers', $d['routers'])->find_many();
$ui->assign('p', $p);
$b = ORM::for_table('tbl_bandwidth')->find_many();
$ui->assign('b', $b);
$r = ORM::for_table('tbl_routers')->find_many();
$ui->assign('r', $r);
run_hook('view_edit_plan'); #HOOK
$ui->display('hotspot-edit.tpl');
} else {
@ -96,6 +158,7 @@ switch ($action) {
$validity = _post('validity');
$validity_unit = _post('validity_unit');
$routers = _post('routers');
$pool_expired = _post('pool_expired');
$enabled = _post('enabled');
$msg = '';
@ -134,8 +197,12 @@ switch ($action) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addHotspotPlan($client, $name, $sharedusers, $rate);
if (!empty($pool_expired)) {
Mikrotik::setHotspotExpiredPlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired);
}
}
$d = ORM::for_table('tbl_plans')->create();
$d->name_plan = $name;
$d->id_bw = $id_bw;
@ -151,6 +218,7 @@ switch ($action) {
$d->validity_unit = $validity_unit;
$d->shared_users = $sharedusers;
$d->routers = $routers;
$d->pool_expired = $pool_expired;
$d->enabled = $enabled;
$d->save();
@ -176,6 +244,7 @@ switch ($action) {
$validity = _post('validity');
$validity_unit = _post('validity_unit');
$routers = _post('routers');
$pool_expired = _post('pool_expired');
$enabled = _post('enabled');
$msg = '';
@ -213,6 +282,9 @@ switch ($action) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::setHotspotPlan($client, $name, $sharedusers, $rate);
if (!empty($pool_expired)) {
Mikrotik::setHotspotExpiredPlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired);
}
}
$d->name_plan = $name;
@ -228,6 +300,7 @@ switch ($action) {
$d->validity_unit = $validity_unit;
$d->shared_users = $sharedusers;
$d->routers = $routers;
$d->pool_expired = $pool_expired;
$d->enabled = $enabled;
$d->save();
@ -260,8 +333,6 @@ switch ($action) {
$ui->assign('_title', $_L['PPPOE_Plans']);
$d = ORM::for_table('tbl_bandwidth')->find_many();
$ui->assign('d', $d);
$p = ORM::for_table('tbl_pool')->find_many();
$ui->assign('p', $p);
$r = ORM::for_table('tbl_routers')->find_many();
$ui->assign('r', $r);
run_hook('view_add_ppoe'); #HOOK
@ -274,10 +345,10 @@ switch ($action) {
$d = ORM::for_table('tbl_plans')->find_one($id);
if ($d) {
$ui->assign('d', $d);
$p = ORM::for_table('tbl_pool')->where('routers', $d['routers'])->find_many();
$ui->assign('p', $p);
$b = ORM::for_table('tbl_bandwidth')->find_many();
$ui->assign('b', $b);
$p = ORM::for_table('tbl_pool')->find_many();
$ui->assign('p', $p);
$r = ORM::for_table('tbl_routers')->find_many();
$ui->assign('r', $r);
run_hook('view_edit_ppoe'); #HOOK
@ -312,6 +383,7 @@ switch ($action) {
$validity_unit = _post('validity_unit');
$routers = _post('routers');
$pool = _post('pool_name');
$pool_expired = _post('pool_expired');
$enabled = _post('enabled');
$msg = '';
@ -348,6 +420,9 @@ switch ($action) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addPpoePlan($client, $name, $pool, $rate);
if (!empty($pool_expired)) {
Mikrotik::setPpoePlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired, '512K/512K');
}
}
$d = ORM::for_table('tbl_plans')->create();
@ -359,6 +434,7 @@ switch ($action) {
$d->validity_unit = $validity_unit;
$d->routers = $routers;
$d->pool = $pool;
$d->pool_expired = $pool_expired;
$d->enabled = $enabled;
$d->save();
@ -377,6 +453,7 @@ switch ($action) {
$validity_unit = _post('validity_unit');
$routers = _post('routers');
$pool = _post('pool_name');
$pool_expired = _post('pool_expired');
$enabled = _post('enabled');
$msg = '';
@ -414,6 +491,9 @@ switch ($action) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::setPpoePlan($client, $name, $pool, $rate);
if (!empty($pool_expired)) {
Mikrotik::setPpoePlan($client, 'EXPIRED NUXBILL ' . $pool_expired, $pool_expired, '512K/512K');
}
}
$d->name_plan = $name;
@ -423,6 +503,7 @@ switch ($action) {
$d->validity_unit = $validity_unit;
$d->routers = $routers;
$d->pool = $pool;
$d->pool_expired = $pool_expired;
$d->enabled = $enabled;
$d->save();

View File

@ -31,8 +31,14 @@ switch ($action) {
if ($admin['user_type'] != 'Admin') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
}
$lan = ORM::for_table('tbl_language')->find_many();
$ui->assign('lan', $lan);
$folders = [];
$files = scandir('system/lan/');
foreach ($files as $file) {
if(is_dir('system/lan/'.$file) && !in_array($file,['.','..'])){
$folders[] = $file;
}
}
$ui->assign('lan', $folders);
$timezonelist = Timezone::timezoneList();
$ui->assign('tlist', $timezonelist);
@ -225,6 +231,8 @@ switch ($action) {
$user_notification_payment = _post('user_notification_payment');
$address = _post('address');
$tawkto = _post('tawkto');
$http_proxy = _post('http_proxy');
$http_proxyauth = _post('http_proxyauth');
$radius_mode = _post('radius_mode') * 1;
run_hook('save_settings'); #HOOK
@ -251,6 +259,28 @@ switch ($action) {
$d->save();
$d = ORM::for_table('tbl_appconfig')->where('setting', 'http_proxy')->find_one();
if ($d) {
$d->value = $http_proxy;
$d->save();
} else {
$d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'http_proxy';
$d->value = $http_proxy;
$d->save();
}
$d = ORM::for_table('tbl_appconfig')->where('setting', 'http_proxyauth')->find_one();
if ($d) {
$d->value = $http_proxyauth;
$d->save();
} else {
$d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'http_proxyauth';
$d->value = $http_proxyauth;
$d->save();
}
$d = ORM::for_table('tbl_appconfig')->where('setting', 'CompanyFooter')->find_one();
if ($d) {
$d->value = $footer;

View File

@ -4,10 +4,40 @@
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/
require('../config.php');
require('orm.php');
// on some server, it getting error because of slash is backwards
function _autoloader($class)
{
if (strpos($class, '_') !== false) {
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
} else {
if (file_exists(__DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
}
}
spl_autoload_register('_autoloader');
if(php_sapi_name() !== 'cli'){
echo "<pre>";
}
require_once '../config.php';
require_once 'orm.php';
require_once 'autoload/PEAR2/Autoload.php';
include "autoload/Hookers.php";
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
@ -16,49 +46,30 @@ ORM::configure('return_result_sets', true);
ORM::configure('logging', true);
include "autoload/Hookers.php";
// notification message
if (file_exists("system/uploads/notifications.json")) {
$_notifmsg = json_decode(file_get_contents('system/uploads/notifications.json'), true);
if (file_exists("uploads/notifications.json")) {
$_notifmsg = json_decode(file_get_contents('uploads/notifications.json'), true);
}
$_notifmsg_default = json_decode(file_get_contents('system/uploads/notifications.default.json'), true);
$_notifmsg_default = json_decode(file_get_contents('uploads/notifications.default.json'), true);
//register all plugin
foreach (glob("plugin/*.php") as $filename) {
foreach (glob(File::pathFixer("plugin/*.php")) as $filename) {
include $filename;
}
// on some server, it getting error because of slash is backwards
function _autoloader($class)
{
if (strpos($class, '_') !== false) {
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
} else {
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
}
}
spl_autoload_register('_autoloader');
$result = ORM::for_table('tbl_appconfig')->find_many();
foreach ($result as $value) {
$config[$value['setting']] = $value['value'];
}
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
$statement = ORM::get_last_statement();
$rows = array();
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
}
$_c = $config;
date_default_timezone_set($config['timezone']);
@ -79,12 +90,16 @@ foreach ($d as $ds) {
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
$m = ORM::for_table('tbl_routers')->where('name', $ds['routers'])->find_one();
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
if (!$_c['radius_mode']) {
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
Mikrotik::setHotspotLimitUptime($client, $c['username']);
if(!empty($p['pool_expired'])){
Mikrotik::setHotspotUserPackage($client, $c['username'], 'EXPIRED NUXBILL '.$p['pool_expired']);
}else{
Mikrotik::removeHotspotUser($client, $c['username']);
}
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removeHotspotUser($client, $c['username']);
Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
}
//update database user dengan status off
@ -93,7 +108,6 @@ foreach ($d as $ds) {
// autorenewal from deposit
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
// if success, then get the balance
@ -123,12 +137,16 @@ foreach ($d as $ds) {
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
$m = ORM::for_table('tbl_routers')->where('name', $ds['routers'])->find_one();
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
if (!$_c['radius_mode']) {
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
Mikrotik::disablePpoeUser($client, $c['username']);
if(!empty($p['pool_expired'])){
Mikrotik::setPpoeUserPlan($client, $c['username'], 'EXPIRED NUXBILL '.$p['pool_expired']);
}else{
Mikrotik::removePpoeUser($client, $c['username']);
}
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
}
@ -137,12 +155,15 @@ foreach ($d as $ds) {
// autorenewal from deposit
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
// if success, then get the balance
Balance::min($ds['customer_id'], $p['price']);
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
echo "auto renewall Success\n";
} else {
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
echo "auto renewall Failed\n";
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #PPPOE \n" . $p['name_plan'] .
"\nRouter: " . $router_name .
"\nPrice: " . $p['price']);

View File

@ -7,46 +7,21 @@
* 0 7 * * * /usr/bin/php /var/www/system/cron_reminder.php
**/
require('../config.php');
require('orm.php');
require_once 'autoload/PEAR2/Autoload.php';
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
ORM::configure('password', $db_password);
ORM::configure('return_result_sets', true);
ORM::configure('logging', true);
include "autoload/Hookers.php";
// notification message
if(file_exists("system/uploads/notifications.json")){
$_notifmsg =json_decode(file_get_contents('system/uploads/notifications.json'), true);
}
$_notifmsg_default = json_decode(file_get_contents('system/uploads/notifications.default.json'), true);
//register all plugin
foreach (glob("plugin/*.php") as $filename) {
include $filename;
}
// on some server, it getting error because of slash is backwards
function _autoloader($class)
{
if (strpos($class, '_') !== false) {
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
} else {
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
@ -54,9 +29,34 @@ function _autoloader($class)
}
}
}
spl_autoload_register('_autoloader');
if(php_sapi_name() !== 'cli'){
echo "<pre>";
}
require_once '../config.php';
require_once 'orm.php';
require_once 'autoload/PEAR2/Autoload.php';
include "autoload/Hookers.php";
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
ORM::configure('password', $db_password);
ORM::configure('return_result_sets', true);
ORM::configure('logging', true);
// notification message
if (file_exists("uploads/notifications.json")) {
$_notifmsg = json_decode(file_get_contents('uploads/notifications.json'), true);
}
$_notifmsg_default = json_decode(file_get_contents('uploads/notifications.default.json'), true);
//register all plugin
foreach (glob(File::pathFixer("plugin/*.php")) as $filename) {
include $filename;
}
$result = ORM::for_table('tbl_appconfig')->find_many();
foreach ($result as $value) {
$config[$value['setting']] = $value['value'];
@ -69,6 +69,14 @@ $d = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
run_hook('cronjob_reminder'); #HOOK
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
$statement = ORM::get_last_statement();
$rows = array();
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
}
$day7 = date('Y-m-d', strtotime("+7 day"));
$day3 = date('Y-m-d', strtotime("+3 day"));

View File

@ -252,8 +252,8 @@ $_L['Community'] = 'Community';
$_L['1_user_can_be_used_for_many_devices'] = '1 user can be used for many devices?';
$_L['Cannot_be_change_after_saved'] = 'Cannot be change after saved';
$_L['Explain_Coverage_of_router'] = 'Jelaskan Cakupan wilayah hotspot';
$_L['Name_of_Area_that_router_operated'] = 'Nama Lokasi/Wilayah Router beroperasi';
$_L['Explain_Coverage_of_router'] = 'Explain Coverage of router';
$_L['Name_of_Area_that_router_operated'] = 'Name of Area that router operated';
$_L['Payment_Notification_URL_Recurring_Notification_URL_Pay_Account_Notification_URL'] = 'Payment Notification URL, Recurring Notification URL, Pay Account Notification URL';
$_L['Finish_Redirect_URL_Unfinish_Redirect_URL_Error_Redirect_URL'] = 'Finish Redirect URL, Unfinish Redirect URL, Error Redirect URL';
$_L['Status'] = 'Status';
@ -310,7 +310,6 @@ $_L['Please_enter_your_email_address'] = 'Please enter your email address';
$_L['Failed_to_create_Paypal_transaction'] = 'Failed to create Paypal transaction.';
$_L['Plugin'] = 'Plugin';
$_L['Plugin_Manager'] = 'Plugin Manager';
$_L['Plugin_Manager'] = 'Plugin Manager';
$_L['User_Notification'] = 'User Notification';
$_L['Expired_Notification'] = 'Expired Notification';
$_L['User_will_get_notification_when_package_expired'] = 'User will get notification when package expired';
@ -375,13 +374,31 @@ $_L['Active'] = 'Active';
$_L['Transfer_Balance'] = 'Transfer Balance';
$_L['Send_your_balance'] = 'Send your balance?';
$_L['Send'] = 'Send';
$_L['Cannot_send_to_yourself'] = 'Cannot send to yourself';
$_L['Sending_balance_success'] = 'Sending balance success';
$_L['From'] = 'From';
$_L['To'] = 'To';
$_L['insufficient_balance'] = 'insufficient balance';
$_L['Send_Balance'] = 'Send Balance';
$_L['Received_Balance'] = 'Received Balance';
$_L['Minimum_Balance_Transfer'] = 'Minimum Balance Transfer';
$_L['Minimum_Transfer'] = 'Minimum Transfer';
$_L['Company_Logo'] = 'Company Logo';
$_L['Cannot_send_to_yourself'] = 'Cannot send to yourself';
$_L['Sending_balance_success'] = 'Sending balance success';
$_L['From'] = 'From';
$_L['To'] = 'To';
$_L['insufficient_balance'] = 'insufficient balance';
$_L['Send_Balance'] = 'Send Balance';
$_L['Received_Balance'] = 'Received Balance';
$_L['Minimum_Balance_Transfer'] = 'Minimum Balance Transfer';
$_L['Minimum_Transfer'] = 'Minimum Transfer';
$_L['Company_Logo'] = 'Company Logo';
$_L['Expired_IP_Pool'] = 'Expired IP Pool';
$_L['Proxy'] = 'Proxy';
$_L['Proxy_Server'] = 'Proxy Server';
$_L['Proxy_Server_Login'] = 'Proxy Server Login';
$_L['Hotspot_Plan'] = 'Hotspot Plan';
$_L['PPPOE_Plan'] = 'PPPOE Plan';
$_L['UNKNOWN'] = 'UNKNOWN';
$_L['Are_You_Sure'] = 'Are You Sure?';
$_L['Success_to_send_package'] = 'Success to send package';
$_L['Target_has_active_plan_different_with_current_plant'] = 'Target has active plan, different with current plant.';
$_L['Recharge_a_friend'] = 'Recharge a friend';
$_L['Buy_for_friend'] = 'Buy for friend';
$_L['Buy_this_for_friend_account'] = 'Buy this for friend account?';
$_L['Review_package_before_recharge'] = 'Review package before recharge';
$_L['Activate'] = 'Activate';
$_L['Deactivate'] = 'Deactivate';
$_L['Sync'] = 'Sync';
$_L['Failed_to_create_PaymeTrust_transaction'] = 'Failed to create PaymeTrust transaction.';

View File

@ -338,3 +338,11 @@ $_L['Country_Code_Phone'] = 'Kode Negara Telepon';
$_L['Voucher_activation_menu_will_be_hidden'] = 'Info Pembelian Voucher dan Redeem akan disembunyikan';
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Pelanggan dapat topup saldo untuk langganan Internet';
$_L['Allow_balance_transfer_between_customers'] = 'Bolehkan transfer saldo antar pelanggan';
$_L['Refill_Balance'] = 'Refill Balance';
$_L['Balance_Plans'] = 'Balance Plans';
$_L['Expired_IP_Pool'] = 'Expired IP Pool';
$_L['Company_Logo'] = 'Company Logo';
$_L['Disable_Voucher'] = 'Disable Voucher';
$_L['Minimum_Balance_Transfer'] = 'Minimum Balance Transfer';
$_L['Reminder_Notification'] = 'Reminder Notification';
$_L['Invoice_Footer'] = 'Invoice Footer';

View File

@ -340,4 +340,5 @@ $_L['Invoice'] = 'Invoice';
$_L['Country_Code_Phone'] = 'Country Code Phone';
$_L['Voucher_activation_menu_will_be_hidden'] = 'Voucher activation menu will be hidden';
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Customer can deposit money to buy voucher';
$_L['Allow_balance_transfer_between_customers'] = 'Allow balance transfer between customers';
$_L['Allow_balance_transfer_between_customers'] = 'Allow balance transfer between customers';$_L['Refill_Balance'] = 'Refill Balance';
$_L['Balance_Plans'] = 'Balance Plans';

View File

@ -7,11 +7,12 @@ if(php_sapi_name() !== 'cli'){
die("RUN ON COMMAND LINE ONLY BY RADIUS ENGINE");
}
require(__DIR__.'/../config.php');
require(__DIR__.'/orm.php');
require_once __DIR__.File::pathFixer('/../config.php');
require_once __DIR__.File::pathFixer('orm.php');
require_once __DIR__.File::pathFixer('/autoload/PEAR2/Autoload.php');
include __DIR__.File::pathFixer("/autoload/Hookers.php");
use PEAR2\Net\RouterOS;
require_once 'autoload/PEAR2/Autoload.php';
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);

View File

@ -17,5 +17,9 @@
"2023.8.28" : [
"ALTER TABLE `tbl_user_recharges` ADD `recharged_time` time NOT NULL DEFAULT '00:00:00' AFTER `recharged_on`;",
"ALTER TABLE `tbl_transactions` ADD `recharged_time` time NOT NULL DEFAULT '00:00:00' AFTER `recharged_on`;"
],
"2023.9.5" : [
"DROP TABLE `tbl_language`;",
"ALTER TABLE `tbl_plans` ADD `pool_expired` varchar(40) NOT NULL DEFAULT '' AFTER `pool`;"
]
}

View File

@ -45,18 +45,16 @@
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Default_Language']}</label>
<div class="col-md-4">
<div class="col-md-6">
<select class="form-control" name="lan" id="lan">
{foreach $lan as $lans}
<option value="{$lans['folder']}" {if $_c['language'] eq $lans['folder']}
selected="selected" {/if}>{$lans['name']}</option>
<option value="{$lans}" {if $_c['language'] eq $lans}
selected="selected" {/if}>{$lans}</option>
{/foreach}
</select>
</div>
<div class="col-md-2">
<a href="{$_url}settings/language" type="button"
class="btn btn-line-success btn-icon-inline"><i
class="ion ion-android-add"></i>{$_L['Add_Language']}</a>
<div class="col-md-4 help-block">
To add new Language, just add the folder, it will automatically detected
</div>
</div>
<div class="form-group">
@ -78,8 +76,8 @@
<div class="col-md-6">
<input type="text" class="form-control" id="currency_code" name="currency_code"
value="{$_c['currency_code']}">
<span class="help-block">{$_L['currency_help']}</span>
</div>
<span class="help-block col-md-4">{$_L['currency_help']}</span>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Country Code Phone')}</label>

View File

@ -80,6 +80,7 @@
<b>[[type]]</b> is Hotspot/PPPOE.<br>
<b>[[plan_name]]</b> Internet Package.<br>
<b>[[plan_price]]</b> Internet Package Prices.<br>
<b>[[name]]</b> Receiver name.<br>
<b>[[user_name]]</b> Username internet.<br>
<b>[[user_password]]</b> User password.<br>
<b>[[expired_date]]</b> Expired datetime.<br>
@ -106,9 +107,12 @@
<b>[[type]]</b> is Hotspot/PPPOE.<br>
<b>[[plan_name]]</b> Internet Package.<br>
<b>[[plan_price]]</b> Internet Package Prices.<br>
<b>[[name]]</b> Receiver name.<br>
<b>[[user_name]]</b> Username internet.<br>
<b>[[user_password]]</b> User password.<br>
<b>[[trx_date]]</b> Transaction datetime.<br>
<b>[[balance_before]]</b> Balance Before.<br>
<b>[[balance]]</b> Balance After.<br>
<b>[[footer]]</b> Invoice Footer.
</p>
</div>
@ -122,7 +126,8 @@
</div>
<p class="col-md-4 help-block">
<b>[[name]]</b> Receiver name.<br>
<b>[[balance]]</b> how much balance have been send.
<b>[[balance]]</b> how much balance have been send.<br>
<b>[[current_balance]]</b> Current Balance.
</p>
</div>
</div>
@ -135,7 +140,8 @@
</div>
<p class="col-md-4 help-block">
<b>[[name]]</b> Sender name.<br>
<b>[[balance]]</b> how much balance have been received.
<b>[[balance]]</b> how much balance have been received.<br>
<b>[[current_balance]]</b> Current Balance.
</p>
</div>
</div>

View File

@ -24,7 +24,8 @@
<label class="col-md-2 control-label">{Lang::T('Company Logo')}</label>
<div class="col-md-6">
<input type="file" class="form-control" id="logo" name="logo" accept="image/*">
<span class="help-block">For PDF Reports | Best size 1078 x 200 | uploaded image will be autosize</span>
<span class="help-block">For PDF Reports | Best size 1078 x 200 | uploaded image will be
autosize</span>
</div>
<span class="help-block col-md-4">
<a href="./{$logo}" target="_blank"><img src="./{$logo}" height="48" alt="logo for PDF"></a>
@ -135,7 +136,8 @@
<div class="form-group">
<label class="col-md-2 control-label">Telegram Bot Token</label>
<div class="col-md-6">
<input type="text" class="form-control" id="telegram_bot" name="telegram_bot"
<input type="password" class="form-control" id="telegram_bot" name="telegram_bot" onmouseleave="this.type = 'password'"
onmouseenter="this.type = 'text'"
value="{$_c['telegram_bot']}" placeholder="123456:asdasgdkuasghddlashdashldhalskdklasd">
</div>
</div>
@ -270,7 +272,6 @@
</div>
{Lang::T('Invoice')}
</div>
<div class="panel-heading"></div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Invoice Footer')}</label>
@ -281,6 +282,30 @@
</div>
</div>
</div>
<div class="panel-heading">
<div class="btn-group pull-right">
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
</div>
{Lang::T('Proxy')}
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Proxy Server')}</label>
<div class="col-md-6">
<input type="text" class="form-control" id="http_proxy" name="http_proxy"
value="{$_c['http_proxy']}" placeholder="127.0.0.1:3128">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Proxy Server Login')}</label>
<div class="col-md-6">
<input type="password" class="form-control" id="http_proxyauth" name="http_proxyauth" autocomplete="off"
value="{$_c['http_proxyauth']}" placeholder="username:password" onmouseleave="this.type = 'password'"
onmouseenter="this.type = 'text'">
</div>
</div>
</div>
</div>
<div class="panel-body">

View File

@ -1,4 +1,4 @@
<option value=''>{$_L['Select_Pool']}</option>
{foreach $d as $ds}
<option value="{$ds['pool_name']}">{$ds['pool_name']}</option>
{/foreach}

View File

@ -1,4 +1,4 @@
<option value="">Select Routers</option>
<option value=''>{$_L['Select_Routers']}</option>
{foreach $d as $ds}
<option value="{$ds['name']}">{$ds['name']}</option>
{/foreach}

View File

@ -1,4 +1,4 @@
<option value="">Select Plans</option>
{foreach $d as $ds}
<option value="{$ds['id']}">{$ds['name_plan']}</option>
<option value="{$ds['id']}">{$ds['name_plan']} &bull; {Lang::moneyFormat($ds['price'])}</option>
{/foreach}

View File

@ -130,7 +130,7 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="col-sm-6" id="update">
<div class="box box-primary box-hovered mb20 activities">
<div class="box-header">
<h3 class="box-title">PHPNUXBILL</h3>
@ -142,8 +142,7 @@
<div class="box-footer" id="latestVersion">ver</div>
<div class="box-footer">
<div class="btn-group btn-group-justified" role="group" aria-label="...">
<a href="./update.php" target="_blank" class="btn btn-success btn-sm btn-block">Install Latest
Version</a>
<a href="./update.php" class="btn btn-success btn-sm btn-block">Install Latest Version</a>
<a href="https://github.com/hotspotbilling/phpnuxbill/archive/refs/heads/master.zip" target="_blank"
class="btn btn-warning btn-sm btn-block">Download Latest Version</a>
</div>

View File

@ -24,14 +24,17 @@
<p class="text-muted">{Lang::nl2br($d['address'])}</p>
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{$_L['Password']}</b> <span class="pull-right" style="background-color: black; color:black;"
onclick="this.select()">{$d['password']}</span>
<b>{$_L['Password']}</b> <input type="password" value="{$d['password']}"
style=" border: 0px; text-align: right;" class="pull-right"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
onclick="this.select()">
</li>
{if $d['pppoe_password'] != ''}
<li class="list-group-item">
<b>PPPOE {$_L['Password']}</b> <span class="pull-right"
style="background-color: black; color:black;"
onclick="this.select()">{$d['pppoe_password']}</span>
<b>PPPOE {$_L['Password']}</b> <input type="password" value="{$d['pppoe_password']}"
style=" border: 0px; text-align: right;" class="pull-right"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
onclick="this.select()">
</li>
{/if}
<li class="list-group-item">
@ -84,8 +87,28 @@
{$package['routers']} <span class="pull-right">{$package['method']}</span>
</li>
</ul>
<div class="row">
<div class="col-xs-4">
<a href="{$_url}customers/deactivate/{$d['id']}" id="{$d['id']}"
class="btn btn-danger btn-block btn-sm"
onclick="return confirm('This will deactivate Customer Plan, and make it expired')">{Lang::T('Deactivate')}</a>
</div>
<div class="col-xs-4">
<a href="{$_url}customers/recharge/{$d['id']}"
onclick="return confirm('This will extend Customer plan, same as recharge')"
class="btn btn-success btn-sm btn-block">{Lang::T('Recharge')}</a>
</div>
<div class="col-xs-4">
<a href="{$_url}customers/sync/{$d['id']}"
onclick="return confirm('This will sync Customer to Mikrotik?')"
class="btn btn-primary btn-sm btn-block">{Lang::T('Sync')}</a>
</div>
</div>
</div>
</div>
{else}
<a href="{$_url}prepaid/recharge/{$d['id']}"
class="btn btn-success btn-sm btn-block mt-1">{Lang::T('Recharge')}</a><br>
{/if}
<a href="{$_url}customers/list" class="btn btn-primary btn-sm btn-block mt-1">{Lang::T('Back')}</a><br>
</div>

View File

@ -24,34 +24,37 @@
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{$_L['Manage']}</th>
<th>{$_L['Username']}</th>
<th>{$_L['Full_Name']}</th>
<th>{Lang::T('Balance')}</th>
<th>{$_L['Phone_Number']}</th>
<th>{$_L['Email']}</th>
<th>{$_L['Package']}</th>
<th>{$_L['Created_On']}</th>
<th>{$_L['Recharge']}</th>
<th>{$_L['Manage']}</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr>
<td align="center">
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}"
class="btn btn-success btn-sm">{Lang::T('View')}</a>
</td>
<td>{$ds['username']}</td>
<td>{$ds['fullname']}</td>
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'" style="cursor:pointer;">{$ds['username']}</td>
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'" style="cursor: pointer;">{$ds['fullname']}</td>
<td>{Lang::moneyFormat($ds['balance'])}</td>
<td>{$ds['phonenumber']}</td>
<td>{$ds['email']}</td>
<td align="center" api-get-text="{$_url}autoload/customer_is_active/{$ds['id']}">
<span class="label label-default">&bull;</span>
</td>
<td>{Lang::dateTimeFormat($ds['created_at'])}</td>
<td align="center"><a href="{$_url}prepaid/recharge-user/{$ds['id']}" id="{$ds['id']}"
class="btn btn-primary btn-sm">{$_L['Recharge']}</a></td>
<td align="center">
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
class="btn btn-success btn-xs">&nbsp;&nbsp;{Lang::T('View')}&nbsp;&nbsp;</a>
<a href="{$_url}prepaid/recharge/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
class="btn btn-primary btn-xs">{$_L['Recharge']}</a>
</td>
</tr>
{/foreach}
</tbody>

View File

@ -33,7 +33,7 @@
<div class="col-lg-3 col-xs-6">
<div class="small-box bg-yellow">
<div class="inner">
<h4>{$u_act}</h4>
<h4>{$u_act}/{$u_all}</h4>
<p>{$_L['Users_Active']}</p>
</div>
@ -47,7 +47,7 @@
<div class="col-lg-3 col-xs-6">
<div class="small-box bg-red">
<div class="inner">
<h4>{$u_all}</h4>
<h4>{$c_all}</h4>
<p>{$_L['Total_Users']}</p>
</div>

View File

@ -112,7 +112,8 @@
<div class="form-group">
<label class="col-md-2 control-label"><a href="{$_url}routers/add">{$_L['Router_Name']}</a></label>
<div class="col-md-6">
<select id="routers" name="routers" class="form-control select2">
<select id="routers" name="routers" required class="form-control select2">
<option value=''>{$_L['Select_Routers']}</option>
{foreach $r as $rs}
<option value="{$rs['name']}">{$rs['name']}</option>
{/foreach}
@ -120,9 +121,16 @@
<p class="help-block">{Lang::T('Cannot be change after saved')}</p>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
<div class="col-md-6">
<select id="pool_expired" name="pool_expired" class="form-control select2">
<option value=''>{$_L['Select_Pool']}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Save']}</button>
Or <a href="{$_url}services/hotspot">{$_L['Cancel']}</a>
</div>

View File

@ -114,9 +114,20 @@
<input type="text" class="form-control" id="routers" name="routers" value="{$d['routers']}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
<div class="col-md-6">
<select id="pool_expired" name="pool_expired" class="form-control select2">
<option value=''>{$_L['Select_Pool']}</option>
{foreach $p as $ps}
<option value="{$ps['pool_name']}" {if $d['pool_expired'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Save']}</button>
Or <a href="{$_url}services/hotspot">{$_L['Cancel']}</a>
</div>

View File

@ -1,68 +1,81 @@
{include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12">
<div class="panel panel-hovered mb20 panel-primary">
<div class="panel-heading">{$_L['Hotspot_Plans']}</div>
<div class="panel-body">
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
<div class="col-md-8">
<form id="site-search" method="post" action="{$_url}services/hotspot/">
<div class="input-group">
<div class="input-group-addon">
<span class="fa fa-search"></span>
</div>
<input type="text" name="name" class="form-control" placeholder="{$_L['Search_by_Name']}...">
<div class="input-group-btn">
<button class="btn btn-success" type="submit">{$_L['Search']}</button>
</div>
</div>
</form>
</div>
<div class="col-md-4">
<a href="{$_url}services/add" class="btn btn-primary btn-block waves-effect"><i class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{$_L['Plan_Name']}</th>
<th>{$_L['Plan_Type']}</th>
<th>{$_L['Bandwidth_Plans']}</th>
<th>{$_L['Plan_Price']}</th>
<th>{$_L['Time_Limit']}</th>
<th>{$_L['Data_Limit']}</th>
<th>{$_L['Plan_Validity']}</th>
<th>{$_L['Routers']}</th>
<th>{$_L['Manage']}</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"{/if}>
<td>{$ds['name_plan']}</td>
<td>{$ds['typebp']}</td>
<td>{$ds['name_bw']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
<td>{$ds['time_limit']} {$ds['time_unit']}</td>
<td>{$ds['data_limit']} {$ds['data_unit']}</td>
<td>{$ds['validity']} {$ds['validity_unit']}</td>
<td>{$ds['routers']}</td>
<td>
<a href="{$_url}services/edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}services/delete/{$ds['id']}" id="{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')" class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{$paginator['contents']}
<div class="row">
<div class="col-sm-12">
<div class="panel panel-hovered mb20 panel-primary">
<div class="panel-heading">
<div class="btn-group pull-right">
<a class="btn btn-primary btn-xs" title="save" href="{$_url}services/sync/hotspot"
onclick="return confirm('This will sync/send hotspot plan to Mikrotik?')"><span
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
</div>{$_L['Hotspot_Plans']}
</div>
<div class="panel-body">
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
<div class="col-md-8">
<form id="site-search" method="post" action="{$_url}services/hotspot/">
<div class="input-group">
<div class="input-group-addon">
<span class="fa fa-search"></span>
</div>
<input type="text" name="name" class="form-control"
placeholder="{$_L['Search_by_Name']}...">
<div class="input-group-btn">
<button class="btn btn-success" type="submit">{$_L['Search']}</button>
</div>
</div>
</form>
</div>
<div class="col-md-4">
<a href="{$_url}services/add" class="btn btn-primary btn-block waves-effect"><i
class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{$_L['Plan_Name']}</th>
<th>{$_L['Plan_Type']}</th>
<th>{$_L['Bandwidth_Plans']}</th>
<th>{$_L['Plan_Price']}</th>
<th>{$_L['Time_Limit']}</th>
<th>{$_L['Data_Limit']}</th>
<th>{$_L['Plan_Validity']}</th>
<th>{$_L['Routers']}</th>
<th>{Lang::T('Expired IP Pool')}</th>
<th>{$_L['Manage']}</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['enabled'] != 1}class="danger" title="disabled" {/if}>
<td>{$ds['name_plan']}</td>
<td>{$ds['typebp']}</td>
<td>{$ds['name_bw']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
<td>{$ds['time_limit']} {$ds['time_unit']}</td>
<td>{$ds['data_limit']} {$ds['data_unit']}</td>
<td>{$ds['validity']} {$ds['validity_unit']}</td>
<td>{$ds['routers']}</td>
<td>{$ds['pool_expired']}</td>
<td>
<a href="{$_url}services/edit/{$ds['id']}"
class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}services/delete/{$ds['id']}" id="{$ds['id']}"
onclick="return confirm('{$_L['Delete']}?')"
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{$paginator['contents']}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{include file="sections/footer.tpl"}
{include file="sections/footer.tpl"}

BIN
ui/ui/images/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

View File

@ -2,7 +2,7 @@
<div class="row">
<div class="col-sm-12">
<div class="panel mb20 panel-primary panel-hovered">
<div class="panel-heading">{$_L[$pageHeader]}</div>
<div class="panel-heading">{$pageHeader}</div>
<div id="myNicPanel" style="width: 100%;"></div>
<div id="panel-edit" class="panel-body">{$htmls}</div>
{if $writeable}

View File

@ -3,7 +3,14 @@
<div class="row">
<div class="col-sm-12">
<div class="panel panel-hovered mb20 panel-primary">
<div class="panel-heading">{$_L['Pool']}</div>
<div class="panel-heading">
<div class="btn-group pull-right">
<a class="btn btn-primary btn-xs" title="save" href="{$_url}pool/sync"
onclick="return confirm('This will sync/send IP Pool to Mikrotik?')"><span
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
</div>
{$_L['Pool']}
</div>
<div class="panel-body">
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
<div class="col-md-8">
@ -45,9 +52,9 @@
<td>{$ds['range_ip']}</td>
<td>{$ds['routers']}</td>
<td align="center">
<a href="{$_url}pool/edit/{$ds['id']}"
class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}pool/delete/{$ds['id']}" id="{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')"
<a href="{$_url}pool/edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}pool/delete/{$ds['id']}" id="{$ds['id']}"
onclick="return confirm('{$_L['Delete']}?')"
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>

View File

@ -60,7 +60,7 @@
<div class="form-group">
<label class="col-md-2 control-label"><a href="{$_url}routers/add">{$_L['Router_Name']}</a></label>
<div class="col-md-6">
<select id="routers" name="routers" class="form-control select2">
<select id="routers" name="routers" required class="form-control select2">
<option value=''>{$_L['Select_Routers']}</option>
{foreach $r as $rs}
<option value="{$rs['name']}">{$rs['name']}</option>
@ -72,14 +72,21 @@
<div class="form-group">
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{$_L['Pool']}</a></label>
<div class="col-md-6">
<select id="pool_name" name="pool_name" class="form-control select2">
<select id="pool_name" name="pool_name" required class="form-control select2">
<option value=''>{$_L['Select_Pool']}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
<div class="col-md-6">
<select id="pool_expired" name="pool_expired" class="form-control select2">
<option value=''>{$_L['Select_Pool']}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-primary waves-effect waves-light" type="submit">{$_L['Save']}</button>
Or <a href="{$_url}services/pppoe">{$_L['Cancel']}</a>
</div>

View File

@ -60,9 +60,20 @@
<div class="form-group">
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{$_L['Pool']}</a></label>
<div class="col-md-6">
<select id="pool_name" name="pool_name" class="form-control select2">
<select id="pool_name" name="pool_name" required class="form-control select2">
{foreach $p as $ps}
<option value="{$ps['pool_name']}" {if $d['pool_name'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
<option value="{$ps['pool_name']}" {if $d['pool'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('Expired IP Pool')}</a></label>
<div class="col-md-6">
<select id="pool_expired" name="pool_expired" class="form-control select2">
<option value=''>{$_L['Select_Pool']}</option>
{foreach $p as $ps}
<option value="{$ps['pool_name']}" {if $d['pool_expired'] eq $ps['pool_name']} selected {/if}>{$ps['pool_name']}</option>
{/foreach}
</select>
</div>

View File

@ -1,63 +1,76 @@
{include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12">
<div class="panel panel-hovered mb20 panel-primary">
<div class="panel-heading">{$_L['PPPOE_Plans']}</div>
<div class="panel-body">
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
<div class="col-md-8">
<form id="site-search" method="post" action="{$_url}services/pppoe/">
<div class="input-group">
<div class="input-group-addon">
<span class="fa fa-search"></span>
</div>
<input type="text" name="name" class="form-control" placeholder="{$_L['Search_by_Name']}...">
<div class="input-group-btn">
<button class="btn btn-success" type="submit">{$_L['Search']}</button>
</div>
</div>
</form>
</div>
<div class="col-md-4">
<a href="{$_url}services/pppoe-add" class="btn btn-primary btn-block waves-effect"><i class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{$_L['Plan_Name']}</th>
<th>{$_L['Bandwidth_Plans']}</th>
<th>{$_L['Plan_Price']}</th>
<th>{$_L['Plan_Validity']}</th>
<th>{$_L['Pool']}</th>
<th>{$_L['Routers']}</th>
<th>{$_L['Manage']}</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"{/if}>
<td>{$ds['name_plan']}</td>
<td>{$ds['name_bw']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
<td>{$ds['validity']} {$ds['validity_unit']}</td>
<td>{$ds['pool']}</td>
<td>{$ds['routers']}</td>
<td>
<a href="{$_url}services/pppoe-edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}services/pppoe-delete/{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')" id="{$ds['id']}" class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{$paginator['contents']}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="panel panel-hovered mb20 panel-primary">
<div class="panel-heading">
<div class="btn-group pull-right">
<a class="btn btn-primary btn-xs" title="save" href="{$_url}services/sync/pppoe"
onclick="return confirm('This will sync/send PPPOE plan to Mikrotik?')"><span
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
</div>{$_L['PPPOE_Plans']}
</div>
<div class="panel-body">
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
<div class="col-md-8">
<form id="site-search" method="post" action="{$_url}services/pppoe/">
<div class="input-group">
<div class="input-group-addon">
<span class="fa fa-search"></span>
</div>
<input type="text" name="name" class="form-control"
placeholder="{$_L['Search_by_Name']}...">
<div class="input-group-btn">
<button class="btn btn-success" type="submit">{$_L['Search']}</button>
</div>
</div>
</form>
</div>
<div class="col-md-4">
<a href="{$_url}services/pppoe-add" class="btn btn-primary btn-block waves-effect"><i
class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{$_L['Plan_Name']}</th>
<th>{$_L['Bandwidth_Plans']}</th>
<th>{$_L['Plan_Price']}</th>
<th>{$_L['Plan_Validity']}</th>
<th>{$_L['Pool']}</th>
<th>{Lang::T('Expired IP Pool')}</th>
<th>{$_L['Routers']}</th>
<th>{$_L['Manage']}</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['enabled'] != 1}class="danger" title="disabled" {/if}>
<td>{$ds['name_plan']}</td>
<td>{$ds['name_bw']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
<td>{$ds['validity']} {$ds['validity_unit']}</td>
<td>{$ds['pool']}</td>
<td>{$ds['pool_expired']}</td>
<td>{$ds['routers']}</td>
<td>
<a href="{$_url}services/pppoe-edit/{$ds['id']}"
class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}services/pppoe-delete/{$ds['id']}"
onclick="return confirm('{$_L['Delete']}?')" id="{$ds['id']}"
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{$paginator['contents']}
</div>
</div>
</div>
</div>
{include file="sections/footer.tpl"}
{include file="sections/footer.tpl"}

View File

@ -28,12 +28,15 @@
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Created_On']}</label>
<div class="col-md-6">
<input type="date" class="form-control" id="recharged_on" name="recharged_on" readonly
value="{$d['recharged_on']} {$d['recharged_time']}">
<div class="col-md-4">
<input type="date" class="form-control" name="expiration" readonly
value="{$d['recharged_on']}">
</div>
<div class="col-md-2">
<input type="text" class="form-control" placeholder="00:00:00" readonly
value="{$d['recharged_time']}">
</div>
</div>
<div class="form-group">

View File

@ -3,7 +3,13 @@
<div class="row">
<div class="col-sm-12">
<div class="panel panel-hovered mb20 panel-primary">
<div class="panel-heading">{$_L['Prepaid_User']}</div>
<div class="panel-heading">
<div class="btn-group pull-right">
<a class="btn btn-primary btn-xs" title="save" href="{$_url}prepaid/sync"
onclick="return confirm('This will sync/send Caustomer active plan to Mikrotik?')"><span
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
</div>{$_L['Prepaid_User']}
</div>
<div class="panel-body">
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
<div class="col-md-8">
@ -41,7 +47,7 @@
</thead>
<tbody>
{foreach $d as $ds}
<tr>
<tr {if $ds['status']=='off'}class="danger" {/if}>
<td><a href="{$_url}customers/viewu/{$ds['username']}">{$ds['username']}</a></td>
<td>{$ds['namebp']}</td>
<td>{$ds['type']}</td>
@ -53,6 +59,7 @@
<a href="{$_url}prepaid/edit/{$ds['id']}"
class="btn btn-warning btn-xs">{$_L['Edit']}</a>
<a href="{$_url}prepaid/delete/{$ds['id']}" id="{$ds['id']}"
onclick="return confirm('{$_L['Delete']}?')"
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>

View File

@ -1,136 +1,168 @@
<!DOCTYPE html>
<html>
<head>
<title>{$_title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="ui/ui/images/favicon.ico">
<style>
.ukuran {
size:A4;
}
.ukuran {
size: A4;
}
body,td,th {
font-size: 12px;
font-family: Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif;
}
page[size="A4"] {
background: white;
width: 21cm;
height: 29.7cm;
display: block;
margin: 0 auto;
margin-bottom: 0.5cm;
html, body {
width: 210mm;
height: 297mm;
}
}
@media print {
body {
size: auto;
margin: 0;
box-shadow: 0;
body,
td,
th {
font-size: 12px;
font-family: Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif;
}
page[size="A4"] {
margin: 0;
size: auto;
box-shadow: 0;
background: white;
width: 21cm;
height: 29.7cm;
display: block;
margin: 0 auto;
margin-bottom: 0.5cm;
html,
body {
width: 210mm;
height: 297mm;
}
}
.page-break { display: block; page-break-before: always; }
.no-print, .no-print *
{
display: none !important;
@media print {
body {
size: auto;
margin: 0;
box-shadow: 0;
}
page[size="A4"] {
margin: 0;
size: auto;
box-shadow: 0;
}
.page-break {
display: block;
page-break-before: always;
}
.no-print,
.no-print * {
display: none !important;
}
}
}
</style>
</head>
<body>
<page size="A4">
<page size="A4">
<form method="post" action="{$_url}prepaid/print-voucher/" class="no-print">
<table width="100%" border="0" cellspacing="0" cellpadding="1" class="btn btn-default btn-sm">
<tr>
<td>ID &gt; <input type="text" name="from_id" style="width:40px" value="{$from_id}"> limit <input type="text" name="limit" style="width:40px" value="{$limit}"></td>
<td>PageBreak after <input type="text" style="width:40px" name="pagebreak" value="{$pagebreak}"> vouchers</td>
<td>Plans <select id="plan_id" name="planid" style="width:150px">
<option value="0">--all--</option>
{foreach $plans as $plan}
<option value="{$plan['id']}" {if $plan['id']==$planid}selected{/if}>{$plan['name_plan']}</option>
{/foreach}
</select></td>
<td><button type="submit">submit</button></td>
</tr>
</table><hr>
<center><button type="button" id="actprint" class="btn btn-default btn-sm no-print">{$_L['Click_Here_to_Print']}</button><br>
{$_L['Print_Info']}<br>
show {$v|@count} vouchers from {$vc} vouchers<br>
from ID {$v[0]['id']} limit {$limit} vouchers
</center>
<table width="100%" border="0" cellspacing="0" cellpadding="1" class="btn btn-default btn-sm">
<tr>
<td>ID &gt; <input type="text" name="from_id" style="width:40px" value="{$from_id}"> limit <input
type="text" name="limit" style="width:40px" value="{$limit}"></td>
<td>PageBreak after <input type="text" style="width:40px" name="pagebreak" value="{$pagebreak}">
vouchers</td>
<td>Plans <select id="plan_id" name="planid" style="width:150px">
<option value="0">--all--</option>
{foreach $plans as $plan}
<option value="{$plan['id']}" {if $plan['id']==$planid}selected{/if}>{$plan['name_plan']}
</option>
{/foreach}
</select></td>
<td><button type="submit">submit</button></td>
</tr>
</table>
<hr>
<center><button type="button" id="actprint"
class="btn btn-default btn-sm no-print">{$_L['Click_Here_to_Print']}</button><br>
{$_L['Print_Info']}<br>
show {$v|@count} vouchers from {$vc} vouchers<br>
from ID {$v[0]['id']} limit {$limit} vouchers
</center>
</form>
<div id="printable">
<hr>
{foreach $v as $vs}
{$jml = $jml + 1}
<table width="100%" height="200" border="0" cellspacing="0" cellpadding="1" style="margin-bottom:5px">
<tbody>
<tr><td align="center" valign="middle"></td></tr>
<tr>
<td align="center" valign="top">
<table width="100%" border="0" cellspacing="0" cellpadding="2">
{$jml = $jml + 1}
<table width="100%" height="200" border="0" cellspacing="0" cellpadding="1" style="margin-bottom:5px">
<tbody>
<tr>
<td width="50%" valign="middle" style="padding-right:10px">
<center><strong style="font-size:38px">{$_L['Voucher_Hotspot']}</strong><span class="no-print"> ID {$vs['id']}</span></center>
<table width="100%" border="1" cellspacing="0" cellpadding="1" bordercolor="#757575">
<tbody>
<tr>
<td rowspan="5" width="1"><img src="qrcode/?data={$vs['code']}"></td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:25px">{Lang::moneyFormat($vs['price'])}</td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:20px">{$_L['Code_Voucher']}</td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:25px">{$vs['code']}</td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:15px">{$vs['name_plan']}</td>
</tr>
</tbody>
</table>
</td>
<td valign="top" style="padding-left:10px">
{include file="$_path/../pages/Voucher.html"}
<td align="center" valign="middle"></td>
</tr>
<tr>
<td align="center" valign="top">
<table width="100%" border="0" cellspacing="0" cellpadding="2">
<tr>
<td width="50%" valign="middle" style="padding-right:10px">
<center><strong style="font-size:38px">{$_L['Voucher_Hotspot']}</strong><span
class="no-print"> ID {$vs['id']}</span></center>
<table width="100%" border="1" cellspacing="0" cellpadding="1"
bordercolor="#757575">
<tbody>
<tr>
<td rowspan="5" width="1"><img src="qrcode/?data={$vs['code']}">
</td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:25px">
{Lang::moneyFormat($vs['price'])}</td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:20px">
{$_L['Code_Voucher']}</td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:25px">
{$vs['code']}</td>
</tr>
<tr>
<td valign="middle" align="center" style="font-size:15px">
{$vs['name_plan']}</td>
</tr>
</tbody>
</table>
</td>
<td valign="top" style="padding-left:10px">
{include file="$_path/../pages/Voucher.html"}
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</tbody>
</table>
<hr>
{if $jml == $pagebreak}
{$jml = 0}
<!-- pageBreak -->
<div class="page-break"><div class="no-print" style="background-color: #E91E63; color:#FFF;" align="center">-- pageBreak --<hr></div></div>
{$jml = 0}
<!-- pageBreak -->
<div class="page-break">
<div class="no-print" style="background-color: #E91E63; color:#FFF;" align="center">-- pageBreak --
<hr>
</div>
</div>
{/if}
{/foreach}
{/foreach}
</div>
</page>
<script src="ui/ui/scripts/jquery-1.10.2.js"></script>
{if isset($xfooter)}
{$xfooter}
{/if}
<script>
jQuery(document).ready(function() {
// initiate layout and plugins
$("#actprint").click(function() {
window.print();
return false;
</page>
<script src="ui/ui/scripts/jquery-1.10.2.js"></script>
{if isset($xfooter)}
{$xfooter}
{/if}
<script>
jQuery(document).ready(function() {
// initiate layout and plugins
$("#actprint").click(function() {
window.print();
return false;
});
});
});
</script>
</script>
</body>
</html>

View File

@ -1,53 +1,58 @@
{include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="panel panel-primary panel-hovered panel-stacked mb30">
<div class="panel-heading">{$_L['Recharge_Account']}</div>
<div class="panel-body">
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/recharge-post" >
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Select_Account']}</label>
<div class="col-md-6">
<select id="personSelect" class="form-control select2" name="id_customer" style="width: 100%" data-placeholder="{$_L['Select_Customer']}...">
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Type']}</label>
<div class="col-md-6">
<input type="radio" id="Hot" name="type" value="Hotspot"> {$_L['Hotspot_Plans']}
<input type="radio" id="POE" name="type" value="PPPOE"> {$_L['PPPOE_Plans']}
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Routers']}</label>
<div class="col-md-6">
<select id="server" name="server" class="form-control select2">
<option value=''>{$_L['Select_Routers']}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="panel panel-primary panel-hovered panel-stacked mb30">
<div class="panel-heading">{$_L['Recharge_Account']}</div>
<div class="panel-body">
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/recharge-post">
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Select_Account']}</label>
<div class="col-md-6">
<select {if $cust}{else}id="personSelect"{/if} class="form-control select2"
name="id_customer" style="width: 100%" data-placeholder="{$_L['Select_Customer']}...">
{if $cust}
<option value="{$cust['id']}">{$cust['username']} &bull; {$cust['fullname']} &bull; {$cust['email']}</option>
{/if}
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Type']}</label>
<div class="col-md-6">
<input type="radio" id="Hot" name="type" value="Hotspot"> {$_L['Hotspot_Plans']}
<input type="radio" id="POE" name="type" value="PPPOE"> {$_L['PPPOE_Plans']}
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Routers']}</label>
<div class="col-md-6">
<select id="server" name="server" class="form-control select2">
<option value=''>{$_L['Select_Routers']}</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Service_Plan']}</label>
<div class="col-md-6">
<select id="plan" name="plan" class="form-control select2">
<option value=''>{$_L['Select_Plans']}</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Service_Plan']}</label>
<div class="col-md-6">
<select id="plan" name="plan" class="form-control select2">
<option value=''>{$_L['Select_Plans']}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Recharge']}</button>
Or <a href="{$_url}customers/list">{$_L['Cancel']}</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-success waves-effect waves-light"
type="submit">{$_L['Recharge']}</button>
Or <a href="{$_url}customers/list">{$_L['Cancel']}</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file="sections/footer.tpl"}
{include file="sections/footer.tpl"}

View File

@ -103,6 +103,12 @@
<a href="{$_url}register" class="btn btn-success">{$_L['Cancel']}</a>
</div>
</div>
<br>
<center>
<a href="./pages/Privacy_Policy.html" target="_blank">Privacy</a>
&bull;
<a href="./pages/Terms_and_Conditions.html" target="_blank">T &amp; C</a>
</center>
</div>
</div>
</div>

View File

@ -78,6 +78,12 @@
type="submit">{Lang::T('Request OTP')}</button>
</div>
</div>
<br>
<center>
<a href="./pages/Privacy_Policy.html" target="_blank">Privacy</a>
&bull;
<a href="./pages/Terms_and_Conditions.html" target="_blank">T &amp; C</a>
</center>
</div>
</div>
</div>

View File

@ -86,14 +86,20 @@
</div>
<br>
<div class="btn-group btn-group-justified mb15">
<div class="btn-group">
<a href="{$_url}login" class="btn btn-warning">{$_L['Cancel']}</a>
</div>
<div class="btn-group">
<a href="{$_url}login" class="btn btn-warning">{$_L['Cancel']}</a>
</div>
<div class="btn-group">
<button class="btn btn-success waves-effect waves-light"
type="submit">{$_L['Register']}</button>
</div>
</div>
<br>
<center>
<a href="./pages/Privacy_Policy.html" target="_blank">Privacy</a>
&bull;
<a href="./pages/Terms_and_Conditions.html" target="_blank">T &amp; C</a>
</center>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Router Error - PHPNuxBill</title>
<title>Error - PHPNuxBill</title>
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
@ -32,27 +32,45 @@
<body class="hold-transition skin-blue">
<div class="container">
<section class="content-header">
<h1 class="text-center">
Router Error
</h1>
</section>
<section class="content">
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3">
<img src="./ui/ui/images/error.png" class="img-responsive hidden-sm hidden-xs">
</div>
<div class="col-md-6">
<div class="alert alert-danger text-center">
{$error_meesage}
<div class="box box-danger box-solid text-center">
<section class="content-header">
<h1 class="text-center">
{$error_title}
</h1>
</section>
<div class="box-title" style="font-size:xx-large; color:red">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
</div>
<div class="box-body" style="font-size: larger;">
<br><br>
{$error_message}
<br><br><br>
</div>
<div class="box-footer">
<div class="btn-group btn-group-justified" role="group" aria-label="...">
<a href="./update.php?step=4" class="btn btn-info btn-sm btn-block">Update Database</a>
<a href="{$_url}community#update" class="btn btn-primary btn-sm btn-block">Update
PHPNuxBill</a>
</div>
<br><br>
<a href="javascript::history.back()" onclick="history.back()"
class="btn btn-warning btn-block">back</a>
</div>
</div>
<a href="javascript::history.back()" onclick="history.back()" class="btn btn-warning btn-block">back</a>
</div>
<div class="col-md-4">
<img src="./ui/ui/images/error.png" class="img-responsive hidden-md hidden-lg">
</div>
</div>
</section>
<footer class="footer text-center">
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener"
target="_blank">iBNuX</a>
</footer>
</div>
</body>

View File

@ -42,7 +42,8 @@
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Router_Secret']}</label>
<div class="col-md-6">
<input type="text" class="form-control" id="password" name="password">
<input type="text" class="form-control" id="password" name="password"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'">
</div>
</div>
<div class="form-group">

View File

@ -14,7 +14,7 @@ $(document).ready(function () {
$('#TimeLimit').show();
$('#DataLimit').show();
}
if ($('#Unlimited').is(':checked')) {
$('#Type').hide();
$('#TimeLimit').hide();
@ -26,12 +26,12 @@ $(document).ready(function () {
if ($('#Hotspot').is(':checked')) {
$('#p').hide();
$('#h').show();
}
}
if ($('#PPPOE').is(':checked')) {
$('#p').show();
$('#h').hide();
}
});
});
$("#Hotspot").prop("checked", true).change();
@ -48,6 +48,7 @@ $(document).ready(function(){
cache: false,
success: function(msg){
$("#pool_name").html(msg);
$("#pool_expired").html(msg);
}
});
});
@ -62,10 +63,10 @@ $(function() {
dataType: "html",
url: "index.php?_route=autoload/server",
success: function(msg){
$("#server").html(msg);
$("#server").html(msg);
}
});
$("#server").change(getAjaxAlamat);
function getAjaxAlamat(){
var server = $("#server").val();

View File

@ -22,6 +22,17 @@
$(document).ready(function() {
$('.select2').select2({theme: "bootstrap"});
});
$(document).ready(function() {
$('.select2tag').select2({theme: "bootstrap", tags: true});
});
var listAtts = document.querySelectorAll(`[api-get-text]`);
listAtts.forEach(function(el) {
$.get(el.getAttribute('api-get-text'), function(data) {
el.innerHTML = data;
});
});
</script>
{/literal}

View File

@ -218,14 +218,19 @@
<li {if $_routes[1] eq 'Voucher'}class="active" {/if}><a
href="{$_url}pages/Voucher">{$_L['Voucher']} Template</a></li>
<li {if $_routes[1] eq 'Announcement'}class="active" {/if}><a
href="{$_url}pages/Announcement">{$_L['Announcement']} Editor</a></li>
href="{$_url}pages/Announcement">{$_L['Announcement']}</a></li>
<li {if $_routes[1] eq 'Registration_Info'}class="active" {/if}><a
href="{$_url}pages/Registration_Info">{$_L['Registration_Info']} Editor</a></li>
href="{$_url}pages/Registration_Info">{$_L['Registration_Info']}</a></li>
<li {if $_routes[1] eq 'Privacy_Policy'}class="active" {/if}><a
href="{$_url}pages/Privacy_Policy">Privacy Policy</a></li>
<li {if $_routes[1] eq 'Terms_and_Conditions'}class="active" {/if}><a
href="{$_url}pages/Terms_and_Conditions">Terms and Conditions</a></li>
{$_MENU_PAGES}
</ul>
</li>
{$_MENU_AFTER_PAGES}
<li class="{if $_system_menu eq 'settings' || $_system_menu eq 'paymentgateway' }active{/if} treeview">
<li
class="{if $_system_menu eq 'settings' || $_system_menu eq 'paymentgateway' }active{/if} treeview">
<a href="#">
<i class="ion ion-gear-a"></i> <span>{$_L['Settings']}</span>
<span class="pull-right-container">
@ -241,8 +246,8 @@
href="{$_url}settings/notifications">{Lang::T('User Notification')}</a></li>
<li {if $_routes[1] eq 'users'}class="active" {/if}><a
href="{$_url}settings/users">{$_L['Administrator_Users']}</a></li>
<li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li>
{* <li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li> *}
<li {if $_routes[0] eq 'pluginmanager'}class="active" {/if}>
<a href="{$_url}pluginmanager">{Lang::T('Plugin Manager')}</a>
</li>

View File

@ -1,45 +1,68 @@
</section>
</div>
{if isset($_c['CompanyFooter'])}
<footer class="main-footer">
{$_c['CompanyFooter']}
</footer>
{else}
<footer class="main-footer">
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener" target="_blank">iBNuX</a>, Theme by <a href="https://adminlte.io/" rel="nofollow noreferrer noopener" target="_blank">AdminLTE</a>
</footer>
{/if}
</div>
</div>
{if isset($_c['CompanyFooter'])}
<footer class="main-footer">
{$_c['CompanyFooter']}
<div class="pull-right">
<a href="./pages/Privacy_Policy.html" target="_blank">Privacy</a>
&bull;
<a href="./pages/Terms_of_Conditions.html" target="_blank">ToC</a>
</div>
</footer>
{else}
<footer class="main-footer">
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener"
target="_blank">iBNuX</a>, Theme by <a href="https://adminlte.io/" rel="nofollow noreferrer noopener"
target="_blank">AdminLTE</a>
<div class="pull-right">
<a href="./pages/Privacy_Policy.html" target="_blank">Privacy</a>
&bull;
<a href="./pages/Terms_of_Conditions.html" target="_blank">ToC</a>
</div>
</footer>
{/if}
</div>
<script src="ui/ui/scripts/jquery.min.js"></script>
<script src="ui/ui/scripts/bootstrap.min.js"></script>
<script src="ui/ui/scripts/adminlte.min.js"></script>
<script src="ui/ui/scripts/jquery.min.js"></script>
<script src="ui/ui/scripts/bootstrap.min.js"></script>
<script src="ui/ui/scripts/adminlte.min.js"></script>
<script src="ui/ui/scripts/plugins/select2.min.js"></script>
<script src="ui/ui/scripts/custom.js"></script>
<script src="ui/ui/scripts/plugins/select2.min.js"></script>
<script src="ui/ui/scripts/custom.js"></script>
{if isset($xfooter)}
{$xfooter}
{/if}
{if isset($xfooter)}
{$xfooter}
{/if}
{if $_c['tawkto'] != ''}
<!--Start of Tawk.to Script-->
<script type="text/javascript">
var Tawk_API = Tawk_API || {},
Tawk_LoadStart = new Date();
(function() {
var s1 = document.createElement("script"),
s0 = document.getElementsByTagName("script")[0];
s1.async = true;
s1.src='https://embed.tawk.to/{$_c['tawkto']}';
s1.charset = 'UTF-8';
s1.setAttribute('crossorigin', '*');
s0.parentNode.insertBefore(s1, s0);
})();
</script>
<!--End of Tawk.to Script-->
{/if}
{if $_c['tawkto'] != ''}
<!--Start of Tawk.to Script-->
<script type="text/javascript">
var Tawk_API = Tawk_API || {},
Tawk_LoadStart = new Date();
(function() {
var s1 = document.createElement("script"),
s0 = document.getElementsByTagName("script")[0];
s1.async = true;
s1.src='https://embed.tawk.to/{$_c['tawkto']}';
s1.charset = 'UTF-8';
s1.setAttribute('crossorigin', '*');
s0.parentNode.insertBefore(s1, s0);
})();
</script>
<!--End of Tawk.to Script-->
{/if}
</body>
{literal}
<script>
var listAtts = document.querySelectorAll(`[api-get-text]`);
listAtts.forEach(function(el) {
$.get(el.getAttribute('api-get-text'), function(data) {
el.innerHTML = data;
});
});
</script>
{/literal}
</body>
</html>

View File

@ -27,6 +27,16 @@
color: red;
background: yellow;
}
.content-wrapper {
margin-top: 50px;
}
@media (max-width: 767px) {
.content-wrapper {
margin-top: 100px;
}
}
</style>
{if isset($xheader)}
@ -37,8 +47,7 @@
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<header class="main-header">
<header class="main-header" style="position:fixed; width: 100%">
<a href="{$_url}home" class="logo">
<span class="logo-mini"><b>N</b>uX</span>
<span class="logo-lg">{$_c['CompanyName']}</span>
@ -48,20 +57,23 @@
<span class="sr-only">Toggle navigation</span>
</a>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{if $_c['enable_balance'] == 'yes'}
<span style="color: whitesmoke;">{Lang::moneyFormat($_user['balance'])}</span>
{else}
<span>{$_user['fullname']}</span>
{/if}
<img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1"
onerror="this.src='system/uploads/user.default.jpg'"
class="user-image" alt="User Image">
<span class="hidden-xs">{$_user['fullname']}</span>
onerror="this.src='system/uploads/user.default.jpg'" class="user-image"
alt="User Image">
</a>
<ul class="dropdown-menu">
<li class="user-header">
<img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1"
onerror="this.src='system/uploads/user.default.jpg'"
class="img-circle" alt="User Image">
onerror="this.src='system/uploads/user.default.jpg'" class="img-circle"
alt="User Image">
<p>
{$_user['fullname']}
@ -94,7 +106,7 @@
</nav>
</header>
<aside class="main-sidebar">
<aside class="main-sidebar" style="position:fixed;">
<section class="sidebar">
<ul class="sidebar-menu" data-widget="tree">
<li {if $_system_menu eq 'home'}class="active" {/if}>
@ -105,12 +117,12 @@
</li>
{$_MENU_AFTER_DASHBOARD}
{if $_c['disable_voucher'] != 'yes'}
<li {if $_system_menu eq 'voucher'}class="active" {/if}>
<a href="{$_url}voucher/activation">
<i class="fa fa-ticket"></i>
<span>{Lang::T('Voucher')}</span>
</a>
</li>
<li {if $_system_menu eq 'voucher'}class="active" {/if}>
<a href="{$_url}voucher/activation">
<i class="fa fa-ticket"></i>
<span>{Lang::T('Voucher')}</span>
</a>
</li>
{/if}
{if $_c['payment_gateway'] != 'none' or $_c['payment_gateway'] == '' }
<li {if $_system_menu eq 'package'}class="active" {/if}>

View File

@ -69,8 +69,9 @@
</tr>
<tr>
<td class="small text-success text-uppercase text-normal">{$_L['Password']}</td>
<td class="small mb15"><input type="text" value="{$_user['password']}"
style="background-color: black; color:black; width:100%; border: 0px;"
<td class="small mb15"><input type="password" value="{$_user['password']}"
style="width:100%; border: 0px;"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
onclick="this.select()"></td>
</tr>
{if $_c['enable_balance'] == 'yes'}
@ -104,19 +105,19 @@
{if $_bill['time'] ne ''}{Lang::dateAndTimeFormat($_bill['expiration'],$_bill['time'])}{/if}&nbsp;
</td>
</tr>
{if $nux_ip}
<tr>
<td class="small text-primary text-uppercase text-normal">{Lang::T('Current IP')}</td>
<td class="small mb15">{$nux_ip}</td>
</tr>
{/if}
{if $nux_mac}
<tr>
<td class="small text-primary text-uppercase text-normal">{Lang::T('Current MAC')}</td>
<td class="small mb15">{$nux_mac}</td>
</tr>
{/if}
{if $_bill['type'] == 'Hotspot' && $_bill['status'] == 'on'}
{if $nux_ip}
<tr>
<td class="small text-primary text-uppercase text-normal">{Lang::T('Current IP')}</td>
<td class="small mb15">{$nux_ip}</td>
</tr>
{/if}
{if $nux_mac}
<tr>
<td class="small text-primary text-uppercase text-normal">{Lang::T('Current MAC')}</td>
<td class="small mb15">{$nux_mac}</td>
</tr>
{/if}
<tr>
<td class="small text-primary text-uppercase text-normal">{Lang::T('Login Status')}</td>
<td class="small mb15" id="login_status">
@ -167,7 +168,8 @@
</div>
<div class="form-group col-sm-2" align="center">
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send"
value="balance"><i class="glyphicon glyphicon-send"></i></button>
onclick="return confirm('{Lang::T("Are You Sure?")}')" value="balance"><i
class="glyphicon glyphicon-send"></i></button>
</div>
</div>
</form>
@ -183,6 +185,24 @@
}
</script>
</div>
<div class="box-header">
<h4 class="box-title">{Lang::T("Recharge a friend")}</h4>
</div>
<div class="box-body p-0">
<form method="post" role="form" action="{$_url}home">
<div class="form-group">
<div class="col-sm-10">
<input type="text" id="username" name="username" class="form-control" required
placeholder="{$_L['Username']}">
</div>
<div class="form-group col-sm-2" align="center">
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send"
onclick="return confirm('{Lang::T("Are You Sure?")}')" value="plan"><i
class="glyphicon glyphicon-send"></i></button>
</div>
</div>
</form>
</div>
</div>
{/if}
<br>

View File

@ -47,7 +47,8 @@
{if $_c['country_code_phone']!= ''}
<span class="input-group-addon" id="basic-addon1">+</span>
{else}
<span class="input-group-addon" id="basic-addon1"><i class="glyphicon glyphicon-phone-alt"></i></span>
<span class="input-group-addon" id="basic-addon1"><i
class="glyphicon glyphicon-phone-alt"></i></span>
{/if}
<input type="text" class="form-control" name="username"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
@ -76,6 +77,12 @@
<button type="submit" class="btn btn-primary">{$_L['Login']}</button>
</div>
</div>
<br>
<center>
<a href="./pages/Privacy_Policy.html" target="_blank">Privacy</a>
&bull;
<a href="./pages/Terms_and_Conditions.html" target="_blank">T &amp; C</a>
</center>
</form>
</div>
</div>

View File

@ -33,10 +33,6 @@
{/foreach}
</div>
</div>
<div class="box box-solid box-success">
<div class="box-header text-center text-bold">{Lang::T('Balance')} {Lang::moneyFormat($_user['balance'])}</div>
</div>
{/if}
{foreach $routers as $router}
<div class="box box-solid box-info">
@ -47,7 +43,7 @@
</div>
{/if}
{if count($plans_hotspot)>0}
<div class="box-header">Hotspot</div>
<div class="box-header">{Lang::T('Hotspot Plan')}</div>
<div class="box-body row">
{foreach $plans_hotspot as $plan}
{if $router['name'] eq $plan['routers']}
@ -83,6 +79,11 @@
class="btn btn-sm btn-block btn-success">{Lang::T('Pay With Balance')}</a>
{/if}
</div>
{if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && $_user['balance']>=$plan['price']}
<a href="{$_url}order/send/{$router['id']}/{$plan['id']}"
onclick="return confirm('{Lang::T('Buy this for friend account?')}')"
class="btn btn-sm btn-block btn-primary">{Lang::T('Buy for friend')}</a>
{/if}
</div>
</div>
</div>
@ -91,7 +92,7 @@
</div>
{/if}
{if count($plans_pppoe)>0}
<div class="box-header text-sm">PPPOE</div>
<div class="box-header text-sm">{Lang::T('PPPOE Plan')}</div>
<div class="box-body row">
{foreach $plans_pppoe as $plan}
{if $router['name'] eq $plan['routers']}
@ -127,6 +128,11 @@
class="btn btn-sm btn-block btn-success">{Lang::T('Pay With Balance')}</a>
{/if}
</div>
{if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && $_user['balance']>=$plan['price']}
<a href="{$_url}order/send/{$router['id']}/{$plan['id']}"
onclick="return confirm('{Lang::T('Buy this for friend account?')}')"
class="btn btn-sm btn-block btn-primary">{Lang::T('Buy for friend')}</a>
{/if}
</div>
</div>
</div>

43
ui/ui/user-sendPlan.tpl Normal file
View File

@ -0,0 +1,43 @@
{include file="sections/user-header.tpl"}
<!-- user-orderView -->
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="box box-solid box-default">
<div class="box-header">{$plan['name_plan']}</div>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<td>{Lang::T('Type')}</td>
<td>{$plan['type']}</td>
</tr>
<tr>
<td>{Lang::T('Price')}</td>
<td>{Lang::moneyFormat($plan['price'])}</td>
</tr>
<tr>
<td>{Lang::T('Validity')}</td>
<td>{$plan['validity']} {$plan['validity_unit']}</td>
</tr>
</tbody>
</table>
</div>
<div class="box-footer">
<form method="post" onsubmit="return askConfirm()" role="form">
<div class="form-group">
<div class="col-sm-9">
<input type="text" id="username" name="username" class="form-control" required value="{$username}"
placeholder="{$_L['Username']}">
</div>
<div class="form-group col-sm-3" align="center">
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send" onclick="return confirm('{Lang::T("Are You Sure?")}')"
value="plan"><i class="glyphicon glyphicon-send"></i></button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file="sections/user-footer.tpl"}

View File

@ -49,16 +49,19 @@
</thead>
<tbody>
{foreach $d as $ds}
<tr>
<tr {if $ds['status'] eq '1'}class="danger"{/if}>
<td>{$ds['id']}</td>
<td>{$ds['type']}</td>
<td>{$ds['routers']}</td>
<td>{$ds['name_plan']}</td>
<td><span style="background-color: black; color:black;">{$ds['code']}</span></td>
<td align="center">{if $ds['status'] eq '0'} <label class="btn-tag btn-tag-success">Not
<td width="10px"><input type="password" value="{$ds['code']}"
style="width:120px;border: 0px; text-align: right;" class="pull-right"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
onclick="this.select()"></td>
<td align="center">{if $ds['status'] eq '0'} <label class="btn-tag btn-tag-success">Not
Use</label> {else} <label class="btn-tag btn-tag-danger">Used</label>
{/if}</td>
<td align="center">{if $ds['user'] eq '0'} - {else} {$ds['user']} {/if}</td>
<td align="center">{if $ds['user'] eq '0'} - {else}<a href="{$_url}customers/viewu/{$ds['user']}">{$ds['user']}</a>{/if}</td>
<td>
<a href="{$_url}prepaid/voucher-delete/{$ds['id']}" id="{$ds['id']}"
class="btn btn-danger btn-xs"

View File

@ -1,3 +1,3 @@
{
"version": "2023.9.1.1"
"version": "2023.9.20"
}