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)) {