mirror of
https://github.com/hotspotbilling/phpnuxbill.git
synced 2025-08-29 22:29:36 +02:00
Compare commits
221 commits
Author | SHA1 | Date | |
---|---|---|---|
|
4a441c5763 | ||
|
d506dd66ff | ||
|
e9b0cfd8f0 | ||
|
aa4dbc0cea | ||
|
4ef054466d | ||
|
41a3cbe700 | ||
|
4938840c5d | ||
|
127d43e45d | ||
|
cdfbab7119 | ||
|
1a2b85ae4f | ||
|
2e2d967a5b | ||
|
c45e19189a | ||
|
d372bf4711 | ||
|
8b8a0357f0 | ||
|
1cb0e30e6b | ||
|
20916b44f0 | ||
|
c63545d33a | ||
|
84500cdfc9 | ||
|
5b21ffcde5 | ||
|
009040cd3c | ||
|
781481e118 | ||
|
66d67cb61d | ||
|
3372da2ac4 | ||
|
803d04a91d | ||
|
17de653752 | ||
|
9301f1058c | ||
|
0868d61271 | ||
|
5f353392e3 | ||
|
fdd8dad509 | ||
|
3563fa531b | ||
|
525f2311fc | ||
|
3b6a6d2f55 | ||
|
3cebfa2171 | ||
|
c65b569f94 | ||
|
ca5a7d60cf | ||
|
5987ffafce | ||
|
d7bbb4d18f | ||
|
e3c173bea4 | ||
|
78e1e2f989 | ||
|
3c7e6c7a64 | ||
|
827bb8706d | ||
|
4731a506bc | ||
|
597c051948 | ||
|
40d3127ca1 | ||
|
c75133c9d2 | ||
|
ed3369244c | ||
|
cf9abbfb45 | ||
|
c74d2bf7ec | ||
|
ec9a06f468 | ||
|
4e3d89a23c | ||
|
30ca1d1b2d | ||
|
1cbff8f9a4 | ||
|
43b1025d3c | ||
|
da14a7bfef | ||
|
8429ed763e | ||
|
3b7d478635 | ||
|
ee3dcc05a0 | ||
|
1e7d9cf6ef | ||
|
986016083b | ||
|
c95de08ed8 | ||
|
d657632876 | ||
|
d8dbe68f51 | ||
|
366ef73d57 | ||
|
dfdf35286f | ||
|
eea99d218d | ||
|
08d1de563e | ||
|
51a0b859ab | ||
|
47a57912ba | ||
|
7bbaee1b88 | ||
|
791e6d55d0 | ||
|
4564ef90d5 | ||
|
23524e4c1f | ||
|
c486acaaf6 | ||
|
e3476a971c | ||
|
b9ccc7561c | ||
|
5a1bb441af | ||
|
19a48c0c88 | ||
|
8d2c334da0 | ||
|
9163f02717 | ||
|
da86f2c422 | ||
|
f929560384 | ||
|
1387f32865 | ||
|
a39ff8a9a4 | ||
|
eb96c7a1e4 | ||
|
83a2505eed | ||
|
e91fbe89ba | ||
|
925097c0b2 | ||
|
6cd46cdf7c | ||
|
9b331813d1 | ||
|
1e500d8941 | ||
|
c433363d31 | ||
|
3901213a73 | ||
|
8860ad1d13 | ||
|
5df32c7119 | ||
|
08be62053e | ||
|
71bf301ccf | ||
|
0e32f128af | ||
|
686f3de2d3 | ||
|
b379266973 | ||
|
9332063c87 | ||
|
db4c643f93 | ||
|
1a2f2e24cd | ||
|
92ce363b16 | ||
|
5ddbf8258c | ||
|
4105ad0b8b | ||
|
af22a26c4c | ||
|
a2ade795c7 | ||
|
7b36a46c50 | ||
|
fa9fe241e2 | ||
|
1aa4110552 | ||
|
8917b2ab7b | ||
|
8238061510 | ||
|
096b4fb3af | ||
|
5d3eea1f45 | ||
|
ee6098774a | ||
|
d272e572c0 | ||
|
2be111e9df | ||
|
6cf7d6b5de | ||
|
e9a947a24a | ||
|
20c0543143 | ||
|
cd1034c3ab | ||
|
f9a938830d | ||
|
5b79432f9a | ||
|
023b4884d1 | ||
|
fca86ac4dc | ||
|
ef51d833d8 | ||
|
c05a943ff5 | ||
|
693d7f4acf | ||
|
5b9cdd6681 | ||
|
a013373554 | ||
|
aeae936f17 | ||
|
ea203ebf64 | ||
|
da0779e368 | ||
|
4bb5361d4b | ||
|
69a7d842e0 | ||
|
fefcd56801 | ||
|
5f0df84fe7 | ||
|
80d213bea3 | ||
|
0b52d3eb35 | ||
|
569d5e3670 | ||
|
7396bcdddf | ||
|
eee1ad72f8 | ||
|
2b80f5e6f1 | ||
|
f98aecc61f | ||
|
4cc85b9261 | ||
|
eff0c7dab7 | ||
|
30bdb89d91 | ||
|
8fc7afb173 | ||
|
fa5be4c196 | ||
|
304de7a999 | ||
|
1ad1320779 | ||
|
a3f66fdd84 | ||
|
86b18e27cd | ||
|
535a44bb54 | ||
|
929f75dc4d | ||
|
8e7a1dc0f2 | ||
|
6865d321c3 | ||
|
75d6f17eb5 | ||
|
4bc47a8d85 | ||
|
0a3205915f | ||
|
60d945d87f | ||
|
685b325ef3 | ||
|
e0884c0a5a | ||
|
b6fadae2e5 | ||
|
91271b9f00 | ||
|
a2237390e0 | ||
|
b3169a2060 | ||
|
b3f4edb2d7 | ||
|
f301382a72 | ||
|
92f2caeece | ||
|
9fd8feb16f | ||
|
ee022781b1 | ||
|
85c5441934 | ||
|
9cc7c0c811 | ||
|
7f785a7c4a | ||
|
05aa1499ab | ||
|
2469aa6b99 | ||
|
4d71c1d48e | ||
|
bdef2b62c3 | ||
|
1cae09763f | ||
|
4ba7c14693 | ||
|
aa9a2e4277 | ||
|
bd87f0143b | ||
|
8c94e9ea01 | ||
|
d09e657ed5 | ||
|
fbe541ef9c | ||
|
5feeb2625e | ||
|
0d116fcb5b | ||
|
8d704f496e | ||
|
94569bca0e | ||
|
129302d558 | ||
|
56762ef277 | ||
|
75880e8366 | ||
|
cbacb1c52f | ||
|
01d966082c | ||
|
e4124bd210 | ||
|
0d4fde6481 | ||
|
6790fdd6d4 | ||
|
40d8a4edfc | ||
|
09eedf4999 | ||
|
9adf1412bc | ||
|
d3e813e7df | ||
|
6ccabf8b45 | ||
|
af064ac5bb | ||
|
0ec7176d1e | ||
|
c594cf28bb | ||
|
2a038d63bb | ||
|
7170b63890 | ||
|
d44c58f610 | ||
|
10adbe48ab | ||
|
b3cb6de028 | ||
|
96dca1a38b | ||
|
face7360e8 | ||
|
f520352bc9 | ||
|
a81bb5c4f5 | ||
|
8d9919afa7 | ||
|
3386b17b1b | ||
|
60c7f61579 | ||
|
fa05ffa58b | ||
|
fa3e256174 | ||
|
0346a843ea |
273 changed files with 11331 additions and 24671 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -54,3 +54,7 @@ docs/**
|
||||||
!docs/*.html
|
!docs/*.html
|
||||||
!docs/*.md
|
!docs/*.md
|
||||||
.htaccess
|
.htaccess
|
||||||
|
.idea
|
||||||
|
!docs/insomnia.rest.json
|
||||||
|
!system/uploads/paid.png
|
||||||
|
system/uploads/invoices/**
|
||||||
|
|
File diff suppressed because one or more lines are too long
1
docs/insomnia.rest.json
Normal file
1
docs/insomnia.rest.json
Normal file
File diff suppressed because one or more lines are too long
25
init.php
25
init.php
|
@ -42,7 +42,7 @@ spl_autoload_register('_autoloader');
|
||||||
if (!file_exists($root_path . 'config.php')) {
|
if (!file_exists($root_path . 'config.php')) {
|
||||||
$root_path .= '..' . DIRECTORY_SEPARATOR;
|
$root_path .= '..' . DIRECTORY_SEPARATOR;
|
||||||
if (!file_exists($root_path . 'config.php')) {
|
if (!file_exists($root_path . 'config.php')) {
|
||||||
r2(getUrl('install'));
|
r2('./install');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ $UPLOAD_PATH = $root_path . File::pathFixer('system/uploads');
|
||||||
$CACHE_PATH = $root_path . File::pathFixer('system/cache');
|
$CACHE_PATH = $root_path . File::pathFixer('system/cache');
|
||||||
$PAGES_PATH = $root_path . File::pathFixer('pages');
|
$PAGES_PATH = $root_path . File::pathFixer('pages');
|
||||||
$PLUGIN_PATH = $root_path . File::pathFixer('system/plugin');
|
$PLUGIN_PATH = $root_path . File::pathFixer('system/plugin');
|
||||||
|
$WIDGET_PATH = $root_path . File::pathFixer('system/widgets');
|
||||||
$PAYMENTGATEWAY_PATH = $root_path . File::pathFixer('system/paymentgateway');
|
$PAYMENTGATEWAY_PATH = $root_path . File::pathFixer('system/paymentgateway');
|
||||||
$UI_PATH = 'ui';
|
$UI_PATH = 'ui';
|
||||||
|
|
||||||
|
@ -111,6 +112,24 @@ $result = ORM::for_table('tbl_appconfig')->find_many();
|
||||||
foreach ($result as $value) {
|
foreach ($result as $value) {
|
||||||
$config[$value['setting']] = $value['value'];
|
$config[$value['setting']] = $value['value'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(empty($config['dashboard_Admin'])){
|
||||||
|
$config['dashboard_Admin'] = "12.7,5.12";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($config['dashboard_Agent'])){
|
||||||
|
$config['dashboard_Agent'] = "12.7,5.12";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($config['dashboard_Sales'])){
|
||||||
|
$config['dashboard_Sales'] = "12.7,5.12";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($config['dashboard_Customer'])){
|
||||||
|
$config['dashboard_Customer'] = "6,6";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$_c = $config;
|
$_c = $config;
|
||||||
if (empty($http_proxy) && !empty($config['http_proxy'])) {
|
if (empty($http_proxy) && !empty($config['http_proxy'])) {
|
||||||
$http_proxy = $config['http_proxy'];
|
$http_proxy = $config['http_proxy'];
|
||||||
|
@ -349,7 +368,7 @@ function _alert($text, $type = 'success', $url = "home", $time = 3)
|
||||||
$ui->assign('type', $type);
|
$ui->assign('type', $type);
|
||||||
$ui->assign('time', $time);
|
$ui->assign('time', $time);
|
||||||
$ui->assign('url', $url);
|
$ui->assign('url', $url);
|
||||||
$ui->display('alert.tpl');
|
$ui->display('admin/alert.tpl');
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +386,7 @@ function displayMaintenanceMessage(): void
|
||||||
}
|
}
|
||||||
http_response_code(503);
|
http_response_code(503);
|
||||||
$ui->assign('companyName', $config['CompanyName']);
|
$ui->assign('companyName', $config['CompanyName']);
|
||||||
$ui->display('maintenance.tpl');
|
$ui->display('admin/maintenance.tpl');
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
install/css/bootstrap.css
vendored
20
install/css/bootstrap.css
vendored
|
@ -1374,7 +1374,7 @@ pre {
|
||||||
color: #333;
|
color: #333;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
@ -2126,7 +2126,7 @@ th {
|
||||||
}
|
}
|
||||||
.table-hover > tbody > tr:hover > td,
|
.table-hover > tbody > tr:hover > td,
|
||||||
.table-hover > tbody > tr:hover > th {
|
.table-hover > tbody > tr:hover > th {
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
}
|
}
|
||||||
table col[class*="col-"] {
|
table col[class*="col-"] {
|
||||||
position: static;
|
position: static;
|
||||||
|
@ -2151,7 +2151,7 @@ table th[class*="col-"] {
|
||||||
.table > thead > tr.active > th,
|
.table > thead > tr.active > th,
|
||||||
.table > tbody > tr.active > th,
|
.table > tbody > tr.active > th,
|
||||||
.table > tfoot > tr.active > th {
|
.table > tfoot > tr.active > th {
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
}
|
}
|
||||||
.table-hover > tbody > tr > td.active:hover,
|
.table-hover > tbody > tr > td.active:hover,
|
||||||
.table-hover > tbody > tr > th.active:hover,
|
.table-hover > tbody > tr > th.active:hover,
|
||||||
|
@ -3170,7 +3170,7 @@ tbody.collapse.in {
|
||||||
.dropdown-menu > li > a:focus {
|
.dropdown-menu > li > a:focus {
|
||||||
color: #262626;
|
color: #262626;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
}
|
}
|
||||||
.dropdown-menu > .active > a,
|
.dropdown-menu > .active > a,
|
||||||
.dropdown-menu > .active > a:hover,
|
.dropdown-menu > .active > a:hover,
|
||||||
|
@ -4293,7 +4293,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
|
||||||
padding: 8px 15px;
|
padding: 8px 15px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
.breadcrumb > li {
|
.breadcrumb > li {
|
||||||
|
@ -4711,7 +4711,7 @@ a.thumbnail.active {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
|
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
|
||||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
|
||||||
|
@ -4854,7 +4854,7 @@ a.list-group-item:hover,
|
||||||
a.list-group-item:focus {
|
a.list-group-item:focus {
|
||||||
color: #555;
|
color: #555;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
}
|
}
|
||||||
.list-group-item.disabled,
|
.list-group-item.disabled,
|
||||||
.list-group-item.disabled:hover,
|
.list-group-item.disabled:hover,
|
||||||
|
@ -5023,7 +5023,7 @@ a.list-group-item-danger.active:focus {
|
||||||
}
|
}
|
||||||
.panel-footer {
|
.panel-footer {
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
border-top: 1px solid #ddd;
|
border-top: 1px solid #ddd;
|
||||||
border-bottom-right-radius: 3px;
|
border-bottom-right-radius: 3px;
|
||||||
border-bottom-left-radius: 3px;
|
border-bottom-left-radius: 3px;
|
||||||
|
@ -5197,7 +5197,7 @@ a.list-group-item-danger.active:focus {
|
||||||
}
|
}
|
||||||
.panel-default > .panel-heading {
|
.panel-default > .panel-heading {
|
||||||
color: #333;
|
color: #333;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
border-color: #ddd;
|
border-color: #ddd;
|
||||||
}
|
}
|
||||||
.panel-default > .panel-heading + .panel-collapse > .panel-body {
|
.panel-default > .panel-heading + .panel-collapse > .panel-body {
|
||||||
|
@ -5329,7 +5329,7 @@ a.list-group-item-danger.active:focus {
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
padding: 19px;
|
padding: 19px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
background-color: #f5f5f5;
|
background-color: #f6f8fa;
|
||||||
border: 1px solid #e3e3e3;
|
border: 1px solid #e3e3e3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||||
|
|
|
@ -251,6 +251,16 @@ CREATE TABLE `tbl_customers_inbox` (
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `tbl_port_pool`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `tbl_port_pool` (
|
||||||
|
`id` int(10) NOT NULL AUTO_INCREMENT,
|
||||||
|
`public_ip` varchar(40) NOT NULL,
|
||||||
|
`port_name` varchar(40) NOT NULL,
|
||||||
|
`range_port` varchar(40) NOT NULL,
|
||||||
|
`routers` varchar(40) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `tbl_meta` (
|
CREATE TABLE IF NOT EXISTS `tbl_meta` (
|
||||||
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`tbl` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Table name',
|
`tbl` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Table name',
|
||||||
|
@ -277,6 +287,28 @@ CREATE TABLE IF NOT EXISTS `tbl_coupons` (
|
||||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `tbl_widgets` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`orders` int NOT NULL DEFAULT '99',
|
||||||
|
`position` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1. top 2. left 3. right 4. bottom',
|
||||||
|
`user` ENUM('Admin','Agent','Sales','Customer') NOT NULL DEFAULT 'Admin',
|
||||||
|
`enabled` tinyint(1) NOT NULL DEFAULT '1',
|
||||||
|
`title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`widget` varchar(64) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||||
|
`content` text COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
|
CREATE TABLE tbl_message_logs (
|
||||||
|
`id` SERIAL PRIMARY KEY,
|
||||||
|
`message_type` VARCHAR(50),
|
||||||
|
`recipient` VARCHAR(255),
|
||||||
|
`message_content` TEXT,
|
||||||
|
`status` VARCHAR(50),
|
||||||
|
`error_message` TEXT,
|
||||||
|
`sent_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
ALTER TABLE `rad_acct`
|
ALTER TABLE `rad_acct`
|
||||||
ADD PRIMARY KEY (`id`),
|
ADD PRIMARY KEY (`id`),
|
||||||
ADD KEY `username` (`username`),
|
ADD KEY `username` (`username`),
|
||||||
|
@ -397,3 +429,48 @@ VALUES (
|
||||||
'2022-09-06 16:09:50',
|
'2022-09-06 16:09:50',
|
||||||
'2014-06-23 01:43:07'
|
'2014-06-23 01:43:07'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
INSERT INTO `tbl_widgets` (`id`, `orders`, `position`, `user`, `enabled`, `title`, `widget`, `content`) VALUES
|
||||||
|
(1, 1, 1, 'Admin', 1, 'Top Widget', 'top_widget', ''),
|
||||||
|
(2, 2, 1, 'Admin', 1, 'Default Info', 'default_info_row', ''),
|
||||||
|
(3, 1, 2, 'Admin', 1, 'Graph Monthly Registered Customers', 'graph_monthly_registered_customers', ''),
|
||||||
|
(4, 2, 2, 'Admin', 1, 'Graph Monthly Sales', 'graph_monthly_sales', ''),
|
||||||
|
(5, 3, 2, 'Admin', 1, 'Voucher Stocks', 'voucher_stocks', ''),
|
||||||
|
(6, 4, 2, 'Admin', 1, 'Customer Expired', 'customer_expired', ''),
|
||||||
|
(7, 1, 3, 'Admin', 1, 'Cron Monitor', 'cron_monitor', ''),
|
||||||
|
(8, 2, 3, 'Admin', 1, 'Mikrotik Cron Monitor', 'mikrotik_cron_monitor', ''),
|
||||||
|
(9, 3, 3, 'Admin', 1, 'Info Payment Gateway', 'info_payment_gateway', ''),
|
||||||
|
(10, 4, 3, 'Admin', 1, 'Graph Customers Insight', 'graph_customers_insight', ''),
|
||||||
|
(11, 5, 3, 'Admin', 1, 'Activity Log', 'activity_log', ''),
|
||||||
|
|
||||||
|
(30, 1, 1, 'Agent', 1, 'Top Widget', 'top_widget', ''),
|
||||||
|
(31, 2, 1, 'Agent', 1, 'Default Info', 'default_info_row', ''),
|
||||||
|
(32, 1, 2, 'Agent', 1, 'Graph Monthly Registered Customers', 'graph_monthly_registered_customers', ''),
|
||||||
|
(33, 2, 2, 'Agent', 1, 'Graph Monthly Sales', 'graph_monthly_sales', ''),
|
||||||
|
(34, 3, 2, 'Agent', 1, 'Voucher Stocks', 'voucher_stocks', ''),
|
||||||
|
(35, 4, 2, 'Agent', 1, 'Customer Expired', 'customer_expired', ''),
|
||||||
|
(36, 1, 3, 'Agent', 1, 'Cron Monitor', 'cron_monitor', ''),
|
||||||
|
(37, 2, 3, 'Agent', 1, 'Mikrotik Cron Monitor', 'mikrotik_cron_monitor', ''),
|
||||||
|
(38, 3, 3, 'Agent', 1, 'Info Payment Gateway', 'info_payment_gateway', ''),
|
||||||
|
(39, 4, 3, 'Agent', 1, 'Graph Customers Insight', 'graph_customers_insight', ''),
|
||||||
|
(40, 5, 3, 'Agent', 1, 'Activity Log', 'activity_log', ''),
|
||||||
|
|
||||||
|
(41, 1, 1, 'Sales', 1, 'Top Widget', 'top_widget', ''),
|
||||||
|
(42, 2, 1, 'Sales', 1, 'Default Info', 'default_info_row', ''),
|
||||||
|
(43, 1, 2, 'Sales', 1, 'Graph Monthly Registered Customers', 'graph_monthly_registered_customers', ''),
|
||||||
|
(44, 2, 2, 'Sales', 1, 'Graph Monthly Sales', 'graph_monthly_sales', ''),
|
||||||
|
(45, 3, 2, 'Sales', 1, 'Voucher Stocks', 'voucher_stocks', ''),
|
||||||
|
(46, 4, 2, 'Sales', 1, 'Customer Expired', 'customer_expired', ''),
|
||||||
|
(47, 1, 3, 'Sales', 1, 'Cron Monitor', 'cron_monitor', ''),
|
||||||
|
(48, 2, 3, 'Sales', 1, 'Mikrotik Cron Monitor', 'mikrotik_cron_monitor', ''),
|
||||||
|
(49, 3, 3, 'Sales', 1, 'Info Payment Gateway', 'info_payment_gateway', ''),
|
||||||
|
(50, 4, 3, 'Sales', 1, 'Graph Customers Insight', 'graph_customers_insight', ''),
|
||||||
|
(51, 5, 3, 'Sales', 1, 'Activity Log', 'activity_log', ''),
|
||||||
|
|
||||||
|
(60, 1, 2, 'Customer', 1, 'Account Info', 'account_info', ''),
|
||||||
|
(61, 3, 1, 'Customer', 1, 'Active Internet Plan', 'active_internet_plan', ''),
|
||||||
|
(62, 4, 1, 'Customer', 1, 'Balance Transfer', 'balance_transfer', ''),
|
||||||
|
(63, 1, 1, 'Customer', 1, 'Unpaid Order', 'unpaid_order', ''),
|
||||||
|
(64, 2, 1, 'Customer', 1, 'Announcement', 'announcement', ''),
|
||||||
|
(65, 5, 1, 'Customer', 1, 'Recharge A Friend', 'recharge_a_friend', ''),
|
||||||
|
(66, 2, 2, 'Customer', 1, 'Voucher Activation', 'voucher_activation', '');
|
|
@ -304,6 +304,14 @@ try {
|
||||||
$d->dateAdded = date('Y-m-d H:i:s');
|
$d->dateAdded = date('Y-m-d H:i:s');
|
||||||
// pastikan data akunting yang disimpan memang customer aktif phpnuxbill
|
// pastikan data akunting yang disimpan memang customer aktif phpnuxbill
|
||||||
$tur = ORM::for_table('tbl_user_recharges')->whereRaw("BINARY username = '$username' AND `status` = 'on' AND `routers` = 'radius'")->find_one();
|
$tur = ORM::for_table('tbl_user_recharges')->whereRaw("BINARY username = '$username' AND `status` = 'on' AND `routers` = 'radius'")->find_one();
|
||||||
|
if (!$tur) {
|
||||||
|
// check if pppoe_username
|
||||||
|
$c = ORM::for_table('tbl_customers')->select('username')->whereRaw("BINARY pppoe_username = '$username'")->find_one();
|
||||||
|
if ($c) {
|
||||||
|
$username = $c['username'];
|
||||||
|
$tur = ORM::for_table('tbl_user_recharges')->whereRaw("BINARY username = '$username'")->find_one();
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($tur) {
|
if ($tur) {
|
||||||
$d->save();
|
$d->save();
|
||||||
if (_post('acctStatusType') == 'Start') {
|
if (_post('acctStatusType') == 'Start') {
|
||||||
|
|
|
@ -6,23 +6,64 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>QR Code Scanner</title>
|
<title>QR Code Scanner</title>
|
||||||
<style>
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#container {
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#qr-reader {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
#qr-reader-results {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
button {
|
button {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="qr-reader" style="width:100%; height:auto"></div>
|
<div id="container">
|
||||||
|
<h2>QR Code Scanner</h2>
|
||||||
|
<div id="qr-reader"></div>
|
||||||
<div id="qr-reader-results"></div>
|
<div id="qr-reader-results"></div>
|
||||||
|
<button id="camera-button">Open Camera</button>
|
||||||
|
</div>
|
||||||
<script src="qrcode.min.js"></script>
|
<script src="qrcode.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function docReady(fn) {
|
function docReady(fn) {
|
||||||
// see if DOM is already available
|
// lihat apakah DOM sudah tersedia
|
||||||
if (document.readyState === "complete" ||
|
if (document.readyState === "complete" ||
|
||||||
document.readyState === "interactive") {
|
document.readyState === "interactive") {
|
||||||
// call on next available tick
|
// panggil di detik berikutnya yang tersedia
|
||||||
setTimeout(fn, 1);
|
setTimeout(fn, 1);
|
||||||
} else {
|
} else {
|
||||||
document.addEventListener("DOMContentLoaded", fn);
|
document.addEventListener("DOMContentLoaded", fn);
|
||||||
|
@ -51,6 +92,9 @@
|
||||||
docReady(function() {
|
docReady(function() {
|
||||||
var resultContainer = document.getElementById('qr-reader-results');
|
var resultContainer = document.getElementById('qr-reader-results');
|
||||||
var lastResult, countResults = 0;
|
var lastResult, countResults = 0;
|
||||||
|
var html5QrcodeScanner;
|
||||||
|
var isCameraOpen = false;
|
||||||
|
|
||||||
function onScanSuccess(decodedText, decodedResult) {
|
function onScanSuccess(decodedText, decodedResult) {
|
||||||
if (decodedText !== lastResult) {
|
if (decodedText !== lastResult) {
|
||||||
++countResults;
|
++countResults;
|
||||||
|
@ -67,12 +111,24 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var html5QrcodeScanner = new Html5QrcodeScanner(
|
function toggleCamera() {
|
||||||
|
if (isCameraOpen) {
|
||||||
|
html5QrcodeScanner.clear();
|
||||||
|
document.getElementById('camera-button').textContent = "Open Camera";
|
||||||
|
isCameraOpen = false;
|
||||||
|
} else {
|
||||||
|
html5QrcodeScanner = new Html5QrcodeScanner(
|
||||||
"qr-reader", {
|
"qr-reader", {
|
||||||
fps: 10,
|
fps: 10,
|
||||||
qrbox: 250
|
qrbox: 250
|
||||||
});
|
});
|
||||||
html5QrcodeScanner.render(onScanSuccess);
|
html5QrcodeScanner.render(onScanSuccess);
|
||||||
|
document.getElementById('camera-button').textContent = "Close Camera";
|
||||||
|
isCameraOpen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('camera-button').addEventListener('click', toggleCamera);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -48,7 +48,28 @@ $ui = new class($key)
|
||||||
}
|
}
|
||||||
function getAll()
|
function getAll()
|
||||||
{
|
{
|
||||||
return $this->assign;
|
|
||||||
|
$result = [];
|
||||||
|
foreach ($this->assign as $key => $value) {
|
||||||
|
if($value instanceof ORM){
|
||||||
|
$result[$key] = $value->as_array();
|
||||||
|
}else if($value instanceof IdiormResultSet){
|
||||||
|
$count = count($value);
|
||||||
|
for($n=0;$n<$count;$n++){
|
||||||
|
foreach ($value[$n] as $k=>$v) {
|
||||||
|
$result[$key][$n][$k] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$result[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetch()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ class Csrf
|
||||||
|
|
||||||
public static function check($token)
|
public static function check($token)
|
||||||
{
|
{
|
||||||
global $config;
|
global $config, $isApi;
|
||||||
if($config['csrf_enabled'] == 'yes') {
|
if($config['csrf_enabled'] == 'yes' && !$isApi) {
|
||||||
if (isset($_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $token)) {
|
if (isset($_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $token)) {
|
||||||
$storedToken = $_SESSION['csrf_token'];
|
$storedToken = $_SESSION['csrf_token'];
|
||||||
$tokenTime = $_SESSION['csrf_token_time'];
|
$tokenTime = $_SESSION['csrf_token_time'];
|
||||||
|
|
|
@ -87,7 +87,7 @@ class File
|
||||||
$src_img = $image_create($source_file);
|
$src_img = $image_create($source_file);
|
||||||
imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $nwidth, $nheight, $width, $height);
|
imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $nwidth, $nheight, $width, $height);
|
||||||
|
|
||||||
$image($dst_img, $dst_dir, $quality);
|
imagepng($dst_img, $dst_dir);
|
||||||
|
|
||||||
if ($dst_img) imagedestroy($dst_img);
|
if ($dst_img) imagedestroy($dst_img);
|
||||||
if ($src_img) imagedestroy($src_img);
|
if ($src_img) imagedestroy($src_img);
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
|
|
||||||
class Http
|
class Http
|
||||||
{
|
{
|
||||||
public static function getData($url, $headers = [])
|
public static function getData($url, $headers = [], $connect_timeout = 3000, $wait_timeout = 3000)
|
||||||
{
|
{
|
||||||
global $http_proxy, $http_proxyauth, $admin;
|
global $http_proxy, $http_proxyauth, $admin;
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, $url);
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
curl_setopt($ch, CURLOPT_POST, 0);
|
curl_setopt($ch, CURLOPT_POST, 0);
|
||||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 100);
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
|
curl_setopt($ch, CURLOPT_TIMEOUT, $wait_timeout);
|
||||||
if (is_array($headers) && count($headers) > 0) {
|
if (is_array($headers) && count($headers) > 0) {
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
}
|
}
|
||||||
|
@ -49,15 +49,15 @@ class Http
|
||||||
return (!empty($server_output)) ? $server_output : $error_msg;
|
return (!empty($server_output)) ? $server_output : $error_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function postJsonData($url, $array_post, $headers = [], $basic = null)
|
public static function postJsonData($url, $array_post, $headers = [], $basic = null, $connect_timeout = 3000, $wait_timeout = 3000)
|
||||||
{
|
{
|
||||||
global $http_proxy, $http_proxyauth, $admin;
|
global $http_proxy, $http_proxyauth, $admin;
|
||||||
$headers[] = 'Content-Type: application/json';
|
$headers[] = 'Content-Type: application/json';
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, $url);
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 100);
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
|
curl_setopt($ch, CURLOPT_TIMEOUT, $wait_timeout);
|
||||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||||
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
|
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
|
||||||
if (!empty($http_proxy)) {
|
if (!empty($http_proxy)) {
|
||||||
|
@ -92,15 +92,15 @@ class Http
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function postData($url, $array_post, $headers = [], $basic = null)
|
public static function postData($url, $array_post, $headers = [], $basic = null, $connect_timeout = 3000, $wait_timeout = 3000)
|
||||||
{
|
{
|
||||||
global $http_proxy, $http_proxyauth, $admin;
|
global $http_proxy, $http_proxyauth, $admin;
|
||||||
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
|
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, $url);
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 100);
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
|
curl_setopt($ch, CURLOPT_TIMEOUT, $wait_timeout);
|
||||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||||
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
|
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
|
||||||
if (!empty($http_proxy)) {
|
if (!empty($http_proxy)) {
|
||||||
|
|
252
system/autoload/Invoice.php
Normal file
252
system/autoload/Invoice.php
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Mpdf\Mpdf;
|
||||||
|
|
||||||
|
class Invoice
|
||||||
|
{
|
||||||
|
public static function generateInvoice($invoiceData)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (empty($invoiceData['invoice'])) {
|
||||||
|
throw new Exception("Invoice ID is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = Lang::getNotifText('email_invoice');
|
||||||
|
if (!$template) {
|
||||||
|
throw new Exception("Invoice template not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($template, '<body') === false) {
|
||||||
|
$template = "<html><body>$template</body></html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$processedHtml = self::renderTemplate($template, $invoiceData);
|
||||||
|
|
||||||
|
// Debugging: Save processed HTML to file for review
|
||||||
|
// file_put_contents('debug_invoice.html', $processedHtml);
|
||||||
|
|
||||||
|
// Generate PDF
|
||||||
|
$mpdf = new Mpdf([
|
||||||
|
'mode' => 'utf-8',
|
||||||
|
'format' => 'A4',
|
||||||
|
'margin_left' => 10,
|
||||||
|
'margin_right' => 10,
|
||||||
|
'margin_top' => 10,
|
||||||
|
'margin_bottom' => 10,
|
||||||
|
'default_font' => 'helvetica',
|
||||||
|
'orientation' => 'P',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$mpdf->SetDisplayMode('fullpage');
|
||||||
|
$mpdf->SetProtection(['print']);
|
||||||
|
$mpdf->shrink_tables_to_fit = 1;
|
||||||
|
$mpdf->SetWatermarkText(strtoupper($invoiceData['status'] ?? 'UNPAID'), 0.15);
|
||||||
|
$mpdf->showWatermarkText = true;
|
||||||
|
$mpdf->WriteHTML($processedHtml);
|
||||||
|
|
||||||
|
// Save PDF
|
||||||
|
$filename = "invoice_{$invoiceData['invoice']}.pdf";
|
||||||
|
$outputPath = "system/uploads/invoices/{$filename}";
|
||||||
|
$mpdf->Output($outputPath, 'F');
|
||||||
|
|
||||||
|
if (!file_exists($outputPath)) {
|
||||||
|
throw new Exception("Failed to save PDF file");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filename;
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
_log("Invoice generation failed: " . $e->getMessage());
|
||||||
|
sendTelegram("Invoice generation failed: " . $e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function renderTemplate($template, $invoiceData)
|
||||||
|
{
|
||||||
|
return preg_replace_callback('/\[\[(\w+)\]\]/', function ($matches) use ($invoiceData) {
|
||||||
|
$key = $matches[1];
|
||||||
|
if (!isset($invoiceData[$key])) {
|
||||||
|
_log("Missing invoice key: $key");
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($key, ['created_at', 'due_date'])) {
|
||||||
|
return date('F j, Y', strtotime($invoiceData[$key]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($key, ['amount', 'total', 'subtotal', 'tax'])) {
|
||||||
|
return $invoiceData['currency_code'] . number_format((float) $invoiceData[$key], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($key === 'bill_rows') {
|
||||||
|
return html_entity_decode($invoiceData[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return htmlspecialchars($invoiceData[$key] ?? '');
|
||||||
|
}, $template);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function sendInvoice($userId, $status = "Unpaid")
|
||||||
|
{
|
||||||
|
global $config, $root_path, $UPLOAD_PATH;
|
||||||
|
|
||||||
|
if (empty($config['currency_code'])) {
|
||||||
|
$config['currency_code'] = '$';
|
||||||
|
}
|
||||||
|
|
||||||
|
$account = ORM::for_table('tbl_customers')->find_one($userId);
|
||||||
|
|
||||||
|
if (!$account) {
|
||||||
|
_log("Failed to send invoice: User not found");
|
||||||
|
sendTelegram("Failed to send invoice: User not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$invoice = ORM::for_table("tbl_transactions")->where("username", $account->username)->find_one();
|
||||||
|
|
||||||
|
if (!$invoice) {
|
||||||
|
_log("Failed to send invoice: Transaction not found");
|
||||||
|
sendTelegram("Failed to send invoice: Transaction not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[$additionalBills, $add_cost] = User::getBills($account->id);
|
||||||
|
|
||||||
|
$invoiceItems = [
|
||||||
|
[
|
||||||
|
'description' => $invoice->plan_name,
|
||||||
|
'details' => 'Monthly Subscription',
|
||||||
|
'amount' => (float) $invoice->price
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$subtotal = (float) $invoice->price;
|
||||||
|
|
||||||
|
if ($add_cost > 0 && $invoice->routers != 'balance') {
|
||||||
|
foreach ($additionalBills as $description => $amount) {
|
||||||
|
if (is_numeric($amount)) {
|
||||||
|
$invoiceItems[] = [
|
||||||
|
'description' => $description,
|
||||||
|
'details' => 'Additional Bill',
|
||||||
|
'amount' => (float) $amount
|
||||||
|
];
|
||||||
|
$subtotal += (float) $amount;
|
||||||
|
} else {
|
||||||
|
_log("Invalid bill amount for {$description}: {$amount}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tax_rate = (float) ($config['tax_rate'] ?? 0);
|
||||||
|
$tax = $config['enable_tax'] ? Package::tax($subtotal) : 0;
|
||||||
|
$total = ($tax > 0) ? $subtotal + $tax : $subtotal + $tax;
|
||||||
|
|
||||||
|
$token = User::generateToken($account->id, 1);
|
||||||
|
if (!empty($token['token'])) {
|
||||||
|
$tur = ORM::for_table('tbl_user_recharges')
|
||||||
|
->where('customer_id', $account->id)
|
||||||
|
->where('namebp', $invoice->plan_name);
|
||||||
|
|
||||||
|
switch ($status) {
|
||||||
|
case 'Paid':
|
||||||
|
$tur->where('status', 'on');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$tur->where('status', 'off');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$turResult = $tur->find_one();
|
||||||
|
$payLink = $turResult ? '?_route=home&recharge=' . $turResult['id'] . '&uid=' . urlencode($token['token']) : '?_route=home';
|
||||||
|
} else {
|
||||||
|
$payLink = '?_route=home';
|
||||||
|
}
|
||||||
|
|
||||||
|
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||||
|
$logo = (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png')) ? $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.png?' . time() : $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.default.png';
|
||||||
|
$invoiceData = [
|
||||||
|
'invoice' => "INV-" . Package::_raid(),
|
||||||
|
'fullname' => $account->fullname,
|
||||||
|
'email' => $account->email,
|
||||||
|
'address' => $account->address,
|
||||||
|
'phone' => $account->phonenumber,
|
||||||
|
'bill_rows' => self::generateBillRows($invoiceItems, $config['currency_code'], $subtotal, $tax_rate, $tax, $total),
|
||||||
|
'status' => $status,
|
||||||
|
'created_at' => date('Y-m-d H:i:s'),
|
||||||
|
'due_date' => date('Y-m-d H:i:s', strtotime('+7 days')),
|
||||||
|
'currency' => $config['currency_code'],
|
||||||
|
'company_address' => $config['address'],
|
||||||
|
'company_name' => $config['CompanyName'],
|
||||||
|
'company_phone' => $config['phone'],
|
||||||
|
'logo' => $logo,
|
||||||
|
'payment_link' => $payLink
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!isset($invoiceData['bill_rows']) || empty($invoiceData['bill_rows'])) {
|
||||||
|
_log("Invoice Error: Bill rows data is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = self::generateInvoice($invoiceData);
|
||||||
|
|
||||||
|
if ($filename) {
|
||||||
|
$pdfPath = "system/uploads/invoices/{$filename}";
|
||||||
|
|
||||||
|
try {
|
||||||
|
Message::sendEmail(
|
||||||
|
$account->email,
|
||||||
|
"Invoice for Account {$account->fullname}",
|
||||||
|
"Please find your invoice attached",
|
||||||
|
$pdfPath
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
_log("Failed to send invoice email: " . $e->getMessage());
|
||||||
|
sendTelegram("Failed to send invoice email: " . $e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function generateBillRows($items, $currency, $subtotal, $tax_rate, $tax, $total)
|
||||||
|
{
|
||||||
|
$html = "<table style='width: 100%; border-collapse: collapse; margin: 20px 0;'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style='background: #3498db; color: white; padding: 12px; text-align: left;'>Description</th>
|
||||||
|
<th style='background: #3498db; color: white; padding: 12px; text-align: left;'>Details</th>
|
||||||
|
<th style='background: #3498db; color: white; padding: 12px; text-align: left;'>Amount</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>";
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$html .= "<tr>
|
||||||
|
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>{$item['description']}</td>
|
||||||
|
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>{$item['details']}</td>
|
||||||
|
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>{$currency}" . number_format((float) $item['amount'], 2) . "</td>
|
||||||
|
</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= "<tr>
|
||||||
|
<td colspan='2' style='text-align: right; padding: 10px; border-top: 2px solid #3498db;'>Subtotal:</td>
|
||||||
|
<td style='padding: 10px; border-top: 2px solid #3498db;'>{$currency}" . number_format($subtotal, 2) . "</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan='2' style='text-align: right; padding: 10px;'>TAX ({$tax_rate}%):</td>
|
||||||
|
<td style='padding: 10px;'>{$currency}" . number_format($tax, 2) . "</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan='2' style='text-align: right; padding: 10px; font-weight: bold;'>Total:</td>
|
||||||
|
<td style='padding: 10px; font-weight: bold;'>{$currency}" . number_format($total, 2) . "</td>
|
||||||
|
</tr>";
|
||||||
|
|
||||||
|
$html .= "</tbody></table>";
|
||||||
|
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -17,15 +17,18 @@ require $root_path . 'system/autoload/mail/SMTP.php';
|
||||||
class Message
|
class Message
|
||||||
{
|
{
|
||||||
|
|
||||||
public static function sendTelegram($txt, $chat_id = null)
|
public static function sendTelegram($txt, $chat_id = null, $topik = '')
|
||||||
{
|
{
|
||||||
global $config;
|
global $config;
|
||||||
run_hook('send_telegram', [$txt, $chat_id = null]); #HOOK
|
run_hook('send_telegram', [$txt, $chat_id, $topik]); #HOOK
|
||||||
if (!empty($config['telegram_bot'])) {
|
if (!empty($config['telegram_bot'])) {
|
||||||
if (empty($chat_id)) {
|
if (empty($chat_id)) {
|
||||||
$chat_id = $config['telegram_target_id'];
|
$chat_id = $config['telegram_target_id'];
|
||||||
}
|
}
|
||||||
return Http::getData('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $chat_id . '&text=' . urlencode($txt));
|
if (!empty($topik)) {
|
||||||
|
$topik = "message_thread_id=$topik&";
|
||||||
|
}
|
||||||
|
return Http::getData('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?' . $topik . 'chat_id=' . $chat_id . '&text=' . urlencode($txt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,23 +47,31 @@ class Message
|
||||||
try {
|
try {
|
||||||
foreach ($txts as $txt) {
|
foreach ($txts as $txt) {
|
||||||
self::sendSMS($config['sms_url'], $phone, $txt);
|
self::sendSMS($config['sms_url'], $phone, $txt);
|
||||||
|
self::logMessage('SMS', $phone, $txt, 'Success');
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Throwable $e) {
|
||||||
// ignore, add to logs
|
// ignore, add to logs
|
||||||
_log("Failed to send SMS using Mikrotik.\n" . $e->getMessage(), 'SMS', 0);
|
self::logMessage('SMS', $phone, $txt, 'Error', $e->getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
self::MikrotikSendSMS($config['sms_url'], $phone, $txt);
|
self::MikrotikSendSMS($config['sms_url'], $phone, $txt);
|
||||||
} catch (Exception $e) {
|
self::logMessage('MikroTikSMS', $phone, $txt, 'Success');
|
||||||
|
} catch (Throwable $e) {
|
||||||
// ignore, add to logs
|
// ignore, add to logs
|
||||||
_log("Failed to send SMS using Mikrotik.\n" . $e->getMessage(), 'SMS', 0);
|
self::logMessage('MikroTikSMS', $phone, $txt, 'Error', $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$smsurl = str_replace('[number]', urlencode($phone), $config['sms_url']);
|
$smsurl = str_replace('[number]', urlencode($phone), $config['sms_url']);
|
||||||
$smsurl = str_replace('[text]', urlencode($txt), $smsurl);
|
$smsurl = str_replace('[text]', urlencode($txt), $smsurl);
|
||||||
return Http::getData($smsurl);
|
try {
|
||||||
|
$response = Http::getData($smsurl);
|
||||||
|
self::logMessage('SMS HTTP Response', $phone, $txt, 'Success', $response);
|
||||||
|
return $response;
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
self::logMessage('SMS HTTP Request', $phone, $txt, 'Error', $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,15 +103,24 @@ class Message
|
||||||
if (empty($txt)) {
|
if (empty($txt)) {
|
||||||
return "kosong";
|
return "kosong";
|
||||||
}
|
}
|
||||||
run_hook('send_whatsapp', [$phone, $txt]); #HOOK
|
|
||||||
|
run_hook('send_whatsapp', [$phone, $txt]); // HOOK
|
||||||
|
|
||||||
if (!empty($config['wa_url'])) {
|
if (!empty($config['wa_url'])) {
|
||||||
$waurl = str_replace('[number]', urlencode(Lang::phoneFormat($phone)), $config['wa_url']);
|
$waurl = str_replace('[number]', urlencode(Lang::phoneFormat($phone)), $config['wa_url']);
|
||||||
$waurl = str_replace('[text]', urlencode($txt), $waurl);
|
$waurl = str_replace('[text]', urlencode($txt), $waurl);
|
||||||
return Http::getData($waurl);
|
|
||||||
|
try {
|
||||||
|
$response = Http::getData($waurl);
|
||||||
|
self::logMessage('WhatsApp HTTP Response', $phone, $txt, 'Success', $response);
|
||||||
|
return $response;
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
self::logMessage('WhatsApp HTTP Request', $phone, $txt, 'Error', $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function sendEmail($to, $subject, $body)
|
public static function sendEmail($to, $subject, $body, $attachmentPath = null)
|
||||||
{
|
{
|
||||||
global $config, $PAGES_PATH, $debug_mail;
|
global $config, $PAGES_PATH, $debug_mail;
|
||||||
if (empty($body)) {
|
if (empty($body)) {
|
||||||
|
@ -119,6 +139,7 @@ class Message
|
||||||
$attr .= "Reply-To: " . $config['mail_reply_to'] . "\r\n";
|
$attr .= "Reply-To: " . $config['mail_reply_to'] . "\r\n";
|
||||||
}
|
}
|
||||||
mail($to, $subject, $body, $attr);
|
mail($to, $subject, $body, $attr);
|
||||||
|
self::logMessage('Email', $to, $body, 'Success');
|
||||||
} else {
|
} else {
|
||||||
$mail = new PHPMailer();
|
$mail = new PHPMailer();
|
||||||
$mail->isSMTP();
|
$mail->isSMTP();
|
||||||
|
@ -140,6 +161,10 @@ class Message
|
||||||
|
|
||||||
$mail->addAddress($to);
|
$mail->addAddress($to);
|
||||||
$mail->Subject = $subject;
|
$mail->Subject = $subject;
|
||||||
|
// Attachments
|
||||||
|
if (!empty($attachmentPath)) {
|
||||||
|
$mail->addAttachment($attachmentPath);
|
||||||
|
}
|
||||||
|
|
||||||
if (!file_exists($PAGES_PATH . DIRECTORY_SEPARATOR . 'Email.html')) {
|
if (!file_exists($PAGES_PATH . DIRECTORY_SEPARATOR . 'Email.html')) {
|
||||||
if (!copy($PAGES_PATH . '_template' . DIRECTORY_SEPARATOR . 'Email.html', $PAGES_PATH . DIRECTORY_SEPARATOR . 'Email.html')) {
|
if (!copy($PAGES_PATH . '_template' . DIRECTORY_SEPARATOR . 'Email.html', $PAGES_PATH . DIRECTORY_SEPARATOR . 'Email.html')) {
|
||||||
|
@ -155,12 +180,16 @@ class Message
|
||||||
$html = str_replace('[[Body]]', nl2br($body), $html);
|
$html = str_replace('[[Body]]', nl2br($body), $html);
|
||||||
$mail->isHTML(true);
|
$mail->isHTML(true);
|
||||||
$mail->Body = $html;
|
$mail->Body = $html;
|
||||||
|
$mail->Body = $html;
|
||||||
} else {
|
} else {
|
||||||
$mail->isHTML(false);
|
$mail->isHTML(false);
|
||||||
$mail->Body = $body;
|
$mail->Body = $body;
|
||||||
}
|
}
|
||||||
if (!$mail->send()) {
|
if (!$mail->send()) {
|
||||||
_log(Lang::T("Email not sent, Mailer Error: ") . $mail->ErrorInfo);
|
$errorMessage = Lang::T("Email not sent, Mailer Error: ") . $mail->ErrorInfo;
|
||||||
|
self::logMessage('Email', $to, $body, 'Error', $errorMessage);
|
||||||
|
} else {
|
||||||
|
self::logMessage('Email', $to, $body, 'Success');
|
||||||
}
|
}
|
||||||
|
|
||||||
//<p style="font-family: Helvetica, sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px;">
|
//<p style="font-family: Helvetica, sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px;">
|
||||||
|
@ -279,7 +308,7 @@ class Message
|
||||||
|
|
||||||
public static function sendInvoice($cust, $trx)
|
public static function sendInvoice($cust, $trx)
|
||||||
{
|
{
|
||||||
global $config;
|
global $config, $db_pass;
|
||||||
$textInvoice = Lang::getNotifText('invoice_paid');
|
$textInvoice = Lang::getNotifText('invoice_paid');
|
||||||
$textInvoice = str_replace('[[company_name]]', $config['CompanyName'], $textInvoice);
|
$textInvoice = str_replace('[[company_name]]', $config['CompanyName'], $textInvoice);
|
||||||
$textInvoice = str_replace('[[address]]', $config['address'], $textInvoice);
|
$textInvoice = str_replace('[[address]]', $config['address'], $textInvoice);
|
||||||
|
@ -305,6 +334,46 @@ class Message
|
||||||
$textInvoice = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($trx['expiration'], $trx['time']), $textInvoice);
|
$textInvoice = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($trx['expiration'], $trx['time']), $textInvoice);
|
||||||
$textInvoice = str_replace('[[footer]]', $config['note'], $textInvoice);
|
$textInvoice = str_replace('[[footer]]', $config['note'], $textInvoice);
|
||||||
|
|
||||||
|
$inv_url = "?_route=voucher/invoice/$trx[id]/" . md5($trx['id'] . $db_pass);
|
||||||
|
$textInvoice = str_replace('[[invoice_link]]', $inv_url, $textInvoice);
|
||||||
|
|
||||||
|
// Calculate bills and additional costs
|
||||||
|
list($bills, $add_cost) = User::getBills($cust['id']);
|
||||||
|
|
||||||
|
// Initialize note and total variables
|
||||||
|
$note = "";
|
||||||
|
$total = $trx['price'];
|
||||||
|
|
||||||
|
// Add bills to the note if there are any additional costs
|
||||||
|
if ($add_cost != 0) {
|
||||||
|
foreach ($bills as $k => $v) {
|
||||||
|
$note .= $k . " : " . Lang::moneyFormat($v) . "\n";
|
||||||
|
}
|
||||||
|
$total += $add_cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate tax
|
||||||
|
$tax = 0;
|
||||||
|
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||||
|
if ($tax_enable === 'yes') {
|
||||||
|
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : null;
|
||||||
|
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float) $config['custom_tax_rate'] : null;
|
||||||
|
|
||||||
|
$tax_rate = ($tax_rate_setting === 'custom') ? $custom_tax_rate : $tax_rate_setting;
|
||||||
|
$tax = Package::tax($trx['price'], $tax_rate);
|
||||||
|
|
||||||
|
if ($tax != 0) {
|
||||||
|
$note .= "Tax : " . Lang::moneyFormat($tax) . "\n";
|
||||||
|
$total += $tax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add total to the note
|
||||||
|
$note .= "Total : " . Lang::moneyFormat($total) . "\n";
|
||||||
|
|
||||||
|
// Replace placeholders in the message
|
||||||
|
$textInvoice = str_replace('[[bills]]', $note, $textInvoice);
|
||||||
|
|
||||||
if ($config['user_notification_payment'] == 'sms') {
|
if ($config['user_notification_payment'] == 'sms') {
|
||||||
Message::sendSMS($cust['phonenumber'], $textInvoice);
|
Message::sendSMS($cust['phonenumber'], $textInvoice);
|
||||||
} else if ($config['user_notification_payment'] == 'email') {
|
} else if ($config['user_notification_payment'] == 'email') {
|
||||||
|
@ -317,6 +386,8 @@ class Message
|
||||||
|
|
||||||
public static function addToInbox($to_customer_id, $subject, $body, $from = 'System')
|
public static function addToInbox($to_customer_id, $subject, $body, $from = 'System')
|
||||||
{
|
{
|
||||||
|
$user = User::find($to_customer_id);
|
||||||
|
try {
|
||||||
$v = ORM::for_table('tbl_customers_inbox')->create();
|
$v = ORM::for_table('tbl_customers_inbox')->create();
|
||||||
$v->from = $from;
|
$v->from = $from;
|
||||||
$v->customer_id = $to_customer_id;
|
$v->customer_id = $to_customer_id;
|
||||||
|
@ -324,5 +395,34 @@ class Message
|
||||||
$v->date_created = date('Y-m-d H:i:s');
|
$v->date_created = date('Y-m-d H:i:s');
|
||||||
$v->body = nl2br($body);
|
$v->body = nl2br($body);
|
||||||
$v->save();
|
$v->save();
|
||||||
|
self::logMessage("Inbox", $user->username, $body, "Success");
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
$errorMessage = Lang::T("Error adding message to inbox: " . $e->getMessage());
|
||||||
|
self::logMessage('Inbox', $user->username, $body, 'Error', $errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMessageType($type, $message)
|
||||||
|
{
|
||||||
|
if (strpos($message, "<divider>") === false) {
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
$msgs = explode("<divider>", $message);
|
||||||
|
if ($type == "PPPOE") {
|
||||||
|
return $msgs[1];
|
||||||
|
} else {
|
||||||
|
return $msgs[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function logMessage($messageType, $recipient, $messageContent, $status, $errorMessage = null)
|
||||||
|
{
|
||||||
|
$log = ORM::for_table('tbl_message_logs')->create();
|
||||||
|
$log->message_type = $messageType;
|
||||||
|
$log->recipient = $recipient;
|
||||||
|
$log->message_content = $messageContent;
|
||||||
|
$log->status = $status;
|
||||||
|
$log->error_message = $errorMessage;
|
||||||
|
$log->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,11 @@ class Response extends Message
|
||||||
/**
|
/**
|
||||||
* The last response for a request.
|
* The last response for a request.
|
||||||
*/
|
*/
|
||||||
const TYPE_FINAL = '!done';
|
const TYPE_FINAL = '!done';/**
|
||||||
|
|
||||||
|
* The empty response for a request.
|
||||||
|
*/
|
||||||
|
const TYPE_EMPTY = '!empty';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A response with data.
|
* A response with data.
|
||||||
|
@ -246,6 +250,7 @@ class Response extends Message
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::TYPE_FINAL:
|
case self::TYPE_FINAL:
|
||||||
|
case self::TYPE_EMPTY:
|
||||||
case self::TYPE_DATA:
|
case self::TYPE_DATA:
|
||||||
case self::TYPE_ERROR:
|
case self::TYPE_ERROR:
|
||||||
case self::TYPE_FATAL:
|
case self::TYPE_FATAL:
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Paginator
|
||||||
{
|
{
|
||||||
public static function findMany($query, $search = [], $per_page = '10', $append_url = "", $toArray = false)
|
public static function findMany($query, $search = [], $per_page = '10', $append_url = "", $toArray = false)
|
||||||
{
|
{
|
||||||
global $routes, $ui;
|
global $routes, $ui, $isApi;
|
||||||
$adjacents = "2";
|
$adjacents = "2";
|
||||||
$page = _get('p', 1);
|
$page = _get('p', 1);
|
||||||
$page = (empty($page) ? 1 : $page);
|
$page = (empty($page) ? 1 : $page);
|
||||||
|
@ -19,6 +19,7 @@ class Paginator
|
||||||
$url .= '&' . http_build_query($search);
|
$url .= '&' . http_build_query($search);
|
||||||
}
|
}
|
||||||
$url .= $append_url.'&p=';
|
$url .= $append_url.'&p=';
|
||||||
|
$url = Text::fixUrl($url);
|
||||||
$totalReq = $query->count();
|
$totalReq = $query->count();
|
||||||
$lastpage = ceil($totalReq / $per_page);
|
$lastpage = ceil($totalReq / $per_page);
|
||||||
$lpm1 = $lastpage - 1;
|
$lpm1 = $lastpage - 1;
|
||||||
|
@ -71,7 +72,7 @@ class Paginator
|
||||||
if ($ui) {
|
if ($ui) {
|
||||||
$ui->assign('paginator', $result);
|
$ui->assign('paginator', $result);
|
||||||
}
|
}
|
||||||
if($toArray){
|
if($toArray || $isApi){
|
||||||
return $query->offset($startpoint)->limit($per_page)->find_array();
|
return $query->offset($startpoint)->limit($per_page)->find_array();
|
||||||
}else{
|
}else{
|
||||||
return $query->offset($startpoint)->limit($per_page)->find_many();
|
return $query->offset($startpoint)->limit($per_page)->find_many();
|
||||||
|
|
|
@ -110,6 +110,12 @@ class Text
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ...$data means it can take any number of arguments.
|
||||||
|
* it can url($var1, $var2, $var3) or url($var1)
|
||||||
|
* and variable will be merge with implode
|
||||||
|
* @return string the URL with all the arguments combined.
|
||||||
|
*/
|
||||||
public static function url(...$data){
|
public static function url(...$data){
|
||||||
global $config;
|
global $config;
|
||||||
$url = implode("", $data);
|
$url = implode("", $data);
|
||||||
|
@ -125,4 +131,22 @@ class Text
|
||||||
return U . $url;
|
return U . $url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function fixUrl($url){
|
||||||
|
//if url dont have ? then add it with replace first & to ?
|
||||||
|
if(strpos($url, '?') === false && strpos($url, '&')!== false){
|
||||||
|
return substr($url, 0, strpos($url, '&')). '?'. substr($url, strpos($url, '&')+1);
|
||||||
|
}
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this will return & or ?
|
||||||
|
public static function isQA(){
|
||||||
|
global $config;
|
||||||
|
if ($config['url_canonical'] == 'yes') {
|
||||||
|
return '?';
|
||||||
|
} else {
|
||||||
|
return '&';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ class User
|
||||||
public static function getTawkToHash($email)
|
public static function getTawkToHash($email)
|
||||||
{
|
{
|
||||||
global $config;
|
global $config;
|
||||||
if (!empty($config['tawkto_api_key']) && !Empty($email)) {
|
if (!empty($config['tawkto_api_key']) && !empty($email)) {
|
||||||
return hash_hmac('sha256', $email, $config['tawkto_api_key']);
|
return hash_hmac('sha256', $email, $config['tawkto_api_key']);
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
|
@ -187,7 +187,7 @@ class User
|
||||||
global $db_pass;
|
global $db_pass;
|
||||||
if (isset($uid)) {
|
if (isset($uid)) {
|
||||||
$token = self::generateToken($uid);
|
$token = self::generateToken($uid);
|
||||||
setcookie('uid', $token['token'], time() + 86400 * 30);
|
setcookie('uid', $token['token'], time() + 86400 * 30, "/");
|
||||||
return $token;
|
return $token;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -197,7 +197,7 @@ class User
|
||||||
public static function removeCookie()
|
public static function removeCookie()
|
||||||
{
|
{
|
||||||
if (isset($_COOKIE['uid'])) {
|
if (isset($_COOKIE['uid'])) {
|
||||||
setcookie('uid', '', time() - 86400);
|
setcookie('uid', '', time() - 86400, "/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,8 @@ class User
|
||||||
return $d;
|
return $d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setFormCustomField($uid = 0){
|
public static function setFormCustomField($uid = 0)
|
||||||
|
{
|
||||||
global $UPLOAD_PATH;
|
global $UPLOAD_PATH;
|
||||||
$fieldPath = $UPLOAD_PATH . DIRECTORY_SEPARATOR . "customer_field.json";
|
$fieldPath = $UPLOAD_PATH . DIRECTORY_SEPARATOR . "customer_field.json";
|
||||||
if (!file_exists($fieldPath)) {
|
if (!file_exists($fieldPath)) {
|
||||||
|
@ -291,7 +292,8 @@ class User
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getFormCustomField($ui, $register = false, $uid = 0){
|
public static function getFormCustomField($ui, $register = false, $uid = 0)
|
||||||
|
{
|
||||||
global $UPLOAD_PATH;
|
global $UPLOAD_PATH;
|
||||||
$fieldPath = $UPLOAD_PATH . DIRECTORY_SEPARATOR . "customer_field.json";
|
$fieldPath = $UPLOAD_PATH . DIRECTORY_SEPARATOR . "customer_field.json";
|
||||||
if (!file_exists($fieldPath)) {
|
if (!file_exists($fieldPath)) {
|
||||||
|
@ -318,4 +320,10 @@ class User
|
||||||
}
|
}
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
public static function find($id)
|
||||||
|
{
|
||||||
|
return ORM::for_table('tbl_customers')->find_one($id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
50
system/autoload/Widget.php
Normal file
50
system/autoload/Widget.php
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||||
|
* by https://t.me/ibnux
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator class
|
||||||
|
*/
|
||||||
|
class Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function rows($rows, $result){
|
||||||
|
$result .= '<div class="row">';
|
||||||
|
foreach($rows as $row){
|
||||||
|
|
||||||
|
}
|
||||||
|
$result .= '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function columns($cols, $result){
|
||||||
|
$c = count($cols);
|
||||||
|
switch($c){
|
||||||
|
case 1:
|
||||||
|
$result .= '<div class="col-md-12">';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$result .= '<div class="col-md-6">';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$result .= '<div class="col-md-4">';
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
$result .= '<div class="col-md-4">';
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
$result .= '<div class="col-md-4">';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result .= '<div class="col-md-1">';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($cols as $col){
|
||||||
|
}
|
||||||
|
$result .= '</div>';
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,18 +68,22 @@ if (isset($_SESSION['notify'])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($_GET['_route'])) {
|
if (!isset($_GET['_route'])) {
|
||||||
$req = ltrim(parse_url($_SERVER['REQUEST_URI'])['path'], '/');
|
$req = ltrim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
|
||||||
|
$len = strlen(ltrim(parse_url(APP_URL, PHP_URL_PATH), '/'));
|
||||||
|
if ($len > 0) {
|
||||||
|
$req = ltrim(substr($req, $len), '/');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Routing Engine
|
// Routing Engine
|
||||||
$req = _get('_route');
|
$req = _get('_route');
|
||||||
}
|
}
|
||||||
|
|
||||||
$routes = explode('/', $req);
|
$routes = explode('/', $req);
|
||||||
$ui->assign('_routes', $routes);
|
$ui->assign('_routes', $routes);
|
||||||
$handler = $routes[0];
|
$handler = $routes[0];
|
||||||
if ($handler == '') {
|
if ($handler == '') {
|
||||||
$handler = 'default';
|
$handler = 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!empty($_GET['uid'])) {
|
if (!empty($_GET['uid'])) {
|
||||||
$_COOKIE['uid'] = $_GET['uid'];
|
$_COOKIE['uid'] = $_GET['uid'];
|
||||||
|
@ -124,11 +128,15 @@ try {
|
||||||
unset($menus, $menu_registered);
|
unset($menus, $menu_registered);
|
||||||
include($sys_render);
|
include($sys_render);
|
||||||
} else {
|
} else {
|
||||||
|
if( empty($_SERVER["HTTP_SEC_FETCH_DEST"]) || $_SERVER["HTTP_SEC_FETCH_DEST"] != 'document' ){
|
||||||
// header 404
|
// header 404
|
||||||
header("HTTP/1.0 404 Not Found");
|
header("HTTP/1.0 404 Not Found");
|
||||||
header("Content-Type: text/html; charset=utf-8");
|
header("Content-Type: text/html; charset=utf-8");
|
||||||
echo "404 Not Found";
|
echo "404 Not Found";
|
||||||
die();
|
die();
|
||||||
|
}else{
|
||||||
|
r2(getUrl('login'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
Message::sendTelegram(
|
Message::sendTelegram(
|
||||||
|
@ -137,11 +145,12 @@ try {
|
||||||
$e->getTraceAsString()
|
$e->getTraceAsString()
|
||||||
);
|
);
|
||||||
if (empty($_SESSION['aid'])) {
|
if (empty($_SESSION['aid'])) {
|
||||||
$ui->display('customer/error.tpl'); die();
|
$ui->display('customer/error.tpl');
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
$ui->assign("error_message", $e->getMessage() . '<br><pre>' . $e->getTraceAsString() . '</pre>');
|
$ui->assign("error_message", $e->getMessage() . '<br><pre>' . $e->getTraceAsString() . '</pre>');
|
||||||
$ui->assign("error_title", "PHPNuxBill Crash");
|
$ui->assign("error_title", "PHPNuxBill Crash");
|
||||||
$ui->display('error.tpl');
|
$ui->display('admin/error.tpl');
|
||||||
die();
|
die();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Message::sendTelegram(
|
Message::sendTelegram(
|
||||||
|
@ -150,10 +159,11 @@ try {
|
||||||
$e->getTraceAsString()
|
$e->getTraceAsString()
|
||||||
);
|
);
|
||||||
if (empty($_SESSION['aid'])) {
|
if (empty($_SESSION['aid'])) {
|
||||||
$ui->display('customer/error.tpl'); die();
|
$ui->display('customer/error.tpl');
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
$ui->assign("error_message", $e->getMessage() . '<br><pre>' . $e->getTraceAsString() . '</pre>');
|
$ui->assign("error_message", $e->getMessage() . '<br><pre>' . $e->getTraceAsString() . '</pre>');
|
||||||
$ui->assign("error_title", "PHPNuxBill Crash");
|
$ui->assign("error_title", "PHPNuxBill Crash");
|
||||||
$ui->display('error.tpl');
|
$ui->display('admin/error.tpl');
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,5 +420,5 @@ switch ($action) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,6 @@ switch ($do) {
|
||||||
run_hook('view_login'); #HOOK
|
run_hook('view_login'); #HOOK
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('admin-login.tpl');
|
$ui->display('admin/admin/login.tpl');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('routers', $routers);
|
$ui->assign('routers', $routers);
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
$ui->display('autoload-pool.tpl');
|
$ui->display('admin/autoload/pool.tpl');
|
||||||
break;
|
break;
|
||||||
case 'bw_name':
|
case 'bw_name':
|
||||||
$bw = ORM::for_table('tbl_bandwidth')->select("name_bw")->find_one($routes['2']);
|
$bw = ORM::for_table('tbl_bandwidth')->select("name_bw")->find_one($routes['2']);
|
||||||
|
@ -44,7 +44,7 @@ switch ($action) {
|
||||||
$d = ORM::for_table('tbl_routers')->where('enabled', '1')->find_many();
|
$d = ORM::for_table('tbl_routers')->where('enabled', '1')->find_many();
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
|
|
||||||
$ui->display('autoload-server.tpl');
|
$ui->display('admin/autoload/server.tpl');
|
||||||
break;
|
break;
|
||||||
case 'pppoe_ip_used':
|
case 'pppoe_ip_used':
|
||||||
if (!empty(_get('ip'))) {
|
if (!empty(_get('ip'))) {
|
||||||
|
@ -100,7 +100,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
|
|
||||||
$ui->display('autoload.tpl');
|
$ui->display('admin/autoload/plan.tpl');
|
||||||
break;
|
break;
|
||||||
case 'customer_is_active':
|
case 'customer_is_active':
|
||||||
if ($config['check_customer_online'] == 'yes') {
|
if ($config['check_customer_online'] == 'yes') {
|
||||||
|
@ -181,5 +181,5 @@ switch ($action) {
|
||||||
echo json_encode(['results' => $json]);
|
echo json_encode(['results' => $json]);
|
||||||
die();
|
die();
|
||||||
default:
|
default:
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,5 +79,5 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
die();
|
die();
|
||||||
default:
|
default:
|
||||||
$ui->display('404.tpl');
|
die();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'list':
|
case 'list':
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/bandwidth.js"></script>');
|
|
||||||
run_hook('view_list_bandwidth'); #HOOK
|
run_hook('view_list_bandwidth'); #HOOK
|
||||||
$name = _post('name');
|
$name = _post('name');
|
||||||
if ($name != '') {
|
if ($name != '') {
|
||||||
|
@ -30,7 +29,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
$ui->display('bandwidth.tpl');
|
$ui->display('admin/bandwidth/list.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'add':
|
case 'add':
|
||||||
|
@ -38,7 +37,7 @@ switch ($action) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
run_hook('view_add_bandwidth'); #HOOK
|
run_hook('view_add_bandwidth'); #HOOK
|
||||||
$ui->display('bandwidth-add.tpl');
|
$ui->display('admin/bandwidth/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
@ -51,7 +50,7 @@ switch ($action) {
|
||||||
if ($d) {
|
if ($d) {
|
||||||
$ui->assign('burst', explode(" ", $d['burst']));
|
$ui->assign('burst', explode(" ", $d['burst']));
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
$ui->display('bandwidth-edit.tpl');
|
$ui->display('admin/bandwidth/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('bandwidth/list'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('bandwidth/list'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -186,5 +185,5 @@ switch ($action) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('masters', $masters);
|
$ui->assign('masters', $masters);
|
||||||
$ui->assign('devs', $devs);
|
$ui->assign('devs', $devs);
|
||||||
$ui->display('community-rollback.tpl');
|
$ui->display('admin/rollback.tpl');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$ui->display('community.tpl');
|
$ui->display('admin/community.tpl');
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('_title', Lang::T('Add Coupon'));
|
$ui->assign('_title', Lang::T('Add Coupon'));
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->display('coupons-add.tpl');
|
$ui->display('admin/coupons/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'add-post':
|
case 'add-post':
|
||||||
|
@ -131,7 +131,7 @@ switch ($action) {
|
||||||
$ui->assign('coupon', $coupon);
|
$ui->assign('coupon', $coupon);
|
||||||
$ui->assign('_title', Lang::T('Edit Coupon: ' . $coupon['code']));
|
$ui->assign('_title', Lang::T('Edit Coupon: ' . $coupon['code']));
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->display('coupons-edit.tpl');
|
$ui->display('admin/coupons/edit.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit-post':
|
case 'edit-post':
|
||||||
|
@ -310,6 +310,6 @@ switch ($action) {
|
||||||
$coupons = Paginator::findMany($couponsData, ['search' => $search], 5, '');
|
$coupons = Paginator::findMany($couponsData, ['search' => $search], 5, '');
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->assign('coupons', $coupons);
|
$ui->assign('coupons', $coupons);
|
||||||
$ui->display('coupons.tpl');
|
$ui->display('admin/coupons/list.tpl');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ switch ($action) {
|
||||||
$ui->assign('xheader', $leafletpickerHeader);
|
$ui->assign('xheader', $leafletpickerHeader);
|
||||||
run_hook('view_add_customer'); #HOOK
|
run_hook('view_add_customer'); #HOOK
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->display('customers-add.tpl');
|
$ui->display('admin/customers/add.tpl');
|
||||||
break;
|
break;
|
||||||
case 'recharge':
|
case 'recharge':
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||||
|
@ -176,6 +176,10 @@ switch ($action) {
|
||||||
$channel = $admin['fullname'];
|
$channel = $admin['fullname'];
|
||||||
$cust = User::_info($id_customer);
|
$cust = User::_info($id_customer);
|
||||||
$plan = ORM::for_table('tbl_plans')->find_one($b['plan_id']);
|
$plan = ORM::for_table('tbl_plans')->find_one($b['plan_id']);
|
||||||
|
$add_inv = User::getAttribute("Invoice", $id_customer);
|
||||||
|
if (!empty($add_inv)) {
|
||||||
|
$plan['price'] = $add_inv;
|
||||||
|
}
|
||||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||||
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : null;
|
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : null;
|
||||||
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : null;
|
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : null;
|
||||||
|
@ -224,8 +228,9 @@ switch ($action) {
|
||||||
$ui->assign('channel', $channel);
|
$ui->assign('channel', $channel);
|
||||||
$ui->assign('server', $b['routers']);
|
$ui->assign('server', $b['routers']);
|
||||||
$ui->assign('plan', $plan);
|
$ui->assign('plan', $plan);
|
||||||
|
$ui->assign('add_inv', $add_inv);
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->display('recharge-confirm.tpl');
|
$ui->display('admin/plan/recharge-confirm.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('customers/view/') . $id_customer, 'e', 'Cannot find active plan');
|
r2(getUrl('customers/view/') . $id_customer, 'e', 'Cannot find active plan');
|
||||||
}
|
}
|
||||||
|
@ -364,7 +369,7 @@ switch ($action) {
|
||||||
$ui->assign('customFields', $customFields);
|
$ui->assign('customFields', $customFields);
|
||||||
$ui->assign('xheader', $leafletpickerHeader);
|
$ui->assign('xheader', $leafletpickerHeader);
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->display('customers-view.tpl');
|
$ui->display('admin/customers/view.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('customers/list'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('customers/list'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -403,7 +408,7 @@ switch ($action) {
|
||||||
$ui->assign('customFields', $customFields);
|
$ui->assign('customFields', $customFields);
|
||||||
$ui->assign('xheader', $leafletpickerHeader);
|
$ui->assign('xheader', $leafletpickerHeader);
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->display('customers-edit.tpl');
|
$ui->display('admin/customers/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('customers/list'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('customers/list'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -908,6 +913,6 @@ switch ($action) {
|
||||||
$ui->assign('order_pos', $order_pos[$order]);
|
$ui->assign('order_pos', $order_pos[$order]);
|
||||||
$ui->assign('orderby', $orderby);
|
$ui->assign('orderby', $orderby);
|
||||||
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
|
||||||
$ui->display('customers.tpl');
|
$ui->display('admin/customers/list.tpl');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,6 @@ switch ($action) {
|
||||||
$fields = json_decode(file_get_contents($fieldPath), true);
|
$fields = json_decode(file_get_contents($fieldPath), true);
|
||||||
}
|
}
|
||||||
$ui->assign('fields', $fields);
|
$ui->assign('fields', $fields);
|
||||||
$ui->display('customfield.tpl');
|
$ui->display('admin/settings/customfield.tpl');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
|
@ -20,6 +20,12 @@ if (isset($_GET['refresh'])) {
|
||||||
r2(getUrl('dashboard'), 's', 'Data Refreshed');
|
r2(getUrl('dashboard'), 's', 'Data Refreshed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$tipeUser = _req("user");
|
||||||
|
if (empty($tipeUser)) {
|
||||||
|
$tipeUser = 'Admin';
|
||||||
|
}
|
||||||
|
$ui->assign('tipeUser', $tipeUser);
|
||||||
|
|
||||||
$reset_day = $config['reset_day'];
|
$reset_day = $config['reset_day'];
|
||||||
if (empty($reset_day)) {
|
if (empty($reset_day)) {
|
||||||
$reset_day = 1;
|
$reset_day = 1;
|
||||||
|
@ -32,202 +38,29 @@ if (date("d") >= $reset_day) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$current_date = date('Y-m-d');
|
$current_date = date('Y-m-d');
|
||||||
$month_n = date('n');
|
|
||||||
|
|
||||||
$iday = ORM::for_table('tbl_transactions')
|
|
||||||
->where('recharged_on', $current_date)
|
|
||||||
->where_not_equal('method', 'Customer - Balance')
|
|
||||||
->where_not_equal('method', 'Recharge Balance - Administrator')
|
|
||||||
->sum('price');
|
|
||||||
|
|
||||||
if ($iday == '') {
|
|
||||||
$iday = '0.00';
|
|
||||||
}
|
|
||||||
$ui->assign('iday', $iday);
|
|
||||||
|
|
||||||
$imonth = ORM::for_table('tbl_transactions')
|
|
||||||
->where_not_equal('method', 'Customer - Balance')
|
|
||||||
->where_not_equal('method', 'Recharge Balance - Administrator')
|
|
||||||
->where_gte('recharged_on', $start_date)
|
|
||||||
->where_lte('recharged_on', $current_date)->sum('price');
|
|
||||||
if ($imonth == '') {
|
|
||||||
$imonth = '0.00';
|
|
||||||
}
|
|
||||||
$ui->assign('imonth', $imonth);
|
|
||||||
|
|
||||||
if ($config['enable_balance'] == 'yes'){
|
|
||||||
$cb = ORM::for_table('tbl_customers')->whereGte('balance', 0)->sum('balance');
|
|
||||||
$ui->assign('cb', $cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
$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);
|
|
||||||
|
|
||||||
$u_all = ORM::for_table('tbl_user_recharges')->count();
|
|
||||||
if (empty($u_all)) {
|
|
||||||
$u_all = '0';
|
|
||||||
}
|
|
||||||
$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);
|
|
||||||
|
|
||||||
if ($config['hide_uet'] != 'yes') {
|
|
||||||
//user expire
|
|
||||||
$query = ORM::for_table('tbl_user_recharges')
|
|
||||||
->where_lte('expiration', $current_date)
|
|
||||||
->order_by_desc('expiration');
|
|
||||||
$expire = Paginator::findMany($query);
|
|
||||||
|
|
||||||
// Get the total count of expired records for pagination
|
|
||||||
$totalCount = ORM::for_table('tbl_user_recharges')
|
|
||||||
->where_lte('expiration', $current_date)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
// Pass the total count and current page to the paginator
|
|
||||||
$paginator['total_count'] = $totalCount;
|
|
||||||
|
|
||||||
// Assign the pagination HTML to the template variable
|
|
||||||
$ui->assign('expire', $expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
//activity log
|
|
||||||
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->find_many();
|
|
||||||
$ui->assign('dlog', $dlog);
|
|
||||||
$log = ORM::for_table('tbl_logs')->count();
|
|
||||||
$ui->assign('log', $log);
|
|
||||||
|
|
||||||
|
|
||||||
if ($config['hide_vs'] != 'yes') {
|
|
||||||
$cacheStocksfile = $CACHE_PATH . File::pathFixer('/VoucherStocks.temp');
|
|
||||||
$cachePlanfile = $CACHE_PATH . File::pathFixer('/VoucherPlans.temp');
|
|
||||||
//Cache for 5 minutes
|
|
||||||
if (file_exists($cacheStocksfile) && time() - filemtime($cacheStocksfile) < 600) {
|
|
||||||
$stocks = json_decode(file_get_contents($cacheStocksfile), true);
|
|
||||||
$plans = json_decode(file_get_contents($cachePlanfile), true);
|
|
||||||
} else {
|
|
||||||
// Count stock
|
|
||||||
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
|
|
||||||
$plans = array();
|
|
||||||
$stocks = array("used" => 0, "unused" => 0);
|
|
||||||
$n = 0;
|
|
||||||
foreach ($tmp as $plan) {
|
|
||||||
$unused = ORM::for_table('tbl_voucher')
|
|
||||||
->where('id_plan', $plan['id'])
|
|
||||||
->where('status', 0)->count();
|
|
||||||
$used = ORM::for_table('tbl_voucher')
|
|
||||||
->where('id_plan', $plan['id'])
|
|
||||||
->where('status', 1)->count();
|
|
||||||
if ($unused > 0 || $used > 0) {
|
|
||||||
$plans[$n]['name_plan'] = $plan['name_plan'];
|
|
||||||
$plans[$n]['unused'] = $unused;
|
|
||||||
$plans[$n]['used'] = $used;
|
|
||||||
$stocks["unused"] += $unused;
|
|
||||||
$stocks["used"] += $used;
|
|
||||||
$n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_put_contents($cacheStocksfile, json_encode($stocks));
|
|
||||||
file_put_contents($cachePlanfile, json_encode($plans));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$cacheMRfile = File::pathFixer('/monthlyRegistered.temp');
|
|
||||||
//Cache for 1 hour
|
|
||||||
if (file_exists($cacheMRfile) && time() - filemtime($cacheMRfile) < 3600) {
|
|
||||||
$monthlyRegistered = json_decode(file_get_contents($cacheMRfile), true);
|
|
||||||
} else {
|
|
||||||
//Monthly Registered Customers
|
|
||||||
$result = ORM::for_table('tbl_customers')
|
|
||||||
->select_expr('MONTH(created_at)', 'month')
|
|
||||||
->select_expr('COUNT(*)', 'count')
|
|
||||||
->where_raw('YEAR(created_at) = YEAR(NOW())')
|
|
||||||
->group_by_expr('MONTH(created_at)')
|
|
||||||
->find_many();
|
|
||||||
|
|
||||||
$monthlyRegistered = [];
|
|
||||||
foreach ($result as $row) {
|
|
||||||
$monthlyRegistered[] = [
|
|
||||||
'date' => $row->month,
|
|
||||||
'count' => $row->count
|
|
||||||
];
|
|
||||||
}
|
|
||||||
file_put_contents($cacheMRfile, json_encode($monthlyRegistered));
|
|
||||||
}
|
|
||||||
|
|
||||||
$cacheMSfile = $CACHE_PATH . File::pathFixer('/monthlySales.temp');
|
|
||||||
//Cache for 12 hours
|
|
||||||
if (file_exists($cacheMSfile) && time() - filemtime($cacheMSfile) < 43200) {
|
|
||||||
$monthlySales = json_decode(file_get_contents($cacheMSfile), true);
|
|
||||||
} else {
|
|
||||||
// Query to retrieve monthly data
|
|
||||||
$results = ORM::for_table('tbl_transactions')
|
|
||||||
->select_expr('MONTH(recharged_on)', 'month')
|
|
||||||
->select_expr('SUM(price)', 'total')
|
|
||||||
->where_raw("YEAR(recharged_on) = YEAR(CURRENT_DATE())") // Filter by the current year
|
|
||||||
->where_not_equal('method', 'Customer - Balance')
|
|
||||||
->where_not_equal('method', 'Recharge Balance - Administrator')
|
|
||||||
->group_by_expr('MONTH(recharged_on)')
|
|
||||||
->find_many();
|
|
||||||
|
|
||||||
// Create an array to hold the monthly sales data
|
|
||||||
$monthlySales = array();
|
|
||||||
|
|
||||||
// Iterate over the results and populate the array
|
|
||||||
foreach ($results as $result) {
|
|
||||||
$month = $result->month;
|
|
||||||
$totalSales = $result->total;
|
|
||||||
|
|
||||||
$monthlySales[$month] = array(
|
|
||||||
'month' => $month,
|
|
||||||
'totalSales' => $totalSales
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in missing months with zero sales
|
|
||||||
for ($month = 1; $month <= 12; $month++) {
|
|
||||||
if (!isset($monthlySales[$month])) {
|
|
||||||
$monthlySales[$month] = array(
|
|
||||||
'month' => $month,
|
|
||||||
'totalSales' => 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the array by month
|
|
||||||
ksort($monthlySales);
|
|
||||||
|
|
||||||
// Reindex the array
|
|
||||||
$monthlySales = array_values($monthlySales);
|
|
||||||
file_put_contents($cacheMSfile, json_encode($monthlySales));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($config['router_check']) {
|
|
||||||
$routeroffs = ORM::for_table('tbl_routers')->selects(['id', 'name', 'last_seen'])->where('status', 'Offline')->where('enabled', '1')->order_by_desc('name')->find_array();
|
|
||||||
$ui->assign('routeroffs', $routeroffs);
|
|
||||||
}
|
|
||||||
|
|
||||||
$timestampFile = "$UPLOAD_PATH/cron_last_run.txt";
|
|
||||||
if (file_exists($timestampFile)) {
|
|
||||||
$lastRunTime = file_get_contents($timestampFile);
|
|
||||||
$ui->assign('run_date', date('Y-m-d h:i:s A', $lastRunTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign the monthly sales data to Smarty
|
|
||||||
$ui->assign('start_date', $start_date);
|
$ui->assign('start_date', $start_date);
|
||||||
$ui->assign('current_date', $current_date);
|
$ui->assign('current_date', $current_date);
|
||||||
$ui->assign('monthlySales', $monthlySales);
|
|
||||||
$ui->assign('xfooter', '');
|
|
||||||
$ui->assign('monthlyRegistered', $monthlyRegistered);
|
|
||||||
$ui->assign('stocks', $stocks);
|
|
||||||
$ui->assign('plans', $plans);
|
|
||||||
|
|
||||||
|
$tipeUser = $admin['user_type'];
|
||||||
|
if (in_array($tipeUser, ['SuperAdmin', 'Admin'])) {
|
||||||
|
$tipeUser = 'Admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
$widgets = ORM::for_table('tbl_widgets')->where("enabled", 1)->where('user', $tipeUser)->order_by_asc("orders")->findArray();
|
||||||
|
$count = count($widgets);
|
||||||
|
for ($i = 0; $i < $count; $i++) {
|
||||||
|
try{
|
||||||
|
if(file_exists($WIDGET_PATH . DIRECTORY_SEPARATOR . $widgets[$i]['widget'].".php")){
|
||||||
|
require_once $WIDGET_PATH . DIRECTORY_SEPARATOR . $widgets[$i]['widget'].".php";
|
||||||
|
$widgets[$i]['content'] = (new $widgets[$i]['widget'])->getWidget($widgets[$i]);
|
||||||
|
}else{
|
||||||
|
$widgets[$i]['content'] = "Widget not found";
|
||||||
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
$widgets[$i]['content'] = $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('widgets', $widgets);
|
||||||
run_hook('view_dashboard'); #HOOK
|
run_hook('view_dashboard'); #HOOK
|
||||||
$ui->display('dashboard.tpl');
|
$ui->display('admin/dashboard.tpl');
|
|
@ -5,9 +5,13 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
if(Admin::getID()){
|
if(Admin::getID()){
|
||||||
r2(getUrl('dashboard'));
|
//r2(getUrl('dashboard'));
|
||||||
}if(User::getID()){
|
$handler = 'dashboard';
|
||||||
r2(getUrl('home'));
|
}else if(User::getID()){
|
||||||
|
//r2(getUrl('home'));
|
||||||
|
$handler = 'home';
|
||||||
}else{
|
}else{
|
||||||
r2(getUrl('login'));
|
//r2(getUrl('login'));
|
||||||
|
$handler = 'login';
|
||||||
}
|
}
|
||||||
|
include($root_path . File::pathFixer('system/controllers/' . $handler . '.php'));
|
|
@ -83,7 +83,7 @@ switch ($action) {
|
||||||
$ui->assign('mdate', $mdate);
|
$ui->assign('mdate', $mdate);
|
||||||
$ui->assign('recharged_on', $mdate);
|
$ui->assign('recharged_on', $mdate);
|
||||||
run_hook('print_by_date'); #HOOK
|
run_hook('print_by_date'); #HOOK
|
||||||
$ui->display('print-by-date.tpl');
|
$ui->display('admin/print/by-date.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'pdf-by-date':
|
case 'pdf-by-date':
|
||||||
|
@ -281,7 +281,7 @@ EOF;
|
||||||
$ui->assign('tdate', $tdate);
|
$ui->assign('tdate', $tdate);
|
||||||
$ui->assign('stype', $stype);
|
$ui->assign('stype', $stype);
|
||||||
run_hook('print_by_period'); #HOOK
|
run_hook('print_by_period'); #HOOK
|
||||||
$ui->display('print-by-period.tpl');
|
$ui->display('admin/print/by-period.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
@ -427,5 +427,5 @@ EOF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,8 +95,7 @@ if (_post('send') == 'balance') {
|
||||||
}
|
}
|
||||||
r2(getUrl('home'), 'w', Lang::T('Your friend do not have active package'));
|
r2(getUrl('home'), 'w', Lang::T('Your friend do not have active package'));
|
||||||
}
|
}
|
||||||
$_bill = User::_billing();
|
|
||||||
$ui->assign('_bills', $_bill);
|
|
||||||
|
|
||||||
// Sync plan to router
|
// Sync plan to router
|
||||||
if (isset($_GET['sync']) && !empty($_GET['sync'])) {
|
if (isset($_GET['sync']) && !empty($_GET['sync'])) {
|
||||||
|
@ -147,7 +146,7 @@ if (isset($_GET['recharge']) && !empty($_GET['recharge'])) {
|
||||||
$routers = ORM::for_table('tbl_routers')->where('name', $bill['routers'])->find_one();
|
$routers = ORM::for_table('tbl_routers')->where('name', $bill['routers'])->find_one();
|
||||||
$router = $routers['id'];
|
$router = $routers['id'];
|
||||||
}
|
}
|
||||||
r2(getUrl('order/gateway/$router/$bill[plan_id]'));
|
r2(getUrl("order/gateway/$router/$bill[plan_id]"));
|
||||||
}
|
}
|
||||||
} else if (!empty(_get('extend'))) {
|
} else if (!empty(_get('extend'))) {
|
||||||
if ($user['status'] != 'Active') {
|
if ($user['status'] != 'Active') {
|
||||||
|
@ -197,8 +196,8 @@ if (isset($_GET['recharge']) && !empty($_GET['recharge'])) {
|
||||||
$tur->save();
|
$tur->save();
|
||||||
App::setToken(_get('stoken'), $id);
|
App::setToken(_get('stoken'), $id);
|
||||||
file_put_contents($path, $m);
|
file_put_contents($path, $m);
|
||||||
_log("Customer $tur[customer_id] $tur[username] extend for $days days", "Customer", $user['id']);
|
_log("Customer $tur[customer_id] $user[fullname] ($tur[username]) extend for $days days", "Customer", $user['id']);
|
||||||
Message::sendTelegram("#u$user[username] #extend #" . $p['type'] . " \n" . $p['name_plan'] .
|
Message::sendTelegram("#u$user[username] ($user[fullname]) #id$tur[customer_id] #extend #" . $p['type'] . " \n" . $p['name_plan'] .
|
||||||
"\nLocation: " . $p['routers'] .
|
"\nLocation: " . $p['routers'] .
|
||||||
"\nCustomer: " . $user['fullname'] .
|
"\nCustomer: " . $user['fullname'] .
|
||||||
"\nNew Expired: " . Lang::dateAndTimeFormat($expiration, $tur['time']));
|
"\nNew Expired: " . Lang::dateAndTimeFormat($expiration, $tur['time']));
|
||||||
|
@ -310,46 +309,25 @@ if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'] && !empty($_SESSI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$tcf = ORM::for_table('tbl_customers_fields')
|
|
||||||
->where('customer_id', $user['id'])
|
|
||||||
->find_many();
|
|
||||||
$vpn = ORM::for_table('tbl_port_pool')
|
|
||||||
->find_one();
|
|
||||||
$ui->assign('cf', $tcf);
|
|
||||||
$ui->assign('vpn', $vpn);
|
|
||||||
|
|
||||||
$unpaid = ORM::for_table('tbl_payment_gateway')
|
$widgets = ORM::for_table('tbl_widgets')->where("enabled", 1)->where('user', 'Customer')->order_by_asc("orders")->findArray();
|
||||||
->where('username', $user['username'])
|
$count = count($widgets);
|
||||||
->where('status', 1)
|
for ($i = 0; $i < $count; $i++) {
|
||||||
->find_one();
|
|
||||||
|
|
||||||
// check expired payments
|
|
||||||
if ($unpaid) {
|
|
||||||
try{
|
try{
|
||||||
if (strtotime($unpaid['expired_date']) < time()) {
|
if(file_exists($WIDGET_PATH . DIRECTORY_SEPARATOR . 'customer' . DIRECTORY_SEPARATOR . $widgets[$i]['widget'].".php")){
|
||||||
$unpaid->status = 4;
|
require_once $WIDGET_PATH . DIRECTORY_SEPARATOR . 'customer' . DIRECTORY_SEPARATOR . $widgets[$i]['widget'].".php";
|
||||||
$unpaid->save();
|
$widgets[$i]['content'] = (new $widgets[$i]['widget'])->getWidget($widgets[$i]);
|
||||||
$unpaid = [];
|
}else{
|
||||||
|
$widgets[$i]['content'] = "Widget not found";
|
||||||
}
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
} catch (Exception $e) {
|
$widgets[$i]['content'] = $e->getMessage();
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (strtotime($unpaid['created_date'], "+24 HOUR") < time()) {
|
|
||||||
$unpaid->status = 4;
|
|
||||||
$unpaid->save();
|
|
||||||
$unpaid = [];
|
|
||||||
}
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
} catch (Exception $e) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$ui->assign('unpaid', $unpaid);
|
$ui->assign('widgets', $widgets);
|
||||||
|
|
||||||
$ui->assign('code', alphanumeric(_get('code'), "-"));
|
$ui->assign('code', alphanumeric(_get('code'), "-"));
|
||||||
|
|
||||||
$abills = User::getAttributes("Bill");
|
|
||||||
$ui->assign('abills', $abills);
|
|
||||||
|
|
||||||
run_hook('view_customer_dashboard'); #HOOK
|
run_hook('view_customer_dashboard'); #HOOK
|
||||||
$ui->display('customer/dashboard.tpl');
|
$ui->display('customer/dashboard.tpl');
|
||||||
|
|
|
@ -80,6 +80,39 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'message-csv':
|
||||||
|
$logs = ORM::for_table('tbl_message_logs')
|
||||||
|
->select('id')
|
||||||
|
->select('message_type')
|
||||||
|
->select('recipient')
|
||||||
|
->select('message_content')
|
||||||
|
->select('status')
|
||||||
|
->select('error_message')
|
||||||
|
->select('sent_at')
|
||||||
|
->order_by_asc('id')->find_array();
|
||||||
|
$h = false;
|
||||||
|
set_time_limit(-1);
|
||||||
|
header('Pragma: public');
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header("Content-type: text/csv");
|
||||||
|
header('Content-Disposition: attachment;filename="message-logs_' . date('Y-m-d_H_i') . '.csv"');
|
||||||
|
header('Content-Transfer-Encoding: binary');
|
||||||
|
foreach ($logs as $log) {
|
||||||
|
$ks = [];
|
||||||
|
$vs = [];
|
||||||
|
foreach ($log as $k => $v) {
|
||||||
|
$ks[] = $k;
|
||||||
|
$vs[] = $v;
|
||||||
|
}
|
||||||
|
if (!$h) {
|
||||||
|
echo '"' . implode('";"', $ks) . "\"\n";
|
||||||
|
$h = true;
|
||||||
|
}
|
||||||
|
echo '"' . implode('";"', $vs) . "\"\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'list':
|
case 'list':
|
||||||
$q = (_post('q') ? _post('q') : _get('q'));
|
$q = (_post('q') ? _post('q') : _get('q'));
|
||||||
$keep = _post('keep');
|
$keep = _post('keep');
|
||||||
|
@ -97,7 +130,7 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
$ui->assign('q', $q);
|
$ui->assign('q', $q);
|
||||||
$ui->display('logs.tpl');
|
$ui->display('admin/logs/system.tpl');
|
||||||
break;
|
break;
|
||||||
case 'radius':
|
case 'radius':
|
||||||
$q = (_post('q') ? _post('q') : _get('q'));
|
$q = (_post('q') ? _post('q') : _get('q'));
|
||||||
|
@ -116,9 +149,36 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
$ui->assign('q', $q);
|
$ui->assign('q', $q);
|
||||||
$ui->display('logs-radius.tpl');
|
$ui->display('admin/logs/radius.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'message':
|
||||||
|
$q = _post('q') ?: _get('q');
|
||||||
|
$keep = (int) _post('keep');
|
||||||
|
if (!empty($keep)) {
|
||||||
|
ORM::raw_execute("DELETE FROM tbl_message_logs WHERE UNIX_TIMESTAMP(sent_at) < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL $keep DAY))");
|
||||||
|
r2(getUrl('logs/message/'), 's', "Deleted logs older than $keep days");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($q !== null && $q !== '') {
|
||||||
|
$query = ORM::for_table('tbl_message_logs')
|
||||||
|
->whereRaw("message_type LIKE '%$q%' OR recipient LIKE '%$q%' OR message_content LIKE '%$q%' OR status LIKE '%$q%' OR error_message LIKE '%$q%'")
|
||||||
|
->order_by_desc('sent_at');
|
||||||
|
$d = Paginator::findMany($query, ['q' => $q]);
|
||||||
|
} else {
|
||||||
|
$query = ORM::for_table('tbl_message_logs')->order_by_desc('sent_at');
|
||||||
|
$d = Paginator::findMany($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($d) {
|
||||||
|
$ui->assign('d', $d);
|
||||||
|
} else {
|
||||||
|
$ui->assign('d', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('q', $q);
|
||||||
|
$ui->display('admin/logs/message.tpl');
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
r2(getUrl('logs/list/'), 's', '');
|
r2(getUrl('logs/list/'), 's', '');
|
||||||
|
|
|
@ -15,6 +15,9 @@ if (empty($action)) {
|
||||||
$action = 'customer';
|
$action = 'customer';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ui->assign('xheader', '<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css">');
|
||||||
|
$ui->assign('xfooter', '<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>');
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'customer':
|
case 'customer':
|
||||||
if(!empty(_req('search'))){
|
if(!empty(_req('search'))){
|
||||||
|
@ -42,12 +45,22 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('search', $search);
|
$ui->assign('search', $search);
|
||||||
$ui->assign('customers', $customerData);
|
$ui->assign('customers', $customerData);
|
||||||
$ui->assign('xheader', '<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css">');
|
|
||||||
$ui->assign('_title', Lang::T('Customer Geo Location Information'));
|
$ui->assign('_title', Lang::T('Customer Geo Location Information'));
|
||||||
$ui->assign('xfooter', '<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>');
|
$ui->display('admin/maps/customers.tpl');
|
||||||
$ui->display('customers-map.tpl');
|
break;
|
||||||
|
case 'routers':
|
||||||
|
$name = _post('name');
|
||||||
|
$query = ORM::for_table('tbl_routers')->where_not_equal('coordinates', '')->order_by_desc('id');
|
||||||
|
$query->selects(['id', 'name', 'coordinates', 'description', 'coverage', 'enabled']);
|
||||||
|
if ($name != '') {
|
||||||
|
$query->where_like('name', '%' . $name . '%');
|
||||||
|
}
|
||||||
|
$d = Paginator::findMany($query, ['name' => $name], '20', '', true);
|
||||||
|
$ui->assign('name', $name);
|
||||||
|
$ui->assign('d', $d);
|
||||||
|
$ui->assign('_title', Lang::T('Routers Geo Location Information'));
|
||||||
|
$ui->display('admin/maps/routers.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
r2(getUrl('map/customer'), 'e', 'action not defined');
|
r2(getUrl('map/customer'), 'e', 'action not defined');
|
||||||
break;
|
break;
|
|
@ -22,6 +22,8 @@ switch ($action) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$appUrl = APP_URL;
|
||||||
|
|
||||||
$select2_customer = <<<EOT
|
$select2_customer = <<<EOT
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
@ -30,9 +32,9 @@ document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
ajax: {
|
ajax: {
|
||||||
url: function(params) {
|
url: function(params) {
|
||||||
if(params.term != undefined){
|
if(params.term != undefined){
|
||||||
return './?_route=autoload/customer_select2&s='+params.term;
|
return '{$appUrl}/?_route=autoload/customer_select2&s='+params.term;
|
||||||
}else{
|
}else{
|
||||||
return './?_route=autoload/customer_select2';
|
return '{$appUrl}/?_route=autoload/customer_select2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +48,7 @@ EOT;
|
||||||
$id = $routes['2'];
|
$id = $routes['2'];
|
||||||
$ui->assign('id', $id);
|
$ui->assign('id', $id);
|
||||||
$ui->assign('xfooter', $select2_customer);
|
$ui->assign('xfooter', $select2_customer);
|
||||||
$ui->display('message.tpl');
|
$ui->display('admin/message/single.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'send-post':
|
case 'send-post':
|
||||||
|
@ -72,6 +74,22 @@ EOT;
|
||||||
$message = str_replace('[[user_name]]', $c['username'], $message);
|
$message = str_replace('[[user_name]]', $c['username'], $message);
|
||||||
$message = str_replace('[[phone]]', $c['phonenumber'], $message);
|
$message = str_replace('[[phone]]', $c['phonenumber'], $message);
|
||||||
$message = str_replace('[[company_name]]', $config['CompanyName'], $message);
|
$message = str_replace('[[company_name]]', $config['CompanyName'], $message);
|
||||||
|
if (strpos($message, '[[payment_link]]') !== false) {
|
||||||
|
// token only valid for 1 day, for security reason
|
||||||
|
$token = User::generateToken($c['id'], 1);
|
||||||
|
if (!empty($token['token'])) {
|
||||||
|
$tur = ORM::for_table('tbl_user_recharges')
|
||||||
|
->where('customer_id', $c['id'])
|
||||||
|
//->where('namebp', $package)
|
||||||
|
->find_one();
|
||||||
|
if ($tur) {
|
||||||
|
$url = '?_route=home&recharge=' . $tur['id'] . '&uid=' . urlencode($token['token']);
|
||||||
|
$message = str_replace('[[payment_link]]', $url, $message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$message = str_replace('[[payment_link]]', '', $message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Send the message
|
//Send the message
|
||||||
|
@ -96,143 +114,318 @@ EOT;
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get form data
|
$ui->assign('routers', ORM::forTable('tbl_routers')->where('enabled', '1')->find_many());
|
||||||
$group = $_POST['group'];
|
$ui->display('admin/message/bulk.tpl');
|
||||||
$message = $_POST['message'];
|
break;
|
||||||
$via = $_POST['via'];
|
|
||||||
$test = isset($_POST['test']) && $_POST['test'] === 'on' ? 'yes' : 'no';
|
|
||||||
$batch = $_POST['batch'];
|
|
||||||
$delay = $_POST['delay'];
|
|
||||||
|
|
||||||
// Initialize counters
|
case 'send_bulk_ajax':
|
||||||
|
// Check user permissions
|
||||||
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||||
|
die(json_encode(['status' => 'error', 'message' => 'Permission denied']));
|
||||||
|
}
|
||||||
|
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
// Get request parameters
|
||||||
|
$group = $_REQUEST['group'] ?? '';
|
||||||
|
$message = $_REQUEST['message'] ?? '';
|
||||||
|
$via = $_REQUEST['via'] ?? '';
|
||||||
|
$batch = $_REQUEST['batch'] ?? 100;
|
||||||
|
$page = $_REQUEST['page'] ?? 0;
|
||||||
|
$router = $_REQUEST['router'] ?? null;
|
||||||
|
$test = isset($_REQUEST['test']) && $_REQUEST['test'] === 'on' ? true : false;
|
||||||
|
$service = $_REQUEST['service'] ?? '';
|
||||||
|
|
||||||
|
if (empty($group) || empty($message) || empty($via) || empty($service)) {
|
||||||
|
die(json_encode(['status' => 'error', 'message' => 'All fields are required']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get batch of customers based on group
|
||||||
|
$startpoint = $page * $batch;
|
||||||
|
$customers = [];
|
||||||
|
$totalCustomers = 0;
|
||||||
|
|
||||||
|
if (isset($router) && !empty($router)) {
|
||||||
|
switch ($router) {
|
||||||
|
case 'radius':
|
||||||
|
$routerName = 'Radius';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$router = ORM::for_table('tbl_routers')->find_one($router);
|
||||||
|
if (!$router) {
|
||||||
|
die(json_encode(['status' => 'error', 'message' => 'Invalid router']));
|
||||||
|
}
|
||||||
|
$routerName = $router->name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($router) && !empty($router)) {
|
||||||
|
$query = ORM::for_table('tbl_user_recharges')
|
||||||
|
->left_outer_join('tbl_customers', 'tbl_user_recharges.customer_id = tbl_customers.id')
|
||||||
|
->where('tbl_user_recharges.routers', $routerName);
|
||||||
|
|
||||||
|
switch ($service) {
|
||||||
|
case 'all':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$validServices = ['PPPoE', 'Hotspot', 'VPN'];
|
||||||
|
if (in_array($service, $validServices)) {
|
||||||
|
$query->where('type', $service);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalCustomers = $query->count();
|
||||||
|
|
||||||
|
$query->offset($startpoint)
|
||||||
|
->limit($batch);
|
||||||
|
|
||||||
|
switch ($group) {
|
||||||
|
case 'all':
|
||||||
|
break;
|
||||||
|
case 'new':
|
||||||
|
$query->where_raw("DATE(recharged_on) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)");
|
||||||
|
break;
|
||||||
|
case 'expired':
|
||||||
|
$query->where('tbl_user_recharges.status', 'off');
|
||||||
|
break;
|
||||||
|
case 'active':
|
||||||
|
$query->where('tbl_user_recharges.status', 'on');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the customers
|
||||||
|
$query->selects([
|
||||||
|
['tbl_customers.phonenumber', 'phonenumber'],
|
||||||
|
['tbl_user_recharges.customer_id', 'customer_id'],
|
||||||
|
['tbl_customers.fullname', 'fullname'],
|
||||||
|
]);
|
||||||
|
$customers = $query->find_array();
|
||||||
|
} else {
|
||||||
|
switch ($group) {
|
||||||
|
case 'all':
|
||||||
|
$totalCustomersQuery = ORM::for_table('tbl_customers');
|
||||||
|
|
||||||
|
switch ($service) {
|
||||||
|
case 'all':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$validServices = ['PPPoE', 'Hotspot', 'VPN'];
|
||||||
|
if (in_array($service, $validServices)) {
|
||||||
|
$totalCustomersQuery->where('service_type', $service);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$totalCustomers = $totalCustomersQuery->count();
|
||||||
|
$customers = $totalCustomersQuery->offset($startpoint)->limit($batch)->find_array();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'new':
|
||||||
|
$totalCustomersQuery = ORM::for_table('tbl_customers')
|
||||||
|
->where_raw("DATE(created_at) >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)");
|
||||||
|
|
||||||
|
switch ($service) {
|
||||||
|
case 'all':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$validServices = ['PPPoE', 'Hotspot', 'VPN'];
|
||||||
|
if (in_array($service, $validServices)) {
|
||||||
|
$totalCustomersQuery->where('service_type', $service);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$totalCustomers = $totalCustomersQuery->count();
|
||||||
|
$customers = $totalCustomersQuery->offset($startpoint)->limit($batch)->find_array();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'expired':
|
||||||
|
$totalCustomersQuery = ORM::for_table('tbl_user_recharges')
|
||||||
|
->where('status', 'off');
|
||||||
|
|
||||||
|
switch ($service) {
|
||||||
|
case 'all':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$validServices = ['PPPoE', 'Hotspot', 'VPN'];
|
||||||
|
if (in_array($service, $validServices)) {
|
||||||
|
$totalCustomersQuery->where('type', $service);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$totalCustomers = $totalCustomersQuery->count();
|
||||||
|
$customers = $totalCustomersQuery->select('customer_id')->offset($startpoint)->limit($batch)->find_array();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'active':
|
||||||
|
$totalCustomersQuery = ORM::for_table('tbl_user_recharges')
|
||||||
|
->where('status', 'on');
|
||||||
|
|
||||||
|
switch ($service) {
|
||||||
|
case 'all':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$validServices = ['PPPoE', 'Hotspot', 'VPN'];
|
||||||
|
if (in_array($service, $validServices)) {
|
||||||
|
$totalCustomersQuery->where('type', $service);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$totalCustomers = $totalCustomersQuery->count();
|
||||||
|
$customers = $totalCustomersQuery->select('customer_id')->offset($startpoint)->limit($batch)->find_array(); // Get customer data
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure $customers is always an array
|
||||||
|
if (!$customers) {
|
||||||
|
$customers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send messages
|
||||||
$totalSMSSent = 0;
|
$totalSMSSent = 0;
|
||||||
$totalSMSFailed = 0;
|
$totalSMSFailed = 0;
|
||||||
$totalWhatsappSent = 0;
|
$totalWhatsappSent = 0;
|
||||||
$totalWhatsappFailed = 0;
|
$totalWhatsappFailed = 0;
|
||||||
$batchStatus = [];
|
$batchStatus = [];
|
||||||
|
|
||||||
if (_req('send') == 'now') {
|
foreach ($customers as $customer) {
|
||||||
// Check if fields are empty
|
$currentMessage = str_replace(
|
||||||
if ($group == '' || $message == '' || $via == '') {
|
['[[name]]', '[[user_name]]', '[[phone]]', '[[company_name]]'],
|
||||||
r2(getUrl('message/send_bulk'), 'e', Lang::T('All fields are required'));
|
[$customer['fullname'], $customer['username'], $customer['phonenumber'], $config['CompanyName']],
|
||||||
} else {
|
$message
|
||||||
// Get customer details from the database based on the selected group
|
);
|
||||||
if ($group == 'all') {
|
|
||||||
$customers = ORM::for_table('tbl_customers')->find_many()->as_array();
|
$phoneNumber = preg_replace('/\D/', '', $customer['phonenumber']);
|
||||||
} elseif ($group == 'new') {
|
|
||||||
// Get customers created just a month ago
|
if (empty($phoneNumber)) {
|
||||||
$customers = ORM::for_table('tbl_customers')->where_raw("DATE(created_at) >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)")->find_many()->as_array();
|
$batchStatus[] = [
|
||||||
} elseif ($group == 'expired') {
|
'name' => $customer['fullname'],
|
||||||
// Get expired user recharges where status is 'off'
|
'phone' => '',
|
||||||
$expired = ORM::for_table('tbl_user_recharges')->where('status', 'off')->find_many();
|
'status' => 'No Phone Number'
|
||||||
$customer_ids = [];
|
];
|
||||||
foreach ($expired as $recharge) {
|
continue;
|
||||||
$customer_ids[] = $recharge->customer_id;
|
|
||||||
}
|
|
||||||
$customers = ORM::for_table('tbl_customers')->where_in('id', $customer_ids)->find_many()->as_array();
|
|
||||||
} elseif ($group == 'active') {
|
|
||||||
// Get active user recharges where status is 'on'
|
|
||||||
$active = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
|
|
||||||
$customer_ids = [];
|
|
||||||
foreach ($active as $recharge) {
|
|
||||||
$customer_ids[] = $recharge->customer_id;
|
|
||||||
}
|
|
||||||
$customers = ORM::for_table('tbl_customers')->where_in('id', $customer_ids)->find_many()->as_array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the batch size
|
if ($test) {
|
||||||
$batchSize = $batch;
|
|
||||||
|
|
||||||
// Calculate the number of batches
|
|
||||||
$totalCustomers = count($customers);
|
|
||||||
$totalBatches = ceil($totalCustomers / $batchSize);
|
|
||||||
|
|
||||||
// Loop through batches
|
|
||||||
for ($batchIndex = 0; $batchIndex < $totalBatches; $batchIndex++) {
|
|
||||||
// Get the starting and ending index for the current batch
|
|
||||||
$start = $batchIndex * $batchSize;
|
|
||||||
$end = min(($batchIndex + 1) * $batchSize, $totalCustomers);
|
|
||||||
$batchCustomers = array_slice($customers, $start, $end - $start);
|
|
||||||
|
|
||||||
// Loop through customers in the current batch and send messages
|
|
||||||
foreach ($batchCustomers as $customer) {
|
|
||||||
// Create a copy of the original message for each customer and save it as currentMessage
|
|
||||||
$currentMessage = $message;
|
|
||||||
$currentMessage = str_replace('[[name]]', $customer['fullname'], $currentMessage);
|
|
||||||
$currentMessage = str_replace('[[user_name]]', $customer['username'], $currentMessage);
|
|
||||||
$currentMessage = str_replace('[[phone]]', $customer['phonenumber'], $currentMessage);
|
|
||||||
$currentMessage = str_replace('[[company_name]]', $config['CompanyName'], $currentMessage);
|
|
||||||
|
|
||||||
// Send the message based on the selected method
|
|
||||||
if ($test === 'yes') {
|
|
||||||
// Only for testing, do not send messages to customers
|
|
||||||
$batchStatus[] = [
|
$batchStatus[] = [
|
||||||
'name' => $customer['fullname'],
|
'name' => $customer['fullname'],
|
||||||
'phone' => $customer['phonenumber'],
|
'phone' => $customer['phonenumber'],
|
||||||
|
'status' => 'Test Mode',
|
||||||
'message' => $currentMessage,
|
'message' => $currentMessage,
|
||||||
'status' => 'Test Mode - Message not sent'
|
'service' => $service,
|
||||||
|
'router' => $routerName,
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
// Send the actual messages
|
|
||||||
if ($via == 'sms' || $via == 'both') {
|
if ($via == 'sms' || $via == 'both') {
|
||||||
$smsSent = Message::sendSMS($customer['phonenumber'], $currentMessage);
|
if (Message::sendSMS($customer['phonenumber'], $currentMessage)) {
|
||||||
if ($smsSent) {
|
|
||||||
$totalSMSSent++;
|
$totalSMSSent++;
|
||||||
$batchStatus[] = [
|
$batchStatus[] = ['name' => $customer['fullname'], 'phone' => $customer['phonenumber'], 'status' => 'SMS Sent', 'message' => $currentMessage];
|
||||||
'name' => $customer['fullname'],
|
|
||||||
'phone' => $customer['phonenumber'],
|
|
||||||
'message' => $currentMessage,
|
|
||||||
'status' => 'SMS Message Sent'
|
|
||||||
];
|
|
||||||
} else {
|
} else {
|
||||||
$totalSMSFailed++;
|
$totalSMSFailed++;
|
||||||
$batchStatus[] = [
|
$batchStatus[] = ['name' => $customer['fullname'], 'phone' => $customer['phonenumber'], 'status' => 'SMS Failed', 'message' => $currentMessage];
|
||||||
'name' => $customer['fullname'],
|
|
||||||
'phone' => $customer['phonenumber'],
|
|
||||||
'message' => $currentMessage,
|
|
||||||
'status' => 'SMS Message Failed'
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($via == 'wa' || $via == 'both') {
|
if ($via == 'wa' || $via == 'both') {
|
||||||
$waSent = Message::sendWhatsapp($customer['phonenumber'], $currentMessage);
|
if (Message::sendWhatsapp($customer['phonenumber'], $currentMessage)) {
|
||||||
if ($waSent) {
|
|
||||||
$totalWhatsappSent++;
|
$totalWhatsappSent++;
|
||||||
$batchStatus[] = [
|
$batchStatus[] = ['name' => $customer['fullname'], 'phone' => $customer['phonenumber'], 'status' => 'WhatsApp Sent', 'message' => $currentMessage];
|
||||||
'name' => $customer['fullname'],
|
|
||||||
'phone' => $customer['phonenumber'],
|
|
||||||
'message' => $currentMessage,
|
|
||||||
'status' => 'WhatsApp Message Sent'
|
|
||||||
];
|
|
||||||
} else {
|
} else {
|
||||||
$totalWhatsappFailed++;
|
$totalWhatsappFailed++;
|
||||||
$batchStatus[] = [
|
$batchStatus[] = ['name' => $customer['fullname'], 'phone' => $customer['phonenumber'], 'status' => 'WhatsApp Failed', 'message' => $currentMessage];
|
||||||
'name' => $customer['fullname'],
|
|
||||||
'phone' => $customer['phonenumber'],
|
|
||||||
'message' => $currentMessage,
|
|
||||||
'status' => 'WhatsApp Message Failed'
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Introduce a delay between each batch
|
// Calculate if there are more customers to process
|
||||||
if ($batchIndex < $totalBatches - 1) {
|
$hasMore = ($startpoint + $batch) < $totalCustomers;
|
||||||
sleep($delay);
|
|
||||||
}
|
// Return JSON response
|
||||||
}
|
echo json_encode([
|
||||||
}
|
'status' => 'success',
|
||||||
}
|
'page' => $page + 1,
|
||||||
$ui->assign('batchStatus', $batchStatus);
|
'batchStatus' => $batchStatus,
|
||||||
$ui->assign('totalSMSSent', $totalSMSSent);
|
'message' => $currentMessage,
|
||||||
$ui->assign('totalSMSFailed', $totalSMSFailed);
|
'totalSent' => $totalSMSSent + $totalWhatsappSent,
|
||||||
$ui->assign('totalWhatsappSent', $totalWhatsappSent);
|
'totalFailed' => $totalSMSFailed + $totalWhatsappFailed,
|
||||||
$ui->assign('totalWhatsappFailed', $totalWhatsappFailed);
|
'hasMore' => $hasMore,
|
||||||
$ui->display('message-bulk.tpl');
|
'service' => $service,
|
||||||
|
'router' => $routerName,
|
||||||
|
]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'send_bulk_selected':
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
// Set headers
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Cache-Control: no-cache, no-store, must-revalidate');
|
||||||
|
|
||||||
|
// Get the posted data
|
||||||
|
$customerIds = $_POST['customer_ids'] ?? [];
|
||||||
|
$via = $_POST['message_type'] ?? '';
|
||||||
|
$message = isset($_POST['message']) ? trim($_POST['message']) : '';
|
||||||
|
if (empty($customerIds) || empty($message) || empty($via)) {
|
||||||
|
echo json_encode(['status' => 'error', 'message' => Lang::T('Invalid customer IDs, Message, or Message Type.')]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to send messages
|
||||||
|
$sentCount = 0;
|
||||||
|
$failedCount = 0;
|
||||||
|
$subject = Lang::T('Notification Message');
|
||||||
|
$form = 'Admin';
|
||||||
|
|
||||||
|
foreach ($customerIds as $customerId) {
|
||||||
|
$customer = ORM::for_table('tbl_customers')->where('id', $customerId)->find_one();
|
||||||
|
if ($customer) {
|
||||||
|
$messageSent = false;
|
||||||
|
|
||||||
|
// Check the message type and send accordingly
|
||||||
|
try {
|
||||||
|
if ($via === 'sms' || $via === 'all') {
|
||||||
|
$messageSent = Message::sendSMS($customer['phonenumber'], $message);
|
||||||
|
}
|
||||||
|
if (!$messageSent && ($via === 'wa' || $via === 'all')) {
|
||||||
|
$messageSent = Message::sendWhatsapp($customer['phonenumber'], $message);
|
||||||
|
}
|
||||||
|
if (!$messageSent && ($via === 'inbox' || $via === 'all')) {
|
||||||
|
Message::addToInbox($customer['id'], $subject, $message, $form);
|
||||||
|
$messageSent = true;
|
||||||
|
}
|
||||||
|
if (!$messageSent && ($via === 'email' || $via === 'all')) {
|
||||||
|
$messageSent = Message::sendEmail($customer['email'], $subject, $message);
|
||||||
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
$messageSent = false;
|
||||||
|
$failedCount++;
|
||||||
|
sendTelegram('Failed to send message to ' . $e->getMessage());
|
||||||
|
_log('Failed to send message to ' . $customer['fullname'] . ': ' . $e->getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($messageSent) {
|
||||||
|
$sentCount++;
|
||||||
|
} else {
|
||||||
|
$failedCount++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$failedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the response
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'success',
|
||||||
|
'totalSent' => $sentCount,
|
||||||
|
'totalFailed' => $failedCount
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode(['status' => 'error', 'message' => Lang::T('Invalid request method.')]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
r2(getUrl('message/send_sms'), 'e', 'action not defined');
|
r2(getUrl('message/send_sms'), 'e', 'action not defined');
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,7 +371,7 @@ switch ($action) {
|
||||||
$d->trx_invoice = $result;
|
$d->trx_invoice = $result;
|
||||||
$d->status = 2;
|
$d->status = 2;
|
||||||
$d->save();
|
$d->save();
|
||||||
r2(getUrl('order/view/$trx_id'), 's', Lang::T("Success to send package"));
|
r2(getUrl("order/view/$trx_id"), 's', Lang::T("Success to send package"));
|
||||||
} else {
|
} else {
|
||||||
$errorMessage = "Send Package with Balance Failed\n\n#u$user[username] #send \n" . $plan['name_plan'] .
|
$errorMessage = "Send Package with Balance Failed\n\n#u$user[username] #send \n" . $plan['name_plan'] .
|
||||||
"\nRouter: " . $router_name .
|
"\nRouter: " . $router_name .
|
||||||
|
@ -410,6 +410,10 @@ switch ($action) {
|
||||||
if ($router['name'] != 'balance') {
|
if ($router['name'] != 'balance') {
|
||||||
list($bills, $add_cost) = User::getBills($id_customer);
|
list($bills, $add_cost) = User::getBills($id_customer);
|
||||||
}
|
}
|
||||||
|
$add_inv = User::getAttribute("Invoice", $id_customer);
|
||||||
|
if (!empty($add_inv)) {
|
||||||
|
$plan['price'] = $add_inv;
|
||||||
|
}
|
||||||
|
|
||||||
if($config['enable_coupons']){
|
if($config['enable_coupons']){
|
||||||
if (!isset($_SESSION['coupon_attempts'])) {
|
if (!isset($_SESSION['coupon_attempts'])) {
|
||||||
|
|
|
@ -60,9 +60,9 @@ if (strpos($action, "-reset") !== false) {
|
||||||
$ui->assign("writeable", is_writable($path));
|
$ui->assign("writeable", is_writable($path));
|
||||||
$ui->assign("pageHeader", str_replace('_', ' ', $action));
|
$ui->assign("pageHeader", str_replace('_', ' ', $action));
|
||||||
$ui->assign("PageFile", $action);
|
$ui->assign("PageFile", $action);
|
||||||
$ui->display('page-edit.tpl');
|
$ui->display('admin/settings/page.tpl');
|
||||||
} else
|
} else
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
} else {
|
} else {
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
|
@ -83,5 +83,5 @@ if (strpos($action, "-reset") !== false) {
|
||||||
r2(getUrl('pages/') . $action, 'e', Lang::T("Failed to save page, make sure i can write to folder pages, <i>chmod 664 pages/*.html<i>"));
|
r2(getUrl('pages/') . $action, 'e', Lang::T("Failed to save page, make sure i can write to folder pages, <i>chmod 664 pages/*.html<i>"));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ switch ($action) {
|
||||||
$ui->assign('pgs', $pgs);
|
$ui->assign('pgs', $pgs);
|
||||||
$ui->assign('pg', $pg);
|
$ui->assign('pg', $pg);
|
||||||
$ui->assign('q', $q);
|
$ui->assign('q', $q);
|
||||||
$ui->display('paymentgateway-audit.tpl');
|
$ui->display('admin/paymentgateway/audit.tpl');
|
||||||
break;
|
break;
|
||||||
case 'auditview':
|
case 'auditview':
|
||||||
$pg = alphanumeric($routes[2]);
|
$pg = alphanumeric($routes[2]);
|
||||||
|
@ -43,7 +43,7 @@ switch ($action) {
|
||||||
$d['pg_paid_response'] = (!empty($d['pg_paid_response']))? Text::jsonArray21Array(json_decode($d['pg_paid_response'], true)) : [];
|
$d['pg_paid_response'] = (!empty($d['pg_paid_response']))? Text::jsonArray21Array(json_decode($d['pg_paid_response'], true)) : [];
|
||||||
$ui->assign('_title', 'Payment Gateway Audit View');
|
$ui->assign('_title', 'Payment Gateway Audit View');
|
||||||
$ui->assign('pg', $d);
|
$ui->assign('pg', $d);
|
||||||
$ui->display('paymentgateway-audit-view.tpl');
|
$ui->display('admin/paymentgateway/audit-view.tpl');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (_post('save') == 'actives') {
|
if (_post('save') == 'actives') {
|
||||||
|
@ -70,13 +70,13 @@ switch ($action) {
|
||||||
if (function_exists($action . '_save_config')) {
|
if (function_exists($action . '_save_config')) {
|
||||||
call_user_func($action . '_save_config');
|
call_user_func($action . '_save_config');
|
||||||
} else {
|
} else {
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (function_exists($action . '_show_config')) {
|
if (function_exists($action . '_show_config')) {
|
||||||
call_user_func($action . '_show_config');
|
call_user_func($action . '_show_config');
|
||||||
} else {
|
} else {
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,7 +92,7 @@ switch ($action) {
|
||||||
$ui->assign('_title', 'Payment Gateway Settings');
|
$ui->assign('_title', 'Payment Gateway Settings');
|
||||||
$ui->assign('pgs', $pgs);
|
$ui->assign('pgs', $pgs);
|
||||||
$ui->assign('actives', explode(',', $config['payment_gateway']));
|
$ui->assign('actives', explode(',', $config['payment_gateway']));
|
||||||
$ui->display('paymentgateway.tpl');
|
$ui->display('admin/paymentgateway/list.tpl');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ $ui->assign('_system_menu', 'plan');
|
||||||
$action = $routes['1'];
|
$action = $routes['1'];
|
||||||
$ui->assign('_admin', $admin);
|
$ui->assign('_admin', $admin);
|
||||||
|
|
||||||
|
$appUrl = APP_URL;
|
||||||
|
|
||||||
$select2_customer = <<<EOT
|
$select2_customer = <<<EOT
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
@ -20,9 +22,9 @@ document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
ajax: {
|
ajax: {
|
||||||
url: function(params) {
|
url: function(params) {
|
||||||
if(params.term != undefined){
|
if(params.term != undefined){
|
||||||
return './?_route=autoload/customer_select2&s='+params.term;
|
return '{$appUrl}/?_route=autoload/customer_select2&s='+params.term;
|
||||||
}else{
|
}else{
|
||||||
return './?_route=autoload/customer_select2';
|
return '{$appUrl}/?_route=autoload/customer_select2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +32,7 @@ document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
EOT;
|
EOT;
|
||||||
|
getUrl('docs');
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'sync':
|
case 'sync':
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
|
@ -82,7 +84,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('usings', $usings);
|
$ui->assign('usings', $usings);
|
||||||
run_hook('view_recharge'); #HOOK
|
run_hook('view_recharge'); #HOOK
|
||||||
$ui->display('recharge.tpl');
|
$ui->display('admin/plan/recharge.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'recharge-confirm':
|
case 'recharge-confirm':
|
||||||
|
@ -105,6 +107,10 @@ switch ($action) {
|
||||||
$cust = User::_info($id_customer);
|
$cust = User::_info($id_customer);
|
||||||
$plan = ORM::for_table('tbl_plans')->find_one($planId);
|
$plan = ORM::for_table('tbl_plans')->find_one($planId);
|
||||||
list($bills, $add_cost) = User::getBills($id_customer);
|
list($bills, $add_cost) = User::getBills($id_customer);
|
||||||
|
$add_inv = User::getAttribute("Invoice", $id_customer);
|
||||||
|
if (!empty($add_inv)) {
|
||||||
|
$plan['price'] = $add_inv;
|
||||||
|
}
|
||||||
|
|
||||||
// Tax calculation start
|
// Tax calculation start
|
||||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||||
|
@ -158,7 +164,8 @@ switch ($action) {
|
||||||
$ui->assign('server', $server);
|
$ui->assign('server', $server);
|
||||||
$ui->assign('using', $using);
|
$ui->assign('using', $using);
|
||||||
$ui->assign('plan', $plan);
|
$ui->assign('plan', $plan);
|
||||||
$ui->display('recharge-confirm.tpl');
|
$ui->assign('add_inv', $add_inv);
|
||||||
|
$ui->display('admin/plan/recharge-confirm.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan/recharge'), 'e', $msg);
|
r2(getUrl('plan/recharge'), 'e', $msg);
|
||||||
}
|
}
|
||||||
|
@ -180,7 +187,7 @@ switch ($action) {
|
||||||
$username = App::getVoucherValue($svoucher);
|
$username = App::getVoucherValue($svoucher);
|
||||||
$in = ORM::for_table('tbl_transactions')->where('username', $username)->order_by_desc('id')->find_one();
|
$in = ORM::for_table('tbl_transactions')->where('username', $username)->order_by_desc('id')->find_one();
|
||||||
Package::createInvoice($in);
|
Package::createInvoice($in);
|
||||||
$ui->display('invoice.tpl');
|
$ui->display('admin/plan/invoice.tpl');
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +246,7 @@ switch ($action) {
|
||||||
$in = ORM::for_table('tbl_transactions')->where('username', $cust['username'])->order_by_desc('id')->find_one();
|
$in = ORM::for_table('tbl_transactions')->where('username', $cust['username'])->order_by_desc('id')->find_one();
|
||||||
Package::createInvoice($in);
|
Package::createInvoice($in);
|
||||||
App::setVoucher($svoucher, $cust['username']);
|
App::setVoucher($svoucher, $cust['username']);
|
||||||
$ui->display('invoice.tpl');
|
$ui->display('admin/plan/invoice.tpl');
|
||||||
_log('[' . $admin['username'] . ']: ' . 'Recharge ' . $cust['username'] . ' [' . $in['plan_name'] . '][' . Lang::moneyFormat($in['price']) . ']', $admin['user_type'], $admin['id']);
|
_log('[' . $admin['username'] . ']: ' . 'Recharge ' . $cust['username'] . ' [' . $in['plan_name'] . '][' . Lang::moneyFormat($in['price']) . ']', $admin['user_type'], $admin['id']);
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan/recharge'), 'e', "Failed to recharge account");
|
r2(getUrl('plan/recharge'), 'e', "Failed to recharge account");
|
||||||
|
@ -262,8 +269,21 @@ switch ($action) {
|
||||||
r2(getUrl('plan/view/') . $id, 'd', "Customer not found");
|
r2(getUrl('plan/view/') . $id, 'd', "Customer not found");
|
||||||
}
|
}
|
||||||
Package::createInvoice($in);
|
Package::createInvoice($in);
|
||||||
|
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||||
|
$logo = '';
|
||||||
|
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png')) {
|
||||||
|
$logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.png';
|
||||||
|
$imgsize = getimagesize($logo);
|
||||||
|
$width = $imgsize[0];
|
||||||
|
$height = $imgsize[1];
|
||||||
|
$ui->assign('wlogo', $width);
|
||||||
|
$ui->assign('hlogo', $height);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('public_url', getUrl("voucher/invoice/$id/".md5($id. $db_pass)));
|
||||||
|
$ui->assign('logo', $logo);
|
||||||
$ui->assign('_title', 'View Invoice');
|
$ui->assign('_title', 'View Invoice');
|
||||||
$ui->display('invoice.tpl');
|
$ui->display('admin/plan/invoice.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,7 +305,7 @@ switch ($action) {
|
||||||
$ui->assign('date', Lang::dateAndTimeFormat($d['recharged_on'], $d['recharged_time']));
|
$ui->assign('date', Lang::dateAndTimeFormat($d['recharged_on'], $d['recharged_time']));
|
||||||
}
|
}
|
||||||
run_hook('print_invoice'); #HOOK
|
run_hook('print_invoice'); #HOOK
|
||||||
$ui->display('invoice-print.tpl');
|
$ui->display('admin/plan/invoice-print.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
@ -312,7 +332,7 @@ switch ($action) {
|
||||||
$ui->assign('p', $ps);
|
$ui->assign('p', $ps);
|
||||||
run_hook('view_edit_customer_plan'); #HOOK
|
run_hook('view_edit_customer_plan'); #HOOK
|
||||||
$ui->assign('_title', 'Edit Plan');
|
$ui->assign('_title', 'Edit Plan');
|
||||||
$ui->display('plan-edit.tpl');
|
$ui->display('admin/plan/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan/list'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('plan/list'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -510,7 +530,7 @@ switch ($action) {
|
||||||
$ui->assign('search', $search);
|
$ui->assign('search', $search);
|
||||||
$ui->assign('page', $page);
|
$ui->assign('page', $page);
|
||||||
run_hook('view_list_voucher'); #HOOK
|
run_hook('view_list_voucher'); #HOOK
|
||||||
$ui->display('voucher.tpl');
|
$ui->display('admin/voucher/list.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'add-voucher':
|
case 'add-voucher':
|
||||||
|
@ -525,7 +545,7 @@ switch ($action) {
|
||||||
$r = ORM::for_table('tbl_routers')->where('enabled', '1')->find_many();
|
$r = ORM::for_table('tbl_routers')->where('enabled', '1')->find_many();
|
||||||
$ui->assign('r', $r);
|
$ui->assign('r', $r);
|
||||||
run_hook('view_add_voucher'); #HOOK
|
run_hook('view_add_voucher'); #HOOK
|
||||||
$ui->display('voucher-add.tpl');
|
$ui->display('admin/voucher/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'remove-voucher':
|
case 'remove-voucher':
|
||||||
|
@ -556,9 +576,11 @@ switch ($action) {
|
||||||
if (empty($vpl)) {
|
if (empty($vpl)) {
|
||||||
$vpl = 3;
|
$vpl = 3;
|
||||||
}
|
}
|
||||||
if ($pagebreak < 1) $pagebreak = 12;
|
if ($pagebreak < 1)
|
||||||
|
$pagebreak = 12;
|
||||||
|
|
||||||
if ($limit < 1) $limit = $pagebreak * 2;
|
if ($limit < 1)
|
||||||
|
$limit = $pagebreak * 2;
|
||||||
if (empty($from_id)) {
|
if (empty($from_id)) {
|
||||||
$from_id = 0;
|
$from_id = 0;
|
||||||
}
|
}
|
||||||
|
@ -684,12 +706,15 @@ switch ($action) {
|
||||||
//for counting pagebreak
|
//for counting pagebreak
|
||||||
$ui->assign('jml', 0);
|
$ui->assign('jml', 0);
|
||||||
run_hook('view_print_voucher'); #HOOK
|
run_hook('view_print_voucher'); #HOOK
|
||||||
$ui->display('print-voucher.tpl');
|
$ui->display('admin/print/voucher.tpl');
|
||||||
break;
|
break;
|
||||||
case 'voucher-post':
|
case 'voucher-post':
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('plan/add-voucher/'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
|
|
||||||
$type = _post('type');
|
$type = _post('type');
|
||||||
$plan = _post('plan');
|
$plan = _post('plan');
|
||||||
|
@ -791,7 +816,7 @@ switch ($action) {
|
||||||
$ui->assign('from_id', 0);
|
$ui->assign('from_id', 0);
|
||||||
$ui->assign('vpl', '3');
|
$ui->assign('vpl', '3');
|
||||||
$ui->assign('pagebreak', $voucherPerPage);
|
$ui->assign('pagebreak', $voucherPerPage);
|
||||||
$ui->display('print-voucher.tpl');
|
$ui->display('admin/print/voucher.tpl');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($numbervoucher == 1) {
|
if ($numbervoucher == 1) {
|
||||||
|
@ -891,7 +916,7 @@ switch ($action) {
|
||||||
$content .= Lang::pad($config['note'], ' ', 2) . "\n";
|
$content .= Lang::pad($config['note'], ' ', 2) . "\n";
|
||||||
$ui->assign('_title', Lang::T('View'));
|
$ui->assign('_title', Lang::T('View'));
|
||||||
$ui->assign('whatsapp', urlencode("```$content```"));
|
$ui->assign('whatsapp', urlencode("```$content```"));
|
||||||
$ui->display('voucher-view.tpl');
|
$ui->display('admin/voucher/view.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan/voucher/'), 'e', Lang::T('Voucher Not Found'));
|
r2(getUrl('plan/voucher/'), 'e', Lang::T('Voucher Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -916,7 +941,7 @@ switch ($action) {
|
||||||
$ui->assign('xfooter', $select2_customer);
|
$ui->assign('xfooter', $select2_customer);
|
||||||
$ui->assign('_title', Lang::T('Refill Account'));
|
$ui->assign('_title', Lang::T('Refill Account'));
|
||||||
run_hook('view_refill'); #HOOK
|
run_hook('view_refill'); #HOOK
|
||||||
$ui->display('refill.tpl');
|
$ui->display('admin/plan/refill.tpl');
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -936,7 +961,7 @@ switch ($action) {
|
||||||
$v1->save();
|
$v1->save();
|
||||||
$in = ORM::for_table('tbl_transactions')->where('username', $user['username'])->order_by_desc('id')->find_one();
|
$in = ORM::for_table('tbl_transactions')->where('username', $user['username'])->order_by_desc('id')->find_one();
|
||||||
Package::createInvoice($in);
|
Package::createInvoice($in);
|
||||||
$ui->display('invoice.tpl');
|
$ui->display('admin/plan/invoice.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan/refill'), 'e', "Failed to refill account");
|
r2(getUrl('plan/refill'), 'e', "Failed to refill account");
|
||||||
}
|
}
|
||||||
|
@ -956,7 +981,7 @@ switch ($action) {
|
||||||
$ui->assign('p', ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->find_many());
|
$ui->assign('p', ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->find_many());
|
||||||
}
|
}
|
||||||
run_hook('view_deposit'); #HOOK
|
run_hook('view_deposit'); #HOOK
|
||||||
$ui->display('deposit.tpl');
|
$ui->display('admin/plan/deposit.tpl');
|
||||||
break;
|
break;
|
||||||
case 'deposit-post':
|
case 'deposit-post':
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||||
|
@ -971,7 +996,7 @@ switch ($action) {
|
||||||
if (App::getVoucherValue($svoucher)) {
|
if (App::getVoucherValue($svoucher)) {
|
||||||
$in = ORM::for_table('tbl_transactions')->find_one(App::getVoucherValue($svoucher));
|
$in = ORM::for_table('tbl_transactions')->find_one(App::getVoucherValue($svoucher));
|
||||||
Package::createInvoice($in);
|
Package::createInvoice($in);
|
||||||
$ui->display('invoice.tpl');
|
$ui->display('admin/plan/invoice.tpl');
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -987,7 +1012,7 @@ switch ($action) {
|
||||||
if (!empty($svoucher)) {
|
if (!empty($svoucher)) {
|
||||||
App::setVoucher($svoucher, $trxId);
|
App::setVoucher($svoucher, $trxId);
|
||||||
}
|
}
|
||||||
$ui->display('invoice.tpl');
|
$ui->display('admin/plan/invoice.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan/refill'), 'e', "Failed to refill account");
|
r2(getUrl('plan/refill'), 'e', "Failed to refill account");
|
||||||
}
|
}
|
||||||
|
@ -1000,7 +1025,7 @@ switch ($action) {
|
||||||
if (!empty($svoucher)) {
|
if (!empty($svoucher)) {
|
||||||
App::setVoucher($svoucher, $trxId);
|
App::setVoucher($svoucher, $trxId);
|
||||||
}
|
}
|
||||||
$ui->display('invoice.tpl');
|
$ui->display('admin/plan/invoice.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan/refill'), 'e', "Failed to refill account");
|
r2(getUrl('plan/refill'), 'e', "Failed to refill account");
|
||||||
}
|
}
|
||||||
|
@ -1050,18 +1075,17 @@ switch ($action) {
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan'), 's', "Customer not found");
|
r2(getUrl('plan'), 's', "Customer not found");
|
||||||
}
|
}
|
||||||
Message::sendTelegram("#u$tur[username] #extend #" . $p['type'] . " \n" . $p['name_plan'] .
|
Message::sendTelegram("#u$tur[username] #id$tur[customer_id] #extend by $admin[fullname] #" . $p['type'] . " \n" . $p['name_plan'] .
|
||||||
"\nLocation: " . $p['routers'] .
|
"\nLocation: " . $p['routers'] .
|
||||||
"\nCustomer: " . $c['fullname'] .
|
"\nCustomer: " . $c['fullname'] .
|
||||||
"\nNew Expired: " . Lang::dateAndTimeFormat($expiration, $tur['time']));
|
"\nNew Expired: " . Lang::dateAndTimeFormat($expiration, $tur['time']));
|
||||||
_log("$admin[fullname] extend Customer $tur[customer_id] $tur[username] for $days days", $admin['user_type'], $admin['id']);
|
_log("$admin[fullname] extend Customer $tur[customer_id] $tur[username] #$tur[customer_id] for $days days", $admin['user_type'], $admin['id']);
|
||||||
r2(getUrl('plan'), 's', "Extend until $expiration");
|
r2(getUrl('plan'), 's', "Extend until $expiration");
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('plan'), 's', "Customer is not expired yet");
|
r2(getUrl('plan'), 's', "Customer is not expired yet");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/plan.js"></script>');
|
|
||||||
$ui->assign('_title', Lang::T('Customer'));
|
$ui->assign('_title', Lang::T('Customer'));
|
||||||
$search = _post('search');
|
$search = _post('search');
|
||||||
$status = _req('status');
|
$status = _req('status');
|
||||||
|
@ -1102,6 +1126,6 @@ switch ($action) {
|
||||||
$d = Paginator::findMany($query, ['search' => $search], 25, $append_url);
|
$d = Paginator::findMany($query, ['search' => $search], 25, $append_url);
|
||||||
run_hook('view_list_billing'); #HOOK
|
run_hook('view_list_billing'); #HOOK
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
$ui->display('plan.tpl');
|
$ui->display('admin/plan/active.tpl');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,12 @@ if (file_exists($cache) && time() - filemtime($cache) < (24 * 60 * 60)) {
|
||||||
}
|
}
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'refresh':
|
case 'refresh':
|
||||||
if (file_exists($cache)) unlink($cache);
|
if (file_exists($cache))
|
||||||
|
unlink($cache);
|
||||||
r2(getUrl('pluginmanager'), 's', 'Refresh success');
|
r2(getUrl('pluginmanager'), 's', 'Refresh success');
|
||||||
break;
|
break;
|
||||||
case 'dlinstall':
|
case 'dlinstall':
|
||||||
if ($_app_stage == 'demo') {
|
if ($_app_stage == 'Demo') {
|
||||||
r2(getUrl('pluginmanager'), 'e', 'Demo Mode cannot install as it Security risk');
|
r2(getUrl('pluginmanager'), 'e', 'Demo Mode cannot install as it Security risk');
|
||||||
}
|
}
|
||||||
if (!is_writeable($CACHE_PATH)) {
|
if (!is_writeable($CACHE_PATH)) {
|
||||||
|
@ -161,6 +162,9 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('pluginmanager'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
if (!is_writeable($CACHE_PATH)) {
|
if (!is_writeable($CACHE_PATH)) {
|
||||||
r2(getUrl('pluginmanager'), 'e', 'Folder cache/ is not writable');
|
r2(getUrl('pluginmanager'), 'e', 'Folder cache/ is not writable');
|
||||||
}
|
}
|
||||||
|
@ -171,7 +175,8 @@ switch ($action) {
|
||||||
$tipe = $routes['2'];
|
$tipe = $routes['2'];
|
||||||
$plugin = $routes['3'];
|
$plugin = $routes['3'];
|
||||||
$file = $CACHE_PATH . DIRECTORY_SEPARATOR . $plugin . '.zip';
|
$file = $CACHE_PATH . DIRECTORY_SEPARATOR . $plugin . '.zip';
|
||||||
if (file_exists($file)) unlink($file);
|
if (file_exists($file))
|
||||||
|
unlink($file);
|
||||||
if ($tipe == 'plugin') {
|
if ($tipe == 'plugin') {
|
||||||
foreach ($json['plugins'] as $plg) {
|
foreach ($json['plugins'] as $plg) {
|
||||||
if ($plg['id'] == $plugin) {
|
if ($plg['id'] == $plugin) {
|
||||||
|
@ -212,6 +217,9 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'install':
|
case 'install':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('pluginmanager'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
if (!is_writeable($CACHE_PATH)) {
|
if (!is_writeable($CACHE_PATH)) {
|
||||||
r2(getUrl('pluginmanager'), 'e', 'Folder cache/ is not writable');
|
r2(getUrl('pluginmanager'), 'e', 'Folder cache/ is not writable');
|
||||||
}
|
}
|
||||||
|
@ -222,7 +230,8 @@ switch ($action) {
|
||||||
$tipe = $routes['2'];
|
$tipe = $routes['2'];
|
||||||
$plugin = $routes['3'];
|
$plugin = $routes['3'];
|
||||||
$file = $CACHE_PATH . DIRECTORY_SEPARATOR . $plugin . '.zip';
|
$file = $CACHE_PATH . DIRECTORY_SEPARATOR . $plugin . '.zip';
|
||||||
if (file_exists($file)) unlink($file);
|
if (file_exists($file))
|
||||||
|
unlink($file);
|
||||||
if ($tipe == 'plugin') {
|
if ($tipe == 'plugin') {
|
||||||
foreach ($json['plugins'] as $plg) {
|
foreach ($json['plugins'] as $plg) {
|
||||||
if ($plg['id'] == $plugin) {
|
if ($plg['id'] == $plugin) {
|
||||||
|
@ -345,7 +354,7 @@ switch ($action) {
|
||||||
$ui->assign('plugins', $json['plugins']);
|
$ui->assign('plugins', $json['plugins']);
|
||||||
$ui->assign('pgs', $json['payment_gateway']);
|
$ui->assign('pgs', $json['payment_gateway']);
|
||||||
$ui->assign('dvcs', $json['devices']);
|
$ui->assign('dvcs', $json['devices']);
|
||||||
$ui->display('plugin-manager.tpl');
|
$ui->display('admin/settings/plugin-manager.tpl');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ require_once $DEVICE_PATH . DIRECTORY_SEPARATOR . 'MikrotikPppoe' . '.php';
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'list':
|
case 'list':
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/pool.js"></script>');
|
|
||||||
|
|
||||||
$name = _post('name');
|
$name = _post('name');
|
||||||
if ($name != '') {
|
if ($name != '') {
|
||||||
|
@ -33,14 +32,14 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_pool'); #HOOK
|
run_hook('view_pool'); #HOOK
|
||||||
$ui->display('pool.tpl');
|
$ui->display('admin/pool/list.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'add':
|
case 'add':
|
||||||
$r = ORM::for_table('tbl_routers')->find_many();
|
$r = ORM::for_table('tbl_routers')->find_many();
|
||||||
$ui->assign('r', $r);
|
$ui->assign('r', $r);
|
||||||
run_hook('view_add_pool'); #HOOK
|
run_hook('view_add_pool'); #HOOK
|
||||||
$ui->display('pool-add.tpl');
|
$ui->display('admin/pool/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
@ -49,7 +48,7 @@ switch ($action) {
|
||||||
if ($d) {
|
if ($d) {
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_edit_pool'); #HOOK
|
run_hook('view_edit_pool'); #HOOK
|
||||||
$ui->display('pool-edit.tpl');
|
$ui->display('admin/pool/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('pool/list'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('pool/list'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -149,7 +148,6 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'port':
|
case 'port':
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/pool.js"></script>');
|
|
||||||
|
|
||||||
$name = _post('name');
|
$name = _post('name');
|
||||||
if ($name != '') {
|
if ($name != '') {
|
||||||
|
@ -162,14 +160,14 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_port'); #HOOK
|
run_hook('view_port'); #HOOK
|
||||||
$ui->display('port.tpl');
|
$ui->display('admin/port/list.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'add-port':
|
case 'add-port':
|
||||||
$r = ORM::for_table('tbl_routers')->find_many();
|
$r = ORM::for_table('tbl_routers')->find_many();
|
||||||
$ui->assign('r', $r);
|
$ui->assign('r', $r);
|
||||||
run_hook('view_add_port'); #HOOK
|
run_hook('view_add_port'); #HOOK
|
||||||
$ui->display('port-add.tpl');
|
$ui->display('admin/port/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit-port':
|
case 'edit-port':
|
||||||
|
@ -178,7 +176,7 @@ switch ($action) {
|
||||||
if ($d) {
|
if ($d) {
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_edit_port'); #HOOK
|
run_hook('view_edit_port'); #HOOK
|
||||||
$ui->display('port-edit.tpl');
|
$ui->display('admin/port/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('pool/port'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('pool/port'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ switch ($action) {
|
||||||
$ui->assign('_system_menu', 'radius');
|
$ui->assign('_system_menu', 'radius');
|
||||||
$ui->assign('_title', "Network Access Server");
|
$ui->assign('_title', "Network Access Server");
|
||||||
$ui->assign('routers', ORM::for_table('tbl_routers')->find_many());
|
$ui->assign('routers', ORM::for_table('tbl_routers')->find_many());
|
||||||
$ui->display('radius-nas-add.tpl');
|
$ui->display('admin/radius/nas-add.tpl');
|
||||||
break;
|
break;
|
||||||
case 'nas-add-post':
|
case 'nas-add-post':
|
||||||
$shortname = _post('shortname');
|
$shortname = _post('shortname');
|
||||||
|
@ -78,7 +78,7 @@ switch ($action) {
|
||||||
if ($d) {
|
if ($d) {
|
||||||
$ui->assign('routers', ORM::for_table('tbl_routers')->find_many());
|
$ui->assign('routers', ORM::for_table('tbl_routers')->find_many());
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
$ui->display('radius-nas-edit.tpl');
|
$ui->display('admin/radius/nas-edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('radius/list'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('radius/list'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -147,5 +147,5 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('name', $name);
|
$ui->assign('name', $name);
|
||||||
$ui->assign('nas', $nas);
|
$ui->assign('nas', $nas);
|
||||||
$ui->display('radius-nas.tpl');
|
$ui->display('admin/radius/nas.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,8 @@ switch ($do) {
|
||||||
$d->save();
|
$d->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (file_exists($_FILES['photo']['tmp_name'])) unlink($_FILES['photo']['tmp_name']);
|
if (file_exists($_FILES['photo']['tmp_name']))
|
||||||
|
unlink($_FILES['photo']['tmp_name']);
|
||||||
User::setFormCustomField($user);
|
User::setFormCustomField($user);
|
||||||
run_hook('register_user'); #HOOK
|
run_hook('register_user'); #HOOK
|
||||||
$msg .= Lang::T('Registration successful') . '<br>';
|
$msg .= Lang::T('Registration successful') . '<br>';
|
||||||
|
@ -147,8 +148,45 @@ switch ($do) {
|
||||||
// Display register-otp.tpl if OTP is enabled
|
// Display register-otp.tpl if OTP is enabled
|
||||||
$ui->display('customer/register-otp.tpl');
|
$ui->display('customer/register-otp.tpl');
|
||||||
} else {
|
} else {
|
||||||
// Display register.tpl if OTP is not enabled
|
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||||
|
if (!empty($config['login_page_logo']) && file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_logo'])) {
|
||||||
|
$login_logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_logo'];
|
||||||
|
} elseif (file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'login-logo.png')) {
|
||||||
|
$login_logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'login-logo.png';
|
||||||
|
} else {
|
||||||
|
$login_logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'login-logo.default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($config['login_page_wallpaper']) && file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_wallpaper'])) {
|
||||||
|
$wallpaper = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_wallpaper'];
|
||||||
|
} elseif (file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'wallpaper.png')) {
|
||||||
|
$wallpaper = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'wallpaper.png';
|
||||||
|
} else {
|
||||||
|
$wallpaper = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'wallpaper.default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($config['login_page_favicon']) && file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_favicon'])) {
|
||||||
|
$favicon = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_favicon'];
|
||||||
|
} elseif (file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'favicon.png')) {
|
||||||
|
$favicon = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'favicon.png';
|
||||||
|
} else {
|
||||||
|
$favicon = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'favicon.default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('login_logo', $login_logo);
|
||||||
|
$ui->assign('wallpaper', $wallpaper);
|
||||||
|
$ui->assign('favicon', $favicon);
|
||||||
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
|
$ui->assign('_title', Lang::T('Login'));
|
||||||
|
$ui->assign('customFields', User::getFormCustomField($ui, true));
|
||||||
|
switch ($config['login_page_type']) {
|
||||||
|
case 'custom':
|
||||||
|
$ui->display('customer/reg-login-custom-' . $config['login_Page_template'] . '.tpl');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
$ui->display('customer/register.tpl');
|
$ui->display('customer/register.tpl');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -196,6 +234,36 @@ switch ($do) {
|
||||||
$ui->display('customer/register-rotp.tpl');
|
$ui->display('customer/register-rotp.tpl');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||||
|
if (!empty($config['login_page_logo']) && file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_logo'])) {
|
||||||
|
$login_logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_logo'];
|
||||||
|
} elseif (file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'login-logo.png')) {
|
||||||
|
$login_logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'login-logo.png';
|
||||||
|
} else {
|
||||||
|
$login_logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'login-logo.default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($config['login_page_wallpaper']) && file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_wallpaper'])) {
|
||||||
|
$wallpaper = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_wallpaper'];
|
||||||
|
} elseif (file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'wallpaper.png')) {
|
||||||
|
$wallpaper = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'wallpaper.png';
|
||||||
|
} else {
|
||||||
|
$wallpaper = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'wallpaper.default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($config['login_page_favicon']) && file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_favicon'])) {
|
||||||
|
$favicon = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . $config['login_page_favicon'];
|
||||||
|
} elseif (file_exists($UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'favicon.png')) {
|
||||||
|
$favicon = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'favicon.png';
|
||||||
|
} else {
|
||||||
|
$favicon = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'favicon.default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('login_logo', $login_logo);
|
||||||
|
$ui->assign('wallpaper', $wallpaper);
|
||||||
|
$ui->assign('favicon', $favicon);
|
||||||
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
|
$ui->assign('_title', Lang::T('Login'));
|
||||||
$ui->assign('customFields', User::getFormCustomField($ui, true));
|
$ui->assign('customFields', User::getFormCustomField($ui, true));
|
||||||
$ui->assign('username', "");
|
$ui->assign('username', "");
|
||||||
$ui->assign('fullname', "");
|
$ui->assign('fullname', "");
|
||||||
|
@ -204,7 +272,15 @@ switch ($do) {
|
||||||
$ui->assign('otp', false);
|
$ui->assign('otp', false);
|
||||||
$ui->assign('_title', Lang::T('Register'));
|
$ui->assign('_title', Lang::T('Register'));
|
||||||
run_hook('view_register'); #HOOK
|
run_hook('view_register'); #HOOK
|
||||||
|
switch ($config['login_page_type']) {
|
||||||
|
case 'custom':
|
||||||
|
$ui->display('customer/reg-login-custom-' . $config['login_Page_template'] . '.tpl');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
$ui->display('customer/register.tpl');
|
$ui->display('customer/register.tpl');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,13 @@ switch ($action) {
|
||||||
->where('type', $tp);
|
->where('type', $tp);
|
||||||
if (count($mts) > 0) {
|
if (count($mts) > 0) {
|
||||||
if (count($mts) != count($methods)) {
|
if (count($mts) != count($methods)) {
|
||||||
|
$w = [];
|
||||||
|
$v = [];
|
||||||
foreach ($mts as $mt) {
|
foreach ($mts as $mt) {
|
||||||
$query->where_like('method', "$mt - %");
|
$w[] ='method';
|
||||||
|
$v[] = "$mt - %";
|
||||||
}
|
}
|
||||||
|
$query->where_likes($w, $v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($rts) > 0) {
|
if (count($rts) > 0) {
|
||||||
|
@ -84,9 +88,13 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
if (count($mts) > 0) {
|
if (count($mts) > 0) {
|
||||||
if (count($mts) != count($methods)) {
|
if (count($mts) != count($methods)) {
|
||||||
|
$w = [];
|
||||||
|
$v = [];
|
||||||
foreach ($mts as $mt) {
|
foreach ($mts as $mt) {
|
||||||
$query->where_like('method', "$mt - %");
|
$w[] ='method';
|
||||||
|
$v[] = "$mt - %";
|
||||||
}
|
}
|
||||||
|
$query->where_likes($w, $v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($rts) > 0) {
|
if (count($rts) > 0) {
|
||||||
|
@ -114,13 +122,6 @@ switch ($action) {
|
||||||
if (count($plns) > 0) {
|
if (count($plns) > 0) {
|
||||||
$query->where_in('plan_name', $plns);
|
$query->where_in('plan_name', $plns);
|
||||||
}
|
}
|
||||||
if (count($mts) > 0) {
|
|
||||||
if (count($mts) != count($methods)) {
|
|
||||||
foreach ($mts as $mt) {
|
|
||||||
$query->where_like('method', "$mt - %");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$count = $query->count();
|
$count = $query->count();
|
||||||
if ($count > 0) {
|
if ($count > 0) {
|
||||||
$result['datas'][] = $count;
|
$result['datas'][] = $count;
|
||||||
|
@ -157,9 +158,13 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
if (count($mts) > 0) {
|
if (count($mts) > 0) {
|
||||||
if (count($mts) != count($methods)) {
|
if (count($mts) != count($methods)) {
|
||||||
|
$w = [];
|
||||||
|
$v = [];
|
||||||
foreach ($mts as $mt) {
|
foreach ($mts as $mt) {
|
||||||
$query->where_like('method', "$mt - %");
|
$w[] ='method';
|
||||||
|
$v[] = "$mt - %";
|
||||||
}
|
}
|
||||||
|
$query->where_likes($w, $v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($rts) > 0) {
|
if (count($rts) > 0) {
|
||||||
|
@ -269,7 +274,7 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('activation', $d);
|
$ui->assign('activation', $d);
|
||||||
$ui->assign('q', $q);
|
$ui->assign('q', $q);
|
||||||
$ui->display('reports-activation.tpl');
|
$ui->display('admin/reports/activation.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'by-period':
|
case 'by-period':
|
||||||
|
@ -277,7 +282,7 @@ switch ($action) {
|
||||||
$ui->assign('mtime', $mtime);
|
$ui->assign('mtime', $mtime);
|
||||||
$ui->assign('tdate', $tdate);
|
$ui->assign('tdate', $tdate);
|
||||||
run_hook('view_reports_by_period'); #HOOK
|
run_hook('view_reports_by_period'); #HOOK
|
||||||
$ui->display('reports-period.tpl');
|
$ui->display('admin/reports/period.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'period-view':
|
case 'period-view':
|
||||||
|
@ -310,7 +315,7 @@ switch ($action) {
|
||||||
$ui->assign('tdate', $tdate);
|
$ui->assign('tdate', $tdate);
|
||||||
$ui->assign('stype', $stype);
|
$ui->assign('stype', $stype);
|
||||||
run_hook('view_reports_period'); #HOOK
|
run_hook('view_reports_period'); #HOOK
|
||||||
$ui->display('reports-period-view.tpl');
|
$ui->display('admin/reports/period-view.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'daily-report':
|
case 'daily-report':
|
||||||
|
@ -348,11 +353,13 @@ switch ($action) {
|
||||||
$query->where_in('type', $tps);
|
$query->where_in('type', $tps);
|
||||||
}
|
}
|
||||||
if (count($mts) > 0) {
|
if (count($mts) > 0) {
|
||||||
if (count($mts) != count($methods)) {
|
$w = [];
|
||||||
|
$v = [];
|
||||||
foreach ($mts as $mt) {
|
foreach ($mts as $mt) {
|
||||||
$query->where_like('method', "$mt - %");
|
$w[] ='method';
|
||||||
}
|
$v[] = "$mt - %";
|
||||||
}
|
}
|
||||||
|
$query->where_likes($w, $v);
|
||||||
}
|
}
|
||||||
if (count($rts) > 0) {
|
if (count($rts) > 0) {
|
||||||
$query->where_in('routers', $rts);
|
$query->where_in('routers', $rts);
|
||||||
|
@ -384,6 +391,6 @@ switch ($action) {
|
||||||
$ui->assign('dr', $dr);
|
$ui->assign('dr', $dr);
|
||||||
$ui->assign('mdate', $mdate);
|
$ui->assign('mdate', $mdate);
|
||||||
run_hook('view_daily_reports'); #HOOK
|
run_hook('view_daily_reports'); #HOOK
|
||||||
$ui->display('reports.tpl');
|
$ui->display('admin/reports/list.tpl');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,24 +23,9 @@ $leafletpickerHeader = <<<EOT
|
||||||
EOT;
|
EOT;
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'maps':
|
|
||||||
$name = _post('name');
|
|
||||||
$query = ORM::for_table('tbl_routers')->where_not_equal('coordinates', '')->order_by_desc('id');
|
|
||||||
$query->selects(['id', 'name', 'coordinates', 'description', 'coverage', 'enabled']);
|
|
||||||
if ($name != '') {
|
|
||||||
$query->where_like('name', '%' . $name . '%');
|
|
||||||
}
|
|
||||||
$d = Paginator::findMany($query, ['name' => $name], '20', '', true);
|
|
||||||
$ui->assign('name', $name);
|
|
||||||
$ui->assign('d', $d);
|
|
||||||
$ui->assign('_title', Lang::T('Routers Geo Location Information'));
|
|
||||||
$ui->assign('xheader', $leafletpickerHeader);
|
|
||||||
$ui->assign('xfooter', '<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>');
|
|
||||||
$ui->display('routers-maps.tpl');
|
|
||||||
break;
|
|
||||||
case 'add':
|
case 'add':
|
||||||
run_hook('view_add_routers'); #HOOK
|
run_hook('view_add_routers'); #HOOK
|
||||||
$ui->display('routers-add.tpl');
|
$ui->display('admin/routers/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
@ -53,7 +38,7 @@ switch ($action) {
|
||||||
if ($d) {
|
if ($d) {
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_router_edit'); #HOOK
|
run_hook('view_router_edit'); #HOOK
|
||||||
$ui->display('routers-edit.tpl');
|
$ui->display('admin/routers/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('routers/list'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('routers/list'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -204,7 +189,6 @@ switch ($action) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/routers.js"></script>');
|
|
||||||
|
|
||||||
$name = _post('name');
|
$name = _post('name');
|
||||||
$name = _post('name');
|
$name = _post('name');
|
||||||
|
@ -215,6 +199,6 @@ switch ($action) {
|
||||||
$d = Paginator::findMany($query, ['name' => $name]);
|
$d = Paginator::findMany($query, ['name' => $name]);
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_list_routers'); #HOOK
|
run_hook('view_list_routers'); #HOOK
|
||||||
$ui->display('routers.tpl');
|
$ui->display('admin/routers/list.tpl');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
r2(getUrl('services/hotspot'), 'w', 'Unknown command');
|
r2(getUrl('services/hotspot'), 'w', 'Unknown command');
|
||||||
case 'hotspot':
|
case 'hotspot':
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/hotspot.js"></script>');
|
|
||||||
$name = _req('name');
|
$name = _req('name');
|
||||||
$type1 = _req('type1');
|
$type1 = _req('type1');
|
||||||
$type2 = _req('type2');
|
$type2 = _req('type2');
|
||||||
|
@ -139,7 +138,7 @@ switch ($action) {
|
||||||
$d = Paginator::findMany($query, ['name' => $name], 20, $append_url);
|
$d = Paginator::findMany($query, ['name' => $name], 20, $append_url);
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_list_plans'); #HOOK
|
run_hook('view_list_plans'); #HOOK
|
||||||
$ui->display('hotspot.tpl');
|
$ui->display('admin/hotspot/list.tpl');
|
||||||
break;
|
break;
|
||||||
case 'add':
|
case 'add':
|
||||||
$d = ORM::for_table('tbl_bandwidth')->find_many();
|
$d = ORM::for_table('tbl_bandwidth')->find_many();
|
||||||
|
@ -156,7 +155,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('devices', $devices);
|
$ui->assign('devices', $devices);
|
||||||
run_hook('view_add_plan'); #HOOK
|
run_hook('view_add_plan'); #HOOK
|
||||||
$ui->display('hotspot-add.tpl');
|
$ui->display('admin/hotspot/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
@ -191,7 +190,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('exps', $exps);
|
$ui->assign('exps', $exps);
|
||||||
run_hook('view_edit_plan'); #HOOK
|
run_hook('view_edit_plan'); #HOOK
|
||||||
$ui->display('hotspot-edit.tpl');
|
$ui->display('admin/hotspot/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('services/hotspot'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('services/hotspot'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -428,7 +427,6 @@ switch ($action) {
|
||||||
|
|
||||||
case 'pppoe':
|
case 'pppoe':
|
||||||
$ui->assign('_title', Lang::T('PPPOE Plans'));
|
$ui->assign('_title', Lang::T('PPPOE Plans'));
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/pppoe.js"></script>');
|
|
||||||
|
|
||||||
$name = _post('name');
|
$name = _post('name');
|
||||||
$name = _req('name');
|
$name = _req('name');
|
||||||
|
@ -516,7 +514,7 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_list_ppoe'); #HOOK
|
run_hook('view_list_ppoe'); #HOOK
|
||||||
$ui->display('pppoe.tpl');
|
$ui->display('admin/pppoe/list.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'pppoe-add':
|
case 'pppoe-add':
|
||||||
|
@ -535,7 +533,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('devices', $devices);
|
$ui->assign('devices', $devices);
|
||||||
run_hook('view_add_ppoe'); #HOOK
|
run_hook('view_add_ppoe'); #HOOK
|
||||||
$ui->display('pppoe-add.tpl');
|
$ui->display('admin/pppoe/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'pppoe-edit':
|
case 'pppoe-edit':
|
||||||
|
@ -578,7 +576,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('exps', $exps);
|
$ui->assign('exps', $exps);
|
||||||
run_hook('view_edit_ppoe'); #HOOK
|
run_hook('view_edit_ppoe'); #HOOK
|
||||||
$ui->display('pppoe-edit.tpl');
|
$ui->display('admin/pppoe/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('services/pppoe'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('services/pppoe'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -819,12 +817,12 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_list_balance'); #HOOK
|
run_hook('view_list_balance'); #HOOK
|
||||||
$ui->display('balance.tpl');
|
$ui->display('admin/balance/list.tpl');
|
||||||
break;
|
break;
|
||||||
case 'balance-add':
|
case 'balance-add':
|
||||||
$ui->assign('_title', Lang::T('Balance Plans'));
|
$ui->assign('_title', Lang::T('Balance Plans'));
|
||||||
run_hook('view_add_balance'); #HOOK
|
run_hook('view_add_balance'); #HOOK
|
||||||
$ui->display('balance-add.tpl');
|
$ui->display('admin/balance/add.tpl');
|
||||||
break;
|
break;
|
||||||
case 'balance-edit':
|
case 'balance-edit':
|
||||||
$ui->assign('_title', Lang::T('Balance Plans'));
|
$ui->assign('_title', Lang::T('Balance Plans'));
|
||||||
|
@ -832,7 +830,7 @@ switch ($action) {
|
||||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_edit_balance'); #HOOK
|
run_hook('view_edit_balance'); #HOOK
|
||||||
$ui->display('balance-edit.tpl');
|
$ui->display('admin/balance/edit.tpl');
|
||||||
break;
|
break;
|
||||||
case 'balance-delete':
|
case 'balance-delete':
|
||||||
$id = $routes['2'];
|
$id = $routes['2'];
|
||||||
|
@ -921,7 +919,6 @@ switch ($action) {
|
||||||
break;
|
break;
|
||||||
case 'vpn':
|
case 'vpn':
|
||||||
$ui->assign('_title', Lang::T('VPN Plans'));
|
$ui->assign('_title', Lang::T('VPN Plans'));
|
||||||
$ui->assign('xfooter', '<script type="text/javascript" src="'.APP_URL.'/ui/lib/c/pppoe.js"></script>');
|
|
||||||
|
|
||||||
$name = _post('name');
|
$name = _post('name');
|
||||||
$name = _req('name');
|
$name = _req('name');
|
||||||
|
@ -1009,7 +1006,7 @@ switch ($action) {
|
||||||
|
|
||||||
$ui->assign('d', $d);
|
$ui->assign('d', $d);
|
||||||
run_hook('view_list_vpn'); #HOOK
|
run_hook('view_list_vpn'); #HOOK
|
||||||
$ui->display('vpn.tpl');
|
$ui->display('admin/vpn/list.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'vpn-add':
|
case 'vpn-add':
|
||||||
|
@ -1028,7 +1025,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('devices', $devices);
|
$ui->assign('devices', $devices);
|
||||||
run_hook('view_add_vpn'); #HOOK
|
run_hook('view_add_vpn'); #HOOK
|
||||||
$ui->display('vpn-add.tpl');
|
$ui->display('admin/vpn/add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'vpn-edit':
|
case 'vpn-edit':
|
||||||
|
@ -1071,7 +1068,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('exps', $exps);
|
$ui->assign('exps', $exps);
|
||||||
run_hook('view_edit_vpn'); #HOOK
|
run_hook('view_edit_vpn'); #HOOK
|
||||||
$ui->display('vpn-edit.tpl');
|
$ui->display('admin/vpn/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('services/vpn'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('services/vpn'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -1300,5 +1297,5 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ switch ($action) {
|
||||||
$d->value = 'yes';
|
$d->value = 'yes';
|
||||||
$d->save();
|
$d->save();
|
||||||
}
|
}
|
||||||
r2('./docs');
|
r2(APP_URL . '/docs');
|
||||||
break;
|
break;
|
||||||
case 'devices':
|
case 'devices':
|
||||||
$files = scandir($DEVICE_PATH);
|
$files = scandir($DEVICE_PATH);
|
||||||
|
@ -50,7 +50,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$ui->assign('devices', $devices);
|
$ui->assign('devices', $devices);
|
||||||
$ui->display('app-devices.tpl');
|
$ui->display('admin/settings/devices.tpl');
|
||||||
break;
|
break;
|
||||||
case 'app':
|
case 'app':
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
|
@ -58,18 +58,30 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(_get('testWa'))) {
|
if (!empty(_get('testWa'))) {
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/app'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$result = Message::sendWhatsapp(_get('testWa'), 'PHPNuxBill Test Whatsapp');
|
$result = Message::sendWhatsapp(_get('testWa'), 'PHPNuxBill Test Whatsapp');
|
||||||
r2(getUrl('settings/app'), 's', 'Test Whatsapp has been send<br>Result: ' . $result);
|
r2(getUrl('settings/app'), 's', 'Test Whatsapp has been send<br>Result: ' . $result);
|
||||||
}
|
}
|
||||||
if (!empty(_get('testSms'))) {
|
if (!empty(_get('testSms'))) {
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/app'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$result = Message::sendSMS(_get('testSms'), 'PHPNuxBill Test SMS');
|
$result = Message::sendSMS(_get('testSms'), 'PHPNuxBill Test SMS');
|
||||||
r2(getUrl('settings/app'), 's', 'Test SMS has been send<br>Result: ' . $result);
|
r2(getUrl('settings/app'), 's', 'Test SMS has been send<br>Result: ' . $result);
|
||||||
}
|
}
|
||||||
if (!empty(_get('testEmail'))) {
|
if (!empty(_get('testEmail'))) {
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/app'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
Message::sendEmail(_get('testEmail'), 'PHPNuxBill Test Email', 'PHPNuxBill Test Email Body');
|
Message::sendEmail(_get('testEmail'), 'PHPNuxBill Test Email', 'PHPNuxBill Test Email Body');
|
||||||
r2(getUrl('settings/app'), 's', 'Test Email has been send');
|
r2(getUrl('settings/app'), 's', 'Test Email has been send');
|
||||||
}
|
}
|
||||||
if (!empty(_get('testTg'))) {
|
if (!empty(_get('testTg'))) {
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/app'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$result = Message::sendTelegram('PHPNuxBill Test Telegram');
|
$result = Message::sendTelegram('PHPNuxBill Test Telegram');
|
||||||
r2(getUrl('settings/app'), 's', 'Test Telegram has been send<br>Result: ' . $result);
|
r2(getUrl('settings/app'), 's', 'Test Telegram has been send<br>Result: ' . $result);
|
||||||
}
|
}
|
||||||
|
@ -165,10 +177,15 @@ switch ($action) {
|
||||||
run_hook('view_app_settings'); #HOOK
|
run_hook('view_app_settings'); #HOOK
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('app-settings.tpl');
|
$ui->display('admin/settings/app.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'app-post':
|
case 'app-post':
|
||||||
|
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/app'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
|
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
@ -186,9 +203,11 @@ switch ($action) {
|
||||||
run_hook('save_settings'); #HOOK
|
run_hook('save_settings'); #HOOK
|
||||||
if (!empty($_FILES['logo']['name'])) {
|
if (!empty($_FILES['logo']['name'])) {
|
||||||
if (function_exists('imagecreatetruecolor')) {
|
if (function_exists('imagecreatetruecolor')) {
|
||||||
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png')) unlink($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png');
|
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png'))
|
||||||
|
unlink($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png');
|
||||||
File::resizeCropImage($_FILES['logo']['tmp_name'], $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png', 1078, 200, 100);
|
File::resizeCropImage($_FILES['logo']['tmp_name'], $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png', 1078, 200, 100);
|
||||||
if (file_exists($_FILES['logo']['tmp_name'])) unlink($_FILES['logo']['tmp_name']);
|
if (file_exists($_FILES['logo']['tmp_name']))
|
||||||
|
unlink($_FILES['logo']['tmp_name']);
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/app'), 'e', 'PHP GD is not installed');
|
r2(getUrl('settings/app'), 'e', 'PHP GD is not installed');
|
||||||
}
|
}
|
||||||
|
@ -205,7 +224,7 @@ switch ($action) {
|
||||||
$ui->assign("error_message", "Radius table not found.<br><br>" .
|
$ui->assign("error_message", "Radius table not found.<br><br>" .
|
||||||
$e->getMessage() .
|
$e->getMessage() .
|
||||||
"<br><br>Download <a href=\"https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/Development/install/radius.sql\">here</a> or <a href=\"https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/master/install/radius.sql\">here</a> and import it to database.<br><br>Check config.php for radius connection details");
|
"<br><br>Download <a href=\"https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/Development/install/radius.sql\">here</a> or <a href=\"https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/master/install/radius.sql\">here</a> and import it to database.<br><br>Check config.php for radius connection details");
|
||||||
$ui->display('error.tpl');
|
$ui->display('admin/error.tpl');
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,25 +235,19 @@ switch ($action) {
|
||||||
$_POST['man_fields_custom'] = isset($_POST['man_fields_custom']) ? 'yes' : 'no';
|
$_POST['man_fields_custom'] = isset($_POST['man_fields_custom']) ? 'yes' : 'no';
|
||||||
$enable_session_timeout = isset($_POST['enable_session_timeout']) ? 1 : 0;
|
$enable_session_timeout = isset($_POST['enable_session_timeout']) ? 1 : 0;
|
||||||
$_POST['enable_session_timeout'] = $enable_session_timeout;
|
$_POST['enable_session_timeout'] = $enable_session_timeout;
|
||||||
foreach ($_POST as $key => $value) {
|
$_POST['notification_reminder_1day'] = isset($_POST['notification_reminder_1day']) ? 'yes' : 'no';
|
||||||
$d = ORM::for_table('tbl_appconfig')->where('setting', $key)->find_one();
|
$_POST['notification_reminder_3days'] = isset($_POST['notification_reminder_3days']) ? 'yes' : 'no';
|
||||||
if ($d) {
|
$_POST['notification_reminder_7days'] = isset($_POST['notification_reminder_7days']) ? 'yes' : 'no';
|
||||||
$d->value = $value;
|
|
||||||
$d->save();
|
|
||||||
} else {
|
|
||||||
$d = ORM::for_table('tbl_appconfig')->create();
|
|
||||||
$d->setting = $key;
|
|
||||||
$d->value = $value;
|
|
||||||
$d->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_log('[' . $admin['username'] . ']: ' . Lang::T('Settings Saved Successfully'), $admin['user_type'], $admin['id']);
|
|
||||||
|
|
||||||
r2(getUrl('settings/app'), 's', Lang::T('Settings Saved Successfully'));
|
// hide dashboard
|
||||||
}
|
$_POST['hide_mrc'] = _post('hide_mrc', 'no');
|
||||||
break;
|
$_POST['hide_tms'] = _post('hide_tms', 'no');
|
||||||
|
$_POST['hide_al'] = _post('hide_al', 'no');
|
||||||
|
$_POST['hide_uet'] = _post('hide_uet', 'no');
|
||||||
|
$_POST['hide_vs'] = _post('hide_vs', 'no');
|
||||||
|
$_POST['hide_pg'] = _post('hide_pg', 'no');
|
||||||
|
$_POST['hide_aui'] = _post('hide_aui', 'no');
|
||||||
|
|
||||||
case 'login-page-post':
|
|
||||||
// Login page post
|
// Login page post
|
||||||
$login_page_title = _post('login_page_head');
|
$login_page_title = _post('login_page_head');
|
||||||
$login_page_description = _post('login_page_description');
|
$login_page_description = _post('login_page_description');
|
||||||
|
@ -260,13 +273,6 @@ switch ($action) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$settings = [
|
|
||||||
'login_page_head' => $login_page_title,
|
|
||||||
'login_page_description' => $login_page_description,
|
|
||||||
'login_Page_template' => $login_Page_template,
|
|
||||||
'login_page_type' => $login_page_type,
|
|
||||||
];
|
|
||||||
|
|
||||||
$image_paths = [];
|
$image_paths = [];
|
||||||
$allowed_types = ['image/jpeg', 'image/png'];
|
$allowed_types = ['image/jpeg', 'image/png'];
|
||||||
|
|
||||||
|
@ -276,8 +282,9 @@ switch ($action) {
|
||||||
$extension = pathinfo($_FILES['login_page_favicon']['name'], PATHINFO_EXTENSION);
|
$extension = pathinfo($_FILES['login_page_favicon']['name'], PATHINFO_EXTENSION);
|
||||||
$favicon_path = $UPLOAD_PATH . DIRECTORY_SEPARATOR . uniqid('favicon_') . '.' . $extension;
|
$favicon_path = $UPLOAD_PATH . DIRECTORY_SEPARATOR . uniqid('favicon_') . '.' . $extension;
|
||||||
File::resizeCropImage($_FILES['login_page_favicon']['tmp_name'], $favicon_path, 16, 16, 100);
|
File::resizeCropImage($_FILES['login_page_favicon']['tmp_name'], $favicon_path, 16, 16, 100);
|
||||||
$settings['login_page_favicon'] = basename($favicon_path); // Save dynamic file name
|
$_POST['login_page_favicon'] = basename($favicon_path); // Save dynamic file name
|
||||||
if (file_exists($_FILES['login_page_favicon']['tmp_name'])) unlink($_FILES['login_page_favicon']['tmp_name']);
|
if (file_exists($_FILES['login_page_favicon']['tmp_name']))
|
||||||
|
unlink($_FILES['login_page_favicon']['tmp_name']);
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/app'), 'e', 'Favicon must be a JPG, JPEG, or PNG image.');
|
r2(getUrl('settings/app'), 'e', 'Favicon must be a JPG, JPEG, or PNG image.');
|
||||||
}
|
}
|
||||||
|
@ -289,8 +296,9 @@ switch ($action) {
|
||||||
$extension = pathinfo($_FILES['login_page_wallpaper']['name'], PATHINFO_EXTENSION);
|
$extension = pathinfo($_FILES['login_page_wallpaper']['name'], PATHINFO_EXTENSION);
|
||||||
$wallpaper_path = $UPLOAD_PATH . DIRECTORY_SEPARATOR . uniqid('wallpaper_') . '.' . $extension;
|
$wallpaper_path = $UPLOAD_PATH . DIRECTORY_SEPARATOR . uniqid('wallpaper_') . '.' . $extension;
|
||||||
File::resizeCropImage($_FILES['login_page_wallpaper']['tmp_name'], $wallpaper_path, 1920, 1080, 100);
|
File::resizeCropImage($_FILES['login_page_wallpaper']['tmp_name'], $wallpaper_path, 1920, 1080, 100);
|
||||||
$settings['login_page_wallpaper'] = basename($wallpaper_path); // Save dynamic file name
|
$_POST['login_page_wallpaper'] = basename($wallpaper_path); // Save dynamic file name
|
||||||
if (file_exists($_FILES['login_page_wallpaper']['tmp_name'])) unlink($_FILES['login_page_wallpaper']['tmp_name']);
|
if (file_exists($_FILES['login_page_wallpaper']['tmp_name']))
|
||||||
|
unlink($_FILES['login_page_wallpaper']['tmp_name']);
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/app'), 'e', 'Wallpaper must be a JPG, JPEG, or PNG image.');
|
r2(getUrl('settings/app'), 'e', 'Wallpaper must be a JPG, JPEG, or PNG image.');
|
||||||
}
|
}
|
||||||
|
@ -302,14 +310,14 @@ switch ($action) {
|
||||||
$extension = pathinfo($_FILES['login_page_logo']['name'], PATHINFO_EXTENSION);
|
$extension = pathinfo($_FILES['login_page_logo']['name'], PATHINFO_EXTENSION);
|
||||||
$logo_path = $UPLOAD_PATH . DIRECTORY_SEPARATOR . uniqid('logo_') . '.' . $extension;
|
$logo_path = $UPLOAD_PATH . DIRECTORY_SEPARATOR . uniqid('logo_') . '.' . $extension;
|
||||||
File::resizeCropImage($_FILES['login_page_logo']['tmp_name'], $logo_path, 300, 60, 100);
|
File::resizeCropImage($_FILES['login_page_logo']['tmp_name'], $logo_path, 300, 60, 100);
|
||||||
$settings['login_page_logo'] = basename($logo_path); // Save dynamic file name
|
$_POST['login_page_logo'] = basename($logo_path); // Save dynamic file name
|
||||||
if (file_exists($_FILES['login_page_logo']['tmp_name'])) unlink($_FILES['login_page_logo']['tmp_name']);
|
if (file_exists($_FILES['login_page_logo']['tmp_name']))
|
||||||
|
unlink($_FILES['login_page_logo']['tmp_name']);
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/app'), 'e', 'Logo must be a JPG, JPEG, or PNG image.');
|
r2(getUrl('settings/app'), 'e', 'Logo must be a JPG, JPEG, or PNG image.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach ($_POST as $key => $value) {
|
||||||
foreach ($settings as $key => $value) {
|
|
||||||
$d = ORM::for_table('tbl_appconfig')->where('setting', $key)->find_one();
|
$d = ORM::for_table('tbl_appconfig')->where('setting', $key)->find_one();
|
||||||
if ($d) {
|
if ($d) {
|
||||||
$d->value = $value;
|
$d->value = $value;
|
||||||
|
@ -321,9 +329,10 @@ switch ($action) {
|
||||||
$d->save();
|
$d->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_log('[' . $admin['username'] . ']: ' . Lang::T('Settings Saved Successfully'), $admin['user_type'], $admin['id']);
|
||||||
|
|
||||||
_log('[' . $admin['username'] . ']: ' . Lang::T('Login Page Settings Saved Successfully'), $admin['user_type'], $admin['id']);
|
r2(getUrl('settings/app'), 's', Lang::T('Settings Saved Successfully'));
|
||||||
r2(getUrl('settings/app'), 's', Lang::T('Login Page Settings Saved Successfully'));
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'localisation':
|
case 'localisation':
|
||||||
|
@ -352,16 +361,19 @@ switch ($action) {
|
||||||
run_hook('view_localisation'); #HOOK
|
run_hook('view_localisation'); #HOOK
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('app-localisation.tpl');
|
$ui->display('admin/settings/localisation.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'localisation-post':
|
case 'localisation-post':
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/localisation'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$csrf_token = _post('csrf_token');
|
$csrf_token = _post('csrf_token');
|
||||||
if (!Csrf::check($csrf_token)) {
|
if (!Csrf::check($csrf_token)) {
|
||||||
r2(getUrl('settings/app'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
r2(getUrl('settings/localisation'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
||||||
}
|
}
|
||||||
$tzone = _post('tzone');
|
$tzone = _post('tzone');
|
||||||
$date_format = _post('date_format');
|
$date_format = _post('date_format');
|
||||||
|
@ -369,7 +381,7 @@ switch ($action) {
|
||||||
$lan = _post('lan');
|
$lan = _post('lan');
|
||||||
run_hook('save_localisation'); #HOOK
|
run_hook('save_localisation'); #HOOK
|
||||||
if ($tzone == '' or $date_format == '' or $lan == '') {
|
if ($tzone == '' or $date_format == '' or $lan == '') {
|
||||||
r2(getUrl('settings/app'), 'e', Lang::T('All field is required'));
|
r2(getUrl('settings/localisation'), 'e', Lang::T('All field is required'));
|
||||||
} else {
|
} else {
|
||||||
$d = ORM::for_table('tbl_appconfig')->where('setting', 'timezone')->find_one();
|
$d = ORM::for_table('tbl_appconfig')->where('setting', 'timezone')->find_one();
|
||||||
$d->value = $tzone;
|
$d->value = $tzone;
|
||||||
|
@ -527,7 +539,7 @@ switch ($action) {
|
||||||
run_hook('view_list_admin'); #HOOK
|
run_hook('view_list_admin'); #HOOK
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('admin.tpl');
|
$ui->display('admin/admin/list.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'users-add':
|
case 'users-add':
|
||||||
|
@ -538,7 +550,7 @@ switch ($action) {
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->assign('_title', Lang::T('Add User'));
|
$ui->assign('_title', Lang::T('Add User'));
|
||||||
$ui->assign('agents', ORM::for_table('tbl_users')->where('user_type', 'Agent')->find_many());
|
$ui->assign('agents', ORM::for_table('tbl_users')->where('user_type', 'Agent')->find_many());
|
||||||
$ui->display('admin-add.tpl');
|
$ui->display('admin/admin/add.tpl');
|
||||||
break;
|
break;
|
||||||
case 'users-view':
|
case 'users-view':
|
||||||
$ui->assign('_title', Lang::T('Edit User'));
|
$ui->assign('_title', Lang::T('Edit User'));
|
||||||
|
@ -548,7 +560,7 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
//allow see himself
|
//allow see himself
|
||||||
if ($admin['id'] == $id) {
|
if ($admin['id'] == $id) {
|
||||||
$d = ORM::for_table('tbl_users')->where('id', $id)->find_array($id)[0];
|
$d = ORM::for_table('tbl_users')->where('id', $id)->find_array()[0];
|
||||||
} else {
|
} else {
|
||||||
if (in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
// Super Admin can see anyone
|
// Super Admin can see anyone
|
||||||
|
@ -567,7 +579,7 @@ switch ($action) {
|
||||||
$ui->assign('_title', $d['username']);
|
$ui->assign('_title', $d['username']);
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('admin-view.tpl');
|
$ui->display('admin/admin/view.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/users'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('settings/users'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -623,7 +635,7 @@ switch ($action) {
|
||||||
run_hook('view_edit_admin'); #HOOK
|
run_hook('view_edit_admin'); #HOOK
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('admin-edit.tpl');
|
$ui->display('admin/admin/edit.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/users'), 'e', Lang::T('Account Not Found'));
|
r2(getUrl('settings/users'), 'e', Lang::T('Account Not Found'));
|
||||||
}
|
}
|
||||||
|
@ -633,7 +645,9 @@ switch ($action) {
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/users'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$id = $routes['2'];
|
$id = $routes['2'];
|
||||||
if (($admin['id']) == $id) {
|
if (($admin['id']) == $id) {
|
||||||
r2(getUrl('settings/users'), 'e', 'Sorry You can\'t delete yourself');
|
r2(getUrl('settings/users'), 'e', 'Sorry You can\'t delete yourself');
|
||||||
|
@ -652,6 +666,9 @@ switch ($action) {
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/users-add'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$csrf_token = _post('csrf_token');
|
$csrf_token = _post('csrf_token');
|
||||||
if (!Csrf::check($csrf_token)) {
|
if (!Csrf::check($csrf_token)) {
|
||||||
r2(getUrl('settings/users-add'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
r2(getUrl('settings/users-add'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
||||||
|
@ -720,6 +737,9 @@ switch ($action) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'users-edit-post':
|
case 'users-edit-post':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/users-edit/'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$csrf_token = _post('csrf_token');
|
$csrf_token = _post('csrf_token');
|
||||||
if (!Csrf::check($csrf_token)) {
|
if (!Csrf::check($csrf_token)) {
|
||||||
r2(getUrl('settings/users-edit/'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
r2(getUrl('settings/users-edit/'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
||||||
|
@ -823,7 +843,8 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$d->photo = '/photos/' . $subfolder . '/' . $hash . '.jpg';
|
$d->photo = '/photos/' . $subfolder . '/' . $hash . '.jpg';
|
||||||
}
|
}
|
||||||
if (file_exists($_FILES['photo']['tmp_name'])) unlink($_FILES['photo']['tmp_name']);
|
if (file_exists($_FILES['photo']['tmp_name']))
|
||||||
|
unlink($_FILES['photo']['tmp_name']);
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/app'), 'e', 'PHP GD is not installed');
|
r2(getUrl('settings/app'), 'e', 'PHP GD is not installed');
|
||||||
}
|
}
|
||||||
|
@ -869,10 +890,13 @@ switch ($action) {
|
||||||
run_hook('view_change_password'); #HOOK
|
run_hook('view_change_password'); #HOOK
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('change-password.tpl');
|
$ui->display('admin/change-password.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'change-password-post':
|
case 'change-password-post':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/change-password'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$password = _post('password');
|
$password = _post('password');
|
||||||
$csrf_token = _post('csrf_token');
|
$csrf_token = _post('csrf_token');
|
||||||
if (!Csrf::check($csrf_token)) {
|
if (!Csrf::check($csrf_token)) {
|
||||||
|
@ -926,9 +950,12 @@ switch ($action) {
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->assign('_default', json_decode(file_get_contents($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'notifications.default.json'), true));
|
$ui->assign('_default', json_decode(file_get_contents($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'notifications.default.json'), true));
|
||||||
$ui->display('app-notifications.tpl');
|
$ui->display('admin/settings/notifications.tpl');
|
||||||
break;
|
break;
|
||||||
case 'notifications-post':
|
case 'notifications-post':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/notifications'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
@ -953,11 +980,14 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$ui->assign('tables', $tables);
|
$ui->assign('tables', $tables);
|
||||||
run_hook('view_database'); #HOOK
|
run_hook('view_database'); #HOOK
|
||||||
$ui->display('dbstatus.tpl');
|
$ui->display('admin/settings/dbstatus.tpl');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'dbbackup':
|
case 'dbbackup':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/dbstatus'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
@ -978,6 +1008,9 @@ switch ($action) {
|
||||||
echo json_encode($array);
|
echo json_encode($array);
|
||||||
break;
|
break;
|
||||||
case 'dbrestore':
|
case 'dbrestore':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/dbstatus'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
if (!in_array($admin['user_type'], ['SuperAdmin'])) {
|
if (!in_array($admin['user_type'], ['SuperAdmin'])) {
|
||||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||||
}
|
}
|
||||||
|
@ -1025,7 +1058,8 @@ switch ($action) {
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
}
|
}
|
||||||
if (file_exists($_FILES['json']['tmp_name'])) unlink($_FILES['json']['tmp_name']);
|
if (file_exists($_FILES['json']['tmp_name']))
|
||||||
|
unlink($_FILES['json']['tmp_name']);
|
||||||
r2(getUrl('settings/dbstatus'), 's', "Restored $suc success $fal failed");
|
r2(getUrl('settings/dbstatus'), 's', "Restored $suc success $fal failed");
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('settings/dbstatus'), 'e', 'Upload failed');
|
r2(getUrl('settings/dbstatus'), 'e', 'Upload failed');
|
||||||
|
@ -1043,10 +1077,13 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
$csrf_token = Csrf::generateAndStoreToken();
|
$csrf_token = Csrf::generateAndStoreToken();
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->display('language-add.tpl');
|
$ui->display('admin/settings/language-add.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'lang-post':
|
case 'lang-post':
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/dbstatus'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$csrf_token = _post('csrf_token');
|
$csrf_token = _post('csrf_token');
|
||||||
if (!Csrf::check($csrf_token)) {
|
if (!Csrf::check($csrf_token)) {
|
||||||
r2(getUrl('settings/language'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
r2(getUrl('settings/language'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
||||||
|
@ -1062,6 +1099,9 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_post('save') == 'save') {
|
if (_post('save') == 'save') {
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/maintenance'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$csrf_token = _post('csrf_token');
|
$csrf_token = _post('csrf_token');
|
||||||
if (!Csrf::check($csrf_token)) {
|
if (!Csrf::check($csrf_token)) {
|
||||||
r2(getUrl('settings/maintenance'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
r2(getUrl('settings/maintenance'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
||||||
|
@ -1095,7 +1135,7 @@ switch ($action) {
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->assign('_c', $config);
|
$ui->assign('_c', $config);
|
||||||
$ui->assign('_title', Lang::T('Maintenance Mode Settings'));
|
$ui->assign('_title', Lang::T('Maintenance Mode Settings'));
|
||||||
$ui->display('maintenance-mode.tpl');
|
$ui->display('admin/settings/maintenance-mode.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'miscellaneous':
|
case 'miscellaneous':
|
||||||
|
@ -1104,6 +1144,9 @@ switch ($action) {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
if (_post('save') == 'save') {
|
if (_post('save') == 'save') {
|
||||||
|
if ($_app_stage == 'Demo') {
|
||||||
|
r2(getUrl('settings/miscellaneous'), 'e', 'You cannot perform this action in Demo mode');
|
||||||
|
}
|
||||||
$csrf_token = _post('csrf_token');
|
$csrf_token = _post('csrf_token');
|
||||||
if (!Csrf::check($csrf_token)) {
|
if (!Csrf::check($csrf_token)) {
|
||||||
r2(getUrl('settings/miscellaneous'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
r2(getUrl('settings/miscellaneous'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
|
||||||
|
@ -1127,9 +1170,9 @@ switch ($action) {
|
||||||
$ui->assign('csrf_token', $csrf_token);
|
$ui->assign('csrf_token', $csrf_token);
|
||||||
$ui->assign('_c', $config);
|
$ui->assign('_c', $config);
|
||||||
$ui->assign('_title', Lang::T('Miscellaneous Settings'));
|
$ui->assign('_title', Lang::T('Miscellaneous Settings'));
|
||||||
$ui->display('app-miscellaneous.tpl');
|
$ui->display('admin/settings/miscellaneous.tpl');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,47 @@
|
||||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||||
* by https://t.me/ibnux
|
* by https://t.me/ibnux
|
||||||
**/
|
**/
|
||||||
_auth();
|
|
||||||
$ui->assign('_title', Lang::T('Voucher'));
|
$ui->assign('_title', Lang::T('Voucher'));
|
||||||
$ui->assign('_system_menu', 'voucher');
|
$ui->assign('_system_menu', 'voucher');
|
||||||
|
|
||||||
$action = $routes['1'];
|
$action = $routes['1'];
|
||||||
|
if(!_auth(false)){
|
||||||
|
if($action== 'invoice'){
|
||||||
|
$id = $routes[2];
|
||||||
|
$sign = $routes[3];
|
||||||
|
if($sign != md5($id. $db_pass)) {
|
||||||
|
die("beda");
|
||||||
|
}
|
||||||
|
if (empty($id)) {
|
||||||
|
$in = ORM::for_table('tbl_transactions')->order_by_desc('id')->find_one();
|
||||||
|
} else {
|
||||||
|
$in = ORM::for_table('tbl_transactions')->where('id', $id)->find_one();
|
||||||
|
}
|
||||||
|
if ($in) {
|
||||||
|
Package::createInvoice($in);
|
||||||
|
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||||
|
$logo = '';
|
||||||
|
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png')) {
|
||||||
|
$logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.png';
|
||||||
|
$imgsize = getimagesize($logo);
|
||||||
|
$width = $imgsize[0];
|
||||||
|
$height = $imgsize[1];
|
||||||
|
$ui->assign('wlogo', $width);
|
||||||
|
$ui->assign('hlogo', $height);
|
||||||
|
}
|
||||||
|
$ui->assign('public_url', getUrl("voucher/invoice/$id/".md5($id. $db_pass)));
|
||||||
|
$ui->assign('logo', $logo);
|
||||||
|
$ui->display('customer/invoice-customer.tpl');
|
||||||
|
die();
|
||||||
|
} else {
|
||||||
|
r2(getUrl('voucher/list-activated'), 'e', Lang::T('Not Found'));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
r2(getUrl('login'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$user = User::_info();
|
$user = User::_info();
|
||||||
$ui->assign('_user', $user);
|
$ui->assign('_user', $user);
|
||||||
|
|
||||||
|
@ -64,11 +100,23 @@ switch ($action) {
|
||||||
}
|
}
|
||||||
if ($in) {
|
if ($in) {
|
||||||
Package::createInvoice($in);
|
Package::createInvoice($in);
|
||||||
|
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||||
|
$logo = '';
|
||||||
|
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png')) {
|
||||||
|
$logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.png';
|
||||||
|
$imgsize = getimagesize($logo);
|
||||||
|
$width = $imgsize[0];
|
||||||
|
$height = $imgsize[1];
|
||||||
|
$ui->assign('wlogo', $width);
|
||||||
|
$ui->assign('hlogo', $height);
|
||||||
|
}
|
||||||
|
$ui->assign('public_url', getUrl("voucher/invoice/$id/".md5($id. $db_pass)));
|
||||||
|
$ui->assign('logo', $logo);
|
||||||
$ui->display('customer/invoice-customer.tpl');
|
$ui->display('customer/invoice-customer.tpl');
|
||||||
} else {
|
} else {
|
||||||
r2(getUrl('voucher/list-activated'), 'e', Lang::T('Not Found'));
|
r2(getUrl('voucher/list-activated'), 'e', Lang::T('Not Found'));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$ui->display('a404.tpl');
|
$ui->display('admin/404.tpl');
|
||||||
}
|
}
|
||||||
|
|
147
system/controllers/widgets.php
Normal file
147
system/controllers/widgets.php
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||||
|
* by https://t.me/ibnux
|
||||||
|
**/
|
||||||
|
_admin();
|
||||||
|
$ui->assign('_title', Lang::T('Dashboard Widgets'));
|
||||||
|
$ui->assign('_system_menu', 'settings');
|
||||||
|
|
||||||
|
$action = alphanumeric($routes['1']);
|
||||||
|
$ui->assign('_admin', $admin);
|
||||||
|
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||||
|
r2(getUrl('dashboard'), 'e', Lang::T('You do not have permission to access this page'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$tipeUser = _req("user");
|
||||||
|
if (empty($tipeUser)) {
|
||||||
|
$tipeUser = 'Admin';
|
||||||
|
}
|
||||||
|
if($tipeUser == 'Customer') {
|
||||||
|
$WIDGET_PATH .= DIRECTORY_SEPARATOR. 'customer';
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('tipeUser', $tipeUser);
|
||||||
|
$max = ORM::for_table('tbl_widgets')->where("user", $tipeUser)->max('position');
|
||||||
|
$max2 = substr_count($config['dashboard_' . $tipeUser], '.') + substr_count($config['dashboard_' . $tipeUser], ',') + 1;
|
||||||
|
if ($max2 > $max) {
|
||||||
|
$max = $max2;
|
||||||
|
}
|
||||||
|
$ui->assign('max', $max);
|
||||||
|
|
||||||
|
if ($action == 'add') {
|
||||||
|
$pos = alphanumeric($routes['2']);
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
$orders = alphanumeric($_POST['orders']);
|
||||||
|
$position = alphanumeric($_POST['position']);
|
||||||
|
$tipeUser = alphanumeric($_POST['tipeUser']);
|
||||||
|
$enabled = alphanumeric($_POST['enabled']);
|
||||||
|
$title = _post('title');
|
||||||
|
$widget = _post('widget');
|
||||||
|
|
||||||
|
$d = ORM::for_table('tbl_widgets')->create();
|
||||||
|
$d->orders = $orders;
|
||||||
|
$d->position = $position;
|
||||||
|
$d->user = $tipeUser;
|
||||||
|
$d->enabled = $enabled;
|
||||||
|
$d->title = $title;
|
||||||
|
$d->widget = $widget;
|
||||||
|
$d->content = _post('content');
|
||||||
|
$d->save();
|
||||||
|
if ($d->id() > 0) {
|
||||||
|
r2(getUrl('widgets&user=' . $tipeUser), 's', 'Widget Added Successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$files = scandir($WIDGET_PATH);
|
||||||
|
$widgets = [];
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (strpos($file, '.php') !== false) {
|
||||||
|
$name = ucwords(str_replace('.php', '', str_replace('_', ' ', $file)));
|
||||||
|
$widgets[str_replace('.php', '', $file)] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$widget['position'] = $pos;
|
||||||
|
$widget['user'] = $tipeUser;
|
||||||
|
$ui->assign('users', ORM::for_table('tbl_widgets')->getEnum("user"));
|
||||||
|
$ui->assign('do', 'add');
|
||||||
|
$ui->assign('widgets', $widgets);
|
||||||
|
$ui->assign('widget', $widget);
|
||||||
|
$ui->display('admin/settings/widgets_add_edit.tpl');
|
||||||
|
} else if ($action == 'edit') {
|
||||||
|
// if request method post then save data
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
$id = alphanumeric($_POST['id']);
|
||||||
|
$orders = alphanumeric($_POST['orders']);
|
||||||
|
$position = alphanumeric($_POST['position']);
|
||||||
|
$tipeUser = alphanumeric($_POST['tipeUser']);
|
||||||
|
$enabled = alphanumeric($_POST['enabled']);
|
||||||
|
$title = _post('title');
|
||||||
|
$widget = _post('widget');
|
||||||
|
$d = ORM::for_table('tbl_widgets')->find_one($id);
|
||||||
|
$d->orders = $orders;
|
||||||
|
$d->position = $position;
|
||||||
|
$d->user = $tipeUser;
|
||||||
|
$d->enabled = $enabled;
|
||||||
|
$d->title = $title;
|
||||||
|
$d->widget = $widget;
|
||||||
|
$d->content = _post('content');
|
||||||
|
$d->save();
|
||||||
|
r2(getUrl('widgets&user=' . $tipeUser), 's', 'Widget Saved Successfully');
|
||||||
|
}
|
||||||
|
$id = alphanumeric($routes['2']);
|
||||||
|
$widget = ORM::for_table('tbl_widgets')->find_one($id);
|
||||||
|
$files = scandir($WIDGET_PATH);
|
||||||
|
$widgets = [];
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (strpos($file, '.php') !== false) {
|
||||||
|
$name = ucwords(str_replace('.php', '', str_replace('_', ' ', $file)));
|
||||||
|
$widgets[str_replace('.php', '', $file)] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$ui->assign('users', ORM::for_table('tbl_widgets')->getEnum("user"));
|
||||||
|
$ui->assign('do', 'edit');
|
||||||
|
$ui->assign('widgets', $widgets);
|
||||||
|
$ui->assign('widget', $widget);
|
||||||
|
$ui->display('admin/settings/widgets_add_edit.tpl');
|
||||||
|
} else if ($action == 'delete') {
|
||||||
|
$id = alphanumeric($routes['2']);
|
||||||
|
$d = ORM::for_table('tbl_widgets')->find_one($id);
|
||||||
|
if ($d) {
|
||||||
|
$d->delete();
|
||||||
|
r2(getUrl('widgets&user=' . $tipeUser), 's', 'Widget Deleted Successfully');
|
||||||
|
}
|
||||||
|
r2(getUrl('widgets&user=' . $tipeUser), 'e', 'Widget Not Found');
|
||||||
|
} else if (!empty($action) && file_exists("system/widget/$action.php") && !empty($routes['2'])) {
|
||||||
|
require_once "system/widget/$action.php";
|
||||||
|
try {
|
||||||
|
(new $action)->run_command($routes['2']);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
//nothing to do
|
||||||
|
}
|
||||||
|
} else if ($action == 'pos') {
|
||||||
|
$jml = count($_POST['orders']);
|
||||||
|
for ($i = 0; $i < $jml; $i++) {
|
||||||
|
$d = ORM::for_table('tbl_widgets')->find_one($_POST['id'][$i]);
|
||||||
|
$d->orders = $_POST['orders'][$i];
|
||||||
|
$d->save();
|
||||||
|
}
|
||||||
|
r2(getUrl('widgets&user=' . $tipeUser), 's', 'Widget order Saved Successfully');
|
||||||
|
} else {
|
||||||
|
if (_post("save") == 'struct') {
|
||||||
|
$d = ORM::for_table('tbl_appconfig')->where('setting', 'dashboard_' . $tipeUser)->find_one();
|
||||||
|
if ($d) {
|
||||||
|
$d->value = _post('dashboard');
|
||||||
|
$d->save();
|
||||||
|
} else {
|
||||||
|
$d = ORM::for_table('tbl_appconfig')->create();
|
||||||
|
$d->setting = 'dashboard_' . $tipeUser;
|
||||||
|
$d->value = _post('dashboard');
|
||||||
|
$d->save();
|
||||||
|
}
|
||||||
|
_alert("Dashboard Structure Saved Successfully", "success", getUrl('widgets&user=' . $tipeUser));
|
||||||
|
}
|
||||||
|
$widgets = ORM::for_table('tbl_widgets')->where("user", $tipeUser)->order_by_asc("orders")->find_many();
|
||||||
|
$ui->assign('widgets', $widgets);
|
||||||
|
$ui->display('admin/settings/widgets.tpl');
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ if (php_sapi_name() !== 'cli') {
|
||||||
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
|
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
|
||||||
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
|
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
|
||||||
$statement = ORM::get_last_statement();
|
$statement = ORM::get_last_statement();
|
||||||
$rows = array();
|
$rows = [];
|
||||||
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
||||||
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
|
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
|
||||||
}
|
}
|
||||||
|
@ -45,62 +45,93 @@ echo "Found " . count($d) . " user(s)\n";
|
||||||
run_hook('cronjob'); #HOOK
|
run_hook('cronjob'); #HOOK
|
||||||
|
|
||||||
foreach ($d as $ds) {
|
foreach ($d as $ds) {
|
||||||
|
try {
|
||||||
$date_now = strtotime(date("Y-m-d H:i:s"));
|
$date_now = strtotime(date("Y-m-d H:i:s"));
|
||||||
$expiration = strtotime($ds['expiration'] . ' ' . $ds['time']);
|
$expiration = strtotime($ds['expiration'] . ' ' . $ds['time']);
|
||||||
echo $ds['expiration'] . " : " . (($isCli) ? $ds['username'] : Lang::maskText($ds['username']));
|
echo $ds['expiration'] . " : " . ($isCli ? $ds['username'] : Lang::maskText($ds['username']));
|
||||||
|
|
||||||
if ($date_now >= $expiration) {
|
if ($date_now >= $expiration) {
|
||||||
echo " : EXPIRED \r\n";
|
echo " : EXPIRED \r\n";
|
||||||
|
|
||||||
|
// Fetch user recharge details
|
||||||
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
|
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
|
||||||
|
if (!$u) {
|
||||||
|
throw new Exception("User recharge record not found for ID: " . $ds['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch customer details
|
||||||
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
|
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
|
||||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
if (!$c) {
|
||||||
if (empty($c)) {
|
|
||||||
$c = $u;
|
$c = $u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch plan details
|
||||||
|
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||||
|
if (!$p) {
|
||||||
|
throw new Exception("Plan not found for ID: " . $u['plan_id']);
|
||||||
|
}
|
||||||
|
|
||||||
$dvc = Package::getDevice($p);
|
$dvc = Package::getDevice($p);
|
||||||
if ($_app_stage != 'demo') {
|
if ($_app_stage != 'demo') {
|
||||||
if (file_exists($dvc)) {
|
if (file_exists($dvc)) {
|
||||||
require_once $dvc;
|
require_once $dvc;
|
||||||
(new $p['device'])->remove_customer($c, $p);
|
(new $p['device'])->remove_customer($c, $p);
|
||||||
} else {
|
} else {
|
||||||
echo "Cron error Devices $p[device] not found, cannot disconnect $c[username]";
|
throw new Exception("Cron error: Devices " . $p['device'] . "not found, cannot disconnect ".$c['username']."\n");
|
||||||
Message::sendTelegram("Cron error Devices $p[device] not found, cannot disconnect $c[username]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
echo Message::sendPackageNotification($c, $u['namebp'], $p['price'], $textExpired, $config['user_notification_expired']) . "\n";
|
|
||||||
//update database user dengan status off
|
// Send notification and update user status
|
||||||
|
try {
|
||||||
|
echo Message::sendPackageNotification(
|
||||||
|
$c,
|
||||||
|
$u['namebp'],
|
||||||
|
$p['price'],
|
||||||
|
Message::getMessageType($p['type'], $textExpired),
|
||||||
|
$config['user_notification_expired']
|
||||||
|
) . "\n";
|
||||||
$u->status = 'off';
|
$u->status = 'off';
|
||||||
$u->save();
|
$u->save();
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
_log($e->getMessage());
|
||||||
|
sendTelegram($e->getMessage());
|
||||||
|
echo "Error: " . $e->getMessage() . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// autorenewal from deposit
|
// Auto-renewal from deposit
|
||||||
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
|
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
|
||||||
list($bills, $add_cost) = User::getBills($ds['customer_id']);
|
[$bills, $add_cost] = User::getBills($ds['customer_id']);
|
||||||
if ($add_cost != 0) {
|
if ($add_cost != 0) {
|
||||||
if (!empty($add_cost)) {
|
|
||||||
$p['price'] += $add_cost;
|
$p['price'] += $add_cost;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ($p && $c['balance'] >= $p['price']) {
|
if ($p && $c['balance'] >= $p['price']) {
|
||||||
if (Package::rechargeUser($ds['customer_id'], $ds['routers'], $p['id'], 'Customer', 'Balance')) {
|
if (Package::rechargeUser($ds['customer_id'], $ds['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||||
// if success, then get the balance
|
|
||||||
Balance::min($ds['customer_id'], $p['price']);
|
Balance::min($ds['customer_id'], $p['price']);
|
||||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
echo "plan enabled: " . (string) $p['enabled'] . " | User balance: " . (string) $c['balance'] . " | price " . (string) $p['price'] . "\n";
|
||||||
echo "auto renewall Success\n";
|
echo "auto renewal Success\n";
|
||||||
} else {
|
} else {
|
||||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
echo "plan enabled: " . $p['enabled'] . " | User balance: " . $c['balance'] . " | price " . $p['price'] . "\n";
|
||||||
echo "auto renewall Failed\n";
|
echo "auto renewal Failed\n";
|
||||||
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
|
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u." . $c['username'] . " #buy #Hotspot \n" . $p['name_plan'] .
|
||||||
"\nRouter: " . $p['routers'] .
|
"\nRouter: " . $p['routers'] .
|
||||||
"\nPrice: " . $p['price']);
|
"\nPrice: " . $p['price']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
echo "no renewall | plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
echo "no renewal | plan enabled: " . (string) $p['enabled'] . " | User balance: " . (string) $c['balance'] . " | price " . (string) $p['price'] . "\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
echo "no renewall | balance $config[enable_balance] auto_renewal $c[auto_renewal]\n";
|
echo "no renewal | balance" . $config['enable_balance'] . " auto_renewal " . $c['auto_renewal'] . "\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
echo " : ACTIVE \r\n";
|
echo " : ACTIVE \r\n";
|
||||||
}
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Catch any unexpected errors
|
||||||
|
_log($e->getMessage());
|
||||||
|
sendTelegram($e->getMessage());
|
||||||
|
echo "Unexpected Error: " . $e->getMessage() . "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Cek interim-update radiusrest
|
//Cek interim-update radiusrest
|
||||||
|
@ -207,14 +238,7 @@ if ($config['router_check']) {
|
||||||
Message::SendEmail($adminEmail, $subject, $message);
|
Message::SendEmail($adminEmail, $subject, $message);
|
||||||
sendTelegram($message);
|
sendTelegram($message);
|
||||||
}
|
}
|
||||||
echo "Router monitoring finished\n";
|
echo "Router monitoring finished checking.\n";
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (defined('PHP_SAPI') && PHP_SAPI === 'cli') {
|
|
||||||
echo "Cronjob finished\n";
|
|
||||||
} else {
|
|
||||||
echo "</pre>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flock($lock, LOCK_UN);
|
flock($lock, LOCK_UN);
|
||||||
|
@ -224,5 +248,5 @@ unlink($lockFile);
|
||||||
$timestampFile = "$UPLOAD_PATH/cron_last_run.txt";
|
$timestampFile = "$UPLOAD_PATH/cron_last_run.txt";
|
||||||
file_put_contents($timestampFile, time());
|
file_put_contents($timestampFile, time());
|
||||||
|
|
||||||
|
|
||||||
run_hook('cronjob_end'); #HOOK
|
run_hook('cronjob_end'); #HOOK
|
||||||
|
echo "Cron job finished and completed successfully.\n";
|
|
@ -23,7 +23,7 @@ run_hook('cronjob_reminder'); #HOOK
|
||||||
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
|
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
|
||||||
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
|
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
|
||||||
$statement = ORM::get_last_statement();
|
$statement = ORM::get_last_statement();
|
||||||
$rows = array();
|
$rows = [];
|
||||||
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
||||||
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
|
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
|
||||||
}
|
}
|
||||||
|
@ -49,12 +49,42 @@ foreach ($d as $ds) {
|
||||||
} else {
|
} else {
|
||||||
$price = $p['price'];
|
$price = $p['price'];
|
||||||
}
|
}
|
||||||
if ($ds['expiration'] == $day7) {
|
if ($ds['expiration'] == $day7 && $config['notification_reminder_7day'] !== 'no') {
|
||||||
echo Message::sendPackageNotification($c, $p['name_plan'], $price, Lang::getNotifText('reminder_7_day'), $config['user_notification_reminder']) . "\n";
|
try {
|
||||||
} else if ($ds['expiration'] == $day3) {
|
echo Message::sendPackageNotification(
|
||||||
echo Message::sendPackageNotification($c, $p['name_plan'], $price, Lang::getNotifText('reminder_3_day'), $config['user_notification_reminder']) . "\n";
|
$c,
|
||||||
} else if ($ds['expiration'] == $day1) {
|
$p['name_plan'],
|
||||||
echo Message::sendPackageNotification($c, $p['name_plan'], $price, Lang::getNotifText('reminder_1_day'), $config['user_notification_reminder']) . "\n";
|
$price,
|
||||||
|
Message::getMessageType($p['type'], Lang::getNotifText('reminder_7_day')),
|
||||||
|
$config['user_notification_reminder']
|
||||||
|
) . "\n";
|
||||||
|
} catch (Exception $e) {
|
||||||
|
sendTelegram("Cron Reminder failed to send 7-day reminder to " . $ds['username'] . " Error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
} else if ($ds['expiration'] == $day3 && $config['notification_reminder_3day'] !== 'no') {
|
||||||
|
try {
|
||||||
|
echo Message::sendPackageNotification(
|
||||||
|
$c,
|
||||||
|
$p['name_plan'],
|
||||||
|
$price,
|
||||||
|
Message::getMessageType($p['type'], Lang::getNotifText('reminder_3_day')),
|
||||||
|
$config['user_notification_reminder']
|
||||||
|
) . "\n";
|
||||||
|
} catch (Exception $e) {
|
||||||
|
sendTelegram("Cron Reminder failed to send 3-day reminder to " . $ds['username'] . " Error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
} else if ($ds['expiration'] == $day1 && $config['notification_reminder_1day'] !== 'no') {
|
||||||
|
try {
|
||||||
|
echo Message::sendPackageNotification(
|
||||||
|
$c,
|
||||||
|
$p['name_plan'],
|
||||||
|
$price,
|
||||||
|
Message::getMessageType($p['type'], Lang::getNotifText('reminder_1_day')),
|
||||||
|
$config['user_notification_reminder']
|
||||||
|
) . "\n";
|
||||||
|
} catch (Exception $e) {
|
||||||
|
sendTelegram("Cron Reminder failed to send 1-day reminder to " . $ds['username'] . " Error: " . $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -122,6 +122,9 @@ class MikrotikHotspot
|
||||||
if (!empty(trim($bw['burst']))) {
|
if (!empty(trim($bw['burst']))) {
|
||||||
$rate .= ' ' . $bw['burst'];
|
$rate .= ' ' . $bw['burst'];
|
||||||
}
|
}
|
||||||
|
if ($bw['rate_up'] == '0' || $bw['rate_down'] == '0') {
|
||||||
|
$rate = '';
|
||||||
|
}
|
||||||
$addRequest = new RouterOS\Request('/ip/hotspot/user/profile/add');
|
$addRequest = new RouterOS\Request('/ip/hotspot/user/profile/add');
|
||||||
$client->sendSync(
|
$client->sendSync(
|
||||||
$addRequest
|
$addRequest
|
||||||
|
@ -202,6 +205,9 @@ class MikrotikHotspot
|
||||||
if (!empty(trim($bw['burst']))) {
|
if (!empty(trim($bw['burst']))) {
|
||||||
$rate .= ' ' . $bw['burst'];
|
$rate .= ' ' . $bw['burst'];
|
||||||
}
|
}
|
||||||
|
if ($bw['rate_up'] == '0' || $bw['rate_down'] == '0') {
|
||||||
|
$rate = '';
|
||||||
|
}
|
||||||
$setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set');
|
$setRequest = new RouterOS\Request('/ip/hotspot/user/profile/set');
|
||||||
$client->sendSync(
|
$client->sendSync(
|
||||||
$setRequest
|
$setRequest
|
||||||
|
|
|
@ -149,6 +149,9 @@ class MikrotikPppoe
|
||||||
if(!empty(trim($bw['burst']))){
|
if(!empty(trim($bw['burst']))){
|
||||||
$rate .= ' '.$bw['burst'];
|
$rate .= ' '.$bw['burst'];
|
||||||
}
|
}
|
||||||
|
if ($bw['rate_up'] == '0' || $bw['rate_down'] == '0') {
|
||||||
|
$rate = '';
|
||||||
|
}
|
||||||
$pool = ORM::for_table("tbl_pool")->where("pool_name", $plan['pool'])->find_one();
|
$pool = ORM::for_table("tbl_pool")->where("pool_name", $plan['pool'])->find_one();
|
||||||
$addRequest = new RouterOS\Request('/ppp/profile/add');
|
$addRequest = new RouterOS\Request('/ppp/profile/add');
|
||||||
$client->sendSync(
|
$client->sendSync(
|
||||||
|
@ -205,6 +208,9 @@ class MikrotikPppoe
|
||||||
if(!empty(trim($bw['burst']))){
|
if(!empty(trim($bw['burst']))){
|
||||||
$rate .= ' '.$bw['burst'];
|
$rate .= ' '.$bw['burst'];
|
||||||
}
|
}
|
||||||
|
if ($bw['rate_up'] == '0' || $bw['rate_down'] == '0') {
|
||||||
|
$rate = '';
|
||||||
|
}
|
||||||
$pool = ORM::for_table("tbl_pool")->where("pool_name", $new_plan['pool'])->find_one();
|
$pool = ORM::for_table("tbl_pool")->where("pool_name", $new_plan['pool'])->find_one();
|
||||||
$setRequest = new RouterOS\Request('/ppp/profile/set');
|
$setRequest = new RouterOS\Request('/ppp/profile/set');
|
||||||
$client->sendSync(
|
$client->sendSync(
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@
|
||||||
"Announcement": "Pemberitahuan",
|
"Announcement": "Pemberitahuan",
|
||||||
"Registration_Info": "Info Pendaftaran",
|
"Registration_Info": "Info Pendaftaran",
|
||||||
"Voucher_not_found__please_buy_voucher_befor_register": "Voucher tidak ditemukan, silakan beli voucher sebelum mendaftar",
|
"Voucher_not_found__please_buy_voucher_befor_register": "Voucher tidak ditemukan, silakan beli voucher sebelum mendaftar",
|
||||||
"Register_Success__You_can_login_now": "Daftar Sukses! Anda dapat masuk sekarang",
|
"Register_Success__You_can_login_now": "Daftar berhadil! Anda dapat masuk sekarang",
|
||||||
"Log_in_to_Member_Panel": "Masuk ke Panel Anggota",
|
"Log_in_to_Member_Panel": "Masuk ke Panel Anggota",
|
||||||
"Register_as_Member": "Daftar sebagai Anggota",
|
"Register_as_Member": "Daftar sebagai Anggota",
|
||||||
"Enter_Admin_Area": "Masuk ke Admin Panel",
|
"Enter_Admin_Area": "Masuk ke Admin Panel",
|
||||||
|
@ -13,11 +13,12 @@
|
||||||
"Password": "Kata Sandi",
|
"Password": "Kata Sandi",
|
||||||
"Passwords_does_not_match": "Kata sandi tidak cocok",
|
"Passwords_does_not_match": "Kata sandi tidak cocok",
|
||||||
"Account_already_axist": "Akun telah ada",
|
"Account_already_axist": "Akun telah ada",
|
||||||
"Manage": "Mengelola",
|
"Manage": "Kelola",
|
||||||
"Submit": "Kirim",
|
"Submit": "Kirim",
|
||||||
"Save_Changes": "Simpan Perubahan",
|
"Save_Changes": "Simpan Perubahan",
|
||||||
"Cancel": "Batal",
|
"Cancel": "Batal",
|
||||||
"Edit": "Sunting",
|
"Edit": "Sunting",
|
||||||
|
"Order": "Urutan",
|
||||||
"Delete": "Hapus",
|
"Delete": "Hapus",
|
||||||
"Welcome": "Selamat Datang",
|
"Welcome": "Selamat Datang",
|
||||||
"Data_Created_Successfully": "Data Berhasil Dibuat",
|
"Data_Created_Successfully": "Data Berhasil Dibuat",
|
||||||
|
@ -123,7 +124,7 @@
|
||||||
"Period_Reports": "Laporan Periode",
|
"Period_Reports": "Laporan Periode",
|
||||||
"All_Transactions": "Semua Transaksi",
|
"All_Transactions": "Semua Transaksi",
|
||||||
"Total_Income": "Jumlah Pemasukan",
|
"Total_Income": "Jumlah Pemasukan",
|
||||||
"All_Transactions_at_Date": "Semua transaksi pada ganggal",
|
"All_Transactions_at_Date": "Semua transaksi pada tanggal",
|
||||||
"Export_for_Print": "Ekspor untuk cetak",
|
"Export_for_Print": "Ekspor untuk cetak",
|
||||||
"Print": "Cetak",
|
"Print": "Cetak",
|
||||||
"Export_to_PDF": "Ekspor ke PDF",
|
"Export_to_PDF": "Ekspor ke PDF",
|
||||||
|
@ -199,7 +200,7 @@
|
||||||
"Search_by_Username": "Cari berdasarkan nama pengguna",
|
"Search_by_Username": "Cari berdasarkan nama pengguna",
|
||||||
"Search_by_Name": "Cari berdasarkan nama",
|
"Search_by_Name": "Cari berdasarkan nama",
|
||||||
"Search_by_Code_Voucher": "Cari berdasarkan kode voucher",
|
"Search_by_Code_Voucher": "Cari berdasarkan kode voucher",
|
||||||
"Search": "Mencari",
|
"Search": "Cari",
|
||||||
"Select_a_customer": "Pilih pelanggan",
|
"Select_a_customer": "Pilih pelanggan",
|
||||||
"Select_Routers": "Pilih Router",
|
"Select_Routers": "Pilih Router",
|
||||||
"Select_Plans": "Pilih Paket",
|
"Select_Plans": "Pilih Paket",
|
||||||
|
@ -331,7 +332,7 @@
|
||||||
"Pay_this_with_Balance__your_active_package_will_be_overwrite": "Bayar ini dengan Saldo? Paket aktif Anda akan ditimpa",
|
"Pay_this_with_Balance__your_active_package_will_be_overwrite": "Bayar ini dengan Saldo? Paket aktif Anda akan ditimpa",
|
||||||
"Success_to_buy_package": "Berhasil membeli paket",
|
"Success_to_buy_package": "Berhasil membeli paket",
|
||||||
"Auto_Renewal": "Perpanjangan otomatis",
|
"Auto_Renewal": "Perpanjangan otomatis",
|
||||||
"View": "Melihat",
|
"View": "Lihat",
|
||||||
"Back": "Kembali",
|
"Back": "Kembali",
|
||||||
"Active": "Aktif",
|
"Active": "Aktif",
|
||||||
"Transfer_Balance": "Kirim saldo",
|
"Transfer_Balance": "Kirim saldo",
|
||||||
|
@ -383,6 +384,7 @@
|
||||||
"Vouchers": "Voucher",
|
"Vouchers": "Voucher",
|
||||||
"Refill_Customer": "Isi Ulang Voucher",
|
"Refill_Customer": "Isi Ulang Voucher",
|
||||||
"Recharge_Customer": "Isi Ulang Paket",
|
"Recharge_Customer": "Isi Ulang Paket",
|
||||||
|
"Plan": "Paket",
|
||||||
"Plans": "Paket",
|
"Plans": "Paket",
|
||||||
"PPPOE": "PPPOE",
|
"PPPOE": "PPPOE",
|
||||||
"Bandwidth": "Bandwidth",
|
"Bandwidth": "Bandwidth",
|
||||||
|
@ -411,7 +413,7 @@
|
||||||
"Paid": "Dibayar",
|
"Paid": "Dibayar",
|
||||||
"Personal": "Pribadi",
|
"Personal": "Pribadi",
|
||||||
"Coordinates": "Koordinat",
|
"Coordinates": "Koordinat",
|
||||||
"Confirm": "Mengonfirmasi",
|
"Confirm": "Konfirmasi",
|
||||||
"Name": "Nama",
|
"Name": "Nama",
|
||||||
"Plan": "Paket",
|
"Plan": "Paket",
|
||||||
"Using": "Menggunakan",
|
"Using": "Menggunakan",
|
||||||
|
@ -419,7 +421,7 @@
|
||||||
"Additional_Cost": "Biaya tambahan",
|
"Additional_Cost": "Biaya tambahan",
|
||||||
"Resend": "Kirim ulang",
|
"Resend": "Kirim ulang",
|
||||||
"Login": "Masuk",
|
"Login": "Masuk",
|
||||||
"success": "Sukses",
|
"success": "Berhasil",
|
||||||
"Click_Here": "Klik disini",
|
"Click_Here": "Klik disini",
|
||||||
"Your_friend_do_not_have_active_package": "Teman Anda tidak memiliki paket aktif",
|
"Your_friend_do_not_have_active_package": "Teman Anda tidak memiliki paket aktif",
|
||||||
"If_your_friend_have_Additional_Cost__you_will_pay_for_that_too": "Jika teman Anda memiliki biaya tambahan, Anda juga akan membayarnya",
|
"If_your_friend_have_Additional_Cost__you_will_pay_for_that_too": "Jika teman Anda memiliki biaya tambahan, Anda juga akan membayarnya",
|
||||||
|
@ -503,11 +505,11 @@
|
||||||
"Time": "Waktu",
|
"Time": "Waktu",
|
||||||
"Data": "Data",
|
"Data": "Data",
|
||||||
"1_Period___1_Month__Expires_the_20th_of_each_month": "1 Periode = 1 Bulan, Berakhir pada tanggal 20 setiap bulannya",
|
"1_Period___1_Month__Expires_the_20th_of_each_month": "1 Periode = 1 Bulan, Berakhir pada tanggal 20 setiap bulannya",
|
||||||
"Expired_Date": "Tanggal kadaluarsa",
|
"Expired_Date": "Tanggal kadaluwarsa",
|
||||||
"Expired_Action": "Tindakan Kedaluwarsa",
|
"Expired_Action": "Tindakan Kedaluwarsa",
|
||||||
"Optional": "Opsional",
|
"Optional": "Opsional",
|
||||||
"Expired_Internet_Plan": "Paket Internet Kedaluwarsa",
|
"Expired_Internet_Plan": "Paket Internet Kedaluwarsa",
|
||||||
"When_Expired__customer_will_be_move_to_selected_internet_plan": "Ketika Expired, pelanggan akan dipindahkan ke paket internet yang dipilih",
|
"When_Expired__customer_will_be_move_to_selected_internet_plan": "Ketika kedaluwarsa, pelanggan akan dipindahkan ke paket internet yang dipilih",
|
||||||
"Period": "Periode",
|
"Period": "Periode",
|
||||||
"Rate": "Kecepatan",
|
"Rate": "Kecepatan",
|
||||||
"Burst": "Burst",
|
"Burst": "Burst",
|
||||||
|
@ -522,7 +524,8 @@
|
||||||
"Ascending": "Naik",
|
"Ascending": "Naik",
|
||||||
"Descending": "Menurun",
|
"Descending": "Menurun",
|
||||||
"Query": "Query",
|
"Query": "Query",
|
||||||
"Add": "Menambahkan",
|
"Add": "Tambah",
|
||||||
|
"Search": "Cari",
|
||||||
"Logout_Successful": "Berhasil Keluar",
|
"Logout_Successful": "Berhasil Keluar",
|
||||||
"warning": "peringatan",
|
"warning": "peringatan",
|
||||||
"Created___Expired": "Dibuat \/ Kedaluwarsa",
|
"Created___Expired": "Dibuat \/ Kedaluwarsa",
|
||||||
|
@ -532,8 +535,8 @@
|
||||||
"Customer_can_login_but_cannot_buy_internet_plan__Admin_cannot_recharge_customer": "Pelanggan dapat login tetapi tidak dapat membeli paket internet, Admin tidak dapat mengisi ulang pelanggan",
|
"Customer_can_login_but_cannot_buy_internet_plan__Admin_cannot_recharge_customer": "Pelanggan dapat login tetapi tidak dapat membeli paket internet, Admin tidak dapat mengisi ulang pelanggan",
|
||||||
"Don_t_forget_to_deactivate_all_active_plan_too": "Jangan lupa untuk menonaktifkan semua paket aktif juga",
|
"Don_t_forget_to_deactivate_all_active_plan_too": "Jangan lupa untuk menonaktifkan semua paket aktif juga",
|
||||||
"Attributes": "Atribut",
|
"Attributes": "Atribut",
|
||||||
"Additional_Information": "informasi tambahan",
|
"Additional_Information": "Informasi tambahan",
|
||||||
"City_of_Resident": "Kota Residen",
|
"City_of_Resident": "Kota Tempat Tinggal",
|
||||||
"State_of_Resident": "Negara Bagian Tempat Tinggal",
|
"State_of_Resident": "Negara Bagian Tempat Tinggal",
|
||||||
"Zip_Code": "Kode Pos",
|
"Zip_Code": "Kode Pos",
|
||||||
"Phone": "Telepon",
|
"Phone": "Telepon",
|
||||||
|
@ -554,7 +557,7 @@
|
||||||
"Input_your_phone_number": "Masukkan nomor telepon Anda",
|
"Input_your_phone_number": "Masukkan nomor telepon Anda",
|
||||||
"OTP": "OTP",
|
"OTP": "OTP",
|
||||||
"Enter_OTP_that_was_sent_to_your_phone": "Masukkan OTP yang dikirimkan ke ponsel Anda",
|
"Enter_OTP_that_was_sent_to_your_phone": "Masukkan OTP yang dikirimkan ke ponsel Anda",
|
||||||
"Update": "Memperbarui",
|
"Update": "Perbarui",
|
||||||
"Verification_code_has_been_sent_to_your_phone": "Kode verifikasi telah dikirimkan ke ponsel Anda",
|
"Verification_code_has_been_sent_to_your_phone": "Kode verifikasi telah dikirimkan ke ponsel Anda",
|
||||||
"Please_wait_1039_seconds_before_sending_another_SMS": "Harap tunggu 1039 detik sebelum mengirim SMS lainnya",
|
"Please_wait_1039_seconds_before_sending_another_SMS": "Harap tunggu 1039 detik sebelum mengirim SMS lainnya",
|
||||||
"Please_wait_1015_seconds_before_sending_another_SMS": "Harap tunggu 1015 detik sebelum mengirim SMS lainnya",
|
"Please_wait_1015_seconds_before_sending_another_SMS": "Harap tunggu 1015 detik sebelum mengirim SMS lainnya",
|
||||||
|
@ -567,7 +570,7 @@
|
||||||
"Api": "Api",
|
"Api": "Api",
|
||||||
"Http_Chap": "Http-Chap",
|
"Http_Chap": "Http-Chap",
|
||||||
"Hotspot_Authentication_Method__Make_sure_you_have_changed_your_hotspot_login_page_": "Metode Otentikasi Hotspot. Pastikan Anda telah mengubah halaman login hotspot Anda.",
|
"Hotspot_Authentication_Method__Make_sure_you_have_changed_your_hotspot_login_page_": "Metode Otentikasi Hotspot. Pastikan Anda telah mengubah halaman login hotspot Anda.",
|
||||||
"Languge_set_to_indonesia": "Language set to indonesia",
|
"Languge_set_to_indonesia": "Bahasa diatur ke Indonesia",
|
||||||
"Enable": "Aktifkan",
|
"Enable": "Aktifkan",
|
||||||
"Diable": "Nonaktifkan",
|
"Diable": "Nonaktifkan",
|
||||||
"Verification_code": "Kod3 V3r1fik@s1",
|
"Verification_code": "Kod3 V3r1fik@s1",
|
||||||
|
@ -583,37 +586,37 @@
|
||||||
"_": "-",
|
"_": "-",
|
||||||
"Search_Users": "Pencarian Pengguna",
|
"Search_Users": "Pencarian Pengguna",
|
||||||
"Routers_Maps": "Peta Router",
|
"Routers_Maps": "Peta Router",
|
||||||
"Theme_Voucher": "Voucher Tema",
|
"Theme_Voucher": "Tema Voucher",
|
||||||
"Payment_Info": "Info Pembayaran",
|
"Payment_Info": "Info Pembayaran",
|
||||||
"Documentation": "Dokumentasi",
|
"Documentation": "Dokumentasi",
|
||||||
"Customers": "Pelanggan",
|
"Customers": "Pelanggan",
|
||||||
"Package_Name": "Nama Paket",
|
"Package_Name": "Nama Paket",
|
||||||
"Routers_Offline": "Router Offline",
|
"Routers_Offline": "Router Off",
|
||||||
"Cron_appear_not_been_setup__please_check_your_cron_setup_": "Cron tampaknya belum disiapkan, silakan periksa pengaturan cron Anda.",
|
"Cron_appear_not_been_setup__please_check_your_cron_setup_": "Cron tampaknya belum disiapkan, silakan periksa pengaturan cron Anda.",
|
||||||
"Buy": "Membeli",
|
"Buy": "Beli",
|
||||||
"You_are_already_logged_in": "Anda sudah masuk",
|
"You_are_already_logged_in": "Anda sudah masuk",
|
||||||
"PPPOE_Package": "Paket PPPoE",
|
"PPPOE_Package": "Paket PPPoE",
|
||||||
"Prepaid": "Prabayar",
|
"Prepaid": "Prabayar",
|
||||||
"Postpaid": "Pascabayar",
|
"Postpaid": "Pascabayar",
|
||||||
"Enabled": "Diaktifkan",
|
"Enabled": "Aktifkan",
|
||||||
"Disable": "Nonaktifkan",
|
"Disable": "Nonaktifkan",
|
||||||
"Create_expired_Internet_Plan": "Buat Paket Internet yang Kedaluwarsa",
|
"Create_expired_Internet_Plan": "Buat Paket Internet yang Kedaluwarsa",
|
||||||
"When_customer_expired__you_can_move_it_to_Expired_Internet_Plan": "Ketika pelanggan kedaluwarsa, Anda dapat memindahkannya ke Paket Internet Kedaluwarsa",
|
"When_customer_expired__you_can_move_it_to_Expired_Internet_Plan": "Ketika pelanggan kedaluwarsa, Anda dapat memindahkannya ke Paket Internet Kedaluwarsa",
|
||||||
"Price_Before_Discount": "Harga Sebelum Diskon",
|
"Price_Before_Discount": "Harga Sebelum Diskon",
|
||||||
"For_Discount_Rate__this_is_price_before_get_discount__must_be_more_expensive_with_real_price": "Untuk Discount Rate, ini adalah harga sebelum mendapat diskon, pasti lebih mahal dari harga sebenarnya",
|
"For_Discount_Rate__this_is_price_before_get_discount__must_be_more_expensive_with_real_price": "Untuk tarif diskon. Ini adalah harga sebelum mendapat diskon, pasti lebih mahal dari harga sebenarnya",
|
||||||
"on_login___on_up": "saat masuk \/ saat mendaftar",
|
"on_login___on_up": "saat masuk \/ saat naik",
|
||||||
"on_logout___on_down": "saat keluar \/ saat turun",
|
"on_logout___on_down": "saat keluar \/ saat turun",
|
||||||
"Get_Directions": "Dapatkan Petunjuk Arah",
|
"Get_Directions": "Dapatkan Petunjuk Arah",
|
||||||
"Not_Working_with_Freeradius_Mysql": "Tidak Bekerja dengan Freeradius Mysql",
|
"Not_Working_with_Freeradius_Mysql": "Tidak Bekerja dengan Freeradius Mysql",
|
||||||
"User_Cannot_change_this__only_admin__if_it_Empty_it_will_use_Customer_Credentials": "Pengguna tidak dapat mengubah ini, hanya admin. Jika Kosong, maka akan menggunakan Kredensial Pelanggan",
|
"User_Cannot_change_this__only_admin__if_it_Empty_it_will_use_Customer_Credentials": "Pengguna tidak dapat mengubah ini, hanya admin. Jika Kosong, maka akan menggunakan Kredensial Pelanggan",
|
||||||
"Buy_this__your_active_package_will_be_overwritten": "Beli ini? Paket aktif Anda akan ditimpa",
|
"Buy_this__your_active_package_will_be_overwritten": "Beli paket ini? Paket aktif Anda akan ditimpa",
|
||||||
"Pay_this_with_Balance__your_active_package_will_be_overwritten": "Bayar ini dengan Saldo? Paket aktif Anda akan ditimpa",
|
"Pay_this_with_Balance__your_active_package_will_be_overwritten": "Bayar ini dengan Saldo? Paket aktif Anda akan ditimpa",
|
||||||
"Error": "Kesalahan",
|
"Error": "Kesalahan",
|
||||||
"Internal_Error": "Kesalahan Internal",
|
"Internal_Error": "Kesalahan Internal",
|
||||||
"Sorry__the_software_failed_to_process_the_request__if_it_still_happening__please_tell": "Maaf, perangkat lunak gagal memproses permintaan, jika masih terjadi, mohon beri tahu",
|
"Sorry__the_software_failed_to_process_the_request__if_it_still_happening__please_tell": "Maaf, perangkat lunak gagal memproses permintaan. Jika masih terjadi, mohon beri tahu",
|
||||||
"Try_Again": "Coba Lagi",
|
"Try_Again": "Coba Lagi",
|
||||||
"Make_sure_you_use_API_Port__Default_8728": "Pastikan Anda menggunakan Port API, Default 8728",
|
"Make_sure_you_use_API_Port__Default_8728": "Pastikan Anda menggunakan Port API, Default 8728",
|
||||||
"Make_sure_Username_and_Password_are_correct": "Pastikan Username dan Password sudah benar",
|
"Make_sure_Username_and_Password_are_correct": "Pastikan nama pengguna dan kata sandi sudah benar",
|
||||||
"Make_sure_your_hosting_not_blocking_port_to_external": "Pastikan hosting Anda tidak memblokir port ke eksternal",
|
"Make_sure_your_hosting_not_blocking_port_to_external": "Pastikan hosting Anda tidak memblokir port ke eksternal",
|
||||||
"Make_sure_your_Mikrotik_accessible_from_PHPNuxBill": "Pastikan Mikrotik Anda dapat diakses dari PHPNuxBill",
|
"Make_sure_your_Mikrotik_accessible_from_PHPNuxBill": "Pastikan Mikrotik Anda dapat diakses dari PHPNuxBill",
|
||||||
"If_you_just_update_PHPNuxBill_from_upload_files__try_click_Update": "Jika Anda baru saja memperbarui PHPNuxBill dari mengunggah file, coba klik Perbarui",
|
"If_you_just_update_PHPNuxBill_from_upload_files__try_click_Update": "Jika Anda baru saja memperbarui PHPNuxBill dari mengunggah file, coba klik Perbarui",
|
||||||
|
@ -669,11 +672,11 @@
|
||||||
"Logout_Admin_if_not_Available_Online_a_period_of_time": "Logout Admin jika tidak tersedia\/Online dalam jangka waktu tertentu",
|
"Logout_Admin_if_not_Available_Online_a_period_of_time": "Logout Admin jika tidak tersedia\/Online dalam jangka waktu tertentu",
|
||||||
"Timeout_Duration": "Durasi Waktu Habis",
|
"Timeout_Duration": "Durasi Waktu Habis",
|
||||||
"Enter_the_session_timeout_duration__minutes_": "Masukkan durasi batas waktu sesi (menit)",
|
"Enter_the_session_timeout_duration__minutes_": "Masukkan durasi batas waktu sesi (menit)",
|
||||||
"Idle_Timeout__Logout_Admin_if_Idle_for_xx_minutes": "Waktu Habis Idle, Keluar dari Admin jika Idle selama xx menit",
|
"Idle_Timeout__Logout_Admin_if_Idle_for_xx_minutes": "Batas waktu idle, Keluar dari Admin jika Idle selama xx menit",
|
||||||
"New_Version_Notification": "Pemberitahuan Versi Baru",
|
"New_Version_Notification": "Pemberitahuan Versi Baru",
|
||||||
"This_is_to_notify_you_when_new_updates_is_available": "Ini untuk memberi tahu Anda ketika pembaruan baru tersedia",
|
"This_is_to_notify_you_when_new_updates_is_available": "Ini untuk memberi tahu Anda ketika pembaruan baru tersedia",
|
||||||
"Router_Check": "Pemeriksaan Router",
|
"Router_Check": "Pemeriksaan Router",
|
||||||
"If_enabled__the_system_will_notify_Admin_when_router_goes_Offline__If_admin_have_10_or_more_router_and_many_customers__it_will_get_overlapping__you_can_disabled": "Jika diaktifkan, sistem akan memberitahu Admin ketika router Offline, Jika admin memiliki 10 atau lebih router dan banyak pelanggan, maka akan terjadi tumpang tindih, Anda dapat menonaktifkannya",
|
"If_enabled__the_system_will_notify_Admin_when_router_goes_Offline__If_admin_have_10_or_more_router_and_many_customers__it_will_get_overlapping__you_can_disabled": "Jika diaktifkan, sistem akan memberitahu Admin ketika router Off, Jika Admin memiliki 10 atau lebih router dan banyak pelanggan, maka akan terjadi tumpang tindih, Anda dapat menonaktifkannya",
|
||||||
"Phone_OTP_Required": "Diperlukan OTP Telepon",
|
"Phone_OTP_Required": "Diperlukan OTP Telepon",
|
||||||
"OTP_is_required_when_user_want_to_change_phone_number_and_registration": "OTP diperlukan ketika pengguna ingin mengubah nomor telepon dan registrasi",
|
"OTP_is_required_when_user_want_to_change_phone_number_and_registration": "OTP diperlukan ketika pengguna ingin mengubah nomor telepon dan registrasi",
|
||||||
"by_WhatsApp": "melalui WhatsApp",
|
"by_WhatsApp": "melalui WhatsApp",
|
||||||
|
@ -701,7 +704,7 @@
|
||||||
"Used_Date": "Tanggal Penggunaan",
|
"Used_Date": "Tanggal Penggunaan",
|
||||||
"Plugin_Installer": "Pemasang Plugin",
|
"Plugin_Installer": "Pemasang Plugin",
|
||||||
"Upload_Zip_Plugin_Theme_Device": "Unggah Plugin\/Tema\/Perangkat Zip",
|
"Upload_Zip_Plugin_Theme_Device": "Unggah Plugin\/Tema\/Perangkat Zip",
|
||||||
"Install": "Memasang",
|
"Install": "Pasang",
|
||||||
"via_SMS": "melalui SMS",
|
"via_SMS": "melalui SMS",
|
||||||
"Via_WhatsApp": "Melalui WhatsApp",
|
"Via_WhatsApp": "Melalui WhatsApp",
|
||||||
"Via_WhatsApp_and_SMS": "Melalui WhatsApp dan SMS",
|
"Via_WhatsApp_and_SMS": "Melalui WhatsApp dan SMS",
|
||||||
|
@ -740,9 +743,9 @@
|
||||||
"Status_": "Status:",
|
"Status_": "Status:",
|
||||||
"Force_Logout_": "Paksa Keluar:",
|
"Force_Logout_": "Paksa Keluar:",
|
||||||
"End_Date_": "Tanggal Berakhir:",
|
"End_Date_": "Tanggal Berakhir:",
|
||||||
"Save": "Menyimpan",
|
"Save": "Simpan",
|
||||||
"Not_Active": "Tidak Aktif",
|
"Not_Active": "Tidak Aktif",
|
||||||
"Limit": "Membatasi",
|
"Limit": "Batasi",
|
||||||
"Create_expired_Internet_Package": "Buat Paket Internet yang Kedaluwarsa",
|
"Create_expired_Internet_Package": "Buat Paket Internet yang Kedaluwarsa",
|
||||||
"When_customer_expired__you_can_move_it_to_Expired_Internet_Package": "Ketika pelanggan telah kedaluwarsa, Anda dapat memindahkannya ke Paket Internet Kedaluwarsa",
|
"When_customer_expired__you_can_move_it_to_Expired_Internet_Package": "Ketika pelanggan telah kedaluwarsa, Anda dapat memindahkannya ke Paket Internet Kedaluwarsa",
|
||||||
"Miscellaneous_Settings": "Pengaturan Lain-Lain",
|
"Miscellaneous_Settings": "Pengaturan Lain-Lain",
|
||||||
|
@ -751,10 +754,10 @@
|
||||||
"Buy_Balance_Plans": "Beli Paket Saldo",
|
"Buy_Balance_Plans": "Beli Paket Saldo",
|
||||||
"New_Voucher_for_10mbps_Created": "Voucher Baru untuk 10mbps Dibuat",
|
"New_Voucher_for_10mbps_Created": "Voucher Baru untuk 10mbps Dibuat",
|
||||||
"Previous": "Sebelumnya",
|
"Previous": "Sebelumnya",
|
||||||
"Share": "Membagikan",
|
"Share": "Bagikan",
|
||||||
"Agent": "Agen",
|
"Agent": "Agen",
|
||||||
"Sub_District": "Kecamatan",
|
"Sub_District": "Kecamatan",
|
||||||
"Ward": "Bangsal",
|
"Ward": "Kelurahan",
|
||||||
"Profile": "Profil",
|
"Profile": "Profil",
|
||||||
"Credentials": "Kredensial",
|
"Credentials": "Kredensial",
|
||||||
"Cron_has_not_run_for_over_1_hour__Please_check_your_setup_": "Cron tidak berjalan selama lebih dari 1 jam. Harap periksa pengaturan Anda.",
|
"Cron_has_not_run_for_over_1_hour__Please_check_your_setup_": "Cron tidak berjalan selama lebih dari 1 jam. Harap periksa pengaturan Anda.",
|
||||||
|
@ -765,7 +768,7 @@
|
||||||
"Username_should_be_between_3_to_45_characters": "Nama pengguna harus terdiri dari 3 hingga 45 karakter",
|
"Username_should_be_between_3_to_45_characters": "Nama pengguna harus terdiri dari 3 hingga 45 karakter",
|
||||||
"Single_session_Admin": "Sesi Tunggal Admin",
|
"Single_session_Admin": "Sesi Tunggal Admin",
|
||||||
"Admin_can_only_have_single_session_login__it_will_logout_another_session": "Admin hanya dapat memiliki login satu sesi, maka akan keluar dari sesi berikutnya",
|
"Admin_can_only_have_single_session_login__it_will_logout_another_session": "Admin hanya dapat memiliki login satu sesi, maka akan keluar dari sesi berikutnya",
|
||||||
"For_Registration_and_Update_Phone_Number": "Untuk Registrasi dan Update Nomor Telepon",
|
"For_Registration_and_Update_Phone_Number": "Untuk Registrasi dan Perbarui Nomor Telepon",
|
||||||
"Login_as_Customer": "Masuk sebagai Pelanggan",
|
"Login_as_Customer": "Masuk sebagai Pelanggan",
|
||||||
"Invalid_or_Expired_CSRF_Token": "Token CSRF Tidak Valid atau Kedaluwarsa",
|
"Invalid_or_Expired_CSRF_Token": "Token CSRF Tidak Valid atau Kedaluwarsa",
|
||||||
"Edit_Service_Package": "Edit Paket Layanan",
|
"Edit_Service_Package": "Edit Paket Layanan",
|
||||||
|
@ -778,8 +781,8 @@
|
||||||
"Home_Address": "Alamat Rumah",
|
"Home_Address": "Alamat Rumah",
|
||||||
"Email_Address": "Alamat Email",
|
"Email_Address": "Alamat Email",
|
||||||
"Custom_Balance": "Saldo Kustom",
|
"Custom_Balance": "Saldo Kustom",
|
||||||
"Input_Desired_Amount": "Masukkan Jumlah yang Diinginkan",
|
"Input_Desired_Amount": "Masukkan jumlah yang diinginkan",
|
||||||
"Advanced_Hotspot_System": "Sistem Hotspot Canggih",
|
"Advanced_Hotspot_System": "Sistem Hotspot Lanjutan",
|
||||||
"Successful_Payments": "Pembayaran Berhasil",
|
"Successful_Payments": "Pembayaran Berhasil",
|
||||||
"More_Info": "Info lebih lanjut",
|
"More_Info": "Info lebih lanjut",
|
||||||
"Failed_Payments": "Pembayaran Gagal",
|
"Failed_Payments": "Pembayaran Gagal",
|
||||||
|
@ -792,7 +795,7 @@
|
||||||
"_Click_this": "Klik ini",
|
"_Click_this": "Klik ini",
|
||||||
"_to_visit_the_hotspot_login_page": "untuk mengunjungi halaman login hotspot",
|
"_to_visit_the_hotspot_login_page": "untuk mengunjungi halaman login hotspot",
|
||||||
"_Choose_your_desired_plan__enter_your_phone_number_and_click_Pay_Now__you_will_be_redirected_to_payment_portal_": "Pilih paket yang Anda inginkan, masukkan nomor telepon Anda dan klik Bayar Sekarang, Anda akan diarahkan ke portal pembayaran.",
|
"_Choose_your_desired_plan__enter_your_phone_number_and_click_Pay_Now__you_will_be_redirected_to_payment_portal_": "Pilih paket yang Anda inginkan, masukkan nomor telepon Anda dan klik Bayar Sekarang, Anda akan diarahkan ke portal pembayaran.",
|
||||||
"_Pay_with_Demo_Success_": "Bayar dengan Demo Sukses.",
|
"_Pay_with_Demo_Success_": "Bayar dengan Demo berhasil.",
|
||||||
"_After_Successful_Payment_you_will_be_awarded_the_package_and_you_will_received_your_Voucher_Code_for_login_": "Setelah Pembayaran Berhasil, Anda akan diberikan paket dan Anda akan menerima Kode Voucher untuk login.",
|
"_After_Successful_Payment_you_will_be_awarded_the_package_and_you_will_received_your_Voucher_Code_for_login_": "Setelah Pembayaran Berhasil, Anda akan diberikan paket dan Anda akan menerima Kode Voucher untuk login.",
|
||||||
"_Come_back_here_to_see_your_hotspot_performance_at_a_glance_": "Kembali ke sini untuk melihat sekilas kinerja hotspot Anda.",
|
"_Come_back_here_to_see_your_hotspot_performance_at_a_glance_": "Kembali ke sini untuk melihat sekilas kinerja hotspot Anda.",
|
||||||
"Hotspot_Payment_History": "Riwayat Pembayaran Hotspot",
|
"Hotspot_Payment_History": "Riwayat Pembayaran Hotspot",
|
||||||
|
@ -825,7 +828,7 @@
|
||||||
"radius": "radius",
|
"radius": "radius",
|
||||||
"Max_30_days": "Maksimal 30 hari",
|
"Max_30_days": "Maksimal 30 hari",
|
||||||
"Information": "Informasi",
|
"Information": "Informasi",
|
||||||
"Export_and_Print_will_show_all_data_without_pagination": "Ekspor dan Cetak akan menampilkan semua data tanpa pagination",
|
"Export_and_Print_will_show_all_data_without_pagination": "Ekspor dan Cetak akan menampilkan semua data tanpa paginasi",
|
||||||
"First_Name": "Nama Depan",
|
"First_Name": "Nama Depan",
|
||||||
"Last_Name": "Nama Belakang",
|
"Last_Name": "Nama Belakang",
|
||||||
"General": "Umum",
|
"General": "Umum",
|
||||||
|
@ -885,7 +888,7 @@
|
||||||
"Select_Balance_Package_or_Custom_Amount": "Pilih Paket Saldo atau Jumlah Kustom",
|
"Select_Balance_Package_or_Custom_Amount": "Pilih Paket Saldo atau Jumlah Kustom",
|
||||||
"Or_custom_balance_amount_below": "Atau jumlah saldo khusus di bawah ini",
|
"Or_custom_balance_amount_below": "Atau jumlah saldo khusus di bawah ini",
|
||||||
"Balance_Amount": "Jumlah Saldo",
|
"Balance_Amount": "Jumlah Saldo",
|
||||||
"Input_custom_balance__will_ignore_plan_above": "Masukkan saldo khusus, akan mengabaikan rencana di atas",
|
"Input_custom_balance__will_ignore_plan_above": "Masukkan saldo khusus, akan mengabaikan paket di atas",
|
||||||
"Note": "Catatan",
|
"Note": "Catatan",
|
||||||
"Customer_Login_Page_Settings": "Pengaturan Halaman Login Pelanggan",
|
"Customer_Login_Page_Settings": "Pengaturan Halaman Login Pelanggan",
|
||||||
"Choose_Template": "Pilih Template",
|
"Choose_Template": "Pilih Template",
|
||||||
|
@ -909,5 +912,7 @@
|
||||||
"Mandatory_Fields": "Bidang yang wajib diisi",
|
"Mandatory_Fields": "Bidang yang wajib diisi",
|
||||||
"Single_Admin_Session": "Sesi Admin Tunggal",
|
"Single_Admin_Session": "Sesi Admin Tunggal",
|
||||||
"Mikrotik_SMS_Command": "Perintah SMS Mikrotik",
|
"Mikrotik_SMS_Command": "Perintah SMS Mikrotik",
|
||||||
"Expired_Cronjob_Every_5_Minutes__Recommended_": "Cronjob Kedaluwarsa Setiap 5 Menit [Direkomendasikan]"
|
"Expired_Cronjob_Every_5_Minutes__Recommended_": "Cronjob Kedaluwarsa Setiap 5 Menit [Direkomendasikan]",
|
||||||
|
"Visit": "Kunjungi",
|
||||||
|
"sync": "Sinkron"
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
"Log_in_to_Member_Panel": "Iniciar sesi\u00f3n en el panel de miembros",
|
"Log_in_to_Member_Panel": "Iniciar sesi\u00f3n en el panel de miembros",
|
||||||
"Register_as_Member": "Reg\u00edstrese como miembro",
|
"Register_as_Member": "Reg\u00edstrese como miembro",
|
||||||
"Enter_Admin_Area": "Panel de administraci\u00f3n",
|
"Enter_Admin_Area": "Panel de administraci\u00f3n",
|
||||||
"PHPNuxBill": "WENJEI",
|
"PHPNuxBill": "Compañia",
|
||||||
"Username": "Usuario",
|
"Username": "Usuario",
|
||||||
"Password": "Contrase\u00f1a",
|
"Password": "Contrase\u00f1a",
|
||||||
"Passwords_does_not_match": "Las contrase\u00f1as no coinciden",
|
"Passwords_does_not_match": "Las contrase\u00f1as no coinciden",
|
||||||
|
@ -541,7 +541,7 @@
|
||||||
"Agent": "Agente",
|
"Agent": "Agente",
|
||||||
"Session_has_expired__Please_log_in_again_": "La sesi\u00f3n ha expirado. Por favor, inicie sesi\u00f3n nuevamente.",
|
"Session_has_expired__Please_log_in_again_": "La sesi\u00f3n ha expirado. Por favor, inicie sesi\u00f3n nuevamente.",
|
||||||
"danger": "Peligro",
|
"danger": "Peligro",
|
||||||
"City": "Ciudad",
|
"City": "Pais",
|
||||||
"District": "Distrito",
|
"District": "Distrito",
|
||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"Zip": "C\u00f3digo Postal",
|
"Zip": "C\u00f3digo Postal",
|
||||||
|
@ -565,5 +565,278 @@
|
||||||
"Max_30_days": "M\u00e1ximo 30 d\u00edas",
|
"Max_30_days": "M\u00e1ximo 30 d\u00edas",
|
||||||
"Total": "Total",
|
"Total": "Total",
|
||||||
"Information": "Informaci\u00f3n",
|
"Information": "Informaci\u00f3n",
|
||||||
"Export_and_Print_will_show_all_data_without_pagination": "Exportar e imprimir mostrar\u00e1 todos los datos sin paginaci\u00f3n"
|
"Export_and_Print_will_show_all_data_without_pagination": "Exportar e imprimir mostrar\u00e1 todos los datos sin paginaci\u00f3n",
|
||||||
|
"Maps": "Mapas",
|
||||||
|
"Custom_Fields": "Campos personalizados",
|
||||||
|
"Cron_appear_not_been_setup__please_check_your_cron_setup_": "Aparece que no se ha configurado Cron, consulte su configuraci\u00f3n de Cron.",
|
||||||
|
"Check_if_Router_Online_": "\u00bfVerifique si Router Online?",
|
||||||
|
"To_check_whether_the_Router_is_online_or_not__please_visit_the_following_page": "Para verificar si el enrutador est\u00e1 en l\u00ednea o no, visite la p\u00e1gina siguiente",
|
||||||
|
"Cek_Now": "Cek ahora",
|
||||||
|
"Enable": "Permitir",
|
||||||
|
"Disable": "Desactivar",
|
||||||
|
"Router_Name___Location": "Nombre \/ ubicaci\u00f3n del enrutador",
|
||||||
|
"Coordinates": "Coordenadas",
|
||||||
|
"Coverage": "Cobertura",
|
||||||
|
"Continue_the_process_of_changing_Routers_": "\u00bfContinuar el proceso de cambiar los enrutadores?",
|
||||||
|
"First_Name": "Nombre",
|
||||||
|
"Last_Name": "Apellido",
|
||||||
|
"Plugin_Installer": "Instalador de plugin",
|
||||||
|
"Upload_Zip_Plugin_Theme_Device": "Subir el complemento\/tema\/dispositivo con zip",
|
||||||
|
"Install": "Instalar",
|
||||||
|
"CPU_Load": "Carga de la CPU",
|
||||||
|
"Temperature": "Temperatura",
|
||||||
|
"Voltage": "Voltaje",
|
||||||
|
"Wireless_Status": "Estado inal\u00e1mbrico",
|
||||||
|
"Interface_Status": "Estado de la interfaz",
|
||||||
|
"Hotspot_Online_Users": "Usuarios en l\u00ednea de hotspot",
|
||||||
|
"PPPoE_Online_Users": "Usuarios en l\u00ednea de PPPOE",
|
||||||
|
"Traffic_Monitor": "Monitor de tr\u00e1fico",
|
||||||
|
"Interface_Name": "Nombre de la interfaz",
|
||||||
|
"Tx__bytes_Out_": "Tx (bytes fuera)",
|
||||||
|
"Rx__bytes_In_": "Rx (bytes en)",
|
||||||
|
"Total_Usage": "Uso total",
|
||||||
|
"Uptime": "Tiempo de actividad",
|
||||||
|
"Server": "Servidor",
|
||||||
|
"Mac_Address": "Direcci\u00f3n MAC",
|
||||||
|
"Session_Time_Left": "Tiempo de sesi\u00f3n restante",
|
||||||
|
"Upload__RX_": "Cargue (RX)",
|
||||||
|
"Download__TX_": "Descargar (TX)",
|
||||||
|
"Service": "Servicio",
|
||||||
|
"Caller_ID": "Identificador de llamadas",
|
||||||
|
"Download": "Descargar",
|
||||||
|
"Upload": "Subir",
|
||||||
|
"Interface": "Interfaz",
|
||||||
|
"Last_Ip": "\u00daltima IP",
|
||||||
|
"Last_Activity": "\u00daltima actividad",
|
||||||
|
"Signal_Strength": "Resistencia a la se\u00f1al",
|
||||||
|
"Tx___Rx_CCQ": "TX \/ RX CCQ",
|
||||||
|
"Rx_Rate": "Tasa de rx",
|
||||||
|
"Tx_Rate": "Tasa de tx",
|
||||||
|
"Interace": "Interacci\u00f3n",
|
||||||
|
"TX": "Tx",
|
||||||
|
"RX": "Rx",
|
||||||
|
"Date_Time": "Fecha\/hora",
|
||||||
|
"Topic": "Tema",
|
||||||
|
"Send_Personal_Message": "Enviar mensaje personal",
|
||||||
|
"Send_Via": "Enviar",
|
||||||
|
"via_SMS": "a trav\u00e9s de SMS",
|
||||||
|
"Via_WhatsApp": "A trav\u00e9s de whatsapp",
|
||||||
|
"Via_WhatsApp_and_SMS": "A trav\u00e9s de whatsapp y sms",
|
||||||
|
"Compose_your_message___": "Componga tu mensaje ...",
|
||||||
|
"Use_placeholders_": "Use marcadores de posici\u00f3n:",
|
||||||
|
"Customer_Name": "Nombre del cliente",
|
||||||
|
"Customer_Username": "Nombre de usuario del cliente",
|
||||||
|
"Customer_Phone": "Tel\u00e9fono del cliente",
|
||||||
|
"Your_Company_Name": "Nombre de su empresa",
|
||||||
|
"Sign_in_into_your_account": "Inicie sesi\u00f3n en su cuenta",
|
||||||
|
"Usernames": "Nombre de usuario",
|
||||||
|
"Don_t_have_an_account_": "\u00bfNo tienes una cuenta?",
|
||||||
|
"General": "General",
|
||||||
|
"Pretty_URL": "Bonita url",
|
||||||
|
"rename__htaccess_firewall_to__htaccess": "renombrar .htaccess_firewall a .htaccess",
|
||||||
|
"Customer_Login_Page_Settings": "Configuraci\u00f3n de la p\u00e1gina de inicio de sesi\u00f3n del cliente",
|
||||||
|
"Choose_Template": "Elija plantilla",
|
||||||
|
"Custom": "Costumbre",
|
||||||
|
"Select_your_login_template_type": "Seleccione su tipo de plantilla de inicio de sesi\u00f3n",
|
||||||
|
"Select_Login_Page": "Seleccione la p\u00e1gina de inicio de sesi\u00f3n",
|
||||||
|
"Select_your_preferred_login_template": "Seleccione su plantilla de inicio de sesi\u00f3n preferida",
|
||||||
|
"Page_Heading___Company_Name": "Encabezado de p\u00e1gina \/ nombre de la empresa",
|
||||||
|
"This_Name_will_be_shown_on_the_login_wallpaper": "Este nombre se mostrar\u00e1 en el fondo de pantalla de inicio de sesi\u00f3n.",
|
||||||
|
"Page_Description": "Descripci\u00f3n de la p\u00e1gina",
|
||||||
|
"This_will_also_display_on_wallpaper__You_can_use_html_tag": "Esto tambi\u00e9n se mostrar\u00e1 en papel tapiz, puede usar la etiqueta HTML",
|
||||||
|
"Favicon": "Favic\u00f3n",
|
||||||
|
"Best_size_30_x_30___uploaded_image_will_be_autosize": "El mejor tama\u00f1o 30 x 30 | La imagen cargada se automatizar\u00e1",
|
||||||
|
"Login_Page_Logo": "Logotipo de la p\u00e1gina de inicio de sesi\u00f3n",
|
||||||
|
"Best_size_300_x_60___uploaded_image_will_be_autosize": "El mejor tama\u00f1o 300 x 60 | La imagen cargada se automatizar\u00e1",
|
||||||
|
"Login_Page_Wallpaper": "Fondo de pantalla de la p\u00e1gina de inicio de sesi\u00f3n",
|
||||||
|
"Best_size_1920_x_1080___uploaded_image_will_be_autosize": "El mejor tama\u00f1o 1920 x 1080 | La imagen cargada se automatizar\u00e1",
|
||||||
|
"Registration": "Registro",
|
||||||
|
"Allow_Registration": "Permitir el registro",
|
||||||
|
"No_Registration": "Sin registro",
|
||||||
|
"Registration_Username": "Nombre de usuario de registro",
|
||||||
|
"Photo_Required": "Foto requerida",
|
||||||
|
"Customer_Registration_need_to_upload_their_photo": "El registro del cliente necesita subir su foto",
|
||||||
|
"Customer_Registration_need_to_validate_using_OTP": "El registro del cliente debe validar con OTP",
|
||||||
|
"For_Registration_and_Update_Phone_Number": "Para el n\u00famero de tel\u00e9fono de registro y actualizaci\u00f3n",
|
||||||
|
"Notify_Admin": "Notificar a administrador",
|
||||||
|
"Notify_Admin_upon_self_registration": "Notificar al administrador sobre el registro autom\u00e1tico",
|
||||||
|
"Mandatory_Fields": "Campos obligatorios",
|
||||||
|
"Security": "Seguridad",
|
||||||
|
"Single_Admin_Session": "Sesi\u00f3n de administrador \u00fanica",
|
||||||
|
"Admin_can_only_have_single_session_login__it_will_logout_another_session": "El administrador solo puede tener inicio de sesi\u00f3n de una sola sesi\u00f3n, iniciar\u00e1 sesi\u00f3n en otra sesi\u00f3n",
|
||||||
|
"Enable_CSRF_Validation": "Habilitar la validaci\u00f3n de CSRF",
|
||||||
|
"Cross_site_request_forgery": "Falsificaci\u00f3n de solicitud de sitio cruzado",
|
||||||
|
"SMS_Notification": "Notificaci\u00f3n de SMS",
|
||||||
|
"Mikrotik_SMS_Command": "Comando de mikrotik sms",
|
||||||
|
"Tax_Rates_by_percentage": "Tasas impositivas por porcentaje",
|
||||||
|
"Settings_For_Mikrotik": "Configuraci\u00f3n para Mikrotik",
|
||||||
|
"Settings_For_Cron_Expired": "Configuraci\u00f3n para Cron expirado",
|
||||||
|
"Expired_Cronjob_Every_5_Minutes__Recommended_": "Cronjob vencido cada 5 minutos [recomendado]",
|
||||||
|
"Settings_For_Cron_Reminder": "Configuraci\u00f3n para el recordatorio de Cron",
|
||||||
|
"Login_Page_Settings_Saved_Successfully": "Configuraci\u00f3n de la p\u00e1gina de inicio de sesi\u00f3n guardada correctamente",
|
||||||
|
"Logout_Successful": "INCOMPTIR SEXITO",
|
||||||
|
"warning": "Advertencia",
|
||||||
|
"Go_Back": "Volver",
|
||||||
|
"Validate": "Validar",
|
||||||
|
"Forgot_Usernames": "Olvid\u00e9 nombres de usuario",
|
||||||
|
"You_are_already_logged_in": "Ya est\u00e1s iniciado",
|
||||||
|
"Hello": "Hola",
|
||||||
|
"your_internet_package": "Tu paquete de Internet",
|
||||||
|
"has_been_expired": "ha sido expirado",
|
||||||
|
"will_be_replaced_with_Customer_Name": "ser\u00e1 reemplazado por el nombre del cliente",
|
||||||
|
"will_be_replaced_with_Customer_username": "ser\u00e1 reemplazado por el nombre de usuario del cliente",
|
||||||
|
"will_be_replaced_with_Package_name": "ser\u00e1 reemplazado por el nombre del paquete",
|
||||||
|
"will_be_replaced_with_Package_price": "ser\u00e1 reemplazado por el precio del paquete",
|
||||||
|
"additional_bills_for_customers": "facturas adicionales para los clientes",
|
||||||
|
"will_be_replaced_with_Expiration_date": "ser\u00e1 reemplazado por la fecha de vencimiento",
|
||||||
|
"Your_Company_Name_at_Settings": "Nombre de su empresa en la configuraci\u00f3n",
|
||||||
|
"Your_Company_Address_at_Settings": "Direcci\u00f3n de su empresa en la configuraci\u00f3n",
|
||||||
|
"Your_Company_Phone_at_Settings": "Tel\u00e9fono de su empresa en la configuraci\u00f3n",
|
||||||
|
"Invoice_number": "N\u00famero de factura",
|
||||||
|
"Date_invoice_created": "Factura de fecha creada",
|
||||||
|
"Payment_gateway_user_paid_from": "El usuario de la pasarela de pago pagado por",
|
||||||
|
"Payment_channel_user_paid_from": "Usuario de canal de pago pagado desde",
|
||||||
|
"is_Hotspot_or_PPPOE": "es hotspot o pppoe",
|
||||||
|
"Internet_Package_Prices": "Precios de paquetes de Internet",
|
||||||
|
"Receiver_name": "Nombre del receptor",
|
||||||
|
"Username_internet": "Nombre de usuario Internet",
|
||||||
|
"User_password": "Contrase\u00f1a de usuario",
|
||||||
|
"Expired_datetime": "Expirado de fecha y hora",
|
||||||
|
"For_Notes_by_admin": "Para notas de admin",
|
||||||
|
"Transaction_datetime": "Transacci\u00f3n data de data",
|
||||||
|
"Balance_Before": "Equilibrar antes",
|
||||||
|
"Balance_After": "Equilibrar",
|
||||||
|
"Welcome_Message": "Mensaje de bienvenida",
|
||||||
|
"will_be_replaced_with_Customer_password": "ser\u00e1 reemplazado por la contrase\u00f1a del cliente",
|
||||||
|
"will_be_replaced_with_Customer_Portal_URL": "ser\u00e1 reemplazado por URL del portal del cliente",
|
||||||
|
"will_be_replaced_with_Company_Name": "ser\u00e1 reemplazado por el nombre de la empresa",
|
||||||
|
"Save": "Guardar",
|
||||||
|
"Save_as_template": "Guardar como plantilla",
|
||||||
|
"Template_Name": "Nombre de plantilla",
|
||||||
|
"Package_Price": "Precio del paquete",
|
||||||
|
"Voucher_Code": "C\u00f3digo de cup\u00f3n",
|
||||||
|
"Voucher_Package": "Paquete de cupones",
|
||||||
|
"Counter": "Contador",
|
||||||
|
"Sub_District": "Distrito",
|
||||||
|
"Ward": "Código Postal",
|
||||||
|
"Profile": "Perfil",
|
||||||
|
"Photo": "Foto",
|
||||||
|
"Phone": "Tel\u00e9fono",
|
||||||
|
"Credentials": "Cartas credenciales",
|
||||||
|
"RB5009_39": "RB5009-39",
|
||||||
|
"Admin": "Administraci\u00f3n",
|
||||||
|
"VPN_Plans": "Planes VPN",
|
||||||
|
"Using": "Usando",
|
||||||
|
"Postpaid_Recharge_for_the_first_time_use": "Recarga pospago por primera vez uso",
|
||||||
|
"Or": "O",
|
||||||
|
"Confirm": "Confirmar",
|
||||||
|
"Name": "Nombre",
|
||||||
|
"Plan": "Plan",
|
||||||
|
"Resend": "Revender",
|
||||||
|
"Home_Address": "Direcci\u00f3n de la casa",
|
||||||
|
"Other": "Otro",
|
||||||
|
"Business": "Negocio",
|
||||||
|
"Not_Working_for_freeradius": "No funciona para freeradius",
|
||||||
|
"Also_Working_for_freeradius": "Tambi\u00e9n trabajando para freeradius",
|
||||||
|
"User_Cannot_change_this__only_admin__if_it_Empty_it_will_use_Customer_Credentials": "El usuario no puede cambiar esto, solo administrador. Si se vac\u00eda, usar\u00e1 las credenciales del cliente",
|
||||||
|
"Send_welcome_message": "Enviar mensaje de bienvenida",
|
||||||
|
"Notification_via": "Notificaci\u00f3n a trav\u00e9s de",
|
||||||
|
"SMS": "SMS",
|
||||||
|
"WA": "Whatsapp",
|
||||||
|
"Attributes": "Atributos",
|
||||||
|
"Additional_Information": "informaci\u00f3n adicional",
|
||||||
|
"City_of_Resident": "Ciudad del residente",
|
||||||
|
"State_of_Resident": "Estado de residente",
|
||||||
|
"Zip_Code": "C\u00f3digo postal",
|
||||||
|
"Continue_the_process_of_adding_Customer_Data_": "\u00bfContinuar el proceso de agregar datos de clientes?",
|
||||||
|
"Customer_cannot_buy_disabled_Package__but_admin_can_recharge_it__use_it_if_you_want_only_admin_recharge_it": "El cliente no puede comprar el paquete discapacitado, pero el administrador puede recargarlo, usarlo si solo desea recargarlo de administrador",
|
||||||
|
"Postpaid_will_have_fix_expired_date": "Postpaid tendr\u00e1 una fecha vencida",
|
||||||
|
"Prepaid": "Pagado",
|
||||||
|
"Postpaid": "Pospago",
|
||||||
|
"Personal_Package_will_only_show_to_personal_Customer__Business_Package_will_only_show_to_Business_Customer": "El paquete personal solo se mostrar\u00e1 al cliente personal, el paquete comercial solo se mostrar\u00e1 al cliente empresarial",
|
||||||
|
"Device": "Dispositivo",
|
||||||
|
"This_Device_are_the_logic_how_PHPNuxBill_Communicate_with_Mikrotik_or_other_Devices": "Este dispositivo es la l\u00f3gica de c\u00f3mo PhpNuxbill se comunica con Mikrotik u otros dispositivos",
|
||||||
|
"Price_Before_Discount": "Precio antes de descuento",
|
||||||
|
"For_Discount_Rate__this_is_price_before_get_discount__must_be_more_expensive_with_real_price": "Para una tasa de descuento, este es el precio antes de obtener descuento, debe ser m\u00e1s costoso con un precio real",
|
||||||
|
"1_Period___1_Month__Expires_the_20th_of_each_month": "1 per\u00edodo = 1 mes, expira el 20 de cada mes",
|
||||||
|
"Expired_Date": "Fecha vencida",
|
||||||
|
"Expired_will_be_this_date_every_month": "Caducado ser\u00e1 esta fecha cada mes",
|
||||||
|
"Expired_Action": "Acci\u00f3n vencida",
|
||||||
|
"Optional": "Opcional",
|
||||||
|
"Expired_Internet_Plan": "Plan de Internet vencido",
|
||||||
|
"When_Expired__customer_will_be_move_to_selected_internet_plan": "Cuando expire, el cliente se trasladar\u00e1 al plan de Internet seleccionado",
|
||||||
|
"on_login___on_up": "en el login \/ encendido",
|
||||||
|
"on_logout___on_down": "On-Logout \/ On-Down",
|
||||||
|
"Continue_the_PPPoE_Package_change_process_": "\u00bfContinuar el proceso de cambio de paquete PPPOE?",
|
||||||
|
"Period": "Per\u00edodo",
|
||||||
|
"Login_as_Customer": "Iniciar sesi\u00f3n como cliente",
|
||||||
|
"Rate": "Tasa",
|
||||||
|
"Create_Bandwidth_Package_for_expired_Internet_Package": "Crear paquete de ancho de banda para paquete de Internet vencido",
|
||||||
|
"When_customer_expired__you_can_move_it_to_Expired_Internet_Package": "Cuando el cliente caduque, podr\u00e1 moverlo a Paquete de Internet Caducado",
|
||||||
|
"Category": "Categor\u00eda",
|
||||||
|
"Create_expired_Internet_Plan": "Crear plan de Internet vencido",
|
||||||
|
"When_customer_expired__you_can_move_it_to_Expired_Internet_Plan": "Cuando el cliente caduque, podr\u00e1 moverlo a Plan de Internet Caducado",
|
||||||
|
"Personal_Package_will_only_show_to_personal_Customer__Business_package_will_only_show_to_Business_Customer": "El paquete personal solo se mostrar\u00e1 a los clientes personales, el paquete comercial solo se mostrar\u00e1 a los clientes comerciales",
|
||||||
|
"Continue_the_process_of_adding_the_PPPoE_Package_": "\u00bfContinuar con el proceso de agregar el paquete PPPoE?",
|
||||||
|
"Face_Detection": "Detecci\u00f3n de rostros",
|
||||||
|
"Customer_cannot_login_again": "El cliente no puede iniciar sesi\u00f3n nuevamente",
|
||||||
|
"Customer_can_login_but_cannot_buy_internet_package__Admin_cannot_recharge_customer": "El cliente puede iniciar sesi\u00f3n pero no puede comprar un paquete de Internet. El administrador no puede recargar al cliente.",
|
||||||
|
"Don_t_forget_to_deactivate_all_active_package_too": "No olvides desactivar tambi\u00e9n todos los paquetes activos.",
|
||||||
|
"Not_Working_with_Freeradius_Mysql": "No funciona con Freeradius Mysql",
|
||||||
|
"Continue_the_Customer_Data_change_process_": "\u00bfContinuar con el proceso de cambio de datos del cliente?",
|
||||||
|
"Port_Pool": "Grupo de puerto",
|
||||||
|
"New_port": "Nuevo puerto",
|
||||||
|
"Port_Name": "Nombre del puerto",
|
||||||
|
"Public_IP": "IP p\u00fablica",
|
||||||
|
"Range_Port": "Rango de Puertos",
|
||||||
|
"Add_Port_Pool": "Agregar grupo de puertos",
|
||||||
|
"Continue_the_process_of_adding_Ports_": "\u00bfContinuar con el proceso de agregar puertos?",
|
||||||
|
"Continue_the_VPN_creation_process_": "\u00bfContinuar con el proceso de creaci\u00f3n de VPN?",
|
||||||
|
"": "",
|
||||||
|
"Local_IP": "IP local",
|
||||||
|
"Test_Connection": "Conexi\u00f3n de prueba",
|
||||||
|
"Continue_the_process_of_adding_Routers_": "\u00bfContinuar con el proceso de agregar enrutadores?",
|
||||||
|
"Continue_the_Pool_addition_process_": "\u00bfContinuar con el proceso de adici\u00f3n de la piscina?",
|
||||||
|
"Private_IP": "IP privada",
|
||||||
|
"Sync_account_if_you_failed_login_to_internet": "Sincronizar cuenta si no se pudo iniciar sesi\u00f3n en Internet",
|
||||||
|
"Data_Change": "Cambio de datos",
|
||||||
|
"Face_Detect": "Detecci\u00f3n de rostro",
|
||||||
|
"Email_Address": "Direcci\u00f3n de correo electr\u00f3nico",
|
||||||
|
"Transaction_History_List": "Lista de historial de transacciones",
|
||||||
|
"Contabo": "Contabo",
|
||||||
|
"Not_Active": "No activo",
|
||||||
|
"New_Service_Package": "Nuevo paquete de servicios",
|
||||||
|
"Limit": "L\u00edmite",
|
||||||
|
"Time": "Tiempo",
|
||||||
|
"Data": "Datos",
|
||||||
|
"ID": "IDENTIFICACI\u00d3N",
|
||||||
|
"Create_expired_Internet_Package": "Crear paquete de Internet vencido",
|
||||||
|
"Oops__The_page_you_are_looking_for_was_not_found": "\u00a1Ups! La p\u00e1gina que est\u00e1 buscando no fue encontrada",
|
||||||
|
"Back_to_Dashboard": "Volver al panel de control",
|
||||||
|
"Add_User": "Agregar usuario",
|
||||||
|
"Report_Viewer": "Visor de informes",
|
||||||
|
"Super_Administrator": "Super administrador",
|
||||||
|
"Send_Notification": "Enviar notificaci\u00f3n",
|
||||||
|
"Don_t_Send": "No env\u00ede",
|
||||||
|
"Registration_successful": "Registro exitoso",
|
||||||
|
"New_User_Registration": "Registro de nuevo usuario",
|
||||||
|
"New_Field": "Nuevo campo",
|
||||||
|
"Installed_Devices": "Dispositivos instalados",
|
||||||
|
"Miscellaneous_Settings": "Configuraciones varias",
|
||||||
|
"Display_bandwidth_plan_for_customer": "Mostrar plan de ancho de banda para el cliente",
|
||||||
|
"Radius_Rest_Interim_Update": "Actualizaci\u00f3n provisional de Radius Rest",
|
||||||
|
"in_minutes__leave_0_to_disable_this_feature_": "en minutos, deje 0 para deshabilitar esta funci\u00f3n.",
|
||||||
|
"Check_if_Customer_Online": "Verificar si el cliente est\u00e1 en l\u00ednea",
|
||||||
|
"This_will_show_is_Customer_currently_is_online_or_not": "Esto mostrar\u00e1 si el cliente est\u00e1 actualmente en l\u00ednea o no.",
|
||||||
|
"Allow_Balance_Custom_Amount": "Permitir saldo Importe personalizado",
|
||||||
|
"Allow_Customer_buy_balance_with_any_amount": "Permitir al Cliente comprar saldo con cualquier monto",
|
||||||
|
"Make_sure_you_use_API_Port__Default_8728": "Aseg\u00farese de utilizar el puerto API, predeterminado 8728",
|
||||||
|
"Make_sure_Username_and_Password_are_correct": "Aseg\u00farese de que el nombre de usuario y la contrase\u00f1a sean correctos",
|
||||||
|
"Make_sure_your_hosting_not_blocking_port_to_external": "Aseg\u00farese de que su hosting no bloquee el puerto al externo",
|
||||||
|
"Make_sure_your_Mikrotik_accessible_from_PHPNuxBill": "Aseg\u00farese de que su Mikrotik sea accesible desde PHPNuxBill",
|
||||||
|
"If_you_just_update_PHPNuxBill_from_upload_files__try_click_Update": "Si simplemente actualiza PHPNuxBill desde la carga de archivos, intente hacer clic en Actualizar",
|
||||||
|
"Update": "Actualizar",
|
||||||
|
"Update_PHPNuxBill": "Actualizar PHPNuxBill",
|
||||||
|
"Ask_Github_Community": "Pregunta a la comunidad de Github",
|
||||||
|
"Ask_Telegram_Community": "Pregunta a la comunidad de Telegram"
|
||||||
}
|
}
|
|
@ -1483,6 +1483,14 @@ class ORM implements ArrayAccess
|
||||||
return $this->_add_simple_where($column_name, 'LIKE', $value);
|
return $this->_add_simple_where($column_name, 'LIKE', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add any WHERE ... LIKE clause to your query.
|
||||||
|
*/
|
||||||
|
public function where_likes($column = null, $values = null)
|
||||||
|
{
|
||||||
|
return $this->_addWhere('(' . implode(' LIKE ? OR ', $column) . ' LIKE ? )', $values);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add where WHERE ... NOT LIKE clause to your query.
|
* Add where WHERE ... NOT LIKE clause to your query.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -187,5 +187,24 @@
|
||||||
],
|
],
|
||||||
"2025.1.23": [
|
"2025.1.23": [
|
||||||
"ALTER TABLE `rad_acct` ADD `acctsessiontime` BIGINT(12) NOT NULL DEFAULT '0' AFTER `framedipaddress`;"
|
"ALTER TABLE `rad_acct` ADD `acctsessiontime` BIGINT(12) NOT NULL DEFAULT '0' AFTER `framedipaddress`;"
|
||||||
|
],
|
||||||
|
"2025.2.14": [
|
||||||
|
"CREATE TABLE IF NOT EXISTS `tbl_widgets` ( `id` int NOT NULL AUTO_INCREMENT, `orders` int NOT NULL DEFAULT '99', `position` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1. top 2. left 3. right 4. bottom',`enabled` tinyint(1) NOT NULL DEFAULT '1', `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `widget` varchar(64) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', `content` text COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;"
|
||||||
|
],
|
||||||
|
"2025.2.17" : [
|
||||||
|
"INSERT INTO `tbl_widgets` (`id`, `orders`, `position`, `enabled`, `title`, `widget`, `content`) VALUES (1, 1, 1, 1, 'Top Widget', 'top_widget', ''),(2, 2, 1, 1, 'Default Info', 'default_info_row', ''),(3, 1, 2, 1, 'Graph Monthly Registered Customers', 'graph_monthly_registered_customers', ''),(4, 2, 2, 1, 'Graph Monthly Sales', 'graph_monthly_sales', ''),(5, 3, 2, 1, 'Voucher Stocks', 'voucher_stocks', ''),(6, 4, 2, 1, 'Customer Expired', 'customer_expired', ''),(7, 1, 3, 1, 'Cron Monitor', 'cron_monitor', ''),(8, 2, 3, 1, 'Mikrotik Cron Monitor', 'mikrotik_cron_monitor', ''),(9, 3, 3, 1, 'Info Payment Gateway', 'info_payment_gateway', ''),(10, 4, 3, 1, 'Graph Customers Insight', 'graph_customers_insight', ''),(11, 5, 3, 1, 'Activity Log', 'activity_log', '');"
|
||||||
|
],
|
||||||
|
"2025.2.19" : [
|
||||||
|
"ALTER TABLE `tbl_widgets` ADD `user` ENUM('Admin','Agent','Sales','Customer') NOT NULL DEFAULT 'Admin' AFTER `position`;"
|
||||||
|
],
|
||||||
|
"2025.2.21" : [
|
||||||
|
"INSERT INTO `tbl_widgets` (`id`, `orders`, `position`, `user`, `enabled`, `title`, `widget`, `content`) VALUES (60, 1, 2, 'Customer', 1, 'Account Info', 'account_info', ''),(61, 3, 1, 'Customer', 1, 'Active Internet Plan', 'active_internet_plan', ''),(62, 4, 1, 'Customer', 1, 'Balance Transfer', 'balance_transfer', ''),(63, 1, 1, 'Customer', 1, 'Unpaid Order', 'unpaid_order', ''),(64, 2, 1, 'Customer', 1, 'Announcement', 'announcement', ''),(65, 5, 1, 'Customer', 1, 'Recharge A Friend', 'recharge_a_friend', ''),(66, 2, 2, 'Customer', 1, 'Voucher Activation', 'voucher_activation', '');"
|
||||||
|
],
|
||||||
|
"2025.2.25" : [
|
||||||
|
"INSERT INTO `tbl_widgets` (`id`, `orders`, `position`, `user`, `enabled`, `title`, `widget`, `content`) VALUES (30, 1, 1, 'Agent', 1, 'Top Widget', 'top_widget', ''), (31, 2, 1, 'Agent', 1, 'Default Info', 'default_info_row', ''), (32, 1, 2, 'Agent', 1, 'Graph Monthly Registered Customers', 'graph_monthly_registered_customers', ''), (33, 2, 2, 'Agent', 1, 'Graph Monthly Sales', 'graph_monthly_sales', ''), (34, 3, 2, 'Agent', 1, 'Voucher Stocks', 'voucher_stocks', ''), (35, 4, 2, 'Agent', 1, 'Customer Expired', 'customer_expired', ''), (36, 1, 3, 'Agent', 1, 'Cron Monitor', 'cron_monitor', ''), (37, 2, 3, 'Agent', 1, 'Mikrotik Cron Monitor', 'mikrotik_cron_monitor', ''), (38, 3, 3, 'Agent', 1, 'Info Payment Gateway', 'info_payment_gateway', ''), (39, 4, 3, 'Agent', 1, 'Graph Customers Insight', 'graph_customers_insight', ''),(40, 5, 3, 'Agent', 1, 'Activity Log', 'activity_log', '');",
|
||||||
|
"INSERT INTO `tbl_widgets` (`id`, `orders`, `position`, `user`, `enabled`, `title`, `widget`, `content`) VALUES (41, 1, 1, 'Sales', 1, 'Top Widget', 'top_widget', ''), (42, 2, 1, 'Sales', 1, 'Default Info', 'default_info_row', ''), (43, 1, 2, 'Sales', 1, 'Graph Monthly Registered Customers', 'graph_monthly_registered_customers', ''), (44, 2, 2, 'Sales', 1, 'Graph Monthly Sales', 'graph_monthly_sales', ''), (45, 3, 2, 'Sales', 1, 'Voucher Stocks', 'voucher_stocks', ''), (46, 4, 2, 'Sales', 1, 'Customer Expired', 'customer_expired', ''), (47, 1, 3, 'Sales', 1, 'Cron Monitor', 'cron_monitor', ''), (48, 2, 3, 'Sales', 1, 'Mikrotik Cron Monitor', 'mikrotik_cron_monitor', ''), (49, 3, 3, 'Sales', 1, 'Info Payment Gateway', 'info_payment_gateway', ''), (50, 4, 3, 'Sales', 1, 'Graph Customers Insight', 'graph_customers_insight', ''), (51, 5, 3, 'Sales', 1, 'Activity Log', 'activity_log', '');"
|
||||||
|
],
|
||||||
|
"2025.3.5" : [
|
||||||
|
"CREATE TABLE IF NOT EXISTS `tbl_message_logs` ( `id` SERIAL PRIMARY KEY, `message_type` VARCHAR(50), `recipient` VARCHAR(255), `message_content` TEXT, `status` VARCHAR(50), `error_message` TEXT, `sent_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;"
|
||||||
]
|
]
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
BIN
system/uploads/paid.png
Normal file
BIN
system/uploads/paid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSansCondensed-Oblique.ttf
vendored
Normal file
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSansCondensed-Oblique.ttf
vendored
Normal file
Binary file not shown.
15
system/widgets/activity_log.php
Normal file
15
system/widgets/activity_log.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class activity_log
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $config, $ui, $current_date, $start_date;
|
||||||
|
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->findArray();
|
||||||
|
$ui->assign('dlog', $dlog);
|
||||||
|
// $log = ORM::for_table('tbl_logs')->count();
|
||||||
|
// $ui->assign('log', $log);
|
||||||
|
return $ui->fetch('widget/activity_log.tpl');
|
||||||
|
}
|
||||||
|
}
|
17
system/widgets/cron_monitor.php
Normal file
17
system/widgets/cron_monitor.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class cron_monitor
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $UPLOAD_PATH,$ui;
|
||||||
|
|
||||||
|
$timestampFile = "$UPLOAD_PATH/cron_last_run.txt";
|
||||||
|
if (file_exists($timestampFile)) {
|
||||||
|
$lastRunTime = file_get_contents($timestampFile);
|
||||||
|
$ui->assign('run_date', date('Y-m-d h:i:s A', $lastRunTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ui->fetch('widget/cron_monitor.tpl');
|
||||||
|
}
|
||||||
|
}
|
14
system/widgets/customer/account_info.php
Normal file
14
system/widgets/customer/account_info.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class account_info
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
|
||||||
|
$abills = User::getAttributes("Bill");
|
||||||
|
$ui->assign('abills', $abills);
|
||||||
|
return $ui->fetch('widget/customers/account_info.tpl');
|
||||||
|
}
|
||||||
|
}
|
20
system/widgets/customer/active_internet_plan.php
Normal file
20
system/widgets/customer/active_internet_plan.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class active_internet_plan
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui, $user;
|
||||||
|
$_bill = User::_billing();
|
||||||
|
$ui->assign('_bills', $_bill);
|
||||||
|
$tcf = ORM::for_table('tbl_customers_fields')
|
||||||
|
->where('customer_id', $user['id'])
|
||||||
|
->find_many();
|
||||||
|
$vpn = ORM::for_table('tbl_port_pool')
|
||||||
|
->find_one();
|
||||||
|
$ui->assign('cf', $tcf);
|
||||||
|
$ui->assign('vpn', $vpn);
|
||||||
|
return $ui->fetch('widget/customers/active_internet_plan.tpl');
|
||||||
|
}
|
||||||
|
}
|
11
system/widgets/customer/announcement.php
Normal file
11
system/widgets/customer/announcement.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class announcement
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
return $ui->fetch('widget/customers/announcement.tpl');
|
||||||
|
}
|
||||||
|
}
|
11
system/widgets/customer/balance_transfer.php
Normal file
11
system/widgets/customer/balance_transfer.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class balance_transfer
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
return $ui->fetch('widget/customers/balance_transfer.tpl');
|
||||||
|
}
|
||||||
|
}
|
11
system/widgets/customer/button_order_internet_plan.php
Normal file
11
system/widgets/customer/button_order_internet_plan.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class button_order_internet_plan
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
return $ui->fetch('widget/customers/button_order_internet_plan.tpl');
|
||||||
|
}
|
||||||
|
}
|
11
system/widgets/customer/html_only.php
Normal file
11
system/widgets/customer/html_only.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class html_only
|
||||||
|
{
|
||||||
|
|
||||||
|
public function getWidget($data = null)
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
return $data['content'];
|
||||||
|
}
|
||||||
|
}
|
22
system/widgets/customer/html_php.php
Normal file
22
system/widgets/customer/html_php.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class html_php
|
||||||
|
{
|
||||||
|
|
||||||
|
public function getWidget($data = null)
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
$ui->assign('card_header', $data['title']);
|
||||||
|
ob_start();
|
||||||
|
try{
|
||||||
|
eval('?>'. $data['content']);
|
||||||
|
}catch(Exception $e){
|
||||||
|
echo $e->getMessage();
|
||||||
|
echo "<br>";
|
||||||
|
echo $e->getTraceAsString();
|
||||||
|
}
|
||||||
|
$content = ob_get_clean();
|
||||||
|
$ui->assign('card_body', $content);
|
||||||
|
return $ui->fetch('widget/card_html.tpl');
|
||||||
|
}
|
||||||
|
}
|
11
system/widgets/customer/recharge_a_friend.php
Normal file
11
system/widgets/customer/recharge_a_friend.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class recharge_a_friend
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
return $ui->fetch('widget/customers/recharge_a_friend.tpl');
|
||||||
|
}
|
||||||
|
}
|
39
system/widgets/customer/unpaid_order.php
Normal file
39
system/widgets/customer/unpaid_order.php
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class unpaid_order
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui, $user;
|
||||||
|
$unpaid = ORM::for_table('tbl_payment_gateway')
|
||||||
|
->where('username', $user['username'])
|
||||||
|
->where('status', 1)
|
||||||
|
->find_one();
|
||||||
|
|
||||||
|
// check expired payments
|
||||||
|
if ($unpaid) {
|
||||||
|
try {
|
||||||
|
if (strtotime($unpaid['expired_date']) < time()) {
|
||||||
|
$unpaid->status = 4;
|
||||||
|
$unpaid->save();
|
||||||
|
$unpaid = [];
|
||||||
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (strtotime($unpaid['created_date'], "+24 HOUR") < time()) {
|
||||||
|
$unpaid->status = 4;
|
||||||
|
$unpaid->save();
|
||||||
|
$unpaid = [];
|
||||||
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('unpaid', $unpaid);
|
||||||
|
return $ui->fetch('widget/customers/unpaid_order.tpl');
|
||||||
|
}
|
||||||
|
}
|
11
system/widgets/customer/voucher_activation.php
Normal file
11
system/widgets/customer/voucher_activation.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class voucher_activation
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
return $ui->fetch('widget/customers/voucher_activation.tpl');
|
||||||
|
}
|
||||||
|
}
|
63
system/widgets/customer_expired.php
Normal file
63
system/widgets/customer_expired.php
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class customer_expired
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui, $current_date, $config;
|
||||||
|
|
||||||
|
//user expire
|
||||||
|
$query = ORM::for_table('tbl_user_recharges')
|
||||||
|
->table_alias('tur')
|
||||||
|
->selects([
|
||||||
|
'c.id',
|
||||||
|
'tur.username',
|
||||||
|
'c.fullname',
|
||||||
|
'c.phonenumber',
|
||||||
|
'c.email',
|
||||||
|
'tur.expiration',
|
||||||
|
'tur.time',
|
||||||
|
'tur.recharged_on',
|
||||||
|
'tur.recharged_time',
|
||||||
|
'tur.namebp',
|
||||||
|
'tur.routers'
|
||||||
|
])
|
||||||
|
->innerJoin('tbl_customers', ['tur.customer_id', '=', 'c.id'], 'c')
|
||||||
|
->where_lte('expiration', $current_date)
|
||||||
|
->order_by_desc('expiration');
|
||||||
|
$expire = Paginator::findMany($query);
|
||||||
|
|
||||||
|
// Get the total count of expired records for pagination
|
||||||
|
$totalCount = ORM::for_table('tbl_user_recharges')
|
||||||
|
->where_lte('expiration', $current_date)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
// Pass the total count and current page to the paginator
|
||||||
|
$paginator['total_count'] = $totalCount;
|
||||||
|
|
||||||
|
if(!empty($_COOKIE['expdef']) && $_COOKIE['expdef'] != $config['customer_expired_expdef']) {
|
||||||
|
$d = ORM::for_table('tbl_appconfig')->where('setting', 'customer_expired_expdef')->find_one();
|
||||||
|
if ($d) {
|
||||||
|
$d->value = $_COOKIE['expdef'];
|
||||||
|
$d->save();
|
||||||
|
} else {
|
||||||
|
$d = ORM::for_table('tbl_appconfig')->create();
|
||||||
|
$d->setting = 'customer_expired_expdef';
|
||||||
|
$d->value = $_COOKIE['expdef'];
|
||||||
|
$d->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!empty($config['customer_expired_expdef']) && empty($_COOKIE['expdef'])){
|
||||||
|
$_COOKIE['expdef'] = $config['customer_expired_expdef'];
|
||||||
|
setcookie('expdef', $config['customer_expired_expdef'], time() + (86400 * 30), "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the pagination HTML to the template variable
|
||||||
|
$ui->assign('expire', $expire);
|
||||||
|
$ui->assign('cookie', $_COOKIE);
|
||||||
|
return $ui->fetch('widget/customer_expired.tpl');
|
||||||
|
}
|
||||||
|
}
|
17
system/widgets/default_info_row.php
Normal file
17
system/widgets/default_info_row.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class default_info_row
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $config,$ui;
|
||||||
|
|
||||||
|
if ($config['enable_balance'] == 'yes'){
|
||||||
|
$cb = ORM::for_table('tbl_customers')->whereGte('balance', 0)->sum('balance');
|
||||||
|
$ui->assign('cb', $cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $ui->fetch('widget/default_info_row.tpl');
|
||||||
|
}
|
||||||
|
}
|
28
system/widgets/graph_customers_insight.php
Normal file
28
system/widgets/graph_customers_insight.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class graph_customers_insight
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $CACHE_PATH,$ui;
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$u_all = ORM::for_table('tbl_user_recharges')->count();
|
||||||
|
if (empty($u_all)) {
|
||||||
|
$u_all = '0';
|
||||||
|
}
|
||||||
|
$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);
|
||||||
|
return $ui->fetch('widget/graph_customers_insight.tpl');
|
||||||
|
}
|
||||||
|
}
|
38
system/widgets/graph_monthly_registered_customers.php
Normal file
38
system/widgets/graph_monthly_registered_customers.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class graph_monthly_registered_customers
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $CACHE_PATH,$ui;
|
||||||
|
|
||||||
|
$cacheMRfile = $CACHE_PATH . File::pathFixer('/monthlyRegistered.temp');
|
||||||
|
//Compatibility for old path
|
||||||
|
if (file_exists($oldCacheMRfile = str_replace($CACHE_PATH, '', $cacheMRfile))) {
|
||||||
|
rename($oldCacheMRfile, $cacheMRfile);
|
||||||
|
}
|
||||||
|
//Cache for 1 hour
|
||||||
|
if (file_exists($cacheMRfile) && time() - filemtime($cacheMRfile) < 3600) {
|
||||||
|
$monthlyRegistered = json_decode(file_get_contents($cacheMRfile), true);
|
||||||
|
} else {
|
||||||
|
//Monthly Registered Customers
|
||||||
|
$result = ORM::for_table('tbl_customers')
|
||||||
|
->select_expr('MONTH(created_at)', 'month')
|
||||||
|
->select_expr('COUNT(*)', 'count')
|
||||||
|
->where_raw('YEAR(created_at) = YEAR(NOW())')
|
||||||
|
->group_by_expr('MONTH(created_at)')
|
||||||
|
->find_many();
|
||||||
|
|
||||||
|
$monthlyRegistered = [];
|
||||||
|
foreach ($result as $row) {
|
||||||
|
$monthlyRegistered[] = [
|
||||||
|
'date' => $row->month,
|
||||||
|
'count' => $row->count
|
||||||
|
];
|
||||||
|
}
|
||||||
|
file_put_contents($cacheMRfile, json_encode($monthlyRegistered));
|
||||||
|
}
|
||||||
|
$ui->assign('monthlyRegistered', $monthlyRegistered);
|
||||||
|
return $ui->fetch('widget/graph_monthly_registered_customers.tpl');
|
||||||
|
}
|
||||||
|
}
|
60
system/widgets/graph_monthly_sales.php
Normal file
60
system/widgets/graph_monthly_sales.php
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class graph_monthly_sales
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $CACHE_PATH, $ui;
|
||||||
|
|
||||||
|
|
||||||
|
$cacheMSfile = $CACHE_PATH . File::pathFixer('/monthlySales.temp');
|
||||||
|
//Cache for 12 hours
|
||||||
|
if (file_exists($cacheMSfile) && time() - filemtime($cacheMSfile) < 43200) {
|
||||||
|
$monthlySales = json_decode(file_get_contents($cacheMSfile), true);
|
||||||
|
} else {
|
||||||
|
// Query to retrieve monthly data
|
||||||
|
$results = ORM::for_table('tbl_transactions')
|
||||||
|
->select_expr('MONTH(recharged_on)', 'month')
|
||||||
|
->select_expr('SUM(price)', 'total')
|
||||||
|
->where_raw("YEAR(recharged_on) = YEAR(CURRENT_DATE())") // Filter by the current year
|
||||||
|
->where_not_equal('method', 'Customer - Balance')
|
||||||
|
->where_not_equal('method', 'Recharge Balance - Administrator')
|
||||||
|
->group_by_expr('MONTH(recharged_on)')
|
||||||
|
->find_many();
|
||||||
|
|
||||||
|
// Create an array to hold the monthly sales data
|
||||||
|
$monthlySales = array();
|
||||||
|
|
||||||
|
// Iterate over the results and populate the array
|
||||||
|
foreach ($results as $result) {
|
||||||
|
$month = $result->month;
|
||||||
|
$totalSales = $result->total;
|
||||||
|
|
||||||
|
$monthlySales[$month] = array(
|
||||||
|
'month' => $month,
|
||||||
|
'totalSales' => $totalSales
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in missing months with zero sales
|
||||||
|
for ($month = 1; $month <= 12; $month++) {
|
||||||
|
if (!isset($monthlySales[$month])) {
|
||||||
|
$monthlySales[$month] = array(
|
||||||
|
'month' => $month,
|
||||||
|
'totalSales' => 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the array by month
|
||||||
|
ksort($monthlySales);
|
||||||
|
|
||||||
|
// Reindex the array
|
||||||
|
$monthlySales = array_values($monthlySales);
|
||||||
|
file_put_contents($cacheMSfile, json_encode($monthlySales));
|
||||||
|
}
|
||||||
|
|
||||||
|
$ui->assign('monthlySales', $monthlySales);
|
||||||
|
return $ui->fetch('widget/graph_monthly_sales.tpl');
|
||||||
|
}
|
||||||
|
}
|
21
system/widgets/html_php.php
Normal file
21
system/widgets/html_php.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class html_php
|
||||||
|
{
|
||||||
|
|
||||||
|
public function getWidget($data = null)
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
$ui->assign('card_header', $data['title']);
|
||||||
|
ob_start();
|
||||||
|
try{
|
||||||
|
eval('?>'. $data['content']);
|
||||||
|
}catch(Exception $e){
|
||||||
|
echo $e->getMessage();
|
||||||
|
echo "<br>";
|
||||||
|
echo $e->getTraceAsString();
|
||||||
|
}
|
||||||
|
$content = ob_get_clean();
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
}
|
22
system/widgets/html_php_card.php
Normal file
22
system/widgets/html_php_card.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class html_php
|
||||||
|
{
|
||||||
|
|
||||||
|
public function getWidget($data = null)
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
$ui->assign('card_header', $data['title']);
|
||||||
|
ob_start();
|
||||||
|
try{
|
||||||
|
eval('?>'. $data['content']);
|
||||||
|
}catch(Exception $e){
|
||||||
|
echo $e->getMessage();
|
||||||
|
echo "<br>";
|
||||||
|
echo $e->getTraceAsString();
|
||||||
|
}
|
||||||
|
$content = ob_get_clean();
|
||||||
|
$ui->assign('card_body', $content);
|
||||||
|
return $ui->fetch('widget/card_html.tpl');
|
||||||
|
}
|
||||||
|
}
|
11
system/widgets/info_payment_gateway.php
Normal file
11
system/widgets/info_payment_gateway.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class info_payment_gateway
|
||||||
|
{
|
||||||
|
|
||||||
|
public function getWidget($data = null)
|
||||||
|
{
|
||||||
|
global $ui;
|
||||||
|
return $ui->fetch('widget/info_payment_gateway.tpl');
|
||||||
|
}
|
||||||
|
}
|
16
system/widgets/mikrotik_cron_monitor.php
Normal file
16
system/widgets/mikrotik_cron_monitor.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class mikrotik_cron_monitor
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $config,$ui;
|
||||||
|
|
||||||
|
if ($config['router_check']) {
|
||||||
|
$routeroffs = ORM::for_table('tbl_routers')->selects(['id', 'name', 'last_seen'])->where('status', 'Offline')->where('enabled', '1')->order_by_desc('name')->find_array();
|
||||||
|
$ui->assign('routeroffs', $routeroffs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ui->fetch('widget/mikrotik_cron_monitor.tpl');
|
||||||
|
}
|
||||||
|
}
|
18
system/widgets/template.md
Normal file
18
system/widgets/template.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```php
|
||||||
|
class widget_name
|
||||||
|
{
|
||||||
|
|
||||||
|
public static getWidget($data)
|
||||||
|
{
|
||||||
|
global $config, $ui;
|
||||||
|
|
||||||
|
return $ui->fetch('widget/template');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
51
system/widgets/top_widget.php
Normal file
51
system/widgets/top_widget.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
class top_widget
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $ui, $current_date, $start_date;
|
||||||
|
|
||||||
|
$iday = ORM::for_table('tbl_transactions')
|
||||||
|
->where('recharged_on', $current_date)
|
||||||
|
->where_not_equal('method', 'Customer - Balance')
|
||||||
|
->where_not_equal('method', 'Recharge Balance - Administrator')
|
||||||
|
->sum('price');
|
||||||
|
|
||||||
|
if ($iday == '') {
|
||||||
|
$iday = '0.00';
|
||||||
|
}
|
||||||
|
$ui->assign('iday', $iday);
|
||||||
|
|
||||||
|
$imonth = ORM::for_table('tbl_transactions')
|
||||||
|
->where_not_equal('method', 'Customer - Balance')
|
||||||
|
->where_not_equal('method', 'Recharge Balance - Administrator')
|
||||||
|
->where_gte('recharged_on', $start_date)
|
||||||
|
->where_lte('recharged_on', $current_date)->sum('price');
|
||||||
|
if ($imonth == '') {
|
||||||
|
$imonth = '0.00';
|
||||||
|
}
|
||||||
|
$ui->assign('imonth', $imonth);
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$u_all = ORM::for_table('tbl_user_recharges')->count();
|
||||||
|
if (empty($u_all)) {
|
||||||
|
$u_all = '0';
|
||||||
|
}
|
||||||
|
$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);
|
||||||
|
return $ui->fetch('widget/top_widget.tpl');
|
||||||
|
}
|
||||||
|
}
|
43
system/widgets/voucher_stocks.php
Normal file
43
system/widgets/voucher_stocks.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class voucher_stocks
|
||||||
|
{
|
||||||
|
public function getWidget()
|
||||||
|
{
|
||||||
|
global $CACHE_PATH,$ui;
|
||||||
|
$cacheStocksfile = $CACHE_PATH . File::pathFixer('/VoucherStocks.temp');
|
||||||
|
$cachePlanfile = $CACHE_PATH . File::pathFixer('/VoucherPlans.temp');
|
||||||
|
//Cache for 5 minutes
|
||||||
|
if (file_exists($cacheStocksfile) && time() - filemtime($cacheStocksfile) < 600) {
|
||||||
|
$stocks = json_decode(file_get_contents($cacheStocksfile), true);
|
||||||
|
$plans = json_decode(file_get_contents($cachePlanfile), true);
|
||||||
|
} else {
|
||||||
|
// Count stock
|
||||||
|
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
|
||||||
|
$plans = array();
|
||||||
|
$stocks = array("used" => 0, "unused" => 0);
|
||||||
|
$n = 0;
|
||||||
|
foreach ($tmp as $plan) {
|
||||||
|
$unused = ORM::for_table('tbl_voucher')
|
||||||
|
->where('id_plan', $plan['id'])
|
||||||
|
->where('status', 0)->count();
|
||||||
|
$used = ORM::for_table('tbl_voucher')
|
||||||
|
->where('id_plan', $plan['id'])
|
||||||
|
->where('status', 1)->count();
|
||||||
|
if ($unused > 0 || $used > 0) {
|
||||||
|
$plans[$n]['name_plan'] = $plan['name_plan'];
|
||||||
|
$plans[$n]['unused'] = $unused;
|
||||||
|
$plans[$n]['used'] = $used;
|
||||||
|
$stocks["unused"] += $unused;
|
||||||
|
$stocks["used"] += $used;
|
||||||
|
$n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_put_contents($cacheStocksfile, json_encode($stocks));
|
||||||
|
file_put_contents($cachePlanfile, json_encode($plans));
|
||||||
|
}
|
||||||
|
$ui->assign('stocks', $stocks);
|
||||||
|
$ui->assign('plans', $plans);
|
||||||
|
return $ui->fetch('widget/voucher_stocks.tpl');
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=bandwidth/delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=customers/delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=services/delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,8 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>403 Forbidden</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>Directory access is forbidden.</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=plan/delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=pool/delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=services/pppoe-delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=routers/delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=settings/users-delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
$(document).on("click", ".cdelete", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var id = this.id;
|
|
||||||
bootbox.confirm("Are you sure?", function(result) {
|
|
||||||
if(result){
|
|
||||||
window.location.href = "index.php?_route=plan/voucher-delete/" + id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
1
ui/lib/css/bootstrap-rtl.min.css
vendored
1
ui/lib/css/bootstrap-rtl.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -1,8 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>403 Forbidden</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>Directory access is forbidden.</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,186 +0,0 @@
|
||||||
/*! DataTables Bootstrap 3 integration
|
|
||||||
* ©2011-2014 SpryMedia Ltd - datatables.net/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DataTables integration for Bootstrap 3. This requires Bootstrap 3 and
|
|
||||||
* DataTables 1.10 or newer.
|
|
||||||
*
|
|
||||||
* This file sets the defaults and adds options to DataTables to style its
|
|
||||||
* controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
|
|
||||||
* for further information.
|
|
||||||
*/
|
|
||||||
(function(window, document, undefined){
|
|
||||||
|
|
||||||
var factory = function( $, DataTable ) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the defaults for DataTables initialisation */
|
|
||||||
$.extend( true, DataTable.defaults, {
|
|
||||||
dom:
|
|
||||||
"<'row'<'col-sm-6'l><'col-sm-6'f>>" +
|
|
||||||
"<'row'<'col-sm-12'tr>>" +
|
|
||||||
"<'row'<'col-sm-6'i><'col-sm-6'p>>",
|
|
||||||
renderer: 'bootstrap'
|
|
||||||
} );
|
|
||||||
|
|
||||||
|
|
||||||
/* Default class modification */
|
|
||||||
$.extend( DataTable.ext.classes, {
|
|
||||||
sWrapper: "dataTables_wrapper form-inline dt-bootstrap",
|
|
||||||
sFilterInput: "form-control input-sm",
|
|
||||||
sLengthSelect: "form-control input-sm"
|
|
||||||
} );
|
|
||||||
|
|
||||||
|
|
||||||
/* Bootstrap paging button renderer */
|
|
||||||
DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {
|
|
||||||
var api = new DataTable.Api( settings );
|
|
||||||
var classes = settings.oClasses;
|
|
||||||
var lang = settings.oLanguage.oPaginate;
|
|
||||||
var btnDisplay, btnClass;
|
|
||||||
|
|
||||||
var attach = function( container, buttons ) {
|
|
||||||
var i, ien, node, button;
|
|
||||||
var clickHandler = function ( e ) {
|
|
||||||
e.preventDefault();
|
|
||||||
if ( !$(e.currentTarget).hasClass('disabled') ) {
|
|
||||||
api.page( e.data.action ).draw( false );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
|
|
||||||
button = buttons[i];
|
|
||||||
|
|
||||||
if ( $.isArray( button ) ) {
|
|
||||||
attach( container, button );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
btnDisplay = '';
|
|
||||||
btnClass = '';
|
|
||||||
|
|
||||||
switch ( button ) {
|
|
||||||
case 'ellipsis':
|
|
||||||
btnDisplay = '…';
|
|
||||||
btnClass = 'disabled';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'first':
|
|
||||||
btnDisplay = lang.sFirst;
|
|
||||||
btnClass = button + (page > 0 ?
|
|
||||||
'' : ' disabled');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'previous':
|
|
||||||
btnDisplay = lang.sPrevious;
|
|
||||||
btnClass = button + (page > 0 ?
|
|
||||||
'' : ' disabled');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'next':
|
|
||||||
btnDisplay = lang.sNext;
|
|
||||||
btnClass = button + (page < pages-1 ?
|
|
||||||
'' : ' disabled');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'last':
|
|
||||||
btnDisplay = lang.sLast;
|
|
||||||
btnClass = button + (page < pages-1 ?
|
|
||||||
'' : ' disabled');
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
btnDisplay = button + 1;
|
|
||||||
btnClass = page === button ?
|
|
||||||
'active' : '';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( btnDisplay ) {
|
|
||||||
node = $('<li>', {
|
|
||||||
'class': classes.sPageButton+' '+btnClass,
|
|
||||||
'aria-controls': settings.sTableId,
|
|
||||||
'tabindex': settings.iTabIndex,
|
|
||||||
'id': idx === 0 && typeof button === 'string' ?
|
|
||||||
settings.sTableId +'_'+ button :
|
|
||||||
null
|
|
||||||
} )
|
|
||||||
.append( $('<a>', {
|
|
||||||
'href': '#'
|
|
||||||
} )
|
|
||||||
.html( btnDisplay )
|
|
||||||
)
|
|
||||||
.appendTo( container );
|
|
||||||
|
|
||||||
settings.oApi._fnBindAction(
|
|
||||||
node, {action: button}, clickHandler
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
attach(
|
|
||||||
$(host).empty().html('<ul class="pagination"/>').children('ul'),
|
|
||||||
buttons
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TableTools Bootstrap compatibility
|
|
||||||
* Required TableTools 2.1+
|
|
||||||
*/
|
|
||||||
if ( DataTable.TableTools ) {
|
|
||||||
// Set the classes that TableTools uses to something suitable for Bootstrap
|
|
||||||
$.extend( true, DataTable.TableTools.classes, {
|
|
||||||
"container": "DTTT btn-group",
|
|
||||||
"buttons": {
|
|
||||||
"normal": "btn btn-default",
|
|
||||||
"disabled": "disabled"
|
|
||||||
},
|
|
||||||
"collection": {
|
|
||||||
"container": "DTTT_dropdown dropdown-menu",
|
|
||||||
"buttons": {
|
|
||||||
"normal": "",
|
|
||||||
"disabled": "disabled"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"print": {
|
|
||||||
"info": "DTTT_print_info"
|
|
||||||
},
|
|
||||||
"select": {
|
|
||||||
"row": "active"
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Have the collection use a bootstrap compatible drop down
|
|
||||||
$.extend( true, DataTable.TableTools.DEFAULTS.oTags, {
|
|
||||||
"collection": {
|
|
||||||
"container": "ul",
|
|
||||||
"button": "li",
|
|
||||||
"liner": "a"
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // /factory
|
|
||||||
|
|
||||||
|
|
||||||
// Define as an AMD module if possible
|
|
||||||
if ( typeof define === 'function' && define.amd ) {
|
|
||||||
define( ['jquery', 'datatables'], factory );
|
|
||||||
}
|
|
||||||
else if ( typeof exports === 'object' ) {
|
|
||||||
// Node/CommonJS
|
|
||||||
factory( require('jquery'), require('datatables') );
|
|
||||||
}
|
|
||||||
else if ( jQuery ) {
|
|
||||||
// Otherwise simply initialise as normal, stopping multiple evaluation
|
|
||||||
factory( jQuery, jQuery.fn.dataTable );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
})(window, document);
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue