mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-04 12:02:33 +02:00
Ran `make rector-fix` (deadCode + codeQuality prepared sets) over the PSR-4 class trees (Core/Domain/Cli/Infrastructure). Net -600 lines: dead-code removal and the empty-if/else collapse (the feedback_simplify_empty_else pattern this adoption targeted). 99 files mechanically transformed. The output was reviewed against the full test suite + PHPStan + a targeted scan; this commit is the CORRECTED pass (no broken state in history): - FIX (Rector bug): its boolean inversion dropped the parens around an assignment-in-condition — `if (($rKey = array_search(...)) === false)` became `if ($rKey = array_search(...) !== false)`, assigning the bool to $rKey and unsetting the wrong array offset. Restored parens in 7 sites (BouquetService, ChannelService, CategoryService). PHPStan caught only 1 of the 7; the rest were silent. Added BouquetServiceTest as a regression (proven to fail on the broken form). - FIX (pre-existing, same class): GroupService::removeGroupFromUsers had the identical dropped-parens bug already in the tree — corrected here too. - FIX: ServersCronJob::pingServer returns floor() (float) under an `: int` return type — added an (int) cast. - ACCEPT: LocallyCalledStaticMethodToNonStaticRector converted 25 locally-called private static helpers to instance methods (behaviour-preserving; call sites rewritten). Updated MonitorCommandTest's reflection helper to invoke on a constructor-less instance. Verified: PHPStan level 5 clean (0), suite 691 tests / 0 errors. NOTE: do not re-run `make rector-fix` on this tree without first skipping the inversion rule — the dropped-parens bug is deterministic and would return.
93 lines
3.2 KiB
PHP
93 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace XcVm\Core\Config;
|
|
|
|
use XcVm\Domain\Stream\ConnectionTracker;
|
|
use XcVm\Infrastructure\Cache\CacheReader;
|
|
|
|
/**
|
|
* DomainResolver — domain resolver
|
|
*
|
|
* @package XC_VM_Core_Config
|
|
* @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
|
|
*/
|
|
|
|
class DomainResolver {
|
|
/**
|
|
* Build the public broadcast URL for a server.
|
|
*
|
|
* Resolves protocol (respecting keep_protocol / forced SSL), optionally picks
|
|
* an active proxy for the server, and selects the appropriate domain/IP and
|
|
* broadcast port; appends an originator hash for chained proxies.
|
|
*
|
|
* @param int $rServerID Server id to resolve.
|
|
* @param bool $rForceSSL Force the https protocol.
|
|
* @return string Public base URL (trailing slash), or '' if no proxy is available.
|
|
*/
|
|
public static function resolve(int $rServerID, bool $rForceSSL = false) {
|
|
global $rServers, $rSettings;
|
|
$rOriginatorID = null;
|
|
if ($rForceSSL) {
|
|
$rProtocol = 'https';
|
|
} else {
|
|
if (isset($_SERVER['SERVER_PORT']) && $rSettings['keep_protocol']) {
|
|
$rProtocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http');
|
|
} else {
|
|
$rProtocol = $rServers[$rServerID]['server_protocol'];
|
|
}
|
|
}
|
|
|
|
$rProxied = $rServers[$rServerID]['enable_proxy'];
|
|
if ($rProxied) {
|
|
$rProxyIDs = array_keys(ConnectionTracker::getProxies($rServerID, true));
|
|
if (count($rProxyIDs) == 0) {
|
|
$rProxyIDs = array_keys(ConnectionTracker::getProxies($rServerID, false));
|
|
}
|
|
if (count($rProxyIDs) != 0) {
|
|
$rOriginatorID = $rServerID;
|
|
$rServerID = $rProxyIDs[array_rand($rProxyIDs)];
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
$rHost = ($_SERVER['HTTP_HOST'] ?? '');
|
|
if (strpos($rHost, ':') !== false) {
|
|
list($rDomain, $rAccessPort) = explode(':', $rHost, 2);
|
|
} else {
|
|
$rDomain = $rHost;
|
|
}
|
|
|
|
if ($rProxied || $rSettings['use_mdomain_in_lists'] == 1) {
|
|
$rResellerDomains = CacheReader::get('reseller_domains') ?: [];
|
|
if (strlen($rDomain) <= 0 || !in_array(strtolower($rDomain), $rResellerDomains)) {
|
|
if (empty($rServers[$rServerID]['domain_name'])) {
|
|
$rDomain = escapeshellcmd($rServers[$rServerID]['server_ip']);
|
|
} elseif (filter_var($rDomain, FILTER_VALIDATE_IP)) {
|
|
$rDomain = escapeshellcmd($rServers[$rServerID]['server_ip']);
|
|
} else {
|
|
$rDomain = str_replace(['http://', '/', 'https://'], '', escapeshellcmd(explode(',', $rServers[$rServerID]['domain_name'])[0]));
|
|
}
|
|
}
|
|
} else {
|
|
if (strlen($rDomain) == 0) {
|
|
if (empty($rServers[$rServerID]['domain_name'])) {
|
|
$rDomain = escapeshellcmd($rServers[$rServerID]['server_ip']);
|
|
} else {
|
|
$rDomain = str_replace(['http://', '/', 'https://'], '', escapeshellcmd(explode(',', $rServers[$rServerID]['domain_name'])[0]));
|
|
}
|
|
}
|
|
}
|
|
|
|
$rServerURL = $rProtocol . '://' . $rDomain . ':' . $rServers[$rServerID][$rProtocol . '_broadcast_port'] . '/';
|
|
if ($rServers[$rServerID]['server_type'] == 1 && $rOriginatorID && $rServers[$rOriginatorID]['is_main'] == 0) {
|
|
$rServerURL .= md5($rServerID . '_' . $rOriginatorID . '_' . OPENSSL_EXTRA) . '/';
|
|
}
|
|
|
|
return $rServerURL;
|
|
}
|
|
}
|