![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/private_html/admin_includes/ |
<?php
/**
* Admin Panel: Live Radio Management
* Manage live streams, stations, listeners, and votes
*/
$pdo = getDBConnection();
// Handle actions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
switch ($action) {
case 'stop_stream':
$stream_id = (int)$_POST['stream_id'];
$stmt = $pdo->prepare("UPDATE radio_streams SET is_live = FALSE WHERE id = ?");
$stmt->execute([$stream_id]);
$success_message = "Stream stopped successfully";
break;
case 'start_stream':
$stream_id = (int)$_POST['stream_id'];
$stmt = $pdo->prepare("UPDATE radio_streams SET is_live = TRUE, started_at = NOW() WHERE id = ?");
$stmt->execute([$stream_id]);
$success_message = "Stream started successfully";
break;
case 'delete_stream':
$stream_id = (int)$_POST['stream_id'];
$stmt = $pdo->prepare("DELETE FROM radio_streams WHERE id = ?");
$stmt->execute([$stream_id]);
$success_message = "Stream deleted successfully";
break;
case 'clear_votes':
$stream_id = (int)$_POST['stream_id'];
$stmt = $pdo->prepare("DELETE FROM radio_votes WHERE stream_id = ?");
$stmt->execute([$stream_id]);
$success_message = "Votes cleared successfully";
break;
}
}
// Check if tables exist first
$tables_exist = false;
$streams = [];
$error_message = null;
try {
// Check if radio_streams table exists
$pdo->query("SELECT 1 FROM radio_streams LIMIT 1");
$tables_exist = true;
// Get all streams with station info
try {
// Check if radio_stations table exists
$pdo->query("SELECT 1 FROM radio_stations LIMIT 1");
$stmt = $pdo->query("
SELECT
rstr.*,
rs.station_name,
rs.call_sign,
rs.subscription_status,
(SELECT COUNT(*) FROM radio_listeners WHERE stream_id = rstr.id AND disconnected_at IS NULL) as current_listeners,
(SELECT COUNT(*) FROM radio_votes WHERE stream_id = rstr.id) as total_votes,
(SELECT COUNT(*) FROM radio_now_playing WHERE stream_id = rstr.id AND ended_at IS NULL) as has_now_playing
FROM radio_streams rstr
LEFT JOIN radio_stations rs ON rstr.station_id = rs.id
ORDER BY rstr.started_at DESC
LIMIT 50
");
$streams = $stmt->fetchAll();
} catch (Exception $e) {
// radio_stations table doesn't exist, try without it
$stmt = $pdo->query("
SELECT
rstr.*,
NULL as station_name,
NULL as call_sign,
NULL as subscription_status,
(SELECT COUNT(*) FROM radio_listeners WHERE stream_id = rstr.id AND disconnected_at IS NULL) as current_listeners,
(SELECT COUNT(*) FROM radio_votes WHERE stream_id = rstr.id) as total_votes,
(SELECT COUNT(*) FROM radio_now_playing WHERE stream_id = rstr.id AND ended_at IS NULL) as has_now_playing
FROM radio_streams rstr
ORDER BY rstr.started_at DESC
LIMIT 50
");
$streams = $stmt->fetchAll();
}
} catch (Exception $e) {
// Tables don't exist yet
$tables_exist = false;
$error_message = "Live streaming tables not found. Please run the migration first.";
}
// Get overall stats
$stats = [
'total_streams' => 0,
'active_streams' => 0,
'total_listeners' => 0,
'total_votes' => 0,
'total_stations' => 0
];
if ($tables_exist) {
try {
$stmt = $pdo->query("SELECT COUNT(*) FROM radio_streams");
$stats['total_streams'] = $stmt->fetchColumn();
$stmt = $pdo->query("SELECT COUNT(*) FROM radio_streams WHERE is_live = 1");
$stats['active_streams'] = $stmt->fetchColumn();
$stmt = $pdo->query("SELECT COUNT(*) FROM radio_listeners WHERE disconnected_at IS NULL");
$stats['total_listeners'] = $stmt->fetchColumn();
$stmt = $pdo->query("SELECT COUNT(*) FROM radio_votes");
$stats['total_votes'] = $stmt->fetchColumn();
// Try to get stations count, but don't fail if table doesn't exist
try {
$stmt = $pdo->query("SELECT COUNT(*) FROM radio_stations WHERE subscription_status = 'active'");
$stats['total_stations'] = $stmt->fetchColumn();
} catch (Exception $e) {
// radio_stations table doesn't exist, that's okay
$stats['total_stations'] = 0;
}
} catch (Exception $e) {
// Stats might fail if tables don't exist
error_log("Error loading radio stats: " . $e->getMessage());
}
}
?>
<style>
.radio-admin {
padding: 2rem;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.stat-card {
background: rgba(26, 26, 26, 0.9);
padding: 1.5rem;
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.stat-card h3 {
font-size: 0.9rem;
color: #a0aec0;
margin-bottom: 0.5rem;
text-transform: uppercase;
letter-spacing: 1px;
}
.stat-card .number {
font-size: 2.5rem;
font-weight: 800;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.streams-table {
width: 100%;
background: rgba(26, 26, 26, 0.9);
border-radius: 12px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.streams-table table {
width: 100%;
border-collapse: collapse;
}
.streams-table th {
background: rgba(102, 126, 234, 0.1);
padding: 1rem;
text-align: left;
font-weight: 600;
color: #667eea;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.streams-table td {
padding: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.streams-table tr:hover {
background: rgba(102, 126, 234, 0.05);
}
.status-badge {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 600;
}
.status-badge.live {
background: rgba(239, 68, 68, 0.2);
color: #ef4444;
}
.status-badge.offline {
background: rgba(156, 163, 175, 0.2);
color: #9ca3af;
}
.btn-small {
padding: 0.5rem 1rem;
border: none;
border-radius: 6px;
font-size: 0.85rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
margin: 0.25rem;
}
.btn-danger {
background: #ef4444;
color: white;
}
.btn-danger:hover {
background: #dc2626;
}
.btn-success {
background: #10b981;
color: white;
}
.btn-success:hover {
background: #059669;
}
.btn-secondary {
background: #6b7280;
color: white;
}
.btn-secondary:hover {
background: #4b5563;
}
.action-buttons {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.empty-state {
text-align: center;
padding: 4rem 2rem;
color: #a0aec0;
}
.empty-state h3 {
font-size: 1.5rem;
margin-bottom: 1rem;
color: #ffffff;
}
</style>
<div class="radio-admin">
<h2 style="margin-bottom: 2rem; font-size: 2rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">📻 Live Radio Management</h2>
<?php if (isset($success_message)): ?>
<div style="background: rgba(16, 185, 129, 0.2); color: #10b981; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; border: 1px solid rgba(16, 185, 129, 0.3);">
✅ <?= htmlspecialchars($success_message) ?>
</div>
<?php endif; ?>
<?php if (isset($error_message)): ?>
<div style="background: rgba(239, 68, 68, 0.2); color: #ef4444; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; border: 1px solid rgba(239, 68, 68, 0.3);">
❌ <?= htmlspecialchars($error_message) ?>
<div style="margin-top: 0.5rem;">
<a href="/radio/migrations/add_live_streaming_tables.php" target="_blank" style="color: #ef4444; text-decoration: underline;">
Click here to run the migration
</a>
</div>
</div>
<?php endif; ?>
<?php if (!$tables_exist): ?>
<div style="background: rgba(255, 193, 7, 0.2); color: #ffc107; padding: 1.5rem; border-radius: 8px; margin-bottom: 2rem; border: 1px solid rgba(255, 193, 7, 0.3);">
<h3 style="margin-bottom: 1rem; color: #ffc107;">⚠️ Setup Required</h3>
<p style="margin-bottom: 1rem;">The live streaming database tables need to be created before you can manage streams.</p>
<a href="/radio/migrations/add_live_streaming_tables.php" target="_blank"
style="display: inline-block; padding: 0.75rem 1.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-decoration: none; border-radius: 8px; font-weight: 600;">
🔧 Run Migration Now
</a>
</div>
<?php endif; ?>
<!-- Stats Overview -->
<?php if ($tables_exist): ?>
<div class="stats-grid">
<div class="stat-card">
<h3>Total Streams</h3>
<div class="number"><?= number_format($stats['total_streams']) ?></div>
</div>
<div class="stat-card">
<h3>Active Streams</h3>
<div class="number"><?= number_format($stats['active_streams']) ?></div>
</div>
<div class="stat-card">
<h3>Current Listeners</h3>
<div class="number"><?= number_format($stats['total_listeners']) ?></div>
</div>
<div class="stat-card">
<h3>Total Votes</h3>
<div class="number"><?= number_format($stats['total_votes']) ?></div>
</div>
<div class="stat-card">
<h3>Active Stations</h3>
<div class="number"><?= number_format($stats['total_stations']) ?></div>
</div>
</div>
<?php endif; ?>
<!-- Streams Table -->
<?php if ($tables_exist): ?>
<div class="streams-table">
<h3 style="padding: 1.5rem 1rem 1rem; font-size: 1.3rem;">All Streams</h3>
<?php if (empty($streams)): ?>
<div class="empty-state">
<h3>No Streams Found</h3>
<p>No radio streams have been created yet. Stations can start streams from their dashboard.</p>
</div>
<?php else: ?>
<table>
<thead>
<tr>
<th>Station</th>
<th>Stream Name</th>
<th>Status</th>
<th>Listeners</th>
<th>Votes</th>
<th>Started</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($streams as $stream): ?>
<tr>
<td>
<strong><?= htmlspecialchars($stream['station_name'] ?? 'Unknown') ?></strong>
<?php if ($stream['call_sign']): ?>
<br><small style="color: #a0aec0;"><?= htmlspecialchars($stream['call_sign']) ?></small>
<?php endif; ?>
</td>
<td><?= htmlspecialchars($stream['stream_name']) ?></td>
<td>
<?php if ($stream['is_live']): ?>
<span class="status-badge live">🔴 LIVE</span>
<?php else: ?>
<span class="status-badge offline">⚫ OFFLINE</span>
<?php endif; ?>
</td>
<td>
<strong style="color: #667eea;"><?= number_format($stream['current_listeners'] ?? 0) ?></strong>
</td>
<td><?= number_format($stream['total_votes'] ?? 0) ?></td>
<td>
<?php if ($stream['started_at']): ?>
<?= date('M j, Y g:i A', strtotime($stream['started_at'])) ?>
<?php else: ?>
<span style="color: #a0aec0;">Never</span>
<?php endif; ?>
</td>
<td>
<div class="action-buttons">
<?php if ($stream['is_live']): ?>
<form method="POST" style="display: inline;" onsubmit="return confirm('Stop this stream?');">
<input type="hidden" name="action" value="stop_stream">
<input type="hidden" name="stream_id" value="<?= $stream['id'] ?>">
<button type="submit" class="btn-small btn-danger">Stop</button>
</form>
<?php else: ?>
<form method="POST" style="display: inline;">
<input type="hidden" name="action" value="start_stream">
<input type="hidden" name="stream_id" value="<?= $stream['id'] ?>">
<button type="submit" class="btn-small btn-success">Start</button>
</form>
<?php endif; ?>
<a href="/radio/live.php?station=<?= $stream['station_id'] ?>" target="_blank" class="btn-small btn-secondary" style="text-decoration: none; display: inline-block;">View</a>
<form method="POST" style="display: inline;" onsubmit="return confirm('Clear all votes for this stream?');">
<input type="hidden" name="action" value="clear_votes">
<input type="hidden" name="stream_id" value="<?= $stream['id'] ?>">
<button type="submit" class="btn-small btn-secondary">Clear Votes</button>
</form>
<form method="POST" style="display: inline;" onsubmit="return confirm('Delete this stream? This cannot be undone.');">
<input type="hidden" name="action" value="delete_stream">
<input type="hidden" name="stream_id" value="<?= $stream['id'] ?>">
<button type="submit" class="btn-small btn-danger">Delete</button>
</form>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- Quick Links -->
<div style="margin-top: 2rem; padding: 1.5rem; background: rgba(26, 26, 26, 0.9); border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.1);">
<h3 style="margin-bottom: 1rem; font-size: 1.2rem;">Quick Links</h3>
<div style="display: flex; gap: 1rem; flex-wrap: wrap;">
<a href="/radio/live.php" target="_blank" style="padding: 0.75rem 1.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-decoration: none; border-radius: 8px; font-weight: 600;">
🎧 View Live Player
</a>
<a href="/radio/" target="_blank" style="padding: 0.75rem 1.5rem; background: rgba(255, 255, 255, 0.1); color: white; text-decoration: none; border-radius: 8px; font-weight: 600; border: 1px solid rgba(255, 255, 255, 0.2);">
📻 Radio Homepage
</a>
<a href="/radio/migrations/add_live_streaming_tables.php" target="_blank" style="padding: 0.75rem 1.5rem; background: rgba(255, 255, 255, 0.1); color: white; text-decoration: none; border-radius: 8px; font-weight: 600; border: 1px solid rgba(255, 255, 255, 0.2);">
🔧 Run Migration
</a>
</div>
</div>
</div>