T.ME/BIBIL_0DAY
CasperSecurity


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/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/RADIO_STATION_QUICK_START.md
# 🚀 Radio Station Licensing - Quick Start Guide

## Overview
This guide will help you get started implementing the radio station licensing system for SoundStudioPro.

## Prerequisites
- PHP 8.0+
- MySQL 5.7+ or MariaDB 10.3+
- Existing SoundStudioPro installation
- Stripe account (for subscription billing)

## Step 1: Run Database Migration

Run the migration script to create all necessary tables:

```bash
php migrations/add_radio_station_system.php
```

Or access via browser:
```
https://soundstudiopro.com/migrations/add_radio_station_system.php
```

This will create:
- 9 new tables for radio station functionality
- Additional columns on existing `music_tracks` and `users` tables

## Step 2: Create Directory Structure

Create the following directories:

```
/radio/
  /dashboard/        - Station dashboard pages
  /api/              - API endpoints
  /playlists/        - Playlist management
  /analytics/        - Analytics pages
  /admin/            - Admin tools for managing stations
```

## Step 3: Create Basic Station Registration

Create `/radio/register.php` for station signup:

```php
<?php
require_once '../config/database.php';
require_once '../includes/header.php';

// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $pdo = getDBConnection();
    
    // Generate API credentials
    $api_key = bin2hex(random_bytes(32));
    $api_secret = bin2hex(random_bytes(32));
    
    // Insert station
    $stmt = $pdo->prepare("
        INSERT INTO radio_stations (
            station_name, call_sign, station_type, license_tier,
            contact_name, contact_email, contact_phone,
            city, state, country, timezone,
            subscription_status, monthly_play_limit,
            api_key, api_secret, api_enabled
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    
    $stmt->execute([
        $_POST['station_name'],
        $_POST['call_sign'] ?? null,
        $_POST['station_type'] ?? 'local',
        $_POST['license_tier'] ?? 'local',
        $_POST['contact_name'],
        $_POST['contact_email'],
        $_POST['contact_phone'] ?? null,
        $_POST['city'] ?? null,
        $_POST['state'] ?? null,
        $_POST['country'] ?? 'US',
        $_POST['timezone'] ?? 'America/New_York',
        'trial',
        $_POST['license_tier'] === 'local' ? 500 : ($_POST['license_tier'] === 'regional' ? 2000 : 999999),
        $api_key,
        password_hash($api_secret, PASSWORD_DEFAULT),
        true
    ]);
    
    $station_id = $pdo->lastInsertId();
    
    // Redirect to Stripe checkout
    header("Location: /radio/subscribe.php?station_id=" . $station_id);
    exit;
}
?>

<!-- Registration form HTML -->
```

## Step 4: Create API Endpoint Structure

Create `/radio/api/v1/index.php` as the main API router:

```php
<?php
require_once '../../../config/database.php';

header('Content-Type: application/json');

// Authenticate API request
function authenticateAPI() {
    $headers = getallheaders();
    $auth = $headers['Authorization'] ?? '';
    
    if (!preg_match('/Bearer (.+):(.+)/', $auth, $matches)) {
        http_response_code(401);
        echo json_encode(['error' => 'Invalid authentication']);
        exit;
    }
    
    $api_key = $matches[1];
    $api_secret = $matches[2];
    
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("
        SELECT * FROM radio_stations 
        WHERE api_key = ? AND api_enabled = 1 AND subscription_status = 'active'
    ");
    $stmt->execute([$api_key]);
    $station = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$station || !password_verify($api_secret, $station['api_secret'])) {
        http_response_code(401);
        echo json_encode(['error' => 'Invalid credentials']);
        exit;
    }
    
    // Check play limit
    if ($station['current_month_plays'] >= $station['monthly_play_limit']) {
        http_response_code(403);
        echo json_encode(['error' => 'Monthly play limit reached']);
        exit;
    }
    
    return $station;
}

// Route requests
$path = $_SERVER['PATH_INFO'] ?? '/';
$method = $_SERVER['REQUEST_METHOD'];

switch ($path) {
    case '/catalog/tracks':
        if ($method === 'GET') {
            require 'endpoints/catalog_tracks.php';
        }
        break;
        
    case '/plays':
        if ($method === 'POST') {
            require 'endpoints/log_play.php';
        } elseif ($method === 'GET') {
            require 'endpoints/get_plays.php';
        }
        break;
        
    case '/playlists':
        if ($method === 'GET') {
            require 'endpoints/get_playlists.php';
        } elseif ($method === 'POST') {
            require 'endpoints/create_playlist.php';
        }
        break;
        
    default:
        http_response_code(404);
        echo json_encode(['error' => 'Endpoint not found']);
}
```

## Step 5: Create Key API Endpoints

### `/radio/api/v1/endpoints/log_play.php`

```php
<?php
$station = authenticateAPI();
$pdo = getDBConnection();

$data = json_decode(file_get_contents('php://input'), true);

// Validate required fields
if (!isset($data['track_id']) || !isset($data['played_at'])) {
    http_response_code(400);
    echo json_encode(['error' => 'Missing required fields']);
    exit;
}

// Check if track is licensed
$stmt = $pdo->prepare("
    SELECT id FROM radio_licenses 
    WHERE station_id = ? AND track_id = ? AND status = 'active'
    AND (end_date IS NULL OR end_date >= CURDATE())
");
$stmt->execute([$station['id'], $data['track_id']]);
$license = $stmt->fetch();

if (!$license) {
    // Auto-create subscription license
    $stmt = $pdo->prepare("
        INSERT INTO radio_licenses (station_id, track_id, license_type, start_date, status)
        VALUES (?, ?, 'subscription', CURDATE(), 'active')
    ");
    $stmt->execute([$station['id'], $data['track_id']]);
}

// Log the play
$stmt = $pdo->prepare("
    INSERT INTO radio_play_logs (
        station_id, track_id, playlist_id,
        played_at, duration_played, play_type,
        time_of_day, day_of_week, source
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
");

$played_at = new DateTime($data['played_at']);
$stmt->execute([
    $station['id'],
    $data['track_id'],
    $data['playlist_id'] ?? null,
    $data['played_at'],
    $data['duration_played'] ?? null,
    $data['play_type'] ?? 'full',
    $played_at->format('H:i:s'),
    $played_at->format('w'),
    $data['source'] ?? 'api'
]);

$play_id = $pdo->lastInsertId();

// Update station play count
$pdo->prepare("
    UPDATE radio_stations 
    SET current_month_plays = current_month_plays + 1
    WHERE id = ?
")->execute([$station['id']]);

// Update track play count
$pdo->prepare("
    UPDATE music_tracks 
    SET radio_play_count = radio_play_count + 1,
        radio_last_played = NOW()
    WHERE id = ?
")->execute([$data['track_id']]);

// Calculate royalty (async in production)
calculateRoyalty($pdo, $play_id, $station['id'], $data['track_id']);

// Return success
echo json_encode([
    'play_id' => $play_id,
    'logged' => true,
    'monthly_plays_remaining' => $station['monthly_play_limit'] - $station['current_month_plays'] - 1
]);
```

## Step 6: Create Station Dashboard

Create `/radio/dashboard/index.php`:

```php
<?php
session_start();
require_once '../../config/database.php';
require_once '../../includes/header.php';

// Get station from session or require login
$station_id = $_SESSION['radio_station_id'] ?? null;
if (!$station_id) {
    header('Location: /radio/login.php');
    exit;
}

$pdo = getDBConnection();

// Get station info
$stmt = $pdo->prepare("SELECT * FROM radio_stations WHERE id = ?");
$stmt->execute([$station_id]);
$station = $stmt->fetch(PDO::FETCH_ASSOC);

// Get stats
$stmt = $pdo->prepare("
    SELECT 
        COUNT(*) as total_plays,
        COUNT(DISTINCT track_id) as unique_tracks,
        COUNT(DISTINCT DATE(played_at)) as active_days
    FROM radio_play_logs
    WHERE station_id = ? 
    AND played_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
");
$stmt->execute([$station_id]);
$stats = $stmt->fetch(PDO::FETCH_ASSOC);

// Get top tracks
$stmt = $pdo->prepare("
    SELECT 
        t.id,
        t.title,
        t.artist_name,
        COUNT(*) as play_count,
        MAX(pl.played_at) as last_played
    FROM radio_play_logs pl
    JOIN music_tracks t ON pl.track_id = t.id
    WHERE pl.station_id = ?
    AND pl.played_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
    GROUP BY t.id
    ORDER BY play_count DESC
    LIMIT 10
");
$stmt->execute([$station_id]);
$top_tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

<!-- Dashboard HTML -->
<div class="radio-dashboard">
    <h1><?= htmlspecialchars($station['station_name']) ?> Dashboard</h1>
    
    <div class="stats-grid">
        <div class="stat-card">
            <h3>Monthly Plays</h3>
            <p class="stat-number"><?= $station['current_month_plays'] ?> / <?= $station['monthly_play_limit'] ?></p>
        </div>
        
        <div class="stat-card">
            <h3>Total Plays (30 days)</h3>
            <p class="stat-number"><?= $stats['total_plays'] ?></p>
        </div>
        
        <div class="stat-card">
            <h3>Unique Tracks</h3>
            <p class="stat-number"><?= $stats['unique_tracks'] ?></p>
        </div>
    </div>
    
    <div class="top-tracks">
        <h2>Top Tracks This Month</h2>
        <table>
            <thead>
                <tr>
                    <th>Track</th>
                    <th>Artist</th>
                    <th>Plays</th>
                    <th>Last Played</th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($top_tracks as $track): ?>
                <tr>
                    <td><?= htmlspecialchars($track['title']) ?></td>
                    <td><?= htmlspecialchars($track['artist_name']) ?></td>
                    <td><?= $track['play_count'] ?></td>
                    <td><?= date('M j, Y g:i A', strtotime($track['last_played'])) ?></td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    </div>
</div>

<?php include '../../includes/footer.php'; ?>
```

## Step 7: Create Playlist Builder

Create `/radio/playlists/create.php`:

```php
<?php
// Playlist creation interface with drag-and-drop
// Search tracks, add to playlist, set rotation rules
?>
```

## Step 8: Set Up Stripe Integration

Create `/radio/subscribe.php` for Stripe checkout:

```php
<?php
require_once '../config/stripe.php'; // Your Stripe config

$station_id = $_GET['station_id'] ?? null;
if (!$station_id) {
    die('Invalid station');
}

$pdo = getDBConnection();
$stmt = $pdo->prepare("SELECT * FROM radio_stations WHERE id = ?");
$stmt->execute([$station_id]);
$station = $stmt->fetch(PDO::FETCH_ASSOC);

// Create Stripe checkout session
$checkout_session = \Stripe\Checkout\Session::create([
    'customer_email' => $station['contact_email'],
    'payment_method_types' => ['card'],
    'line_items' => [[
        'price_data' => [
            'currency' => 'usd',
            'product_data' => [
                'name' => 'Radio Station License - ' . ucfirst($station['license_tier']),
            ],
            'unit_amount' => getTierPrice($station['license_tier']) * 100,
            'recurring' => ['interval' => 'month'],
        ],
        'quantity' => 1,
    ]],
    'mode' => 'subscription',
    'success_url' => 'https://soundstudiopro.com/radio/subscription_success.php?session_id={CHECKOUT_SESSION_ID}',
    'cancel_url' => 'https://soundstudiopro.com/radio/register.php',
    'metadata' => [
        'station_id' => $station_id
    ]
]);

header("Location: " . $checkout_session->url);
```

## Step 9: Create Royalty Calculation Function

Add to `/radio/includes/functions.php`:

```php
<?php
function calculateRoyalty($pdo, $play_log_id, $station_id, $track_id) {
    // Get track and artist info
    $stmt = $pdo->prepare("
        SELECT t.radio_royalty_rate, t.user_id as artist_id
        FROM music_tracks t
        WHERE t.id = ?
    ");
    $stmt->execute([$track_id]);
    $track = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$track) return;
    
    // Get station subscription info for royalty pool calculation
    $stmt = $pdo->prepare("
        SELECT license_tier, monthly_play_limit
        FROM radio_stations
        WHERE id = ?
    ");
    $stmt->execute([$station_id]);
    $station = $stmt->fetch(PDO::FETCH_ASSOC);
    
    // Calculate royalty (simplified - in production, use actual subscription revenue)
    $base_rate = $track['radio_royalty_rate'];
    $royalty_amount = $base_rate; // Per play
    
    // Insert royalty record
    $stmt = $pdo->prepare("
        INSERT INTO radio_royalties (
            play_log_id, station_id, track_id, artist_id,
            base_rate, total_amount, artist_payout, payment_status
        ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending')
    ");
    $stmt->execute([
        $play_log_id,
        $station_id,
        $track_id,
        $track['artist_id'],
        $base_rate,
        $royalty_amount,
        $royalty_amount * 0.7 // 70% to artist
    ]);
    
    // Update track royalty calculated flag
    $pdo->prepare("
        UPDATE radio_play_logs 
        SET royalty_calculated = TRUE, royalty_amount = ?
        WHERE id = ?
    ")->execute([$royalty_amount, $play_log_id]);
    
    // Update artist totals
    $pdo->prepare("
        UPDATE users 
        SET radio_total_plays = radio_total_plays + 1,
            radio_total_royalties = radio_total_royalties + ?
        WHERE id = ?
    ")->execute([$royalty_amount * 0.7, $track['artist_id']]);
}
```

## Step 10: Testing

### Test API Endpoint

```bash
curl -X POST https://soundstudiopro.com/radio/api/v1/plays \
  -H "Authorization: Bearer YOUR_API_KEY:YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "track_id": 123,
    "played_at": "2025-01-15T10:30:00Z",
    "duration_played": 180,
    "play_type": "full"
  }'
```

### Test Playlist Creation

1. Log into station dashboard
2. Navigate to Playlists
3. Create new playlist
4. Search and add tracks
5. Verify playlist appears in list

## Next Steps

1. **Build Catalog Browser** - Full search and filter interface
2. **Create Scheduler** - Calendar-based scheduling system
3. **Build Analytics Dashboard** - Charts and reports
4. **Implement PRO Reporting** - Automated compliance reports
5. **Create Artist Dashboard** - Radio performance view for artists
6. **Add Webhooks** - Real-time notifications
7. **Mobile App** - React Native or PWA for station managers

## Resources

- Full Technical Design: `RADIO_STATION_LICENSING_VISION.md`
- Database Schema: See migration script
- API Documentation: Create OpenAPI spec from endpoints

## Support

For questions or issues, refer to the main vision document or create an issue in your project tracker.


CasperSecurity Mini