Files
XC_VM/build/phpstan.dist.neon
T
Divarion_D fda7f41258 refactor(ministra): move Stalker portal from module into core (src/Ministra)
Ministra stops being a module — the whole Stalker portal (portal.php,
MinistraBootstrap, PortalHandler/PortalHelpers and the STB front-end) now
lives in src/Ministra/ under the XcVm\Ministra namespace, served at
/home/xc_vm/Ministra via the nginx alias.

- src/ministra/* and Modules/ministra_85a7d/{PortalHandler,PortalHelpers}
  → src/Ministra/; MinistraModule.php + module.json removed. Ministra was
  the only committed module, so src/Modules/ keeps a .gitkeep.
- portal.php resolves PortalHandler as a sibling and derives MAIN_HOME from
  its new location (glob crutch gone).
- nginx alias + AuthRepository $rAlias switched to /home/xc_vm/Ministra
  (PascalCase); ministra entry dropped from bundled_modules.php.
- Makefile: Modules/ removed from LB_DIRS — all modules are MAIN-only, so
  the ~50 MB of portal assets no longer ship to LB nodes.
- ArchitectureTest: zero committed modules is now a valid state.
- PHPStan: analyse src/Ministra, exclude the procedural portal.php entry,
  repath the ministra baseline entries.
- Docs (architecture, ministra-browser-emulation, extraction plan) updated
  to the new layout; the "extract to a separate repo" plan is cancelled.

Verified: php -l, make gates, make phpstan (No errors), full unit suite
(432 tests). On-server smoke: handshake + get_profile work end-to-end with
a registered MAC after deploy.
2026-08-11 21:41:11 +03:00

236 lines
8.2 KiB
Plaintext

parameters:
# Start low for a legacy codebase, then raise one step at a time (0 → max).
# Every increment surfaces a new class of issues; fix or baseline, then bump.
level: 5
phpVersion: 80300
# Entry points to analyze. Add/remove dirs as the audit progresses.
paths:
- ../src/Core
- ../src/Domain
- ../src/Infrastructure
- ../src/Streaming
- ../src/Modules
- ../src/Ministra
- ../src/Cli
# The bootstrap only defines global constants; it does NOT wire a project
# autoloader. PHPStan resolves every symbol statically from `paths` +
# `scanDirectories` below (no project code is executed).
bootstrapFiles:
- ../tools/phpstan/phpstan-bootstrap.php
# Listed directly (not just require'd from the bootstrap) so PHPStan
# tracks it for result-cache invalidation when constants change.
- ../tools/phpstan/constants.stub.php
# Indexed for symbol resolution (classes/interfaces/functions defined here
# are findable) but NOT reported on directly. These cover every source dir
# outside `paths` so cross-references always resolve.
scanDirectories:
- ../src/Public
- ../src/signals
- ../src/content
- ../src/resources
- ../src/config
- ../src/migrations
# Root file holding the global XC_Bootstrap class, referenced across the
# codebase but living outside any scanned directory.
scanFiles:
- ../src/bootstrap.php
excludePaths:
analyse:
- ../src/*/tmp/*
- ../src/tmp/*
- ../src/backups/*
# Composer autoloader glue + third-party packages (committed +
# shipped). Symbols resolve via src/vendor/autoload.php, which the
# Composer-installed phpstan binary loads automatically.
- ../src/vendor/*
# View templates: included into a controller's scope, so their
# variables ($rSettings, $language, ...) are injected by the caller.
# PHPStan analyses files standalone and would flag every such var as
# undefined — not real bugs. (Still indexed via scanDirectories.)
- ../src/Modules/*/views/*
# ministra portal entry: procedural front-controller whose
# $rSettings/$db are injected by the bootstrap it includes — same
# standalone-analysis false positives as views. The PortalHandler /
# PortalHelpers classes next to it ARE analysed; only this entry is
# excluded (it was scan-only under the old src/ministra layout too).
- ../src/Ministra/portal.php
# Bundled third-party libraries (not our code): the php-tmdb client
# and the Mobile-Detect library. Like the vendored packages above,
# they are indexed for symbol resolution but not analysed.
- ../src/Infrastructure/Tmdb/lib/*
treatPhpDocTypesAsCertain: false
reportUnmatchedIgnoredErrors: false
# These constants are defined at runtime with values that vary by
# deployment; tell PHPStan to use their type, not the literal value the
# stub happens to set (otherwise comparisons read as always true/false).
dynamicConstantNames:
- ARCHIVE_PATH
- BIN_PATH
- BUFFER_SIZE
- CACHE_TMP_PATH
- CIDR_TMP_PATH
- CLIENT_BANNED
- CLIENT_DISABLED
- CLIENT_DISALLOWED
- CLIENT_EXPIRED
- CLIENT_INVALID
- CLIENT_IS_E2
- CLIENT_IS_MAG
- CLIENT_IS_STALKER
- CLOSE_EMPTY
- CONFIG_PATH
- CONS_TMP_PATH
- CONTENT_PATH
- CREATED_PATH
- CRONS_TMP_PATH
- DB_ACCESS_ENABLED
- DELAY_PATH
- DEV_MODE
- DIVERGENCE_TMP_PATH
- E2_IMAGES_PATH
- EPG_PATH
- FFMPEG
- FFMPEG_BIN_40
- FFMPEG_BIN_71
- FFMPEG_BIN_80
- FFMPEG_FONT
- FFPROBE
- FFPROBE_BIN_40
- FFPROBE_BIN_71
- FFPROBE_BIN_80
- FLOOD_TMP_PATH
- GEOISP_BIN
- GEOLITE2_BIN
- GEOLITE2C_BIN
- GIT_OWNER
- GIT_REPO_BIN
- GIT_REPO_MAIN
- GIT_REPO_UPDATE
- HOST
- IMAGES_PATH
- KEYFRAME_HEADER
- LINES_TMP_PATH
- LOGS_TMP_PATH
- MAIN_HOME
- MAX_PREBUFFER
- MAX_SEG_BYTES
- MINISTRA_TMP_PATH
- MIN_SEG_PTS
- MONITOR_CALLS
- OPENSSL_EXTRA
- PACKET_SIZE
- PAGE_NAME
- PAT_HEADER
- PAT_PERIOD
- PHP_BIN
- PHP_ERRORS
- PLAYER_BOOTSTRAP_DONE
- PLAYER_TMP_PATH
- PLAYLIST_PATH
- SEGMENT_DURATION
- SERIES_TMP_PATH
- SERVER_ID
- SIGNALS_PATH
- SIGNALS_TMP_PATH
- STATUS_CERTBOT
- STATUS_CERTBOT_INVALID
- STATUS_CERTBOT_RUNNING
- STATUS_CODE_LENGTH
- STATUS_DISABLED
- STATUS_EXISTS_CODE
- STATUS_EXISTS_DIR
- STATUS_EXISTS_HMAC
- STATUS_EXISTS_IP
- STATUS_EXISTS_MAC
- STATUS_EXISTS_NAME
- STATUS_EXISTS_SOURCE
- STATUS_EXISTS_USERNAME
- STATUS_FAILURE
- STATUS_FLUSH
- STATUS_INSUFFICIENT_CREDITS
- STATUS_INVALID_CAPTCHA
- STATUS_INVALID_CODE
- STATUS_INVALID_DATA
- STATUS_INVALID_DATE
- STATUS_INVALID_DIR
- STATUS_INVALID_EMAIL
- STATUS_INVALID_FILE
- STATUS_INVALID_GROUP
- STATUS_INVALID_INPUT
- STATUS_INVALID_IP
- STATUS_INVALID_MAC
- STATUS_INVALID_NAME
- STATUS_INVALID_PACKAGE
- STATUS_INVALID_PASSWORD
- STATUS_INVALID_PLAYLIST
- STATUS_INVALID_SUBRESELLER
- STATUS_INVALID_TYPE
- STATUS_INVALID_USER
- STATUS_INVALID_USERNAME
- STATUS_NO_DESCRIPTION
- STATUS_NO_KEY
- STATUS_NO_SOURCE
- STATUS_NO_SOURCES
- STATUS_NOT_ADMIN
- STATUS_NO_TITLE
- STATUS_NOT_RESELLER
- STATUS_NO_TRIALS
- STATUS_RESERVED_CODE
- STATUS_SPACE_ISSUE
- STATUS_SUCCESS
- STATUS_SUCCESS_MULTI
- STATUS_SUCCESS_REPLACE
- STATUS_TOO_MANY_RESULTS
- STORAGE_PATH
- STORE_PREBUFFER
- STREAMS_PATH
- STREAMS_TMP_PATH
- TIMEOUT
- TIMEOUT_READ
- TMP_PATH
- VIDEO_PATH
- VOD_PATH
- WATCH_TMP_PATH
- XC_VM_VERSION
- YOUTUBE_BIN
# Documented FALSE POSITIVES that static analysis cannot resolve — NOT a
# baseline of real bugs. Each entry is unactionable by design.
ignoreErrors:
# Dynamic require/include built from absolute runtime paths
# (MAIN_HOME = /home/xc_vm/ on a deployed server). The files exist at
# deploy time; PHPStan cannot see them on a dev/CI checkout.
- identifier: requireOnce.fileNotFound
- identifier: include.fileNotFound
- identifier: require.fileNotFound
# Proprietary ioncube-encoded class, shipped only in licensed builds.
# Every call site is guarded with class_exists('XC_VM').
- '#unknown class XC_VM\.#'
# Same class: method_exists('XC_VM', ...) probes for APIs that exist
# only in licensed builds; PHPStan treats the unknown class as absent
# and calls the guard impossible.
- '#method_exists\(\) with .XC_VM.#'
# External vendor library (maxmind-db/reader), installed at runtime and
# not part of the source tree.
- '#MaxMind\\Db\\Reader#'
# ext-inotify stub is incomplete: inotify_init() really can return false
# (PHP manual), so the defensive check below is correct, not dead code.
-
message: '#=== between resource and false will always evaluate to false#'
path: ../src/Streaming/AsyncFileOperations.php
includes:
# Pre-existing errors frozen so CI is green and only NEW code is checked.
# NOT a list of accepted bugs — most are false positives (DB-row shape
# narrowing, template vars) or cosmetic. Shrink over time and regenerate
# with `make phpstan-baseline` after fixing a batch.
- phpstan-baseline.neon