mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-09-26 12:01:57 +02:00
Widen the Rector config to the remaining class-based trees (Streaming, Public\Controllers, Ministra), keeping the templates, procedural front-controllers (Public/stream, Public/admin, Ministra/portal.php) and the streaming hot-path bootstraps out. Also document the recurring dropped-parens bug + the review grep in the config header. The resulting 107-file pass (94 Public\Controllers, 11 Streaming, 2 Ministra) was reviewed against the suite + PHPStan + the usual scans: - No dropped-parens bug this time (the assignment-in-condition pattern didn't occur in these files). - 6 locally-called private static helpers became instance methods (behaviour-preserving; all called via $this->, no static call sites); one unused private param dropped (FanoutConfig::desired $rSnapshot, call site updated). - De Morgan / ternary / dead-code simplifications; two `$x = getById()` truthy-assignments folded into the condition (no comparison, safe). PHPStan level 5 clean; suite 721 tests / 0 errors.
1711 lines
89 KiB
PHP
1711 lines
89 KiB
PHP
<?php
|
|
|
|
namespace XcVm\Public\Controllers\Reseller;
|
|
|
|
use XcVm\Core\Auth\AuthRepository;
|
|
use XcVm\Core\Config\SettingsManager;
|
|
use XcVm\Core\Http\RequestManager;
|
|
use XcVm\Core\Util\TimeUtils;
|
|
use XcVm\Domain\Device\EnigmaService;
|
|
use XcVm\Domain\Device\MagService;
|
|
use XcVm\Domain\Line\PackageService;
|
|
use XcVm\Domain\Server\ServerRepository;
|
|
use XcVm\Domain\Stream\CategoryService;
|
|
use XcVm\Domain\Stream\ConnectionTracker;
|
|
use XcVm\Domain\User\UserRepository;
|
|
use XcVm\Infrastructure\Bootstrap\WebApiBootstrap;
|
|
use XcVm\Infrastructure\Redis\RedisManager;
|
|
|
|
/**
|
|
* Reseller DataTables JSON API
|
|
*
|
|
* @package XC_VM_Includes_Api_Reseller
|
|
* @author Divarion_D <https://github.com/Divarion-D>
|
|
* @copyright 2025-2026 Vateron Media
|
|
* @link https://github.com/Vateron-Media/XC_VM
|
|
* @license AGPL-3.0 https://www.gnu.org/licenses/agpl-3.0.html
|
|
*/
|
|
|
|
session_start();
|
|
session_write_close();
|
|
if (!defined('MAIN_HOME')) {
|
|
define('MAIN_HOME', dirname(__DIR__, 3) . '/');
|
|
require_once MAIN_HOME . 'vendor/autoload.php';
|
|
}
|
|
WebApiBootstrap::init('reseller');
|
|
if (!PHP_ERRORS) {
|
|
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
|
|
exit();
|
|
}
|
|
}
|
|
$rReturn = ['draw' => intval(RequestManager::get('draw')), 'recordsTotal' => 0, 'recordsFiltered' => 0, 'data' => []];
|
|
$rIsAPI = false;
|
|
if (RequestManager::has('api_key')) {
|
|
$rReturn = ['status' => 'STATUS_SUCCESS', 'data' => []];
|
|
$db->query('SELECT `id` FROM `users` LEFT JOIN `users_groups` ON `users_groups`.`group_id` = `users`.`member_group_id` WHERE `api_key` = ? AND LENGTH(`api_key`) > 0 AND `is_reseller` = 1 AND `status` = 1;', RequestManager::get('api_key'));
|
|
if ($db->num_rows() != 0) {
|
|
$rUserID = $db->get_row()['id'];
|
|
$rIsAPI = true;
|
|
require_once MAIN_HOME . 'bootstrap.php';
|
|
\XC_Bootstrap::boot(\XC_Bootstrap::CONTEXT_ADMIN);
|
|
$rUserInfo = UserRepository::getRegisteredUserById($rUserID);
|
|
$rPermissions = array_merge(AuthRepository::getPermissions($rUserInfo['member_group_id']), AuthRepository::getGroupPermissions($rUserInfo['id']));
|
|
if ((string) $rUserInfo['timezone'] !== '') {
|
|
date_default_timezone_set($rUserInfo['timezone']);
|
|
}
|
|
} else {
|
|
echo json_encode(['status' => 'STATUS_FAILURE', 'error' => 'Invalid API key.']);
|
|
exit();
|
|
}
|
|
} else {
|
|
if (isset($_SESSION['reseller'])) {
|
|
include __DIR__ . '/functions.php';
|
|
} else {
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
}
|
|
if (!$rUserInfo['id']) {
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
if (isset($rUserInfo['reports'])) {
|
|
$rType = RequestManager::get('id');
|
|
$rStart = intval(RequestManager::get('start'));
|
|
$rLimit = intval(RequestManager::get('length'));
|
|
if (1000 < $rLimit || $rLimit <= 0) {
|
|
$rLimit = 1000;
|
|
}
|
|
if ($rType == 'lines') {
|
|
if ($rPermissions['create_line']) {
|
|
$rOrder = ['`lines`.`id`', '`lines`.`username`', '`lines`.`password`', '`users`.`username`', '`lines`.`enabled` - `lines`.`admin_enabled`', '`active_connections` > 0', '`lines`.`is_trial`', '`active_connections`', '`lines`.`max_connections`', '`lines`.`exp_date`', '`last_activity`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
$rWhere[] = '`lines`.`is_mag` = 0 AND `lines`.`is_e2` = 0';
|
|
$rWhere[] = '`lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 6) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`lines`.`username` LIKE ? OR `lines`.`password` LIKE ? OR `users`.`username` LIKE ? OR FROM_UNIXTIME(`exp_date`) LIKE ? OR `lines`.`max_connections` LIKE ? OR `lines`.`reseller_notes` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('filter') !== '') {
|
|
if (RequestManager::get('filter') == 1) {
|
|
$rWhere[] = '(`lines`.`admin_enabled` = 1 AND `lines`.`enabled` = 1 AND (`lines`.`exp_date` IS NULL OR `lines`.`exp_date` > UNIX_TIMESTAMP()))';
|
|
} else {
|
|
if (RequestManager::get('filter') == 2) {
|
|
$rWhere[] = '`lines`.`enabled` = 0';
|
|
} else {
|
|
if (RequestManager::get('filter') == 3) {
|
|
$rWhere[] = '`lines`.`admin_enabled` = 0';
|
|
} else {
|
|
if (RequestManager::get('filter') == 4) {
|
|
$rWhere[] = '(`lines`.`exp_date` IS NOT NULL AND `lines`.`exp_date` <= UNIX_TIMESTAMP())';
|
|
} else {
|
|
if (RequestManager::get('filter') == 5) {
|
|
$rWhere[] = '`lines`.`is_trial` = 1';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ((string) RequestManager::get('reseller') !== '') {
|
|
$rWhere[] = '`lines`.`member_id` = ?';
|
|
$rWhereV[] = RequestManager::get('reseller');
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(`lines`.`id`) AS `count` FROM `lines` LEFT JOIN `users` ON `users`.`id` = `lines`.`member_id` ' . $rWhereString . ';';
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `lines`.`id`, `lines`.`member_id`, `lines`.`last_activity`, `lines`.`last_activity_array`, `lines`.`username`, `lines`.`password`, `lines`.`exp_date`, `lines`.`admin_enabled`, `lines`.`is_restreamer`, `lines`.`enabled`, `lines`.`admin_notes`, `lines`.`reseller_notes`, `lines`.`max_connections`, `lines`.`is_trial`, (SELECT COUNT(*) AS `active_connections` FROM `lines_live` WHERE `user_id` = `lines`.`id` AND `hls_end` = 0) AS `active_connections` FROM `lines` LEFT JOIN `users` ON `users`.`id` = `lines`.`member_id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
$rActivityIDs = $rLineInfo = $rLineIDs = [];
|
|
foreach ($rRows as $rRow) {
|
|
$rLineIDs[] = intval($rRow['id']);
|
|
$rLineInfo[intval($rRow['id'])] = ['owner_name' => null, 'stream_display_name' => null, 'stream_id' => null, 'last_active' => null];
|
|
if ($rLastInfo = json_decode($rRow['last_activity_array'], true)) {
|
|
$rLineInfo[intval($rRow['id'])]['stream_id'] = $rLastInfo['stream_id'];
|
|
$rLineInfo[intval($rRow['id'])]['last_active'] = $rLastInfo['date_end'];
|
|
} else {
|
|
if ($rRow['last_activity']) {
|
|
$rActivityIDs[] = intval($rRow['last_activity']);
|
|
}
|
|
}
|
|
}
|
|
if (0 < count($rLineIDs)) {
|
|
$db->query('SELECT `users`.`username`, `lines`.`id` FROM `users` LEFT JOIN `lines` ON `lines`.`member_id` = `users`.`id` WHERE `lines`.`id` IN (' . implode(',', $rLineIDs) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rLineInfo[$rRow['id']]['owner_name'] = $rRow['username'];
|
|
}
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rConnectionCount = [];
|
|
$rConnectionMap = ConnectionTracker::getUserConnections($rLineIDs, false);
|
|
$rStreamIDs = [];
|
|
foreach ($rConnectionMap as $rUserID => $rConnections) {
|
|
foreach ($rConnections as $rConnection) {
|
|
if (!in_array($rConnection['stream_id'], $rStreamIDs)) {
|
|
$rStreamIDs[] = intval($rConnection['stream_id']);
|
|
}
|
|
}
|
|
}
|
|
$rStreamMap = [];
|
|
if (0 < count($rStreamIDs)) {
|
|
$db->query('SELECT `id`, `stream_display_name` FROM `streams` WHERE `id` IN (' . implode(',', $rStreamIDs) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rStreamMap[$rRow['id']] = $rRow['stream_display_name'];
|
|
}
|
|
}
|
|
foreach (array_keys($rConnectionMap) as $rUserID) {
|
|
array_multisort(array_column($rConnectionMap[$rUserID], 'date_start'), SORT_DESC, $rConnectionMap[$rUserID]);
|
|
$rLineInfo[$rUserID]['stream_display_name'] = $rStreamMap[$rConnectionMap[$rUserID][0]['stream_id']];
|
|
$rLineInfo[$rUserID]['stream_id'] = $rConnectionMap[$rUserID][0]['stream_id'];
|
|
$rLineInfo[$rUserID]['last_active'] = $rConnectionMap[$rUserID][0]['date_start'];
|
|
$rConnectionCount[$rUserID] = count($rConnectionMap[$rUserID]);
|
|
}
|
|
unset($rConnectionMap);
|
|
} else {
|
|
$db->query('SELECT `lines_live`.`user_id`, `lines_live`.`stream_id`, `lines_live`.`date_start` AS `last_active`, `streams`.`stream_display_name` FROM `lines_live` LEFT JOIN `streams` ON `streams`.`id` = `lines_live`.`stream_id` INNER JOIN (SELECT `user_id`, MAX(`date_start`) AS `ts` FROM `lines_live` GROUP BY `user_id`) `maxt` ON (`lines_live`.`user_id` = `maxt`.`user_id` AND `lines_live`.`date_start` = `maxt`.`ts`) WHERE `lines_live`.`user_id` IN (' . implode(',', $rLineIDs) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rLineInfo[$rRow['user_id']]['stream_display_name'] = $rRow['stream_display_name'];
|
|
$rLineInfo[$rRow['user_id']]['stream_id'] = $rRow['stream_id'];
|
|
$rLineInfo[$rRow['user_id']]['last_active'] = $rRow['last_active'];
|
|
}
|
|
}
|
|
}
|
|
if (0 < count($rActivityIDs)) {
|
|
$db->query('SELECT `user_id`, `stream_id`, `date_end` AS `last_active` FROM `lines_activity` WHERE `activity_id` IN (' . implode(',', $rActivityIDs) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
if (!isset($rLineInfo[$rRow['user_id']]['stream_id'])) {
|
|
$rLineInfo[$rRow['user_id']]['stream_id'] = $rRow['stream_id'];
|
|
$rLineInfo[$rRow['user_id']]['last_active'] = $rRow['last_active'];
|
|
}
|
|
}
|
|
}
|
|
foreach ($rRows as $rRow) {
|
|
$rRow = array_merge($rRow, $rLineInfo[$rRow['id']]);
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rRow['active_connections'] = (isset($rConnectionCount[$rRow['id']]) ? $rConnectionCount[$rRow['id']] : 0);
|
|
}
|
|
if (!$rIsAPI) {
|
|
if (!$rRow['admin_enabled']) {
|
|
$rStatus = '<i class="text-danger fas fa-square tooltip" title="Banned"></i>';
|
|
} else {
|
|
if (!$rRow['enabled']) {
|
|
$rStatus = '<i class="text-secondary fas fa-square tooltip" title="Disabled"></i>';
|
|
} else {
|
|
if ($rRow['exp_date'] && $rRow['exp_date'] < time()) {
|
|
$rStatus = '<i class="text-warning far fa-square tooltip" title="Expired"></i>';
|
|
} else {
|
|
$rStatus = '<i class="text-success fas fa-square tooltip" title="Active"></i>';
|
|
}
|
|
}
|
|
}
|
|
if (0 < $rRow['active_connections']) {
|
|
$rActive = '<i class="text-success fas fa-square"></i>';
|
|
} else {
|
|
$rActive = '<i class="text-secondary far fa-square"></i>';
|
|
}
|
|
if ($rRow['is_trial']) {
|
|
$rTrial = '<i class="text-warning fas fa-square"></i>';
|
|
} else {
|
|
$rTrial = '<i class="text-secondary far fa-square"></i>';
|
|
}
|
|
if ($rRow['exp_date']) {
|
|
if ($rRow['exp_date'] < time()) {
|
|
$rExpDate = '<span class="expired">' . date($rSettings['date_format'], $rRow['exp_date']) . '<br/><small>' . date('H:i:s', $rRow['exp_date']) . '</small></span>';
|
|
} else {
|
|
$rExpDate = date($rSettings['date_format'], $rRow['exp_date']) . "<br/><small class='text-secondary'>" . date('H:i:s', $rRow['exp_date']) . '</small>';
|
|
}
|
|
} else {
|
|
$rExpDate = '∞';
|
|
}
|
|
if (0 < $rRow['active_connections']) {
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
$rActiveConnections = "<a href='javascript: void(0);' onClick='viewLiveConnections(" . intval($rRow['id']) . ");'><button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['active_connections'] . '</button></a>';
|
|
} else {
|
|
$rActiveConnections = "<button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['active_connections'] . '</button>';
|
|
}
|
|
} else {
|
|
$rActiveConnections = "<button type='button' class='btn btn-secondary btn-xs waves-effect waves-light'>0</button>";
|
|
}
|
|
if ($rRow['max_connections'] == 0) {
|
|
$rMaxConnections = "<button type='button' class='btn btn-dark text-white btn-xs waves-effect waves-light'>∞</button>";
|
|
} else {
|
|
$rMaxConnections = "<button type='button' class='btn btn-secondary btn-xs waves-effect waves-light'>" . $rRow['max_connections'] . '</button>';
|
|
}
|
|
$rButtons = '<div class="btn-group">';
|
|
$rNotes = '';
|
|
if ((string) $rRow['reseller_notes'] !== '') {
|
|
if (strlen($rNotes) != 0) {
|
|
$rNotes .= "\n";
|
|
}
|
|
$rNotes .= $rRow['reseller_notes'];
|
|
}
|
|
if ($rNotes !== '') {
|
|
$rButtons .= '<button type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" title="' . $rNotes . '"><i class="mdi mdi-note"></i></button>';
|
|
} else {
|
|
$rButtons .= '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-note"></i></button>';
|
|
}
|
|
$rButtons .= '<a href="line?id=' . $rRow['id'] . '"><button title="Edit" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip"><i class="mdi mdi-pencil-outline"></i></button></a>';
|
|
if ($rPermissions['allow_download']) {
|
|
$rButtons .= "<button type=\"button\" title=\"Download Playlist\" class=\"btn btn-light waves-effect waves-light btn-xs tooltip\" onClick=\"download('" . $rRow['username'] . "', '" . $rRow['password'] . "');\"><i class=\"mdi mdi-download\"></i></button>";
|
|
}
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
if (0 < $rRow['active_connections']) {
|
|
$rButtons .= '<button title="Kill Connections" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'kill_line');\"><i class=\"fas fa-hammer\"></i></button>";
|
|
} else {
|
|
$rButtons .= '<button disabled type="button" class="btn btn-light waves-effect waves-light btn-xs"><i class="fas fa-hammer"></i></button>';
|
|
}
|
|
}
|
|
if ($rRow['is_isplock']) {
|
|
$rButtons .= '<button title="Reset ISP Lock" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'reset_isp');\"><i class=\"mdi mdi-lock-reset\"></i></button>";
|
|
}
|
|
if ($rRow['enabled']) {
|
|
$rButtons .= '<button title="Disable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'disable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
} else {
|
|
$rButtons .= '<button title="Enable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'enable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
}
|
|
$rButtons .= '<button title="Delete" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'delete');\"><i class=\"mdi mdi-close\"></i></button>";
|
|
$rButtons .= '</div>';
|
|
if ($rRow['active_connections'] && $rRow['last_active']) {
|
|
$rLastActive = "<a href='stream_view?id=" . $rRow['stream_id'] . "'>" . $rRow['stream_display_name'] . "</a><br/><small class='text-secondary'>Online: " . TimeUtils::secondsToTime(time() - $rRow['last_active']) . '</small>';
|
|
} else {
|
|
if ($rRow['last_active']) {
|
|
$rLastActive = date($rSettings['date_format'], $rRow['last_active']) . "<br/><small class='text-secondary'>" . date('H:i:s', $rRow['last_active']) . '</small>';
|
|
} else {
|
|
$rLastActive = 'Never';
|
|
}
|
|
}
|
|
if (in_array($rRow['member_id'], array_merge($rPermissions['direct_reports'], [$rUserInfo['id']]))) {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['member_id']) . "'>" . $rRow['owner_name'] . '</a>';
|
|
} else {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['member_id']) . "'>" . $rRow['owner_name'] . "<br/><small class='text-pink'>(indirect)</small></a>";
|
|
}
|
|
$rReturn['data'][] = ["<a href='line?id=" . $rRow['id'] . "'>" . $rRow['id'] . '</a>', "<a href='line?id=" . $rRow['id'] . "'>" . $rRow['username'] . '</a>', $rRow['password'], $rOwner, $rStatus, $rActive, $rTrial, $rActiveConnections, $rMaxConnections, $rExpDate, $rLastActive, $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'mags') {
|
|
if ($rPermissions['create_mag']) {
|
|
$rOrder = ['`lines`.`id`', '`lines`.`username`', '`mag_devices`.`mac`', '`mag_devices`.`stb_type`', '`users`.`username`', '`lines`.`enabled`', '`active_connections`', '`lines`.`is_trial`', '`lines`.`exp_date`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
$rWhere[] = '`lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 6) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`lines`.`username` LIKE ? OR `mag_devices`.`mac` LIKE ? OR `mag_devices`.`stb_type` LIKE ? OR `users`.`username` LIKE ? OR FROM_UNIXTIME(`exp_date`) LIKE ? OR `lines`.`reseller_notes` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('filter') !== '') {
|
|
if (RequestManager::get('filter') == 1) {
|
|
$rWhere[] = '(`lines`.`admin_enabled` = 1 AND `lines`.`enabled` = 1 AND (`lines`.`exp_date` IS NULL OR `lines`.`exp_date` > UNIX_TIMESTAMP()))';
|
|
} else {
|
|
if (RequestManager::get('filter') == 2) {
|
|
$rWhere[] = '`lines`.`enabled` = 0';
|
|
} else {
|
|
if (RequestManager::get('filter') == 3) {
|
|
$rWhere[] = '(`lines`.`exp_date` IS NOT NULL AND `lines`.`exp_date` <= UNIX_TIMESTAMP())';
|
|
} else {
|
|
if (RequestManager::get('filter') == 4) {
|
|
$rWhere[] = '`lines`.`is_trial` = 1';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ((string) RequestManager::get('reseller') !== '') {
|
|
$rWhere[] = '`lines`.`member_id` = ?';
|
|
$rWhereV[] = RequestManager::get('reseller');
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(`lines`.`id`) AS `count` FROM `lines` LEFT JOIN `users` ON `users`.`id` = `lines`.`member_id` INNER JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines`.`id` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `lines`.`id`, `lines`.`username`, `lines`.`member_id`, `lines`.`is_isplock`, `mag_devices`.`mac`, `mag_devices`.`stb_type`, `mag_devices`.`mag_id`, `lines`.`exp_date`, `lines`.`admin_enabled`, `lines`.`enabled`, `lines`.`reseller_notes`, `lines`.`max_connections`, `lines`.`is_trial`, `users`.`username` AS `owner_name`, (SELECT count(*) FROM `lines_live` WHERE `lines`.`id` = `lines_live`.`user_id` AND `hls_end` = 0) AS `active_connections` FROM `lines` LEFT JOIN `users` ON `users`.`id` = `lines`.`member_id` INNER JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines`.`id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
$rLineIDs = [];
|
|
foreach ($rRows as $rRow) {
|
|
if ($rRow['id']) {
|
|
$rLineIDs[] = intval($rRow['id']);
|
|
}
|
|
}
|
|
if (0 < count($rLineIDs)) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rConnectionCount = [];
|
|
$rConnectionMap = ConnectionTracker::getUserConnections($rLineIDs, false);
|
|
foreach (array_keys($rConnectionMap) as $rUserID) {
|
|
$rConnectionCount[$rUserID] = count($rConnectionMap[$rUserID]);
|
|
}
|
|
unset($rConnectionMap);
|
|
}
|
|
}
|
|
foreach ($rRows as $rRow) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rRow['active_connections'] = (isset($rConnectionCount[$rRow['id']]) ? $rConnectionCount[$rRow['id']] : 0);
|
|
}
|
|
if (!$rIsAPI) {
|
|
if (!$rRow['admin_enabled']) {
|
|
$rStatus = '<i class="text-danger fas fa-square"></i>';
|
|
} else {
|
|
if (!$rRow['enabled']) {
|
|
$rStatus = '<i class="text-secondary fas fa-square"></i>';
|
|
} else {
|
|
if ($rRow['exp_date'] && $rRow['exp_date'] < time()) {
|
|
$rStatus = '<i class="text-warning far fa-square"></i>';
|
|
} else {
|
|
$rStatus = '<i class="text-success fas fa-square"></i>';
|
|
}
|
|
}
|
|
}
|
|
if (0 < $rRow['active_connections']) {
|
|
$rActive = '<i class="text-success fas fa-square"></i>';
|
|
} else {
|
|
$rActive = '<i class="text-warning far fa-square"></i>';
|
|
}
|
|
if ($rRow['is_trial']) {
|
|
$rTrial = '<i class="text-warning fas fa-square"></i>';
|
|
} else {
|
|
$rTrial = '<i class="text-secondary far fa-square"></i>';
|
|
}
|
|
if ($rRow['exp_date']) {
|
|
if ($rRow['exp_date'] < time()) {
|
|
$rExpDate = '<span class="expired">' . date($rSettings['date_format'], $rRow['exp_date']) . '<br/><small>' . date('H:i:s', $rRow['exp_date']) . '</small></span>';
|
|
} else {
|
|
$rExpDate = date($rSettings['date_format'], $rRow['exp_date']) . "<br/><small class='text-secondary'>" . date('H:i:s', $rRow['exp_date']) . '</small>';
|
|
}
|
|
} else {
|
|
$rExpDate = '∞';
|
|
}
|
|
$rButtons = '<div class="btn-group">';
|
|
$rNotes = '';
|
|
if ((string) $rRow['reseller_notes'] !== '') {
|
|
if (strlen($rNotes) != 0) {
|
|
$rNotes .= "\n";
|
|
}
|
|
$rNotes .= $rRow['reseller_notes'];
|
|
}
|
|
if ($rNotes !== '') {
|
|
$rButtons .= '<button type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" title="' . $rNotes . '"><i class="mdi mdi-note"></i></button>';
|
|
} else {
|
|
$rButtons .= '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-note"></i></button>';
|
|
}
|
|
$rButtons .= '<button title="MAG Event" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="message(' . $rRow['mag_id'] . ", '" . $rRow['mac'] . "');\"><i class=\"mdi mdi-message-alert\"></i></button>";
|
|
$rButtons .= '<a href="mag?id=' . $rRow['mag_id'] . '"><button title="Edit" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip"><i class="mdi mdi-pencil-outline"></i></button></a>';
|
|
if ($rRow['is_isplock']) {
|
|
$rButtons .= '<button title="Reset ISP Lock" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['mag_id'] . ", 'reset_isp');\"><i class=\"mdi mdi-lock-reset\"></i></button>";
|
|
}
|
|
if ($rPermissions['create_line']) {
|
|
$rButtons .= '<button title="Convert to User Line" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['mag_id'] . ", 'convert');\"><i class=\"fas fa-retweet\"></i></button>";
|
|
}
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
if (0 < $rRow['active_connections']) {
|
|
$rButtons .= '<button title="Kill Connections" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['mag_id'] . ", 'kill_line');\"><i class=\"fas fa-hammer\"></i></button>";
|
|
} else {
|
|
$rButtons .= '<button disabled type="button" class="btn btn-light waves-effect waves-light btn-xs"><i class="fas fa-hammer"></i></button>';
|
|
}
|
|
}
|
|
if ($rRow['enabled'] == 1) {
|
|
$rButtons .= '<button title="Disable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['mag_id'] . ", 'disable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
} else {
|
|
$rButtons .= '<button title="Enable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['mag_id'] . ", 'enable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
}
|
|
$rButtons .= '<button title="Delete" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['mag_id'] . ", 'delete');\"><i class=\"mdi mdi-close\"></i></button>";
|
|
$rButtons .= '</div>';
|
|
if (in_array($rRow['member_id'], array_merge($rPermissions['direct_reports'], [$rUserInfo['id']]))) {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['member_id']) . "'>" . $rRow['owner_name'] . '</a>';
|
|
} else {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['member_id']) . "'>" . $rRow['owner_name'] . "<br/><small class='text-pink'>(indirect)</small></a>";
|
|
}
|
|
$rReturn['data'][] = ["<a href='mag?id=" . $rRow['mag_id'] . "'>" . $rRow['mag_id'] . '</a>', $rRow['username'], "<a href='mag?id=" . $rRow['mag_id'] . "'>" . $rRow['mac'] . '</a>', $rRow['stb_type'], $rOwner, $rStatus, $rActive, $rTrial, $rExpDate, $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'enigmas') {
|
|
if ($rPermissions['create_enigma']) {
|
|
$rOrder = ['`lines`.`id`', '`lines`.`username`', '`enigma2_devices`.`mac`', '`enigma2_devices`.`public_ip`', '`users`.`username`', '`lines`.`enabled`', '`active_connections`', '`lines`.`is_trial`', '`lines`.`exp_date`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
$rWhere[] = '`lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 6) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`lines`.`username` LIKE ? OR `enigma2_devices`.`mac` LIKE ? OR `enigma2_devices`.`public_ip` LIKE ? OR `users`.`username` LIKE ? OR FROM_UNIXTIME(`exp_date`) LIKE ? OR `lines`.`reseller_notes` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('filter') !== '') {
|
|
if (RequestManager::get('filter') == 1) {
|
|
$rWhere[] = '(`lines`.`admin_enabled` = 1 AND `lines`.`enabled` = 1 AND (`lines`.`exp_date` IS NULL OR `lines`.`exp_date` > UNIX_TIMESTAMP()))';
|
|
} else {
|
|
if (RequestManager::get('filter') == 2) {
|
|
$rWhere[] = '`lines`.`enabled` = 0';
|
|
} else {
|
|
if (RequestManager::get('filter') == 3) {
|
|
$rWhere[] = '(`lines`.`exp_date` IS NOT NULL AND `lines`.`exp_date` <= UNIX_TIMESTAMP())';
|
|
} else {
|
|
if (RequestManager::get('filter') == 4) {
|
|
$rWhere[] = '`lines`.`is_trial` = 1';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ((string) RequestManager::get('reseller') !== '') {
|
|
$rWhere[] = '`lines`.`member_id` = ?';
|
|
$rWhereV[] = RequestManager::get('reseller');
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(`lines`.`id`) AS `count` FROM `lines` LEFT JOIN `users` ON `users`.`id` = `lines`.`member_id` INNER JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines`.`id` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `lines`.`id`, `lines`.`username`, `lines`.`member_id`, `lines`.`is_isplock`, `enigma2_devices`.`mac`, `enigma2_devices`.`public_ip`, `enigma2_devices`.`device_id`, `lines`.`exp_date`, `lines`.`admin_enabled`, `lines`.`enabled`, `lines`.`reseller_notes`, `lines`.`max_connections`, `lines`.`is_trial`, `users`.`username` AS `owner_name`, (SELECT count(*) FROM `lines_live` WHERE `lines`.`id` = `lines_live`.`user_id` AND `hls_end` = 0) AS `active_connections` FROM `lines` LEFT JOIN `users` ON `users`.`id` = `lines`.`member_id` INNER JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines`.`id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
$rLineIDs = [];
|
|
foreach ($rRows as $rRow) {
|
|
if ($rRow['id']) {
|
|
$rLineIDs[] = intval($rRow['id']);
|
|
}
|
|
}
|
|
if (0 < count($rLineIDs)) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rConnectionCount = [];
|
|
$rConnectionMap = ConnectionTracker::getUserConnections($rLineIDs, false);
|
|
foreach (array_keys($rConnectionMap) as $rUserID) {
|
|
$rConnectionCount[$rUserID] = count($rConnectionMap[$rUserID]);
|
|
}
|
|
unset($rConnectionMap);
|
|
}
|
|
}
|
|
foreach ($rRows as $rRow) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rRow['active_connections'] = (isset($rConnectionCount[$rRow['id']]) ? $rConnectionCount[$rRow['id']] : 0);
|
|
}
|
|
if (!$rIsAPI) {
|
|
if (!$rRow['admin_enabled']) {
|
|
$rStatus = '<i class="text-danger fas fa-square"></i>';
|
|
} else {
|
|
if (!$rRow['enabled']) {
|
|
$rStatus = '<i class="text-secondary fas fa-square"></i>';
|
|
} else {
|
|
if ($rRow['exp_date'] && $rRow['exp_date'] < time()) {
|
|
$rStatus = '<i class="text-warning far fa-square"></i>';
|
|
} else {
|
|
$rStatus = '<i class="text-success fas fa-square"></i>';
|
|
}
|
|
}
|
|
}
|
|
if (0 < $rRow['active_connections']) {
|
|
$rActive = '<i class="text-success fas fa-square"></i>';
|
|
} else {
|
|
$rActive = '<i class="text-warning far fa-square"></i>';
|
|
}
|
|
if ($rRow['is_trial']) {
|
|
$rTrial = '<i class="text-warning fas fa-square"></i>';
|
|
} else {
|
|
$rTrial = '<i class="text-secondary far fa-square"></i>';
|
|
}
|
|
if ($rRow['exp_date']) {
|
|
if ($rRow['exp_date'] < time()) {
|
|
$rExpDate = '<span class="expired">' . date($rSettings['date_format'], $rRow['exp_date']) . '<br/><small>' . date('H:i:s', $rRow['exp_date']) . '</small></span>';
|
|
} else {
|
|
$rExpDate = date($rSettings['date_format'], $rRow['exp_date']) . "<br/><small class='text-secondary'>" . date('H:i:s', $rRow['exp_date']) . '</small>';
|
|
}
|
|
} else {
|
|
$rExpDate = '∞';
|
|
}
|
|
$rButtons = '<div class="btn-group">';
|
|
$rNotes = '';
|
|
if ((string) $rRow['reseller_notes'] !== '') {
|
|
if (strlen($rNotes) != 0) {
|
|
$rNotes .= "\n";
|
|
}
|
|
$rNotes .= $rRow['reseller_notes'];
|
|
}
|
|
if ($rNotes !== '') {
|
|
$rButtons .= '<button type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" title="' . $rNotes . '"><i class="mdi mdi-note"></i></button>';
|
|
} else {
|
|
$rButtons .= '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-note"></i></button>';
|
|
}
|
|
$rButtons .= '<a href="enigma?id=' . $rRow['device_id'] . '"><button title="Edit" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip"><i class="mdi mdi-pencil-outline"></i></button></a>';
|
|
if ($rRow['is_isplock']) {
|
|
$rButtons .= '<button title="Reset ISP Lock" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['device_id'] . ", 'reset_isp');\"><i class=\"mdi mdi-lock-reset\"></i></button>";
|
|
}
|
|
if ($rPermissions['create_line']) {
|
|
$rButtons .= '<button title="Convert to User Line" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['device_id'] . ", 'convert');\"><i class=\"fas fa-retweet\"></i></button>";
|
|
}
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
if (0 < $rRow['active_connections']) {
|
|
$rButtons .= '<button title="Kill Connections" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['device_id'] . ", 'kill_line');\"><i class=\"fas fa-hammer\"></i></button>";
|
|
} else {
|
|
$rButtons .= '<button disabled type="button" class="btn btn-light waves-effect waves-light btn-xs"><i class="fas fa-hammer"></i></button>';
|
|
}
|
|
}
|
|
if ($rRow['enabled'] == 1) {
|
|
$rButtons .= '<button title="Disable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['device_id'] . ", 'disable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
} else {
|
|
$rButtons .= '<button title="Enable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['device_id'] . ", 'enable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
}
|
|
$rButtons .= '<button title="Delete" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['device_id'] . ", 'delete');\"><i class=\"mdi mdi-close\"></i></button>";
|
|
$rButtons .= '</div>';
|
|
if (in_array($rRow['member_id'], array_merge($rPermissions['direct_reports'], [$rUserInfo['id']]))) {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['member_id']) . "'>" . $rRow['owner_name'] . '</a>';
|
|
} else {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['member_id']) . "'>" . $rRow['owner_name'] . "<br/><small class='text-pink'>(indirect)</small></a>";
|
|
}
|
|
$rReturn['data'][] = ["<a href='enigma?id=" . $rRow['device_id'] . "'>" . $rRow['device_id'] . '</a>', $rRow['username'], "<a href='enigma?id=" . $rRow['device_id'] . "'>" . $rRow['mac'] . '</a>', "<a onClick=\"whois('" . $rRow['public_ip'] . "');\" href='javascript: void(0);'>" . $rRow['public_ip'] . '</a>', $rOwner, $rStatus, $rActive, $rTrial, $rExpDate, $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'streams') {
|
|
if ($rPermissions['can_view_vod']) {
|
|
$rCategories = CategoryService::getAllByType('live');
|
|
$rOrder = ['`id`', false, '`stream_display_name`', '`category_id`', '`clients`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rCreated = RequestManager::has('created');
|
|
$rWhere = $rWhereV = [];
|
|
if (0 < count($rPermissions['stream_ids'])) {
|
|
$rWhere[] = '`streams`.`id` IN (' . implode(',', array_map('intval', $rPermissions['stream_ids'])) . ')';
|
|
if ($rCreated) {
|
|
$rWhere[] = '`type` = 3';
|
|
} else {
|
|
$rWhere[] = '`type` = 1';
|
|
}
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 2) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`id` LIKE ? OR `stream_display_name` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rWhere[] = "JSON_CONTAINS(`category_id`, ?, '\$')";
|
|
$rWhereV[] = RequestManager::get('category');
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(`streams`.`id`) AS `count` FROM `streams` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `id`, `stream_icon`, `stream_display_name`, `tv_archive_duration`, `tv_archive_server_id`, `category_id`, (SELECT COUNT(*) FROM `lines_live` LEFT JOIN `lines` ON `lines`.`id` = `lines_live`.`user_id` WHERE `lines_live`.`stream_id` = `streams`.`id` AND `hls_end` = 0 AND `lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')) AS `clients` FROM `streams` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rConnectionCount = $rReports = [];
|
|
$db->query('SELECT `id` FROM `lines` WHERE `member_id` IN (' . implode(',', $rUserInfo['reports']) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rReports[] = $rRow['id'];
|
|
}
|
|
if (0 < count($rReports)) {
|
|
foreach (ConnectionTracker::getUserConnections($rReports, false) as $rConnections) {
|
|
foreach ($rConnections as $rConnection) {
|
|
$rConnectionCount[$rConnection['stream_id']]++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($rRows as $rRow) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rRow['clients'] = ($rConnectionCount[$rRow['id']] ?: 0);
|
|
}
|
|
if (!$rIsAPI) {
|
|
$rCategoryIDs = json_decode($rRow['category_id'], true);
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rCategory = ($rCategories[intval(RequestManager::get('category'))]['category_name'] ?: 'No Category');
|
|
} else {
|
|
$rCategory = ($rCategories[$rCategoryIDs[0]]['category_name'] ?: 'No Category');
|
|
}
|
|
if (1 < count($rCategoryIDs)) {
|
|
$rCategory .= ' (+' . (count($rCategoryIDs) - 1) . ' others)';
|
|
}
|
|
if (0 < $rRow['tv_archive_duration'] && 0 < $rRow['tv_archive_server_id']) {
|
|
$rRow['stream_display_name'] .= " <i class='text-danger mdi mdi-record'></i>";
|
|
}
|
|
if (0 < $rRow['clients']) {
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
$rButtons = '<button title="Kill Connections" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'purge');\"><i class=\"mdi mdi-hammer\"></i></button>";
|
|
$rClients = "<a href='javascript: void(0);' onClick='viewLiveConnections(" . intval($rRow['id']) . ");'><button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button></a>';
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button>';
|
|
}
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-secondary btn-xs waves-effect waves-light'>0</button>";
|
|
}
|
|
if ((string) $rRow['stream_icon'] !== '') {
|
|
$rIcon = "<a href='javascript: void(0);' onClick='openImage(this);' data-src='resize?maxw=512&maxh=512&url=" . $rRow['stream_icon'] . "'><img loading='lazy' src='resize?maxw=96&maxh=32&url=" . $rRow['stream_icon'] . "' /></a>";
|
|
} else {
|
|
$rIcon = '';
|
|
}
|
|
$rReturn['data'][] = [$rRow['id'], $rIcon, $rRow['stream_display_name'], $rCategory, $rClients, $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'radios') {
|
|
if ($rPermissions['can_view_vod']) {
|
|
$rCategories = CategoryService::getAllByType('radio');
|
|
$rOrder = ['`id`', false, '`stream_display_name`', '`category_id`', '`clients`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
if (0 < count($rPermissions['stream_ids'])) {
|
|
$rWhere[] = '`streams`.`id` IN (' . implode(',', array_map('intval', $rPermissions['stream_ids'])) . ')';
|
|
$rWhere[] = '`type` = 4';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 2) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`id` LIKE ? OR `stream_display_name` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rWhere[] = "JSON_CONTAINS(`category_id`, ?, '\$')";
|
|
$rWhereV[] = RequestManager::get('category');
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(`streams`.`id`) AS `count` FROM `streams` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `id`, `stream_icon`, `stream_display_name`, `category_id`, (SELECT COUNT(*) FROM `lines_live` LEFT JOIN `lines` ON `lines`.`id` = `lines_live`.`user_id` WHERE `lines_live`.`stream_id` = `streams`.`id` AND `hls_end` = 0 AND `lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')) AS `clients` FROM `streams` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rConnectionCount = $rReports = [];
|
|
$db->query('SELECT `id` FROM `lines` WHERE `member_id` IN (' . implode(',', $rUserInfo['reports']) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rReports[] = $rRow['id'];
|
|
}
|
|
if (0 < count($rReports)) {
|
|
foreach (ConnectionTracker::getUserConnections($rReports, false) as $rConnections) {
|
|
foreach ($rConnections as $rConnection) {
|
|
$rConnectionCount[$rConnection['stream_id']]++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($rRows as $rRow) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rRow['clients'] = ($rConnectionCount[$rRow['id']] ?: 0);
|
|
}
|
|
if (!$rIsAPI) {
|
|
$rCategoryIDs = json_decode($rRow['category_id'], true);
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rCategory = ($rCategories[intval(RequestManager::get('category'))]['category_name'] ?: 'No Category');
|
|
} else {
|
|
$rCategory = ($rCategories[$rCategoryIDs[0]]['category_name'] ?: 'No Category');
|
|
}
|
|
if (1 < count($rCategoryIDs)) {
|
|
$rCategory .= ' (+' . (count($rCategoryIDs) - 1) . ' others)';
|
|
}
|
|
if (0 < $rRow['clients']) {
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
$rButtons = '<button title="Kill Connections" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'purge');\"><i class=\"mdi mdi-hammer\"></i></button>";
|
|
$rClients = "<a href='javascript: void(0);' onClick='viewLiveConnections(" . intval($rRow['id']) . ");'><button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button></a>';
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button>';
|
|
}
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-secondary btn-xs waves-effect waves-light'>0</button>";
|
|
}
|
|
if ((string) $rRow['stream_icon'] !== '') {
|
|
$rIcon = "<a href='javascript: void(0);' onClick='openImage(this);' data-src='resize?maxw=512&maxh=512&url=" . $rRow['stream_icon'] . "'><img loading='lazy' src='resize?maxw=96&maxh=32&url=" . $rRow['stream_icon'] . "' /></a>";
|
|
} else {
|
|
$rIcon = '';
|
|
}
|
|
$rReturn['data'][] = [$rRow['id'], $rIcon, $rRow['stream_display_name'], $rCategory, $rClients, $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'movies') {
|
|
if ($rPermissions['can_view_vod']) {
|
|
$rCategories = CategoryService::getAllByType('movie');
|
|
$rOrder = ['`id`', false, '`stream_display_name`', '`category_id`', '`clients`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
if (0 < count($rPermissions['stream_ids'])) {
|
|
$rWhere[] = '`streams`.`id` IN (' . implode(',', array_map('intval', $rPermissions['stream_ids'])) . ')';
|
|
$rWhere[] = '`type` = 2';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 2) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`id` LIKE ? OR `stream_display_name` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rWhere[] = "JSON_CONTAINS(`category_id`, ?, '\$')";
|
|
$rWhereV[] = RequestManager::get('category');
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(`streams`.`id`) AS `count` FROM `streams` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `id`, `stream_icon`, `stream_display_name`, `movie_properties`, `category_id`, (SELECT COUNT(*) FROM `lines_live` LEFT JOIN `lines` ON `lines`.`id` = `lines_live`.`user_id` WHERE `lines_live`.`stream_id` = `streams`.`id` AND `hls_end` = 0 AND `lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')) AS `clients` FROM `streams` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rConnectionCount = $rReports = [];
|
|
$db->query('SELECT `id` FROM `lines` WHERE `member_id` IN (' . implode(',', $rUserInfo['reports']) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rReports[] = $rRow['id'];
|
|
}
|
|
if (0 < count($rReports)) {
|
|
foreach (ConnectionTracker::getUserConnections($rReports, false) as $rConnections) {
|
|
foreach ($rConnections as $rConnection) {
|
|
$rConnectionCount[$rConnection['stream_id']]++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($rRows as $rRow) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rRow['clients'] = ($rConnectionCount[$rRow['id']] ?: 0);
|
|
}
|
|
if (!$rIsAPI) {
|
|
$rCategoryIDs = json_decode($rRow['category_id'], true);
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rCategory = ($rCategories[intval(RequestManager::get('category'))]['category_name'] ?: 'No Category');
|
|
} else {
|
|
$rCategory = ($rCategories[$rCategoryIDs[0]]['category_name'] ?: 'No Category');
|
|
}
|
|
if (1 < count($rCategoryIDs)) {
|
|
$rCategory .= ' (+' . (count($rCategoryIDs) - 1) . ' others)';
|
|
}
|
|
if (0 < $rRow['clients']) {
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
$rButtons = '<button title="Kill Connections" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'purge');\"><i class=\"mdi mdi-hammer\"></i></button>";
|
|
$rClients = "<a href='javascript: void(0);' onClick='viewLiveConnections(" . intval($rRow['id']) . ");'><button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button></a>';
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button>';
|
|
}
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-secondary btn-xs waves-effect waves-light'>0</button>";
|
|
}
|
|
$rProperties = json_decode($rRow['movie_properties'], true);
|
|
if ((string) $rProperties['movie_image'] !== '') {
|
|
$rImage = "<a href='javascript: void(0);' onClick='openImage(this);' data-src='resize?maxw=512&maxh=512&url=" . $rProperties['movie_image'] . "'><img loading='lazy' src='resize?maxh=58&maxw=32&url=" . $rProperties['movie_image'] . "' /></a>";
|
|
} else {
|
|
$rImage = '';
|
|
}
|
|
$rReturn['data'][] = [$rRow['id'], $rImage, $rRow['stream_display_name'], $rCategory, $rClients, $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'episodes') {
|
|
if ($rPermissions['can_view_vod']) {
|
|
$rCategories = CategoryService::getAllByType('series');
|
|
$rOrder = ['`id`', false, '`stream_display_name`', '`category_id`', '`clients`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
if (0 < count($rPermissions['stream_ids'])) {
|
|
$rWhere[] = '`streams`.`id` IN (' . implode(',', array_map('intval', $rPermissions['stream_ids'])) . ')';
|
|
$rWhere[] = '`type` = 5';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 3) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`streams`.`id` LIKE ? OR `stream_display_name` LIKE ? OR `streams_series`.`title` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rWhere[] = "JSON_CONTAINS(`streams_series`.`category_id`, ?, '\$')";
|
|
$rWhereV[] = RequestManager::get('category');
|
|
}
|
|
if ((string) RequestManager::get('series') !== '') {
|
|
$rWhere[] = '`streams_series`.`id` = ?';
|
|
$rWhereV[] = RequestManager::get('series');
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(`streams`.`id`) AS `count` FROM `streams` LEFT JOIN `streams_episodes` ON `streams_episodes`.`stream_id` = `streams`.`id` LEFT JOIN `streams_series` ON `streams_series`.`id` = `streams_episodes`.`series_id` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `streams`.`id`, `stream_icon`, `stream_display_name`, `movie_properties`, `streams_series`.`category_id`, `streams_series`.`title`, `streams_episodes`.`season_num`, (SELECT COUNT(*) FROM `lines_live` LEFT JOIN `lines` ON `lines`.`id` = `lines_live`.`user_id` WHERE `lines_live`.`stream_id` = `streams`.`id` AND `hls_end` = 0 AND `lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')) AS `clients` FROM `streams` LEFT JOIN `streams_episodes` ON `streams_episodes`.`stream_id` = `streams`.`id` LEFT JOIN `streams_series` ON `streams_series`.`id` = `streams_episodes`.`series_id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rConnectionCount = $rReports = [];
|
|
$db->query('SELECT `id` FROM `lines` WHERE `member_id` IN (' . implode(',', $rUserInfo['reports']) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rReports[] = $rRow['id'];
|
|
}
|
|
if (0 < count($rReports)) {
|
|
foreach (ConnectionTracker::getUserConnections($rReports, false) as $rConnections) {
|
|
foreach ($rConnections as $rConnection) {
|
|
$rConnectionCount[$rConnection['stream_id']]++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($rRows as $rRow) {
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rRow['clients'] = ($rConnectionCount[$rRow['id']] ?: 0);
|
|
}
|
|
if (!$rIsAPI) {
|
|
$rSeriesName = $rRow['title'] . ' - Season ' . $rRow['season_num'];
|
|
$rStreamName = '<b>' . $rRow['stream_display_name'] . "</b><br><span style='font-size:11px;'>" . $rSeriesName . '</span>';
|
|
$rCategoryIDs = json_decode($rRow['category_id'], true);
|
|
if ((string) RequestManager::get('category') !== '') {
|
|
$rCategory = ($rCategories[intval(RequestManager::get('category'))]['category_name'] ?: 'No Category');
|
|
} else {
|
|
$rCategory = ($rCategories[$rCategoryIDs[0]]['category_name'] ?: 'No Category');
|
|
}
|
|
if (1 < count($rCategoryIDs)) {
|
|
$rCategory .= ' (+' . (count($rCategoryIDs) - 1) . ' others)';
|
|
}
|
|
if (0 < $rRow['clients']) {
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
$rButtons = '<button title="Kill Connections" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'purge');\"><i class=\"mdi mdi-hammer\"></i></button>";
|
|
$rClients = "<a href='javascript: void(0);' onClick='viewLiveConnections(" . intval($rRow['id']) . ");'><button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button></a>';
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-info btn-xs waves-effect waves-light'>" . $rRow['clients'] . '</button>';
|
|
}
|
|
} else {
|
|
$rButtons = '<button type="button" disabled class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-hammer"></i></button>';
|
|
$rClients = "<button type='button' class='btn btn-secondary btn-xs waves-effect waves-light'>0</button>";
|
|
}
|
|
$rProperties = json_decode($rRow['movie_properties'], true);
|
|
if ((string) $rProperties['movie_image'] !== '') {
|
|
$rImage = "<a href='javascript: void(0);' onClick='openImage(this);' data-src='resize?maxw=512&maxh=512&url=" . $rProperties['movie_image'] . "'><img loading='lazy' src='resize?maxh=58&maxw=32&url=" . $rProperties['movie_image'] . "' /></a>";
|
|
} else {
|
|
$rImage = '';
|
|
}
|
|
$rReturn['data'][] = [$rRow['id'], $rImage, $rStreamName, $rCategory, $rClients, $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'line_activity') {
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
$rOrder = ['`username`', '`streams`.`stream_display_name`', '`lines_activity`.`user_agent`', '`lines_activity`.`isp`', '`lines_activity`.`user_ip`', '`lines_activity`.`date_start`', '`lines_activity`.`date_end`', '`lines_activity`.`date_end` - `lines_activity`.`date_start`', '`lines_activity`.`container`'];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
$rWhere[] = '`lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 10) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`lines_activity`.`user_agent` LIKE ? OR `lines_activity`.`user_ip` LIKE ? OR `lines_activity`.`container` LIKE ? OR FROM_UNIXTIME(`lines_activity`.`date_start`) LIKE ? OR FROM_UNIXTIME(`lines_activity`.`date_end`) LIKE ? OR `lines_activity`.`geoip_country_code` LIKE ? OR `lines`.`username` LIKE ? OR `mag_devices`.`mac` LIKE ? OR `enigma2_devices`.`mac` LIKE ? OR `streams`.`stream_display_name` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('range') !== '') {
|
|
$rStartTime = substr(RequestManager::get('range'), 0, 10);
|
|
$rEndTime = substr(RequestManager::get('range'), strlen(RequestManager::get('range')) - 10, 10);
|
|
if (!$rStartTime = strtotime($rStartTime . ' 00:00:00')) {
|
|
$rStartTime = null;
|
|
}
|
|
if (!$rEndTime = strtotime($rEndTime . ' 23:59:59')) {
|
|
$rEndTime = null;
|
|
}
|
|
if ($rStartTime && $rEndTime) {
|
|
$rWhere[] = '(`lines_activity`.`date_start` >= ? AND `lines_activity`.`date_end` <= ?)';
|
|
$rWhereV[] = $rStartTime;
|
|
$rWhereV[] = $rEndTime;
|
|
}
|
|
}
|
|
if ((string) RequestManager::get('stream') !== '') {
|
|
$rWhere[] = '`lines_activity`.`stream_id` = ?';
|
|
$rWhereV[] = RequestManager::get('stream');
|
|
}
|
|
if ((string) RequestManager::get('user') !== '') {
|
|
$rWhere[] = '`lines`.`member_id` = ?';
|
|
$rWhereV[] = RequestManager::get('user');
|
|
}
|
|
if ((string) RequestManager::get('line') !== '') {
|
|
$rWhere[] = '`lines_activity`.`user_id` = ?';
|
|
$rWhereV[] = RequestManager::get('line');
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(*) AS `count` FROM `lines_activity` LEFT JOIN `lines` ON `lines_activity`.`user_id` = `lines`.`id` LEFT JOIN `streams` ON `lines_activity`.`stream_id` = `streams`.`id` LEFT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines_activity`.`user_id` LEFT JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines_activity`.`user_id` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `mag_devices`.`mag_id`, `enigma2_devices`.`device_id`, `lines`.`is_e2`, `lines`.`is_mag`, `lines_activity`.`activity_id`, `lines_activity`.`container`, `lines_activity`.`isp`, `lines_activity`.`user_id`, `lines_activity`.`stream_id`, `streams`.`series_no`, `lines_activity`.`server_id`, `lines_activity`.`user_agent`, `lines_activity`.`user_ip`, `lines_activity`.`container`, `lines_activity`.`date_start`, `lines_activity`.`date_end`, `lines_activity`.`geoip_country_code`, IF(`lines`.`is_mag`, `mag_devices`.`mac`, IF(`lines`.`is_e2`, `enigma2_devices`.`mac`, `lines`.`username`)) AS `username`, `streams`.`stream_display_name`, `streams`.`type`, `lines`.`is_restreamer` FROM `lines_activity` LEFT JOIN `lines` ON `lines_activity`.`user_id` = `lines`.`id` LEFT JOIN `streams` ON `lines_activity`.`stream_id` = `streams`.`id` LEFT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines_activity`.`user_id` LEFT JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines_activity`.`user_id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
foreach ($db->get_rows() as $rRow) {
|
|
if (!$rIsAPI) {
|
|
if ($rRow['is_mag']) {
|
|
$rUsername = "<a href='mag?id=" . $rRow['mag_id'] . "'>" . $rRow['username'] . '</a>';
|
|
} else {
|
|
if ($rRow['is_e2']) {
|
|
$rUsername = "<a href='enigma?id=" . $rRow['device_id'] . "'>" . $rRow['username'] . '</a>';
|
|
} else {
|
|
$rUsername = "<a href='line?id=" . $rRow['user_id'] . "'>" . $rRow['username'] . '</a>';
|
|
}
|
|
}
|
|
$rChannel = $rRow['stream_display_name'];
|
|
if ((string) $rRow['geoip_country_code'] !== '') {
|
|
$rGeoCountry = "<img loading='lazy' src='assets/img/countries/" . strtolower($rRow['geoip_country_code']) . ".png'></img> ";
|
|
} else {
|
|
$rGeoCountry = '';
|
|
}
|
|
if ($rRow['user_ip']) {
|
|
$rIP = $rGeoCountry . "<a onClick=\"whois('" . $rRow['user_ip'] . "');\" href='javascript: void(0);'>" . $rRow['user_ip'] . '</a>';
|
|
} else {
|
|
$rIP = '';
|
|
}
|
|
if ($rRow['date_start']) {
|
|
$rStart = date($rSettings['datetime_format'], $rRow['date_start']);
|
|
} else {
|
|
$rStart = '';
|
|
}
|
|
if ($rRow['date_end']) {
|
|
$rStop = date($rSettings['datetime_format'], $rRow['date_end']);
|
|
} else {
|
|
$rStop = '';
|
|
}
|
|
$rPlayer = trim(explode('(', $rRow['user_agent'])[0]);
|
|
$rDuration = $rRow['date_end'] - $rRow['date_start'];
|
|
$rColour = 'success';
|
|
if (86400 <= $rDuration) {
|
|
$rDuration = sprintf('%02dd %02dh', $rDuration / 86400, ($rDuration / 3600) % 24);
|
|
$rColour = 'danger';
|
|
} else {
|
|
if (3600 <= $rDuration) {
|
|
if (14400 < $rDuration) {
|
|
$rColour = 'warning';
|
|
} else {
|
|
if (43200 < $rDuration) {
|
|
$rColour = 'danger';
|
|
}
|
|
}
|
|
$rDuration = sprintf('%02dh %02dm', $rDuration / 3600, ($rDuration / 60) % 60);
|
|
} else {
|
|
$rDuration = sprintf('%02dm %02ds', ($rDuration / 60) % 60, $rDuration % 60);
|
|
}
|
|
}
|
|
$rDuration = "<button type='button' class='btn btn-" . $rColour . " btn-xs waves-effect waves-light btn-fixed'>" . $rDuration . '</button>';
|
|
$rReturn['data'][] = [$rUsername, $rChannel, $rPlayer, $rRow['isp'], $rIP, $rStart, $rStop, $rDuration, strtoupper($rRow['container'])];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'live_connections') {
|
|
if ($rPermissions['reseller_client_connection_logs']) {
|
|
$rRows = [];
|
|
if (SettingsManager::get('redis_handler')) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) !== 'desc');
|
|
$rReports = [];
|
|
$rUserID = (0 < intval(RequestManager::get('user')) ? intval(RequestManager::get('user')) : null);
|
|
$rStreamID = (0 < intval(RequestManager::get('stream_id')) ? intval(RequestManager::get('stream_id')) : null);
|
|
if ($rUserID && in_array($rUserID, $rUserInfo['reports'])) {
|
|
$db->query('SELECT `id` FROM `lines` WHERE `member_id` = ?;', $rUserID);
|
|
} else {
|
|
$db->query('SELECT `id` FROM `lines` WHERE `member_id` IN (' . implode(',', $rUserInfo['reports']) . ');');
|
|
}
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rReports[] = $rRow['id'];
|
|
}
|
|
$rKeys = ConnectionTracker::getUserConnections($rReports, false, true);
|
|
if ($rOrderDirection) {
|
|
$rKeys = array_reverse($rKeys);
|
|
}
|
|
$rKeyCount = count($rKeys);
|
|
foreach (RedisManager::instance()->mGet($rKeys) as $rRow) {
|
|
$rRow = igbinary_unserialize($rRow);
|
|
if (is_array($rRow)) {
|
|
if (!$rFilterBefore) {
|
|
if (!$rStreamID || $rStreamID == $rRow['stream_id']) {
|
|
if (!in_array($rRow['user_id'], $rReports)) {
|
|
$rKeyCount--;
|
|
}
|
|
} else {
|
|
$rKeyCount--;
|
|
}
|
|
}
|
|
$rRow['activity_id'] = $rRow['uuid'];
|
|
$rRow['identifier'] = ($rRow['user_id'] ?: $rRow['hmac_id'] . '_' . $rRow['hmac_identifier']);
|
|
$rRow['active_time'] = time() - $rRow['date_start'];
|
|
$rRow['server_name'] = (ServerRepository::getAll()[$rRow['server_id']]['server_name'] ?: '');
|
|
$rRows[] = $rRow;
|
|
} else {
|
|
$rKeyCount--;
|
|
}
|
|
}
|
|
$rOrder = ['uuid', 'divergence', 'identifier', 'stream_display_name', 'user_agent', 'isp', 'user_ip', 'active_time', 'container', null];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
array_multisort(array_column($rRows, $rOrder[$rOrderRow]), ($rOrderDirection ? SORT_ASC : SORT_DESC), $rRows);
|
|
}
|
|
$rRows = array_slice($rRows, $rStart, $rLimit);
|
|
$rUUIDs = $rStreamIDs = $rUserIDs = [];
|
|
foreach ($rRows as $rRow) {
|
|
if ($rRow['stream_id']) {
|
|
$rStreamIDs[] = intval($rRow['stream_id']);
|
|
}
|
|
if ($rRow['user_id']) {
|
|
$rUserIDs[] = intval($rRow['user_id']);
|
|
}
|
|
if ($rRow['uuid']) {
|
|
$rUUIDs[] = $rRow['uuid'];
|
|
}
|
|
}
|
|
$rStreamNames = $rDivergenceMap = $rSeriesMap = $rUserMap = [];
|
|
if (0 < count($rUserIDs)) {
|
|
$db->query('SELECT `lines`.`id`, `lines`.`is_mag`, `lines`.`is_e2`, `lines`.`is_restreamer`, `lines`.`username`, `mag_devices`.`mag_id`, `enigma2_devices`.`device_id` FROM `lines` LEFT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines`.`id` LEFT JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines`.`id` WHERE `lines`.`id` IN (' . implode(',', $rUserIDs) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rUserID = $rRow['id'];
|
|
unset($rRow['id']);
|
|
$rUserMap[$rUserID] = $rRow;
|
|
}
|
|
}
|
|
if (0 < count($rStreamIDs)) {
|
|
$db->query('SELECT `stream_id`, `series_id` FROM `streams_episodes` WHERE `stream_id` IN (' . implode(',', $rStreamIDs) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rSeriesMap[$rRow['stream_id']] = $rRow['series_id'];
|
|
}
|
|
$db->query('SELECT `id`, `type`, `stream_display_name` FROM `streams` WHERE `id` IN (' . implode(',', $rStreamIDs) . ');');
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rStreamNames[$rRow['id']] = [$rRow['stream_display_name'], $rRow['type']];
|
|
}
|
|
}
|
|
if (0 < count($rUUIDs)) {
|
|
$db->query("SELECT `uuid`, `divergence` FROM `lines_divergence` WHERE `uuid` IN ('" . implode("','", $rUUIDs) . "');");
|
|
foreach ($db->get_rows() as $rRow) {
|
|
$rDivergenceMap[$rRow['uuid']] = $rRow['divergence'];
|
|
}
|
|
}
|
|
$i = 0;
|
|
while ($i < count($rRows)) {
|
|
$rRows[$i]['divergence'] = ($rDivergenceMap[$rRows[$i]['uuid']] ?: 0);
|
|
$rRows[$i]['series_no'] = ($rSeriesMap[$rRows[$i]['stream_id']] ?: null);
|
|
$rRows[$i]['stream_display_name'] = ($rStreamNames[$rRows[$i]['stream_id']][0] ?: '');
|
|
$rRows[$i]['type'] = ($rStreamNames[$rRows[$i]['stream_id']][1] ?: 1);
|
|
$rRows[$i] = array_merge($rRows[$i], ($rUserMap[$rRows[$i]['user_id']] ?: []));
|
|
$i++;
|
|
}
|
|
$rReturn['recordsTotal'] = $rKeyCount;
|
|
$rReturn['recordsFiltered'] = ($rIsAPI ? ($rReturn['recordsTotal'] < $rLimit ? $rReturn['recordsTotal'] : $rLimit) : $rReturn['recordsTotal']);
|
|
} else {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrder = ['`lines_live`.`activity_id`', '`lines_live`.`divergence`', '`username`', '`streams`.`stream_display_name`', '`lines_live`.`user_agent`', '`lines_live`.`isp`', '`lines_live`.`user_ip`', 'UNIX_TIMESTAMP() - `lines_live`.`date_start`', '`lines_live`.`container`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
$rWhere[] = '`hls_end` = 0';
|
|
$rWhere[] = '`lines`.`member_id` IN (' . implode(',', $rUserInfo['reports']) . ')';
|
|
if (0 < strlen(RequestManager::get('search')['value'])) {
|
|
foreach (range(1, 9) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`lines_live`.`user_agent` LIKE ? OR `lines_live`.`user_ip` LIKE ? OR `lines_live`.`container` LIKE ? OR FROM_UNIXTIME(`lines_live`.`date_start`) LIKE ? OR `lines_live`.`geoip_country_code` LIKE ? OR `lines`.`username` LIKE ? OR `mag_devices`.`mac` LIKE ? OR `enigma2_devices`.`mac` LIKE ? OR `streams`.`stream_display_name` LIKE ?)';
|
|
}
|
|
if (0 < intval(RequestManager::get('stream'))) {
|
|
$rWhere[] = '`lines_live`.`stream_id` = ?';
|
|
$rWhereV[] = RequestManager::get('stream');
|
|
}
|
|
if (0 < intval(RequestManager::get('user'))) {
|
|
$rWhere[] = '`lines`.`member_id` = ?';
|
|
$rWhereV[] = RequestManager::get('user');
|
|
}
|
|
if (0 < intval(RequestManager::get('line'))) {
|
|
$rWhere[] = '`lines_live`.`user_id` = ?';
|
|
$rWhereV[] = RequestManager::get('line');
|
|
}
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(*) AS `count` FROM `lines_live` LEFT JOIN `lines` ON `lines_live`.`user_id` = `lines`.`id` LEFT JOIN `streams` ON `lines_live`.`stream_id` = `streams`.`id` LEFT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines_live`.`user_id` LEFT JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines_live`.`user_id` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `mag_devices`.`mag_id`, `enigma2_devices`.`device_id`, `lines`.`is_e2`, `lines`.`is_mag`, `lines_live`.`activity_id`, `lines_live`.`divergence`, `lines_live`.`user_id`, `lines_live`.`stream_id`, `streams`.`series_no`, `lines`.`is_restreamer`, `lines_live`.`isp`, `lines_live`.`server_id`, `lines_live`.`user_agent`, `lines_live`.`user_ip`, `lines_live`.`container`, `lines_live`.`uuid`, `lines_live`.`date_start`, `lines_live`.`geoip_country_code`, IF(`lines`.`is_mag`, `mag_devices`.`mac`, IF(`lines`.`is_e2`, `enigma2_devices`.`mac`, `lines`.`username`)) AS `username`, `streams`.`stream_display_name`, `streams`.`type` FROM `lines_live` LEFT JOIN `lines` ON `lines_live`.`user_id` = `lines`.`id` LEFT JOIN `streams` ON `lines_live`.`stream_id` = `streams`.`id` LEFT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines_live`.`user_id` LEFT JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines_live`.`user_id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
$rRows = $db->get_rows();
|
|
}
|
|
}
|
|
}
|
|
if (0 < count($rRows)) {
|
|
foreach ($rRows as $rRow) {
|
|
if (!$rIsAPI) {
|
|
if ($rRow['divergence'] <= 50) {
|
|
$rDivergence = '<i class="text-success fas fa-square tooltip" title="' . intval(100 - $rRow['divergence']) . '%"></i>';
|
|
} else {
|
|
if ($rRow['divergence'] <= 80) {
|
|
$rDivergence = '<i class="text-warning fas fa-square tooltip" title="' . intval(100 - $rRow['divergence']) . '%"></i>';
|
|
} else {
|
|
$rDivergence = '<i class="text-danger fas fa-square tooltip" title="' . intval(100 - $rRow['divergence']) . '%"></i>';
|
|
}
|
|
}
|
|
if ($rRow['is_mag']) {
|
|
$rUsername = "<a href='mag?id=" . $rRow['mag_id'] . "'>" . $rRow['username'] . '</a>';
|
|
} else {
|
|
if ($rRow['is_e2']) {
|
|
$rUsername = "<a href='enigma?id=" . $rRow['device_id'] . "'>" . $rRow['username'] . '</a>';
|
|
} else {
|
|
$rUsername = "<a href='line?id=" . $rRow['user_id'] . "'>" . $rRow['username'] . '</a>';
|
|
}
|
|
}
|
|
$rChannel = $rRow['stream_display_name'];
|
|
if ((string) $rRow['geoip_country_code'] !== '') {
|
|
$rGeoCountry = "<img loading='lazy' src='assets/img/countries/" . strtolower($rRow['geoip_country_code']) . ".png'></img> ";
|
|
} else {
|
|
$rGeoCountry = '';
|
|
}
|
|
if ($rRow['user_ip']) {
|
|
$rIP = $rGeoCountry . "<a onClick=\"whois('" . $rRow['user_ip'] . "');\" href='javascript: void(0);'>" . $rRow['user_ip'] . '</a>';
|
|
} else {
|
|
$rIP = '';
|
|
}
|
|
$rPlayer = trim(explode('(', $rRow['user_agent'])[0]);
|
|
$rDuration = intval(time()) - intval($rRow['date_start']);
|
|
$rColour = 'success';
|
|
if (86400 <= $rDuration) {
|
|
$rDuration = sprintf('%02dd %02dh', $rDuration / 86400, ($rDuration / 3600) % 24);
|
|
$rColour = 'danger';
|
|
} else {
|
|
if (3600 <= $rDuration) {
|
|
if (14400 < $rDuration) {
|
|
$rColour = 'warning';
|
|
} else {
|
|
if (43200 < $rDuration) {
|
|
$rColour = 'danger';
|
|
}
|
|
}
|
|
$rDuration = sprintf('%02dh %02dm', $rDuration / 3600, ($rDuration / 60) % 60);
|
|
} else {
|
|
$rDuration = sprintf('%02dm %02ds', ($rDuration / 60) % 60, $rDuration % 60);
|
|
}
|
|
}
|
|
$rDuration = "<button type='button' class='btn btn-" . $rColour . " btn-xs waves-effect waves-light btn-fixed'>" . $rDuration . '</button>';
|
|
$rButtons = "<button title=\"Kill Connection\" type=\"button\" class=\"btn btn-light waves-effect waves-light btn-xs tooltip\" onClick=\"api('" . $rRow['uuid'] . "', 'kill');\"><i class=\"fas fa-hammer\"></i></button>";
|
|
$rReturn['data'][] = [$rRow['activity_id'], $rDivergence, $rUsername, $rChannel, $rPlayer, $rRow['isp'], $rIP, $rDuration, strtoupper($rRow['container']), $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
if ($rType == 'reg_user_logs') {
|
|
$rOrder = ['`users_logs`.`id`', '`users`.`username`', '`users_logs`.`log_id`', '`users_logs`.`type`, `users_logs`.`action`', '`users_logs`.`cost`', '`users_logs`.`credits_after`', '`users_logs`.`date`'];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
$rWhere[] = '`users_logs`.`owner` IN (' . implode(',', $rUserInfo['reports']) . ')';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 3) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`users`.`username` LIKE ? OR `users_logs`.`type` LIKE ? OR `users_logs`.`action` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('range') !== '') {
|
|
$rStartTime = substr(RequestManager::get('range'), 0, 10);
|
|
$rEndTime = substr(RequestManager::get('range'), strlen(RequestManager::get('range')) - 10, 10);
|
|
if (!$rStartTime = strtotime($rStartTime . ' 00:00:00')) {
|
|
$rStartTime = null;
|
|
}
|
|
if (!$rEndTime = strtotime($rEndTime . ' 23:59:59')) {
|
|
$rEndTime = null;
|
|
}
|
|
if ($rStartTime && $rEndTime) {
|
|
$rWhere[] = '(`users_logs`.`date` >= ? AND `users_logs`.`date` <= ?)';
|
|
$rWhereV[] = $rStartTime;
|
|
$rWhereV[] = $rEndTime;
|
|
}
|
|
}
|
|
if ((string) RequestManager::get('reseller') !== '') {
|
|
$rWhere[] = '`users_logs`.`owner` = ?';
|
|
$rWhereV[] = RequestManager::get('reseller');
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(*) AS `count` FROM `users_logs` LEFT JOIN `users` ON `users`.`id` = `users_logs`.`owner` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rPackages = PackageService::getAll();
|
|
$rQuery = 'SELECT `users`.`username`, `users_logs`.`id`, `users_logs`.`owner`, `users_logs`.`type`, `users_logs`.`action`, `users_logs`.`log_id`, `users_logs`.`package_id`, `users_logs`.`cost`, `users_logs`.`credits_after`, `users_logs`.`date`, `users_logs`.`deleted_info` FROM `users_logs` LEFT JOIN `users` ON `users`.`id` = `users_logs`.`owner` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
foreach ($db->get_rows() as $rRow) {
|
|
if (!$rIsAPI) {
|
|
if (in_array($rRow['owner'], array_merge($rPermissions['direct_reports'], [$rUserInfo['id']]))) {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['owner']) . "'>" . $rRow['username'] . '</a>';
|
|
} else {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['owner']) . "'>" . $rRow['username'] . "<br/><small class='text-pink'>(indirect)</small></a>";
|
|
}
|
|
$rDevice = ['line' => 'User Line', 'mag' => 'MAG Device', 'enigma' => 'Enigma2 Device', 'user' => 'Reseller'][$rRow['type']];
|
|
switch ($rRow['action']) {
|
|
case 'new':
|
|
if ($rRow['package_id']) {
|
|
$rText = 'Created New ' . $rDevice . ' with Package: ' . $rPackages[$rRow['package_id']]['package_name'];
|
|
} else {
|
|
$rText = 'Created New ' . $rDevice;
|
|
}
|
|
break;
|
|
case 'extend':
|
|
if ($rRow['package_id']) {
|
|
$rText = 'Extended ' . $rDevice . ' with Package: ' . $rPackages[$rRow['package_id']]['package_name'];
|
|
} else {
|
|
$rText = 'Extended ' . $rDevice;
|
|
}
|
|
break;
|
|
case 'edit':
|
|
$rText = 'Edited ' . $rDevice;
|
|
break;
|
|
case 'enable':
|
|
$rText = 'Enabled ' . $rDevice;
|
|
break;
|
|
case 'disable':
|
|
$rText = 'Disabled ' . $rDevice;
|
|
break;
|
|
case 'delete':
|
|
$rText = 'Deleted ' . $rDevice;
|
|
break;
|
|
case 'send_event':
|
|
$rText = 'Sent Event to ' . $rDevice;
|
|
break;
|
|
case 'adjust_credits':
|
|
$rText = 'Adjusted Credits by ' . $rRow['cost'];
|
|
break;
|
|
}
|
|
$rLineInfo = null;
|
|
switch ($rRow['type']) {
|
|
case 'line':
|
|
$rLine = UserRepository::getLineById($rRow['log_id']);
|
|
if ($rLine) {
|
|
$rLineInfo = "<a href='line?id=" . $rRow['log_id'] . "'>" . $rLine['username'] . '</a>';
|
|
}
|
|
break;
|
|
case 'user':
|
|
$rLine = UserRepository::getRegisteredUserById($rRow['log_id']);
|
|
if ($rLine) {
|
|
$rLineInfo = "<a href='user?id=" . $rRow['log_id'] . "'>" . $rLine['username'] . '</a>';
|
|
}
|
|
break;
|
|
case 'mag':
|
|
$rLine = MagService::getById($rRow['log_id']);
|
|
if ($rLine) {
|
|
$rLineInfo = "<a href='mag?id=" . $rRow['log_id'] . "'>" . $rLine['mac'] . '</a>';
|
|
}
|
|
break;
|
|
case 'enigma':
|
|
$rLine = EnigmaService::getById($rRow['log_id']);
|
|
if ($rLine) {
|
|
$rLineInfo = "<a href='enigma?id=" . $rRow['log_id'] . "'>" . $rLine['mac'] . '</a>';
|
|
}
|
|
break;
|
|
}
|
|
if (!$rLineInfo) {
|
|
$rDeletedInfo = json_decode($rRow['deleted_info'], true);
|
|
if (is_array($rDeletedInfo)) {
|
|
if (isset($rDeletedInfo['mac'])) {
|
|
$rLineInfo = "<span class='text-secondary'>" . $rDeletedInfo['mac'] . '</span>';
|
|
} else {
|
|
$rLineInfo = "<span class='text-secondary'>" . $rDeletedInfo['username'] . '</span>';
|
|
}
|
|
} else {
|
|
$rLineInfo = "<span class='text-secondary'>DELETED</span>";
|
|
}
|
|
}
|
|
$rReturn['data'][] = [$rRow['id'], $rOwner, $rLineInfo, $rText, number_format($rRow['cost'], 0), number_format($rRow['credits_after'], 0), date($rSettings['datetime_format'], $rRow['date'])];
|
|
} else {
|
|
unset($rRow['deleted_info']);
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
if ($rType == 'reg_users') {
|
|
if ($rPermissions['create_sub_resellers']) {
|
|
$rOrder = ['`users`.`id`', '`users`.`username`', '`r`.`username`', '`users`.`ip`', '`users`.`status`', '`users`.`credits`', '`user_count`', '`users`.`last_login`', false];
|
|
if (RequestManager::has('order') && (string) RequestManager::get('order')[0]['column'] !== '') {
|
|
$rOrderRow = intval(RequestManager::get('order')[0]['column']);
|
|
} else {
|
|
$rOrderRow = 0;
|
|
}
|
|
$rWhere = $rWhereV = [];
|
|
$rWhere[] = '`users`.`owner_id` IN (' . implode(',', $rUserInfo['reports']) . ')';
|
|
if ((string) RequestManager::get('search')['value'] !== '') {
|
|
foreach (range(1, 9) as $rInt) {
|
|
$rWhereV[] = '%' . RequestManager::get('search')['value'] . '%';
|
|
}
|
|
$rWhere[] = '(`users`.`id` LIKE ? OR `users`.`username` LIKE ? OR `users`.`notes` LIKE ? OR `r`.`username` LIKE ? OR FROM_UNIXTIME(`users`.`date_registered`) LIKE ? OR FROM_UNIXTIME(`users`.`last_login`) LIKE ? OR `users`.`email` LIKE ? OR `users`.`ip` LIKE ? OR `users_groups`.`group_name` LIKE ?)';
|
|
}
|
|
if ((string) RequestManager::get('filter') !== '') {
|
|
if (RequestManager::get('filter') == 1) {
|
|
$rWhere[] = '`users`.`status` = 1';
|
|
} else {
|
|
if (RequestManager::get('filter') == 2) {
|
|
$rWhere[] = '`users`.`status` = 0';
|
|
}
|
|
}
|
|
}
|
|
if ((string) RequestManager::get('reseller') !== '') {
|
|
$rWhere[] = '`users`.`owner_id` = ?';
|
|
$rWhereV[] = RequestManager::get('reseller');
|
|
}
|
|
if (0 < count($rWhere)) {
|
|
$rWhereString = 'WHERE ' . implode(' AND ', $rWhere);
|
|
} else {
|
|
$rWhereString = '';
|
|
}
|
|
if ($rOrder[$rOrderRow]) {
|
|
$rOrderDirection = (strtolower(RequestManager::get('order')[0]['dir']) === 'desc' ? 'desc' : 'asc');
|
|
$rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection;
|
|
}
|
|
$rCountQuery = 'SELECT COUNT(*) AS `count` FROM `users` LEFT JOIN `users_groups` ON `users_groups`.`group_id` = `users`.`member_group_id` LEFT JOIN `users` AS `r` on `r`.`id` = `users`.`owner_id` ' . $rWhereString . ';';
|
|
$db->query($rCountQuery, ...$rWhereV);
|
|
if ($db->num_rows() == 1) {
|
|
$rReturn['recordsTotal'] = $db->get_row()['count'];
|
|
} else {
|
|
$rReturn['recordsTotal'] = 0;
|
|
}
|
|
$rReturn['recordsFiltered'] = $rReturn['recordsTotal'];
|
|
if (0 < $rReturn['recordsTotal']) {
|
|
$rQuery = 'SELECT `users`.`id`, `users`.`status`, `users_groups`.`is_reseller`, `users`.`notes`, `users`.`owner_id`, `users`.`credits`, `users`.`username`, `users`.`email`, `users`.`ip`, FROM_UNIXTIME(`users`.`date_registered`) AS `date_registered`, FROM_UNIXTIME(`users`.`last_login`) AS `last_login`, `r`.`username` as `owner_username`, `users_groups`.`group_name`, `users`.`status`, (SELECT COUNT(`id`) FROM `lines` WHERE `member_id` = `users`.`id`) AS `user_count` FROM `users` LEFT JOIN `users_groups` ON `users_groups`.`group_id` = `users`.`member_group_id` LEFT JOIN `users` AS `r` on `r`.`id` = `users`.`owner_id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';';
|
|
$db->query($rQuery, ...$rWhereV);
|
|
if (0 < $db->num_rows()) {
|
|
foreach ($db->get_rows() as $rRow) {
|
|
if (!$rIsAPI) {
|
|
if ($rRow['status'] == 1) {
|
|
$rStatus = '<i class="text-success fas fa-square"></i>';
|
|
} else {
|
|
$rStatus = '<i class="text-secondary fas fa-square"></i>';
|
|
}
|
|
if (!$rRow['last_login']) {
|
|
$rRow['last_login'] = 'NEVER';
|
|
}
|
|
$rButtons = '<div class="btn-group">';
|
|
if ((string) $rRow['notes'] !== '') {
|
|
$rButtons .= '<button type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" title="' . $rRow['notes'] . '"><i class="mdi mdi-note"></i></button>';
|
|
} else {
|
|
$rButtons .= '<button disabled type="button" class="btn btn-light waves-effect waves-light btn-xs"><i class="mdi mdi-note"></i></button>';
|
|
}
|
|
if (in_array($rRow['id'], array_merge($rPermissions['direct_reports'], [$rUserInfo['id']]))) {
|
|
$rButtons .= '<button title="Adjust Credits" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="addCredits(' . $rRow['id'] . ", '" . addslashes($rRow['username']) . "', " . intval($rRow['credits']) . ');"><i class="mdi mdi-coin"></i></button>';
|
|
$rUsername = "<a href='user?id=" . intval($rRow['id']) . "'>" . $rRow['username'] . '</a>';
|
|
} else {
|
|
$rButtons .= '<button title="Adjust Credits" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="addCredits(' . $rRow['id'] . ", '" . addslashes($rRow['username']) . "', " . intval($rRow['credits']) . ', true);"><i class="mdi mdi-coin"></i></button>';
|
|
$rUsername = "<a href='user?id=" . intval($rRow['id']) . "'>" . $rRow['username'] . "<br/><small class='text-pink'>(indirect)</small></a>";
|
|
}
|
|
$rButtons .= '<a href="user?id=' . $rRow['id'] . '"><button title="Edit" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip"><i class="mdi mdi-pencil-outline"></i></button></a>';
|
|
if ($rRow['status'] == 1) {
|
|
$rButtons .= '<button title="Disable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'disable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
} else {
|
|
$rButtons .= '<button title="Enable" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'enable');\"><i class=\"mdi mdi-lock\"></i></button>";
|
|
}
|
|
if ($rPermissions['delete_users']) {
|
|
$rButtons .= '<button title="Delete" type="button" class="btn btn-light waves-effect waves-light btn-xs tooltip" onClick="api(' . $rRow['id'] . ", 'delete');\"><i class=\"mdi mdi-close\"></i></button>";
|
|
}
|
|
$rButtons .= '</div>';
|
|
if ((string) $rRow['ip'] !== '') {
|
|
$rIP = "<a onClick=\"whois('" . $rRow['ip'] . "');\" href='javascript: void(0);'>" . $rRow['ip'] . '</a>';
|
|
} else {
|
|
$rIP = '';
|
|
}
|
|
if ($rRow['is_reseller']) {
|
|
$rCredits = '<button type="button" class="btn btn-info btn-xs waves-effect waves-light">' . number_format($rRow['credits'], 0) . '</button>';
|
|
} else {
|
|
$rCredits = '<button type="button" class="btn btn-secondary btn-xs waves-effect waves-light">-</button>';
|
|
}
|
|
if (0 < $rRow['user_count']) {
|
|
$rUserCount = '<button type="button" class="btn btn-info btn-xs waves-effect waves-light">' . number_format($rRow['user_count'], 0) . '</button>';
|
|
} else {
|
|
$rUserCount = '<button type="button" class="btn btn-secondary btn-xs waves-effect waves-light">0</button>';
|
|
}
|
|
if (in_array($rRow['owner_id'], array_merge($rPermissions['direct_reports'], [$rUserInfo['id']]))) {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['owner_id']) . "'>" . $rRow['owner_username'] . '</a>';
|
|
} else {
|
|
$rOwner = "<a href='user?id=" . intval($rRow['owner_id']) . "'>" . $rRow['owner_username'] . "<br/><small class='text-pink'>(indirect)</small></a>";
|
|
}
|
|
$rReturn['data'][] = ["<a href='user?id=" . intval($rRow['id']) . "'>" . $rRow['id'] . '</a>', $rUsername, $rOwner, $rIP, $rStatus, $rCredits, $rUserCount, $rRow['last_login'], $rButtons];
|
|
} else {
|
|
$rReturn['data'][] = filterrow($rRow, RequestManager::get('show_columns'), RequestManager::get('hide_columns'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
exit();
|
|
}
|
|
} else {
|
|
echo json_encode($rReturn);
|
|
exit();
|
|
}
|
|
|
|
function filterRow($rRow, $rShow, $rHide) {
|
|
if ($rShow || $rHide) {
|
|
$rReturn = [];
|
|
foreach (array_keys($rRow) as $rKey) {
|
|
if ($rShow) {
|
|
if (in_array($rKey, $rShow)) {
|
|
$rReturn[$rKey] = $rRow[$rKey];
|
|
}
|
|
} else {
|
|
if ($rHide) {
|
|
if (!in_array($rKey, $rHide)) {
|
|
$rReturn[$rKey] = $rRow[$rKey];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $rReturn;
|
|
}
|
|
return $rRow;
|
|
}
|