Commit Graph

486 Commits

Author SHA1 Message Date
Divarion-D
ff58f4c12b fix(cli): improve MonitorCommand failure handling and process kill
- Use >= instead of == for stop_failures threshold (prevents skipping
  the exact failure count if incremented past it)
- Add retry with sleep on stream start failure before goto label76
- Replace shell_exec('kill -9 `ps ...`') with safer xargs pipeline
  that handles empty PID lists gracefully (xargs -r)
2026-03-17 20:46:31 +03:00
Divarion-D
bde1ae9506 fix(admin): increase APIRequest timeout for mass stream operations
All 6 mass stream operations (start/stop/restart for live/movie)
used the default 5s timeout, causing failures on panels with many streams.
Increased to 120s to allow bulk operations to complete.
2026-03-17 20:46:31 +03:00
Divarion-D
d5cc661de2 fix(player): support XC_CODE in player session redirects
Player redirects to /login ignored the access code prefix,
causing 404 on multi-code installations. Now reads $_SERVER['XC_CODE']
and builds the correct redirect URL with the code prefix.
2026-03-17 20:46:30 +03:00
Divarion-D
c7947dce29 fix(player): load admin.php bootstrap in PlayerLoginController
WebPlayer login was broken — DB connection, settings, and destroySession()
were unavailable because includes/admin.php was not loaded.
Added require_once for the missing bootstrap dependency.
2026-03-17 20:46:30 +03:00
Divarion-D
0f390d8c38 docs: add module system documentation
- New: docs/en/development/modules.md — full module creation guide (EN)
- New: docs/ru/development/modules.md — full module creation guide (RU)
- Sidebars: add 'Module System' links (EN + RU)
- Build docs: replace TMDB cron rows with module system note
2026-03-16 22:34:17 +03:00
Divarion-D
858ad4508c build(makefile): update LB build for module system
- Remove TmdbCronJob/TmdbPopularCronJob from LB_FILES_TO_REMOVE
- Add comment: modules/ excluded from LB_DIRS (all modules MAIN-only)
- MIGRATION.md: update TMDB cron references to modules/tmdb/
2026-03-16 22:33:32 +03:00
Divarion-D
1fdff708a0 fix(tmdb): use include_once/require_once to prevent redeclarations
- tmdb.php: replace include → include_once for all TMDb sub-files
- TmdbCron: replace require → require_once for tmdb.php and tmdb_release.php
- Prevents 'Cannot redeclare' errors when multiple entry points load TMDB
2026-03-16 22:33:32 +03:00
Divarion-D
8746b6a44d fix(startup): clear and warm autoloader cache on startup
- Call XC_Autoloader::clearCache() + warmCache() at the start of execute()
- Ensures fresh class map after updates before cron installation
2026-03-16 22:33:32 +03:00
Divarion-D
09a6662a83 fix(logging): add caller file tracking to FileLogger, improve ErrorsCronJob
- FileLogger::log(): capture caller file via debug_backtrace()
- FileLogger: add 'file' field to log entries
- Database: pass exception line number to FileLogger::log()
- ErrorsCronJob: support both legacy (log_message/log_extra) and current
  (message/extra) log formats for backward compatibility
- ErrorsCronJob: extract log fields into typed local variables
2026-03-16 22:33:32 +03:00
Divarion-D
85d8c8b932 refactor(console): replace manual registration with auto-discovery
- console.php: scan cli/Commands/ and cli/CronJobs/ via glob + reflection
- console.php: load module commands via ModuleLoader::registerAllCommands()
- Remove ~150 lines of manual require_once + register calls
- CommandRegistry: update docblock to reflect auto-discovery approach
- New commands are discovered automatically by implementing CommandInterface
2026-03-16 22:33:32 +03:00
Divarion-D
7b0977c993 refactor(cli): move module commands from cli/ to modules/
- Move PlexCronJob, PlexItemCommand → modules/plex/
- Move TmdbCronJob, TmdbPopularCronJob → modules/tmdb/
- Move WatchCronJob, WatchItemCommand → modules/watch/
- Delete originals from cli/Commands/ and cli/CronJobs/
- Module commands now registered via ModuleInterface::registerCommands()
- TmdbCronJob: use require_once __DIR__ for module-local includes
2026-03-16 22:33:32 +03:00
Divarion-D
bc94afb4e8 refactor(modules): update all modules to ModuleInterface v2
- Replace registerCrons() → registerCommands(CommandRegistry) in all modules
- Add empty install()/uninstall() methods to all modules
- Simplify module.json: remove 'dependencies' field (metadata only)
- Plex: register PlexCronJob + PlexItemCommand via registerCommands()
- Tmdb: register TmdbCronJob + TmdbPopularCronJob via registerCommands()
- Watch: register WatchCronJob + WatchItemCommand via registerCommands()
- Fingerprint, Magscan, Ministra, TheftDetection: empty registerCommands()
2026-03-16 22:33:31 +03:00
Divarion-D
62042d907f refactor(core): ModuleInterface v2 — registerCommands(), install/uninstall, auto-discovery
- ModuleInterface: replace registerCrons() with registerCommands(CommandRegistry)
- ModuleInterface: add install() and uninstall() lifecycle methods
- ModuleLoader: auto-discover modules from modules/*/module.json
- ModuleLoader: config/modules.php now holds only overrides (enabled => false)
- ModuleLoader: remove constructor dependency on ServiceContainer/Router
- ModuleLoader: add bootAll() for web context, registerAllCommands() for CLI
- ModuleLoader: resolve class name by convention (kebab-case → PascalCase + Module)
- Remove checkDependencies() — modules must not depend on each other
2026-03-16 22:33:31 +03:00
Divarion-D
b3324f01e8 chore: update actions/checkout to v6 in build and pre-release workflows 2026-03-15 19:32:14 +03:00
Divarion-D
382d1d6db4 chore: remove duplicate files entry in release asset upload step 2026-03-15 19:25:52 +03:00
Divarion-D
b636f8320c chore: enhance workflows to support manual dispatch and dynamic tag resolution 2026-03-15 19:21:21 +03:00
Divarion-D
6eb190fa84 chore: update pre-release workflow to build assets and remove manual inputs 2.0.0 2026-03-15 18:49:20 +03:00
Divarion-D
1d65621a64 ci: automate release asset builds via GitHub Actions 2026-03-15 18:45:19 +03:00
Divarion-D
c58696944d chore: add Docker test container for release verification
- Dockerfile: Ubuntu 22.04 + systemd for testing installer end-to-end
- docker-compose.yml: build config for image
- test_release.sh: orchestration script (build/run/install/clean/logs)
- auto_install.sh: feeds answers to interactive installer prompts
- README.md: usage documentation

Container runs privileged with --cgroupns=host for systemd support.
Mounts dist/XC_VM.zip read-only, runs full install + post-verification.
2026-03-15 16:07:55 +03:00
Divarion-D
7d84eff494 chore: disable DEVELOPMENT mode for release 2026-03-15 16:07:55 +03:00
Divarion-D
65ca557f3d fix: guard setcookie() and header() with headers_sent() check
functions.php and session.php are included from post.php inside footer,
after HTML output has started. setcookie() and header() calls without
headers_sent() guard produced 'Cannot modify header information' warnings.
2026-03-15 16:07:55 +03:00
Divarion-D
e43d720fa4 fix: propagate _SETUP variable through unified layout system
- Add _SETUP to globals import list in renderUnifiedLayoutHeader/Footer
- Pass _SETUP via $vars in setup.php render calls
- Set $GLOBALS['_SETUP'] explicitly in setup.php
- Make header.php theme check null-safe (defensive against missing
  $rUserInfo/$rThemes on setup page)
2026-03-15 16:07:55 +03:00
Divarion-D
8abcda5091 fix: CacheReader returns null for missing cache files
On fresh install cache files (blocked_ua, blocked_isp, blocked_ips,
blocked_servers, allowed_ips, proxy_servers) do not exist yet.
Added is_file() guard before file_get_contents() to prevent warnings.
2026-03-15 16:07:54 +03:00
Divarion-D
05539123c8 fix: use __DIR__ instead of dirname($argv[0]) in CLI entry points
status, tools, crons/epg.php used dirname($argv[0]) which resolves
relative to CWD. When called from a different directory (e.g. by the
installer), './console.php' was not found. __DIR__ is always absolute.
2026-03-15 16:07:54 +03:00
Divarion-D
688b2b5347 fix: fix the PHP version in the README to 8.1.33 2026-03-15 14:59:12 +03:00
Divarion-D
bf8ee88f6e fix: update file permissions in Makefile for improved security and organization 2026-03-15 14:35:01 +03:00
Divarion-D
2bb146a800 fix: update PHP version in README to 8.1.333 2026-03-15 13:55:13 +03:00
Divarion-D
d8717d2499 ci: extract PHP syntax check into reusable script
- Add tools/php_syntax_check.sh (supports full scan + single-file mode)
- CI workflow now calls the shared script
- All 6 agents updated to reference the script
- CONTRIBUTING.md: add Pre-Commit Checks section
- Exclude src/bin/* (third-party stubs) from lint
2026-03-15 13:49:18 +03:00
Divarion-D
599da65efe fix: resolve PHP syntax errors in EnigmaService, MagService and review.php
- EnigmaService.php: add 5 missing closing braces in massEdit foreach
- MagService.php: same fix — 5 missing closing braces in massEdit foreach
- review.php: replace short open tag <? with <?php (short_open_tag=Off)
2026-03-15 13:47:39 +03:00
Divarion-D
d045506bac security: harden binary endpoints against MIME sniffing XSS
- Add X-Content-Type-Options: nosniff to all binary output endpoints
- Add Content-Type: application/octet-stream to key.php
- Add Content-Length header to PlayerProxyController
- Fix missing intval() on $_GET[w]/h in player_resize_body.php
- Fix missing null coalescing on $_GET[url] in admin/resize.php
- Addresses semgrep echoed-request findings (false positives for binary data)
2026-03-15 13:19:05 +03:00
Divarion-D
dfe916abcf ci: upgrade actions to Node.js 24-compatible versions
- actions/checkout@v4 -> @v5 (Node 24 since v5.0.0)
- github/codeql-action/upload-sarif@v3 -> @v4
- softprops/action-gh-release@v1 -> @v2
- shivammathur/setup-php@v2 stays (no v3 released yet)
2026-03-15 12:41:13 +03:00
Divarion-D
9bc5cfa2f3 fix: correct interface declaration in m3u_v2.php (implements -> extends) 2026-03-15 12:36:31 +03:00
Divarion-D
e0a42634b1 ci: add security scan workflow with PHP syntax check and Semgrep
New GitHub Actions workflow that runs on push/PR to main and weekly:

1. PHP Syntax Check: validates all src/*.php files with php -l
2. Semgrep Security Scan: runs php, security-audit, command-injection,
   sql-injection, and xss rule packs against src/

SARIF results are uploaded to GitHub Code Scanning.
2026-03-15 12:28:34 +03:00
Divarion-D
2bf20fb09c build: improve delete_files_list and add LB-scoped variant
delete_files_list:
- Add LAST_TAG empty guard to prevent git diff against empty ref
- Use --diff-filter=DR to catch both deletions and renames
- Add sort -u to deduplicate entries

New target lb_delete_files_list:
- Filters deleted files to only those relevant to LB builds
- Uses awk to match against LB_DIRS and LB_ROOT_FILES
- lb_update now uses lb_delete_files_list instead of delete_files_list
2026-03-15 12:28:06 +03:00
Divarion-D
1b118d0bbe fix: guard igbinary_unserialize against Redis false returns
Redis::get() returns false when a key does not exist.
igbinary_unserialize(false) produces a PHP warning and returns false,
which can cause unexpected behavior or fatal errors on the streaming
hot path.

All 5 call sites now check for false before deserializing:
- ConnectionTracker::getConnection()
- ConnectionTracker::closeConnection() (internal lookup)
- ConnectionLimiter::closeConnection()
- reseller_api_actions.php (line_activity kill)
- UsersCronJob (mGet bulk deserialize via array_map)
2026-03-15 12:27:28 +03:00
Divarion-D
eef98fb361 docs: add autoloader documentation in English and Russian
Covers: how the autoloader works, adding new classes, cache
invalidation, manual registration (addClass), adding new directories,
naming rules, duplicate resolution, and debugging.

Sidebar links added to both language versions of the Docsify site.
2026-03-15 12:26:50 +03:00
Divarion-D
dc4c5cdbac refactor: rename duplicate controllers to resolve autoloader conflicts
The tokenizer-based autoloader requires unique class names across the
entire project. These controllers had naming conflicts with module
classes (e.g. PlexController in both Admin and modules/plex/).

Renames:
- Admin/PlexController -> AdminPlexController
- Admin/WatchController -> AdminWatchController
- Admin/LogoutController -> AdminLogoutController
- Player/LogoutController -> PlayerLogoutController

Routes updated accordingly in admin.php and player.php.
2026-03-15 12:26:24 +03:00
Divarion-D
8ac5f4e949 refactor: rewrite autoloader with tokenizer-based discovery and igbinary cache
Replace the 220-line manual buildClassMap() with automatic class
discovery using token_get_all(). The autoloader now:

- Scans registered directories recursively via warmCache()
- Extracts class/interface/trait/enum declarations from PHP files
- Persists the class map to disk using igbinary serialization
- Loads cached map on subsequent requests for O(1) resolution
- Uses negative cache ($notFound) for instant rejection of missing classes
- Falls back to warmCache() rebuild instead of per-request recursive scan
- Removes findRecursive() — no recursive traversal during autoload
- Adds infrastructure/ to registered directories
- Enables file cache by default at bootstrap

All comments and PHPDoc rewritten in English with production-quality
@param/@return documentation.
2026-03-15 12:24:40 +03:00
Divarion-D
32b1080285 fix: use require_once for tmdb.php to prevent duplicate class declarations
tmdb.php defines the TMDB class. Multiple code paths can include it
(cron jobs, episode import, watch folder). Using require instead of
require_once causes "Cannot declare class TMDB" fatal errors when
the file is loaded more than once in the same process.
2026-03-15 12:23:51 +03:00
Divarion-D
cc3596c824 fix: suppress exec/shell_exec warnings and guard null references
DaemonTrait: added @ to shell_exec calls that may fail on restricted
systems (e.g. when /proc is unavailable).

ProcessManager::isNginxRunning(): suppressed exec warning when pgrep
is not available.

Database::query(): guarded explode on debugString output to prevent
undefined offset when Sent SQL section is missing.

UpdateCronJob: added null check for $gitRelease to prevent fatal error
when GitHubReleases service fails to initialize.
2026-03-15 12:23:08 +03:00
Divarion-D
f5ea95aa6e fix: correct HTTP_X_REQUESTED_WITH check and $rStream init in admin stream
stream.php view: replaced || with && in the AJAX detection condition
to prevent accessing an undefined index when the header is absent.

StreamController: moved $rStream = null above the conditional block
so the variable is always defined before the template reads it.
2026-03-15 12:22:33 +03:00
Divarion-D
9c5beba10f fix: move register_shutdown_function after init.php require in streaming endpoints
ShutdownHandler::handle() depends on classes and globals initialized in
init.php. Registering it before require_once "init.php" caused a fatal
error (class not found) when the shutdown handler fired.

Affected endpoints: live.php, vod.php, timeshift.php
2026-03-15 12:21:55 +03:00
Divarion-D
00cf0209e6 fix: Update documentation links to point to the correct repository 2026-03-15 00:19:34 +03:00
Divarion-D
756c20c8e6 feat: Remove the temporary script tmp_resolve.sh 2026-03-15 00:14:49 +03:00
Divarion-D
cfa72a8b13 Merge branch 'main' of https://github.com/Vateron-Media/XC_VM
# Conflicts:
#	src/crons/epg.php
2026-03-15 00:13:00 +03:00
Divarion-D
2a803f8a8f docs: Full Docsify documentation (EN + RU) and migration replacement
Full bilingual documentation for XC_VM has been added
with Docsify SPA and the outdated database migration has been replaced.

## Docsify

- docs/index.html — SPA entry point: en-us/ru-ru routing,
search, syntax highlighting (bash, PHP, SQL, nginx, JSON)

## EN Documentation

- docs/en/info/faq.md — FAQ (12 questions: streams, access, database, SSL, updates, permissions)
- docs/en/info/migration_guide.md — migration guide from other systems
- docs/en/info/update.md — step-by-step update via the web panel
- docs/en/info/watch_folder.md — Watch Folder: workflow, PTN/guessit parsers, configuration
- docs/en/updates_checklist.md — release preparation checklist

## RU Documentation (fully localized)

- docs/ru/README.md — Main Page
- docs/ru/_sidebar.md — Sidebar Navigation
- docs/ru/administration/ssl-generation.md — Self-Signed SSL Generation
- docs/ru/administration/update-system.md — Update Mechanism (PHP → Python → Post-Update)
- docs/ru/api/playlist.md — Playlist API with Error Codes
- docs/ru/api/system_api.md — System API (13 endpoints)
- docs/ru/api/xtreamcodes_api.md — XtreamCodes API (Authorization, Live, VOD, TV Series, EPG)
- docs/ru/builds/build_binaries.md — nginx build, nginx_rtmp, PHP-FPM, network
- docs/ru/builds/build_ffmpeg.md — Building FFmpeg 8.0 with NVENC/CUDA
- docs/ru/builds/build_system.md — MAIN vs. LB build system
- docs/ru/development/cli-tools.md — CLI: 26 commands, 25 crons, 8 daemons, database migrations
- docs/ru/info/faq.md — FAQ (12 questions)
- docs/ru/info/migration_guide.md — Migration guide
- docs/ru/info/update.md — Updating via the control panel
- docs/ru/info/watch_folder.md — Watch Folder
- docs/ru/updates_checklist.md — Release checklist

## Migrations

- Removed: 001_drop_watch_folders_plex_token.sql (Deprecated)
- Added: 001_update_crontab_filenames.sql — removes the .php suffix from filenames in the crontab table (switches to console.php commands)
2026-03-15 00:02:19 +03:00
Divarion-D
774d2318f3 feat: Migrate legacy CLI scripts to console.php and extract streaming middleware
CLI consolidation:
- Delete 13 legacy CLI scripts from includes/cli/ (ondemand, proxy, queue, record, scanner, signals, startup, thumbnail, tools, update, watchdog, plex_item, watch_item)
- Convert status and tools entry points to thin proxies that delegate to console.php
- Update all shell_exec() calls across admin controllers, views, and API layer to use console.php command syntax instead of direct CLI file paths
- Update src/service to launch daemons via console.php (signals, watchdog, queue, cache_handler, startup)
- Update Python src/update script to call console.php update instead of includes/cli/update.php
- Update test_installer to use console.php startup

Streaming deduplication:
- Extract StreamAuthMiddleware — common response headers and token decryption shared by live/vod/timeshift
- Extract ShutdownHandler — unified shutdown logic replacing 3 duplicate function shutdown() blocks
- Refactor live.php, vod.php, timeshift.php to use new middleware classes
- Add streaming micro-router to www/stream/index.php as fallback entry point

Routing fixes:
- Fix admin index.php redirect to use relative path (supports access code prefixes)
- Add access code root redirect in public/index.php to prevent broken CSS/JS asset resolution
- Fix init.php for CLI compatibility: guard $_SERVER access, define PHP_ERRORS safely

Migrations:
- 001_update_crontab_filenames.sql — strip .php suffix from crontab filenames
- Fix cache.php view query to match new filename format (cache_engine instead of cache_engine.php)
2026-03-14 23:57:33 +03:00
Danil
2d7fdba7c5 Merge pull request #96 from icleitoncosta/hotfix/not-gen-epg
fix: Improve bouquet handling in force reload EPG
2026-03-12 21:44:52 +03:00
Cleiton Costa
947b8bc569 style: Removed invalid variable 2026-03-12 15:34:33 -03:00
Divarion-D
aefd1bcbb9 Phase 11: Unify API layer — route all API endpoints through Front Controller
Steps 11.1–11.6: migrated all standalone API entry points to controller classes
dispatched via the Front Controller, then deleted the legacy PHP files.

Controllers created:
- PlayerApiController (player_api.php, 12 actions + numeric aliases)
- Enigma2ApiController (enigma2.php + xplugin.php)
- PlaylistApiController (playlist.php)
- EpgApiController (epg.php)
- InternalApiController (api.php, ~40 server-to-server actions)

Nginx changes (MAIN + LB configs):
- Add location block for streaming API endpoints → FC with XC_SCOPE=api
- Add location block for internal API (/api.php) → FC with XC_API=internal
- Change 6 rewrite rules from break→last for deleted file URLs
- Remove allow/deny from /api.php location — auth handled by PHP
  (password + IP whitelist + brute-force guard)

Front Controller (public/index.php):
- Add section 3a: REST API dispatch (XC_SCOPE=includes/api/*)
- Add section 3b: Streaming API dispatch (XC_SCOPE=api, XC_API=*)
- Move autoloader require to top (section 1b) for all code paths
- Controller map: endpoint name → controller class → init → dispatch

Bootstrap changes:
- www/init.php, www/stream/init.php: replace FC_API_NAME constant with
  direct $rFilename variable (set by FC before require, checked via isset)

Bug fixes:
- PlayerApiController: fix 3 PHP 8 warnings ($rBouquets undefined,
  missing 'rating'/'subtitle' array keys in get_vod_info)
- Fix server-to-server API calls blocked by nginx deny all (api_url_ip
  uses external server IP, not 127.0.0.1)

Deleted files (8):
- www/player_api.php, www/enigma2.php, www/xplugin.php
- www/epg.php, www/playlist.php, www/api.php
- includes/api/admin/index.php, includes/api/reseller/index.php

New files:
- tools/test_player_api.sh — comprehensive Player API test suite (13 sections)
2026-03-12 21:26:20 +03:00