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/public_html/cron/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/cron/auto_fix_titles.php
<?php
/**
 * Cron Job: Auto-Fix Stuck Tracks and Missing Titles
 * 
 * This script can be called:
 * 1. Via cPanel Cron Job: /usr/bin/php /home/gositeme/domains/soundstudiopro.com/public_html/cron/auto_fix_titles.php
 * 2. Via HTTP with secret key: https://soundstudiopro.com/cron/auto_fix_titles.php?key=YOUR_SECRET_KEY
 * 
 * Recommended frequency: Every 15 minutes
 */

// Security: Check for secret key when called via HTTP
$is_cli = php_sapi_name() === 'cli';
$secret_key = 'soundstudiopro_autofix_2025_secure';

if (!$is_cli) {
    $provided_key = $_GET['key'] ?? '';
    if ($provided_key !== $secret_key) {
        http_response_code(403);
        echo json_encode(['error' => 'Unauthorized access']);
        exit;
    }
    
    // Set content type for web access
    header('Content-Type: application/json');
}

// Change to public_html directory
chdir(dirname(__DIR__));

require_once 'config/database.php';

$log_file = __DIR__ . '/../logs/auto_fix_cron.log';
$results = [
    'timestamp' => date('Y-m-d H:i:s'),
    'stuck_tracks_fixed' => 0,
    'titles_fixed' => 0,
    'errors' => []
];

function cronLog($message) {
    global $log_file;
    $timestamp = date('Y-m-d H:i:s');
    $log_entry = "[$timestamp] $message\n";
    file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
}

cronLog("=== Auto-Fix Cron Started ===");

try {
    $pdo = getDBConnection();
    if (!$pdo) {
        throw new Exception("Database connection failed");
    }
    
    // PART 1: Fix completed tracks with missing titles
    cronLog("Scanning for completed tracks with missing titles...");
    
    // Only fix titles that haven't been user-modified
    $stmt = $pdo->query("
        SELECT id, task_id, title FROM music_tracks 
        WHERE status = 'complete' 
        AND (title IS NULL OR title = '' OR title = 'Untitled Track' OR title = 'Generated Track')
        AND (title_user_modified = 0 OR title_user_modified IS NULL)
        ORDER BY created_at DESC
        LIMIT 50
    ");
    
    $missing_title_tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
    cronLog("Found " . count($missing_title_tracks) . " tracks with missing titles");
    
    foreach ($missing_title_tracks as $track) {
        $result_file = dirname(__DIR__) . "/task_results/{$track['task_id']}.json";
        
        if (file_exists($result_file)) {
            $result_data = json_decode(file_get_contents($result_file), true);
            
            // Extract title from API response
            $extracted_title = null;
            if (isset($result_data['data']['data']) && is_array($result_data['data']['data'])) {
                foreach ($result_data['data']['data'] as $item) {
                    if (isset($item['title']) && !empty($item['title']) && trim($item['title']) !== '') {
                        $extracted_title = trim($item['title']);
                        break;
                    }
                }
            }
            
            if ($extracted_title) {
                $update_stmt = $pdo->prepare("UPDATE music_tracks SET title = ?, updated_at = NOW() WHERE id = ?");
                if ($update_stmt->execute([$extracted_title, $track['id']])) {
                    cronLog("✅ Fixed title for Track ID {$track['id']}: $extracted_title");
                    $results['titles_fixed']++;
                }
            }
        }
    }
    
    // PART 2: Check for stuck processing tracks (older than 1 hour)
    cronLog("Scanning for stuck processing tracks...");
    
    $stmt = $pdo->query("
        SELECT id, task_id, title, created_at FROM music_tracks 
        WHERE status = 'processing' 
        AND created_at < DATE_SUB(NOW(), INTERVAL 1 HOUR)
        ORDER BY created_at ASC
        LIMIT 20
    ");
    
    $stuck_tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
    cronLog("Found " . count($stuck_tracks) . " stuck processing tracks");
    
    foreach ($stuck_tracks as $track) {
        $result_file = dirname(__DIR__) . "/task_results/{$track['task_id']}.json";
        
        if (file_exists($result_file)) {
            $result_data = json_decode(file_get_contents($result_file), true);
            
            if ($result_data && isset($result_data['data']['callbackType']) && $result_data['data']['callbackType'] === 'complete') {
                $audio_data = $result_data['data']['data'][0] ?? null;
                
                if ($audio_data && isset($audio_data['audio_url']) && !empty($audio_data['audio_url'])) {
                    $audio_url = $audio_data['audio_url'];
                    $duration = $audio_data['duration'] ?? null;
                    
                    // Extract title
                    $title = null;
                    foreach ($result_data['data']['data'] as $item) {
                        if (isset($item['title']) && !empty($item['title'])) {
                            $title = trim($item['title']);
                            break;
                        }
                    }
                    
                    // Extract tags
                    $tags = null;
                    if (isset($audio_data['tags']) && !empty($audio_data['tags'])) {
                        $tags = is_array($audio_data['tags']) ? implode('; ', $audio_data['tags']) : $audio_data['tags'];
                    }
                    
                    // Update using updateMusicTrack function
                    updateMusicTrack($track['task_id'], 'complete', $audio_url, null, null, json_encode($result_data), $duration, $title, $tags);
                    
                    cronLog("✅ Fixed stuck track ID {$track['id']}: set to complete" . ($title ? " with title: $title" : ""));
                    $results['stuck_tracks_fixed']++;
                }
            }
        } else {
            // No result file and stuck for too long - check age
            $age_hours = (time() - strtotime($track['created_at'])) / 3600;
            if ($age_hours > 3) {
                // Mark as failed after 3 hours with no result
                $pdo->prepare("UPDATE music_tracks SET status = 'failed', updated_at = NOW() WHERE id = ?")->execute([$track['id']]);
                cronLog("⚠️ Marked track ID {$track['id']} as failed (no result after {$age_hours}h)");
            }
        }
    }
    
    // Final stats
    $stmt = $pdo->query("
        SELECT 
            COUNT(CASE WHEN status = 'complete' AND (title IS NULL OR title = '' OR title = 'Untitled Track') THEN 1 END) as still_missing
        FROM music_tracks
    ");
    $stats = $stmt->fetch(PDO::FETCH_ASSOC);
    $results['still_missing_titles'] = (int)$stats['still_missing'];
    
    cronLog("=== Auto-Fix Cron Completed: {$results['titles_fixed']} titles fixed, {$results['stuck_tracks_fixed']} stuck tracks fixed, {$results['still_missing_titles']} still missing ===");
    
} catch (Exception $e) {
    $results['errors'][] = $e->getMessage();
    cronLog("ERROR: " . $e->getMessage());
}

$results['success'] = empty($results['errors']);

if (!$is_cli) {
    echo json_encode($results, JSON_PRETTY_PRINT);
} else {
    echo "Auto-Fix Complete:\n";
    echo "- Titles fixed: {$results['titles_fixed']}\n";
    echo "- Stuck tracks fixed: {$results['stuck_tracks_fixed']}\n";
    echo "- Still missing titles: {$results['still_missing_titles']}\n";
}
?>


CasperSecurity Mini