diff --git a/src/Infrastructure/Bootstrap/AdminScopeBootstrap.php b/src/Infrastructure/Bootstrap/AdminScopeBootstrap.php
index 2a38246e..cbdbea65 100644
--- a/src/Infrastructure/Bootstrap/AdminScopeBootstrap.php
+++ b/src/Infrastructure/Bootstrap/AdminScopeBootstrap.php
@@ -6,6 +6,7 @@ use XcVm\Core\Auth\AuthRepository;
use XcVm\Core\Auth\SessionManager;
use XcVm\Core\Config\SettingsManager;
use XcVm\Core\Http\RequestManager;
+use XcVm\Core\Localization\Translator;
use XcVm\Core\Util\AdminHelpers;
use XcVm\Core\Util\NetworkUtils;
use XcVm\Domain\User\UserRepository;
@@ -92,7 +93,7 @@ final class AdminScopeBootstrap implements ScopeBootstrap {
*/
private function bootFunctions(): void {
global $db, $rSettings, $rMobile, $rServers, $rProxyServers, $rDetect,
- $rTimeout, $rProtocol, $allServers, $rPermissions, $language, $allowedLangs,
+ $rTimeout, $rProtocol, $allServers, $rPermissions, $allowedLangs,
$rServerError, $allServersHealthy, $updateRequired, $rUserInfo,
$_STATUS, $customScript;
@@ -124,7 +125,7 @@ final class AdminScopeBootstrap implements ScopeBootstrap {
}
if (!isset($_COOKIE['lang']) || $_COOKIE['lang'] != $rUserInfo['lang']) {
- $language::setLanguage($rUserInfo['lang']);
+ Translator::setLanguage($rUserInfo['lang']);
}
$rPermissions = AuthRepository::getPermissions($rUserInfo['member_group_id']);
diff --git a/src/Infrastructure/Bootstrap/ResellerScopeBootstrap.php b/src/Infrastructure/Bootstrap/ResellerScopeBootstrap.php
index c0aab885..faab0e82 100644
--- a/src/Infrastructure/Bootstrap/ResellerScopeBootstrap.php
+++ b/src/Infrastructure/Bootstrap/ResellerScopeBootstrap.php
@@ -5,6 +5,7 @@ namespace XcVm\Infrastructure\Bootstrap;
use XcVm\Core\Auth\AuthRepository;
use XcVm\Core\Auth\SessionManager;
use XcVm\Core\Http\RequestManager;
+use XcVm\Core\Localization\Translator;
use XcVm\Core\Util\AdminHelpers;
use XcVm\Core\Util\NetworkUtils;
use XcVm\Domain\User\UserRepository;
@@ -81,7 +82,7 @@ final class ResellerScopeBootstrap implements ScopeBootstrap {
* @return void
*/
private function bootFunctions(): void {
- global $db, $rSettings, $rMobile, $language, $rPermissions, $rUserInfo,
+ global $db, $rSettings, $rMobile, $rPermissions, $rUserInfo,
$_STATUS, $customScript;
if (!defined('MAIN_HOME')) {
@@ -104,7 +105,7 @@ final class ResellerScopeBootstrap implements ScopeBootstrap {
setcookie('hue', $rUserInfo['hue'] ?? '', time() + 604800);
setcookie('theme', $rUserInfo['theme'] ?? '', time() + 604800);
- $language::setLanguage($rUserInfo['lang']);
+ Translator::setLanguage($rUserInfo['lang']);
$rPermissions = array_merge(AuthRepository::getPermissions($rUserInfo['member_group_id']), AuthRepository::getGroupPermissions($rUserInfo['id']));
$rPermissions['direct_reports'] = $rPermissions['direct_reports'] ?? [];
diff --git a/src/Public/Controllers/Admin/Ajax/SearchAjaxController.php b/src/Public/Controllers/Admin/Ajax/SearchAjaxController.php
index f326032f..959e68be 100644
--- a/src/Public/Controllers/Admin/Ajax/SearchAjaxController.php
+++ b/src/Public/Controllers/Admin/Ajax/SearchAjaxController.php
@@ -5,6 +5,7 @@ namespace XcVm\Public\Controllers\Admin\Ajax;
use XcVm\Core\Auth\Authorization;
use XcVm\Core\Config\SettingsManager;
use XcVm\Core\Http\RequestManager;
+use XcVm\Core\Localization\Translator;
use XcVm\Core\Reference\StatusBadge;
use XcVm\Core\Util\AdminHelpers;
use XcVm\Core\Util\TimeUtils;
@@ -36,7 +37,7 @@ class SearchAjaxController extends BaseAjaxController {
$this->requireXhr();
/** @var class-string $language */
- global $db, $rServers, $language;
+ global $db, $rServers;
$rReturn = array('total_count' => 0, 'items' => array(), 'result' => true);
$rTables = array('lines' => array('Lines', 'line?id=', '`username`, `admin_notes`, `reseller_notes`, `last_ip`, `contact`', 'id', 'username'), 'mag_devices' => array('MAG Devices', 'mag?id=', '`mac_filter`, `ip`', 'mag_id', 'mac'), 'enigma2_devices' => array('Enigma2 Devices', 'enigma?id=', '`mac_filter`, `public_ip`', 'device_id', 'mac'), 'users' => array('Users', 'user?id=', '`username`, `email`, `ip`, `notes`, `reseller_dns`', 'id', 'username'), 'streams' => array('Streams, Movies & Episodes', 'stream_view?id=', '`stream_display_name`, `stream_source`, `notes`, `channel_id`', 'id', 'stream_display_name'), 'streams_series' => array('TV Series', 'serie?id=', '`title`, `plot`, `cast`, `director`', 'id', 'title'));
@@ -378,7 +379,6 @@ class SearchAjaxController extends BaseAjaxController {
/** streams_series row -> series payload. */
private function buildSeriesItem(array $rItem, array $rCtx): array {
- global $language;
$rSeriesItem = ($rCtx['rSeriesInfo'][$rItem['id']] ?? array()) ?: array();
$rCategoryIDs = json_decode($rItem['category_id'], true) ?: array();
$rCategory = ($rCtx['rCategories'][$rCategoryIDs[0] ?? null]['category_name'] ?? '') ?: 'No Category';
@@ -406,7 +406,7 @@ class SearchAjaxController extends BaseAjaxController {
'category' => $rCategory,
'image' => array('url' => $rItem['cover'], 'size' => 512),
'rating' => $this->ratingData($rItem['rating'] ?? 0, $rItem['year'] ?? ''),
- 'badge' => array('text' => $language::get('tv_series_btn'), 'variant' => 'danger'),
+ 'badge' => array('text' => Translator::get('tv_series_btn'), 'variant' => 'danger'),
'seasons' => intval($rSeriesItem[0] ?? 0),
'episodes' => intval($rSeriesItem[1] ?? 0),
'actions' => $rActions,
@@ -415,7 +415,6 @@ class SearchAjaxController extends BaseAjaxController {
/** users row -> registered-user payload. */
private function buildUserItem(array $rItem, array $rCtx): array {
- global $language;
$rGroup = $rCtx['rGroups'][$rItem['member_group_id']] ?? array();
$rIsReseller = (bool) ($rGroup['is_reseller'] ?? false);
$rActive = $rItem['status'] == 1;
@@ -423,7 +422,7 @@ class SearchAjaxController extends BaseAjaxController {
if (Authorization::check('adv', 'edit_reguser')) {
if ($rIsReseller) {
- $rActions[] = array('kind' => 'credits', 'id' => intval($rItem['id']), 'icon' => 'mdi-coin', 'title' => $language::get('add_credits'));
+ $rActions[] = array('kind' => 'credits', 'id' => intval($rItem['id']), 'icon' => 'mdi-coin', 'title' => Translator::get('add_credits'));
}
$rActions[] = array('kind' => 'navigate', 'target' => 'user?id=' . $rItem['id'], 'icon' => 'mdi-pencil', 'title' => 'Edit');
@@ -441,7 +440,7 @@ class SearchAjaxController extends BaseAjaxController {
'status' => array('label' => $rActive ? 'Active' : 'Inactive', 'variant' => $rActive ? 'info' : 'warning'),
'users_count' => intval($rCtx['rUsersCount'][$rItem['id']] ?? 0),
'lines_count' => intval($rCtx['rLinesCount'][$rItem['id']] ?? 0),
- 'badge' => array('text' => $language::get('user_btn'), 'variant' => 'warning'),
+ 'badge' => array('text' => Translator::get('user_btn'), 'variant' => 'warning'),
'actions' => $rActions,
);
}
diff --git a/src/Public/Controllers/Admin/BaseAdminController.php b/src/Public/Controllers/Admin/BaseAdminController.php
index f21bfb4c..05884be1 100644
--- a/src/Public/Controllers/Admin/BaseAdminController.php
+++ b/src/Public/Controllers/Admin/BaseAdminController.php
@@ -5,6 +5,7 @@ namespace XcVm\Public\Controllers\Admin;
use XcVm\Core\Auth\Authorization;
use XcVm\Core\Auth\PageAuthorization;
use XcVm\Core\Http\RequestManager;
+use XcVm\Core\Localization\Translator;
use XcVm\Core\Util\AdminHelpers;
/**
@@ -88,7 +89,6 @@ class BaseAdminController {
// вьюхи теперь получают напрямую через XcVm\Core\Reference\* и enum'ы.
$viewGlobals = [
// Core rendering
- 'language',
'db',
'rSettings',
'rMobile',
@@ -123,6 +123,10 @@ class BaseAdminController {
}
unset($_g);
+ // Translator FQCN for legacy views' `$language::get(...)` calls
+ // (replaces the former bootstrap-set global $language).
+ $data['language'] ??= Translator::class;
+
extract($data, EXTR_SKIP);
$__viewsDir = MAIN_HOME . 'Public/Views/' . $this->scope . '/';
diff --git a/src/Public/Controllers/Admin/TableController.php b/src/Public/Controllers/Admin/TableController.php
index 4ce1d450..9419fbc6 100644
--- a/src/Public/Controllers/Admin/TableController.php
+++ b/src/Public/Controllers/Admin/TableController.php
@@ -8,6 +8,7 @@ use XcVm\Core\Backup\BackupService;
use XcVm\Core\Config\SettingsManager;
use XcVm\Core\Enum\ClientFilter;
use XcVm\Core\Http\RequestManager;
+use XcVm\Core\Localization\Translator;
use XcVm\Core\Reference\StatusBadge;
use XcVm\Core\Util\TimeUtils;
use XcVm\Domain\Device\EnigmaService;
@@ -1064,7 +1065,7 @@ class TableController extends BaseAdminController {
}
private function handleStreams($rReturn, $rStart, $rLimit, $rIsAPI) {
- global $db, $rSettings, $rServers, $language;
+ global $db, $rSettings, $rServers;
if (!Authorization::check("adv", "streams") && !Authorization::check("adv", "mass_edit_streams")) {
exit;
}
@@ -1412,7 +1413,7 @@ class TableController extends BaseAdminController {
}
$rUptime = "";
} elseif ($rActualStatus == 3) {
- $rUptime = "";
+ $rUptime = "";
} elseif ($rActualStatus == 6) {
$rSources = json_decode($rRow["stream_source"], true);
$rLeft = count(array_diff($rSources, json_decode($rRow["cchannel_rsources"], true)));
@@ -1655,7 +1656,7 @@ class TableController extends BaseAdminController {
}
private function handleRadios($rReturn, $rStart, $rLimit, $rIsAPI) {
- global $db, $rSettings, $rServers, $language;
+ global $db, $rSettings, $rServers;
if (!Authorization::check("adv", "radio") && !Authorization::check("adv", "mass_edit_radio")) {
exit;
}
@@ -1863,7 +1864,7 @@ class TableController extends BaseAdminController {
}
$rUptime = "";
} elseif ($rActualStatus == 3) {
- $rUptime = "";
+ $rUptime = "";
} else {
$rUptime = StatusBadge::stream($rActualStatus);
}
@@ -2662,7 +2663,7 @@ class TableController extends BaseAdminController {
}
private function handleLiveConnections($rReturn, $rStart, $rLimit, $rIsAPI) {
- global $db, $language, $rProxyServers;
+ global $db, $rProxyServers;
if (!Authorization::check("adv", "live_connections")) {
exit;
}
@@ -2946,7 +2947,7 @@ class TableController extends BaseAdminController {
$rDuration = (int) time() - (int) $rRow["date_start"];
$rColour = "success";
if (!empty($rRow["hls_end"])) {
- $rDuration = "";
+ $rDuration = "";
} else {
if (86400 <= $rDuration) {
$rDuration = sprintf("%02dd %02dh", $rDuration / 86400, $rDuration / 3600 % 24);
@@ -4301,7 +4302,7 @@ class TableController extends BaseAdminController {
}
private function handleAsns($rReturn, $rStart, $rLimit, $rIsAPI) {
- global $db, $language;
+ global $db;
if (!Authorization::check("adv", "block_isps")) {
exit;
}
@@ -4357,9 +4358,9 @@ class TableController extends BaseAdminController {
}
$rButtons .= "";
if ($rRow["blocked"]) {
- $rStatus = "";
+ $rStatus = "";
} else {
- $rStatus = "";
+ $rStatus = "";
}
$rType = strtoupper($rRow["type"]);
$rReturn["data"][] = [$rRow["asn"], $rRow["isp"], $rRow["domain"], "
", number_format($rRow["num_ips"], 0), $rType, $rStatus, $rButtons];
diff --git a/src/Public/Controllers/Reseller/ResellerLoginController.php b/src/Public/Controllers/Reseller/ResellerLoginController.php
index d48a9a4a..2565609e 100644
--- a/src/Public/Controllers/Reseller/ResellerLoginController.php
+++ b/src/Public/Controllers/Reseller/ResellerLoginController.php
@@ -4,6 +4,7 @@ namespace XcVm\Public\Controllers\Reseller;
use XcVm\Core\Config\SettingsManager;
use XcVm\Core\Http\RequestManager;
+use XcVm\Core\Localization\Translator;
use XcVm\Core\Util\NetworkUtils;
use XcVm\Domain\Security\BlocklistService;
use XcVm\Domain\User\ResellerAPI;
@@ -38,7 +39,10 @@ class ResellerLoginController {
// Flood protection
$rSettings = SettingsManager::getAll();
- global $db, $language;
+ global $db;
+
+ // Translator FQCN for reseller/login.php's `$language::get(...)` calls.
+ $language = Translator::class;
if (intval($rSettings['login_flood']) > 0) {
$db->query(
diff --git a/src/Public/Controllers/Reseller/ResellerPostController.php b/src/Public/Controllers/Reseller/ResellerPostController.php
index c75c1f51..0559f104 100644
--- a/src/Public/Controllers/Reseller/ResellerPostController.php
+++ b/src/Public/Controllers/Reseller/ResellerPostController.php
@@ -3,6 +3,7 @@
namespace XcVm\Public\Controllers\Reseller;
use XcVm\Core\Http\RequestManager;
+use XcVm\Core\Localization\Translator;
use XcVm\Domain\User\ResellerAPI;
/**
@@ -43,7 +44,7 @@ class ResellerPostController extends BaseResellerController
}
$rUserInfo = $GLOBALS['rUserInfo'];
- $language = $GLOBALS['language'];
+ $language = Translator::class;
switch ($rAction) {
case 'edit_profile':
diff --git a/src/Public/Views/admin/functions.php b/src/Public/Views/admin/functions.php
index c87aab41..8b718315 100644
--- a/src/Public/Views/admin/functions.php
+++ b/src/Public/Views/admin/functions.php
@@ -6,6 +6,7 @@ use XcVm\Core\Config\SettingsManager;
use XcVm\Core\Http\RequestManager;
use XcVm\Core\Util\AdminHelpers;
use XcVm\Core\Util\NetworkUtils;
+use XcVm\Core\Localization\Translator;
use XcVm\Domain\User\UserRepository;
if (!defined('MAIN_HOME')) {
@@ -18,12 +19,16 @@ if (!defined('MAIN_HOME')) {
// эти переменные без `global` не видны в текущем scope.
// В глобальном scope (прямой вызов через nginx) — это no-op.
global $db, $rSettings, $rMobile, $rServers, $rProxyServers, $rDetect,
- $rTimeout, $rProtocol, $allServers, $rPermissions, $language, $allowedLangs,
+ $rTimeout, $rProtocol, $allServers, $rPermissions, $allowedLangs,
$rServerError, $allServersHealthy, $updateRequired, $rUserInfo;
require_once MAIN_HOME . 'bootstrap.php';
XC_Bootstrap::boot(XC_Bootstrap::CONTEXT_ADMIN);
+// Translator FQCN for this page's views' `$language::get(...)` /
+// `$language::setLanguage(...)` calls (replaces the former global $language).
+$language = Translator::class;
+
if ($rMobile) {
$rSettings['js_navigate'] = 0;
}
diff --git a/src/Public/Views/layouts/admin.php b/src/Public/Views/layouts/admin.php
index 9ffdde54..16755ab1 100644
--- a/src/Public/Views/layouts/admin.php
+++ b/src/Public/Views/layouts/admin.php
@@ -27,7 +27,7 @@ if (!function_exists('renderUnifiedLayoutHeader')) {
// Since we require it from inside a function, pull them from $GLOBALS.
foreach ([
'rUserInfo', 'rSettings', 'rThemes', 'rMobile', 'rHues',
- 'db', 'language', 'allServersHealthy', 'rServerError',
+ 'db', 'allServersHealthy', 'rServerError',
'rServers', 'allServers', 'rUpdate', '_TITLE', 'rModal',
'rProxyServers', 'rPermissions', '_PAGE', '_SETUP',
] as $_g) {
@@ -37,6 +37,9 @@ if (!function_exists('renderUnifiedLayoutHeader')) {
}
unset($_g);
+ // Translator FQCN for the legacy header's $language::get(...) calls.
+ $language = \XcVm\Core\Localization\Translator::class;
+
$rootPath = dirname(__DIR__, 3);
if ($scope === 'player') {
diff --git a/src/Public/Views/layouts/footer.php b/src/Public/Views/layouts/footer.php
index 7c731837..7c62c761 100644
--- a/src/Public/Views/layouts/footer.php
+++ b/src/Public/Views/layouts/footer.php
@@ -31,7 +31,7 @@ if (!function_exists('renderUnifiedLayoutFooter')) {
// Legacy footer.php expects these variables in file scope.
foreach ([
'rUserInfo', 'rSettings', 'rThemes', 'rMobile', 'rHues',
- 'db', 'language', 'rServers', 'allServers', 'rUpdate',
+ 'db', 'rServers', 'allServers', 'rUpdate',
'_TITLE', 'rModal', 'rProxyServers', 'rPermissions',
'rServerError', 'allServersHealthy', '_PAGE', '_SETUP',
'rStreamIDs', 'rFilterBy', 'rSortArray', 'rFilterArray',
@@ -45,6 +45,9 @@ if (!function_exists('renderUnifiedLayoutFooter')) {
}
unset($_g);
+ // Translator FQCN for the legacy footer's $language::get(...) calls.
+ $language = \XcVm\Core\Localization\Translator::class;
+
$rootPath = dirname(__DIR__, 3);
if ($scope === 'player') {
diff --git a/src/bootstrap.php b/src/bootstrap.php
index 59ec6196..2acf063e 100644
--- a/src/bootstrap.php
+++ b/src/bootstrap.php
@@ -526,8 +526,7 @@ class XC_Bootstrap {
* Initialize Translator (i18n).
*/
private static function initTranslator(): void {
- $language = Translator::class;
- $language::init(MAIN_HOME . 'resources/langs/');
+ Translator::init(MAIN_HOME . 'resources/langs/');
}
/**
@@ -665,7 +664,7 @@ class XC_Bootstrap {
private static function initAdminGlobals(): void {
global $rDetect, $rMobile, $rTimeout, $rSQLTimeout, $rProtocol,
$allServers, $rServers, $rSettings, $rProxyServers,
- $rPermissions, $language, $allowedLangs;
+ $rPermissions, $allowedLangs;
if (!defined('SERVER_ID')) {
define('SERVER_ID', intval(ConfigReader::get('server_id')));
@@ -690,8 +689,7 @@ class XC_Bootstrap {
}
$rProxyServers = ServerRepository::getProxySimple($rPermissions);
- $language = Translator::class;
- $allowedLangs = $language::available();
+ $allowedLangs = Translator::available();
// Sort servers by order
if (is_array($rServers)) {