Sync current dev state
Some checks failed
EasyStream Test Suite / test (pull_request) Has been cancelled
EasyStream Test Suite / code-quality (pull_request) Has been cancelled
EasyStream Test Suite / integration-test (pull_request) Has been cancelled

This commit is contained in:
SamiAhmed7777
2025-12-15 17:28:21 -08:00
parent 3bf64b1058
commit f0f346deb9
54 changed files with 11060 additions and 484 deletions

View File

@@ -0,0 +1,183 @@
<?php
/*
* EasyStream JW Player Branding Migration
* Safely updates serialized JW Player config in `db_fileplayers` to remove legacy ViewShark branding.
* Usage: php f_scripts/migrations/update_jw_branding.php
*/
define('_ISVALID', true);
// Bootstrap core to reuse DB + config
require_once __DIR__ . '/../../f_core/config.core.php';
/**
* Unserialize safely (no objects), returning array or null
*/
function safe_unserialize($str)
{
if (!is_string($str) || $str === '') {
return null;
}
// PHP >= 7 allows allowed_classes => false
$data = @unserialize($str, ['allowed_classes' => false]);
if ($data === false || !is_array($data)) {
// Try without options for older compatibility
$data = @unserialize($str);
if (!is_array($data)) {
// Some environments may deliver escaped content from DB; try un-escaping
$clean = stripslashes($str);
$data = @unserialize($clean, ['allowed_classes' => false]);
if ($data === false || !is_array($data)) {
$data = @unserialize($clean);
if (!is_array($data)) {
// Last resort: stripcslashes
$clean2 = stripcslashes($str);
$data = @unserialize($clean2, ['allowed_classes' => false]);
if ($data === false || !is_array($data)) {
$data = @unserialize($clean2);
if (!is_array($data)) {
return null;
}
}
}
}
}
}
return $data;
}
/**
* Apply branding changes to JW config array
*/
function apply_branding(array $cfg, string $siteName, string $siteUrl): array
{
$changed = false;
$replacements = [
// Remove external logo file by default; admin can set later from UI
'jw_logo_file' => '',
// Point links to local site if available
'jw_logo_link' => $siteUrl,
// Update right-click text/link
'jw_rc_text' => 'Powered by ' . ($siteName ?: 'EasyStream'),
'jw_rc_link' => $siteUrl,
];
foreach ($replacements as $key => $value) {
if (array_key_exists($key, $cfg) && $cfg[$key] !== $value) {
$cfg[$key] = $value;
$changed = true;
}
}
// If jw_share_enabled is set, ensure no external domains are hardcoded in share link defaults
if (isset($cfg['jw_share_link']) && is_string($cfg['jw_share_link'])) {
// Replace known legacy domains if present
$legacy = ['viewsharkdemo.com', 'viewshark.com'];
foreach ($legacy as $dom) {
if (stripos($cfg['jw_share_link'], $dom) !== false) {
$cfg['jw_share_link'] = '';
$changed = true;
break;
}
}
}
$cfg['__changed__'] = $changed; // marker for caller
return $cfg;
}
try {
global $db, $cfg; // from config.core.php
if (!isset($db)) {
throw new Exception('Database connection not initialized.');
}
$siteName = $cfg['site_name'] ?? 'EasyStream';
$siteUrl = $cfg['site_url'] ?? '';
$targets = ['jw_local', 'jw_embed'];
$updated = 0;
foreach ($targets as $name) {
$rs = $db->Execute("SELECT `db_id`, `db_config` FROM `db_fileplayers` WHERE `db_name` = ? LIMIT 1", [$name]);
if ($rs && !$rs->EOF) {
$dbId = (int)$rs->fields['db_id'];
$raw = $rs->fields['db_config'];
$arr = safe_unserialize($raw);
if (is_array($arr)) {
$arr = apply_branding($arr, $siteName, $siteUrl);
$changed = !empty($arr['__changed__']);
unset($arr['__changed__']);
if ($changed) {
$serialized = serialize($arr);
$ok = $db->Execute("UPDATE `db_fileplayers` SET `db_config` = ? WHERE `db_id` = ?", [$serialized, $dbId]);
if ($ok) {
echo "Updated branding for {$name} (db_id={$dbId})\n";
$updated++;
} else {
echo "Failed to update {$name} (db_id={$dbId}): " . $db->ErrorMsg() . "\n";
}
} else {
echo "No changes needed for {$name}\n";
}
} else {
// Fallback: attempt in-place serialized string rewriting for known keys
$orig = (string)$raw;
$updatedSerialized = $orig;
$kv = [
'jw_logo_file' => '',
'jw_logo_link' => $siteUrl,
'jw_rc_text' => 'Powered by ' . ($siteName ?: 'EasyStream'),
'jw_rc_link' => $siteUrl,
];
$didChange = false;
foreach ($kv as $k => $v) {
$escapedKey = preg_quote($k, '/');
$replacement = function ($m) use ($v) {
$len = strlen($v);
$safe = str_replace('"', '"', $v); // value is plain; ensure quotes are safe
return $m[1] . 's:' . $len . ':"' . $safe . '";';
};
$pattern = '/(s:\d+:"' . $escapedKey . '";s:)\d+:("[\s\S]*?");/';
$new = preg_replace_callback($pattern, $replacement, $updatedSerialized, 1, $count);
if ($count > 0 && is_string($new)) {
$updatedSerialized = $new;
$didChange = true;
}
}
if ($didChange) {
$ok = $db->Execute("UPDATE `db_fileplayers` SET `db_config` = ? WHERE `db_id` = ?", [$updatedSerialized, $dbId]);
if ($ok) {
echo "Updated branding (fallback) for {$name} (db_id={$dbId})\n";
$updated++;
} else {
echo "Failed fallback update {$name} (db_id={$dbId}): " . $db->ErrorMsg() . "\n";
}
} else {
$snippet = substr((string)$raw, 0, 160);
echo "Could not unserialize config for {$name}; snippet: " . str_replace(["\n","\r"], ['\\n',''], $snippet) . "\n";
}
}
} else {
echo "No db_fileplayers row found for {$name}; skipping.\n";
}
}
echo "Done. Updated {$updated} row(s).\n";
exit(0);
} catch (Throwable $e) {
// Best-effort logging
if (class_exists('VLogger')) {
$logger = VLogger::getInstance();
$logger->log(VLogger::ERROR, 'JW branding migration failed', ['error' => $e->getMessage()]);
}
fwrite(STDERR, 'Error: ' . $e->getMessage() . "\n");
exit(1);
}