![]() 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/ |
<?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";
}
?>