Commit Graph
6 Commits
Author SHA1 Message Date
Divarion_D 320edb819c refactor(bootstrap): convert procedural prelude to BC shims
Point the five procedural prelude files at the new source-of-truth classes,
keeping them on disk as thin shims because the boot paths require_once them by
name and legacy code reads their globals/constants directly.

- Paths.php / AppConfig.php / Binaries.php -> ConstantsInitializer::init()
- ErrorCodes.php -> bridges ErrorResponder::codes() into $GLOBALS['rErrorCodes']
- ErrorHandler.php -> generateError()/generate404() shims (function_exists
  guarded) delegating to ErrorResponder; production still exit()s, so the ~139
  call sites are untouched.

Register ErrorHandler.php in composer autoload.files so the functions exist even
on paths that do not require the prelude; regenerate the production-only vendor
autoload accordingly.

The path/app-config constants are no longer literal define()s PHPStan can scan,
so add the four it previously learned from them but that were missing from the
stub (GIT_REPO_FANOUT, FANOUT_{RUN_PATH,CTL_SOCK,HTTP_SOCK}).

Debug/404 output stays byte-identical to the legacy functions (golden tests);
full suite, PHPStan, phpcs and make gates all green.
2026-09-16 16:34:16 +03:00
Divarion_D 72eb0fbc58 refactor(bootstrap): replace per-scope include pairs with ScopeBootstrap classes
The front controller selected a pair of procedural files per scope
(<scope>_session.php + <scope>_functions.php) from a hardcoded map and
require'd them at global scope. Consolidate into a typed class hierarchy:

- ScopeBootstrap (interface) + ScopeBootstrapFactory::create($scope)
- Admin/Reseller/PlayerScopeBootstrap, each porting its former session +
  functions logic 1:1 into boot()/bootSession()/bootFunctions().

index.php now calls ScopeBootstrapFactory::create($scope)->boot() instead
of building file paths and require'ing. Unknown scopes still fall back to
admin.

Behaviour is unchanged: the view-facing globals ($rUserInfo, $rPermissions,
$_STATUS, $customScript, $_PAGE, server/health flags) are still injected via
explicit `global` declarations in the boot methods, so the ~140 procedural
view templates read them from scope exactly as before. player_utility_-
functions.php is unchanged and still loaded by PlayerScopeBootstrap.

Also fix the PHPStan stub: SERVER_ID is an int (getMainID(): ?int, a
server_id PK), not a string. Moving its define() into a class method meant
PHPStan no longer inferred the type from a top-level define and fell back to
the stub, which wrongly typed it `(string) mt_rand()` — surfacing 20
false argument.type errors at int-param call sites. Stub now uses mt_rand().

Removes: admin_session_fc.php, admin_functions_fc.php, reseller_session.php,
reseller_functions.php, player_session.php, player_functions.php.

make phpstan / cs / gates all green.
2026-08-27 15:57:35 +03:00
Divarion_D cb056cdcf5 fix(phpstan): wire constants-stub regen into make, refresh drifted stub
gen-constants-stub.php had no Makefile/CI target, so tools/phpstan/
constants.stub.php (a bootstrapFile in phpstan.dist.neon) silently drifted:
regenerating it added DB_ACCESS_PWD and GIT_REPO_PROXY (real runtime define()s
in src/Core/Config/AppConfig.php that PHPStan could not see). Added `make
phpstan-stub` so the stub is regenerable/discoverable, and refreshed it
(129 -> 131 constants).
2026-08-07 21:03:42 +03:00
Divarion-D 66ecbc8cbc fix(phpstan): fix real bugs (return contracts, arg/byref, stub types) 599→585
- constants stub: use mt_rand()-based exprs so PHPStan infers GENERAL types,
  not literal 0/'' — fixes false division-by-zero (PACKET_SIZE) and
  foreach-over-false (str_split with len 0). Load stub via bootstrapFiles so
  result-cache invalidates on change.
- return contracts: explicit returns where a path fell through to null and
  violated the declared type:
  - StreamRepository::getById/getWatchFolder, GroupService::getById,
    getStream() → return false (declared array|false).
  - ServerRepository::getPublicURL → return '' when server missing (array→string).
  - MagService::resetSTB → return query() result (declared bool).
  - StreamUtils::getPlaylistSegments → explicit return null.
  - NetworkUtils::stopDownload → @return null corrected to @return void.
- PlexController: getPlexToken() called with 5 args but accepts 4 — dropped
  the dead 5th argument.
- DropboxClient::getMetaFromHeaders: array_shift() on an array_filter()
  expression (not a variable, by-ref error) — assign to a var first.
- WatchdogCommand: wrap numeric-string subtractions (nginx/proc-stat values)
  in floatval()/intval().
2026-06-23 20:02:46 +03:00
Divarion-D b9e911e7e8 fix(phpstan): resolve false positives and real bugs (988 → 622)
Systemic fixes (cascade across modules):
- Type `$db` params as \DatabaseHandler in 38 files (was `object`), so
  PHPStan resolves get_row()/query() and stops inferring closed array
  shapes — clears offsetAccess.notFound clusters.
- Database/DatabaseHandler: correct get_row()/clean_row() PHPDoc to
  array<string,mixed>, and query() $buffered param to mixed (it is the
  first positional bind value via func_get_args, not a bool flag).
- constants stub generator: explicit type overrides (HOST/PAGE_NAME →
  string, PHP_ERRORS → bool) to avoid null/mixed false positives.
- phpstan.dist.neon: scanFiles autoload.php/bootstrap.php; ignore
  unactionable FPs (dynamic require paths, proprietary XC_VM ioncube
  class, MaxMind vendor lib, ext-inotify stub gap).

Real bugs fixed:
- streaming/ConnectionLimiter: appended the whole accumulated UUID array
  instead of a single uuid, breaking per-stream temp-file cleanup.
- streaming/TimeshiftClient: dead `|| $x == 3` branch (always redundant).
- streaming/AsyncFileOperations: redundant is_array after === false.
- core/Storage/DropboxClient: @param callback → callable|null.

streaming module is clean (0 errors); infrastructure 39 → 27.
2026-06-23 19:46:33 +03:00
Divarion-D 69669d8e1c feat(phpstan): add PHPStan static analysis setup and constants stub generation 2026-06-23 19:28:45 +03:00