092a8bc7ce
- Removed all backup/duplicate files - Removed test files from root - Consolidated documentation to /docs/ - Moved scripts to /scripts/ - Renamed f_* directories (removed prefix) - Organized icons and assets - Removed unused vendor directories - Cleaned up redundant config files
761 lines
25 KiB
PHP
761 lines
25 KiB
PHP
<?php
|
|
/*******************************************************************************************************************
|
|
| Software Name : EasyStream
|
|
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
|
|
| Software Author : (c) Sami Ahmed
|
|
|*******************************************************************************************************************
|
|
|
|
|
|*******************************************************************************************************************
|
|
| This source file is subject to the EasyStream Proprietary License Agreement.
|
|
|
|
|
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|
|
|*******************************************************************************************************************
|
|
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|
|
|*******************************************************************************************************************/
|
|
|
|
defined('_ISVALID') or header('Location: /error');
|
|
|
|
/**
|
|
* VBranding - Comprehensive Branding and Customization System
|
|
*
|
|
* This class handles all aspects of platform branding including:
|
|
* - Colors, fonts, and styling
|
|
* - Logos and images
|
|
* - Layout settings
|
|
* - Badge configurations
|
|
* - Theme presets
|
|
* - Dynamic CSS generation
|
|
* - Cache management
|
|
*/
|
|
class VBranding
|
|
{
|
|
private static $instance = null;
|
|
private $settings = [];
|
|
private $cache_enabled = true;
|
|
private $cache_duration = 3600; // 1 hour
|
|
|
|
public static function getInstance()
|
|
{
|
|
if (self::$instance === null) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
private function __construct()
|
|
{
|
|
$this->loadSettings();
|
|
}
|
|
|
|
/**
|
|
* Load all branding settings from database
|
|
*/
|
|
private function loadSettings()
|
|
{
|
|
global $db;
|
|
|
|
try {
|
|
$sql = "SELECT setting_key, setting_value, setting_type FROM db_branding_settings ORDER BY category, setting_key";
|
|
$result = $db->Execute($sql);
|
|
|
|
if ($result) {
|
|
while (!$result->EOF) {
|
|
$key = $result->fields['setting_key'];
|
|
$value = $result->fields['setting_value'];
|
|
$type = $result->fields['setting_type'];
|
|
|
|
// Convert value based on type
|
|
$this->settings[$key] = $this->convertValue($value, $type);
|
|
$result->MoveNext();
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$logger = VLogger::getInstance();
|
|
$logger->logError('Failed to load branding settings: ' . $e->getMessage());
|
|
$this->loadDefaultSettings();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load default settings if database fails
|
|
*/
|
|
private function loadDefaultSettings()
|
|
{
|
|
$this->settings = [
|
|
'site_name' => 'EasyStream',
|
|
'site_tagline' => 'Your Video Streaming Platform',
|
|
'color_primary' => '#007bff',
|
|
'color_primary_dark' => '#0056b3',
|
|
'color_primary_light' => '#66b3ff',
|
|
'color_bg_main' => '#ffffff',
|
|
'color_text_primary' => '#212529',
|
|
'logo_main' => '/f_scripts/fe/img/logo-header-blue.svg',
|
|
'font_family_primary' => '"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Convert setting value based on type
|
|
*/
|
|
private function convertValue($value, $type)
|
|
{
|
|
switch ($type) {
|
|
case 'boolean':
|
|
return (bool) $value;
|
|
case 'number':
|
|
return is_numeric($value) ? (float) $value : 0;
|
|
case 'json':
|
|
return json_decode($value, true) ?: [];
|
|
default:
|
|
return $value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a branding setting value
|
|
*/
|
|
public function get($key, $default = null)
|
|
{
|
|
return isset($this->settings[$key]) ? $this->settings[$key] : $default;
|
|
}
|
|
|
|
/**
|
|
* Set a branding setting value
|
|
*/
|
|
public function set($key, $value, $type = 'text')
|
|
{
|
|
global $db;
|
|
|
|
try {
|
|
// Update in memory
|
|
$this->settings[$key] = $this->convertValue($value, $type);
|
|
|
|
// Update in database
|
|
$sql = "INSERT INTO db_branding_settings (setting_key, setting_value, setting_type)
|
|
VALUES (?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE setting_value = ?, updated_at = NOW()";
|
|
$result = $db->Execute($sql, [$key, $value, $type, $value]);
|
|
|
|
if ($result) {
|
|
// Clear CSS cache
|
|
$this->clearCache('css');
|
|
return true;
|
|
}
|
|
} catch (Exception $e) {
|
|
$logger = VLogger::getInstance();
|
|
$logger->logError('Failed to set branding setting: ' . $e->getMessage());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get multiple settings by category
|
|
*/
|
|
public function getByCategory($category)
|
|
{
|
|
global $db;
|
|
$settings = [];
|
|
|
|
try {
|
|
$sql = "SELECT setting_key, setting_value, setting_type, description, default_value
|
|
FROM db_branding_settings
|
|
WHERE category = ?
|
|
ORDER BY setting_key";
|
|
$result = $db->Execute($sql, [$category]);
|
|
|
|
if ($result) {
|
|
while (!$result->EOF) {
|
|
$key = $result->fields['setting_key'];
|
|
$settings[$key] = [
|
|
'value' => $this->convertValue($result->fields['setting_value'], $result->fields['setting_type']),
|
|
'type' => $result->fields['setting_type'],
|
|
'description' => $result->fields['description'],
|
|
'default' => $result->fields['default_value']
|
|
];
|
|
$result->MoveNext();
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$logger = VLogger::getInstance();
|
|
$logger->logError('Failed to get settings by category: ' . $e->getMessage());
|
|
}
|
|
|
|
return $settings;
|
|
}
|
|
|
|
/**
|
|
* Get all categories
|
|
*/
|
|
public function getCategories()
|
|
{
|
|
global $db;
|
|
$categories = [];
|
|
|
|
try {
|
|
$sql = "SELECT DISTINCT category FROM db_branding_settings ORDER BY category";
|
|
$result = $db->Execute($sql);
|
|
|
|
if ($result) {
|
|
while (!$result->EOF) {
|
|
$categories[] = $result->fields['category'];
|
|
$result->MoveNext();
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$logger = VLogger::getInstance();
|
|
$logger->logError('Failed to get categories: ' . $e->getMessage());
|
|
}
|
|
|
|
return $categories;
|
|
}
|
|
|
|
/**
|
|
* Generate dynamic CSS based on current settings
|
|
*/
|
|
public function generateCSS()
|
|
{
|
|
// Check cache first
|
|
if ($this->cache_enabled) {
|
|
$cached = $this->getCache('dynamic_css');
|
|
if ($cached) {
|
|
return $cached;
|
|
}
|
|
}
|
|
|
|
$css = $this->buildCSS();
|
|
|
|
// Cache the result
|
|
if ($this->cache_enabled) {
|
|
$this->setCache('dynamic_css', $css, $this->cache_duration);
|
|
}
|
|
|
|
return $css;
|
|
}
|
|
|
|
/**
|
|
* Build the actual CSS content
|
|
*/
|
|
private function buildCSS()
|
|
{
|
|
$css = "/* EasyStream Dynamic CSS - Generated " . date('Y-m-d H:i:s') . " */\n\n";
|
|
|
|
// CSS Variables (Custom Properties)
|
|
$css .= ":root {\n";
|
|
$css .= " /* Primary Colors */\n";
|
|
$css .= " --color-primary: " . $this->get('color_primary', '#007bff') . ";\n";
|
|
$css .= " --color-primary-dark: " . $this->get('color_primary_dark', '#0056b3') . ";\n";
|
|
$css .= " --color-primary-light: " . $this->get('color_primary_light', '#66b3ff') . ";\n";
|
|
$css .= " --color-secondary: " . $this->get('color_secondary', '#6c757d') . ";\n";
|
|
$css .= " --color-success: " . $this->get('color_success', '#28a745') . ";\n";
|
|
$css .= " --color-warning: " . $this->get('color_warning', '#ffc107') . ";\n";
|
|
$css .= " --color-danger: " . $this->get('color_danger', '#dc3545') . ";\n";
|
|
$css .= " --color-info: " . $this->get('color_info', '#17a2b8') . ";\n\n";
|
|
|
|
$css .= " /* Background Colors */\n";
|
|
$css .= " --color-bg-main: " . $this->get('color_bg_main', '#ffffff') . ";\n";
|
|
$css .= " --color-bg-secondary: " . $this->get('color_bg_secondary', '#f8f9fa') . ";\n";
|
|
$css .= " --color-bg-dark: " . $this->get('color_bg_dark', '#343a40') . ";\n";
|
|
$css .= " --color-bg-card: " . $this->get('color_bg_card', '#ffffff') . ";\n";
|
|
$css .= " --color-bg-header: " . $this->get('color_bg_header', '#ffffff') . ";\n";
|
|
$css .= " --color-bg-footer: " . $this->get('color_bg_footer', '#343a40') . ";\n\n";
|
|
|
|
$css .= " /* Text Colors */\n";
|
|
$css .= " --color-text-primary: " . $this->get('color_text_primary', '#212529') . ";\n";
|
|
$css .= " --color-text-secondary: " . $this->get('color_text_secondary', '#6c757d') . ";\n";
|
|
$css .= " --color-text-muted: " . $this->get('color_text_muted', '#868e96') . ";\n";
|
|
$css .= " --color-text-light: " . $this->get('color_text_light', '#ffffff') . ";\n";
|
|
$css .= " --color-text-link: " . $this->get('color_text_link', '#007bff') . ";\n";
|
|
$css .= " --color-text-link-hover: " . $this->get('color_text_link_hover', '#0056b3') . ";\n\n";
|
|
|
|
$css .= " /* Border and Shadow Colors */\n";
|
|
$css .= " --color-border: " . $this->get('color_border', '#dee2e6') . ";\n";
|
|
$css .= " --color-border-light: " . $this->get('color_border_light', '#e9ecef') . ";\n";
|
|
$css .= " --color-border-dark: " . $this->get('color_border_dark', '#adb5bd') . ";\n";
|
|
$css .= " --color-shadow: " . $this->get('color_shadow', 'rgba(0,0,0,0.1)') . ";\n\n";
|
|
|
|
$css .= " /* Typography */\n";
|
|
$css .= " --font-family-primary: " . $this->get('font_family_primary', '"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif') . ";\n";
|
|
$css .= " --font-family-secondary: " . $this->get('font_family_secondary', 'Georgia, "Times New Roman", serif') . ";\n";
|
|
$css .= " --font-size-base: " . $this->get('font_size_base', 16) . "px;\n";
|
|
$css .= " --font-size-small: " . $this->get('font_size_small', 14) . "px;\n";
|
|
$css .= " --font-size-large: " . $this->get('font_size_large', 18) . "px;\n";
|
|
$css .= " --line-height-base: " . $this->get('line_height_base', '1.5') . ";\n\n";
|
|
|
|
$css .= " /* Layout */\n";
|
|
$css .= " --layout-max-width: " . $this->get('layout_max_width', 1200) . "px;\n";
|
|
$css .= " --layout-sidebar-width: " . $this->get('layout_sidebar_width', 250) . "px;\n";
|
|
$css .= " --layout-header-height: " . $this->get('layout_header_height', 60) . "px;\n";
|
|
$css .= " --layout-footer-height: " . $this->get('layout_footer_height', 80) . "px;\n";
|
|
$css .= " --layout-border-radius: " . $this->get('layout_border_radius', 8) . "px;\n";
|
|
$css .= " --layout-spacing-small: " . $this->get('layout_spacing_small', 8) . "px;\n";
|
|
$css .= " --layout-spacing-medium: " . $this->get('layout_spacing_medium', 16) . "px;\n";
|
|
$css .= " --layout-spacing-large: " . $this->get('layout_spacing_large', 24) . "px;\n\n";
|
|
|
|
$css .= " /* Buttons */\n";
|
|
$css .= " --button-border-radius: " . $this->get('button_border_radius', 4) . "px;\n";
|
|
$css .= " --button-padding-x: " . $this->get('button_padding_x', 12) . "px;\n";
|
|
$css .= " --button-padding-y: " . $this->get('button_padding_y', 8) . "px;\n";
|
|
$css .= " --button-font-weight: " . $this->get('button_font_weight', 500) . ";\n\n";
|
|
|
|
$css .= " /* Badges */\n";
|
|
$css .= " --badge-border-radius: " . $this->get('badge_border_radius', 12) . "px;\n";
|
|
$css .= " --badge-font-size: " . $this->get('badge_font_size', 12) . "px;\n";
|
|
$css .= " --badge-padding-x: " . $this->get('badge_padding_x', 8) . "px;\n";
|
|
$css .= " --badge-padding-y: " . $this->get('badge_padding_y', 4) . "px;\n";
|
|
$css .= " --badge-verified-color: " . $this->get('badge_verified_color', '#28a745') . ";\n";
|
|
$css .= " --badge-premium-color: " . $this->get('badge_premium_color', '#ffc107') . ";\n";
|
|
$css .= " --badge-live-color: " . $this->get('badge_live_color', '#dc3545') . ";\n";
|
|
$css .= " --badge-new-color: " . $this->get('badge_new_color', '#17a2b8') . ";\n\n";
|
|
|
|
$css .= " /* Animation */\n";
|
|
$css .= " --animation-duration: " . $this->get('animation_duration', 300) . "ms;\n";
|
|
$css .= "}\n\n";
|
|
|
|
// Base styles using CSS variables
|
|
$css .= $this->generateBaseStyles();
|
|
|
|
// Component styles
|
|
$css .= $this->generateComponentStyles();
|
|
|
|
// Badge styles
|
|
$css .= $this->generateBadgeStyles();
|
|
|
|
// Button styles
|
|
$css .= $this->generateButtonStyles();
|
|
|
|
// Custom CSS
|
|
$customCSS = $this->get('custom_css', '');
|
|
if (!empty($customCSS)) {
|
|
$css .= "\n/* Custom CSS */\n" . $customCSS . "\n";
|
|
}
|
|
|
|
return $css;
|
|
}
|
|
|
|
/**
|
|
* Generate base styles
|
|
*/
|
|
private function generateBaseStyles()
|
|
{
|
|
return "
|
|
/* Base Styles */
|
|
body {
|
|
font-family: var(--font-family-primary);
|
|
font-size: var(--font-size-base);
|
|
line-height: var(--line-height-base);
|
|
color: var(--color-text-primary);
|
|
background-color: var(--color-bg-main);
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.container {
|
|
max-width: var(--layout-max-width);
|
|
margin: 0 auto;
|
|
padding: 0 var(--layout-spacing-medium);
|
|
}
|
|
|
|
.header {
|
|
background-color: var(--color-bg-header);
|
|
height: var(--layout-header-height);
|
|
border-bottom: 1px solid var(--color-border);
|
|
box-shadow: 0 2px 4px var(--color-shadow);
|
|
}
|
|
|
|
.footer {
|
|
background-color: var(--color-bg-footer);
|
|
color: var(--color-text-light);
|
|
min-height: var(--layout-footer-height);
|
|
padding: var(--layout-spacing-large) 0;
|
|
}
|
|
|
|
.card {
|
|
background-color: var(--color-bg-card);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--layout-border-radius);
|
|
box-shadow: 0 2px 4px var(--color-shadow);
|
|
padding: var(--layout-spacing-medium);
|
|
margin-bottom: var(--layout-spacing-medium);
|
|
}
|
|
|
|
a {
|
|
color: var(--color-text-link);
|
|
text-decoration: none;
|
|
transition: color var(--animation-duration) ease;
|
|
}
|
|
|
|
a:hover {
|
|
color: var(--color-text-link-hover);
|
|
}
|
|
|
|
";
|
|
}
|
|
|
|
/**
|
|
* Generate component styles
|
|
*/
|
|
private function generateComponentStyles()
|
|
{
|
|
return "
|
|
/* Component Styles */
|
|
.video-player {
|
|
border-radius: " . $this->get('player_border_radius', 8) . "px;
|
|
background-color: " . $this->get('player_background_color', '#000000') . ";
|
|
overflow: hidden;
|
|
}
|
|
|
|
.video-thumbnail {
|
|
border-radius: var(--layout-border-radius);
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.video-thumbnail::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(45deg, transparent 30%, var(--color-primary) 100%);
|
|
opacity: 0;
|
|
transition: opacity var(--animation-duration) ease;
|
|
}
|
|
|
|
.video-thumbnail:hover::after {
|
|
opacity: 0.1;
|
|
}
|
|
|
|
.sidebar {
|
|
width: var(--layout-sidebar-width);
|
|
background-color: var(--color-bg-secondary);
|
|
border-right: 1px solid var(--color-border);
|
|
min-height: calc(100vh - var(--layout-header-height));
|
|
}
|
|
|
|
.main-content {
|
|
margin-left: var(--layout-sidebar-width);
|
|
padding: var(--layout-spacing-large);
|
|
}
|
|
|
|
";
|
|
}
|
|
|
|
/**
|
|
* Generate badge styles
|
|
*/
|
|
private function generateBadgeStyles()
|
|
{
|
|
return "
|
|
/* Badge Styles */
|
|
.badge {
|
|
display: inline-block;
|
|
padding: var(--badge-padding-y) var(--badge-padding-x);
|
|
font-size: var(--badge-font-size);
|
|
font-weight: 600;
|
|
line-height: 1;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
vertical-align: baseline;
|
|
border-radius: var(--badge-border-radius);
|
|
transition: all var(--animation-duration) ease;
|
|
}
|
|
|
|
.badge-verified {
|
|
background-color: var(--badge-verified-color);
|
|
color: white;
|
|
}
|
|
|
|
.badge-premium {
|
|
background-color: var(--badge-premium-color);
|
|
color: #212529;
|
|
}
|
|
|
|
.badge-live {
|
|
background-color: var(--badge-live-color);
|
|
color: white;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
.badge-new {
|
|
background-color: var(--badge-new-color);
|
|
color: white;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0% { opacity: 1; }
|
|
50% { opacity: 0.7; }
|
|
100% { opacity: 1; }
|
|
}
|
|
|
|
";
|
|
}
|
|
|
|
/**
|
|
* Generate button styles
|
|
*/
|
|
private function generateButtonStyles()
|
|
{
|
|
return "
|
|
/* Button Styles */
|
|
.btn {
|
|
display: inline-block;
|
|
padding: var(--button-padding-y) var(--button-padding-x);
|
|
font-size: var(--font-size-base);
|
|
font-weight: var(--button-font-weight);
|
|
line-height: 1.5;
|
|
text-align: center;
|
|
text-decoration: none;
|
|
vertical-align: middle;
|
|
cursor: pointer;
|
|
border: 1px solid transparent;
|
|
border-radius: var(--button-border-radius);
|
|
transition: all var(--animation-duration) ease;
|
|
user-select: none;
|
|
}
|
|
|
|
.btn-primary {
|
|
color: white;
|
|
background-color: var(--color-primary);
|
|
border-color: var(--color-primary);
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background-color: var(--color-primary-dark);
|
|
border-color: var(--color-primary-dark);
|
|
}
|
|
|
|
.btn-secondary {
|
|
color: white;
|
|
background-color: var(--color-secondary);
|
|
border-color: var(--color-secondary);
|
|
}
|
|
|
|
.btn-success {
|
|
color: white;
|
|
background-color: var(--color-success);
|
|
border-color: var(--color-success);
|
|
}
|
|
|
|
.btn-warning {
|
|
color: #212529;
|
|
background-color: var(--color-warning);
|
|
border-color: var(--color-warning);
|
|
}
|
|
|
|
.btn-danger {
|
|
color: white;
|
|
background-color: var(--color-danger);
|
|
border-color: var(--color-danger);
|
|
}
|
|
|
|
.btn-info {
|
|
color: white;
|
|
background-color: var(--color-info);
|
|
border-color: var(--color-info);
|
|
}
|
|
|
|
.btn-outline-primary {
|
|
color: var(--color-primary);
|
|
background-color: transparent;
|
|
border-color: var(--color-primary);
|
|
}
|
|
|
|
.btn-outline-primary:hover {
|
|
color: white;
|
|
background-color: var(--color-primary);
|
|
}
|
|
|
|
";
|
|
}
|
|
|
|
/**
|
|
* Apply a preset theme
|
|
*/
|
|
public function applyPreset($presetName)
|
|
{
|
|
global $db;
|
|
|
|
try {
|
|
$sql = "SELECT preset_data FROM db_branding_presets WHERE preset_name = ?";
|
|
$result = $db->Execute($sql, [$presetName]);
|
|
|
|
if ($result && !$result->EOF) {
|
|
$presetData = json_decode($result->fields['preset_data'], true);
|
|
|
|
if ($presetData) {
|
|
foreach ($presetData as $key => $value) {
|
|
$this->set($key, $value);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$logger = VLogger::getInstance();
|
|
$logger->logError('Failed to apply preset: ' . $e->getMessage());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Save current settings as a preset
|
|
*/
|
|
public function savePreset($name, $description, $settings)
|
|
{
|
|
global $db;
|
|
|
|
try {
|
|
$presetData = json_encode($settings);
|
|
$sql = "INSERT INTO db_branding_presets (preset_name, preset_description, preset_data)
|
|
VALUES (?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE preset_description = ?, preset_data = ?, updated_at = NOW()";
|
|
$result = $db->Execute($sql, [$name, $description, $presetData, $description, $presetData]);
|
|
|
|
return (bool) $result;
|
|
} catch (Exception $e) {
|
|
$logger = VLogger::getInstance();
|
|
$logger->logError('Failed to save preset: ' . $e->getMessage());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get all available presets
|
|
*/
|
|
public function getPresets()
|
|
{
|
|
global $db;
|
|
$presets = [];
|
|
|
|
try {
|
|
$sql = "SELECT preset_name, preset_description, is_default, created_at
|
|
FROM db_branding_presets
|
|
ORDER BY is_default DESC, preset_name";
|
|
$result = $db->Execute($sql);
|
|
|
|
if ($result) {
|
|
while (!$result->EOF) {
|
|
$presets[] = [
|
|
'name' => $result->fields['preset_name'],
|
|
'description' => $result->fields['preset_description'],
|
|
'is_default' => (bool) $result->fields['is_default'],
|
|
'created_at' => $result->fields['created_at']
|
|
];
|
|
$result->MoveNext();
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$logger = VLogger::getInstance();
|
|
$logger->logError('Failed to get presets: ' . $e->getMessage());
|
|
}
|
|
|
|
return $presets;
|
|
}
|
|
|
|
/**
|
|
* Cache management
|
|
*/
|
|
private function getCache($key)
|
|
{
|
|
global $db;
|
|
|
|
try {
|
|
$sql = "SELECT cache_data FROM db_branding_cache
|
|
WHERE cache_key = ? AND (expires_at IS NULL OR expires_at > NOW())";
|
|
$result = $db->Execute($sql, [$key]);
|
|
|
|
if ($result && !$result->EOF) {
|
|
return $result->fields['cache_data'];
|
|
}
|
|
} catch (Exception $e) {
|
|
// Fail silently for cache
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private function setCache($key, $data, $duration = 3600)
|
|
{
|
|
global $db;
|
|
|
|
try {
|
|
$expiresAt = date('Y-m-d H:i:s', time() + $duration);
|
|
$sql = "INSERT INTO db_branding_cache (cache_key, cache_data, expires_at)
|
|
VALUES (?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE cache_data = ?, expires_at = ?";
|
|
$db->Execute($sql, [$key, $data, $expiresAt, $data, $expiresAt]);
|
|
} catch (Exception $e) {
|
|
// Fail silently for cache
|
|
}
|
|
}
|
|
|
|
private function clearCache($type = null)
|
|
{
|
|
global $db;
|
|
|
|
try {
|
|
if ($type) {
|
|
$sql = "DELETE FROM db_branding_cache WHERE cache_type = ?";
|
|
$db->Execute($sql, [$type]);
|
|
} else {
|
|
$sql = "DELETE FROM db_branding_cache";
|
|
$db->Execute($sql);
|
|
}
|
|
} catch (Exception $e) {
|
|
// Fail silently for cache
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate logo HTML with proper branding
|
|
*/
|
|
public function getLogo($type = 'main', $class = '', $alt = null)
|
|
{
|
|
$logoPath = $this->get("logo_$type", '/f_scripts/fe/img/logo-header-blue.svg');
|
|
$siteName = $this->get('site_name', 'EasyStream');
|
|
$altText = $alt ?: $siteName;
|
|
|
|
return "<img src=\"$logoPath\" alt=\"$altText\" class=\"logo $class\">";
|
|
}
|
|
|
|
/**
|
|
* Generate badge HTML
|
|
*/
|
|
public function getBadge($type, $text = null, $class = '')
|
|
{
|
|
$badges = [
|
|
'verified' => ['text' => '✓ Verified', 'class' => 'badge-verified'],
|
|
'premium' => ['text' => '★ Premium', 'class' => 'badge-premium'],
|
|
'live' => ['text' => '● LIVE', 'class' => 'badge-live'],
|
|
'new' => ['text' => 'NEW', 'class' => 'badge-new']
|
|
];
|
|
|
|
if (!isset($badges[$type])) {
|
|
return '';
|
|
}
|
|
|
|
$badgeText = $text ?: $badges[$type]['text'];
|
|
$badgeClass = $badges[$type]['class'];
|
|
|
|
return "<span class=\"badge $badgeClass $class\">$badgeText</span>";
|
|
}
|
|
|
|
/**
|
|
* Get site information for templates
|
|
*/
|
|
public function getSiteInfo()
|
|
{
|
|
return [
|
|
'name' => $this->get('site_name', 'EasyStream'),
|
|
'tagline' => $this->get('site_tagline', 'Your Video Streaming Platform'),
|
|
'description' => $this->get('site_description', 'A powerful video streaming platform'),
|
|
'footer_text' => $this->get('footer_text', '© 2025 EasyStream. All rights reserved.'),
|
|
'logo_main' => $this->get('logo_main', '/f_scripts/fe/img/logo-header-blue.svg'),
|
|
'logo_small' => $this->get('logo_small', '/f_scripts/fe/img/logo-small.png'),
|
|
'favicon' => $this->get('favicon', '/favicon.ico')
|
|
];
|
|
}
|
|
}
|