diff --git a/MIGRATION.md b/MIGRATION.md index c30aedb8..02b48774 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -6,12 +6,13 @@ ## Содержание 1. [Принцип миграции](#1-принцип-миграции) -2. [Завершённые фазы (0–13)](#2-завершённые-фазы-013) +2. [Завершённые фазы (0–14, 16)](#2-завершённые-фазы-014-16) 3. [Фаза 14: CSS/JS partials](#3-фаза-14-cssjs-partials) -4. [Фаза 15: Удаление includes/admin.php](#4-фаза-15-удаление-includesadminphp) -5. [Отложенные подшаги](#5-отложенные-подшаги) -6. [Известные пробелы и TODO](#6-известные-пробелы-и-todo) -7. [Стратегия и релизы](#7-стратегия-и-релизы) +4. [Фаза 15: Ликвидация src/includes/](#4-фаза-15-ликвидация-srcincludes) +5. [Фаза 16: Удаление includes/admin.php](#5-фаза-16-удаление-includesadminphp) +6. [Отложенные подшаги](#6-отложенные-подшаги) +7. [Известные пробелы и TODO](#7-известные-пробелы-и-todo) +8. [Стратегия и релизы](#8-стратегия-и-релизы) --- @@ -30,7 +31,7 @@ --- -## 2. Завершённые фазы (0–13) +## 2. Завершённые фазы (0–14, 16) | Фаза | Суть | Ключевой результат | |------|------|--------------------| @@ -48,6 +49,8 @@ | **11** | Унификация API (11.1–11.4) | 7 API-контроллеров (2313 стр.), 6 thin proxies в www/. PlayerApi, Enigma2, XPlugin, Playlist, Epg, InternalApi | | **12** | CLI runner | console.php + 26 Commands + 25 CronJobs. includes/cli/ и crons/ удалены. LB guards | | **13** | Streaming (13.1–13.3) | ShutdownHandler, StreamAuthMiddleware, micro-router. Hot path не затронут | +| **14** | CSS/JS partials | footer.php: 810→85 строк, common.js (730 стр.), XC_VM.Config bridge | +| **16** | Удаление admin.php | 121 функция → 17 классов, admin_proxies.php, loadLegacyProxies(), unified bootstrap | **Новые классы (Phase 8):** SettingsManager, RequestManager, ConfigReader, DatabaseFactory, RedisManager, FfmpegPaths, FileCache, DataEncryptor, InputSanitizer, IpUtils, UrlBuilder, ImageUtils, Helpers, ProcessManager, ConnectionManager, BackupService, ProviderService, ProfileService, RadioService, SystemCheck, InputValidator. @@ -78,47 +81,128 @@ 3. **PHP → JS bridge:** 6 вызовов `$language::get()` + `$rSettings['js_navigate']` → `window.XC_VM.Config` 4. Глобальные переменные (`rSwitches`, `jBoxes`, etc.) → `window.*` для совместимости со страничными скриптами -#### 14.3 — Минификация (отложено) +--- -1. `make js-minify` target -2. terser для `assets/js/*.js` -3. Версионирование: `?v={hash}` +## 4. Фаза 15: Ликвидация src/includes/ — распределение по архитектуре + +> **Цель:** Полностью удалить директорию `src/includes/`, распределив содержимое по `core/`, `domain/`, `modules/`, `streaming/`, `config/`, `bin/`. Стратегия: proxy-redirect (переместить + оставить тонкий `require_once` на старом месте → потом удалить proxy). + +> **Статус:** ✅ Фаза 15 полностью завершена (15.0–15.6). Директория `src/includes/` удалена. Константа `INCLUDES_PATH` удалена. + +#### 15.0 — Удаление пустых файлов ✅ + +| Файл | Действие | +|------|----------| +| `admin_new.php` | N/A — уже не существует | +| `.do_swap.sh` | N/A — уже не существует | + +#### 15.1 — Перенос библиотек (libs/) ✅ + +| Файл | Новое расположение | Обоснование | +|------|-------------------|-------------| +| `libs/Translator.php` | `core/Localization/Translator.php` | Core i18n | +| `libs/Logger.php` | `core/Logging/Logger.php` | Уже есть `core/Logging/` | +| `libs/GithubReleases.php` | `core/Updates/GithubReleases.php` | Обновления = core | +| `libs/AsyncFileOperations.php` | `streaming/AsyncFileOperations.php` | Используется только streaming | +| `libs/Dropbox.php` | `core/Storage/DropboxClient.php` | Backup storage | +| `libs/XmlStringStreamer.php` | `core/Parsing/XmlStringStreamer.php` | XML парсинг = core utility | +| `libs/mobiledetect.php` | `core/Device/MobileDetect.php` | Device detection | +| `libs/m3u.php` | `domain/Stream/M3UEntry.php` | M3U парсинг | +| `libs/m3u_v2.php` | `domain/Stream/M3UParser.php` | M3U v2 (✅ hardcoded paths исправлены на `__DIR__`) | +| `libs/resources/*` | `domain/Stream/resources/` | Данные для M3U-парсера | + +#### 15.2 — Перенос TMDb-пакета в модуль ✅ + +| Файл | Новое расположение | +|------|-------------------| +| `libs/tmdb.php` | `modules/tmdb/lib/TmdbClient.php` | +| `libs/tmdb_release.php` | `modules/tmdb/lib/Release.php` | +| `libs/TMDb/*.php` (10 entity) | `modules/tmdb/lib/Entities/` | +| `libs/TMDb/config/` | `modules/tmdb/lib/config/` | +| `libs/TMDb/roles/` | `modules/tmdb/lib/roles/` | + +#### 15.3 — Перенос API-контроллеров и данных ✅ + +| Файл | Новое расположение | Обоснование | +|------|-------------------|-------------| +| `api/admin/table.php` | `public/Controllers/Admin/TableController.php` | Presentation layer | +| `api/reseller/table.php` | `public/Controllers/Reseller/TableController.php` | Presentation layer | +| `reseller_api.php` | `infrastructure/legacy/reseller_api.php` | Утилитарный класс `ResellerAPI` (не контроллер) | +| `data/permissions.php` | `config/permissions.php` | Конфигурация | +| `ts.php` | `streaming/TimeshiftClient.php` | Streaming domain | + +#### 15.4 — Перенос Python-утилит ✅ + +| Файл | Новое расположение | +|------|-------------------| +| `python/release.py` | `bin/python/release.py` | +| `python/PTN/` | `bin/python/PTN/` | + +#### 15.5 — admin.php → infrastructure/legacy/ ✅ + +| Файл | Новое расположение | Причина | +|------|-------------------|---------| +| `admin.php` | `infrastructure/legacy/admin.php` | Legacy bootstrap, 70+ callers | +| `admin_functions.php` | N/A — не существует | Упоминался в плане, но файл отсутствует | + +> После 15.5: на старых местах остаются proxy-файлы (32 шт.). Proxy удаляются в Фазе 16. +> Makefile обновлён: `infrastructure/legacy/admin.php` и `infrastructure/legacy/reseller_api.php` добавлены в `LB_FILES_TO_REMOVE`. + +#### 15.6 — Удаление src/includes/ ✅ + +> **Завершено:** 2025-07-06. Директория `src/includes/` полностью удалена (40 файлов: 34 proxy + 6 оригиналов). + +Выполнено: + +1. 7 мёртвых `shell_exec()` вызовов (`INCLUDES_PATH . 'cli/...'`) заменены на `MAIN_HOME . 'console.php ...'` в: + `VodCronJob`, `SeriesService`, `MovieService`, `RootSignalsCronJob`, `WatchCron`, `PlexCron` +2. `INCLUDES_PATH` define удалён из `LoopbackCommand`, `LlodCommand` +3. Autoloader: убраны `addDirectory('includes')` и `addDirectory('includes/libs')` +4. Константа `INCLUDES_PATH` удалена из `core/Config/Paths.php` +5. `rm -rf src/includes/` — удалены все 40 файлов +6. Makefile: убраны `includes/admin_api.php`, `includes/admin.php`, `includes/reseller_api.php` из `LB_FILES_TO_REMOVE` +7. `php -l` всех 10 модифицированных файлов — 0 ошибок + +> **Сохранены** маршрутные идентификаторы nginx: `includes/api/admin` и `includes/api/reseller` в `index.php` и `AuthRepository.php` — это протокольные значения, не файловые пути. --- -## 4. Фаза 15: Удаление includes/admin.php — финальный legacy bootstrap +## 5. Фаза 16: Удаление includes/admin.php — финальный legacy bootstrap ✅ -> **Цель:** `includes/admin.php` (~3060 стр.) удалён. Весь bootstrap через `XC_Bootstrap::boot()`. +> **Завершено:** 2026-04-08. `infrastructure/legacy/admin.php` удалён. Весь bootstrap через `XC_Bootstrap::boot()`. +> admin.php: 3060 → 2641 → 2135 → 1131 → 518 → 27 → **удалён**. -#### 15.1 — Аудит зависимостей +#### 16.1 — Аудит зависимостей ✅ -1. `grep -rn "include.*admin\.php\|require.*admin\.php" src/` +1. `grep -rn "include.*admin\.php\|require.*admin\.php" src/` — найдено 18 callers 2. Для каждого подключения: что ожидается (переменные, функции, сессия)? -3. Что живёт ТОЛЬКО в admin.php и не имеет замены? +3. Что живёт ТОЛЬКО в admin.php и не имеет замены? → Ничего. Все 121 функция извлечены. -#### 15.2 — Перенос оставшихся функций +#### 16.2 — Перенос оставшихся функций ✅ -- глобальные утилиты → `includes/admin_functions.php` или domain-сервисы -- `$language` → `core/I18n/Translator.php` -- session → `core/Auth/SessionManager.php` -- `$rPermissions` → `domain/Auth/AuthorizationService.php` +- 121 функция извлечена в 17 целевых классов (core/, domain/) +- Новые файлы: `core/Database/QueryHelper.php`, `core/Util/AdminHelpers.php`, `core/Auth/PageAuthorization.php`, `core/Http/ApiClient.php`, `domain/Vod/TMDbService.php`, `domain/User/TicketRepository.php` +- 11 существующих файлов расширены: ServerService, ServerRepository, BackupService, BlocklistService, DiagnosticsService, StreamService, ConnectionTracker, SettingsManager, CategoryService, ProviderService, EpgService и др. +- admin.php: 3060 → 518 строк (все функции → one-liner proxies) -#### 15.3 — Переключение bootstrap +#### 16.3 — Переключение bootstrap ✅ -1. `BaseAdminController::before()` / `BaseResellerController::before()` → только `XC_Bootstrap::boot(CONTEXT_ADMIN)` -2. Feature flag: `use_legacy_bootstrap = false` -3. Тестирование всех 134 страниц +1. Создан `infrastructure/legacy/admin_proxies.php` (121 proxy, 508 строк) +2. Добавлен `XC_Bootstrap::loadLegacyProxies()` — идемпотентный метод, вызывается в конце CONTEXT_ADMIN boot +3. Переключены все 18 callers: 3 bootstrap + 5 CronJobs/CLI + 10 FC/Controllers/Views +4. admin.php: 518 → 27 строк (backward-compat wrapper) -#### 15.4 — Удаление +#### 16.4 — Удаление ✅ -1. `rm src/includes/admin.php` -2. Удалить все `require 'admin.php'` -3. Убрать dual bootstrap ветку из `bootstrap.php` -4. `php -l` + smoke test +1. `rm src/infrastructure/legacy/admin.php` — файл удалён (0 runtime callers) +2. Все `require 'admin.php'` заменены в Phase 16.3 +3. BaseAdminController / BaseResellerController: `function_exists()` guards → прямые вызовы `PageAuthorization`, `AdminHelpers`, `Authorization` +4. Makefile: `admin.php` → `admin_proxies.php` в `LB_FILES_TO_REMOVE` +5. `php -l` — all pass --- -## 5. Отложенные подшаги +## 6. Отложенные подшаги | Шаг | Суть | Блокер | Усилия | |-----|------|--------|--------| @@ -128,7 +212,7 @@ --- -## 6. Известные пробелы и TODO +## 7. Известные пробелы и TODO > Актуализировано: 2026-04-07. @@ -170,27 +254,30 @@ | 6.6 | BalancerCommand sentinel | ✅ | — | — | | §11.5 | Admin/Reseller REST API | ⏳ | Удаление www/ proxies | 8–16 ч | | Phase 14 | CSS/JS partials (common.js) | ✅ | — | — | -| Phase 15 | Удаление admin.php | ⏳ | Финальный milestone | 16–32 ч | +| Phase 15 | Ликвидация src/includes/ | ✅ | — | — | +| Phase 16 | Удаление admin.php (legacy bootstrap) | ✅ | — | — | --- -## 7. Стратегия и релизы +## 8. Стратегия и релизы -### Dual bootstrap (текущее состояние) +### Unified bootstrap (текущее состояние) ``` -bootstrap.php includes/admin.php (legacy) - ├── autoload.php ├── ~3060 строк legacy init - ├── ServiceContainer ├── session, permissions - └── core/domain/ └── global $db, define() +bootstrap.php (единственный entry point) + ├── autoload.php + ├── ServiceContainer + ├── core/domain/ + └── loadLegacyProxies() → admin_proxies.php (121 proxy функций) ``` -`bootstrap.php` загружается первым. `includes/admin.php` — для ещё не мигрированного legacy-кода. Удаляется в Фазе 15. +`bootstrap.php` — единственный bootstrap. `infrastructure/legacy/admin.php` удалён (Phase 16.4). +`admin_proxies.php` содержит 121 deprecated proxy-функцию; постепенно заменяются прямыми вызовами классов. +`includes/admin.php` — минимальный proxy (5 строк), перенаправляет на `bootstrap.php` + `boot(CONTEXT_ADMIN)`. ### Feature flags - `use_legacy_fallback` — FC legacy routing (реализован в `public/index.php`) -- `use_legacy_bootstrap` — для Фазы 15 (планируется) ### Rollback plan @@ -206,15 +293,18 @@ bootstrap.php includes/admin.php (legacy) Phase 14 ─── CSS/JS partials (footer.php) ✅ Завершено │ ▼ -Phase 11 ─── API deletion (11.5 + 11.6) 🟡 Средний риск +Phase 16 ─── Удаление legacy admin.php ✅ Завершено │ ▼ -Phase 15 ─── Удаление includes/admin.php 🔴 Высокий риск +Phase 15 ─── Ликвидация src/includes/ ✅ Завершено + │ + ▼ +Phase 11 ─── API deletion (11.5 + 11.6) 🟡 Средний риск ``` ### Релизы | Релиз | Содержит | Риск | |-------|----------|------| -| **v2.4** | ~~Phase 14 (CSS/JS)~~ ✅ + Phase 11 (API deletion) + пробелы 6.3 | 🟡 | -| **v3.0** | Phase 15 (удаление legacy bootstrap) | 🔴 Финальный | +| **v2.4** | ~~Phase 14 (CSS/JS)~~ ✅ + ~~Phase 16 (admin.php)~~ ✅ + ~~Phase 15 (ликвидация includes/)~~ ✅ | ✅ | +| **v2.5** | Phase 11 (API deletion) + пробелы 6.3 | 🟡 | diff --git a/Makefile b/Makefile index 0581362a..1d3826ae 100644 --- a/Makefile +++ b/Makefile @@ -47,9 +47,7 @@ LB_DIRS_TO_REMOVE := \ # Files to remove from LB LB_FILES_TO_REMOVE := \ bin/maxmind/GeoLite2-City.mmdb \ - includes/admin_api.php \ - includes/admin.php \ - includes/reseller_api.php \ + infrastructure/legacy/reseller_api.php \ www/xplugin.php \ www/probe.php \ www/playlist.php \ diff --git a/docs/en/_sidebar.md b/docs/en/_sidebar.md index 99217fac..55bfd1cd 100644 --- a/docs/en/_sidebar.md +++ b/docs/en/_sidebar.md @@ -22,6 +22,7 @@ - [⚙️ Autoloader & Class Registration](en-us/development/autoloader.md) - [🧩 Module System](en-us/development/modules.md) - [📂 Development Workflow (SFTP)](en-us/development/dev-workflow.md) + - [🌐 Adding a Custom Language](en-us/development/translations.md) - 📦 **Additional** - [🎬 Watchfolder](en-us/info/watch_folder.md) diff --git a/docs/ru/_sidebar.md b/docs/ru/_sidebar.md index 98baac38..32e3c63b 100644 --- a/docs/ru/_sidebar.md +++ b/docs/ru/_sidebar.md @@ -22,6 +22,7 @@ - [⚙️ Автозагрузчик и регистрация классов](ru-ru/development/autoloader.md) - [🧩 Система модулей](ru-ru/development/modules.md) - [📂 Рабочий процесс (SFTP)](ru-ru/development/dev-workflow.md) + - [🌐 Добавление своего языка](ru-ru/development/translations.md) - 📦 **Дополнительно** - [🎬 Watchfolder](ru-ru/info/watch_folder.md) diff --git a/src/autoload.php b/src/autoload.php index 56a6557b..f68d32eb 100644 --- a/src/autoload.php +++ b/src/autoload.php @@ -450,10 +450,6 @@ class XC_Autoloader { private static function registerDirectories() { $base = self::$basePath; - // Legacy directories - self::addDirectory($base . 'includes'); - self::addDirectory($base . 'includes/libs'); - // New architecture directories self::addDirectory($base . 'core'); self::addDirectory($base . 'domain'); diff --git a/src/bootstrap.php b/src/bootstrap.php index 4a8842cb..d2b1f94e 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -437,7 +437,7 @@ class XC_Bootstrap { global $db; - require_once INCLUDES_PATH . 'reseller_api.php'; + require_once MAIN_HOME . 'infrastructure/legacy/reseller_api.php'; // Admin user info if (isset($_SESSION['hash'])) { @@ -453,7 +453,7 @@ class XC_Bootstrap { * Initialize Translator (i18n). */ private static function initTranslator(): void { - require_once INCLUDES_PATH . 'libs/Translator.php'; + require_once MAIN_HOME . 'core/Localization/Translator.php'; $language = Translator::class; $language::init(MAIN_HOME . 'resources/langs/'); @@ -578,7 +578,7 @@ class XC_Bootstrap { define('SERVER_ID', intval(ConfigReader::get('server_id'))); } - require_once INCLUDES_PATH . 'libs/mobiledetect.php'; + require_once MAIN_HOME . 'core/Device/MobileDetect.php'; $rDetect = new \Mobile_Detect(); $rMobile = $rDetect->isMobile(); @@ -598,6 +598,16 @@ class XC_Bootstrap { $language = Translator::class; $allowedLangs = $language::available(); + // Sort servers by order (moved from infrastructure/legacy/admin.php) + if (is_array($rServers)) { + uasort( + $rServers, + function ($a, $b) { + return $a['order'] - $b['order']; + } + ); + } + require_once MAIN_HOME . 'resources/data/admin_constants.php'; } diff --git a/src/cli/Commands/LlodCommand.php b/src/cli/Commands/LlodCommand.php index 8cac6940..8b928ef5 100644 --- a/src/cli/Commands/LlodCommand.php +++ b/src/cli/Commands/LlodCommand.php @@ -49,7 +49,6 @@ class LlodCommand implements CommandInterface { if (!defined('MAIN_HOME')) define('MAIN_HOME', '/home/xc_vm/'); if (!defined('STREAMS_PATH')) define('STREAMS_PATH', MAIN_HOME . 'content/streams/'); - if (!defined('INCLUDES_PATH')) define('INCLUDES_PATH', MAIN_HOME . 'includes/'); if (!defined('CACHE_TMP_PATH')) define('CACHE_TMP_PATH', MAIN_HOME . 'tmp/cache/'); if (!defined('CONS_TMP_PATH')) define('CONS_TMP_PATH', MAIN_HOME . 'tmp/opened_cons/'); if (!defined('FFMPEG')) define('FFMPEG', MAIN_HOME . 'bin/ffmpeg_bin/4.0/ffmpeg'); @@ -86,7 +85,7 @@ class LlodCommand implements CommandInterface { set_time_limit(0); error_reporting(E_WARNING | E_PARSE); cli_set_process_title('LLOD[' . $rStreamID . ']'); - require INCLUDES_PATH . 'ts.php'; + require MAIN_HOME . 'streaming/TimeshiftClient.php'; $rSettings = igbinary_unserialize(file_get_contents(CACHE_TMP_PATH . 'settings')); diff --git a/src/cli/Commands/LoopbackCommand.php b/src/cli/Commands/LoopbackCommand.php index ca6e105b..7467612d 100644 --- a/src/cli/Commands/LoopbackCommand.php +++ b/src/cli/Commands/LoopbackCommand.php @@ -38,7 +38,6 @@ class LoopbackCommand implements CommandInterface { if (!defined('MAIN_HOME')) define('MAIN_HOME', '/home/xc_vm/'); if (!defined('STREAMS_PATH')) define('STREAMS_PATH', MAIN_HOME . 'content/streams/'); - if (!defined('INCLUDES_PATH')) define('INCLUDES_PATH', MAIN_HOME . 'includes/'); if (!defined('FFMPEG')) define('FFMPEG', MAIN_HOME . 'bin/ffmpeg_bin/4.0/ffmpeg'); if (!defined('FFPROBE')) define('FFPROBE', MAIN_HOME . 'bin/ffmpeg_bin/4.0/ffprobe'); if (!defined('CACHE_TMP_PATH')) define('CACHE_TMP_PATH', MAIN_HOME . 'tmp/cache/'); @@ -86,7 +85,7 @@ class LoopbackCommand implements CommandInterface { set_time_limit(0); cli_set_process_title('Loopback[' . $rStreamID . ']'); - require INCLUDES_PATH . 'ts.php'; + require MAIN_HOME . 'streaming/TimeshiftClient.php'; $rSettings = igbinary_unserialize(file_get_contents(CACHE_TMP_PATH . 'settings')); $rServers = igbinary_unserialize(file_get_contents(CACHE_TMP_PATH . 'servers')); diff --git a/src/cli/Commands/MigrateCommand.php b/src/cli/Commands/MigrateCommand.php index b4d42896..c9fefa27 100644 --- a/src/cli/Commands/MigrateCommand.php +++ b/src/cli/Commands/MigrateCommand.php @@ -22,8 +22,6 @@ class MigrateCommand implements CommandInterface { public function execute(array $rArgs): int { // migrate requires admin bootstrap (CONTEXT_ADMIN) for $_INFO credentials - require INCLUDES_PATH . 'admin.php'; - // Expose $argc/$argv for migration_logic.php compatibility global $argc, $argv; diff --git a/src/cli/CronJobs/BackupsCronJob.php b/src/cli/CronJobs/BackupsCronJob.php index abf9e688..c690c0e2 100644 --- a/src/cli/CronJobs/BackupsCronJob.php +++ b/src/cli/CronJobs/BackupsCronJob.php @@ -32,8 +32,6 @@ class BackupsCronJob implements CommandInterface { ini_set('display_startup_errors', 1); error_reporting(32757); - require INCLUDES_PATH . 'admin.php'; - if (!ServerRepository::getAll()[SERVER_ID]['is_main']) { echo 'Please run on main server.' . "\n"; return 1; @@ -74,7 +72,7 @@ class BackupsCronJob implements CommandInterface { if (0 < filesize($rFilename)) { if (SettingsManager::getAll()['dropbox_remote']) { file_put_contents($rFilename . '.uploading', time()); - $rResponse = uploadRemoteBackup(basename($rFilename), $rFilename); + $rResponse = BackupService::uploadRemote(basename($rFilename), $rFilename); if (!isset($rResponse->error)) { $rResponse = json_decode(json_encode($rResponse, JSON_UNESCAPED_UNICODE), true); if (!(isset($rResponse['size']) && intval($rResponse['size']) == filesize($rFilename))) { @@ -97,7 +95,7 @@ class BackupsCronJob implements CommandInterface { } } - $rBackups = getBackups(); + $rBackups = BackupService::getLocal(); if (intval(SettingsManager::getAll()['backups_to_keep']) < count($rBackups) && 0 < intval(SettingsManager::getAll()['backups_to_keep'])) { $rDelete = array_slice($rBackups, 0, count($rBackups) - intval(SettingsManager::getAll()['backups_to_keep'])); foreach ($rDelete as $rItem) { @@ -108,12 +106,12 @@ class BackupsCronJob implements CommandInterface { } if (SettingsManager::getAll()['dropbox_remote']) { - $rRemoteBackups = getRemoteBackups(); + $rRemoteBackups = BackupService::getRemote(); if (intval(SettingsManager::getAll()['dropbox_keep']) < count($rRemoteBackups) && 0 < intval(SettingsManager::getAll()['dropbox_keep'])) { $rDelete = array_slice($rRemoteBackups, 0, count($rRemoteBackups) - intval(SettingsManager::getAll()['dropbox_keep'])); foreach ($rDelete as $rItem) { try { - deleteRemoteBackup($rItem['path']); + BackupService::deleteRemote($rItem['path']); } catch (exception $e) { } } diff --git a/src/cli/CronJobs/EpgCronJob.php b/src/cli/CronJobs/EpgCronJob.php index 9b1262f8..8d432378 100644 --- a/src/cli/CronJobs/EpgCronJob.php +++ b/src/cli/CronJobs/EpgCronJob.php @@ -39,7 +39,7 @@ class EpgCronJob implements CommandInterface { set_time_limit(0); ini_set('memory_limit', -1); - require INCLUDES_PATH . 'libs/XmlStringStreamer.php'; + require MAIN_HOME . 'core/Parsing/XmlStringStreamer.php'; shell_exec('kill -9 `ps -ef | grep \'XC_VM\\[EPG\\]\' | grep -v grep | awk \'{print $2}\'`;'); cli_set_process_title('XC_VM[EPG]'); diff --git a/src/cli/CronJobs/RootMysqlCronJob.php b/src/cli/CronJobs/RootMysqlCronJob.php index 88a06ac6..06a92404 100644 --- a/src/cli/CronJobs/RootMysqlCronJob.php +++ b/src/cli/CronJobs/RootMysqlCronJob.php @@ -28,8 +28,6 @@ class RootMysqlCronJob implements CommandInterface { return 1; } - require INCLUDES_PATH . 'admin.php'; - if (!$this->checkMariaDB()) { return 1; } diff --git a/src/cli/CronJobs/RootSignalsCronJob.php b/src/cli/CronJobs/RootSignalsCronJob.php index 0bf69c13..1386f4d9 100644 --- a/src/cli/CronJobs/RootSignalsCronJob.php +++ b/src/cli/CronJobs/RootSignalsCronJob.php @@ -509,7 +509,7 @@ class RootSignalsCronJob implements CommandInterface { case 'certbot_generate': echo 'Generating certbot certificate.' . "\n"; $db->query("INSERT INTO `mysql_syslog`(`server_id`, `type`, `error`, `username`, `ip`, `database`, `date`) VALUES(?, 'CERTBOT', 'Attempting to generate certbot certificate on request.', 'root', 'localhost', NULL, ?);", SERVER_ID, time()); - shell_exec('sudo ' . PHP_BIN . ' ' . INCLUDES_PATH . 'cli/certbot.php "' . base64_encode(json_encode($rData)) . '" 2>&1 &'); + shell_exec('sudo ' . PHP_BIN . ' ' . MAIN_HOME . 'console.php certbot "' . base64_encode(json_encode($rData)) . '" 2>&1 &'); break; case 'update_binaries': echo 'Updating binaries...' . "\n"; diff --git a/src/cli/CronJobs/SeriesCronJob.php b/src/cli/CronJobs/SeriesCronJob.php index d387b6fb..05d74725 100644 --- a/src/cli/CronJobs/SeriesCronJob.php +++ b/src/cli/CronJobs/SeriesCronJob.php @@ -28,8 +28,6 @@ class SeriesCronJob implements CommandInterface { return 1; } - require INCLUDES_PATH . 'admin.php'; - $this->setProcessTitle('XC_VM[Series]'); $this->acquireCronLock(); diff --git a/src/cli/CronJobs/VodCronJob.php b/src/cli/CronJobs/VodCronJob.php index a73f8421..08ca66bf 100644 --- a/src/cli/CronJobs/VodCronJob.php +++ b/src/cli/CronJobs/VodCronJob.php @@ -65,7 +65,7 @@ class VodCronJob implements CommandInterface { $db->query('SELECT `id` FROM `recordings` WHERE `status` NOT IN (1,2) AND `source_id` = ? AND ((`start` <= UNIX_TIMESTAMP() AND `end` > UNIX_TIMESTAMP()) OR (`archive` = 1));', SERVER_ID); if ($db->num_rows() > 0) { foreach ($db->get_rows() as $rRow) { - shell_exec(PHP_BIN . ' ' . INCLUDES_PATH . 'cli/record.php ' . intval($rRow['id']) . ' > /dev/null 2>/dev/null &'); + shell_exec(PHP_BIN . ' ' . MAIN_HOME . 'console.php record ' . intval($rRow['id']) . ' > /dev/null 2>/dev/null &'); } } diff --git a/src/cli/migration_logic.php b/src/cli/migration_logic.php index 5a745ca5..ab2495c4 100644 --- a/src/cli/migration_logic.php +++ b/src/cli/migration_logic.php @@ -58,8 +58,8 @@ if ($odb->num_rows() > 0) { if ($rResult['type'] == 0) { $AdminAccesCode = $rResult['code']; } - $rResult = verifyPostTable('access_codes', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('access_codes', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `access_codes`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); AuthRepository::updateCodes(); @@ -88,8 +88,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `users` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('users', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -107,8 +107,8 @@ if ($odb->num_rows() > 0) { echo 'Blocking ' . number_format(count($rResults), 0) . ' IP addresses.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('blocked_ips', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('blocked_ips', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `blocked_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -125,8 +125,8 @@ if ($odb->num_rows() > 0) { echo 'Blocking ' . number_format(count($rResults), 0) . ' user-agents.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('blocked_uas', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('blocked_uas', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `blocked_uas`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -143,8 +143,8 @@ if ($odb->num_rows() > 0) { echo 'Blocking ' . number_format(count($rResults), 0) . " ISP's." . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('blocked_isps', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('blocked_isps', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `blocked_isps`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -161,8 +161,8 @@ if ($odb->num_rows() > 0) { echo 'Creating ' . number_format(count($rResults), 0) . ' bouquets.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('bouquets', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('bouquets', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -190,8 +190,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `enigma2_devices` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('enigma2_devices', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('enigma2_devices', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `enigma2_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -220,8 +220,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `mag_devices` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('mag_devices', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('mag_devices', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `mag_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -239,8 +239,8 @@ if ($odb->num_rows() > 0) { echo 'Processing ' . number_format(count($rResults), 0) . ' EPG URLs.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('epg', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('epg', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `epg`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -257,8 +257,8 @@ if ($odb->num_rows() > 0) { echo 'Creating ' . number_format(count($rResults), 0) . ' user groups.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('users_groups', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users_groups', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -275,8 +275,8 @@ if ($odb->num_rows() > 0) { echo 'Creating ' . number_format(count($rResults), 0) . ' user packages.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('users_packages', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users_packages', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users_packages`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -293,8 +293,8 @@ if ($odb->num_rows() > 0) { echo 'Authorising ' . number_format(count($rResults), 0) . ' RTMP IPs.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('rtmp_ips', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('rtmp_ips', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `rtmp_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -322,8 +322,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `streams_series` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('streams_series', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_series', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_series`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -352,8 +352,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `streams_episodes` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('streams_episodes', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_episodes', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_episodes`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -372,8 +372,8 @@ if ($odb->num_rows() > 0) { echo 'Moving ' . number_format(count($rResults), 0) . ' servers.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('servers', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('servers', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -401,8 +401,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `streams` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('streams', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -431,8 +431,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `streams_options` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('streams_options', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_options', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_options`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -467,8 +467,8 @@ if ($odb->num_rows() > 0) { if ($rResult['pid'] < 0) { $rResult['pid'] = null; } - $rResult = verifyPostTable('streams_servers', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_servers', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -486,8 +486,8 @@ if ($odb->num_rows() > 0) { echo 'Creating ' . number_format(count($rResults), 0) . ' categories.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('streams_categories', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_categories', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -504,8 +504,8 @@ if ($odb->num_rows() > 0) { echo 'Posting ' . number_format(count($rResults), 0) . ' tickets.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('tickets', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('tickets', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `tickets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -522,8 +522,8 @@ if ($odb->num_rows() > 0) { echo 'Posting ' . number_format(count($rResults), 0) . ' replies.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('tickets_replies', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('tickets_replies', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `tickets_replies`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -540,8 +540,8 @@ if ($odb->num_rows() > 0) { echo 'Generating ' . number_format(count($rResults), 0) . ' transcoding profiles.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('profiles', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('profiles', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `profiles`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -558,8 +558,8 @@ if ($odb->num_rows() > 0) { echo 'Generating ' . number_format(count($rResults), 0) . ' providers.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('providers', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('providers', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `providers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -593,8 +593,8 @@ if ($odb->num_rows() > 0) { if ($rResult['pid'] < 0) { $rResult['pid'] = null; } - $rResult = verifyPostTable('lines', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('lines', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -615,8 +615,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `watch_folders`;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('watch_folders', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('watch_folders', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `watch_folders`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -672,8 +672,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `reg_users` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('users', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -703,8 +703,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `members` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('users', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -722,8 +722,8 @@ if ($odb->num_rows() > 0) { echo 'Blocking ' . number_format(count($rResults), 0) . ' IP addresses.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('blocked_ips', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('blocked_ips', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `blocked_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -740,8 +740,8 @@ if ($odb->num_rows() > 0) { echo 'Blocking ' . number_format(count($rResults), 0) . ' user-agents.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('blocked_uas', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('blocked_uas', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `blocked_uas`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -758,8 +758,8 @@ if ($odb->num_rows() > 0) { echo 'Blocking ' . number_format(count($rResults), 0) . " ISP's." . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('blocked_isps', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('blocked_isps', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `blocked_isps`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -776,8 +776,8 @@ if ($odb->num_rows() > 0) { echo 'Blocking ' . number_format(count($rResults), 0) . " ISP's." . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('blocked_isps', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('blocked_isps', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `blocked_isps`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -822,8 +822,8 @@ if ($odb->num_rows() > 0) { $rResult['bouquet_' . $rType] = '[]'; } } - $rResult = verifyPostTable('bouquets', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('bouquets', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -853,8 +853,8 @@ if ($odb->num_rows() > 0) { $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { $rResult['lock_device'] = 1; - $rResult = verifyPostTable('enigma2_devices', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('enigma2_devices', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `enigma2_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -888,8 +888,8 @@ if ($odb->num_rows() > 0) { $rResult['lock_device'] = 1; if (0 >= $rResult['user_id']) { } else { - $rResult = verifyPostTable('mag_devices', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('mag_devices', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `mag_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -908,8 +908,8 @@ if ($odb->num_rows() > 0) { echo 'Processing ' . number_format(count($rResults), 0) . ' EPG URLs.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('epg', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('epg', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `epg`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -926,8 +926,8 @@ if ($odb->num_rows() > 0) { echo 'Processing ' . number_format(count($rResults), 0) . ' EPG URLs.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('epg', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('epg', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `epg`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -950,8 +950,8 @@ if ($odb->num_rows() > 0) { $rResult['allow_change_password'] = 1; $rResult['minimum_username_length'] = 8; $rResult['minimum_password_length'] = 8; - $rResult = verifyPostTable('users_groups', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users_groups', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -974,8 +974,8 @@ if ($odb->num_rows() > 0) { $rResult['allow_change_password'] = 1; $rResult['minimum_username_length'] = 8; $rResult['minimum_password_length'] = 8; - $rResult = verifyPostTable('users_groups', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users_groups', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -998,8 +998,8 @@ if ($odb->num_rows() > 0) { $rResult['allow_change_password'] = 1; $rResult['minimum_username_length'] = 8; $rResult['minimum_password_length'] = 8; - $rResult = verifyPostTable('users_groups', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users_groups', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1037,8 +1037,8 @@ if ($odb->num_rows() > 0) { } else { $rResult['output_formats'] = '[1,2,3]'; } - $rResult = verifyPostTable('users_packages', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('users_packages', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `users_packages`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1055,10 +1055,10 @@ if ($odb->num_rows() > 0) { echo 'Authorising ' . number_format(count($rResults), 0) . ' RTMP IPs.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('rtmp_ips', $rResult); + $rResult = QueryHelper::verifyPostTable('rtmp_ips', $rResult); $rResult['push'] = 1; $rResult['pull'] = 1; - $rPrepare = prepareArray($rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `rtmp_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1093,8 +1093,8 @@ if ($odb->num_rows() > 0) { } else { $rResult['tmdb_id'] = null; } - $rResult = verifyPostTable('streams_series', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_series', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT IGNORE INTO `streams_series`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -1125,8 +1125,8 @@ if ($odb->num_rows() > 0) { $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { $rResult['episode_num'] = $rResult['sort']; - $rResult = verifyPostTable('streams_episodes', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_episodes', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_episodes`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -1159,8 +1159,8 @@ if ($odb->num_rows() > 0) { } else { $rResult['is_main'] = 0; } - $rResult = verifyPostTable('servers', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('servers', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1192,8 +1192,8 @@ if ($odb->num_rows() > 0) { } else { $rResult['is_main'] = 0; } - $rResult = verifyPostTable('servers', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('servers', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1236,8 +1236,8 @@ if ($odb->num_rows() > 0) { list($rResult['target_container']) = json_decode($rResult['target_container'], true); } $rCreatedOptions[$rResult['id']] = $rResult['cchannel_rsources']; - $rResult = verifyPostTable('streams', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1270,8 +1270,8 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `streams_options` LIMIT ' . $rStep . ', 1000;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('streams_options', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_options', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_options`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -1318,8 +1318,8 @@ if ($odb->num_rows() > 0) { if ($rResult['pid'] < 0) { $rResult['pid'] = null; } - $rResult = verifyPostTable('streams_servers', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_servers', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -1363,8 +1363,8 @@ if ($odb->num_rows() > 0) { } else { $rResult['pid'] = null; } - $rResult = verifyPostTable('streams_servers', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_servers', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -1383,8 +1383,8 @@ if ($odb->num_rows() > 0) { echo 'Creating ' . number_format(count($rResults), 0) . ' categories.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('streams_categories', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_categories', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1401,8 +1401,8 @@ if ($odb->num_rows() > 0) { echo 'Creating ' . number_format(count($rResults), 0) . ' categories.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('streams_categories', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('streams_categories', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1419,8 +1419,8 @@ if ($odb->num_rows() > 0) { echo 'Posting ' . number_format(count($rResults), 0) . ' tickets.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('tickets', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('tickets', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `tickets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1437,8 +1437,8 @@ if ($odb->num_rows() > 0) { echo 'Posting ' . number_format(count($rResults), 0) . ' replies.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('tickets_replies', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('tickets_replies', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `tickets_replies`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1455,8 +1455,8 @@ if ($odb->num_rows() > 0) { echo 'Generating ' . number_format(count($rResults), 0) . ' transcoding profiles.' . "\n"; foreach ($rResults as $rResult) { try { - $rResult = verifyPostTable('profiles', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('profiles', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `profiles`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } catch (Exception $e) { @@ -1526,8 +1526,8 @@ if ($odb->num_rows() > 0) { $rResult['allowed_outputs'] = $rResult['output']; } $rResult['bouquet'] = '[' . implode(',', array_map('intval', json_decode($rResult['bouquet'], true))) . ']'; - $rResult = verifyPostTable('lines', $rResult); - $rPrepare = prepareArray($rResult); + $rResult = QueryHelper::verifyPostTable('lines', $rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } @@ -1553,10 +1553,10 @@ if ($odb->num_rows() > 0) { $odb->query('SELECT * FROM `watch_folders`;'); $rResults = $odb->get_rows(); foreach ($rResults as $rResult) { - $rResult = verifyPostTable('watch_folders', $rResult); + $rResult = QueryHelper::verifyPostTable('watch_folders', $rResult); $rResult['bouquets'] = '[' . implode(',', array_map('intval', json_decode($rResult['bouquets'], true))) . ']'; $rResult['fb_bouquets'] = '[' . implode(',', array_map('intval', json_decode($rResult['fb_bouquets'], true))) . ']'; - $rPrepare = prepareArray($rResult); + $rPrepare = QueryHelper::prepareArray($rResult); $rQuery = 'INSERT INTO `watch_folders`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); } diff --git a/src/core/Auth/Authenticator.php b/src/core/Auth/Authenticator.php index 1ed1cc44..4431a833 100644 --- a/src/core/Auth/Authenticator.php +++ b/src/core/Auth/Authenticator.php @@ -45,7 +45,7 @@ class Authenticator { return array('status' => STATUS_INVALID_CODE); } - $rPermissions = getPermissions($rUserInfo['member_group_id']); + $rPermissions = AuthRepository::getPermissions($rUserInfo['member_group_id']); if (!$rPermissions['is_admin']) { if (!empty($rSettings['save_login_logs'])) { $db->query("INSERT INTO `login_logs`(`type`, `access_code`, `user_id`, `status`, `login_ip`, `date`) VALUES('ADMIN', ?, ?, ?, ?, ?);", $rAccessCode['id'], $rUserInfo['id'], 'NOT_ADMIN', $rIP, time()); @@ -54,7 +54,7 @@ class Authenticator { } if ($rUserInfo['status'] == 1) { - $rCrypt = cryptPassword($rData['password']); + $rCrypt = self::hashPassword($rData['password']); $db->query('UPDATE `users` SET `password` = ?, `last_login` = UNIX_TIMESTAMP(), `ip` = ? WHERE `id` = ?;', $rCrypt, $rIP, $rUserInfo['id']); $_SESSION['hash'] = $rUserInfo['id']; @@ -105,7 +105,7 @@ class Authenticator { return array('status' => STATUS_INVALID_CODE); } - $rPermissions = getPermissions($rUserInfo['member_group_id']); + $rPermissions = AuthRepository::getPermissions($rUserInfo['member_group_id']); if (!$rPermissions['is_reseller']) { if (!empty($rSettings['save_login_logs'])) { $db->query("INSERT INTO `login_logs`(`type`, `access_code`, `user_id`, `status`, `login_ip`, `date`) VALUES('RESELLER', ?, ?, ?, ?, ?);", $rAccessCode['id'], $rUserInfo['id'], 'NOT_ADMIN', $rIP, time()); @@ -114,7 +114,7 @@ class Authenticator { } if ($rUserInfo['status'] == 1) { - $rCrypt = cryptPassword($rData['password']); + $rCrypt = self::hashPassword($rData['password']); $db->query('UPDATE `users` SET `password` = ?, `last_login` = UNIX_TIMESTAMP(), `ip` = ? WHERE `id` = ?;', $rCrypt, $rIP, $rUserInfo['id']); $_SESSION['reseller'] = $rUserInfo['id']; @@ -137,4 +137,18 @@ class Authenticator { return array('status' => STATUS_FAILURE); } + + public static function hashPassword($password, $salt = null, $rounds = 20000) { + if ($salt === null || $salt === '') { + $salt = substr(bin2hex(openssl_random_pseudo_bytes(16)), 0, 16); + } + if (strpos($salt, 'rounds=') === false) { + $salt = sprintf('$6$rounds=%d$%s$', $rounds, $salt); + } + return crypt($password, $salt); + } + + public static function checkPassword($password, $storedHash) { + return hash_equals($storedHash, crypt($password, $storedHash)); + } } diff --git a/src/core/Auth/SessionManager.php b/src/core/Auth/SessionManager.php index e1c67a91..a98f60c2 100644 --- a/src/core/Auth/SessionManager.php +++ b/src/core/Auth/SessionManager.php @@ -79,6 +79,10 @@ class SessionManager { 'code' => 'rcode', 'verify' => 'rverify', ], + 'player' => [ + 'auth' => 'phash', + 'verify' => 'pverify', + ], ]; /** @@ -223,6 +227,21 @@ class SessionManager { self::$started = false; } + /** + * Clear session keys for a specific context without destroying the session. + * Drop-in replacement for legacy destroySession($type). + * + * @param string $context 'admin', 'reseller', or 'player' + */ + public static function clearContext($context) { + if (!isset(self::$keyMap[$context])) { + return; + } + foreach (self::$keyMap[$context] as $key) { + unset($_SESSION[$key]); + } + } + /** * Update the last activity timestamp and close session for writing */ diff --git a/src/core/Backup/BackupService.php b/src/core/Backup/BackupService.php index dd8b9530..4fca328f 100644 --- a/src/core/Backup/BackupService.php +++ b/src/core/Backup/BackupService.php @@ -102,4 +102,108 @@ class BackupService { public static function revokePrivileges($host, $db, $config) { $db->query("REVOKE ALL PRIVILEGES ON `" . $config['database'] . "`.* FROM '" . $config['username'] . "'@'" . $host . "';"); } + + public static function getLocal() { + $rBackups = array(); + + foreach (scandir(MAIN_HOME . 'backups/') as $rBackup) { + $rInfo = pathinfo(MAIN_HOME . 'backups/' . $rBackup); + + if ($rInfo['extension'] != 'sql') { + } else { + $rBackups[] = array('filename' => $rBackup, 'timestamp' => filemtime(MAIN_HOME . 'backups/' . $rBackup), 'date' => date('Y-m-d H:i:s', filemtime(MAIN_HOME . 'backups/' . $rBackup)), 'filesize' => filesize(MAIN_HOME . 'backups/' . $rBackup)); + } + } + usort( + $rBackups, + function ($a, $b) { + return $a['timestamp']; + } + ); + + return $rBackups; + } + + public static function checkRemoteConnection() { + require_once MAIN_HOME . 'core/Storage/DropboxClient.php'; + + try { + $rClient = new DropboxClient(); + $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); + $rClient->GetFiles(); + + return true; + } catch (exception $e) { + return false; + } + } + + public static function getRemote() { + require_once MAIN_HOME . 'core/Storage/DropboxClient.php'; + + try { + $rClient = new DropboxClient(); + $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); + $rFiles = $rClient->GetFiles(); + } catch (exception $e) { + $rFiles = array(); + } + $rBackups = array(); + + foreach ($rFiles as $rFile) { + try { + if (!(!$rFile->isDir && strtolower(pathinfo($rFile->name)['extension']) == 'sql' && 0 < $rFile->size)) { + } else { + $rJSON = json_decode(json_encode($rFile, JSON_UNESCAPED_UNICODE), true); + $rJSON['time'] = strtotime($rFile->server_modified); + $rBackups[] = $rJSON; + } + } catch (exception $e) { + } + } + array_multisort(array_column($rBackups, 'time'), SORT_ASC, $rBackups); + + return $rBackups; + } + + public static function downloadRemote($rPath, $rFilename) { + require_once MAIN_HOME . 'core/Storage/DropboxClient.php'; + $rClient = new DropboxClient(); + + try { + $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); + $rClient->downloadFile($rPath, $rFilename); + + return true; + } catch (exception $e) { + return false; + } + } + + public static function uploadRemote($rPath, $rFilename, $rOverwrite = true) { + require_once MAIN_HOME . 'core/Storage/DropboxClient.php'; + $rClient = new DropboxClient(); + + try { + $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); + + return $rClient->UploadFile($rFilename, $rPath, $rOverwrite); + } catch (exception $e) { + return (object) array('error' => $e); + } + } + + public static function deleteRemote($rPath) { + require_once MAIN_HOME . 'core/Storage/DropboxClient.php'; + $rClient = new DropboxClient(); + + try { + $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); + $rClient->Delete($rPath); + + return true; + } catch (exception $e) { + return false; + } + } } diff --git a/src/core/Config/Paths.php b/src/core/Config/Paths.php index 1d70e1e0..02629f68 100644 --- a/src/core/Config/Paths.php +++ b/src/core/Config/Paths.php @@ -38,7 +38,6 @@ if (!defined('TMP_PATH')) { define('CONFIG_PATH', MAIN_HOME . 'config/'); define('BIN_PATH', MAIN_HOME . 'bin/'); -define('INCLUDES_PATH', MAIN_HOME . 'includes/'); define('WWW_PATH', MAIN_HOME . 'www/'); define('SIGNALS_PATH', MAIN_HOME . 'signals/'); diff --git a/src/core/Config/SettingsManager.php b/src/core/Config/SettingsManager.php index ce477882..67a27f89 100644 --- a/src/core/Config/SettingsManager.php +++ b/src/core/Config/SettingsManager.php @@ -47,4 +47,10 @@ class SettingsManager { public static function update(string $key, $value): void { self::$settings[$key] = $value; } + + public static function clearCache() { + if (file_exists(CACHE_TMP_PATH . 'settings')) { + unlink(CACHE_TMP_PATH . 'settings'); + } + } } diff --git a/src/core/Diagnostics/DiagnosticsService.php b/src/core/Diagnostics/DiagnosticsService.php index 38b35a90..1841c1d5 100644 --- a/src/core/Diagnostics/DiagnosticsService.php +++ b/src/core/Diagnostics/DiagnosticsService.php @@ -247,4 +247,102 @@ class DiagnosticsService { return $data['ip']; } + + public static function getPIDs($rServerID) { + $rReturn = array(); + $rProcesses = json_decode(ApiClient::systemRequest($rServerID, array('action' => 'get_pids')), true); + if (!is_array($rProcesses)) { + return $rReturn; + } + array_shift($rProcesses); + + foreach ($rProcesses as $rProcess) { + $rSplit = explode(' ', preg_replace('!\\s+!', ' ', trim($rProcess))); + + if ($rSplit[0] == 'xc_vm') { + $rUsage = array(0, 0, 0); + $rTimer = explode('-', $rSplit[9]); + + if (1 < count($rTimer)) { + $rDays = intval($rTimer[0]); + $rTime = $rTimer[1]; + } else { + $rDays = 0; + $rTime = $rTimer[0]; + } + + $rTime = explode(':', $rTime); + + if (count($rTime) == 3) { + $rSeconds = intval($rTime[0]) * 3600 + intval($rTime[1]) * 60 + intval($rTime[2]); + } else { + if (count($rTime) == 2) { + $rSeconds = intval($rTime[0]) * 60 + intval($rTime[1]); + } else { + $rSeconds = intval($rTime[2]); + } + } + + $rUsage[0] = $rSeconds + $rDays * 86400; + $rTimer = explode('-', $rSplit[8]); + + if (1 < count($rTimer)) { + $rDays = intval($rTimer[0]); + $rTime = $rTimer[1]; + } else { + $rDays = 0; + $rTime = $rTimer[0]; + } + + $rTime = explode(':', $rTime); + + if (count($rTime) == 3) { + $rSeconds = intval($rTime[0]) * 3600 + intval($rTime[1]) * 60 + intval($rTime[2]); + } else { + if (count($rTime) == 2) { + $rSeconds = intval($rTime[0]) * 60 + intval($rTime[1]); + } else { + $rSeconds = intval($rTime[2]); + } + } + + $rUsage[1] = $rSeconds + $rDays * 86400; + if ($rUsage[0] != 0) { + $rUsage[2] = $rUsage[1] / $rUsage[0] * 100; + } else { + $rUsage[2] = 0; + } + + $rReturn[] = array('user' => $rSplit[0], 'pid' => $rSplit[1], 'cpu' => $rSplit[2], 'mem' => $rSplit[3], 'vsz' => $rSplit[4], 'rss' => $rSplit[5], 'tty' => $rSplit[6], 'stat' => $rSplit[7], 'time' => $rUsage[1], 'etime' => $rUsage[0], 'load_average' => $rUsage[2], 'command' => implode(' ', array_splice($rSplit, 10, count($rSplit) - 10))); + } + } + + return $rReturn; + } + + public static function getNVENCProcesses($rServerID) { + global $db; + $rProcesses = array(); + $rServer = ServerRepository::getById($rServerID); + $rGPUInfo = json_decode($rServer['gpu_info'], true); + + if (!is_array($rGPUInfo)) { + } else { + foreach ($rGPUInfo['gpus'] as $rGPU) { + foreach ($rGPU['processes'] as $rProcess) { + $rArray = array('pid' => $rProcess['pid'], 'memory' => $rProcess['memory'], 'stream_id' => null); + $db->query('SELECT `stream_id` FROM `streams_servers` WHERE `pid` = ? AND `server_id` = ?;', $rProcess['pid'], $rServerID); + + if (0 >= $db->num_rows()) { + } else { + $rArray['stream_id'] = $db->get_row()['stream_id']; + } + + $rProcesses[] = $rArray; + } + } + } + + return $rProcesses; + } } diff --git a/src/core/Http/RequestGuard.php b/src/core/Http/RequestGuard.php index 378be408..a2d6fc82 100644 --- a/src/core/Http/RequestGuard.php +++ b/src/core/Http/RequestGuard.php @@ -61,7 +61,7 @@ define('PHP_ERRORS', $rShowErrors); // ── Logger ───────────────────────────────────────────────────── // After fixing all the warnings, replace DEVELOPMENT with PHP_ERRORS -require_once INCLUDES_PATH . 'libs/Logger.php'; +require_once MAIN_HOME . 'core/Logging/Logger.php'; Logger::init( DEVELOPMENT, LOGS_TMP_PATH . 'error_log.log' diff --git a/src/core/Http/Router.php b/src/core/Http/Router.php index e4e105de..c46ed2cc 100644 --- a/src/core/Http/Router.php +++ b/src/core/Http/Router.php @@ -461,7 +461,7 @@ class Router { */ protected function denyAccess() { if (function_exists('goHome')) { - goHome(); + AdminHelpers::goHome(); } else { http_response_code(403); echo 'Access denied'; diff --git a/src/domain/Auth/AuthRepository.php b/src/domain/Auth/AuthRepository.php index 30b87ac0..acfc1cde 100644 --- a/src/domain/Auth/AuthRepository.php +++ b/src/domain/Auth/AuthRepository.php @@ -12,10 +12,6 @@ */ class AuthRepository { - // ────────────────────────────────────────────── - // Из CodeRepository - // ────────────────────────────────────────────── - public static function getAllCodes($rType = null) { global $db; $rReturn = array(); @@ -71,6 +67,9 @@ class AuthRepository { $rWhitelist[] = 'deny all;'; } + // NOTE: 'includes/api/admin' and 'includes/api/reseller' are legacy nginx route + // identifiers baked into generated access-code configs — NOT filesystem paths. + // Do not rename without regenerating all deployed nginx configs. $rType = array('admin', 'reseller', 'ministra', 'includes/api/admin', 'includes/api/reseller', 'ministra/new', 'player')[$rCode['type']]; $rAlias = array('public/Views/admin', 'reseller', 'ministra', 'includes/api/admin', 'includes/api/reseller', 'ministra/new', 'public/assets/player')[$rCode['type']]; $rBurst = array(500, 50, 50, 1000, 1000, 50, 500)[$rCode['type']]; @@ -93,9 +92,7 @@ class AuthRepository { } } - if (function_exists('systemapirequest')) { - systemapirequest($rServerId, array('action' => 'reload_nginx')); - } + ApiClient::systemRequest($rServerId, array('action' => 'reload_nginx')); } public static function getCurrentCode($rInfo = false) { @@ -117,10 +114,6 @@ class AuthRepository { return $rCode; } - // ────────────────────────────────────────────── - // Из HMACRepository - // ────────────────────────────────────────────── - public static function getAllHMAC() { global $db; $rReturn = array(); @@ -142,4 +135,117 @@ class AuthRepository { return $db->get_row(); } } + + // ────────────────────────────────────────────── + // Permissions + // ────────────────────────────────────────────── + + public static function getPermissions($rID) { + global $db; + $db->query('SELECT * FROM `users_groups` WHERE `group_id` = ?;', $rID); + + if ($db->num_rows() == 1) { + $rRow = $db->get_row(); + $rRow['subresellers'] = !empty($rRow['subresellers']) ? json_decode($rRow['subresellers'], true) : []; + + if (count($rRow['subresellers'] ?? []) == 0) { + $rRow['create_sub_resellers'] = 0; + } + + return $rRow; + } + + return []; + } + + public static function getGroupPermissions($rUserID, $rStreams = true, $rUsers = true) { + global $db; + $rStart = round(microtime(true) * 1000); + $rReturn = array('create_line' => false, 'create_mag' => false, 'create_enigma' => false, 'stream_ids' => array(), 'series_ids' => array(), 'category_ids' => array(), 'users' => array(), 'direct_reports' => array(), 'all_reports' => array(), 'report_map' => array()); + $rUser = UserRepository::getRegisteredUserById($rUserID); + + if (!$rUser) { + } else { + if (!file_exists(CACHE_TMP_PATH . 'permissions_' . intval($rUser['member_group_id']))) { + } else { + $rPermData = igbinary_unserialize(file_get_contents(CACHE_TMP_PATH . 'permissions_' . intval($rUser['member_group_id']))); + if (is_array($rPermData)) { + $rReturn = array_merge($rReturn, $rPermData); + } + } + + $db->query("SELECT * FROM `users_packages` WHERE JSON_CONTAINS(`groups`, ?, '\$');", $rUser['member_group_id']); + + foreach ($db->get_rows() as $rRow) { + if (!$rRow['is_line']) { + } else { + $rReturn['create_line'] = true; + } + + if (!$rRow['is_mag']) { + } else { + $rReturn['create_mag'] = true; + } + + if (!$rRow['is_e2']) { + } else { + $rReturn['create_enigma'] = true; + } + } + + if (!$rUsers) { + } else { + $rReturn['users'] = UserRepository::getSubUsers($rUser['id']); + + foreach ($rReturn['users'] as $rUserID => $rUserData) { + if ($rUser['id'] != $rUserData['parent']) { + } else { + $rReturn['direct_reports'][] = $rUserID; + } + + $rReturn['all_reports'][] = $rUserID; + } + } + } + + return $rReturn; + } + + public static function getCodeById($rID) { + global $db; + $db->query('SELECT * FROM `access_codes` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return null; + } + + return $db->get_row(); + } + + public static function deleteCode($rID) { + global $db; + $db->query('SELECT `id` FROM `access_codes` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $db->query('DELETE FROM `access_codes` WHERE `id` = ?;', $rID); + self::updateCodes(); + + return true; + } + + public static function deleteHMAC($rID) { + global $db; + $db->query('SELECT `id` FROM `hmac_keys` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $db->query('DELETE FROM `hmac_keys` WHERE `id` = ?;', $rID); + + return true; + } } diff --git a/src/domain/Auth/AuthService.php b/src/domain/Auth/AuthService.php index 866b90bd..39fefd67 100644 --- a/src/domain/Auth/AuthService.php +++ b/src/domain/Auth/AuthService.php @@ -19,10 +19,10 @@ class AuthService { public static function processCode($rData) { global $db; if (isset($rData['edit'])) { - $rArray = overwriteData(getCode($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(AuthRepository::getCodeById($rData['edit']), $rData); $rOrigCode = $rArray['code']; } else { - $rArray = verifyPostTable('access_codes', $rData); + $rArray = QueryHelper::verifyPostTable('access_codes', $rData); $rOrigCode = null; unset($rArray['id']); } @@ -72,7 +72,7 @@ class AuthService { return array('status' => STATUS_EXISTS_CODE, 'data' => $rData); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `access_codes`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -91,9 +91,9 @@ class AuthService { public static function processHMAC($rData) { global $db, $rSettings; if (isset($rData['edit'])) { - $rArray = overwriteData(AuthRepository::getHMACById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(AuthRepository::getHMACById($rData['edit']), $rData); } else { - $rArray = verifyPostTable('hmac_keys', $rData); + $rArray = QueryHelper::verifyPostTable('hmac_keys', $rData); unset($rArray['id']); } @@ -129,7 +129,7 @@ class AuthService { $rArray['key'] = Encryption::encrypt($rData['keygen'], $rSettings['live_streaming_pass'], OPENSSL_EXTRA); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `hmac_keys`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { diff --git a/src/domain/Bouquet/BouquetService.php b/src/domain/Bouquet/BouquetService.php index fd83f3af..e9c5b8a6 100644 --- a/src/domain/Bouquet/BouquetService.php +++ b/src/domain/Bouquet/BouquetService.php @@ -18,13 +18,13 @@ class BouquetService { exit(); } - $rArray = overwriteData(getBouquet($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(BouquetService::getById($rData['edit']), $rData); } else { if (!Authorization::check('adv', 'add_bouquet')) { exit(); } - $rArray = verifyPostTable('bouquets', $rData); + $rArray = QueryHelper::verifyPostTable('bouquets', $rData); unset($rArray['id']); } @@ -34,7 +34,7 @@ class BouquetService { $rBouquetMovies = $rBouquetData['movies']; $rBouquetRadios = $rBouquetData['radios']; $rBouquetSeries = $rBouquetData['series']; - $rRequiredIDs = confirmIDs(array_merge($rBouquetStreams, $rBouquetMovies, $rBouquetRadios)); + $rRequiredIDs = AdminHelpers::confirmIDs(array_merge($rBouquetStreams, $rBouquetMovies, $rBouquetRadios)); $rStreams = array(); if (count($rRequiredIDs) > 0) { @@ -70,7 +70,7 @@ class BouquetService { $rArray['bouquet_order'] = intval($db->get_row()['max']) + 1; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -86,10 +86,10 @@ class BouquetService { public static function reorder($rData) { global $db; $rOrder = json_decode($rData['stream_order_array'], true); - $rOrder['stream'] = confirmIDs($rOrder['stream']); - $rOrder['series'] = confirmIDs($rOrder['series']); - $rOrder['movie'] = confirmIDs($rOrder['movie']); - $rOrder['radio'] = confirmIDs($rOrder['radio']); + $rOrder['stream'] = AdminHelpers::confirmIDs($rOrder['stream']); + $rOrder['series'] = AdminHelpers::confirmIDs($rOrder['series']); + $rOrder['movie'] = AdminHelpers::confirmIDs($rOrder['movie']); + $rOrder['radio'] = AdminHelpers::confirmIDs($rOrder['radio']); $db->query('UPDATE `bouquets` SET `bouquet_channels` = ?, `bouquet_series` = ?, `bouquet_movies` = ?, `bouquet_radios` = ? WHERE `id` = ?;', '[' . implode(',', array_map('intval', $rOrder['stream'])) . ']', '[' . implode(',', array_map('intval', $rOrder['series'])) . ']', '[' . implode(',', array_map('intval', $rOrder['movie'])) . ']', '[' . implode(',', array_map('intval', $rOrder['radio'])) . ']', $rData['reorder']); return array('status' => STATUS_SUCCESS, 'data' => array('insert_id' => $rData['reorder'])); @@ -114,15 +114,15 @@ class BouquetService { foreach ($rUsers as $rUser) { $rBouquet = json_decode($rUser['bouquet'], true); - $rBouquet = array_map('intval', sortArrayByArray($rBouquet, $rOrder)); + $rBouquet = array_map('intval', AdminHelpers::sortArrayByArray($rBouquet, $rOrder)); $db->query('UPDATE `lines` SET `bouquet` = ? WHERE `id` = ?;', '[' . implode(',', $rBouquet) . ']', $rUser['id']); LineService::updateLineSignal($rUser['id']); } - $rPackages = getPackages(); + $rPackages = PackageService::getAll(); foreach ($rPackages as $rPackage) { $rBouquet = json_decode($rPackage['bouquets'], true); - $rBouquet = array_map('intval', sortArrayByArray($rBouquet, $rOrder)); + $rBouquet = array_map('intval', AdminHelpers::sortArrayByArray($rBouquet, $rOrder)); $db->query('UPDATE `users_packages` SET `bouquets` = ? WHERE `id` = ?;', '[' . implode(',', $rBouquet) . ']', $rPackage['id']); } @@ -138,7 +138,7 @@ class BouquetService { public static function scanOne($rID) { global $db; - $rBouquet = getBouquet($rID); + $rBouquet = BouquetService::getById($rID); if (!$rBouquet) { return; } @@ -160,10 +160,10 @@ class BouquetService { } $updateData = [ - 'channels' => filterIDs(json_decode($rBouquet['bouquet_channels'] ?? '[]', true), $availableStreams, true), - 'movies' => filterIDs(json_decode($rBouquet['bouquet_movies'] ?? '[]', true), $availableStreams, true), - 'radios' => filterIDs(json_decode($rBouquet['bouquet_radios'] ?? '[]', true), $availableStreams, true), - 'series' => filterIDs(json_decode($rBouquet['bouquet_series'] ?? '[]', true), $availableSeries, false) + 'channels' => AdminHelpers::filterIDs(json_decode($rBouquet['bouquet_channels'] ?? '[]', true), $availableStreams, true), + 'movies' => AdminHelpers::filterIDs(json_decode($rBouquet['bouquet_movies'] ?? '[]', true), $availableStreams, true), + 'radios' => AdminHelpers::filterIDs(json_decode($rBouquet['bouquet_radios'] ?? '[]', true), $availableStreams, true), + 'series' => AdminHelpers::filterIDs(json_decode($rBouquet['bouquet_series'] ?? '[]', true), $availableSeries, false) ]; $db->query( @@ -248,4 +248,161 @@ class BouquetService { global $db; return self::getAllSimple(); } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `bouquets` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return null; + } + + return $db->get_row(); + } + + public static function deleteById($rID) { + global $db; + $rBouquet = self::getById($rID); + + if (!$rBouquet) { + return false; + } + + $db->query("SELECT `id`, `bouquet` FROM `lines` WHERE JSON_CONTAINS(`bouquet`, ?, '\$');", $rID); + + foreach ($db->get_rows() as $rRow) { + $rRow['bouquet'] = json_decode($rRow['bouquet'], true); + + if (($rKey = array_search($rID, $rRow['bouquet'])) === false) { + } else { + unset($rRow['bouquet'][$rKey]); + } + + $db->query("UPDATE `lines` SET `bouquet` = ? WHERE `id` = ?;", '[' . implode(',', array_map('intval', $rRow['bouquet'])) . ']', $rRow['id']); + LineService::updateLineSignal($rRow['id']); + } + $db->query("SELECT `id`, `bouquets` FROM `users_packages` WHERE JSON_CONTAINS(`bouquets`, ?, '\$');", $rID); + + foreach ($db->get_rows() as $rRow) { + $rRow['bouquets'] = json_decode($rRow['bouquets'], true); + + if (($rKey = array_search($rID, $rRow['bouquets'])) === false) { + } else { + unset($rRow['bouquets'][$rKey]); + } + + $db->query("UPDATE `users_packages` SET `bouquets` = ? WHERE `id` = ?;", '[' . implode(',', array_map('intval', $rRow['bouquets'])) . ']', $rRow['id']); + } + $db->query("SELECT `id`, `bouquets` FROM `watch_folders` WHERE JSON_CONTAINS(`bouquets`, ?, '\$') OR JSON_CONTAINS(`fb_bouquets`, ?, '\$');", $rID, $rID); + + foreach ($db->get_rows() as $rRow) { + $rRow['bouquets'] = json_decode($rRow['bouquets'], true); + + if (($rKey = array_search($rID, $rRow['bouquets'])) === false) { + } else { + unset($rRow['bouquets'][$rKey]); + } + + $rRow['fb_bouquets'] = json_decode($rRow['fb_bouquets'], true); + + if (($rKey = array_search($rID, $rRow['fb_bouquets'])) === false) { + } else { + unset($rRow['fb_bouquets'][$rKey]); + } + + $db->query("UPDATE `watch_folders` SET `bouquets` = ?, `fb_bouquets` = ? WHERE `id` = ?;", '[' . implode(',', array_map('intval', $rRow['bouquets'])) . ']', '[' . implode(',', array_map('intval', $rRow['fb_bouquets'])) . ']', $rRow['id']); + } + $db->query('DELETE FROM `bouquets` WHERE `id` = ?;', $rID); + self::scan(); + + return true; + } + + public static function addItems($rType, $rBouquetID, $rIDs) { + global $db; + + if (!is_array($rIDs)) { + $rIDs = array($rIDs); + } + + $rBouquet = self::getById($rBouquetID); + + if (!$rBouquet) { + return; + } + + if ($rType == 'stream') { + $rColumn = 'bouquet_channels'; + } else { + if ($rType == 'movie') { + $rColumn = 'bouquet_movies'; + } else { + if ($rType == 'radio') { + $rColumn = 'bouquet_radios'; + } else { + $rColumn = 'bouquet_series'; + } + } + } + + $rChanged = false; + $rChannels = AdminHelpers::confirmIDs(json_decode($rBouquet[$rColumn], true)); + + foreach ($rIDs as $rID) { + if (0 >= intval($rID) || in_array($rID, $rChannels)) { + } else { + $rChannels[] = $rID; + $rChanged = true; + } + } + + if (!$rChanged) { + } else { + $db->query('UPDATE `bouquets` SET `' . $rColumn . '` = ? WHERE `id` = ?;', '[' . implode(',', array_map('intval', $rChannels)) . ']', $rBouquetID); + } + } + + public static function removeItems($rType, $rBouquetID, $rIDs) { + global $db; + + if (!is_array($rIDs)) { + $rIDs = array($rIDs); + } + + $rBouquet = self::getById($rBouquetID); + + if (!$rBouquet) { + return; + } + + if ($rType == 'stream') { + $rColumn = 'bouquet_channels'; + } else { + if ($rType == 'movie') { + $rColumn = 'bouquet_movies'; + } else { + if ($rType == 'radio') { + $rColumn = 'bouquet_radios'; + } else { + $rColumn = 'bouquet_series'; + } + } + } + + $rChanged = false; + $rChannels = AdminHelpers::confirmIDs(json_decode($rBouquet[$rColumn], true)); + + foreach ($rIDs as $rID) { + if (($rKey = array_search($rID, $rChannels)) === false) { + } else { + unset($rChannels[$rKey]); + $rChanged = true; + } + } + + if (!$rChanged) { + } else { + $db->query('UPDATE `bouquets` SET `' . $rColumn . '` = ? WHERE `id` = ?;', '[' . implode(',', array_map('intval', $rChannels)) . ']', $rBouquetID); + } + } } diff --git a/src/domain/Device/EnigmaService.php b/src/domain/Device/EnigmaService.php index 8dbfb8df..e376e129 100644 --- a/src/domain/Device/EnigmaService.php +++ b/src/domain/Device/EnigmaService.php @@ -18,7 +18,7 @@ class EnigmaService { ini_set('default_socket_timeout', 0); $rEnigmas = json_decode($rData['enigmas'], true); - deleteEnigmas($rEnigmas); + EnigmaService::deleteDevices($rEnigmas); return array('status' => STATUS_SUCCESS); } @@ -88,7 +88,7 @@ class EnigmaService { $rUserArray['bouquet'][] = $rBouquet; } } - $rUserArray['bouquet'] = sortArrayByArray($rUserArray['bouquet'], array_keys(BouquetService::getOrder())); + $rUserArray['bouquet'] = AdminHelpers::sortArrayByArray($rUserArray['bouquet'], array_keys(BouquetService::getOrder())); $rUserArray['bouquet'] = '[' . implode(',', array_map('intval', $rUserArray['bouquet'])) . ']'; } @@ -111,13 +111,13 @@ class EnigmaService { $rDevices = json_decode($rData['devices_selected'], true); foreach ($rDevices as $rDevice) { - $rDeviceInfo = getEnigma($rDevice); + $rDeviceInfo = EnigmaService::getById($rDevice); if (!$rDeviceInfo) { } else { if (0 >= count($rArray)) { } else { - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (0 >= count($rPrepare['data'])) { } else { @@ -142,7 +142,7 @@ class EnigmaService { } foreach ($rUserIDs as $rUserID) { - $rPrepare = prepareArray($rUserArray); + $rPrepare = QueryHelper::prepareArray($rUserArray); if (0 >= count($rPrepare['data'])) { } else { @@ -167,13 +167,13 @@ class EnigmaService { if (InputValidator::validate('processEnigma', $rData)) { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_e2')) { - $rArray = overwriteData(getEnigma($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(EnigmaService::getById($rData['edit']), $rData); $rUser = UserRepository::getLineById($rArray['user_id']); if ($rUser) { - $rUserArray = overwriteData($rUser, $rData); + $rUserArray = AdminHelpers::overwriteData($rUser, $rData); } else { - $rUserArray = verifyPostTable('lines', $rData); + $rUserArray = QueryHelper::verifyPostTable('lines', $rData); $rUserArray['created_at'] = time(); unset($rUserArray['id']); } @@ -182,8 +182,8 @@ class EnigmaService { } } else { if (Authorization::check('adv', 'add_e2')) { - $rArray = verifyPostTable('enigma2_devices', $rData); - $rUserArray = verifyPostTable('lines', $rData); + $rArray = QueryHelper::verifyPostTable('enigma2_devices', $rData); + $rUserArray = QueryHelper::verifyPostTable('lines', $rData); $rUserArray['created_at'] = time(); unset($rArray['device_id'], $rUserArray['id']); } else { @@ -193,12 +193,12 @@ class EnigmaService { if (strlen($rUserArray['username']) != 0) { } else { - $rUserArray['username'] = generateString(32); + $rUserArray['username'] = AdminHelpers::generateString(32); } if (strlen($rUserArray['password']) != 0) { } else { - $rUserArray['password'] = generateString(32); + $rUserArray['password'] = AdminHelpers::generateString(32); } if (strlen($rData['isp_clear']) != 0) { @@ -230,7 +230,7 @@ class EnigmaService { $rArray['lock_device'] = 0; } - $rUserArray['bouquet'] = sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); + $rUserArray['bouquet'] = AdminHelpers::sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); $rUserArray['bouquet'] = '[' . implode(',', array_map('intval', $rUserArray['bouquet'])) . ']'; if (isset($rData['exp_date']) && !isset($rData['no_expire'])) { @@ -291,7 +291,7 @@ class EnigmaService { } if (0 >= $db->num_rows()) { - $rPrepare = prepareArray($rUserArray); + $rPrepare = QueryHelper::prepareArray($rUserArray); $rQuery = 'REPLACE INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; @@ -310,7 +310,7 @@ class EnigmaService { $rArray['modem_mac'] = $rArray['local_ip']; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `enigma2_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -342,4 +342,94 @@ class EnigmaService { return array('status' => STATUS_INVALID_INPUT, 'data' => $rData); } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `enigma2_devices` WHERE `device_id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return array(); + } + + $rRow = $db->get_row(); + $rRow['user'] = UserRepository::getLineById($rRow['user_id']); + + $db->query('SELECT `pair_id` FROM `lines` WHERE `id` = ?;', $rRow['user_id']); + + if ($db->num_rows() != 1) { + } else { + $rRow['paired'] = UserRepository::getLineById($rRow['user']['pair_id']); + } + + return $rRow; + } + + public static function getByUserId($rID) { + global $db; + $db->query('SELECT * FROM `enigma2_devices` WHERE `user_id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return ''; + } + + return $db->get_row(); + } + + public static function deleteDevice($rID, $rDeletePaired = false, $rCloseCons = true, $rConvert = false) { + global $db; + $rEnigma = self::getById($rID); + + if (!$rEnigma) { + return false; + } + + $db->query('DELETE FROM `enigma2_devices` WHERE `device_id` = ?;', $rID); + $db->query('DELETE FROM `enigma2_actions` WHERE `device_id` = ?;', $rID); + + if (!$rEnigma['user']) { + } else { + if ($rConvert) { + $db->query('UPDATE `lines` SET `is_e2` = 0 WHERE `id` = ?;', $rEnigma['user']['id']); + LineService::updateLineSignal($rEnigma['user']['id']); + } else { + $rCount = 0; + $db->query('SELECT `mag_id` FROM `mag_devices` WHERE `user_id` = ?;', $rEnigma['user']['id']); + $rCount += $db->num_rows(); + $db->query('SELECT `device_id` FROM `enigma2_devices` WHERE `user_id` = ?;', $rEnigma['user']['id']); + $rCount += $db->num_rows(); + + if ($rCount != 0) { + } else { + LineService::deleteLineById($rEnigma['user']['id'], $rDeletePaired, $rCloseCons); + } + } + } + + return true; + } + + public static function deleteDevices($rIDs) { + global $db; + $rIDs = AdminHelpers::confirmIDs($rIDs); + + if (0 >= count($rIDs)) { + return false; + } + + $rUserIDs = array(); + $db->query('SELECT `user_id` FROM `enigma2_devices` WHERE `device_id` IN (' . implode(',', $rIDs) . ');'); + + foreach ($db->get_rows() as $rRow) { + $rUserIDs[] = $rRow['user_id']; + } + $db->query('DELETE FROM `enigma2_devices` WHERE `device_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `enigma2_actions` WHERE `device_id` IN (' . implode(',', $rIDs) . ');'); + + if (0 >= count($rUserIDs)) { + } else { + LineRepository::deleteMany($rUserIDs); + } + + return true; + } } diff --git a/src/domain/Device/MagService.php b/src/domain/Device/MagService.php index 22fc7390..bbbacc8b 100644 --- a/src/domain/Device/MagService.php +++ b/src/domain/Device/MagService.php @@ -18,7 +18,7 @@ class MagService { ini_set('default_socket_timeout', 0); $rMags = json_decode($rData['mags'], true); - deleteMAGs($rMags); + self::deleteDevices($rMags); return array('status' => STATUS_SUCCESS); } @@ -101,7 +101,7 @@ class MagService { $rUserArray['bouquet'][] = $rBouquet; } } - $rUserArray['bouquet'] = sortArrayByArray($rUserArray['bouquet'], array_keys(BouquetService::getOrder())); + $rUserArray['bouquet'] = AdminHelpers::sortArrayByArray($rUserArray['bouquet'], array_keys(BouquetService::getOrder())); $rUserArray['bouquet'] = '[' . implode(',', array_map('intval', $rUserArray['bouquet'])) . ']'; } @@ -140,7 +140,7 @@ class MagService { $rDevices = json_decode($rData['devices_selected'], true); foreach ($rDevices as $rDevice) { - $rDeviceInfo = getMag($rDevice); + $rDeviceInfo = MagService::getById($rDevice); if ($rDeviceInfo) { if (!empty($rData['message_type'])) { @@ -148,7 +148,7 @@ class MagService { } if (count($rArray) > 0) { - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (count($rPrepare['data']) > 0) { $rPrepare['data'][] = $rDevice; @@ -169,7 +169,7 @@ class MagService { } foreach ($rUserIDs as $rUserID) { - $rPrepare = prepareArray($rUserArray); + $rPrepare = QueryHelper::prepareArray($rUserArray); if (count($rPrepare['data']) > 0) { $rPrepare['data'][] = $rUserID; @@ -193,13 +193,13 @@ class MagService { if (InputValidator::validate('processMAG', $rData)) { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_mag')) { - $rArray = overwriteData(getMag($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(MagService::getById($rData['edit']), $rData); $rUser = UserRepository::getLineById($rArray['user_id']); if ($rUser) { - $rUserArray = overwriteData($rUser, $rData); + $rUserArray = AdminHelpers::overwriteData($rUser, $rData); } else { - $rUserArray = verifyPostTable('lines', $rData); + $rUserArray = QueryHelper::verifyPostTable('lines', $rData); $rUserArray['created_at'] = time(); unset($rUserArray['id']); } @@ -208,9 +208,9 @@ class MagService { } } else { if (Authorization::check('adv', 'add_mag')) { - $rArray = verifyPostTable('mag_devices', $rData); + $rArray = QueryHelper::verifyPostTable('mag_devices', $rData); $rArray['theme_type'] = SettingsManager::getAll()['mag_default_type']; - $rUserArray = verifyPostTable('lines', $rData); + $rUserArray = QueryHelper::verifyPostTable('lines', $rData); $rUserArray['created_at'] = time(); unset($rArray['mag_id'], $rUserArray['id']); } else { @@ -219,11 +219,11 @@ class MagService { } if (strlen($rUserArray['username']) == 0) { - $rUserArray['username'] = generateString(32); + $rUserArray['username'] = AdminHelpers::generateString(32); } if (strlen($rUserArray['password']) == 0) { - $rUserArray['password'] = generateString(32); + $rUserArray['password'] = AdminHelpers::generateString(32); } if (strlen($rData['isp_clear']) == 0) { @@ -254,7 +254,7 @@ class MagService { $rArray['lock_device'] = 0; } - $rUserArray['bouquet'] = sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); + $rUserArray['bouquet'] = AdminHelpers::sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); $rUserArray['bouquet'] = '[' . implode(',', array_map('intval', $rUserArray['bouquet'])) . ']'; if (isset($rData['exp_date']) && !isset($rData['no_expire'])) { @@ -310,7 +310,7 @@ class MagService { } if (0 >= $db->num_rows()) { - $rPrepare = prepareArray($rUserArray); + $rPrepare = QueryHelper::prepareArray($rUserArray); $rQuery = 'REPLACE INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; @@ -328,7 +328,7 @@ class MagService { $rArray['sn'] = $rArray['image_version']; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `mag_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -382,7 +382,7 @@ class MagService { } if (isset($rUpdateDevice['id'])) { - $rPrepare = prepareArray($rUpdateDevice); + $rPrepare = QueryHelper::prepareArray($rUpdateDevice); $rQuery = 'REPLACE INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; $db->query($rQuery, ...$rPrepare['data']); LineService::updateLineSignal($rUpdateDevice['id']); @@ -390,4 +390,91 @@ class MagService { } } } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `mag_devices` WHERE `mag_id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return array(); + } + + $rRow = $db->get_row(); + $rRow['user'] = UserRepository::getLineById($rRow['user_id']); + $db->query('SELECT `pair_id` FROM `lines` WHERE `id` = ?;', $rRow['user_id']); + + if ($db->num_rows() != 1) { + } else { + $rRow['paired'] = UserRepository::getLineById($rRow['user']['pair_id']); + } + + return $rRow; + } + + public static function deleteDevice($rID, $rDeletePaired = false, $rCloseCons = true, $rConvert = false) { + global $db; + $rMag = self::getById($rID); + + if (!$rMag) { + return false; + } + + $db->query('DELETE FROM `mag_devices` WHERE `mag_id` = ?;', $rID); + $db->query('DELETE FROM `mag_claims` WHERE `mag_id` = ?;', $rID); + $db->query('DELETE FROM `mag_events` WHERE `mag_device_id` = ?;', $rID); + $db->query('DELETE FROM `mag_logs` WHERE `mag_id` = ?;', $rID); + + if (!$rMag['user']) { + } else { + if ($rConvert) { + $db->query('UPDATE `lines` SET `is_mag` = 0 WHERE `id` = ?;', $rMag['user']['id']); + LineService::updateLineSignal($rMag['user']['id']); + } else { + $rCount = 0; + $db->query('SELECT `mag_id` FROM `mag_devices` WHERE `user_id` = ?;', $rMag['user']['id']); + $rCount += $db->num_rows(); + $db->query('SELECT `device_id` FROM `enigma2_devices` WHERE `user_id` = ?;', $rMag['user']['id']); + $rCount += $db->num_rows(); + + if ($rCount != 0) { + } else { + LineService::deleteLineById($rMag['user']['id'], $rDeletePaired, $rCloseCons); + } + } + } + + return true; + } + + public static function deleteDevices($rIDs) { + global $db; + $rIDs = AdminHelpers::confirmIDs($rIDs); + + if (0 >= count($rIDs)) { + return false; + } + + $rUserIDs = array(); + $db->query('SELECT `user_id` FROM `mag_devices` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); + + foreach ($db->get_rows() as $rRow) { + $rUserIDs[] = $rRow['user_id']; + } + $db->query('DELETE FROM `mag_devices` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `mag_claims` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `mag_events` WHERE `mag_device_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `mag_logs` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); + + if (0 >= count($rUserIDs)) { + } else { + LineRepository::deleteMany($rUserIDs); + } + + return true; + } + + public static function resetSTB($rID) { + global $db; + $db->query("UPDATE `mag_devices` SET `ip` = '', `ver` = '', `image_version` = '', `stb_type` = '', `sn` = '', `device_id` = '', `device_id2` = '', `hw_version` = '', `token` = '' WHERE `mag_id` = ?;", $rID); + } } diff --git a/src/domain/Epg/EpgService.php b/src/domain/Epg/EpgService.php index 80110391..484f5cba 100644 --- a/src/domain/Epg/EpgService.php +++ b/src/domain/Epg/EpgService.php @@ -17,16 +17,16 @@ class EpgService { if (!Authorization::check('adv', 'epg_edit')) { exit(); } - $rArray = overwriteData(self::getById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(self::getById($rData['edit']), $rData); } else { if (!Authorization::check('adv', 'add_epg')) { exit(); } - $rArray = verifyPostTable('epg', $rData); + $rArray = QueryHelper::verifyPostTable('epg', $rData); unset($rArray['id']); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `epg`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -129,4 +129,33 @@ class EpgService { return $rData[$rProgrammeID]; } } + + public static function getAll() { + global $db; + $rReturn = array(); + $db->query('SELECT * FROM `epg` ORDER BY `id` ASC;'); + + if ($db->num_rows() > 0) { + foreach ($db->get_rows() as $rRow) { + $rReturn[intval($rRow['id'])] = $rRow; + } + } + + return $rReturn; + } + + public static function deleteEpgById($rID) { + global $db; + $rEPG = self::getById($rID); + + if (!$rEPG) { + return false; + } + + $db->query('DELETE FROM `epg` WHERE `id` = ?;', $rID); + $db->query('DELETE FROM `epg_channels` WHERE `epg_id` = ?;', $rID); + $db->query('UPDATE `streams` SET `epg_id` = null, `channel_id` = null, `epg_lang` = null WHERE `epg_id` = ?;', $rID); + + return true; + } } diff --git a/src/domain/Line/LineRepository.php b/src/domain/Line/LineRepository.php index 5a4b517f..d55f12c7 100644 --- a/src/domain/Line/LineRepository.php +++ b/src/domain/Line/LineRepository.php @@ -13,7 +13,7 @@ class LineRepository { public static function deleteMany($rIDs) { global $db; - $rIDs = confirmIDs($rIDs); + $rIDs = AdminHelpers::confirmIDs($rIDs); if (0 >= count($rIDs)) { return false; diff --git a/src/domain/Line/LineService.php b/src/domain/Line/LineService.php index 5f679ea4..7a38bd29 100644 --- a/src/domain/Line/LineService.php +++ b/src/domain/Line/LineService.php @@ -102,7 +102,7 @@ class LineService { $rArray['bouquet'][] = $rBouquet; } } - $rArray['bouquet'] = sortArrayByArray($rArray['bouquet'], array_keys(BouquetService::getOrder())); + $rArray['bouquet'] = AdminHelpers::sortArrayByArray($rArray['bouquet'], array_keys(BouquetService::getOrder())); $rArray['bouquet'] = '[' . implode(',', array_map('intval', $rArray['bouquet'])) . ']'; } @@ -112,11 +112,11 @@ class LineService { $rArray['as_number'] = $rArray['isp_desc']; } - $rUsers = confirmIDs(json_decode($rData['users_selected'], true)); + $rUsers = AdminHelpers::confirmIDs(json_decode($rData['users_selected'], true)); if (0 >= count($rUsers)) { } else { - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (0 >= count($rPrepare['data'])) { } else { @@ -143,13 +143,13 @@ class LineService { if (InputValidator::validate('processLine', $rData)) { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_user')) { - $rArray = overwriteData(UserRepository::getLineById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(UserRepository::getLineById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'add_user')) { - $rArray = verifyPostTable('lines', $rData); + $rArray = QueryHelper::verifyPostTable('lines', $rData); $rArray['created_at'] = time(); unset($rArray['id']); } else { @@ -159,12 +159,12 @@ class LineService { if (strlen($rData['username']) != 0) { } else { - $rArray['username'] = generateString(10); + $rArray['username'] = AdminHelpers::generateString(10); } if (strlen($rData['password']) != 0) { } else { - $rArray['password'] = generateString(10); + $rArray['password'] = AdminHelpers::generateString(10); } foreach (array('max_connections', 'enabled', 'admin_enabled') as $rSelection) { @@ -189,7 +189,7 @@ class LineService { $rArray['as_number'] = null; } - $rArray['bouquet'] = sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); + $rArray['bouquet'] = AdminHelpers::sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); $rArray['bouquet'] = '[' . implode(',', array_map('intval', $rArray['bouquet'])) . ']'; if (isset($rData['exp_date']) && !isset($rData['no_expire'])) { @@ -244,8 +244,8 @@ class LineService { $rArray['allowed_outputs'] = '[' . implode(',', array_map('intval', $rOutputs)) . ']'; - if (!checkExists('lines', 'username', $rArray['username'], 'id', $rData['edit'])) { - $rPrepare = prepareArray($rArray); + if (!QueryHelper::checkExists('lines', 'username', $rArray['username'], 'id', $rData['edit'])) { + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; @@ -303,4 +303,98 @@ class LineService { } return false; } + + public static function deleteLineById($rID, $rDeletePaired = false, $rCloseCons = true) { + global $db; + $rLine = UserRepository::getLineById($rID); + + if (!$rLine) { + return false; + } + + self::deleteLineSignal($rID); + $db->query('DELETE FROM `lines` WHERE `id` = ?;', $rID); + $db->query('DELETE FROM `lines_logs` WHERE `user_id` = ?;', $rID); + $db->query('UPDATE `lines_activity` SET `user_id` = 0 WHERE `user_id` = ?;', $rID); + + if (!$rCloseCons) { + } else { + if (SettingsManager::getAll()['redis_handler']) { + foreach (ConnectionTracker::getRedisConnections($rID, null, null, true, false, false) as $rConnection) { + ConnectionTracker::closeConnection($rConnection); + } + } else { + $db->query('SELECT * FROM `lines_live` WHERE `user_id` = ?;', $rID); + + foreach ($db->get_rows() as $rRow) { + ConnectionTracker::closeConnection($rRow); + } + } + } + + $db->query('SELECT `id` FROM `lines` WHERE `pair_id` = ?;', $rID); + + foreach ($db->get_rows() as $rRow) { + if ($rDeletePaired) { + self::deleteLineById($rRow['id'], true, $rCloseCons); + } else { + $db->query('UPDATE `lines` SET `pair_id` = null WHERE `id` = ?;', $rRow['id']); + self::updateLineSignal($rRow['id']); + } + } + + return true; + } + + public static function getExpiring($rLimit = 2419200) { + global $db; + global $rUserInfo; + global $rPermissions; + $rReturn = array(); + $rReports = array_map('intval', array_merge(array($rUserInfo['id']), $rPermissions['all_reports'])); + + if (0 >= count($rReports)) { + } else { + $db->query('SELECT `is_mag`, `is_e2`, `lines`.`id` AS `line_id`, `lines`.`reseller_notes`, `mag_devices`.`mag_id`, `enigma2_devices`.`device_id` AS `e2_id`, `member_id`, `username`, `password`, `exp_date`, `mag_devices`.`mac` AS `mag_mac`, `enigma2_devices`.`mac` AS `e2_mac` FROM `lines` LEFT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines`.`id` LEFT JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines`.`id` WHERE `member_id` IN (' . implode(',', $rReports) . ') AND `exp_date` IS NOT NULL AND `exp_date` >= ? AND `exp_date` < ? ORDER BY `exp_date` ASC LIMIT 250;', time(), time() + $rLimit); + + foreach ($db->get_rows() as $rRow) { + $rReturn[] = $rRow; + } + } + + return $rReturn; + } + + public static function canGenerateTrials($rUserID) { + global $db; + global $rSettings; + $rUser = UserRepository::getRegisteredUserById($rUserID); + $rPermissions = AuthRepository::getPermissions($rUser['member_group_id']); + + if ($rSettings['disable_trial']) { + return false; + } + + if (floatval($rUser['credits']) < floatval($rPermissions['minimum_trial_credits'])) { + return false; + } + + $rTotal = $rPermissions['total_allowed_gen_trials']; + + if (0 >= $rTotal) { + return false; + } + + $rTotalIn = $rPermissions['total_allowed_gen_in']; + + if ($rTotalIn == 'hours') { + $rTime = time() - intval($rTotal) * 3600; + } else { + $rTime = time() - intval($rTotal) * 3600 * 24; + } + + $db->query('SELECT COUNT(`id`) AS `count` FROM `lines` WHERE `member_id` = ? AND `created_at` >= ? AND `is_trial` = 1;', $rUser['id'], $rTime); + + return $db->get_row()['count'] < $rTotal; + } } diff --git a/src/domain/Line/PackageService.php b/src/domain/Line/PackageService.php index 7de400bd..ce963715 100644 --- a/src/domain/Line/PackageService.php +++ b/src/domain/Line/PackageService.php @@ -17,12 +17,12 @@ class PackageService { if (!Authorization::check('adv', 'edit_package')) { exit(); } - $rArray = overwriteData(getPackage($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(PackageService::getById($rData['edit']), $rData); } else { if (!Authorization::check('adv', 'add_packages')) { exit(); } - $rArray = verifyPostTable('users_packages', $rData); + $rArray = QueryHelper::verifyPostTable('users_packages', $rData); unset($rArray['id']); } @@ -39,7 +39,7 @@ class PackageService { } $rArray['groups'] = '[' . implode(',', array_map('intval', json_decode($rData['groups_selected'], true))) . ']'; - $rArray['bouquets'] = sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); + $rArray['bouquets'] = AdminHelpers::sortArrayByArray(array_values(json_decode($rData['bouquets_selected'], true)), array_keys(BouquetService::getOrder())); $rArray['bouquets'] = '[' . implode(',', array_map('intval', $rArray['bouquets'])) . ']'; if (isset($rData['output_formats'])) { @@ -50,7 +50,7 @@ class PackageService { $rArray['output_formats'] = '[' . implode(',', array_map('intval', $rArray['output_formats'])) . ']'; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `users_packages`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -61,11 +61,9 @@ class PackageService { return array('status' => STATUS_FAILURE, 'data' => $rData); } - // ──────────── Из PackageRepository ──────────── - public static function deleteById($rID) { global $db; - $rPackage = getPackage($rID); + $rPackage = self::getById($rID); if (!$rPackage) { return false; @@ -76,4 +74,60 @@ class PackageService { return true; } + + public static function getAll($rGroup = null, $rType = null) { + global $db; + $rReturn = array(); + $db->query('SELECT * FROM `users_packages` ORDER BY `id` ASC;'); + + if ($db->num_rows() > 0) { + foreach ($db->get_rows() as $rRow) { + if (isset($rGroup) && !in_array(intval($rGroup), json_decode($rRow['groups'], true))) { + } else { + if ($rType && !$rRow['is_' . $rType]) { + } else { + $rReturn[intval($rRow['id'])] = $rRow; + } + } + } + } + + return $rReturn; + } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `users_packages` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return null; + } + + return $db->get_row(); + } + + public static function checkCompatible($rIDA, $rIDB) { + $rPackageA = self::getById($rIDA); + $rPackageB = self::getById($rIDB); + $rCompatible = true; + + if (!($rPackageA && $rPackageB)) { + } else { + foreach (array('bouquets', 'output_formats') as $rKey) { + if (json_decode($rPackageA[$rKey], true) == json_decode($rPackageB[$rKey], true)) { + } else { + $rCompatible = false; + } + } + + foreach (array('is_restreamer', 'is_isplock', 'max_connections', 'force_server_id', 'forced_country', 'lock_device') as $rKey) { + if ($rPackageA[$rKey] == $rPackageB[$rKey]) { + } else { + $rCompatible = false; + } + } + } + + return $rCompatible; + } } diff --git a/src/domain/Security/BlocklistService.php b/src/domain/Security/BlocklistService.php index 5446e7c0..11aafffa 100644 --- a/src/domain/Security/BlocklistService.php +++ b/src/domain/Security/BlocklistService.php @@ -13,13 +13,13 @@ class BlocklistService { public static function blockIP($rData) { global $db; - if (!validateCIDR($rData['ip'])) { + if (!AdminHelpers::validateCIDR($rData['ip'])) { return array('status' => STATUS_INVALID_IP, 'data' => $rData); } $rArray = array('ip' => $rData['ip'], 'notes' => $rData['notes'], 'date' => time()); touch(FLOOD_TMP_PATH . 'block_' . $rData['ip']); - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `blocked_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -36,12 +36,12 @@ class BlocklistService { if (!Authorization::check('adv', 'block_isps')) { exit(); } - $rArray = overwriteData(getISP($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(BlocklistService::getISPById($rData['edit']), $rData); } else { if (!Authorization::check('adv', 'block_isps')) { exit(); } - $rArray = verifyPostTable('blocked_isps', $rData); + $rArray = QueryHelper::verifyPostTable('blocked_isps', $rData); unset($rArray['id']); } @@ -55,7 +55,7 @@ class BlocklistService { return array('status' => STATUS_INVALID_NAME, 'data' => $rData); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `blocked_isps`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -69,9 +69,9 @@ class BlocklistService { public static function processRTMPIP($rData) { global $db; if (isset($rData['edit'])) { - $rArray = overwriteData(getRTMPIP($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(BlocklistService::getRTMPIPById($rData['edit']), $rData); } else { - $rArray = verifyPostTable('rtmp_ips', $rData); + $rArray = QueryHelper::verifyPostTable('rtmp_ips', $rData); unset($rArray['id']); } @@ -87,15 +87,15 @@ class BlocklistService { return array('status' => STATUS_INVALID_IP, 'data' => $rData); } - if (checkExists('rtmp_ips', 'ip', $rData['ip'], 'id', $rArray['id'])) { + if (QueryHelper::checkExists('rtmp_ips', 'ip', $rData['ip'], 'id', $rArray['id'])) { return array('status' => STATUS_EXISTS_IP, 'data' => $rData); } if (strlen($rData['password']) == 0) { - $rArray['password'] = generateString(16); + $rArray['password'] = AdminHelpers::generateString(16); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `rtmp_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -109,9 +109,9 @@ class BlocklistService { public static function processUA($rData) { global $db; if (isset($rData['edit'])) { - $rArray = overwriteData(getUserAgent($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(BlocklistService::getUserAgentById($rData['edit']), $rData); } else { - $rArray = verifyPostTable('blocked_uas', $rData); + $rArray = QueryHelper::verifyPostTable('blocked_uas', $rData); unset($rArray['id']); } @@ -121,7 +121,7 @@ class BlocklistService { $rArray['exact_match'] = false; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `blocked_uas`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -333,4 +333,140 @@ class BlocklistService { } return $rReturn; } + + public static function deleteBlockedIP($rID) { + global $db; + $db->query('SELECT `id`, `ip` FROM `blocked_ips` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $rRow = $db->get_row(); + $db->query('DELETE FROM `blocked_ips` WHERE `id` = ?;', $rID); + + if (!file_exists(FLOOD_TMP_PATH . 'block_' . $rRow['ip'])) { + } else { + unlink(FLOOD_TMP_PATH . 'block_' . $rRow['ip']); + } + + return true; + } + + public static function deleteBlockedISP($rID) { + global $db; + $db->query('SELECT `id` FROM `blocked_isps` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $db->query('DELETE FROM `blocked_isps` WHERE `id` = ?;', $rID); + + return true; + } + + public static function deleteBlockedUA($rID) { + global $db; + $db->query('SELECT `id` FROM `blocked_uas` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $db->query('DELETE FROM `blocked_uas` WHERE `id` = ?;', $rID); + + return true; + } + + public static function flushIPs() { + global $db; + global $rServers; + global $rProxyServers; + $db->query('TRUNCATE `blocked_ips`;'); + shell_exec('rm ' . FLOOD_TMP_PATH . 'block_*'); + + foreach ($rServers as $rServer) { + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServer['id'], time(), json_encode(array('action' => 'flush'))); + } + + foreach ($rProxyServers as $rServer) { + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServer['id'], time(), json_encode(array('action' => 'flush'))); + } + + return true; + } + + public static function getAllUserAgents() { + global $db; + $rReturn = array(); + $db->query('SELECT * FROM `blocked_uas` ORDER BY `id` ASC;'); + + if (0 >= $db->num_rows()) { + } else { + foreach ($db->get_rows() as $rRow) { + $rReturn[] = $rRow; + } + } + + return $rReturn; + } + + public static function getAllISPs() { + global $db; + $rReturn = array(); + $db->query('SELECT * FROM `blocked_isps` ORDER BY `id` ASC;'); + + if (0 >= $db->num_rows()) { + } else { + foreach ($db->get_rows() as $rRow) { + $rReturn[] = $rRow; + } + } + + return $rReturn; + } + + public static function getUserAgentById($rID) { + global $db; + $db->query('SELECT * FROM `blocked_uas` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + } else { + return $db->get_row(); + } + } + + public static function getISPById($rID) { + global $db; + $db->query('SELECT * FROM `blocked_isps` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + } else { + return $db->get_row(); + } + } + + public static function deleteRTMPIP($rID) { + global $db; + $db->query('SELECT `id` FROM `rtmp_ips` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $db->query('DELETE FROM `rtmp_ips` WHERE `id` = ?;', $rID); + + return true; + } + + public static function getRTMPIPById($rID) { + global $db; + $db->query('SELECT * FROM `rtmp_ips` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + } else { + return $db->get_row(); + } + } } diff --git a/src/domain/Server/ServerRepository.php b/src/domain/Server/ServerRepository.php index b6fa7140..58f44771 100644 --- a/src/domain/Server/ServerRepository.php +++ b/src/domain/Server/ServerRepository.php @@ -156,7 +156,7 @@ class ServerRepository { public static function getFreeSpace($rServerID) { $rReturn = array(); - $rLines = json_decode(systemapirequest($rServerID, array('action' => 'get_free_space')), true); + $rLines = json_decode(ApiClient::systemRequest($rServerID, array('action' => 'get_free_space')), true); if (!is_array($rLines)) { return $rReturn; @@ -177,7 +177,7 @@ class ServerRepository { } public static function getStreamsRamdisk($rServerID) { - $response = systemapirequest($rServerID, array('action' => 'streams_ramdisk')); + $response = ApiClient::systemRequest($rServerID, array('action' => 'streams_ramdisk')); $rReturn = json_decode($response, true); if (!is_array($rReturn)) { @@ -192,11 +192,11 @@ class ServerRepository { } public static function killPID($rServerID, $rPID) { - systemapirequest($rServerID, array('action' => 'kill_pid', 'pid' => $rPID)); + ApiClient::systemRequest($rServerID, array('action' => 'kill_pid', 'pid' => $rPID)); } public static function getRTMPStats($rServerID) { - return json_decode(systemapirequest($rServerID, array('action' => 'rtmp_stats')), true); + return json_decode(ApiClient::systemRequest($rServerID, array('action' => 'rtmp_stats')), true); } public static function checkSource($rServers, $rFFProbe, $rServerID, $rFilename) { @@ -220,20 +220,20 @@ class ServerRepository { } public static function freeTemp($rServerID) { - systemapirequest($rServerID, array('action' => 'free_temp')); + ApiClient::systemRequest($rServerID, array('action' => 'free_temp')); } public static function freeStreams($rServerID) { - systemapirequest($rServerID, array('action' => 'free_streams')); + ApiClient::systemRequest($rServerID, array('action' => 'free_streams')); } public static function probeSource($rServerID, $rURL, $rUserAgent = null, $rProxy = null, $rCookies = null, $rHeaders = null) { - return json_decode(systemapirequest($rServerID, array('action' => 'probe', 'url' => $rURL, 'user_agent' => $rUserAgent, 'http_proxy' => $rProxy, 'cookies' => $rCookies, 'headers' => $rHeaders), 30), true); + return json_decode(ApiClient::systemRequest($rServerID, array('action' => 'probe', 'url' => $rURL, 'user_agent' => $rUserAgent, 'http_proxy' => $rProxy, 'cookies' => $rCookies, 'headers' => $rHeaders), 30), true); } public static function deleteById($rID, $rReplaceWith = null) { global $db, $rSettings; - $rServer = getStreamingServersByID($rID); + $rServer = ServerRepository::getById($rID); if (!$rServer || $rServer['is_main']) { return false; @@ -391,4 +391,15 @@ class ServerRepository { return $rServerURL; } } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `servers` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return false; + } + + return $db->get_row(); + } } diff --git a/src/domain/Server/ServerService.php b/src/domain/Server/ServerService.php index 18c30cbc..da32f646 100644 --- a/src/domain/Server/ServerService.php +++ b/src/domain/Server/ServerService.php @@ -17,12 +17,12 @@ class ServerService { exit(); } - $rServer = getStreamingServersByID($rData['edit']); + $rServer = ServerRepository::getById($rData['edit']); if (!$rServer) { return array('status' => STATUS_INVALID_INPUT, 'data' => $rData); } - $rArray = verifyPostTable('servers', $rData, true); + $rArray = QueryHelper::verifyPostTable('servers', $rData, true); $rPorts = array('http' => array(), 'https' => array()); if (!isset($rData['http_broadcast_ports']) || !is_array($rData['http_broadcast_ports'])) { @@ -109,7 +109,7 @@ class ServerService { } $rArray['total_services'] = $rData['total_services']; - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rPrepare['data'][] = $rData['edit']; $rQuery = 'UPDATE `servers` SET ' . $rPrepare['update'] . ' WHERE `id` = ?;'; @@ -129,16 +129,16 @@ class ServerService { $rPorts['https'][] = intval($rPort); } } - changePort($rInsertID, 0, $rPorts['http'], false); - changePort($rInsertID, 1, $rPorts['https'], false); - changePort($rInsertID, 2, array($rArray['rtmp_port']), false); - setServices($rInsertID, intval($rArray['total_services']), true); + ServerService::changePort($rInsertID, 0, $rPorts['http'], false); + ServerService::changePort($rInsertID, 1, $rPorts['https'], false); + ServerService::changePort($rInsertID, 2, array($rArray['rtmp_port']), false); + ServerService::setServices($rInsertID, intval($rArray['total_services']), true); if (!empty($rArray['governor'])) { - setGovernor($rInsertID, $rArray['governor']); + ServerService::setGovernor($rInsertID, $rArray['governor']); } if (!empty($rArray['sysctl'])) { - setSysctl($rInsertID, $rArray['sysctl']); + ServerService::setSysctl($rInsertID, $rArray['sysctl']); } if (file_exists(CACHE_TMP_PATH . 'servers')) { unlink(CACHE_TMP_PATH . 'servers'); @@ -169,7 +169,7 @@ class ServerService { exit(); } - $rArray = overwriteData(getStreamingServersByID($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(ServerRepository::getById($rData['edit']), $rData); foreach (array('enable_https', 'random_ip', 'enable_geoip', 'enabled') as $rKey) { $rArray[$rKey] = isset($rData[$rKey]); } @@ -192,12 +192,12 @@ class ServerService { if (strlen($rData['server_ip']) == 0 || !filter_var($rData['server_ip'], FILTER_VALIDATE_IP)) { return array('status' => STATUS_INVALID_IP, 'data' => $rData); } - if (checkExists('servers', 'server_ip', $rData['server_ip'], 'id', $rArray['id'])) { + if (QueryHelper::checkExists('servers', 'server_ip', $rData['server_ip'], 'id', $rArray['id'])) { return array('status' => STATUS_EXISTS_IP, 'data' => $rData); } $rArray['server_type'] = 1; - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -252,7 +252,7 @@ class ServerService { return array('status' => STATUS_SUCCESS, 'data' => array('insert_id' => $rServer['id'])); } - $rArray = verifyPostTable('servers', $rData); + $rArray = QueryHelper::verifyPostTable('servers', $rData); $rArray['status'] = 3; unset($rArray['id']); @@ -268,7 +268,7 @@ class ServerService { } $rArray['network_interface'] = 'auto'; - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'INSERT INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -301,4 +301,52 @@ class ServerService { return array('status' => STATUS_SUCCESS); } + + public static function changePort($rServerID, $rType, $rPorts, $rReload = false) { + global $db; + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_port', 'type' => intval($rType), 'ports' => $rPorts, 'reload' => $rReload))); + } + + public static function setServices($rServerID, $rNumServices, $rReload = true) { + global $db; + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_services', 'count' => intval($rNumServices), 'reload' => $rReload))); + } + + public static function setGovernor($rServerID, $rGovernor) { + global $db; + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_governor', 'data' => $rGovernor))); + } + + public static function setSysctl($rServerID, $rSysCtl) { + global $db; + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_sysctl', 'data' => $rSysCtl))); + } + + public static function restoreImages() { + global $db; + global $rServers; + foreach (array_keys($rServers) as $rServerID) { + if (!$rServers[$rServerID]['server_online']) { + } else { + ApiClient::systemRequest($rServerID, array('action' => 'restore_images')); + } + } + + return true; + } + + public static function killPlexSync() { + global $db; + $db->query("SELECT DISTINCT(`server_id`) AS `server_id` FROM `watch_folders` WHERE `active` = 1 AND `type` = 'plex';"); + + global $rServers; + foreach ($db->get_rows() as $rRow) { + if (!$rServers[$rRow['server_id']]['server_online']) { + } else { + ApiClient::systemRequest($rRow['server_id'], array('action' => 'kill_plex')); + } + } + + return true; + } } diff --git a/src/domain/Server/SettingsService.php b/src/domain/Server/SettingsService.php index e135e130..a3c699fd 100644 --- a/src/domain/Server/SettingsService.php +++ b/src/domain/Server/SettingsService.php @@ -18,7 +18,7 @@ class SettingsService { unset($rData[$rKey]); } - $rArray = verifyPostTable('settings', $rData, true); + $rArray = QueryHelper::verifyPostTable('settings', $rData, true); foreach (array('php_loopback', 'restreamer_bypass_proxy', 'request_prebuffer', 'modal_edit', 'group_buttons', 'enable_search', 'on_demand_checker', 'ondemand_balance_equal', 'disable_mag_token', 'allow_cdn_access', 'dts_legacy_ffmpeg', 'mag_load_all_channels', 'disable_xmltv_restreamer', 'disable_playlist_restreamer', 'ffmpeg_warnings', 'reseller_ssl_domain', 'extract_subtitles', 'show_category_duplicates', 'vod_sort_newest', 'header_stats', 'mag_keep_extension', 'keep_protocol', 'read_native_hls', 'player_allow_playlist', 'player_allow_bouquet', 'player_hide_incompatible', 'player_allow_hevc', 'force_epg_timezone', 'check_vod', 'ignore_keyframes', 'save_login_logs', 'save_restart_logs', 'mag_legacy_redirect', 'restrict_playlists', 'monitor_connection_status', 'kill_rogue_ffmpeg', 'show_images', 'on_demand_instant_off', 'on_demand_failure_exit', 'playlist_from_mysql', 'ignore_invalid_users', 'legacy_mag_auth', 'ministra_allow_blank', 'block_proxies', 'block_streaming_servers', 'ip_subnet_match', 'debug_show_errors', 'enable_debug_stalker', 'restart_php_fpm', 'restream_deny_unauthorised', 'api_probe', 'legacy_panel_api', 'hide_failures', 'verify_host', 'encrypt_playlist', 'encrypt_playlist_restreamer', 'mag_disable_ssl', 'legacy_get', 'legacy_xmltv', 'save_closed_connection', 'show_tickets', 'stream_logs_save', 'client_logs_save', 'streams_grouped', 'cloudflare', 'cleanup', 'dashboard_stats', 'dashboard_status', 'dashboard_map', 'dashboard_display_alt', 'recaptcha_enable', 'ip_logout', 'disable_player_api', 'disable_playlist', 'disable_xmltv', 'disable_enigma2', 'disable_ministra', 'enable_isp_lock', 'block_svp', 'disable_ts', 'disable_ts_allow_restream', 'disable_hls', 'disable_hls_allow_restream', 'disable_rtmp', 'disable_rtmp_allow_restream', 'case_sensitive_line', 'county_override_1st', 'disallow_2nd_ip_con', 'use_mdomain_in_lists', 'encrypt_hls', 'disallow_empty_user_agents', 'detect_restream_block_user', 'download_images', 'api_redirect', 'use_buffer', 'audio_restart_loss', 'show_isps', 'priority_backup', 'rtmp_random', 'show_connected_video', 'show_not_on_air_video', 'show_banned_video', 'show_expired_video', 'show_expiring_video', 'show_all_category_mag', 'always_enabled_subtitles', 'enable_connection_problem_indication', 'show_tv_channel_logo', 'show_channel_logo_in_preview', 'disable_trial', 'restrict_same_ip', 'js_navigate') as $rSetting) { if (isset($rData[$rSetting])) { @@ -58,14 +58,20 @@ class SettingsService { $rArray['search_items'] = 1; } - $rPrepare = prepareArray($rArray); + if (isset($rArray['language']) && class_exists('Translator', false)) { + if (!in_array($rArray['language'], Translator::available(), true)) { + $rArray['language'] = 'en'; + } + } + + $rPrepare = QueryHelper::prepareArray($rArray); if (count($rPrepare['data']) <= 0) { return array('status' => STATUS_FAILURE); } $rQuery = 'UPDATE `settings` SET ' . $rPrepare['update'] . ';'; if ($db->query($rQuery, ...$rPrepare['data'])) { - clearSettingsCache(); + SettingsManager::clearCache(); return array('status' => STATUS_SUCCESS); } @@ -74,7 +80,7 @@ class SettingsService { public static function editBackup($rData) { global $db; - $rArray = verifyPostTable('settings', $rData, true); + $rArray = QueryHelper::verifyPostTable('settings', $rData, true); foreach (array('dropbox_remote') as $rSetting) { if (isset($rData[$rSetting])) { @@ -92,14 +98,14 @@ class SettingsService { $rArray['allowed_stb_types'] = array(); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (count($rPrepare['data']) <= 0) { return array('status' => STATUS_FAILURE); } $rQuery = 'UPDATE `settings` SET ' . $rPrepare['update'] . ';'; if ($db->query($rQuery, ...$rPrepare['data'])) { - clearSettingsCache(); + SettingsManager::clearCache(); return array('status' => STATUS_SUCCESS); } @@ -133,7 +139,7 @@ class SettingsService { unlink(TMP_PATH . 'crontab'); } - clearSettingsCache(); + SettingsManager::clearCache(); return array('status' => STATUS_SUCCESS); } diff --git a/src/domain/Stream/CategoryService.php b/src/domain/Stream/CategoryService.php index 100cfb00..8c1ff6fa 100644 --- a/src/domain/Stream/CategoryService.php +++ b/src/domain/Stream/CategoryService.php @@ -28,9 +28,9 @@ class CategoryService { public static function process($rData) { global $db; if (isset($rData['edit'])) { - $rArray = overwriteData(getCategory($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(CategoryService::getById($rData['edit']), $rData); } else { - $rArray = verifyPostTable('streams_categories', $rData); + $rArray = QueryHelper::verifyPostTable('streams_categories', $rData); $rArray['cat_order'] = 99; unset($rArray['id']); } @@ -41,7 +41,7 @@ class CategoryService { $rArray['is_adult'] = 0; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -118,4 +118,54 @@ class CategoryService { } return $rReturn; } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `streams_categories` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return false; + } + + return $db->get_row(); + } + + public static function deleteById($rID) { + global $db; + $rCategory = self::getById($rID); + + if (!$rCategory) { + return false; + } + + $db->query("SELECT `id`, `category_id` FROM `streams` WHERE JSON_CONTAINS(`category_id`, ?, '\$');", $rID); + + foreach ($db->get_rows() as $rRow) { + $rRow['category_id'] = json_decode($rRow['category_id'], true); + + if (($rKey = array_search($rID, $rRow['category_id'])) === false) { + } else { + unset($rRow['category_id'][$rKey]); + } + + $db->query("UPDATE `streams` SET `category_id` = ? WHERE `id` = ?;", '[' . implode(',', array_map('intval', $rRow['category_id'])) . ']', $rRow['id']); + } + $db->query("SELECT `id`, `category_id` FROM `streams_series` WHERE JSON_CONTAINS(`category_id`, ?, '\$');", $rID); + + foreach ($db->get_rows() as $rRow) { + $rRow['category_id'] = json_decode($rRow['category_id'], true); + + if (($rKey = array_search($rID, $rRow['category_id'])) === false) { + } else { + unset($rRow['category_id'][$rKey]); + } + + $db->query("UPDATE `streams_series` SET `category_id` = ? WHERE `id` = ?;", '[' . implode(',', array_map('intval', $rRow['category_id'])) . ']', $rRow['id']); + } + $db->query('DELETE FROM `streams_categories` WHERE `id` = ?;', $rID); + $db->query('UPDATE `watch_folders` SET `category_id` = null WHERE `category_id` = ?;', $rID); + $db->query('UPDATE `watch_folders` SET `fb_category_id` = null WHERE `fb_category_id` = ?;', $rID); + + return true; + } } diff --git a/src/domain/Stream/ChannelService.php b/src/domain/Stream/ChannelService.php index c1bae188..18ff79e9 100644 --- a/src/domain/Stream/ChannelService.php +++ b/src/domain/Stream/ChannelService.php @@ -15,13 +15,13 @@ class ChannelService { global $db, $rSettings; if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_cchannel')) { - $rArray = overwriteData(StreamRepository::getById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(StreamRepository::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'create_channel')) { - $rArray = verifyPostTable('streams', $rData); + $rArray = QueryHelper::verifyPostTable('streams', $rData); $rArray['type'] = 3; $rArray['added'] = time(); unset($rArray['id']); @@ -74,7 +74,7 @@ class ChannelService { $rBouquetCreate = array(); foreach (json_decode($rData['bouquet_create_list'], true) as $rBouquet) { - $rPrepare = prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); + $rPrepare = QueryHelper::prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -86,7 +86,7 @@ class ChannelService { $rCategoryCreate = array(); foreach (json_decode($rData['category_create_list'], true) as $rCategory) { - $rPrepare = prepareArray(array('category_type' => 'live', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); + $rPrepare = QueryHelper::prepareArray(array('category_type' => 'live', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -130,7 +130,7 @@ class ChannelService { $rArray['order'] = StreamRepository::getNextOrder(); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -173,22 +173,22 @@ class ChannelService { foreach ($rStreamExists as $rServerID => $rDBID) { if (in_array($rServerID, $rStreamsAdded)) { } else { - deleteStream($rInsertID, $rServerID, false, false); + StreamRepository::deleteStream($rInsertID, $rServerID, false, false); } } if ($rReencode) { - APIRequest(array('action' => 'stream', 'sub' => 'stop', 'stream_ids' => array($rInsertID))); + ApiClient::request(array('action' => 'stream', 'sub' => 'stop', 'stream_ids' => array($rInsertID))); $db->query("UPDATE `streams_servers` SET `pids_create_channel` = '[]', `cchannel_rsources` = '[]' WHERE `stream_id` = ?;", $rInsertID); StreamProcess::queueChannel($rInsertID); } if ($rRestart) { - APIRequest(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array($rInsertID))); + ApiClient::request(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array($rInsertID))); } foreach ($rBouquets as $rBouquet) { - addToBouquet('stream', $rBouquet, $rInsertID); + BouquetService::addItems('stream', $rBouquet, $rInsertID); } if (!isset($rData['edit'])) { @@ -196,7 +196,7 @@ class ChannelService { foreach (BouquetService::getAllSimple() as $rBouquet) { if (in_array($rBouquet['id'], $rBouquets)) { } else { - removeFromBouquet('stream', $rBouquet['id'], $rInsertID); + BouquetService::removeItems('stream', $rBouquet['id'], $rInsertID); } } } @@ -299,7 +299,7 @@ class ChannelService { $rArray['category_id'] = '[' . implode(',', $rCategories) . ']'; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (0 >= count($rPrepare['data'])) { } else { @@ -398,15 +398,15 @@ class ChannelService { } foreach ($rDeleteServers as $rServerID => $rDeleteIDs) { - deleteStreamsByServer($rDeleteIDs, $rServerID, false); + StreamRepository::deleteStreamsByServer($rDeleteIDs, $rServerID, false); } foreach ($rAddBouquet as $rBouquetID => $rAddIDs) { - addToBouquet('stream', $rBouquetID, $rAddIDs); + BouquetService::addItems('stream', $rBouquetID, $rAddIDs); } foreach ($rDelBouquet as $rBouquetID => $rRemIDs) { - removeFromBouquet('stream', $rBouquetID, $rRemIDs); + BouquetService::removeItems('stream', $rBouquetID, $rRemIDs); } if (empty($rAddQuery)) { @@ -426,11 +426,11 @@ class ChannelService { $db->query('INSERT INTO `queue`(`type`, `stream_id`, `server_id`, `added`) VALUES ' . $rEncQuery . ';'); } - APIRequest(array('action' => 'stream', 'sub' => 'stop', 'stream_ids' => array_values($rStreamIDs))); + ApiClient::request(array('action' => 'stream', 'sub' => 'stop', 'stream_ids' => array_values($rStreamIDs))); } else { if (!isset($rData['restart_on_edit'])) { } else { - APIRequest(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array_values($rStreamIDs))); + ApiClient::request(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array_values($rStreamIDs))); } } } diff --git a/src/domain/Stream/ConnectionTracker.php b/src/domain/Stream/ConnectionTracker.php index c2500977..3cc0b153 100644 --- a/src/domain/Stream/ConnectionTracker.php +++ b/src/domain/Stream/ConnectionTracker.php @@ -551,4 +551,37 @@ class ConnectionTracker { return null; } } + + public static function getLiveConnections($rServerID, $rProxy = false) { + global $db; + + if (SettingsManager::getAll()['redis_handler']) { + $rCount = 0; + + if ($rProxy) { + $rParentIDs = ServerRepository::getAll()[$rServerID]['parent_id']; + + foreach ($rParentIDs as $rParentID) { + foreach (self::getRedisConnections(null, $rParentID, null, true, false, false) as $rConnection) { + if ($rConnection['proxy_id'] != $rServerID) { + } else { + $rCount++; + } + } + } + } else { + list($rCount) = self::getRedisConnections(null, $rServerID, null, true, true, false); + } + + return $rCount; + } else { + if ($rProxy) { + $db->query('SELECT COUNT(*) AS `count` FROM `lines_live` WHERE `proxy_id` = ? AND `hls_end` = 0;', $rServerID); + } else { + $db->query('SELECT COUNT(*) AS `count` FROM `lines_live` WHERE `server_id` = ? AND `hls_end` = 0;', $rServerID); + } + + return $db->get_row()['count']; + } + } } diff --git a/src/domain/Stream/ProfileService.php b/src/domain/Stream/ProfileService.php index b4c54559..38caf643 100644 --- a/src/domain/Stream/ProfileService.php +++ b/src/domain/Stream/ProfileService.php @@ -313,7 +313,7 @@ class ProfileService { $rArray['profile_id'] = $rData['edit']; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `profiles`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { diff --git a/src/domain/Stream/ProviderService.php b/src/domain/Stream/ProviderService.php index fcb95bf7..71707125 100644 --- a/src/domain/Stream/ProviderService.php +++ b/src/domain/Stream/ProviderService.php @@ -16,13 +16,13 @@ class ProviderService { if (InputValidator::validate('processProvider', $rData)) { if (isset($rData['edit'])) { if (Authorization::check('adv', 'streams')) { - $rArray = overwriteData(getStreamProvider($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(ProviderService::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'streams')) { - $rArray = verifyPostTable('providers', $rData); + $rArray = QueryHelper::verifyPostTable('providers', $rData); unset($rArray['id']); } else { exit(); @@ -44,7 +44,7 @@ class ProviderService { } if (0 >= $db->num_rows()) { - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `providers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -60,4 +60,43 @@ class ProviderService { return array('status' => STATUS_INVALID_INPUT, 'data' => $rData); } } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `providers` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return null; + } + + return $db->get_row(); + } + + public static function getAll() { + global $db; + $rReturn = array(); + $db->query('SELECT * FROM `providers` ORDER BY `last_changed` DESC;'); + + if ($db->num_rows() > 0) { + foreach ($db->get_rows() as $rRow) { + $rReturn[] = $rRow; + } + } + + return $rReturn; + } + + public static function deleteById($rID) { + global $db; + $rProvider = self::getById($rID); + + if (!$rProvider) { + return false; + } + + $db->query('DELETE FROM `providers` WHERE `id` = ?;', $rID); + $db->query('DELETE FROM `providers_streams` WHERE `provider_id` = ?;', $rID); + + return true; + } } diff --git a/src/domain/Stream/RadioService.php b/src/domain/Stream/RadioService.php index 136b04fc..14fb53b1 100644 --- a/src/domain/Stream/RadioService.php +++ b/src/domain/Stream/RadioService.php @@ -16,13 +16,13 @@ class RadioService { if (InputValidator::validate('processRadio', $rData)) { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_radio')) { - $rArray = overwriteData(StreamRepository::getById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(StreamRepository::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'add_radio')) { - $rArray = verifyPostTable('streams', $rData); + $rArray = QueryHelper::verifyPostTable('streams', $rData); $rArray['type'] = 4; $rArray['added'] = time(); unset($rArray['id']); @@ -70,7 +70,7 @@ class RadioService { $rBouquetCreate = array(); foreach (json_decode($rData['bouquet_create_list'] ?? '[]', true) ?: [] as $rBouquet) { - $rPrepare = prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); + $rPrepare = QueryHelper::prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -82,7 +82,7 @@ class RadioService { $rCategoryCreate = array(); foreach (json_decode($rData['category_create_list'] ?? '[]', true) ?: [] as $rCategory) { - $rPrepare = prepareArray(array('category_type' => 'radio', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); + $rPrepare = QueryHelper::prepareArray(array('category_type' => 'radio', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -134,7 +134,7 @@ class RadioService { $rImportArray['order'] = StreamRepository::getNextOrder(); } - $rPrepare = prepareArray($rImportArray); + $rPrepare = QueryHelper::prepareArray($rImportArray); $rQuery = 'REPLACE INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -177,7 +177,7 @@ class RadioService { foreach ($rStationExists as $rServerID => $rDBID) { if (in_array($rServerID, $rStreamsAdded)) { } else { - deleteStream($rInsertID, $rServerID, false, false); + StreamRepository::deleteStream($rInsertID, $rServerID, false, false); } } $db->query('DELETE FROM `streams_options` WHERE `stream_id` = ?;', $rInsertID); @@ -212,11 +212,11 @@ class RadioService { if (!$rRestart) { } else { - APIRequest(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array($rInsertID))); + ApiClient::request(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array($rInsertID))); } foreach ($rBouquets as $rBouquet) { - addToBouquet('radio', $rBouquet, $rInsertID); + BouquetService::addItems('radio', $rBouquet, $rInsertID); } if (!isset($rData['edit'])) { @@ -224,7 +224,7 @@ class RadioService { foreach (BouquetService::getAllSimple() as $rBouquet) { if (in_array($rBouquet['id'], $rBouquets)) { } else { - removeFromBouquet('radio', $rBouquet['id'], $rInsertID); + BouquetService::removeItems('radio', $rBouquet['id'], $rInsertID); } } } @@ -334,7 +334,7 @@ class RadioService { $rArray['category_id'] = '[' . implode(',', $rCategories) . ']'; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (0 >= count($rPrepare['data'])) { } else { @@ -421,15 +421,15 @@ class RadioService { } foreach ($rDeleteServers as $rServerID => $rDeleteIDs) { - deleteStreamsByServer($rDeleteIDs, $rServerID, false); + StreamRepository::deleteStreamsByServer($rDeleteIDs, $rServerID, false); } foreach ($rAddBouquet as $rBouquetID => $rAddIDs) { - addToBouquet('radio', $rBouquetID, $rAddIDs); + BouquetService::addItems('radio', $rBouquetID, $rAddIDs); } foreach ($rDelBouquet as $rBouquetID => $rRemIDs) { - removeFromBouquet('radio', $rBouquetID, $rRemIDs); + BouquetService::removeItems('radio', $rBouquetID, $rRemIDs); } if (empty($rAddQuery)) { @@ -442,7 +442,7 @@ class RadioService { if (!isset($rData['restart_on_edit'])) { } else { - APIRequest(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array_values($rStreamIDs))); + ApiClient::request(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array_values($rStreamIDs))); } } @@ -460,7 +460,7 @@ class RadioService { if (InputValidator::validate('massDeleteStations', $rData)) { $rStreams = json_decode($rData['radios'], true); - deleteStreams($rStreams, false); + StreamRepository::deleteStreams($rStreams, false); return array('status' => STATUS_SUCCESS); } diff --git a/src/domain/Stream/StreamConfigRepository.php b/src/domain/Stream/StreamConfigRepository.php index adea8d12..b3b4fdfc 100644 --- a/src/domain/Stream/StreamConfigRepository.php +++ b/src/domain/Stream/StreamConfigRepository.php @@ -44,4 +44,30 @@ class StreamConfigRepository { return $rReturn; } + + public static function getTranscodeProfile($rID) { + global $db; + $db->query('SELECT * FROM `profiles` WHERE `profile_id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return null; + } + + return $db->get_row(); + } + + public static function deleteProfile($rID) { + global $db; + $rProfile = self::getTranscodeProfile($rID); + + if (!$rProfile) { + return false; + } + + $db->query('DELETE FROM `profiles` WHERE `profile_id` = ?;', $rID); + $db->query('UPDATE `streams` SET `transcode_profile_id` = 0 WHERE `transcode_profile_id` = ?;', $rID); + $db->query('UPDATE `watch_folders` SET `transcode_profile_id` = 0 WHERE `transcode_profile_id` = ?;', $rID); + + return true; + } } diff --git a/src/domain/Stream/StreamRepository.php b/src/domain/Stream/StreamRepository.php index af92fff5..ac9f457b 100644 --- a/src/domain/Stream/StreamRepository.php +++ b/src/domain/Stream/StreamRepository.php @@ -147,6 +147,171 @@ class StreamRepository { return 0; } + return intval($db->get_row()['order']) + 1; } + + public static function getEncodeErrors($rID) { + global $db; + $rErrors = array(); + $db->query('SELECT `server_id`, `error` FROM `streams_errors` WHERE `stream_id` = ?;', $rID); + + foreach ($db->get_rows() as $rRow) { + $rErrors[intval($rRow['server_id'])] = $rRow['error']; + } + + return $rErrors; + } + + public static function getSelections($rSources) { + global $db; + $rReturn = array(); + + foreach ($rSources as $rSource) { + $db->query("SELECT `id` FROM `streams` WHERE `type` IN (2,5) AND `stream_source` LIKE ? ESCAPE '|' LIMIT 1;", '%' . str_replace('/', '\\/', $rSource) . '"%'); + + if ($db->num_rows() != 1) { + } else { + $rReturn[] = intval($db->get_row()['id']); + } + } + + return $rReturn; + } + + public static function deleteStream($rID, $rServerID = -1, $rDeleteFiles = true, $f2d619cb38696890 = true) { + global $db; + $db->query('SELECT `id`, `type` FROM `streams` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $rType = $db->get_row()['type']; + $rRemaining = 0; + + if ($rServerID == -1) { + } else { + $db->query('SELECT `server_stream_id` FROM `streams_servers` WHERE `stream_id` = ? AND `server_id` <> ?;', $rID, $rServerID); + $rRemaining = $db->num_rows(); + } + + if ($rRemaining == 0 && $f2d619cb38696890) { + $db->query('DELETE FROM `lines_logs` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `mag_claims` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `streams` WHERE `id` = ?;', $rID); + $db->query('DELETE FROM `streams_episodes` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `streams_errors` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `streams_logs` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `streams_options` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `streams_stats` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `watch_refresh` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `watch_logs` WHERE `stream_id` = ?;', $rID); + $db->query('DELETE FROM `recordings` WHERE `created_id` = ? OR `stream_id` = ?;', $rID, $rID); + $db->query('UPDATE `lines_activity` SET `stream_id` = 0 WHERE `stream_id` = ?;', $rID); + $db->query('SELECT `server_id` FROM `streams_servers` WHERE `stream_id` = ?;', $rID); + $rServerIDs = array(); + + foreach ($db->get_rows() as $rRow) { + $rServerIDs[] = $rRow['server_id']; + } + + if (!($rDeleteFiles && 0 < count($rServerIDs) && in_array($rType, array(2, 5)))) { + } else { + MovieService::deleteFile($rServerIDs, $rID); + } + + $db->query('DELETE FROM `streams_servers` WHERE `stream_id` = ?;', $rID); + } else { + $rServerIDs = array($rServerID); + $db->query('DELETE FROM `streams_servers` WHERE `stream_id` = ? AND `server_id` = ?;', $rID, $rServerID); + + if (!($rDeleteFiles && in_array($rType, array(2, 5)))) { + } else { + MovieService::deleteFile(array($rServerID), $rID); + } + } + + $db->query('DELETE FROM `streams_servers` WHERE `parent_id` IS NOT NULL AND `parent_id` > 0 AND `parent_id` NOT IN (SELECT `id` FROM `servers` WHERE `server_type` = 0);'); + StreamProcess::updateStream($rID); + BouquetService::scan(); + + return true; + } + + public static function deleteStreams($rIDs, $rDeleteFiles = false) { + global $db; + $rIDs = AdminHelpers::confirmIDs($rIDs); + + if (0 >= count($rIDs)) { + } else { + $db->query('DELETE FROM `lines_logs` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `mag_claims` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams` WHERE `id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_episodes` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_errors` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_logs` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_options` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_stats` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `watch_refresh` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `watch_logs` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `lines_live` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `recordings` WHERE `created_id` IN (' . implode(',', $rIDs) . ') OR `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('UPDATE `lines_activity` SET `stream_id` = 0 WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('SELECT `server_id` FROM `streams_servers` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_servers` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_servers` WHERE `parent_id` IS NOT NULL AND `parent_id` > 0 AND `parent_id` NOT IN (SELECT `id` FROM `servers` WHERE `server_type` = 0);'); + $db->query('INSERT INTO `signals`(`server_id`, `cache`, `time`, `custom_data`) VALUES(?, 1, ?, ?);', SERVER_ID, time(), json_encode(array('type' => 'update_streams', 'id' => $rIDs))); + + if ($rDeleteFiles) { + foreach (array_keys(ServerRepository::getAll()) as $rServerID) { + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`, `cache`) VALUES(?, ?, ?, 1);', $rServerID, time(), json_encode(array('type' => 'delete_vods', 'id' => $rIDs))); + } + } + + BouquetService::scan(); + } + + return true; + } + + public static function deleteStreamsByServer($rIDs, $rServerID, $rDeleteFiles = false) { + global $db; + $rIDs = AdminHelpers::confirmIDs($rIDs); + + if (0 >= count($rIDs)) { + } else { + $db->query('DELETE FROM `streams_servers` WHERE `server_id` = ? AND `stream_id` IN (' . implode(',', $rIDs) . ');', $rServerID); + $db->query('UPDATE `streams_servers` SET `parent_id` = NULL WHERE `parent_id` = ? AND `stream_id` IN (' . implode(',', $rIDs) . ');', $rServerID); + + if ($rDeleteFiles) { + $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`, `cache`) VALUES(?, ?, ?, 1);', $rServerID, time(), json_encode(array('type' => 'delete_vods', 'id' => $rIDs))); + } + } + + return true; + } + + public static function getWatchFolder($rID) { + global $db; + $db->query('SELECT * FROM `watch_folders` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + } else { + return $db->get_row(); + } + } + + public static function deleteWatchFolder($rID) { + global $db; + $db->query('SELECT `id` FROM `watch_folders` WHERE `id` = ?;', $rID); + + if (0 >= $db->num_rows()) { + return false; + } + + $db->query('DELETE FROM `watch_folders` WHERE `id` = ?;', $rID); + + return true; + } } diff --git a/src/domain/Stream/StreamService.php b/src/domain/Stream/StreamService.php index 45d841f2..f70bb305 100644 --- a/src/domain/Stream/StreamService.php +++ b/src/domain/Stream/StreamService.php @@ -20,13 +20,13 @@ class StreamService { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_stream')) { - $rArray = overwriteData(StreamRepository::getById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(StreamRepository::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'add_stream')) { - $rArray = verifyPostTable('streams', $rData); + $rArray = QueryHelper::verifyPostTable('streams', $rData); $rArray['type'] = 1; $rArray['added'] = time(); unset($rArray['id']); @@ -246,7 +246,7 @@ class StreamService { if (!$rReview) { $rBouquetList = json_decode($rData['bouquet_create_list'] ?? '[]', true) ?: []; foreach ($rBouquetList as $rBouquet) { - $rPrepare = prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); + $rPrepare = QueryHelper::prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -257,7 +257,7 @@ class StreamService { $rCategoryList = json_decode($rData['category_create_list'] ?? '[]', true) ?: []; foreach ($rCategoryList as $rCategory) { - $rPrepare = prepareArray(array('category_type' => 'live', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); + $rPrepare = QueryHelper::prepareArray(array('category_type' => 'live', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -330,7 +330,7 @@ class StreamService { } } - $rPrepare = prepareArray($rImportArray); + $rPrepare = QueryHelper::prepareArray($rImportArray); $rQuery = 'REPLACE INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -370,7 +370,7 @@ class StreamService { foreach ($rStreamExists as $rServerID => $rDBID) { if (!in_array($rServerID, $rStreamsAdded)) { - deleteStream($rInsertID, $rServerID, false, false); + StreamRepository::deleteStream($rInsertID, $rServerID, false, false); } } $db->query('DELETE FROM `streams_options` WHERE `stream_id` = ?;', $rInsertID); @@ -400,17 +400,17 @@ class StreamService { } if ($rRestart) { - APIRequest(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array($rInsertID))); + ApiClient::request(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array($rInsertID))); } foreach ($rBouquets as $rBouquet) { - addToBouquet('stream', $rBouquet, $rInsertID); + BouquetService::addItems('stream', $rBouquet, $rInsertID); } if (isset($rData['edit']) || isset($rImportStream['id'])) { foreach (BouquetService::getAllSimple() as $rBouquet) { if (!in_array($rBouquet['id'], $rBouquets)) { - removeFromBouquet('stream', $rBouquet['id'], $rInsertID); + BouquetService::removeItems('stream', $rBouquet['id'], $rInsertID); } } } @@ -555,7 +555,7 @@ class StreamService { $rArray['category_id'] = '[' . implode(',', $rCategories) . ']'; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (count($rPrepare['data']) > 0) { $rPrepare['data'][] = $rStreamID; @@ -659,7 +659,7 @@ class StreamService { } foreach ($rDeleteServers as $rServerID => $rDeleteIDs) { - deleteStreamsByServer($rDeleteIDs, $rServerID, false); + StreamRepository::deleteStreamsByServer($rDeleteIDs, $rServerID, false); } foreach ($rDelOptions as $rOptionID => $rDelIDs) { @@ -675,11 +675,11 @@ class StreamService { } foreach ($rAddBouquet as $rBouquetID => $rAddIDs) { - addToBouquet('stream', $rBouquetID, $rAddIDs); + BouquetService::addItems('stream', $rBouquetID, $rAddIDs); } foreach ($rDelBouquet as $rBouquetID => $rRemIDs) { - removeFromBouquet('stream', $rBouquetID, $rRemIDs); + BouquetService::removeItems('stream', $rBouquetID, $rRemIDs); } if (!empty($rAddQuery)) { @@ -690,7 +690,7 @@ class StreamService { StreamProcess::updateStreams($rStreamIDs); if (isset($rData['restart_on_edit'])) { - APIRequest(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array_values($rStreamIDs))); + ApiClient::request(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array_values($rStreamIDs))); } } @@ -754,13 +754,13 @@ class StreamService { ini_set('default_socket_timeout', 0); $rStreams = json_decode($rData['streams'], true); - deleteStreams($rStreams, false); + StreamRepository::deleteStreams($rStreams, false); return array('status' => STATUS_SUCCESS); } public static function parseM3U($rData, $rFile = true) { - require_once INCLUDES_PATH . 'libs/m3u.php'; + require_once MAIN_HOME . 'domain/Stream/M3UEntry.php'; $rParser = new M3uParser(); $rParser->addDefaultTags(); @@ -770,4 +770,69 @@ class StreamService { return $rParser->parse($rData); } + + public static function getArchiveFiles($rServerID, $rStreamID) { + return json_decode(ApiClient::systemRequest($rServerID, array('action' => 'get_archive_files', 'stream_id' => $rStreamID)), true)['data']; + } + + public static function getArchive($rStreamID) { + global $db; + $rReturn = array(); + $rStream = StreamRepository::getById($rStreamID); + $rEPG = EpgService::getChannelEpg($rStream, true); + $rFiles = self::getArchiveFiles($rStream['tv_archive_server_id'], $rStreamID); + + if (!empty($rFiles) && !empty($rEPG)) { + foreach ($rFiles as $rFile) { + $rFilename = pathinfo($rFile)['filename']; + $rTimestamp = strtotime(explode(':', $rFilename)[0] . 'T' . implode(':', explode('-', explode(':', $rFilename)[1])) . ':00Z ' . str_replace(':', '', gmdate('P'))); + $rEPGID = null; + $rI = 0; + + foreach ($rEPG as $rEPGItem) { + if (!filter_var($rTimestamp, FILTER_VALIDATE_INT, array('options' => array('min_range' => $rEPGItem['start'], 'max_range' => $rEPGItem['end'] - 1)))) { + $rI++; + } else { + $rEPGID = $rI; + + break; + } + } + + if ($rEPGID) { + if (!isset($rReturn[$rEPGID])) { + $rReturn[$rEPGID] = $rEPG[$rEPGID]; + $rReturn[$rEPGID]['archive_stop'] = null; + $rReturn[$rEPGID]['archive_start'] = $rReturn[$rEPGID]['archive_stop']; + } + + if ($rTimestamp - 60 >= $rReturn[$rEPGID]['archive_start'] && $rReturn[$rEPGID]['archive_start']) { + } else { + $rReturn[$rEPGID]['archive_start'] = $rTimestamp - 60; + } + + if ($rReturn[$rEPGID]['archive_stop'] >= $rTimestamp && $rReturn[$rEPGID]['archive_stop']) { + } else { + $rReturn[$rEPGID]['archive_stop'] = $rTimestamp; + } + } + } + } + + foreach ($rReturn as $rKey => $rItem) { + if (time() < $rItem['end']) { + $rReturn[$rKey]['in_progress'] = true; + } else { + $rReturn[$rKey]['in_progress'] = false; + } + + if (!$rReturn[$rKey]['in_progress'] && filter_var($rItem['start'], FILTER_VALIDATE_INT, array('options' => array('min_range' => $rItem['archive_start'] - 60, 'max_range' => $rItem['archive_start'] + 60))) && filter_var($rItem['end'], FILTER_VALIDATE_INT, array('options' => array('min_range' => $rItem['archive_stop'] - 60, 'max_range' => $rItem['archive_stop'] + 60)))) { + $rReturn[$rKey]['complete'] = true; + } else { + $rReturn[$rKey]['complete'] = false; + } + } + + return $rReturn; + } } diff --git a/src/domain/User/GroupService.php b/src/domain/User/GroupService.php index 8f6b1743..1d248e4b 100644 --- a/src/domain/User/GroupService.php +++ b/src/domain/User/GroupService.php @@ -16,13 +16,13 @@ class GroupService { if (InputValidator::validate('processGroup', $rData)) { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_group')) { - $rArray = overwriteData(self::getById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(self::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'add_group')) { - $rArray = verifyPostTable('users_groups', $rData); + $rArray = QueryHelper::verifyPostTable('users_groups', $rData); unset($rArray['id']); } else { exit(); @@ -49,7 +49,7 @@ class GroupService { if (strlen($rData['group_name']) != 0) { $rArray['subresellers'] = '[' . implode(',', array_map('intval', json_decode($rData['groups_selected'], true))) . ']'; $rArray['notice_html'] = htmlentities($rData['notice_html']); - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { diff --git a/src/domain/User/UserRepository.php b/src/domain/User/UserRepository.php index 150a2e23..8e170d54 100644 --- a/src/domain/User/UserRepository.php +++ b/src/domain/User/UserRepository.php @@ -18,7 +18,7 @@ class UserRepository { if ($db->num_rows() == 1) { $rRow = $db->get_row(); - if (verifyPassword($rPassword, $rRow['password'])) { + if (Authenticator::checkPassword($rPassword, $rRow['password'])) { return $rRow; } } diff --git a/src/domain/User/UserService.php b/src/domain/User/UserService.php index 35bc475b..08c8d8f0 100644 --- a/src/domain/User/UserService.php +++ b/src/domain/User/UserService.php @@ -18,7 +18,7 @@ class UserService { ini_set('default_socket_timeout', 0); $rUsers = json_decode($rData['users'], true); - deleteUser($rUsers); + UserService::deleteRegisteredUser($rUsers); return array('status' => STATUS_SUCCESS); } @@ -71,14 +71,14 @@ class UserService { $rArray['override_packages'] = json_encode($rOverride); } - $rUsers = confirmIDs(json_decode($rData['users_selected'], true)); + $rUsers = AdminHelpers::confirmIDs(json_decode($rData['users_selected'], true)); if (count($rUsers) > 0) { if (isset($rData['c_owner_id']) && $rUser == $rArray['owner_id']) { unset($rArray['owner_id']); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (count($rPrepare['data']) > 0) { $rQuery = 'UPDATE `users` SET ' . $rPrepare['update'] . ' WHERE `id` IN (' . implode(',', $rUsers) . ');'; @@ -98,13 +98,13 @@ class UserService { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_reguser') || $rBypassAuth) { $rUser = UserRepository::getRegisteredUserById($rData['edit']); - $rArray = overwriteData($rUser, $rData, array('password')); + $rArray = AdminHelpers::overwriteData($rUser, $rData, array('password')); } else { exit(); } } else { if (Authorization::check('adv', 'add_reguser') || $rBypassAuth) { - $rArray = verifyPostTable('users', $rData); + $rArray = QueryHelper::verifyPostTable('users', $rData); $rArray['date_registered'] = time(); unset($rArray['id']); } else { @@ -114,12 +114,12 @@ class UserService { if (!empty($rData['member_group_id'])) { if (strlen($rData['username']) == 0) { - $rArray['username'] = generateString(10); + $rArray['username'] = AdminHelpers::generateString(10); } - if (!checkExists('users', 'username', $rArray['username'], 'id', $rData['edit'] ?? null)) { + if (!QueryHelper::checkExists('users', 'username', $rArray['username'], 'id', $rData['edit'] ?? null)) { if (strlen($rData['password']) > 0) { - $rArray['password'] = cryptPassword($rData['password']); + $rArray['password'] = Authenticator::hashPassword($rData['password']); } $rOverride = array(); @@ -151,7 +151,7 @@ class UserService { $rReason = $rData['credits_reason']; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `users`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -183,7 +183,7 @@ class UserService { } if (0 < strlen($rData['password'])) { - $rPassword = cryptPassword($rData['password']); + $rPassword = Authenticator::hashPassword($rData['password']); } else { $rPassword = $rUserInfo['password']; } @@ -204,9 +204,9 @@ class UserService { public static function submitTicket($rData, $rUserInfo) { global $db; if (isset($rData['edit'])) { - $rArray = overwriteData(getTicket($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(TicketRepository::getById($rData['edit']), $rData); } else { - $rArray = verifyPostTable('tickets', $rData); + $rArray = QueryHelper::verifyPostTable('tickets', $rData); unset($rArray['id']); } @@ -215,7 +215,7 @@ class UserService { } if (!isset($rData['respond'])) { - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `tickets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -227,7 +227,7 @@ class UserService { return array('status' => STATUS_FAILURE, 'data' => $rData); } - $rTicket = getTicket($rData['respond']); + $rTicket = TicketRepository::getById($rData['respond']); if (!$rTicket) { return array('status' => STATUS_FAILURE, 'data' => $rData); } @@ -242,4 +242,60 @@ class UserService { return array('status' => STATUS_SUCCESS, 'data' => array('insert_id' => $rData['respond'])); } + + public static function deleteRegisteredUser($rID, $rDeleteSubUsers = false, $rDeleteLines = false, $rReplaceWith = null) { + global $db; + $rUser = UserRepository::getRegisteredUserById($rID); + + if (!$rUser) { + return false; + } + + $db->query('DELETE FROM `users` WHERE `id` = ?;', $rID); + $db->query('DELETE FROM `users_credits_logs` WHERE `admin_id` = ?;', $rID); + $db->query('DELETE FROM `users_logs` WHERE `owner` = ?;', $rID); + $db->query('DELETE FROM `tickets_replies` WHERE `ticket_id` IN (SELECT `id` FROM `tickets` WHERE `member_id` = ?);', $rID); + $db->query('DELETE FROM `tickets` WHERE `member_id` = ?;', $rID); + + if ($rDeleteSubUsers) { + $db->query('SELECT `id` FROM `users` WHERE `owner_id` = ?;', $rID); + + foreach ($db->get_rows() as $rRow) { + self::deleteRegisteredUser($rRow['id'], $rDeleteSubUsers, $rDeleteLines, $rReplaceWith); + } + } else { + $db->query('UPDATE `users` SET `owner_id` = ? WHERE `owner_id` = ?;', $rReplaceWith, $rID); + } + + if ($rDeleteLines) { + $db->query('SELECT `id` FROM `lines` WHERE `member_id` = ?;', $rID); + + foreach ($db->get_rows() as $rRow) { + LineService::deleteLineById($rRow['id']); + } + } else { + $db->query('UPDATE `lines` SET `member_id` = ? WHERE `member_id` = ?;', $rReplaceWith, $rID); + } + + return true; + } + + public static function deleteRegisteredUsers($rIDs) { + global $db; + $rIDs = AdminHelpers::confirmIDs($rIDs); + + if (0 >= count($rIDs)) { + return false; + } + + $db->query('DELETE FROM `users` WHERE `id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `users_credits_logs` WHERE `admin_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `users_logs` WHERE `owner` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `tickets_replies` WHERE `ticket_id` IN (SELECT `id` FROM `tickets` WHERE `member_id` IN (' . implode(',', $rIDs) . '));'); + $db->query('DELETE FROM `tickets` WHERE `member_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('UPDATE `users` SET `owner_id` = NULL WHERE `owner_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('UPDATE `lines` SET `member_id` = NULL WHERE `member_id` IN (' . implode(',', $rIDs) . ');'); + + return true; + } } diff --git a/src/domain/Vod/EpisodeService.php b/src/domain/Vod/EpisodeService.php index 83b8510e..2a629b27 100644 --- a/src/domain/Vod/EpisodeService.php +++ b/src/domain/Vod/EpisodeService.php @@ -15,13 +15,13 @@ class EpisodeService { global $db, $rSettings; if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_episode')) { - $rArray = overwriteData(StreamRepository::getById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(StreamRepository::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'add_episode')) { - $rArray = verifyPostTable('streams', $rData); + $rArray = QueryHelper::verifyPostTable('streams', $rData); $rArray['type'] = 5; $rArray['added'] = time(); $rArray['series_no'] = intval($rData['series']); @@ -63,8 +63,8 @@ class EpisodeService { if (isset($rData['multi'])) { if (Authorization::check('adv', 'import_episodes')) { set_time_limit(0); - require_once INCLUDES_PATH . 'libs/tmdb.php'; - $rSeries = getSerie(intval($rData['series'])); + require_once MAIN_HOME . 'modules/tmdb/lib/TmdbClient.php'; + $rSeries = SeriesService::getById(intval($rData['series'])); if (0 < strlen($rSettings['tmdb_language'])) { $rTMDB = new TMDB($rSettings['tmdb_api_key'], $rSettings['tmdb_language']); @@ -169,7 +169,7 @@ class EpisodeService { $rArray['target_container'] = $rData['target_container']; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -203,7 +203,7 @@ class EpisodeService { foreach ($rStreamExists as $rServerID => $rDBID) { if (!in_array($rServerID, $rStreamsAdded)) { - deleteStream($rInsertID, $rServerID, true, false); + StreamRepository::deleteStream($rInsertID, $rServerID, true, false); } } @@ -219,7 +219,7 @@ class EpisodeService { } if ($rRestart) { - APIRequest(array('action' => 'vod', 'sub' => 'start', 'stream_ids' => $rRestartIDs)); + ApiClient::request(array('action' => 'vod', 'sub' => 'start', 'stream_ids' => $rRestartIDs)); } if (isset($rData['multi'])) { @@ -236,7 +236,7 @@ class EpisodeService { ini_set('default_socket_timeout', 0); $rEpisodes = json_decode($rData['episodes'], true); - deleteStreams($rEpisodes, true); + StreamRepository::deleteStreams($rEpisodes, true); return array('status' => STATUS_SUCCESS); } @@ -306,7 +306,7 @@ class EpisodeService { } } - $rStreamIDs = confirmIDs(json_decode($rData['streams'], true)); + $rStreamIDs = AdminHelpers::confirmIDs(json_decode($rData['streams'], true)); if (0 < count($rStreamIDs)) { if (isset($rData['c_serie_name'])) { @@ -314,7 +314,7 @@ class EpisodeService { $db->query('UPDATE `streams` SET `series_no` = ? WHERE `id` IN (' . implode(',', array_map('intval', $rStreamIDs)) . ');', $rData['serie_name']); } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (0 < count($rPrepare['data'])) { $rQuery = 'UPDATE `streams` SET ' . $rPrepare['update'] . ' WHERE `id` IN (' . implode(',', array_map('intval', $rStreamIDs)) . ');'; @@ -373,7 +373,7 @@ class EpisodeService { } foreach ($rDeleteServers as $rServerID => $rDeleteIDs) { - deleteStreamsByServer($rDeleteIDs, $rServerID, true); + StreamRepository::deleteStreamsByServer($rDeleteIDs, $rServerID, true); } if (!empty($rAddQuery)) { diff --git a/src/domain/Vod/MovieService.php b/src/domain/Vod/MovieService.php index c8bd68cd..ef9cc641 100644 --- a/src/domain/Vod/MovieService.php +++ b/src/domain/Vod/MovieService.php @@ -21,13 +21,13 @@ class MovieService { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_movie')) { - $rArray = overwriteData(StreamRepository::getById($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(StreamRepository::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'add_movie')) { - $rArray = verifyPostTable('streams', $rData); + $rArray = QueryHelper::verifyPostTable('streams', $rData); $rArray['added'] = time(); $rArray['type'] = 2; unset($rArray['id']); @@ -71,7 +71,7 @@ class MovieService { $rImportStreams = array(); if (isset($rData['review'])) { - require_once MAIN_HOME . 'includes/libs/tmdb.php'; + require_once MAIN_HOME . 'modules/tmdb/lib/TmdbClient.php'; if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); @@ -232,11 +232,11 @@ class MovieService { if (!is_numeric($rParts[1])) { } else { if (isset($rData['scan_recursive'])) { - $rFiles = scanRecursive(intval($rParts[1]), $rParts[2], array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts')); + $rFiles = ApiClient::scanRecursive(intval($rParts[1]), $rParts[2], array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts')); } else { $rFiles = array(); - foreach (listDir(intval($rParts[1]), rtrim($rParts[2], '/'), array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts'))['files'] as $rFile) { + foreach (ApiClient::listDir(intval($rParts[1]), rtrim($rParts[2], '/'), array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts'))['files'] as $rFile) { $rFiles[] = rtrim($rParts[2], '/') . '/' . $rFile; } } @@ -302,7 +302,7 @@ class MovieService { if ($rReview) { } else { foreach (json_decode($rData['bouquet_create_list'], true) as $rBouquet) { - $rPrepare = prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); + $rPrepare = QueryHelper::prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -313,7 +313,7 @@ class MovieService { } foreach (json_decode($rData['category_create_list'], true) as $rCategory) { - $rPrepare = prepareArray(array('category_type' => 'movie', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); + $rPrepare = QueryHelper::prepareArray(array('category_type' => 'movie', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -378,7 +378,7 @@ class MovieService { $rImportArray['tmdb_id'] = ($rImportStream['movie_properties']['tmdb_id'] ?: null); $rSync = $rImportArray['async']; unset($rImportArray['async']); - $rPrepare = prepareArray($rImportArray); + $rPrepare = QueryHelper::prepareArray($rImportArray); $rQuery = 'REPLACE INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -422,7 +422,7 @@ class MovieService { foreach ($rStreamExists as $rServerID => $rDBID) { if (in_array($rServerID, $rStreamsAdded)) { } else { - deleteStream($rInsertID, $rServerID, true, false); + StreamRepository::deleteStream($rInsertID, $rServerID, true, false); } } @@ -431,13 +431,13 @@ class MovieService { } foreach ($rBouquets as $rBouquet) { - addToBouquet('movie', $rBouquet, $rInsertID); + BouquetService::addItems('movie', $rBouquet, $rInsertID); } foreach (BouquetService::getAllSimple() as $rBouquet) { if (in_array($rBouquet['id'], $rBouquets)) { } else { - removeFromBouquet('movie', $rBouquet['id'], $rInsertID); + BouquetService::removeItems('movie', $rBouquet['id'], $rInsertID); } } @@ -462,7 +462,7 @@ class MovieService { if (!$rRestart) { } else { - APIRequest(array('action' => 'vod', 'sub' => 'start', 'stream_ids' => $rRestartIDs)); + ApiClient::request(array('action' => 'vod', 'sub' => 'start', 'stream_ids' => $rRestartIDs)); } return array('status' => STATUS_SUCCESS, 'data' => array('insert_id' => $rInsertID)); @@ -572,11 +572,11 @@ class MovieService { if (!is_numeric($rParts[1])) { } else { if (isset($rData['scan_recursive'])) { - $rFiles = scanRecursive(intval($rParts[1]), $rParts[2], array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts')); + $rFiles = ApiClient::scanRecursive(intval($rParts[1]), $rParts[2], array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts')); } else { $rFiles = array(); - foreach (listDir(intval($rParts[1]), rtrim($rParts[2], '/'), array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts'))['files'] as $rFile) { + foreach (ApiClient::listDir(intval($rParts[1]), rtrim($rParts[2], '/'), array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts'))['files'] as $rFile) { $rFiles[] = rtrim($rParts[2], '/') . '/' . $rFile; } } @@ -606,7 +606,7 @@ class MovieService { $rBouquets = array(); foreach (json_decode($rData['bouquet_create_list'], true) as $rBouquet) { - $rPrepare = prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); + $rPrepare = QueryHelper::prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -626,7 +626,7 @@ class MovieService { $rCategories = array(); foreach (json_decode($rData['category_create_list'], true) as $rCategory) { - $rPrepare = prepareArray(array('category_type' => 'movie', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); + $rPrepare = QueryHelper::prepareArray(array('category_type' => 'movie', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -655,7 +655,7 @@ class MovieService { foreach ($rImportStreams as $rImportStream) { $rData = array('import' => true, 'type' => 'movie', 'title' => $rImportStream['title'], 'file' => $rImportStream['url'], 'subtitles' => array(), 'servers' => $rServerIDs, 'fb_category_id' => $rCategories, 'fb_bouquets' => $rBouquets, 'disable_tmdb' => $rDisableTMDB, 'ignore_no_match' => $rIgnoreMatch, 'bouquets' => array(), 'category_id' => array(), 'language' => SettingsManager::getAll()['tmdb_language'], 'watch_categories' => $rWatchCategories, 'read_native' => $rData['read_native'], 'movie_symlink' => $rData['movie_symlink'], 'remove_subtitles' => $rData['remove_subtitles'], 'direct_source' => $rData['direct_source'], 'direct_proxy' => $rData['direct_proxy'], 'auto_encode' => $rRestart, 'auto_upgrade' => false, 'fallback_title' => false, 'ffprobe_input' => false, 'transcode_profile_id' => $rData['transcode_profile_id'], 'target_container' => $rImportStream['container'], 'max_genres' => intval(SettingsManager::getAll()['max_genres']), 'duplicate_tmdb' => true); - $rCommand = '/usr/bin/timeout 300 ' . PHP_BIN . ' ' . INCLUDES_PATH . 'cli/watch_item.php "' . base64_encode(json_encode($rData, JSON_UNESCAPED_UNICODE)) . '" > /dev/null 2>/dev/null &'; + $rCommand = '/usr/bin/timeout 300 ' . PHP_BIN . ' ' . MAIN_HOME . 'console.php watch_item "' . base64_encode(json_encode($rData, JSON_UNESCAPED_UNICODE)) . '" > /dev/null 2>/dev/null &'; shell_exec($rCommand); } @@ -678,7 +678,7 @@ class MovieService { ini_set('default_socket_timeout', 0); $rMovies = json_decode($rData['movies'], true); - deleteStreams($rMovies, true); + StreamRepository::deleteStreams($rMovies, true); return array('status' => STATUS_SUCCESS); } @@ -796,7 +796,7 @@ class MovieService { $rArray['category_id'] = '[' . implode(',', $rCategories) . ']'; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (0 < count($rPrepare['data'])) { $rPrepare['data'][] = $rStreamID; @@ -868,15 +868,15 @@ class MovieService { } foreach ($rDeleteServers as $rServerID => $rDeleteIDs) { - deleteStreamsByServer($rDeleteIDs, $rServerID, true); + StreamRepository::deleteStreamsByServer($rDeleteIDs, $rServerID, true); } foreach ($rAddBouquet as $rBouquetID => $rAddIDs) { - addToBouquet('movie', $rBouquetID, $rAddIDs); + BouquetService::addItems('movie', $rBouquetID, $rAddIDs); } foreach ($rDelBouquet as $rBouquetID => $rRemIDs) { - removeFromBouquet('movie', $rBouquetID, $rRemIDs); + BouquetService::removeItems('movie', $rBouquetID, $rRemIDs); } if (!empty($rAddQuery)) { @@ -903,7 +903,7 @@ class MovieService { // ──────────── Из MovieRepository ──────────── public static function getSimilar($rID, $rPage = 1) { - require_once MAIN_HOME . 'includes/libs/tmdb.php'; + require_once MAIN_HOME . 'modules/tmdb/lib/TmdbClient.php'; if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); diff --git a/src/domain/Vod/SeriesService.php b/src/domain/Vod/SeriesService.php index b55e4e50..056a896e 100644 --- a/src/domain/Vod/SeriesService.php +++ b/src/domain/Vod/SeriesService.php @@ -16,13 +16,13 @@ class SeriesService { if (InputValidator::validate('processSeries', $rData)) { if (isset($rData['edit'])) { if (Authorization::check('adv', 'edit_series')) { - $rArray = overwriteData(getSerie($rData['edit']), $rData); + $rArray = AdminHelpers::overwriteData(SeriesService::getById($rData['edit']), $rData); } else { exit(); } } else { if (Authorization::check('adv', 'add_series')) { - $rArray = verifyPostTable('streams_series', $rData); + $rArray = QueryHelper::verifyPostTable('streams_series', $rData); unset($rArray['id']); } else { exit(); @@ -47,7 +47,7 @@ class SeriesService { $rBouquetCreate = array(); foreach (json_decode($rData['bouquet_create_list'], true) as $rBouquet) { - $rPrepare = prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); + $rPrepare = QueryHelper::prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -59,7 +59,7 @@ class SeriesService { $rCategoryCreate = array(); foreach (json_decode($rData['category_create_list'], true) as $rCategory) { - $rPrepare = prepareArray(array('category_type' => 'series', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); + $rPrepare = QueryHelper::prepareArray(array('category_type' => 'series', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -93,7 +93,7 @@ class SeriesService { } } $rArray['category_id'] = '[' . implode(',', array_map('intval', $rCategories)) . ']'; - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); $rQuery = 'REPLACE INTO `streams_series`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if ($db->query($rQuery, ...$rPrepare['data'])) { @@ -101,13 +101,13 @@ class SeriesService { SeriesService::queueRefresh($rInsertID); foreach ($rBouquets as $rBouquet) { - addToBouquet('series', $rBouquet, $rInsertID); + BouquetService::addItems('series', $rBouquet, $rInsertID); } foreach (BouquetService::getAllSimple() as $rBouquet) { if (in_array($rBouquet['id'], $rBouquets)) { } else { - removeFromBouquet('series', $rBouquet['id'], $rInsertID); + BouquetService::removeItems('series', $rBouquet['id'], $rInsertID); } } @@ -214,11 +214,11 @@ class SeriesService { if (!is_numeric($rParts[1])) { } else { if (isset($rData['scan_recursive'])) { - $rFiles = scanRecursive(intval($rParts[1]), $rParts[2], array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts')); + $rFiles = ApiClient::scanRecursive(intval($rParts[1]), $rParts[2], array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts')); } else { $rFiles = array(); - foreach (listDir(intval($rParts[1]), rtrim($rParts[2], '/'), array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts'))['files'] as $rFile) { + foreach (ApiClient::listDir(intval($rParts[1]), rtrim($rParts[2], '/'), array('mp4', 'mkv', 'avi', 'mpg', 'flv', '3gp', 'm4v', 'wmv', 'mov', 'ts'))['files'] as $rFile) { $rFiles[] = rtrim($rParts[2], '/') . '/' . $rFile; } } @@ -248,7 +248,7 @@ class SeriesService { $rBouquets = array(); foreach (json_decode($rData['bouquet_create_list'], true) as $rBouquet) { - $rPrepare = prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); + $rPrepare = QueryHelper::prepareArray(array('bouquet_name' => $rBouquet, 'bouquet_channels' => array(), 'bouquet_movies' => array(), 'bouquet_series' => array(), 'bouquet_radios' => array())); $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -268,7 +268,7 @@ class SeriesService { $rCategories = array(); foreach (json_decode($rData['category_create_list'], true) as $rCategory) { - $rPrepare = prepareArray(array('category_type' => 'series', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); + $rPrepare = QueryHelper::prepareArray(array('category_type' => 'series', 'category_name' => $rCategory, 'parent_id' => 0, 'cat_order' => 99, 'is_adult' => 0)); $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');'; if (!$db->query($rQuery, ...$rPrepare['data'])) { @@ -297,7 +297,7 @@ class SeriesService { foreach ($rImportStreams as $rImportStream) { $rData = array('import' => true, 'type' => 'series', 'title' => $rImportStream['title'], 'file' => $rImportStream['url'], 'subtitles' => array(), 'servers' => $rServerIDs, 'fb_category_id' => $rCategories, 'fb_bouquets' => $rBouquets, 'disable_tmdb' => false, 'ignore_no_match' => false, 'bouquets' => array(), 'category_id' => array(), 'language' => SettingsManager::getAll()['tmdb_language'], 'watch_categories' => $rWatchCategories, 'read_native' => $rData['read_native'], 'movie_symlink' => $rData['movie_symlink'], 'remove_subtitles' => $rData['remove_subtitles'], 'direct_source' => $rData['direct_source'], 'direct_proxy' => $rData['direct_proxy'], 'auto_encode' => $rRestart, 'auto_upgrade' => false, 'fallback_title' => false, 'ffprobe_input' => false, 'transcode_profile_id' => $rData['transcode_profile_id'], 'target_container' => $rImportStream['container'], 'max_genres' => intval(SettingsManager::getAll()['max_genres']), 'duplicate_tmdb' => true); - $rCommand = '/usr/bin/timeout 300 ' . PHP_BIN . ' ' . INCLUDES_PATH . 'cli/watch_item.php "' . base64_encode(json_encode($rData, JSON_UNESCAPED_UNICODE)) . '" > /dev/null 2>/dev/null &'; + $rCommand = '/usr/bin/timeout 300 ' . PHP_BIN . ' ' . MAIN_HOME . 'console.php watch_item "' . base64_encode(json_encode($rData, JSON_UNESCAPED_UNICODE)) . '" > /dev/null 2>/dev/null &'; shell_exec($rCommand); } @@ -320,7 +320,7 @@ class SeriesService { ini_set('default_socket_timeout', 0); $rSeries = json_decode($rData['series'], true); - deleteSeriesMass($rSeries); + SeriesService::deleteSeriesByIds($rSeries); return array('status' => STATUS_SUCCESS); } @@ -373,7 +373,7 @@ class SeriesService { $rArray['category_id'] = '[' . implode(',', $rCategories) . ']'; } - $rPrepare = prepareArray($rArray); + $rPrepare = QueryHelper::prepareArray($rArray); if (0 < count($rPrepare['data'])) { $rPrepare['data'][] = $rSeriesID; @@ -405,11 +405,11 @@ class SeriesService { } foreach ($rAddBouquet as $rBouquetID => $rAddIDs) { - addToBouquet('series', $rBouquetID, $rAddIDs); + BouquetService::addItems('series', $rBouquetID, $rAddIDs); } foreach ($rDelBouquet as $rBouquetID => $rRemIDs) { - removeFromBouquet('series', $rBouquetID, $rRemIDs); + BouquetService::removeItems('series', $rBouquetID, $rRemIDs); } if (isset($rData['reprocess_tmdb'])) { @@ -427,7 +427,7 @@ class SeriesService { // ──────────── Из SeriesRepository ──────────── public static function getSimilar($rID, $rPage = 1) { - require_once MAIN_HOME . 'includes/libs/tmdb.php'; + require_once MAIN_HOME . 'modules/tmdb/lib/TmdbClient.php'; if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); @@ -460,7 +460,7 @@ class SeriesService { */ public static function updateFromTMDB($rID) { global $db; - require_once MAIN_HOME . 'includes/libs/tmdb.php'; + require_once MAIN_HOME . 'modules/tmdb/lib/TmdbClient.php'; $db->query('SELECT `tmdb_id`, `tmdb_language` FROM `streams_series` WHERE `id` = ?;', $rID); if ($db->num_rows() != 1) { @@ -532,4 +532,87 @@ class SeriesService { return $rReturn; } + + public static function getById($rID) { + global $db; + $db->query('SELECT * FROM `streams_series` WHERE `id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return null; + } + + return $db->get_row(); + } + + public static function getAll() { + global $db; + $rReturn = array(); + $db->query('SELECT * FROM `streams_series` ORDER BY `title` ASC;'); + + if ($db->num_rows() > 0) { + foreach ($db->get_rows() as $rRow) { + $rReturn[] = $rRow; + } + } + + return $rReturn; + } + + public static function getByTMDBId($rID) { + global $db; + $db->query('SELECT * FROM `streams_series` WHERE `tmdb_id` = ?;', $rID); + + if ($db->num_rows() != 1) { + return null; + } + + return $db->get_row(); + } + + public static function deleteSeriesById($rID, $rDeleteFiles = true) { + global $db; + $rSeries = self::getById($rID); + + if (!$rSeries) { + return false; + } + + $db->query('SELECT `stream_id` FROM `streams_episodes` WHERE `series_id` = ?;', $rID); + + foreach ($db->get_rows() as $rRow) { + StreamRepository::deleteStream($rRow['stream_id'], -1, $rDeleteFiles); + } + $db->query('DELETE FROM `streams_episodes` WHERE `series_id` = ?;', $rID); + $db->query('DELETE FROM `streams_series` WHERE `id` = ?;', $rID); + BouquetService::scan(); + + return true; + } + + public static function deleteSeriesByIds($rIDs) { + global $db; + $rIDs = AdminHelpers::confirmIDs($rIDs); + + if (0 >= count($rIDs)) { + return false; + } + + $rStreamIDs = array(); + $db->query('SELECT `stream_id` FROM `streams_episodes` WHERE `series_id` IN (' . implode(',', $rIDs) . ');'); + + foreach ($db->get_rows() as $rRow) { + $rStreamIDs[] = $rRow['stream_id']; + } + $db->query('DELETE FROM `streams_episodes` WHERE `series_id` IN (' . implode(',', $rIDs) . ');'); + $db->query('DELETE FROM `streams_series` WHERE `id` IN (' . implode(',', $rIDs) . ');'); + + if (0 >= count($rStreamIDs)) { + } else { + StreamRepository::deleteStreams($rStreamIDs, true); + } + + BouquetService::scan(); + + return true; + } } diff --git a/src/includes/admin.php b/src/includes/admin.php deleted file mode 100644 index cd300ad5..00000000 --- a/src/includes/admin.php +++ /dev/null @@ -1,3076 +0,0 @@ - - * @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 - */ - -// Импорт глобальных переменных — нужен когда файл включается -// из метода контроллера (не из глобального scope). -global $db, $rSettings, $rMobile, $rServers, $rProxyServers, $rDetect, - $rTimeout, $rProtocol, $allServers, $rPermissions, $language, $allowedLangs, $_INFO; - -require_once __DIR__ . '/../bootstrap.php'; -XC_Bootstrap::boot(XC_Bootstrap::CONTEXT_ADMIN); - -if (is_array($rServers)) { - uasort( - $rServers, - function ($a, $b) { - return $a['order'] - $b['order']; - } - ); -} - -function secondsToTime($inputSeconds) { - $secondsInAMinute = 60; - $secondsInAnHour = 60 * $secondsInAMinute; - $secondsInADay = 24 * $secondsInAnHour; - $days = floor($inputSeconds / $secondsInADay); - $hourSeconds = $inputSeconds % $secondsInADay; - $hours = floor($hourSeconds / $secondsInAnHour); - $minuteSeconds = $hourSeconds % $secondsInAnHour; - $minutes = floor($minuteSeconds / $secondsInAMinute); - $remainingSeconds = $minuteSeconds % $secondsInAMinute; - $seconds = ceil($remainingSeconds); - - return array('d' => (int) $days, 'h' => (int) $hours, 'm' => (int) $minutes, 's' => (int) $seconds); -} - -function validateCIDR($rCIDR) { - $rParts = explode('/', $rCIDR); - $rIP = $rParts[0]; - $rNetmask = null; - - if (count($rParts) != 2) { - } else { - $rNetmask = intval($rParts[1]); - - if ($rNetmask >= 0) { - } else { - return false; - } - } - - if (!filter_var($rIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { - if (!filter_var($rIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - return false; - } - - - return (is_null($rNetmask) ? true : $rNetmask <= 128); - } - - return (is_null($rNetmask) ? true : $rNetmask <= 32); -} - -function encodeRow($rRow) { - foreach ($rRow as $rKey => $rValue) { - if (!is_array($rValue)) { - } else { - $rRow[$rKey] = json_encode($rValue, JSON_UNESCAPED_UNICODE); - } - } - - return $rRow; -} - -function getArchiveFiles($rServerID, $rStreamID) { - return json_decode(systemapirequest($rServerID, array('action' => 'get_archive_files', 'stream_id' => $rStreamID)), true)['data']; -} - -function getArchive($rStreamID) { - global $db; - $rReturn = array(); - $rStream = StreamRepository::getById($rStreamID); - $rEPG = EpgService::getChannelEpg($rStream, true); - $rFiles = getArchiveFiles($rStream['tv_archive_server_id'], $rStreamID); - - if (!empty($rFiles) && !empty($rEPG)) { - foreach ($rFiles as $rFile) { - $rFilename = pathinfo($rFile)['filename']; - $rTimestamp = strtotime(explode(':', $rFilename)[0] . 'T' . implode(':', explode('-', explode(':', $rFilename)[1])) . ':00Z ' . str_replace(':', '', gmdate('P'))); - $rEPGID = null; - $rI = 0; - - foreach ($rEPG as $rEPGItem) { - if (!filter_var($rTimestamp, FILTER_VALIDATE_INT, array('options' => array('min_range' => $rEPGItem['start'], 'max_range' => $rEPGItem['end'] - 1)))) { - $rI++; - } else { - $rEPGID = $rI; - - break; - } - } - - if ($rEPGID) { - if (!isset($rReturn[$rEPGID])) { - $rReturn[$rEPGID] = $rEPG[$rEPGID]; - $rReturn[$rEPGID]['archive_stop'] = null; - $rReturn[$rEPGID]['archive_start'] = $rReturn[$rEPGID]['archive_stop']; - } - - if ($rTimestamp - 60 >= $rReturn[$rEPGID]['archive_start'] && $rReturn[$rEPGID]['archive_start']) { - } else { - $rReturn[$rEPGID]['archive_start'] = $rTimestamp - 60; - } - - if ($rReturn[$rEPGID]['archive_stop'] >= $rTimestamp && $rReturn[$rEPGID]['archive_stop']) { - } else { - $rReturn[$rEPGID]['archive_stop'] = $rTimestamp; - } - } - } - } - - foreach ($rReturn as $rKey => $rItem) { - if (time() < $rItem['end']) { - $rReturn[$rKey]['in_progress'] = true; - } else { - $rReturn[$rKey]['in_progress'] = false; - } - - if (!$rReturn[$rKey]['in_progress'] && filter_var($rItem['start'], FILTER_VALIDATE_INT, array('options' => array('min_range' => $rItem['archive_start'] - 60, 'max_range' => $rItem['archive_start'] + 60))) && filter_var($rItem['end'], FILTER_VALIDATE_INT, array('options' => array('min_range' => $rItem['archive_stop'] - 60, 'max_range' => $rItem['archive_stop'] + 60)))) { - $rReturn[$rKey]['complete'] = true; - } else { - $rReturn[$rKey]['complete'] = false; - } - } - - return $rReturn; -} - -function getMovieTMDB($rID) { - require_once MAIN_HOME . 'includes/libs/tmdb.php'; - - if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); - } else { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key']); - } - - return ($rTMDB->getMovie($rID) ?: null); -} - -function getSeriesTMDB($rID) { - require_once MAIN_HOME . 'includes/libs/tmdb.php'; - - if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); - } else { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key']); - } - - return (json_decode($rTMDB->getTVShow($rID)->getJSON(), true) ?: null); -} - -function getSeasonTMDB($rID, $rSeason) { - require_once MAIN_HOME . 'includes/libs/tmdb.php'; - - - if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); - } else { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key']); - } - - return json_decode($rTMDB->getSeason($rID, intval($rSeason))->getJSON(), true); -} - -function overwriteData($rData, $rOverwrite, $rSkip = array()) { - foreach ($rOverwrite as $rKey => $rValue) { - if (!array_key_exists($rKey, $rData) || in_array($rKey, $rSkip)) { - } else { - if (empty($rValue) && is_null($rData[$rKey])) { - $rData[$rKey] = null; - } else { - $rData[$rKey] = $rValue; - } - } - } - - return $rData; -} - -function verifyPostTable($rTable, $rData = array(), $rOnlyExisting = false) { - global $db; - $rReturn = array(); - $db->query('SELECT `column_name`, `column_default`, `is_nullable`, `data_type` FROM `information_schema`.`columns` WHERE `table_schema` = (SELECT DATABASE()) AND `table_name` = ? ORDER BY `ordinal_position`;', $rTable); - - foreach ($db->get_rows() as $rRow) { - if ($rRow['column_default'] != 'NULL') { - } else { - $rRow['column_default'] = null; - } - - $rForceDefault = false; - - - if ($rRow['is_nullable'] != 'NO' || $rRow['column_default']) { - } else { - if (in_array($rRow['data_type'], array('int', 'float', 'tinyint', 'double', 'decimal', 'smallint', 'mediumint', 'bigint', 'bit'))) { - $rRow['column_default'] = 0; - } else { - $rRow['column_default'] = ''; - } - - $rForceDefault = true; - } - - if (array_key_exists($rRow['column_name'], $rData)) { - if (empty($rData[$rRow['column_name']]) && !is_numeric($rData[$rRow['column_name']]) && is_null($rRow['column_default'])) { - $rReturn[$rRow['column_name']] = ($rForceDefault ? $rRow['column_default'] : null); - } else { - $rReturn[$rRow['column_name']] = $rData[$rRow['column_name']]; - } - } else { - if ($rOnlyExisting) { - } else { - $rReturn[$rRow['column_name']] = $rRow['column_default']; - } - } - } - - return $rReturn; -} - -function preparecolumn($rValue) { - return strtolower(preg_replace('/[^a-z0-9_]+/i', '', $rValue)); -} - -function prepareArray($rArray) { - $UpdateData = $rColumns = $rPlaceholder = $rData = array(); - - - foreach (array_keys($rArray) as $rKey) { - $rColumns[] = '`' . preparecolumn($rKey) . '`'; - $UpdateData[] = '`' . preparecolumn($rKey) . '` = ?'; - } - - foreach (array_values($rArray) as $rValue) { - if (is_array($rValue)) { - $rValue = json_encode($rValue, JSON_UNESCAPED_UNICODE); - } else { - if (is_null($rValue) || strtolower($rValue) == 'null') { - $rValue = null; - } - } - - $rPlaceholder[] = '?'; - $rData[] = $rValue; - } - - return array('placeholder' => implode(',', $rPlaceholder), 'columns' => implode(',', $rColumns), 'data' => $rData, 'update' => implode(',', $UpdateData)); -} - -function setArgs($rArgs, $rGet = true) { - $rURL = getPageName(); - - if (count($rArgs) > 0) { - $rURL .= '?' . http_build_query($rArgs); - - if ($rGet) { - foreach ($rArgs as $rKey => $rValue) { - RequestManager::getAll()[$rKey] = $rValue; - } - } - } - - return ""; -} - -function getPageFromURL($rURL) { - if ($rURL) { - return strtolower(basename(ltrim(parse_url($rURL)['path'], '/'), '.php')); - } - - return null; -} - -function verifyCode() { - global $rUserInfo; - - if (isset($rUserInfo)) { - $rAccessCode = AuthRepository::getCurrentCode(true); - - if (in_array($rUserInfo['member_group_id'], json_decode($rAccessCode['groups'], true)) || count(AuthRepository::getActiveCodes(MAIN_HOME)) == 0) { - if (isset($_SESSION['code']) && $_SESSION['code'] != $rAccessCode['code']) { - return false; - } - - - return true; - } - - return false; - } - - - - - - - - - return false; -} - -function getNearest($arr, $search) { - $closest = null; - - - - foreach ($arr as $item) { - if (!($closest === null || abs($item - $search) < abs($search - $closest))) { - } else { - $closest = $item; - } - } - - return $closest; -} - -function generateUniqueCode() { - return substr(md5(SettingsManager::getAll()['live_streaming_pass']), 0, 15); -} - -function checkExists($rTable, $rColumn, $rValue, $rExcludeColumn = null, $rExclude = null) { - global $db; - - - if ($rExcludeColumn && $rExclude) { - $db->query('SELECT COUNT(*) AS `count` FROM `' . preparecolumn($rTable) . '` WHERE `' . preparecolumn($rColumn) . '` = ? AND `' . preparecolumn($rExcludeColumn) . '` <> ?;', $rValue, $rExclude); - } else { - $db->query('SELECT COUNT(*) AS `count` FROM `' . preparecolumn($rTable) . '` WHERE `' . preparecolumn($rColumn) . '` = ?;', $rValue); - } - - - - - return 0 < $db->get_row()['count']; -} - -function deleteMAG($rID, $rDeletePaired = false, $rCloseCons = true, $rConvert = false) { - global $db; - $rMag = getMag($rID); - - if (!$rMag) { - return false; - } - - $db->query('DELETE FROM `mag_devices` WHERE `mag_id` = ?;', $rID); - $db->query('DELETE FROM `mag_claims` WHERE `mag_id` = ?;', $rID); - $db->query('DELETE FROM `mag_events` WHERE `mag_device_id` = ?;', $rID); - $db->query('DELETE FROM `mag_logs` WHERE `mag_id` = ?;', $rID); - - if (!$rMag['user']) { - } else { - if ($rConvert) { - $db->query('UPDATE `lines` SET `is_mag` = 0 WHERE `id` = ?;', $rMag['user']['id']); - LineService::updateLineSignal($rMag['user']['id']); - } else { - $rCount = 0; - $db->query('SELECT `mag_id` FROM `mag_devices` WHERE `user_id` = ?;', $rMag['user']['id']); - $rCount += $db->num_rows(); - $db->query('SELECT `device_id` FROM `enigma2_devices` WHERE `user_id` = ?;', $rMag['user']['id']); - $rCount += $db->num_rows(); - - if ($rCount != 0) { - } else { - deleteLine($rMag['user']['id'], $rDeletePaired, $rCloseCons); - } - } - } - - return true; -} - -function deleteMAGs($rIDs) { - global $db; - $rIDs = confirmIDs($rIDs); - - - if (0 >= count($rIDs)) { - return false; - } - - $rUserIDs = array(); - $db->query('SELECT `user_id` FROM `mag_devices` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); - - foreach ($db->get_rows() as $rRow) { - $rUserIDs[] = $rRow['user_id']; - } - $db->query('DELETE FROM `mag_devices` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `mag_claims` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `mag_events` WHERE `mag_device_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `mag_logs` WHERE `mag_id` IN (' . implode(',', $rIDs) . ');'); - - if (0 >= count($rUserIDs)) { - } else { - deletelines($rUserIDs); - } - - return true; -} - -function deleteEnigma($rID, $rDeletePaired = false, $rCloseCons = true, $rConvert = false) { - global $db; - $rEnigma = getEnigma($rID); - - if (!$rEnigma) { - return false; - } - - $db->query('DELETE FROM `enigma2_devices` WHERE `device_id` = ?;', $rID); - $db->query('DELETE FROM `enigma2_actions` WHERE `device_id` = ?;', $rID); - - - if (!$rEnigma['user']) { - } else { - if ($rConvert) { - $db->query('UPDATE `lines` SET `is_e2` = 0 WHERE `id` = ?;', $rEnigma['user']['id']); - LineService::updateLineSignal($rEnigma['user']['id']); - } else { - $rCount = 0; - $db->query('SELECT `mag_id` FROM `mag_devices` WHERE `user_id` = ?;', $rEnigma['user']['id']); - $rCount += $db->num_rows(); - $db->query('SELECT `device_id` FROM `enigma2_devices` WHERE `user_id` = ?;', $rEnigma['user']['id']); - $rCount += $db->num_rows(); - - if ($rCount != 0) { - } else { - deleteLine($rEnigma['user']['id'], $rDeletePaired, $rCloseCons); - } - } - } - - return true; -} - -function deleteEnigmas($rIDs) { - global $db; - $rIDs = confirmIDs($rIDs); - - - if (0 >= count($rIDs)) { - return false; - } - - $rUserIDs = array(); - $db->query('SELECT `user_id` FROM `enigma2_devices` WHERE `device_id` IN (' . implode(',', $rIDs) . ');'); - - - foreach ($db->get_rows() as $rRow) { - $rUserIDs[] = $rRow['user_id']; - } - $db->query('DELETE FROM `enigma2_devices` WHERE `device_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `enigma2_actions` WHERE `device_id` IN (' . implode(',', $rIDs) . ');'); - - if (0 >= count($rUserIDs)) { - } else { - deletelines($rUserIDs); - } - - return true; -} - -function deleteSeries($rID, $rDeleteFiles = true) { - global $db; - $rSeries = getSerie($rID); - - if (!$rSeries) { - return false; - } - - $db->query('SELECT `stream_id` FROM `streams_episodes` WHERE `series_id` = ?;', $rID); - - foreach ($db->get_rows() as $rRow) { - deleteStream($rRow['stream_id'], -1, $rDeleteFiles); - } - $db->query('DELETE FROM `streams_episodes` WHERE `series_id` = ?;', $rID); - $db->query('DELETE FROM `streams_series` WHERE `id` = ?;', $rID); - BouquetService::scan(); - - return true; -} - -function deleteSeriesMass($rIDs) { - global $db; - $rIDs = confirmIDs($rIDs); - - if (0 >= count($rIDs)) { - return false; - } - - $db->query('SELECT `stream_id` FROM `streams_episodes` WHERE `series_id` IN (' . implode(',', $rIDs) . ');'); - - - foreach ($db->get_rows() as $rRow) { - $rStreamIDs[] = $rRow['stream_id']; - } - $db->query('DELETE FROM `streams_episodes` WHERE `series_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_series` WHERE `id` IN (' . implode(',', $rIDs) . ');'); - - if (0 >= count($rStreamIDs)) { - } else { - deleteStreams($rStreamIDs, true); - } - - BouquetService::scan(); - - return true; -} - -function deleteBouquet($rID) { - global $db; - $rBouquet = getBouquet($rID); - - - if (!$rBouquet) { - return false; - } - - $db->query("SELECT `id`, `bouquet` FROM `lines` WHERE JSON_CONTAINS(`bouquet`, ?, '\$');", $rID); - - - foreach ($db->get_rows() as $rRow) { - $rRow['bouquet'] = json_decode($rRow['bouquet'], true); - - - - - if (($rKey = array_search($rID, $rRow['bouquet'])) === false) { - } else { - unset($rRow['bouquet'][$rKey]); - } - - $db->query("UPDATE `lines` SET `bouquet` = '[" . implode(',', array_map('intval', $rRow['bouquet'])) . "]' WHERE `id` = ?;", $rRow['id']); - LineService::updateLineSignal($rRow['id']); - } - $db->query("SELECT `id`, `bouquets` FROM `users_packages` WHERE JSON_CONTAINS(`bouquets`, ?, '\$');", $rID); - - foreach ($db->get_rows() as $rRow) { - $rRow['bouquets'] = json_decode($rRow['bouquets'], true); - - if (($rKey = array_search($rID, $rRow['bouquets'])) === false) { - } else { - unset($rRow['bouquets'][$rKey]); - } - - $db->query("UPDATE `users_packages` SET `bouquets` = '[" . implode(',', array_map('intval', $rRow['bouquets'])) . "]' WHERE `id` = ?;", $rRow['id']); - } - $db->query("SELECT `id`, `bouquets` FROM `watch_folders` WHERE JSON_CONTAINS(`bouquets`, ?, '\$') OR JSON_CONTAINS(`fb_bouquets`, ?, '\$');", $rID, $rID); - - foreach ($db->get_rows() as $rRow) { - $rRow['bouquets'] = json_decode($rRow['bouquets'], true); - - if (($rKey = array_search($rID, $rRow['bouquets'])) === false) { - } else { - unset($rRow['bouquets'][$rKey]); - } - - $rRow['fb_bouquets'] = json_decode($rRow['fb_bouquets'], true); - - - - - - if (($rKey = array_search($rID, $rRow['fb_bouquets'])) === false) { - } else { - unset($rRow['fb_bouquets'][$rKey]); - } - - $db->query("UPDATE `watch_folders` SET `bouquets` = '[" . implode(',', array_map('intval', $rRow['bouquets'])) . "]', `fb_bouquets` = '[" . implode(',', array_map('intval', $rRow['fb_bouquets'])) . "]' WHERE `id` = ?;", $rRow['id']); - } - $db->query('DELETE FROM `bouquets` WHERE `id` = ?;', $rID); - BouquetService::scan(); - - return true; -} - -function deleteCategory($rID) { - global $db; - $rCategory = getCategory($rID); - - - if (!$rCategory) { - return false; - } - - $db->query("SELECT `id`, `category_id` FROM `streams` WHERE JSON_CONTAINS(`category_id`, ?, '\$');", $rID); - - foreach ($db->get_rows() as $rRow) { - $rRow['category_id'] = json_decode($rRow['category_id'], true); - - if (($rKey = array_search($rID, $rRow['category_id'])) === false) { - } else { - unset($rRow['category_id'][$rKey]); - } - - $db->query("UPDATE `streams` SET `category_id` = '[" . implode(',', array_map('intval', $rRow['category_id'])) . "]' WHERE `id` = ?;", $rRow['id']); - } - $db->query("SELECT `id`, `category_id` FROM `streams_series` WHERE JSON_CONTAINS(`category_id`, ?, '\$');", $rID); - - foreach ($db->get_rows() as $rRow) { - $rRow['category_id'] = json_decode($rRow['category_id'], true); - - if (($rKey = array_search($rID, $rRow['category_id'])) === false) { - } else { - unset($rRow['category_id'][$rKey]); - } - - $db->query("UPDATE `streams_series` SET `category_id` = '[" . implode(',', array_map('intval', $rRow['category_id'])) . "]' WHERE `id` = ?;", $rRow['id']); - } - $db->query('DELETE FROM `streams_categories` WHERE `id` = ?;', $rID); - $db->query('UPDATE `watch_folders` SET `category_id` = null WHERE `category_id` = ?;', $rID); - $db->query('UPDATE `watch_folders` SET `fb_category_id` = null WHERE `fb_category_id` = ?;', $rID); - - return true; -} - -function deleteProfile($rID) { - global $db; - $rProfile = getTranscodeProfile($rID); - - if (!$rProfile) { - return false; - } - - $db->query('DELETE FROM `profiles` WHERE `profile_id` = ?;', $rID); - $db->query('UPDATE `streams` SET `transcode_profile_id` = 0 WHERE `transcode_profile_id` = ?;', $rID); - $db->query('UPDATE `watch_folders` SET `transcode_profile_id` = 0 WHERE `transcode_profile_id` = ?;', $rID); - - return true; -} - -function AsyncAPIRequest($rServerIDs, $rData) { - $rURLs = array(); - global $rServers; - - foreach ($rServerIDs as $rServerID) { - if (!$rServers[$rServerID]['server_online']) { - } else { - $rURLs[$rServerID] = array('url' => $rServers[$rServerID]['api_url'], 'postdata' => $rData); - } - } - CurlClient::getMultiCURL($rURLs); - - return array('result' => true); -} - -function changePort($rServerID, $rType, $rPorts, $rReload = false) { - global $db; - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_port', 'type' => intval($rType), 'ports' => $rPorts, 'reload' => $rReload))); -} - -function setServices($rServerID, $rNumServices, $rReload = true) { - global $db; - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_services', 'count' => intval($rNumServices), 'reload' => $rReload))); -} - -function setGovernor($rServerID, $rGovernor) { - global $db; - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_governor', 'data' => $rGovernor))); -} - -function setSysctl($rServerID, $rSysCtl) { - global $db; - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServerID, time(), json_encode(array('action' => 'set_sysctl', 'data' => $rSysCtl))); -} - -function resetSTB($rID) { - global $db; - $db->query("UPDATE `mag_devices` SET `ip` = '', `ver` = '', `image_version` = '', `stb_type` = '', `sn` = '', `device_id` = '', `device_id2` = '', `hw_version` = '', `token` = '' WHERE `mag_id` = ?;", $rID); -} - -function formatUptime($rUptime) { - if (86400 <= $rUptime) { - $rUptime = sprintf('%02dd %02dh %02dm', $rUptime / 86400, ($rUptime / 3600) % 24, ($rUptime / 60) % 60); - } else { - $rUptime = sprintf('%02dh %02dm %02ds', $rUptime / 3600, ($rUptime / 60) % 60, $rUptime % 60); - } - - - - - return $rUptime; -} - -function getSettings() { - global $db; - $db->query('SELECT * FROM `settings` LIMIT 1;'); - - - - return $db->get_row(); -} - - -function APIRequest($rData, $rTimeout = 5) { - ini_set('default_socket_timeout', $rTimeout); - $rAPI = 'http://127.0.0.1:' . intval(ServerRepository::getAll()[SERVER_ID]['http_broadcast_port']) . '/admin/api'; - - if (!empty(SettingsManager::getAll()['api_pass'])) { - $rData['api_pass'] = SettingsManager::getAll()['api_pass']; - } - - $rPost = http_build_query($rData); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $rAPI); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $rPost); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $rTimeout); - curl_setopt($ch, CURLOPT_TIMEOUT, $rTimeout); - - return curl_exec($ch); -} - -function systemapirequest($rServerID, $rData, $rTimeout = 5) { - ini_set('default_socket_timeout', $rTimeout); - global $rServers, $rSettings; - if (!is_array($rServers) || !isset($rServers[$rServerID])) { - return null; - } - if ($rServers[$rServerID]['server_online']) { - $rAPI = 'http://' . $rServers[intval($rServerID)]['server_ip'] . ':' . $rServers[intval($rServerID)]['http_broadcast_port'] . '/api'; - $rData['password'] = $rSettings['live_streaming_pass']; - $rPost = http_build_query($rData); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $rAPI); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $rPost); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $rTimeout); - curl_setopt($ch, CURLOPT_TIMEOUT, $rTimeout); - - $rResult = curl_exec($ch); - - return $rResult; - } - return null; -} - -function getWatchFolder($rID) { - global $db; - $db->query('SELECT * FROM `watch_folders` WHERE `id` = ?;', $rID); - - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getSeriesByTMDB($rID) { - global $db; - $db->query('SELECT * FROM `streams_series` WHERE `tmdb_id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getSeries() { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `streams_series` ORDER BY `title` ASC;'); - - if (0 >= $db->num_rows()) { - } else { - foreach ($db->get_rows() as $rRow) { - $rReturn[] = $rRow; - } - } - - return $rReturn; -} - -function getSerie($rID) { - global $db; - $db->query('SELECT * FROM `streams_series` WHERE `id` = ?;', $rID); - - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getSeriesTrailer($rTMDBID, $rLanguage = null) { - $rURL = 'https://api.themoviedb.org/3/tv/' . intval($rTMDBID) . '/videos?api_key=' . urlencode(SettingsManager::getAll()['tmdb_api_key']); - - - - if ($rLanguage) { - $rURL .= '&language=' . urlencode($rLanguage); - } else { - if (0 >= strlen(SettingsManager::getAll()['tmdb_language'])) { - } else { - $rURL .= '&language=' . urlencode(SettingsManager::getAll()['tmdb_language']); - } - } - - $rJSON = json_decode(file_get_contents($rURL), true); - - - foreach ($rJSON['results'] as $rVideo) { - if (!(strtolower($rVideo['type']) == 'trailer' && strtolower($rVideo['site']) == 'youtube')) { - } else { - return $rVideo['key']; - } - } - - return ''; -} - -function getBouquet($rID) { - global $db; - $db->query('SELECT * FROM `bouquets` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getLanguages() { - return array(); -} - -function addToBouquet($rType, $rBouquetID, $rIDs) { - global $db; - - if (is_array($rIDs)) { - } else { - $rIDs = array($rIDs); - } - - $rBouquet = getBouquet($rBouquetID); - - if (!$rBouquet) { - } else { - if ($rType == 'stream') { - $rColumn = 'bouquet_channels'; - } else { - if ($rType == 'movie') { - $rColumn = 'bouquet_movies'; - } else { - if ($rType == 'radio') { - $rColumn = 'bouquet_radios'; - } else { - - $rColumn = 'bouquet_series'; - } - } - } - - $rChanged = false; - $rChannels = confirmIDs(json_decode($rBouquet[$rColumn], true)); - - foreach ($rIDs as $rID) { - if (0 >= intval($rID) || in_array($rID, $rChannels)) { - } else { - $rChannels[] = $rID; - $rChanged = true; - } - } - - if (!$rChanged) { - } else { - $db->query('UPDATE `bouquets` SET `' . $rColumn . '` = ? WHERE `id` = ?;', '[' . implode(',', array_map('intval', $rChannels)) . ']', $rBouquetID); - } - } -} - -function removeFromBouquet($rType, $rBouquetID, $rIDs) { - global $db; - - if (is_array($rIDs)) { - } else { - $rIDs = array($rIDs); - } - - $rBouquet = getBouquet($rBouquetID); - - if (!$rBouquet) { - } else { - if ($rType == 'stream') { - $rColumn = 'bouquet_channels'; - } else { - if ($rType == 'movie') { - $rColumn = 'bouquet_movies'; - } else { - if ($rType == 'radio') { - $rColumn = 'bouquet_radios'; - } else { - $rColumn = 'bouquet_series'; - } - } - } - - - - - - - - - - - $rChanged = false; - $rChannels = confirmIDs(json_decode($rBouquet[$rColumn], true)); - - foreach ($rIDs as $rID) { - if (($rKey = array_search($rID, $rChannels)) === false) { - } else { - unset($rChannels[$rKey]); - $rChanged = true; - } - } - - if (!$rChanged) { - } else { - $db->query('UPDATE `bouquets` SET `' . $rColumn . '` = ? WHERE `id` = ?;', '[' . implode(',', array_map('intval', $rChannels)) . ']', $rBouquetID); - } - } -} - -function confirmIDs($rIDs) { - $rReturn = array(); - - foreach ($rIDs as $rID) { - if (0 >= intval($rID)) { - } else { - $rReturn[] = $rID; - } - } - - return array_unique($rReturn); -} - -function downloadRemoteBackup($rPath, $rFilename) { - require_once MAIN_HOME . 'includes/libs/Dropbox.php'; - $rClient = new DropboxClient(); - - try { - $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); - $rClient->downloadFile($rPath, $rFilename); - - - - return true; - } catch (exception $e) { - return false; - } -} - -function deleteRemoteBackup($rPath) { - require_once MAIN_HOME . 'includes/libs/Dropbox.php'; - $rClient = new DropboxClient(); - - - - - - - - - try { - $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); - $rClient->Delete($rPath); - - - - - return true; - } catch (exception $e) { - - - - - - - - return false; - } -} - -function parserelease($rRelease) { - if (SettingsManager::getAll()['parse_type'] == 'guessit') { - $rCommand = MAIN_HOME . 'bin/guess ' . escapeshellarg(pathinfo($rRelease)['filename'] . '.mkv'); - } else { - $rCommand = '/usr/bin/python3 ' . MAIN_HOME . 'includes/python/release.py ' . escapeshellarg(pathinfo(str_replace('-', '_', $rRelease))['filename']); - } - - return json_decode(shell_exec($rCommand), true); -} - -function scanRecursive($rServerID, $rDirectory, $rAllowed = null) { - return json_decode(systemapirequest($rServerID, array('action' => 'scandir_recursive', 'dir' => $rDirectory, 'allowed' => implode('|', $rAllowed))), true); -} - -function listDir($rServerID, $rDirectory, $rAllowed = null) { - return json_decode(systemapirequest($rServerID, array('action' => 'scandir', 'dir' => $rDirectory, 'allowed' => implode('|', $rAllowed))), true); -} - -function rdeleteBlockedIP($rID) { - global $db; - $db->query('SELECT `id`, `ip` FROM `blocked_ips` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - $rRow = $db->get_row(); - $db->query('DELETE FROM `blocked_ips` WHERE `id` = ?;', $rID); - - if (!file_exists(FLOOD_TMP_PATH . 'block_' . $rRow['ip'])) { - } else { - unlink(FLOOD_TMP_PATH . 'block_' . $rRow['ip']); - } - - return true; -} - -function rdeleteBlockedISP($rID) { - global $db; - $db->query('SELECT `id` FROM `blocked_isps` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - $db->query('DELETE FROM `blocked_isps` WHERE `id` = ?;', $rID); - - - - - - - - - return true; -} - -function rdeleteBlockedUA($rID) { - global $db; - $db->query('SELECT `id` FROM `blocked_uas` WHERE `id` = ?;', $rID); - - - if (0 >= $db->num_rows()) { - - - - return false; - } - - - $db->query('DELETE FROM `blocked_uas` WHERE `id` = ?;', $rID); - - - - - - - return true; -} - -function removeAccessEntry($rID) { - global $db; - $db->query('SELECT `id` FROM `access_codes` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - - $db->query('DELETE FROM `access_codes` WHERE `id` = ?;', $rID); - AuthRepository::updateCodes(); - - - - - return true; -} - -function validateHMAC($rID) { - global $db; - $db->query('SELECT `id` FROM `hmac_keys` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - $db->query('DELETE FROM `hmac_keys` WHERE `id` = ?;', $rID); - - - - - - - - - return true; -} - -function getStills($rTMDBID, $rSeason, $rEpisode) { - $rURL = 'https://api.themoviedb.org/3/tv/' . intval($rTMDBID) . '/season/' . intval($rSeason) . '/episode/' . intval($rEpisode) . '/images?api_key=' . urlencode(SettingsManager::getAll()['tmdb_api_key']); - - - if (0 >= strlen(SettingsManager::getAll()['tmdb_language'])) { - } else { - $rURL .= '&language=' . urlencode(SettingsManager::getAll()['tmdb_language']); - } - - return json_decode(file_get_contents($rURL), true); -} - -function getUserAgents() { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `blocked_uas` ORDER BY `id` ASC;'); - - if (0 >= $db->num_rows()) { - } else { - foreach ($db->get_rows() as $rRow) { - $rReturn[] = $rRow; - } - } - - return $rReturn; -} - -function getISPs() { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `blocked_isps` ORDER BY `id` ASC;'); - - if (0 >= $db->num_rows()) { - } else { - foreach ($db->get_rows() as $rRow) { - $rReturn[] = $rRow; - } - } - - return $rReturn; -} - -function getStreamProviders() { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `providers` ORDER BY `last_changed` DESC;'); - - if (0 >= $db->num_rows()) { - } else { - foreach ($db->get_rows() as $rRow) { - $rReturn[] = $rRow; - } - } - - return $rReturn; -} - -function getStreamProvider($rID) { - global $db; - $db->query('SELECT * FROM `providers` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getExpiring($rLimit = 2419200) { - global $db; - global $rUserInfo; - global $rPermissions; - $rReturn = array(); - $rReports = array_map('intval', array_merge(array($rUserInfo['id']), $rPermissions['all_reports'])); - - if (0 >= count($rReports)) { - } else { - $db->query('SELECT `is_mag`, `is_e2`, `lines`.`id` AS `line_id`, `lines`.`reseller_notes`, `mag_devices`.`mag_id`, `enigma2_devices`.`device_id` AS `e2_id`, `member_id`, `username`, `password`, `exp_date`, `mag_devices`.`mac` AS `mag_mac`, `enigma2_devices`.`mac` AS `e2_mac` FROM `lines` LEFT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines`.`id` LEFT JOIN `enigma2_devices` ON `enigma2_devices`.`user_id` = `lines`.`id` WHERE `member_id` IN (' . implode(',', $rReports) . ') AND `exp_date` IS NOT NULL AND `exp_date` >= ? AND `exp_date` < ? ORDER BY `exp_date` ASC LIMIT 250;', time(), time() + $rLimit); - - foreach ($db->get_rows() as $rRow) { - $rReturn[] = $rRow; - } - } - - return $rReturn; -} - -function getTickets($rID = null, $rAdmin = false) { - global $db; - global $rUserInfo; - global $rPermissions; - $rReturn = array(); - - if ($rID) { - if ($rAdmin) { - $db->query('SELECT `tickets`.`id`, `tickets`.`member_id`, `tickets`.`title`, `tickets`.`status`, `tickets`.`admin_read`, `tickets`.`user_read`, `users`.`username` FROM `tickets`, `users` WHERE `member_id` IN (SELECT `id` FROM `users` WHERE `owner_id` = ?) AND `users`.`id` = `tickets`.`member_id` ORDER BY `id` DESC;', $rID); - } else { - $db->query('SELECT `tickets`.`id`, `tickets`.`member_id`, `tickets`.`title`, `tickets`.`status`, `tickets`.`admin_read`, `tickets`.`user_read`, `users`.`username` FROM `tickets`, `users` WHERE `member_id` IN (' . implode(',', array_map('intval', array_merge(array($rUserInfo['id']), $rPermissions['all_reports']))) . ') AND `users`.`id` = `tickets`.`member_id` ORDER BY `id` DESC;'); - } - } else { - $db->query('SELECT `tickets`.`id`, `tickets`.`member_id`, `tickets`.`title`, `tickets`.`status`, `tickets`.`admin_read`, `tickets`.`user_read`, `users`.`username` FROM `tickets`, `users` WHERE `users`.`id` = `tickets`.`member_id` ORDER BY `id` DESC;'); - } - - if (0 >= $db->num_rows()) { - } else { - foreach ($db->get_rows() as $rRow) { - $db->query('SELECT MIN(`date`) AS `date` FROM `tickets_replies` WHERE `ticket_id` = ?;', $rRow['id']); - - if ($rDate = $db->get_row()['date']) { - $rRow['created'] = date('Y-m-d H:i', $rDate); - } else { - $rRow['created'] = ''; - } - - $db->query('SELECT * FROM `tickets_replies` WHERE `ticket_id` = ? ORDER BY `id` DESC LIMIT 1;', $rRow['id']); - $rLastResponse = $db->get_row(); - $rRow['last_reply'] = date('Y-m-d H:i', $rLastResponse['date']); - - if ($rRow['member_id'] == $rID) { - if ($rRow['status'] == 0) { - } else { - if ($rLastResponse['admin_reply']) { - if ($rRow['user_read'] == 1) { - $rRow['status'] = 3; - } else { - $rRow['status'] = 4; - } - } else { - if ($rRow['admin_read'] == 1) { - $rRow['status'] = 5; - } else { - $rRow['status'] = 2; - } - } - } - } else { - if ($rRow['status'] == 0) { - } else { - if ($rLastResponse['admin_reply']) { - if ($rRow['user_read'] == 1) { - $rRow['status'] = 6; - } else { - $rRow['status'] = 2; - } - } else { - if ($rRow['admin_read'] == 1) { - $rRow['status'] = 5; - } else { - $rRow['status'] = 4; - } - } - } - } - - $rReturn[] = $rRow; - } - } - - return $rReturn; -} - -function cryptPassword($rPassword, $rSalt = null, $rRounds = 20000) { - if ($rSalt === null || $rSalt === '') { - $rSalt = substr(bin2hex(openssl_random_pseudo_bytes(16)), 0, 16); - } - - if (!stripos($rSalt, 'rounds=')) { - $rSalt = sprintf('$6$rounds=%d$%s$', $rRounds, $rSalt); - } - - return crypt($rPassword, $rSalt); -} - -function verifyPassword($rPassword, $rStoredHash) { - return hash_equals($rStoredHash, crypt($rPassword, $rStoredHash)); -} - -function getPermissions($rID) { - global $db; - $db->query('SELECT * FROM `users_groups` WHERE `group_id` = ?;', $rID); - - if ($db->num_rows() == 1) { - $rRow = $db->get_row(); - $rRow['subresellers'] = !empty($rRow['subresellers']) ? json_decode($rRow['subresellers'], true) : []; - - if (count($rRow['subresellers'] ?? []) == 0) { - $rRow['create_sub_resellers'] = 0; - } - - return $rRow; - } - - return []; -} - -function destroySession($rType = 'admin') { - global $_SESSION; - $rKeys = array('admin' => array('hash', 'ip', 'code', 'verify', 'last_activity'), 'reseller' => array('reseller', 'rip', 'rcode', 'rverify', 'rlast_activity'), 'player' => array('phash', 'pverify')); - - foreach ($rKeys[$rType] as $rKey) { - if (!isset($_SESSION[$rKey])) { - } else { - unset($_SESSION[$rKey]); - } - } -} - -function getSelections($rSources) { - global $db; - $rReturn = array(); - - foreach ($rSources as $rSource) { - $db->query("SELECT `id` FROM `streams` WHERE `type` IN (2,5) AND `stream_source` LIKE ? ESCAPE '|' LIMIT 1;", '%' . str_replace('/', '\\/', $rSource) . '"%'); - - if ($db->num_rows() != 1) { - } else { - $rReturn[] = intval($db->get_row()['id']); - } - } - - return $rReturn; -} - -function getBackups() { - $rBackups = array(); - - foreach (scandir(MAIN_HOME . 'backups/') as $rBackup) { - $rInfo = pathinfo(MAIN_HOME . 'backups/' . $rBackup); - - if ($rInfo['extension'] != 'sql') { - } else { - $rBackups[] = array('filename' => $rBackup, 'timestamp' => filemtime(MAIN_HOME . 'backups/' . $rBackup), 'date' => date('Y-m-d H:i:s', filemtime(MAIN_HOME . 'backups/' . $rBackup)), 'filesize' => filesize(MAIN_HOME . 'backups/' . $rBackup)); - } - } - usort( - $rBackups, - function ($a, $b) { - return $a['timestamp']; - } - ); - - return $rBackups; -} - -function checkRemote() { - require_once MAIN_HOME . 'includes/libs/Dropbox.php'; - - try { - $rClient = new DropboxClient(); - $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); - $rClient->GetFiles(); - - return true; - } catch (exception $e) { - return false; - } -} - -function getRemoteBackups() { - - require_once MAIN_HOME . 'includes/libs/Dropbox.php'; - - - try { - $rClient = new DropboxClient(); - $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); - $rFiles = $rClient->GetFiles(); - } catch (exception $e) { - $rFiles = array(); - } - $rBackups = array(); - - foreach ($rFiles as $rFile) { - try { - if (!(!$rFile->isDir && strtolower(pathinfo($rFile->name)['extension']) == 'sql' && 0 < $rFile->size)) { - } else { - $rJSON = json_decode(json_encode($rFile, JSON_UNESCAPED_UNICODE), true); - $rJSON['time'] = strtotime($rFile->server_modified); - $rBackups[] = $rJSON; - } - } catch (exception $e) { - } - } - array_multisort(array_column($rBackups, 'time'), SORT_ASC, $rBackups); - - return $rBackups; -} - -function uploadRemoteBackup($rPath, $rFilename, $rOverwrite = true) { - require_once MAIN_HOME . 'includes/libs/Dropbox.php'; - $rClient = new DropboxClient(); - - try { - $rClient->SetBearerToken(array('t' => SettingsManager::getAll()['dropbox_token'])); - - return $rClient->UploadFile($rFilename, $rPath, $rOverwrite); - } catch (exception $e) { - return (object) array('error' => $e); - } -} - -function restoreImages() { - global $db; - global $rServers; - foreach (array_keys($rServers) as $rServerID) { - if (!$rServers[$rServerID]['server_online']) { - } else { - systemapirequest($rServerID, array('action' => 'restore_images')); - } - } - - return true; -} - -function killPlexSync() { - global $db; - $db->query("SELECT DISTINCT(`server_id`) AS `server_id` FROM `watch_folders` WHERE `active` = 1 AND `type` = 'plex';"); - - global $rServers; - foreach ($db->get_rows() as $rRow) { - if (!$rServers[$rRow['server_id']]['server_online']) { - } else { - systemapirequest($rRow['server_id'], array('action' => 'kill_plex')); - } - } - - return true; -} - -function getPIDs($rServerID) { - $rReturn = array(); - $rProcesses = json_decode(systemapirequest($rServerID, array('action' => 'get_pids')), true); - if (!is_array($rProcesses)) { - return $rReturn; - } - array_shift($rProcesses); - - foreach ($rProcesses as $rProcess) { - $rSplit = explode(' ', preg_replace('!\\s+!', ' ', trim($rProcess))); - - if ($rSplit[0] == 'xc_vm') { - $rUsage = array(0, 0, 0); - $rTimer = explode('-', $rSplit[9]); - - if (1 < count($rTimer)) { - $rDays = intval($rTimer[0]); - $rTime = $rTimer[1]; - } else { - $rDays = 0; - $rTime = $rTimer[0]; - } - - $rTime = explode(':', $rTime); - - if (count($rTime) == 3) { - $rSeconds = intval($rTime[0]) * 3600 + intval($rTime[1]) * 60 + intval($rTime[2]); - } else { - if (count($rTime) == 2) { - $rSeconds = intval($rTime[0]) * 60 + intval($rTime[1]); - } else { - $rSeconds = intval($rTime[2]); - } - } - - - $rUsage[0] = $rSeconds + $rDays * 86400; - $rTimer = explode('-', $rSplit[8]); - - if (1 < count($rTimer)) { - $rDays = intval($rTimer[0]); - $rTime = $rTimer[1]; - } else { - $rDays = 0; - $rTime = $rTimer[0]; - } - - $rTime = explode(':', $rTime); - - if (count($rTime) == 3) { - $rSeconds = intval($rTime[0]) * 3600 + intval($rTime[1]) * 60 + intval($rTime[2]); - } else { - if (count($rTime) == 2) { - $rSeconds = intval($rTime[0]) * 60 + intval($rTime[1]); - } else { - $rSeconds = intval($rTime[2]); - } - } - - $rUsage[1] = $rSeconds + $rDays * 86400; - if ($rUsage[0] != 0) { - $rUsage[2] = $rUsage[1] / $rUsage[0] * 100; - } else { - $rUsage[2] = 0; - } - - $rReturn[] = array('user' => $rSplit[0], 'pid' => $rSplit[1], 'cpu' => $rSplit[2], 'mem' => $rSplit[3], 'vsz' => $rSplit[4], 'rss' => $rSplit[5], 'tty' => $rSplit[6], 'stat' => $rSplit[7], 'time' => $rUsage[1], 'etime' => $rUsage[0], 'load_average' => $rUsage[2], 'command' => implode(' ', array_splice($rSplit, 10, count($rSplit) - 10))); - } - } - - return $rReturn; -} - -function clearSettingsCache() { - unlink(CACHE_TMP_PATH . 'settings'); -} - -function deleteUser($rID, $rDeleteSubUsers = false, $rDeleteLines = false, $rReplaceWith = null) { - global $db; - $rUser = UserRepository::getRegisteredUserById($rID); - - if (!$rUser) { - return false; - } - - $db->query('DELETE FROM `users` WHERE `id` = ?;', $rID); - $db->query('DELETE FROM `users_credits_logs` WHERE `admin_id` = ?;', $rID); - $db->query('DELETE FROM `users_logs` WHERE `owner` = ?;', $rID); - $db->query('DELETE FROM `tickets_replies` WHERE `ticket_id` IN (SELECT `id` FROM `tickets` WHERE `member_id` = ?);', $rID); - $db->query('DELETE FROM `tickets` WHERE `member_id` = ?;', $rID); - - if ($rDeleteSubUsers) { - $db->query('SELECT `id` FROM `users` WHERE `owner_id` = ?;', $rID); - - foreach ($db->get_rows() as $rRow) { - deleteUser($rRow['id'], $rDeleteSubUsers, $rDeleteLines, $rReplaceWith); - } - } else { - $db->query('UPDATE `users` SET `owner_id` = ? WHERE `owner_id` = ?;', $rReplaceWith, $rID); - } - - if ($rDeleteLines) { - $db->query('SELECT `id` FROM `lines` WHERE `member_id` = ?;', $rID); - - foreach ($db->get_rows() as $rRow) { - deleteLine($rRow['id']); - } - } else { - $db->query('UPDATE `lines` SET `member_id` = ? WHERE `member_id` = ?;', $rReplaceWith, $rID); - } - - return true; -} - -function deleteUsers($rIDs) { - global $db; - $rIDs = confirmids($rIDs); - - if (0 >= count($rIDs)) { - return false; - } - - $db->query('DELETE FROM `users` WHERE `id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `users_credits_logs` WHERE `admin_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `users_logs` WHERE `owner` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `tickets_replies` WHERE `ticket_id` IN (SELECT `id` FROM `tickets` WHERE `member_id` IN (' . implode(',', $rIDs) . '));'); - $db->query('DELETE FROM `tickets` WHERE `member_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('UPDATE `users` SET `owner_id` = NULL WHERE `owner_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('UPDATE `lines` SET `member_id` = NULL WHERE `member_id` IN (' . implode(',', $rIDs) . ');'); - - return true; -} - -function deleteStream($rID, $rServerID = -1, $rDeleteFiles = true, $f2d619cb38696890 = true) { - global $db; - $db->query('SELECT `id`, `type` FROM `streams` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - $rType = $db->get_row()['type']; - $rRemaining = 0; - - if ($rServerID == -1) { - } else { - $db->query('SELECT `server_stream_id` FROM `streams_servers` WHERE `stream_id` = ? AND `server_id` <> ?;', $rID, $rServerID); - $rRemaining = $db->num_rows(); - } - - if ($rRemaining == 0 && $f2d619cb38696890) { - $db->query('DELETE FROM `lines_logs` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `mag_claims` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `streams` WHERE `id` = ?;', $rID); - $db->query('DELETE FROM `streams_episodes` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `streams_errors` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `streams_logs` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `streams_options` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `streams_stats` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `watch_refresh` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `watch_logs` WHERE `stream_id` = ?;', $rID); - $db->query('DELETE FROM `recordings` WHERE `created_id` = ? OR `stream_id` = ?;', $rID, $rID); - $db->query('UPDATE `lines_activity` SET `stream_id` = 0 WHERE `stream_id` = ?;', $rID); - $db->query('SELECT `server_id` FROM `streams_servers` WHERE `stream_id` = ?;', $rID); - $rServerIDs = array(); - - foreach ($db->get_rows() as $rRow) { - $rServerIDs[] = $rRow['server_id']; - } - - if (!($rDeleteFiles && 0 < count($rServerIDs) && in_array($rType, array(2, 5)))) { - } else { - MovieService::deleteFile($rServerIDs, $rID); - } - - $db->query('DELETE FROM `streams_servers` WHERE `stream_id` = ?;', $rID); - } else { - $rServerIDs = array($rServerID); - $db->query('DELETE FROM `streams_servers` WHERE `stream_id` = ? AND `server_id` = ?;', $rID, $rServerID); - - if (!($rDeleteFiles && in_array($rType, array(2, 5)))) { - } else { - MovieService::deleteFile(array($rServerID), $rID); - } - } - - $db->query('DELETE FROM `streams_servers` WHERE `parent_id` IS NOT NULL AND `parent_id` > 0 AND `parent_id` NOT IN (SELECT `id` FROM `servers` WHERE `server_type` = 0);'); - StreamProcess::updateStream($rID); - BouquetService::scan(); - - return true; -} - -function deleteStreams($rIDs, $rDeleteFiles = false) { - global $db; - $rIDs = confirmids($rIDs); - - - if (0 >= count($rIDs)) { - } else { - $db->query('DELETE FROM `lines_logs` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `mag_claims` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams` WHERE `id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_episodes` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_errors` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_logs` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_options` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_stats` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `watch_refresh` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `watch_logs` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `lines_live` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `recordings` WHERE `created_id` IN (' . implode(',', $rIDs) . ') OR `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('UPDATE `lines_activity` SET `stream_id` = 0 WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('SELECT `server_id` FROM `streams_servers` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_servers` WHERE `stream_id` IN (' . implode(',', $rIDs) . ');'); - $db->query('DELETE FROM `streams_servers` WHERE `parent_id` IS NOT NULL AND `parent_id` > 0 AND `parent_id` NOT IN (SELECT `id` FROM `servers` WHERE `server_type` = 0);'); - $db->query('INSERT INTO `signals`(`server_id`, `cache`, `time`, `custom_data`) VALUES(?, 1, ?, ?);', SERVER_ID, time(), json_encode(array('type' => 'update_streams', 'id' => $rIDs))); - - if ($rDeleteFiles) { - foreach (array_keys(ServerRepository::getAll()) as $rServerID) { - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`, `cache`) VALUES(?, ?, ?, 1);', $rServerID, time(), json_encode(array('type' => 'delete_vods', 'id' => $rIDs))); - } - } - - BouquetService::scan(); - } - - return true; -} - -function deleteStreamsByServer($rIDs, $rServerID, $rDeleteFiles = false) { - global $db; - $rIDs = confirmids($rIDs); - - if (0 >= count($rIDs)) { - } else { - $db->query('DELETE FROM `streams_servers` WHERE `server_id` = ? AND `stream_id` IN (' . implode(',', $rIDs) . ');', $rServerID); - $db->query('UPDATE `streams_servers` SET `parent_id` = NULL WHERE `parent_id` = ? AND `stream_id` IN (' . implode(',', $rIDs) . ');', $rServerID); - - if ($rDeleteFiles) { - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`, `cache`) VALUES(?, ?, ?, 1);', $rServerID, time(), json_encode(array('type' => 'delete_vods', 'id' => $rIDs))); - } - - // The panel will rescan itself within a minute. - // scanBouquets(); - } - - return true; -} - -function flushIPs() { - global $db; - global $rServers; - global $rProxyServers; - $db->query('TRUNCATE `blocked_ips`;'); - shell_exec('rm ' . FLOOD_TMP_PATH . 'block_*'); - - foreach ($rServers as $rServer) { - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServer['id'], time(), json_encode(array('action' => 'flush'))); - } - - foreach ($rProxyServers as $rServer) { - $db->query('INSERT INTO `signals`(`server_id`, `time`, `custom_data`) VALUES(?, ?, ?);', $rServer['id'], time(), json_encode(array('action' => 'flush'))); - } - - return true; -} - -function addTMDbCategories() { - global $db; - require_once MAIN_HOME . 'includes/libs/tmdb.php'; - - if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); - } else { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key']); - } - - $rCurrentCats = array('movie' => array(), 'series' => array()); - - $db->query('SELECT `id`, `category_type`, `category_name` FROM `streams_categories`;'); - - if ($db->num_rows() > 0) { - foreach ($db->get_rows() as $rRow) { - if (array_key_exists($rRow['category_type'], $rCurrentCats)) { - $rCurrentCats[$rRow['category_type']][] = $rRow['category_name']; - } - } - } - - $rMovieGenres = $rTMDB->getMovieGenres(); - foreach ($rMovieGenres as $rMovieGenre) { - $movieGenreName = $rMovieGenre->getName(); - if (!in_array($movieGenreName, $rCurrentCats['movie'])) { - $db->query("INSERT INTO `streams_categories`(`category_type`, `category_name`) VALUES('movie', ?);", $movieGenreName); - } - } - - $rTVGenres = $rTMDB->getTVGenres(); - foreach ($rTVGenres as $rTVGenre) { - $seriesGenreName = $rTVGenre->getName(); - if (!in_array($seriesGenreName, $rCurrentCats['series'])) { - $db->query("INSERT INTO `streams_categories`(`category_type`, `category_name`) VALUES('series', ?);", $seriesGenreName); - } - } - - return true; -} - -function updateTMDbCategories() { - global $db; - require_once MAIN_HOME . 'includes/libs/tmdb.php'; - - if (0 < strlen(SettingsManager::getAll()['tmdb_language'])) { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key'], SettingsManager::getAll()['tmdb_language']); - } else { - $rTMDB = new TMDB(SettingsManager::getAll()['tmdb_api_key']); - } - - $rCurrentCats = array(1 => array(), 2 => array()); - $db->query('SELECT `id`, `type`, `genre_id` FROM `watch_categories`;'); - - if ($db->num_rows() > 0) { - foreach ($db->get_rows() as $rRow) { - if (array_key_exists($rRow['type'], $rCurrentCats)) { - - if (in_array($rRow['genre_id'], $rCurrentCats[$rRow['type']])) { - $db->query('DELETE FROM `watch_categories` WHERE `id` = ?;', $rRow['id']); - } - $rCurrentCats[$rRow['type']][] = $rRow['genre_id']; - } - } - } - - $rMovieGenres = $rTMDB->getMovieGenres(); - - foreach ($rMovieGenres as $rMovieGenre) { - if (!in_array($rMovieGenre->getID(), $rCurrentCats[1])) { - $db->query("INSERT INTO `watch_categories`(`type`, `genre_id`, `genre`, `category_id`, `bouquets`) VALUES(1, ?, ?, 0, '[]');", $rMovieGenre->getID(), $rMovieGenre->getName()); - } - - if (!in_array($rMovieGenre->getID(), $rCurrentCats[2])) { - $db->query("INSERT INTO `watch_categories`(`type`, `genre_id`, `genre`, `category_id`, `bouquets`) VALUES(2, ?, ?, 0, '[]');", $rMovieGenre->getID(), $rMovieGenre->getName()); - } - } - - $rTVGenres = $rTMDB->getTVGenres(); - - foreach ($rTVGenres as $rTVGenre) { - if (!in_array($rTVGenre->getID(), $rCurrentCats[1])) { - $db->query("INSERT INTO `watch_categories`(`type`, `genre_id`, `genre`, `category_id`, `bouquets`) VALUES(1, ?, ?, 0, '[]');", $rTVGenre->getID(), $rTVGenre->getName()); - } - - if (!in_array($rTVGenre->getID(), $rCurrentCats[2])) { - $db->query("INSERT INTO `watch_categories`(`type`, `genre_id`, `genre`, `category_id`, `bouquets`) VALUES(2, ?, ?, 0, '[]');", $rTVGenre->getID(), $rTVGenre->getName()); - } - } -} - -function goHome() { - header('Location: dashboard'); - - exit(); -} - -function checkResellerPermissions($rPage = null) { - global $rPermissions; - - if ($rPage) { - } else { - $rPage = strtolower(basename($_SERVER['SCRIPT_FILENAME'], '.php')); - } - - switch ($rPage) { - case 'user': - case 'users': - return $rPermissions['create_sub_resellers']; - - case 'line': - case 'lines': - return $rPermissions['create_line']; - - case 'mag': - case 'mags': - return $rPermissions['create_mag']; - - case 'enigma': - case 'enigmas': - return $rPermissions['create_enigma']; - - case 'epg_view': - case 'streams': - case 'created_channels': - case 'movies': - case 'episodes': - case 'radios': - return $rPermissions['can_view_vod']; - - case 'live_connections': - case 'line_activity': - return $rPermissions['reseller_client_connection_logs']; - } - - return true; -} - -function checkPermissions($rPage = null) { - if ($rPage) { - } else { - $rPage = strtolower(basename($_SERVER['SCRIPT_FILENAME'], '.php')); - } - - switch ($rPage) { - case 'isps': - case 'isp': - case 'asns': - return Authorization::check('adv', 'block_isps'); - - case 'bouquet': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_bouquet')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_bouquet')) { - } else { - return true; - } - - // no break - case 'bouquet_order': - case 'bouquet_sort': - return Authorization::check('adv', 'edit_bouquet'); - - case 'bouquets': - return Authorization::check('adv', 'bouquets'); - - case 'channel_order': - return Authorization::check('adv', 'channel_order'); - - case 'client_logs': - return Authorization::check('adv', 'client_request_log'); - - case 'created_channel': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_cchannel')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'create_channel')) { - } else { - return true; - } - - // no break - case 'code': - case 'codes': - return Authorization::check('adv', 'add_code'); - - case 'hmac': - case 'hmacs': - return Authorization::check('adv', 'add_hmac'); - - case 'credit_logs': - return Authorization::check('adv', 'credits_log'); - - case 'enigmas': - return Authorization::check('adv', 'manage_e2'); - - case 'epg': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'epg_edit')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_epg')) { - } else { - return true; - } - - // no break - case 'epgs': - return Authorization::check('adv', 'epg'); - - case 'episode': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_episode')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_episode')) { - } else { - return true; - } - - // no break - case 'episodes': - return Authorization::check('adv', 'episodes'); - - case 'series_mass': - case 'episodes_mass': - return Authorization::check('adv', 'mass_sedits'); - - case 'fingerprint': - return Authorization::check('adv', 'fingerprint'); - - case 'group': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_group')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_group')) { - } else { - return true; - } - - // no break - case 'groups': - return Authorization::check('adv', 'mng_groups'); - - case 'ip': - case 'ips': - return Authorization::check('adv', 'block_ips'); - - case 'live_connections': - return Authorization::check('adv', 'live_connections'); - - case 'mag': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_mag')) { - return true; - } - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_mag')) { - break; - } - return true; - case 'mag_events': - return Authorization::check('adv', 'manage_events'); - case 'mags': - return Authorization::check('adv', 'manage_mag'); - - case 'mass_delete': - return Authorization::check('adv', 'mass_delete'); - - case 'record': - return Authorization::check('adv', 'add_movie'); - case 'recordings': - return Authorization::check('adv', 'movies'); - case 'queue': - return Authorization::check('adv', 'streams') || Authorization::check('adv', 'episodes') || Authorization::check('adv', 'series'); - case 'movie': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_movie')) { - return true; - } - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_movie')) { - } else { - if (isset(RequestManager::getAll()['import']) && !Authorization::check('adv', 'import_movies')) { - } else { - return true; - } - } - break; - case 'movie_mass': - return Authorization::check('adv', 'mass_sedits_vod'); - case 'movies': - return Authorization::check('adv', 'movies'); - case 'package': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_package')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_packages')) { - break; - } - return true; - case 'packages': - case 'addons': - return Authorization::check('adv', 'mng_packages'); - - case 'player': - return Authorization::check('adv', 'player'); - - case 'process_monitor': - return Authorization::check('adv', 'process_monitor'); - - case 'profile': - return Authorization::check('adv', 'tprofile'); - - case 'profiles': - return Authorization::check('adv', 'tprofiles'); - - case 'radio': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_radio')) { - return true; - } - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_radio')) { - break; - } - return true; - case 'radio_mass': - return Authorization::check('adv', 'mass_edit_radio'); - case 'radios': - return Authorization::check('adv', 'radio'); - case 'user': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_reguser')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_reguser')) { - break; - } - return true; - case 'user_logs': - return Authorization::check('adv', 'reg_userlog'); - case 'users': - return Authorization::check('adv', 'mng_regusers'); - case 'rtmp_ip': - return Authorization::check('adv', 'add_rtmp'); - case 'rtmp_ips': - case 'rtmp_monitor': - return Authorization::check('adv', 'rtmp'); - case 'serie': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_series')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_series')) { - break; - } - return true; - case 'series': - return Authorization::check('adv', 'series'); - case 'series_order': - return Authorization::check('adv', 'edit_series'); - case 'server': - case 'proxy': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_server')) { - return true; - } - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_server')) { - break; - } - return true; - case 'server_install': - return Authorization::check('adv', 'add_server'); - case 'servers': - case 'server_view': - case 'server_order': - case 'proxies': - return Authorization::check('adv', 'servers'); - - case 'settings': - return Authorization::check('adv', 'settings'); - - case 'backups': - case 'cache': - case 'setup': - return Authorization::check('adv', 'database'); - - case 'settings_watch': - case 'settings_plex': - return Authorization::check('adv', 'folder_watch_settings'); - - case 'stream': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_stream')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_stream')) { - } else { - if (isset(RequestManager::getAll()['import']) && !Authorization::check('adv', 'import_streams')) { - } else { - return true; - } - } - - break; - - case 'review': - return Authorization::check('adv', 'import_streams'); - - case 'mass_edit_streams': - return Authorization::check('adv', 'edit_stream'); - - case 'stream_categories': - return Authorization::check('adv', 'categories'); - - case 'stream_category': - return Authorization::check('adv', 'add_cat'); - - case 'stream_errors': - return Authorization::check('adv', 'stream_errors'); - - case 'created_channel_mass': - case 'stream_mass': - return Authorization::check('adv', 'mass_edit_streams'); - - case 'user_mass': - return Authorization::check('adv', 'mass_edit_users'); - - case 'mag_mass': - return Authorization::check('adv', 'mass_edit_mags'); - - - - case 'enigma_mass': - return Authorization::check('adv', 'mass_edit_enigmas'); - - - case 'quick_tools': - return Authorization::check('adv', 'quick_tools'); - - - - case 'stream_tools': - return Authorization::check('adv', 'stream_tools'); - - - - - - - case 'stream_view': - case 'provider': - case 'providers': - case 'streams': - case 'epg_view': - case 'created_channels': - case 'stream_rank': - case 'archive': - return Authorization::check('adv', 'streams'); - - case 'ticket': - return Authorization::check('adv', 'ticket'); - - case 'ticket_view': - case 'tickets': - return Authorization::check('adv', 'manage_tickets'); - - case 'line': - if (isset(RequestManager::getAll()['id']) && Authorization::check('adv', 'edit_user')) { - return true; - } - - if (isset(RequestManager::getAll()['id']) || !Authorization::check('adv', 'add_user')) { - break; - } - - - - return true; - - - case 'line_activity': - case 'theft_detection': - case 'line_ips': - return Authorization::check('adv', 'connection_logs'); - - case 'line_mass': - return Authorization::check('adv', 'mass_edit_lines'); - - - case 'useragents': - case 'useragent': - return Authorization::check('adv', 'block_uas'); - - - - - - - - - - - - case 'lines': - return Authorization::check('adv', 'users'); - - - case 'plex': - case 'watch': - return Authorization::check('adv', 'folder_watch'); - - - - case 'plex_add': - case 'watch_add': - return Authorization::check('adv', 'folder_watch_add'); - - case 'watch_output': - return Authorization::check('adv', 'folder_watch_output'); - - - - case 'mysql_syslog': - case 'panel_logs': - return Authorization::check('adv', 'panel_logs'); - - - - - - - - case 'login_logs': - return Authorization::check('adv', 'login_logs'); - - case 'restream_logs': - return Authorization::check('adv', 'restream_logs'); - - - - - default: - return true; - } -} - -function getPackages($rGroup = null, $rType = null) { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `users_packages` ORDER BY `id` ASC;'); - - if (0 >= $db->num_rows()) { - } else { - foreach ($db->get_rows() as $rRow) { - if (isset($rGroup) && !in_array(intval($rGroup), json_decode($rRow['groups'], true))) { - } else { - if ($rType && !$rRow['is_' . $rType]) { - } else { - $rReturn[intval($rRow['id'])] = $rRow; - } - } - } - } - - return $rReturn; -} - - - - - -function checkCompatible($rIDA, $rIDB) { - $rPackageA = getPackage($rIDA); - $rPackageB = getPackage($rIDB); - $rCompatible = true; - - if (!($rPackageA && $rPackageB)) { - } else { - foreach (array('bouquets', 'output_formats') as $rKey) { - if (json_decode($rPackageA[$rKey], true) == json_decode($rPackageB[$rKey], true)) { - } else { - $rCompatible = false; - } - } - - foreach (array('is_restreamer', 'is_isplock', 'max_connections', 'force_server_id', 'forced_country', 'lock_device') as $rKey) { - if ($rPackageA[$rKey] == $rPackageB[$rKey]) { - } else { - $rCompatible = false; - } - } - } - - return $rCompatible; -} - -function getPackage($rID) { - global $db; - $db->query('SELECT * FROM `users_packages` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getcodes($rType = null) { - global $db; - $rReturn = array(); - - if (!is_null($rType)) { - $db->query('SELECT * FROM `access_codes` WHERE `type` = ? ORDER BY `id` ASC;', $rType); - } else { - $db->query('SELECT * FROM `access_codes` ORDER BY `id` ASC;'); - } - - if (0 >= $db->num_rows()) { - } else { - foreach ($db->get_rows() as $rRow) { - $rReturn[intval($rRow['id'])] = $rRow; - } - } - - return $rReturn; -} - -function getCode($rID) { - global $db; - $db->query('SELECT * FROM `access_codes` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getBarColour($rInt) { - if (75 <= $rInt) { - return 'bg-danger'; - } - - if (50 <= $rInt) { - return 'bg-warning'; - } - - return 'bg-success'; -} - -function getNVENCProcesses($rServerID) { - global $db; - $rProcesses = array(); - $rServer = getStreamingServersByID($rServerID); - $rGPUInfo = json_decode($rServer['gpu_info'], true); - - if (!is_array($rGPUInfo)) { - } else { - foreach ($rGPUInfo['gpus'] as $rGPU) { - foreach ($rGPU['processes'] as $rProcess) { - $rArray = array('pid' => $rProcess['pid'], 'memory' => $rProcess['memory'], 'stream_id' => null); - $db->query('SELECT `stream_id` FROM `streams_servers` WHERE `pid` = ? AND `server_id` = ?;', $rProcess['pid'], $rServerID); - - if (0 >= $db->num_rows()) { - } else { - $rArray['stream_id'] = $db->get_row()['stream_id']; - } - - $rProcesses[] = $rArray; - } - } - } - - return $rProcesses; -} - -function deleteLine($rID, $rDeletePaired = false, $rCloseCons = true) { - global $db; - $rLine = UserRepository::getLineById($rID); - - if (!$rLine) { - return false; - } - - - LineService::deleteLineSignal($rID); - $db->query('DELETE FROM `lines` WHERE `id` = ?;', $rID); - $db->query('DELETE FROM `lines_logs` WHERE `user_id` = ?;', $rID); - $db->query('UPDATE `lines_activity` SET `user_id` = 0 WHERE `user_id` = ?;', $rID); - - if (!$rCloseCons) { - } else { - if (SettingsManager::getAll()['redis_handler']) { - foreach (ConnectionTracker::getRedisConnections($rID, null, null, true, false, false) as $rConnection) { - ConnectionTracker::closeConnection($rConnection); - } - } else { - $db->query('SELECT * FROM `lines_live` WHERE `user_id` = ?;', $rID); - - foreach ($db->get_rows() as $rRow) { - ConnectionTracker::closeConnection($rRow); - } - } - } - - $db->query('SELECT `id` FROM `lines` WHERE `pair_id` = ?;', $rID); - - foreach ($db->get_rows() as $rRow) { - if ($rDeletePaired) { - deleteLine($rRow['id'], true, $rCloseCons); - } else { - $db->query('UPDATE `lines` SET `pair_id` = null WHERE `id` = ?;', $rRow['id']); - LineService::updateLineSignal($rRow['id']); - } - } - - return true; -} - -function deleteRTMPIP($rID) { - global $db; - $db->query('SELECT `id` FROM `rtmp_ips` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - $db->query('DELETE FROM `rtmp_ips` WHERE `id` = ?;', $rID); - - return true; -} - -function deleteWatchFolder($rID) { - global $db; - $db->query('SELECT `id` FROM `watch_folders` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - - - $db->query('DELETE FROM `watch_folders` WHERE `id` = ?;', $rID); - - - - - - return true; -} - -function deleteTicket($rID) { - global $db; - $db->query('SELECT `id` FROM `tickets` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - return false; - } - - $db->query('DELETE FROM `tickets` WHERE `id` = ?;', $rID); - $db->query('DELETE FROM `tickets_replies` WHERE `ticket_id` = ?;', $rID); - - return true; -} - -function canGenerateTrials($rUserID) { - global $db; - global $rSettings; - $rUser = UserRepository::getRegisteredUserById($rUserID); - $rPermissions = getPermissions($rUser['member_group_id']); - - if ($rSettings['disable_trial']) { - return false; - } - - if (floatval($rUser['credits']) < floatval($rPermissions['minimum_trial_credits'])) { - return false; - } - - $rTotal = $rPermissions['total_allowed_gen_trials']; - - - - - - if (0 >= $rTotal) { - return false; - } - - - - - - - - - - $rTotalIn = $rPermissions['total_allowed_gen_in']; - - - - - - if ($rTotalIn == 'hours') { - $rTime = time() - intval($rTotal) * 3600; - } else { - $rTime = time() - intval($rTotal) * 3600 * 24; - } - - $db->query('SELECT COUNT(`id`) AS `count` FROM `lines` WHERE `member_id` = ? AND `created_at` >= ? AND `is_trial` = 1;', $rUser['id'], $rTime); - - return $db->get_row()['count'] < $rTotal; -} - -function getGroupPermissions($rUserID, $rStreams = true, $rUsers = true) { - global $db; - $rStart = round(microtime(true) * 1000); - $rReturn = array('create_line' => false, 'create_mag' => false, 'create_enigma' => false, 'stream_ids' => array(), 'series_ids' => array(), 'category_ids' => array(), 'users' => array(), 'direct_reports' => array(), 'all_reports' => array(), 'report_map' => array()); - $rUser = UserRepository::getRegisteredUserById($rUserID); - - if (!$rUser) { - } else { - if (!file_exists(CACHE_TMP_PATH . 'permissions_' . intval($rUser['member_group_id']))) { - } else { - $rPermData = igbinary_unserialize(file_get_contents(CACHE_TMP_PATH . 'permissions_' . intval($rUser['member_group_id']))); - if (is_array($rPermData)) { - $rReturn = array_merge($rReturn, $rPermData); - } - } - - $db->query("SELECT * FROM `users_packages` WHERE JSON_CONTAINS(`groups`, ?, '\$');", $rUser['member_group_id']); - - - - foreach ($db->get_rows() as $rRow) { - if (!$rRow['is_line']) { - } else { - $rReturn['create_line'] = true; - } - - if (!$rRow['is_mag']) { - } else { - $rReturn['create_mag'] = true; - } - - if (!$rRow['is_e2']) { - } else { - $rReturn['create_enigma'] = true; - } - } - - if (!$rUsers) { - } else { - $rReturn['users'] = UserRepository::getSubUsers($rUser['id']); - - foreach ($rReturn['users'] as $rUserID => $rUserData) { - if ($rUser['id'] != $rUserData['parent']) { - } else { - $rReturn['direct_reports'][] = $rUserID; - } - - $rReturn['all_reports'][] = $rUserID; - } - } - } - - return $rReturn; -} - -function grantPrivilegesToAllServers() { - global $rServers; - - foreach ($rServers as $rServerID => $rServerArray) { - BackupService::grantPrivileges($rServerArray['server_ip'], DatabaseFactory::get(), ConfigReader::getAll()); - } -} - -function getTranscodeProfile($rID) { - global $db; - $db->query('SELECT * FROM `profiles` WHERE `profile_id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getUserAgent($rID) { - global $db; - $db->query('SELECT * FROM `blocked_uas` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getCategory($rID) { - global $db; - $db->query('SELECT * FROM `streams_categories` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - return false; - } - - return $db->get_row(); -} - -function getMag($rID) { - global $db; - $db->query('SELECT * FROM `mag_devices` WHERE `mag_id` = ?;', $rID); - - if ($db->num_rows() != 1) { - return array(); - } - - $rRow = $db->get_row(); - $rRow['user'] = UserRepository::getLineById($rRow['user_id']); - $db->query('SELECT `pair_id` FROM `lines` WHERE `id` = ?;', $rRow['user_id']); - - if ($db->num_rows() != 1) { - } else { - $rRow['paired'] = UserRepository::getLineById($rRow['user']['pair_id']); - } - - - - return $rRow; -} - -function getEnigma($rID) { - global $db; - $db->query('SELECT * FROM `enigma2_devices` WHERE `device_id` = ?;', $rID); - - if ($db->num_rows() != 1) { - return array(); - } - - $rRow = $db->get_row(); - $rRow['user'] = UserRepository::getLineById($rRow['user_id']); - - $db->query('SELECT `pair_id` FROM `lines` WHERE `id` = ?;', $rRow['user_id']); - - if ($db->num_rows() != 1) { - } else { - $rRow['paired'] = UserRepository::getLineById($rRow['user']['pair_id']); - } - - return $rRow; -} - -function getE2User($rID) { - global $db; - $db->query('SELECT * FROM `enigma2_devices` WHERE `user_id` = ?;', $rID); - - if ($db->num_rows() != 1) { - return ''; - } - - return $db->get_row(); -} - -function getTicket($rID) { - global $db; - $db->query('SELECT * FROM `tickets` WHERE `id` = ?;', $rID); - - if (0 >= $db->num_rows()) { - } else { - $rRow = $db->get_row(); - $rRow['replies'] = array(); - $rRow['title'] = htmlspecialchars($rRow['title']); - $db->query('SELECT * FROM `tickets_replies` WHERE `ticket_id` = ? ORDER BY `date` ASC;', $rID); - - foreach ($db->get_rows() as $rReply) { - $rReply['message'] = htmlspecialchars($rReply['message']); - - if (strlen($rReply['message']) >= 80) { - } else { - $rReply['message'] .= str_repeat('  ', 80 - strlen($rReply['message'])); - } - - $rRow['replies'][] = $rReply; - } - $rRow['user'] = UserRepository::getRegisteredUserById($rRow['member_id']); - return $rRow; - } -} - -function getISP($rID) { - global $db; - $db->query('SELECT * FROM `blocked_isps` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getRTMPIP($rID) { - global $db; - $db->query('SELECT * FROM `rtmp_ips` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - } else { - return $db->get_row(); - } -} - -function getEPGs() { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `epg` ORDER BY `id` ASC;'); - - if ($db->num_rows() > 0) { - foreach ($db->get_rows() as $rRow) { - $rReturn[intval($rRow['id'])] = $rRow; - } - } - - return $rReturn; -} - -function getChannels($rType = 'live') { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `streams_categories` WHERE `category_type` = ? ORDER BY `cat_order` ASC;', $rType); - - if (0 >= $db->num_rows()) { - } else { - - foreach ($db->get_rows() as $rRow) { - $rReturn[intval($rRow['id'])] = $rRow; - } - } - - return $rReturn; -} - -function getChannelsByID($rID) { - global $db; - $db->query('SELECT * FROM `streams` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - return false; - } - - return $db->get_row(); -} - -function getStreamingServersByID($rID) { - global $db; - $db->query('SELECT * FROM `servers` WHERE `id` = ?;', $rID); - - if ($db->num_rows() != 1) { - return false; - } - - return $db->get_row(); -} - -function getLiveConnections($rServerID, $rProxy = false) { - global $db; - - if (SettingsManager::getAll()['redis_handler']) { - $rCount = 0; - - - if ($rProxy) { - $rParentIDs = ServerRepository::getAll()[$rServerID]['parent_id']; - - foreach ($rParentIDs as $rParentID) { - foreach (ConnectionTracker::getRedisConnections(null, $rParentID, null, true, false, false) as $rConnection) { - if ($rConnection['proxy_id'] != $rServerID) { - } else { - $rCount++; - } - } - } - } else { - list($rCount) = ConnectionTracker::getRedisConnections(null, $rServerID, null, true, true, false); - } - - return $rCount; - } else { - if ($rProxy) { - $db->query('SELECT COUNT(*) AS `count` FROM `lines_live` WHERE `proxy_id` = ? AND `hls_end` = 0;', $rServerID); - } else { - $db->query('SELECT COUNT(*) AS `count` FROM `lines_live` WHERE `server_id` = ? AND `hls_end` = 0;', $rServerID); - } - - return $db->get_row()['count']; - } -} - -function getEPGSources() { - global $db; - $rReturn = array(); - $db->query('SELECT * FROM `epg`;'); - - if (0 >= $db->num_rows()) { - } else { - - foreach ($db->get_rows() as $rRow) { - $rReturn[$rRow['id']] = $rRow; - } - } - - return $rReturn; -} - -function deleteProvider($rID) { - global $db; - $rProvider = getstreamprovider($rID); - - if (!$rProvider) { - return false; - } - - $db->query('DELETE FROM `providers` WHERE `id` = ?;', $rID); - $db->query('DELETE FROM `providers_streams` WHERE `provider_id` = ?;', $rID); - - return true; -} - -function deleteEPG($rID) { - global $db; - $rEPG = EpgService::getById($rID); - - if (!$rEPG) { - return false; - } - - $db->query('DELETE FROM `epg` WHERE `id` = ?;', $rID); - $db->query('DELETE FROM `epg_channels` WHERE `epg_id` = ?;', $rID); - $db->query('UPDATE `streams` SET `epg_id` = null, `channel_id` = null, `epg_lang` = null WHERE `epg_id` = ?;', $rID); - - return true; -} - -function deleteServer($rID, $rReplaceWith = null) { - global $db; - return ServerRepository::deleteById($rID, $rReplaceWith); -} - -function getEncodeErrors($rID) { - global $db; - $rErrors = array(); - $db->query('SELECT `server_id`, `error` FROM `streams_errors` WHERE `stream_id` = ?;', $rID); - - foreach ($db->get_rows() as $rRow) { - $rErrors[intval($rRow['server_id'])] = $rRow['error']; - } - - return $rErrors; -} - -function issecure() { - $https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; - $port443 = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443; - - return $https || $port443; -} - -function getProtocol() { - if (issecure()) { - return 'https'; - } - - return 'http'; -} - -function generateString($strength = 10) { - $input = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ'; - $input_length = strlen($input); - $random_string = ''; - - for ($i = 0; $i < $strength; $i++) { - $random_character = $input[mt_rand(0, $input_length - 1)]; - $random_string .= $random_character; - } - - return $random_string; -} - -function roundUpToAny($n, $x = 5) { - return round(($n + $x / 2) / $x) * $x; -} - -function getPageName() { - if (defined('PAGE_NAME') && PAGE_NAME) { - return strtolower(PAGE_NAME); - } - - return strtolower(basename(get_included_files()[0], '.php')); -} - -function sortArrayByArray($rArray, $rSort) { - if (!(empty($rArray) || empty($rSort))) { - $rOrdered = array(); - - foreach ($rSort as $rValue) { - if (($rKey = array_search($rValue, $rArray)) === false) { - } else { - $rOrdered[] = $rValue; - unset($rArray[$rKey]); - } - } - - return $rOrdered + $rArray; - } else { - return array(); - } -} - -function cleanValue($rValue) { - if ($rValue != '') { - $rValue = str_replace(' ', ' ', stripslashes($rValue)); - $rValue = str_replace(array("\r\n", "\n\r", "\r"), "\n", $rValue); - $rValue = str_replace('', '-->', $rValue); - $rValue = str_ireplace(' v" . XC_VM_VERSION; -} - -/** - * Filter and validate array of IDs - * - * @param array $ids Array of IDs to filter - * @param array $availableIDs Array of valid available IDs - * @param bool $checkPositive Whether to check for positive integers - * @return array Filtered array of valid IDs - */ -function filterIDs($ids, $availableIDs, $checkPositive = true) { - $filtered = []; - - if (!is_array($ids)) { - return $filtered; - } - - foreach ($ids as $id) { - $intID = (int)$id; - $isValid = (!$checkPositive || $intID > 0) && in_array($intID, $availableIDs); - - if ($isValid) { - $filtered[] = $intID; - } - } - - return $filtered; -} - -function shutdown_admin() { - global $db; - - if (!is_object($db)) { - } else { - $db->close_mysql(); - } -} - -/** - * Retrieves a list of available time zones with their UTC offsets. - * - * This function generates an array of time zones, each containing the time zone - * identifier and its current UTC offset based on the current timestamp. It includes - * error handling to ensure safe execution and restores the original timezone after - * processing. - * - * @return array An array of associative arrays containing: - * - 'zone': The time zone identifier (e.g., 'America/New_York') - * - 'diff_from_GMT': The UTC offset (e.g., 'UTC/GMT +00:00') - * @throws RuntimeException If setting a timezone fails or if timezone_identifiers_list() is unavailable. - */ -function TimeZoneList(): array { - // Check if timezone_identifiers_list is available - if (!function_exists('timezone_identifiers_list')) { - throw new RuntimeException('Timezone identifiers list function is not available.'); - } - - $zones_array = []; - $timestamp = time(); - $original_timezone = date_default_timezone_get(); // Store original timezone - - try { - foreach (timezone_identifiers_list() as $key => $zone) { - // Validate timezone identifier - if (empty($zone) || !is_string($zone)) { - continue; // Skip invalid timezone identifiers - } - - // Attempt to set the timezone - if (date_default_timezone_set($zone) === false) { - continue; // Skip if timezone setting fails - } - - // Store timezone data - $zones_array[$key] = [ - 'zone' => $zone, - 'diff_from_GMT' => '[UTC/GMT ' . date('P', $timestamp) . ']' - ]; - } - } catch (Exception $e) { - // Restore original timezone before throwing exception - date_default_timezone_set($original_timezone); - throw new RuntimeException('Error processing timezone list: ' . $e->getMessage()); - } - - // Restore original timezone - date_default_timezone_set($original_timezone); - - return $zones_array; -} diff --git a/src/includes/api/admin/table.php b/src/includes/api/admin/table.php deleted file mode 100644 index ed18674f..00000000 --- a/src/includes/api/admin/table.php +++ /dev/null @@ -1,6885 +0,0 @@ - - * @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 - */ - -session_start(); -session_write_close(); -if (file_exists('../www/init.php')) { - require_once '../www/init.php'; -} else { - require_once '../../../www/init.php'; -} -if (!PHP_ERRORS) { - if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') { - exit(); - } -} -$rReturn = array('draw' => intval(RequestManager::getAll()['draw']), 'recordsTotal' => 0, 'recordsFiltered' => 0, 'data' => array()); -$rIsAPI = false; -if (isset(RequestManager::getAll()['api_key'])) { - $rReturn = array('status' => 'STATUS_SUCCESS', 'data' => array()); - $db->query('SELECT `id` FROM `users` LEFT JOIN `users_groups` ON `users_groups`.`group_id` = `users`.`member_group_id` WHERE `api_key` = ? AND LENGTH(`api_key`) > 0 AND `is_admin` = 1 AND `status` = 1;', RequestManager::getAll()['api_key']); - if ($db->num_rows() != 0) { - $rUserID = $db->get_row()['id']; - $rIsAPI = true; - require_once MAIN_HOME . 'includes/admin.php'; - $rUserInfo = UserRepository::getRegisteredUserById($rUserID); - $rPermissions = getPermissions($rUserInfo['member_group_id']); - $rPermissions['advanced'] = json_decode($rPermissions['allowed_pages'], true); - if (strlen($rUserInfo['timezone']) > 0) { - date_default_timezone_set($rUserInfo['timezone']); - } - } else { - echo json_encode(array('status' => 'STATUS_FAILURE', 'error' => 'Invalid API key.')); - exit(); - } -} else { - if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1' && isset(RequestManager::getAll()['api_user_id'])) { - $rIsAPI = true; - require_once MAIN_HOME . 'includes/admin.php'; - $rUserInfo = UserRepository::getRegisteredUserById(RequestManager::getAll()['api_user_id']); - $rPermissions = getPermissions($rUserInfo['member_group_id']); - $rPermissions['advanced'] = json_decode($rPermissions['allowed_pages'], true); - if (strlen($rUserInfo['timezone']) > 0) { - date_default_timezone_set($rUserInfo['timezone']); - } - } else { - if (isset($_SESSION['hash'])) { - include 'functions.php'; - } else { - echo json_encode($rReturn); - exit(); - } - } -} -if ($rMobile) { - SettingsManager::update('modal_edit', false); - SettingsManager::update('group_buttons', false); -} -$rType = RequestManager::getAll()['id']; -$rStart = intval(RequestManager::getAll()['start']); -$rLimit = intval(RequestManager::getAll()['length']); -if ((1000 < $rLimit || $rLimit <= 0) || !$rIsAPI) { - $rLimit = 1000; -} -if (SettingsManager::getAll()['redis_handler']) { - RedisManager::ensureConnected(); -} -if ($rType == 'lines') { - if (Authorization::check('adv', 'users') || Authorization::check('adv', 'mass_edit_users')) { - $rOrderDirection = (strtolower(RequestManager::getAll()['order'][0]['dir']) === 'desc' ? 'desc' : 'asc'); - $rOrder = array('`lines`.`id`', '`lines`.`username`', '`lines`.`password`', '`lines`.`member_id`', '`lines`.`enabled` - `lines`.`admin_enabled`', '`active_connections` > 0', '`lines`.`is_trial`', '`lines`.`is_restreamer`', '`active_connections`', '`lines`.`max_connections`', '`lines`.`exp_date`', '`active_connections` ' . $rOrderDirection . ', `last_activity`', false); - if (isset(RequestManager::getAll()['order']) && 0 < strlen(RequestManager::getAll()['order'][0]['column'])) { - $rOrderRow = intval(RequestManager::getAll()['order'][0]['column']); - } else { - $rOrderRow = 0; - } - $rWhere = $rWhereV = array(); - $rWhere[] = '(`is_mag` + `is_e2`) = 0'; - if (0 >= strlen(RequestManager::getAll()['search']['value'])) { - } else { - foreach (range(1, 6) as $rInt) { - $rWhereV[] = '%' . RequestManager::getAll()['search']['value'] . '%'; - } - $rWhere[] = '(`lines`.`username` LIKE ? OR `lines`.`password` LIKE ? OR FROM_UNIXTIME(`exp_date`) LIKE ? OR `lines`.`max_connections` LIKE ? OR `lines`.`reseller_notes` LIKE ? OR `lines`.`admin_notes` LIKE ?)'; - } - if (0 >= strlen(RequestManager::getAll()['filter'] ?? '')) { - } else { - if (RequestManager::getAll()['filter'] == 1) { - $rWhere[] = '(`lines`.`admin_enabled` = 1 AND `lines`.`enabled` = 1 AND (`lines`.`exp_date` IS NULL OR `lines`.`exp_date` > UNIX_TIMESTAMP()))'; - } else { - if (RequestManager::getAll()['filter'] == 2) { - $rWhere[] = '`lines`.`enabled` = 0'; - } else { - if (RequestManager::getAll()['filter'] == 3) { - $rWhere[] = '`lines`.`admin_enabled` = 0'; - } else { - if (RequestManager::getAll()['filter'] == 4) { - $rWhere[] = '(`lines`.`exp_date` IS NOT NULL AND `lines`.`exp_date` <= UNIX_TIMESTAMP())'; - } else { - if (RequestManager::getAll()['filter'] == 5) { - $rWhere[] = '`lines`.`is_trial` = 1'; - } else { - if (RequestManager::getAll()['filter'] == 6) { - $rWhere[] = '`lines`.`is_restreamer` = 1'; - } else { - if (RequestManager::getAll()['filter'] == 7) { - $rWhere[] = '`lines`.`is_stalker` = 1'; - } else { - if (RequestManager::getAll()['filter'] != 8) { - } else { - $rWhere[] = '(`lines`.`exp_date` IS NOT NULL AND `lines`.`exp_date` > UNIX_TIMESTAMP() AND `lines`.`exp_date` <= (UNIX_TIMESTAMP() + (86400*14)))'; - } - } - } - } - } - } - } - } - } - if (0 >= strlen(RequestManager::getAll()['reseller'] ?? '')) { - } else { - $rWhere[] = '`lines`.`member_id` = ?'; - $rWhereV[] = RequestManager::getAll()['reseller']; - } - if (0 < count($rWhere)) { - $rWhereString = 'WHERE ' . implode(' AND ', $rWhere); - } else { - $rWhereString = ''; - } - $rCountQuery = 'SELECT COUNT(`id`) AS `count` FROM `lines` ' . $rWhereString . ';'; - if (!$rOrder[$rOrderRow]) { - } else { - $rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection; - } - $db->query($rCountQuery, ...$rWhereV); - if ($db->num_rows() == 1) { - $rReturn['recordsTotal'] = $db->get_row()['count']; - } else { - $rReturn['recordsTotal'] = 0; - } - $rReturn['recordsFiltered'] = ($rIsAPI ? ($rReturn['recordsTotal'] < $rLimit ? $rReturn['recordsTotal'] : $rLimit) : $rReturn['recordsTotal']); - if (0 >= $rReturn['recordsTotal']) { - } else { - $rQuery = 'SELECT `lines`.`id`, `lines`.`member_id`, `lines`.`last_activity`, `lines`.`last_activity_array`, `lines`.`username`, `lines`.`password`, `lines`.`exp_date`, `lines`.`admin_enabled`, `lines`.`is_restreamer`, `lines`.`enabled`, `lines`.`admin_notes`, `lines`.`reseller_notes`, `lines`.`max_connections`, `lines`.`is_trial`, (SELECT COUNT(*) AS `active_connections` FROM `lines_live` WHERE `user_id` = `lines`.`id` AND `hls_end` = 0) AS `active_connections` FROM `lines` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';'; - $db->query($rQuery, ...$rWhereV); - if (0 >= $db->num_rows()) { - } else { - $rRows = $db->get_rows(); - $rActivityIDs = $rLineInfo = $rLineIDs = array(); - foreach ($rRows as $rRow) { - $rLineIDs[] = intval($rRow['id']); - $rLineInfo[intval($rRow['id'])] = array('owner_name' => null, 'stream_display_name' => null, 'stream_id' => null, 'last_active' => null); - if ($rLastInfo = json_decode($rRow['last_activity_array'], true)) { - $rLineInfo[intval($rRow['id'])]['stream_id'] = $rLastInfo['stream_id']; - $rLineInfo[intval($rRow['id'])]['last_active'] = $rLastInfo['date_end']; - } else { - if (!$rRow['last_activity']) { - } else { - $rActivityIDs[] = intval($rRow['last_activity']); - } - } - } - if (0 >= count($rLineIDs)) { - } else { - $db->query('SELECT `users`.`username`, `lines`.`id` FROM `users` LEFT JOIN `lines` ON `lines`.`member_id` = `users`.`id` WHERE `lines`.`id` IN (' . implode(',', $rLineIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - $rLineInfo[$rRow['id']]['owner_name'] = $rRow['username']; - } - if (SettingsManager::getAll()['redis_handler']) { - $rConnectionCount = ConnectionTracker::getUserConnections($rLineIDs, true); - $rConnectionMap = ConnectionTracker::getFirstConnection($rLineIDs); - $rStreamIDs = array(); - foreach ($rConnectionMap as $rUserID => $rConnection) { - if (in_array($rConnection['stream_id'], $rStreamIDs)) { - } else { - $rStreamIDs[] = intval($rConnection['stream_id']); - } - } - $rStreamMap = array(); - if (0 >= count($rStreamIDs)) { - } else { - $db->query('SELECT `id`, `stream_display_name` FROM `streams` WHERE `id` IN (' . implode(',', $rStreamIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - $rStreamMap[$rRow['id']] = $rRow['stream_display_name']; - } - } - foreach ($rConnectionMap as $rUserID => $rConnection) { - $rLineInfo[$rUserID]['stream_display_name'] = $rStreamMap[$rConnection['stream_id']]; - $rLineInfo[$rUserID]['stream_id'] = $rConnection['stream_id']; - $rLineInfo[$rUserID]['last_active'] = $rConnection['date_start']; - } - unset($rConnectionMap); - } else { - $db->query('SELECT `lines_live`.`user_id`, `lines_live`.`stream_id`, `lines_live`.`date_start` AS `last_active`, `streams`.`stream_display_name` FROM `lines_live` LEFT JOIN `streams` ON `streams`.`id` = `lines_live`.`stream_id` INNER JOIN (SELECT `user_id`, MAX(`date_start`) AS `ts` FROM `lines_live` GROUP BY `user_id`) `maxt` ON (`lines_live`.`user_id` = `maxt`.`user_id` AND `lines_live`.`date_start` = `maxt`.`ts`) WHERE `lines_live`.`hls_end` = 0 AND `lines_live`.`user_id` IN (' . implode(',', $rLineIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - $rLineInfo[$rRow['user_id']]['stream_display_name'] = $rRow['stream_display_name']; - $rLineInfo[$rRow['user_id']]['stream_id'] = $rRow['stream_id']; - $rLineInfo[$rRow['user_id']]['last_active'] = $rRow['last_active']; - } - } - } - if (0 >= count($rActivityIDs)) { - } else { - $db->query('SELECT `user_id`, `stream_id`, `date_end` AS `last_active` FROM `lines_activity` WHERE `activity_id` IN (' . implode(',', $rActivityIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - if (isset($rLineInfo[$rRow['user_id']]['stream_id'])) { - } else { - $rLineInfo[$rRow['user_id']]['stream_id'] = $rRow['stream_id']; - $rLineInfo[$rRow['user_id']]['last_active'] = $rRow['last_active']; - } - } - } - foreach ($rRows as $rRow) { - $rRow = array_merge($rRow, $rLineInfo[$rRow['id']]); - if (!SettingsManager::getAll()['redis_handler']) { - } else { - $rRow['active_connections'] = (isset($rConnectionCount[$rRow['id']]) ? $rConnectionCount[$rRow['id']] : 0); - } - if (!$rIsAPI) { - if (!$rRow['admin_enabled']) { - $rStatus = ''; - } else { - if (!$rRow['enabled']) { - $rStatus = ''; - } else { - if ($rRow['exp_date'] && $rRow['exp_date'] < time()) { - $rStatus = ''; - } else { - $rStatus = ''; - } - } - } - if (0 < $rRow['active_connections']) { - $rActive = ''; - } else { - $rActive = ''; - } - if ($rRow['is_trial']) { - $rTrial = ''; - } else { - $rTrial = ''; - } - if ($rRow['is_restreamer']) { - $rRestreamer = ''; - } else { - $rRestreamer = ''; - } - if ($rRow['exp_date']) { - if ($rRow['exp_date'] < time()) { - $rExpDate = '' . date($rSettings['date_format'], $rRow['exp_date']) . '
' . date('H:i:s', $rRow['exp_date']) . '
'; - } else { - $rExpDate = date($rSettings['date_format'], $rRow['exp_date']) . "
" . date('H:i:s', $rRow['exp_date']) . ''; - } - } else { - $rExpDate = '∞'; - } - if (0 < $rRow['active_connections']) { - $rActiveConnections = "'; - } else { - $rActiveConnections = ""; - } - if (!(Authorization::check('adv', 'live_connections') && 0 < $rRow['active_connections'])) { - } else { - $rActiveConnections = '' . $rActiveConnections . ''; - } - if ($rRow['max_connections'] == 0) { - $rMaxConnections = ""; - } else { - $rMaxConnections = "'; - } - $rNotes = ''; - if (0 >= strlen($rRow['admin_notes'])) { - } else { - $rNotes .= $rRow['admin_notes']; - } - if (0 >= strlen($rRow['reseller_notes'])) { - } else { - if (strlen($rNotes) == 0) { - } else { - $rNotes .= "\n"; - } - $rNotes .= $rRow['reseller_notes']; - } - if (SettingsManager::getAll()['group_buttons']) { - $rButtons = ''; - if (0 >= strlen($rNotes)) { - } else { - $rButtons .= ''; - } - $rButtons .= ''; - } else { - $rButtons = '
'; - if (0 < strlen($rNotes)) { - $rButtons .= ''; - } else { - $rButtons .= ''; - } - if (!Authorization::check('adv', 'edit_user')) { - } else { - $rButtons .= ''; - } - if (!Authorization::check('adv', 'fingerprint')) { - } else { - if (0 < $rRow['active_connections']) { - $rButtons .= '"; - } else { - $rButtons .= ''; - } - } - $rButtons .= ""; - if (!Authorization::check('adv', 'edit_user')) { - } else { - $rButtons .= '"; - if ($rRow['admin_enabled']) { - $rButtons .= '"; - } else { - $rButtons .= '"; - } - if ($rRow['enabled']) { - $rButtons .= '"; - } else { - $rButtons .= '"; - } - $rButtons .= '"; - } - $rButtons .= '
'; - } - if ($rRow['active_connections'] && $rRow['last_active']) { - $rLastActive = "" . $rRow['stream_display_name'] . "
Online: " . TimeUtils::secondsToTime(time() - $rRow['last_active']) . ''; - } else { - if ($rRow['last_active']) { - $rLastActive = date($rSettings['date_format'], $rRow['last_active']) . "
" . date('H:i:s', $rRow['last_active']) . ''; - } else { - $rLastActive = 'Never'; - } - } - if (0 < $rRow['member_id']) { - $rOwner = "" . $rRow['owner_name'] . ''; - } else { - $rOwner = $rRow['owner_name']; - } - if (!isset(RequestManager::getAll()['no_url'])) { - $rReturn['data'][] = array("" . $rRow['id'] . '', "" . $rRow['username'] . '', $rRow['password'], $rOwner, $rStatus, $rActive, $rTrial, $rRestreamer, $rActiveConnections, $rMaxConnections, $rExpDate, $rLastActive, $rButtons); - } else { - $rReturn['data'][] = array($rRow['id'], $rRow['username'], $rRow['password'], $rRow['owner_name'], $rStatus, $rActive, $rTrial, $rRestreamer, $rActiveConnections, $rMaxConnections, $rExpDate, $rLastActive, $rButtons); - } - } else { - $rReturn['data'][] = filterrow($rRow, RequestManager::getAll()['show_columns'] ?? '', RequestManager::getAll()['hide_columns'] ?? ''); - } - } - } - } - echo json_encode($rReturn); - exit(); - } - exit(); -} -if ($rType == 'mags') { - if (Authorization::check('adv', 'manage_mag')) { - $rOrderDirection = (strtolower(RequestManager::getAll()['order'][0]['dir']) === 'desc' ? 'desc' : 'asc'); - $rOrder = array('`lines`.`id`', '`lines`.`username`', '`mag_devices`.`mac`', '`mag_devices`.`stb_type`', '`lines`.`member_id`', '`lines`.`enabled`', '`active_connections` > 0', '`lines`.`is_trial`', '`lines`.`exp_date`', '`active_connections` ' . $rOrderDirection . ', `last_activity`', false); - if (isset(RequestManager::getAll()['order']) && 0 < strlen(RequestManager::getAll()['order'][0]['column'])) { - $rOrderRow = intval(RequestManager::getAll()['order'][0]['column']); - } else { - $rOrderRow = 0; - } - $rWhere = $rWhereV = array(); - if (0 >= strlen(RequestManager::getAll()['search']['value'])) { - } else { - foreach (range(1, 6) as $rInt) { - $rWhereV[] = '%' . RequestManager::getAll()['search']['value'] . '%'; - } - $rWhere[] = '(`lines`.`username` LIKE ? OR `mag_devices`.`mac` LIKE ? OR `mag_devices`.`stb_type` LIKE ? OR FROM_UNIXTIME(`exp_date`) LIKE ? OR `lines`.`reseller_notes` LIKE ? OR `lines`.`admin_notes` LIKE ?)'; - } - if (0 >= strlen(RequestManager::getAll()['filter'] ?? '')) { - } else { - if (RequestManager::getAll()['filter'] == 1) { - $rWhere[] = '(`lines`.`admin_enabled` = 1 AND `lines`.`enabled` = 1 AND (`lines`.`exp_date` IS NULL OR `lines`.`exp_date` > UNIX_TIMESTAMP()))'; - } else { - if (RequestManager::getAll()['filter'] == 2) { - $rWhere[] = '`lines`.`enabled` = 0'; - } else { - if (RequestManager::getAll()['filter'] == 3) { - $rWhere[] = '`lines`.`admin_enabled` = 0'; - } else { - if (RequestManager::getAll()['filter'] == 4) { - $rWhere[] = '(`lines`.`exp_date` IS NOT NULL AND `lines`.`exp_date` <= UNIX_TIMESTAMP())'; - } else { - if (RequestManager::getAll()['filter'] != 5) { - } else { - $rWhere[] = '`lines`.`is_trial` = 1'; - } - } - } - } - } - } - if (0 >= strlen(RequestManager::getAll()['reseller'] ?? '')) { - } else { - $rWhere[] = '`lines`.`member_id` = ?'; - $rWhereV[] = RequestManager::getAll()['reseller']; - } - if (0 < count($rWhere)) { - $rWhereString = 'WHERE ' . implode(' AND ', $rWhere); - } else { - $rWhereString = ''; - } - if (!$rOrder[$rOrderRow]) { - } else { - $rOrderBy = 'ORDER BY ' . $rOrder[$rOrderRow] . ' ' . $rOrderDirection; - } - $rCountQuery = 'SELECT COUNT(*) AS `count` FROM `lines` RIGHT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines`.`id` ' . $rWhereString . ';'; - $db->query($rCountQuery, ...$rWhereV); - if ($db->num_rows() == 1) { - $rReturn['recordsTotal'] = $db->get_row()['count']; - } else { - $rReturn['recordsTotal'] = 0; - } - $rReturn['recordsFiltered'] = ($rIsAPI ? ($rReturn['recordsTotal'] < $rLimit ? $rReturn['recordsTotal'] : $rLimit) : $rReturn['recordsTotal']); - if (0 >= $rReturn['recordsTotal']) { - } else { - $rQuery = 'SELECT `lines`.`id`, `lines`.`username`, `lines`.`member_id`, `lines`.`last_activity`, `lines`.`last_activity_array`, `mag_devices`.`mac`, `mag_devices`.`stb_type`, `mag_devices`.`mag_id`, `lines`.`exp_date`, `lines`.`admin_enabled`, `lines`.`enabled`, `lines`.`admin_notes`, `lines`.`reseller_notes`, `lines`.`max_connections`, `lines`.`is_trial`, (SELECT count(*) FROM `lines_live` WHERE `lines`.`id` = `lines_live`.`user_id` AND `hls_end` = 0) AS `active_connections` FROM `lines` RIGHT JOIN `mag_devices` ON `mag_devices`.`user_id` = `lines`.`id` ' . $rWhereString . ' ' . $rOrderBy . ' LIMIT ' . $rStart . ', ' . $rLimit . ';'; - $db->query($rQuery, ...$rWhereV); - if (0 >= $db->num_rows()) { - } else { - $rRows = $db->get_rows(); - $rActivityIDs = $rLineInfo = $rLineIDs = array(); - foreach ($rRows as $rRow) { - if (!$rRow['id']) { - } else { - $rLineIDs[] = intval($rRow['id']); - $rLineInfo[intval($rRow['id'])] = array('owner_name' => null, 'stream_display_name' => null, 'stream_id' => null, 'last_active' => null); - } - if ($rLastInfo = json_decode($rRow['last_activity_array'], true)) { - $rLineInfo[intval($rRow['id'])]['stream_id'] = $rLastInfo['stream_id']; - $rLineInfo[intval($rRow['id'])]['last_active'] = $rLastInfo['date_end']; - } else { - if (!$rRow['last_activity']) { - } else { - $rActivityIDs[] = intval($rRow['last_activity']); - } - } - } - if (0 >= count($rLineIDs)) { - } else { - $db->query('SELECT `users`.`username`, `lines`.`id` FROM `users` LEFT JOIN `lines` ON `lines`.`member_id` = `users`.`id` WHERE `lines`.`id` IN (' . implode(',', $rLineIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - $rLineInfo[$rRow['id']]['owner_name'] = $rRow['username']; - } - if (SettingsManager::getAll()['redis_handler']) { - $rConnectionCount = ConnectionTracker::getUserConnections($rLineIDs, true); - $rConnectionMap = ConnectionTracker::getFirstConnection($rLineIDs); - $rStreamIDs = array(); - foreach ($rConnectionMap as $rUserID => $rConnection) { - if (in_array($rConnection['stream_id'], $rStreamIDs)) { - } else { - $rStreamIDs[] = intval($rConnection['stream_id']); - } - } - $rStreamMap = array(); - if (0 >= count($rStreamIDs)) { - } else { - $db->query('SELECT `id`, `stream_display_name` FROM `streams` WHERE `id` IN (' . implode(',', $rStreamIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - $rStreamMap[$rRow['id']] = $rRow['stream_display_name']; - } - } - foreach ($rConnectionMap as $rUserID => $rConnection) { - $rLineInfo[$rUserID]['stream_display_name'] = $rStreamMap[$rConnection['stream_id']]; - $rLineInfo[$rUserID]['stream_id'] = $rConnection['stream_id']; - $rLineInfo[$rUserID]['last_active'] = $rConnection['date_start']; - } - unset($rConnectionMap); - } else { - $db->query('SELECT `lines_live`.`user_id`, `lines_live`.`stream_id`, `lines_live`.`date_start` AS `last_active`, `streams`.`stream_display_name` FROM `lines_live` LEFT JOIN `streams` ON `streams`.`id` = `lines_live`.`stream_id` INNER JOIN (SELECT `user_id`, MAX(`date_start`) AS `ts` FROM `lines_live` GROUP BY `user_id`) `maxt` ON (`lines_live`.`user_id` = `maxt`.`user_id` AND `lines_live`.`date_start` = `maxt`.`ts`) WHERE `lines_live`.`user_id` IN (' . implode(',', $rLineIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - $rLineInfo[$rRow['user_id']]['stream_display_name'] = $rRow['stream_display_name']; - $rLineInfo[$rRow['user_id']]['stream_id'] = $rRow['stream_id']; - $rLineInfo[$rRow['user_id']]['last_active'] = $rRow['last_active']; - } - } - } - if (0 >= count($rActivityIDs)) { - } else { - $db->query('SELECT `user_id`, `stream_id`, `date_end` AS `last_active` FROM `lines_activity` WHERE `activity_id` IN (' . implode(',', $rActivityIDs) . ');'); - foreach ($db->get_rows() as $rRow) { - if (isset($rLineInfo[$rRow['user_id']]['stream_id'])) { - } else { - $rLineInfo[$rRow['user_id']]['stream_id'] = $rRow['stream_id']; - $rLineInfo[$rRow['user_id']]['last_active'] = $rRow['last_active']; - } - } - } - foreach ($rRows as $rRow) { - if (!isset($rLineInfo[$rRow['id']])) { - } else { - $rRow = array_merge($rRow, $rLineInfo[$rRow['id']]); - } - if (!SettingsManager::getAll()['redis_handler']) { - } else { - $rRow['active_connections'] = (isset($rConnectionCount[$rRow['id']]) ? $rConnectionCount[$rRow['id']] : 0); - } - if (!$rIsAPI) { - if (!$rRow['id']) { - $rStatus = ''; - } else { - if (!$rRow['admin_enabled']) { - $rStatus = ''; - } else { - if (!$rRow['enabled']) { - $rStatus = ''; - } else { - if ($rRow['exp_date'] && $rRow['exp_date'] < time()) { - $rStatus = ''; - } else { - $rStatus = ''; - } - } - } - } - if (0 < $rRow['active_connections']) { - $rActive = ''; - } else { - $rActive = ''; - } - if ($rRow['is_trial']) { - $rTrial = ''; - } else { - $rTrial = ''; - } - if ($rRow['exp_date']) { - if ($rRow['exp_date'] < time()) { - $rExpDate = '' . date($rSettings['date_format'], $rRow['exp_date']) . '
' . date('H:i:s', $rRow['exp_date']) . '
'; - } else { - $rExpDate = date($rSettings['date_format'], $rRow['exp_date']) . "
" . date('H:i:s', $rRow['exp_date']) . ''; - } - } else { - $rExpDate = '∞'; - } - if (Authorization::check('adv', 'live_connections')) { - $rActiveConnections = '' . $rRow['active_connections'] . ''; - } else { - $rActiveConnections = $rRow['active_connections']; - } - $rNotes = ''; - if (0 >= strlen($rRow['admin_notes'])) { - } else { - $rNotes .= $rRow['admin_notes']; - } - if (0 >= strlen($rRow['reseller_notes'])) { - } else { - if (strlen($rNotes) == 0) { - } else { - $rNotes .= "\n"; - } - $rNotes .= $rRow['reseller_notes']; - } - if (SettingsManager::getAll()['group_buttons']) { - $rButtons = ''; - if (0 >= strlen($rNotes)) { - } else { - $rButtons .= ''; - } - $rButtons .= ' - 0 && !checkRemote()) : ?> + 0 && !BackupService::checkRemoteConnection()) : ?> diff --git a/src/public/Views/admin/bouquet.php b/src/public/Views/admin/bouquet.php index 110f3f98..2cbd3100 100644 --- a/src/public/Views/admin/bouquet.php +++ b/src/public/Views/admin/bouquet.php @@ -4,19 +4,19 @@ if (!isset($__viewMode)): include 'session.php'; include 'functions.php'; - if (checkPermissions()) { + if (PageAuthorization::checkPermissions()) { } else { - goHome(); + AdminHelpers::goHome(); } if (!isset(RequestManager::getAll()['id'])) { } else { - $rBouquetArr = getBouquet(RequestManager::getAll()['id']); + $rBouquetArr = BouquetService::getById(RequestManager::getAll()['id']); } if (!isset(RequestManager::getAll()['duplicate'])) { } else { - $rBouquetArr = getBouquet(RequestManager::getAll()['duplicate']); + $rBouquetArr = BouquetService::getById(RequestManager::getAll()['duplicate']); $rBouquetArr['bouquet_name'] .= ' - Copy'; unset($rBouquetArr['id']); } @@ -29,7 +29,7 @@ if (!isset($__viewMode)): $rBouquetMovies = json_decode($rBouquetArr['bouquet_movies'], true); $rBouquetRadios = json_decode($rBouquetArr['bouquet_radios'], true); $rBouquetSeries = json_decode($rBouquetArr['bouquet_series'], true); - $rRequiredIDs = confirmIDs(array_merge($rBouquetChannels, $rBouquetMovies, $rBouquetRadios)); + $rRequiredIDs = AdminHelpers::confirmIDs(array_merge($rBouquetChannels, $rBouquetMovies, $rBouquetRadios)); if (0 >= count($rRequiredIDs)) { } else { diff --git a/src/public/Views/admin/bouquet_order.php b/src/public/Views/admin/bouquet_order.php index 72a169ac..52679044 100644 --- a/src/public/Views/admin/bouquet_order.php +++ b/src/public/Views/admin/bouquet_order.php @@ -4,8 +4,8 @@ include 'session.php'; include 'functions.php'; - if (!checkPermissions()) { - goHome(); + if (!PageAuthorization::checkPermissions()) { + AdminHelpers::goHome(); } $_TITLE = 'Bouquet Order'; diff --git a/src/public/Views/admin/bouquet_sort.php b/src/public/Views/admin/bouquet_sort.php index f8a1adbd..acd15c8a 100644 --- a/src/public/Views/admin/bouquet_sort.php +++ b/src/public/Views/admin/bouquet_sort.php @@ -2,13 +2,13 @@ - [], 'movie' => [], 'radio' => [], 'series' => []]; diff --git a/src/public/Views/admin/bouquets.php b/src/public/Views/admin/bouquets.php index 5c7d36eb..0ab72e42 100644 --- a/src/public/Views/admin/bouquets.php +++ b/src/public/Views/admin/bouquets.php @@ -2,8 +2,8 @@ - - + + diff --git a/src/public/Views/admin/cache.php b/src/public/Views/admin/cache.php index 5e9e9227..05d2bd5c 100644 --- a/src/public/Views/admin/cache.php +++ b/src/public/Views/admin/cache.php @@ -2,8 +2,8 @@ - - - + + @@ -53,7 +53,7 @@ renderUnifiedLayoutHeader('admin'); - + diff --git a/src/public/Views/admin/created_channel.php b/src/public/Views/admin/created_channel.php index 6306f429..18f4015e 100644 --- a/src/public/Views/admin/created_channel.php +++ b/src/public/Views/admin/created_channel.php @@ -4,8 +4,8 @@ include 'session.php'; include 'functions.php'; - if (!checkPermissions()) { - goHome(); + if (!PageAuthorization::checkPermissions()) { + AdminHelpers::goHome(); } $rCategories = CategoryService::getAllByType('live'); @@ -17,7 +17,7 @@ $rChannel = StreamRepository::getById(RequestManager::getAll()['id']); if (!$rChannel || $rChannel['type'] != 3) { - goHome(); + AdminHelpers::goHome(); } } @@ -100,7 +100,7 @@ endif;
$rEncodeError) { ?> @@ -227,7 +227,7 @@ endif;
@@ -709,7 +709,7 @@ renderUnifiedLayoutFooter('admin'); if (isset($rChannel) && $rProperties['type'] == 2) { echo "\t\t" . 'var rSelection = '; - echo json_encode(getSelections(json_decode($rChannel['stream_source'], true))); + echo json_encode(StreamRepository::getSelections(json_decode($rChannel['stream_source'], true))); echo ';' . "\r\n\t\t"; } else { echo "\t\t" . 'var rSelection = [];' . "\r\n\t\t"; diff --git a/src/public/Views/admin/created_channel_mass.php b/src/public/Views/admin/created_channel_mass.php index a076a45e..ee9e0760 100644 --- a/src/public/Views/admin/created_channel_mass.php +++ b/src/public/Views/admin/created_channel_mass.php @@ -4,9 +4,9 @@ include 'session.php'; include 'functions.php'; - if (checkPermissions()) { + if (PageAuthorization::checkPermissions()) { } else { - goHome(); + AdminHelpers::goHome(); } $rCategories = CategoryService::getAllByType('live'); diff --git a/src/public/Views/admin/created_channels.php b/src/public/Views/admin/created_channels.php index 13f96ea5..58e39d93 100644 --- a/src/public/Views/admin/created_channels.php +++ b/src/public/Views/admin/created_channels.php @@ -1,9 +1,9 @@ value="">Server Default - + @@ -105,7 +105,7 @@
-
diff --git a/src/public/Views/admin/enigma.php b/src/public/Views/admin/enigma.php index 4ed1848a..022e748a 100644 --- a/src/public/Views/admin/enigma.php +++ b/src/public/Views/admin/enigma.php @@ -4,14 +4,14 @@ if (!isset($__viewMode)): include 'session.php'; include 'functions.php'; - if (checkPermissions()) { + if (PageAuthorization::checkPermissions()) { } else { - goHome(); + AdminHelpers::goHome(); } if (!isset(RequestManager::getAll()['id'])) { } else { - $rDevice = getEnigma(RequestManager::getAll()['id']); + $rDevice = EnigmaService::getById(RequestManager::getAll()['id']); if ($rDevice['user_id']) { } else { diff --git a/src/public/Views/admin/enigma_mass.php b/src/public/Views/admin/enigma_mass.php index 65acd2f7..4dccb6a7 100644 --- a/src/public/Views/admin/enigma_mass.php +++ b/src/public/Views/admin/enigma_mass.php @@ -4,8 +4,8 @@ include 'session.php'; include 'functions.php'; - if (!checkPermissions()) { - goHome(); + if (!PageAuthorization::checkPermissions()) { + AdminHelpers::goHome(); } $_TITLE = 'Mass Edit Devices'; diff --git a/src/public/Views/admin/enigmas.php b/src/public/Views/admin/enigmas.php index 28e886a1..c6aab4b4 100644 --- a/src/public/Views/admin/enigmas.php +++ b/src/public/Views/admin/enigmas.php @@ -1,8 +1,8 @@ - + diff --git a/src/public/Views/admin/episode.php b/src/public/Views/admin/episode.php index 9692db51..161aa010 100644 --- a/src/public/Views/admin/episode.php +++ b/src/public/Views/admin/episode.php @@ -1,18 +1,11 @@ ' . "\n\t\t\t\t" . '
' . "\n\t\t\t" . '' . "\n\t\t" . ' $rEncodeError) { echo "\t\t\t\t" . '' . "\n" . ' ' . "\n" . '
' . "\n" . ' - + diff --git a/src/public/Views/admin/movie.php b/src/public/Views/admin/movie.php index f1afcb89..2b6a88b5 100644 --- a/src/public/Views/admin/movie.php +++ b/src/public/Views/admin/movie.php @@ -4,8 +4,8 @@ include 'session.php'; include 'functions.php'; - if (!checkPermissions()) { - goHome(); + if (!PageAuthorization::checkPermissions()) { + AdminHelpers::goHome(); } $rCategories = CategoryService::getAllByType('movie'); @@ -16,7 +16,7 @@ if ($rMovie && $rMovie['type'] == 2) { } else { - goHome(); + AdminHelpers::goHome(); } } @@ -116,7 +116,7 @@ $rEncodeError): if (in_array(intval($rServerID), $activeStreamingServers)): ?> @@ -131,7 +131,7 @@ - + $rEncodeError): ?>
GPU Memory Usage MB / MB
%
-
+
GPU Encoder Usage
%
-
+
GPU Decoder Usage
%
-
+
@@ -584,7 +584,8 @@ }); + $rViewServerId = intval(RequestManager::getAll()['id']); + if (in_array($allServers[$rViewServerId]['status'] ?? 0, array(3, 4)) || in_array($rProxyServers[$rViewServerId]['status'] ?? 0, array(3, 4))): ?> function getInstallStatus() { $.getJSON("./api?action=install_status&server_id=", function(data) { @@ -767,7 +768,7 @@ } } $(document).ready(function() { - + getInstallStatus(); getStats(); diff --git a/src/public/Views/admin/servers.php b/src/public/Views/admin/servers.php index c7c27f03..3926ccf3 100644 --- a/src/public/Views/admin/servers.php +++ b/src/public/Views/admin/servers.php @@ -4,8 +4,8 @@ include 'session.php'; include 'functions.php'; - if (!checkPermissions()) { - goHome(); + if (!PageAuthorization::checkPermissions()) { + AdminHelpers::goHome(); } $rServers = ServerRepository::getAll(true); @@ -127,7 +127,7 @@ if (SettingsManager::getAll()['redis_handler']) { $rClients = $rServer['connections']; } else { - $rClients = getLiveConnections($rServer['id']); + $rClients = ConnectionTracker::getLiveConnections($rServer['id']); } if (Authorization::check('adv', 'live_connections')) { $rClients = ''; diff --git a/src/public/Views/admin/settings.php b/src/public/Views/admin/settings.php index 287b3cf3..191f6aa0 100644 --- a/src/public/Views/admin/settings.php +++ b/src/public/Views/admin/settings.php @@ -5,11 +5,11 @@ if (!isset($__settingsViewMode)): include "session.php"; include "functions.php"; - if (!checkPermissions()) { - goHome(); + if (!PageAuthorization::checkPermissions()) { + AdminHelpers::goHome(); } - $rSettings = getSettings(); + $rSettings = SettingsManager::getAll(); $rStreamArguments = StreamConfigRepository::getStreamArguments(); $GeoLite2 = json_decode(file_get_contents(BIN_PATH . "maxmind/version.json"), true)["geolite2_version"]; @@ -159,7 +159,7 @@ endif; // !$__settingsViewMode - + echo '
'; if (isset($rStream)) { - foreach (json_decode($rEPGSources[intval($rStream['epg_id'])]['data'], true)[$rStream['channel_id']]['langs'] as $rID => $rLang) { + $rEPGData = json_decode($rEPGSources[intval($rStream['epg_id'])]['data'] ?? '[]', true) ?: []; + foreach (($rEPGData[$rStream['channel_id']]['langs'] ?? []) as $rID => $rLang) { echo '