- getE2Info: collapse the obfuscated `if (cond) {} else { body }` chain into
straight positive-form ifs; drop the redundant re-init of pair_line_info.
- getUserInfo: same de-obfuscation of the ISP block, and fix the same
"Undefined array key isp_asn" bug already fixed in getStreamingUserInfo — the
ISP-persist step ran even on a GeoIP miss (con_isp_name null), reading the
undefined isp_asn key and writing a null isp_desc/as_number to the line.
- Extract the persist predicate both methods shared into a pure, tested
UserRepository::ispChanged() helper (+ tests/Unit/UserRepositoryTest.php).
Verified: php -l, phpunit (423 tests, 944 assertions), make gates.
getStreamingUserInfo() sets isp_asn / con_isp_name only when
GeoIPService::getISP() actually returns an ISP. The follow-up block that
persists a changed ISP still ran when none was detected (con_isp_name stays
null): it read the undefined isp_asn key — the "Undefined array key isp_asn"
warning from UserRepository.php:348 — and wrote a null isp_desc/as_number to the
line. Gate it on a non-empty con_isp_name, matching the isp_violate check above.
Replace the fragile per-class setDb()/db() pattern (which threw when a
bootstrap path forgot to wire $db) with a shared trait that lazily resolves
from DatabaseFactory. Fixes the streaming UserRepository fatal and the same
latent issue in module crons. 42 classes converted.
LoadBalancer nginx had no ^/admin/ location, so when a server higher in
the tree pulled a stream whose source is an LB, the LB returned 404 for
/admin/{live,timeshift,thumb,vod} before the request ever reached PHP.
The MAIN→LB direction worked (MAIN has the route); LB→MAIN was silently
broken — stream shown down, nothing in the panel logs.
Add a reduced admin location exposing ONLY the loopback handlers
(live|timeshift|thumb|vod) — not index|api|proxy_api — so the admin
panel itself is never served from a LoadBalancer. Mirrors the MAIN
admin gateway block.
Also fix a PSR-4 rename miss: the directory rename public/ → Public/
(1a296d09) updated src/bin/nginx/conf/nginx.conf but left
lb_configs/nginx.conf pointing at /home/xc_vm/public/ everywhere
(root, stream, progress, api). On a case-sensitive fresh LB install the
on-disk path is Public/, so every SCRIPT_FILENAME 404'd — all LB
streaming broke, not just loopback. Repoint the 8 filesystem paths to
Public/; SCRIPT_NAME stays /public/ (logical CGI path, matches MAIN).
Note: bin/nginx is update-excluded, so existing LBs keep their old
config and must be patched manually or reinstalled; only fresh installs
pick up the corrected lb_configs/nginx.conf.
Apply 'make cs-fix' — 493 files. Mechanical, import-block only:
- sort use statements alphabetically (class/function/const grouped);
- drop imports left unused by the PSR-4 migration (e.g. classes referenced by
leading-backslash FQCN whose redundant 'use' the automated insertion had added);
- one blank line after namespace and after the import block; collapse stray
blank lines around use.
No logic changes. Verified: php -l clean; PHPStan no errors; PHPUnit 295/295; and a
temporary PHPStan pass over src/Public/Controllers confirms no still-referenced
import was removed (0 unresolved classes). 'use' after inline HTML in view
templates is valid and aliases correctly (verified) — those imports are sorted too.
Move Core/Database into XcVm\Core\Database (DatabaseHandler, Database,
MigrationRunner, QueryHelper). First of the Core hub sub-layers.
- Namespace the 4 classes; DatabaseHandler extends Database (same namespace);
built-ins/ioncube qualified (\PDO, \PDOException, \Exception, \Throwable,
\XC_VM); Database keeps its 'use XcVm\Core\Logging\FileLogger;'.
- Add 'use XcVm\Core\Database\...;' to referencing files (DatabaseHandler 51,
Database 64, QueryHelper 29, MigrationRunner 3) + 2 test files (PHPStan does not
analyse tests/, so PHPUnit is the gate there).
- Rewrite pre-existing leading-backslash global refs (\DatabaseHandler etc., e.g.
in @param docblocks of ResellerApiDispatcher/ResellerTableRenderer) to the full
FQCN \XcVm\Core\Database\... — a 'use' import does not cover a leading-\
reference. Done with a lookbehind so FQCN continuations and use-lines are intact.
- phpstan-baseline.neon regenerated (292→292; pre-existing Database/migration_logic
findings re-anchored after class names in messages gained the namespace).
Verified: php -l clean; PHPStan no errors; PHPUnit 295/295.