![]() 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/ |
<?php
/**
* Fix All Failed Tracks
*
* This script:
* 1. Finds all failed tracks and processing tracks that should be failed
* 2. Checks API status to get actual error messages
* 3. Updates metadata with exact error messages (sanitized of API.Box references)
* 4. Refunds credits if not already refunded
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once 'config/database.php';
$api_key = '63edba40620216c5aa2c04240ac41dbd';
$api_base_url = 'https://api.api.box/api/v1/status/';
echo "<!DOCTYPE html>
<html>
<head>
<title>Fix All Failed Tracks</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; }
.track { background: white; padding: 15px; margin: 10px 0; border-radius: 8px; border-left: 4px solid #667eea; }
.success { color: #10b981; }
.error { color: #ef4444; }
.warning { color: #f59e0b; }
.info { color: #3b82f6; }
h1 { color: #1a1a2e; }
h2 { color: #667eea; margin-top: 30px; }
.summary { background: white; padding: 20px; border-radius: 8px; margin-top: 20px; }
.summary-item { padding: 10px; margin: 5px 0; }
pre { background: #f8f9fa; padding: 10px; border-radius: 4px; overflow-x: auto; }
</style>
</head>
<body>";
echo "<h1>đ§ Fix All Failed Tracks</h1>";
echo "<p>This script will:</p>";
echo "<ul>";
echo "<li>Check all failed tracks and update their error messages</li>";
echo "<li>Check processing tracks that should be marked as failed</li>";
echo "<li>Refund credits for failed tracks that haven't been refunded</li>";
echo "<li>Update metadata with exact error messages from API</li>";
echo "</ul>";
echo "<hr>";
$pdo = getDBConnection();
if (!$pdo) {
die("<p class='error'>â Database connection failed</p>");
}
// Get all failed tracks
$stmt = $pdo->prepare("
SELECT id, task_id, title, user_id, status, metadata, created_at
FROM music_tracks
WHERE status = 'failed'
ORDER BY created_at DESC
LIMIT 500
");
$stmt->execute();
$failedTracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Get processing tracks that might be failed (older than 5 minutes)
$stmt = $pdo->prepare("
SELECT id, task_id, title, user_id, status, metadata, created_at
FROM music_tracks
WHERE status = 'processing'
AND task_id IS NOT NULL
AND task_id != ''
AND task_id != 'unknown'
AND task_id NOT LIKE 'temp_%'
AND task_id NOT LIKE 'retry_%'
AND created_at < DATE_SUB(NOW(), INTERVAL 5 MINUTE)
ORDER BY created_at DESC
LIMIT 200
");
$stmt->execute();
$processingTracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
$allTracks = array_merge($failedTracks, $processingTracks);
echo "<p><strong>Found " . count($failedTracks) . " failed tracks and " . count($processingTracks) . " potentially stuck processing tracks</strong></p>";
echo "<hr>";
$stats = [
'updated' => 0,
'refunded' => 0,
'already_refunded' => 0,
'no_task_id' => 0,
'api_error' => 0,
'still_processing' => 0,
'marked_failed' => 0,
'errors' => 0
];
foreach ($allTracks as $track) {
$trackId = $track['id'];
$taskId = $track['task_id'];
$userId = $track['user_id'];
$currentStatus = $track['status'];
$title = htmlspecialchars($track['title'] ?? 'Untitled');
echo "<div class='track'>";
echo "<h3>Track #{$trackId}: {$title}</h3>";
echo "<p><strong>Status:</strong> {$currentStatus} | <strong>Task ID:</strong> " . ($taskId ? substr($taskId, 0, 20) . '...' : 'N/A') . "</p>";
// First, check existing metadata for error message
$existing_metadata = json_decode($track['metadata'] ?? '{}', true);
$existing_error_msg = null;
$existing_error_code = null;
if ($existing_metadata) {
$existing_error_msg = $existing_metadata['msg'] ??
$existing_metadata['error'] ??
$existing_metadata['error_msg'] ??
$existing_metadata['message'] ??
null;
$existing_error_code = $existing_metadata['code'] ?? null;
if ($existing_error_msg) {
// Check if it's a real error message (not generic)
$error_lower = strtolower($existing_error_msg);
if (strpos($error_lower, 'song description') !== false ||
strpos($error_lower, 'contained artist name') !== false ||
strpos($error_lower, 'content violation') !== false ||
(strlen($existing_error_msg) > 20 && $existing_error_msg !== 'Generation failed')) {
echo "<p class='info'>âšī¸ Found existing error message in metadata: <strong>" . htmlspecialchars($existing_error_msg) . "</strong></p>";
// If we have a good error message and track is already failed, just check credit refund
if ($currentStatus === 'failed' && $existing_error_code) {
// Check if credit was already refunded
$check_stmt = $pdo->prepare("
SELECT COUNT(*)
FROM credit_transactions
WHERE user_id = ?
AND type = 'refund'
AND (description LIKE ? OR description LIKE ? OR description LIKE ?)
");
$check_stmt->execute([
$userId,
"%Track failed: {$trackId}%",
"%Track #{$trackId}%",
"%track {$trackId}%"
]);
$already_refunded = $check_stmt->fetchColumn() > 0;
if (!$already_refunded) {
// Refund credit
$refund_stmt = $pdo->prepare("UPDATE users SET credits = credits + 1 WHERE id = ?");
if ($refund_stmt->execute([$userId])) {
$trans_stmt = $pdo->prepare("
INSERT INTO credit_transactions (user_id, amount, type, description, created_at)
VALUES (?, 1, 'refund', 'Track failed (existing error): {$trackId} - {$title}', NOW())
");
$trans_stmt->execute([$userId]);
echo "<p class='success'>â
Refunded 1 credit</p>";
$stats['refunded']++;
}
} else {
echo "<p class='info'>âšī¸ Credit already refunded</p>";
$stats['already_refunded']++;
}
// Ensure metadata has exact error message (sanitized of API.Box only)
$sanitized_error = preg_replace('/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/i', '', $existing_error_msg);
$sanitized_error = trim($sanitized_error);
$sanitized_error = preg_replace('/\s+/', ' ', $sanitized_error);
if ($sanitized_error !== $existing_error_msg) {
// Update metadata with sanitized version
$existing_metadata['msg'] = $sanitized_error;
$updated_metadata = json_encode($existing_metadata, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$update_stmt = $pdo->prepare("UPDATE music_tracks SET metadata = ?, updated_at = NOW() WHERE id = ?");
if ($update_stmt->execute([$updated_metadata, $trackId])) {
echo "<p class='success'>â
Updated metadata with sanitized error message</p>";
$stats['updated']++;
}
}
echo "</div>";
continue;
}
}
}
}
// Check if we have a valid task_id
if (empty($taskId) || $taskId === 'unknown' || str_starts_with($taskId, 'temp_') || str_starts_with($taskId, 'retry_')) {
echo "<p class='warning'>â ī¸ No valid task ID - checking if credit needs refund</p>";
// Even without a valid task ID, if track is failed, check if credit was refunded
if ($currentStatus === 'failed') {
$check_stmt = $pdo->prepare("
SELECT COUNT(*)
FROM credit_transactions
WHERE user_id = ?
AND type = 'refund'
AND (description LIKE ? OR description LIKE ? OR description LIKE ?)
");
$check_stmt->execute([
$userId,
"%Track failed: {$trackId}%",
"%Track #{$trackId}%",
"%track {$trackId}%"
]);
$already_refunded = $check_stmt->fetchColumn() > 0;
if (!$already_refunded) {
// Check if track was created (meaning credit was deducted)
// If track exists and is failed, credit should be refunded
$refund_stmt = $pdo->prepare("UPDATE users SET credits = credits + 1 WHERE id = ?");
if ($refund_stmt->execute([$userId])) {
$trans_stmt = $pdo->prepare("
INSERT INTO credit_transactions (user_id, amount, type, description, created_at)
VALUES (?, 1, 'refund', 'Track failed (no task ID): {$trackId} - {$title}', NOW())
");
$trans_stmt->execute([$userId]);
echo "<p class='success'>â
Refunded 1 credit (no valid task ID but track is failed)</p>";
$stats['refunded']++;
}
} else {
echo "<p class='info'>âšī¸ Credit already refunded</p>";
$stats['already_refunded']++;
}
}
$stats['no_task_id']++;
echo "</div>";
continue;
}
// Check API status
$api_url = $api_base_url . $taskId;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $api_key,
'Content-Type: application/json',
'User-Agent: SoundStudioPro-FixTracks/1.0'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Handle 404 - task doesn't exist on API (likely rejected/deleted)
if ($http_code === 404) {
echo "<p class='warning'>â ī¸ Task not found on API (HTTP 404)</p>";
// Check existing metadata for error message first
$existing_metadata = json_decode($track['metadata'] ?? '{}', true);
$existing_error = $existing_metadata['msg'] ??
$existing_metadata['error'] ??
$existing_metadata['error_msg'] ??
$existing_metadata['message'] ??
null;
$existing_code = $existing_metadata['code'] ?? null;
// If we have a good error message in metadata, preserve it
if (!empty($existing_error) &&
($existing_error !== 'Generation failed') &&
($existing_error !== 'Track generation was rejected or cancelled by the service')) {
echo "<p class='info'>âšī¸ Found existing error message in metadata: <strong>" . htmlspecialchars($existing_error) . "</strong></p>";
// Sanitize error message - only remove API.Box references
$sanitized_error = preg_replace('/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/i', '', $existing_error);
$sanitized_error = trim($sanitized_error);
$sanitized_error = preg_replace('/\s+/', ' ', $sanitized_error);
// Update metadata preserving the exact error message
$error_metadata = json_encode([
'code' => $existing_code ?? 404,
'msg' => $sanitized_error,
'error_type' => ($existing_code == 400) ? 'content_violation' : 'not_found',
'data' => $existing_metadata['data'] ?? null,
'timestamp' => date('Y-m-d H:i:s'),
'fixed_by' => 'fix_all_failed_tracks.php',
'api_response' => 'HTTP 404 - Task not found (error from existing metadata)'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} else {
// No good error message, use generic one
if ($currentStatus === 'processing') {
$error_msg = 'Track generation was rejected or cancelled by the service';
} else {
$error_msg = 'Track generation was rejected or cancelled by the service';
}
// Sanitize error message
$sanitized_error = preg_replace('/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/i', '', $error_msg);
$sanitized_error = trim($sanitized_error);
// Update metadata
$error_metadata = json_encode([
'code' => 404,
'msg' => $sanitized_error,
'error_type' => 'not_found',
'timestamp' => date('Y-m-d H:i:s'),
'fixed_by' => 'fix_all_failed_tracks.php',
'api_response' => 'HTTP 404 - Task not found'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
// Update track
$update_stmt = $pdo->prepare("
UPDATE music_tracks
SET status = 'failed',
metadata = ?,
updated_at = NOW()
WHERE id = ?
");
if ($update_stmt->execute([$error_metadata, $trackId])) {
echo "<p class='success'>â
Updated track status and error message</p>";
$stats['updated']++;
if ($currentStatus === 'processing') {
$stats['marked_failed']++;
}
// Check if credit was already refunded
$check_stmt = $pdo->prepare("
SELECT COUNT(*)
FROM credit_transactions
WHERE user_id = ?
AND type = 'refund'
AND (description LIKE ? OR description LIKE ? OR description LIKE ?)
");
$check_stmt->execute([
$userId,
"%Track failed: {$trackId}%",
"%Track #{$trackId}%",
"%track {$trackId}%"
]);
$already_refunded = $check_stmt->fetchColumn() > 0;
if ($already_refunded) {
echo "<p class='info'>âšī¸ Credit already refunded</p>";
$stats['already_refunded']++;
} else {
// Refund credit
$refund_stmt = $pdo->prepare("UPDATE users SET credits = credits + 1 WHERE id = ?");
if ($refund_stmt->execute([$userId])) {
// Record refund transaction
$trans_stmt = $pdo->prepare("
INSERT INTO credit_transactions (user_id, amount, type, description, created_at)
VALUES (?, 1, 'refund', 'Track failed (404 not found): {$trackId} - {$title}', NOW())
");
$trans_stmt->execute([$userId]);
echo "<p class='success'>â
Refunded 1 credit to user</p>";
$stats['refunded']++;
} else {
echo "<p class='error'>â Failed to refund credit</p>";
$stats['errors']++;
}
}
} else {
echo "<p class='error'>â Failed to update track</p>";
$stats['errors']++;
}
echo "</div>";
continue;
}
if ($http_code !== 200 || !$response) {
echo "<p class='error'>â API check failed: HTTP {$http_code}</p>";
$stats['api_error']++;
echo "</div>";
continue;
}
$api_data = json_decode($response, true);
if (!$api_data) {
echo "<p class='error'>â Invalid JSON response from API</p>";
$stats['api_error']++;
echo "</div>";
continue;
}
// Check for error codes or failed status
$has_error_code = isset($api_data['code']) && ($api_data['code'] == 400 || $api_data['code'] == 531 || $api_data['code'] >= 400);
$api_status = $api_data['status'] ?? null;
$is_failed = false;
$api_error_msg = null;
$error_code = null;
if ($has_error_code) {
$is_failed = true;
$error_code = $api_data['code'];
$api_error_msg = $api_data['msg'] ?? $api_data['error'] ?? $api_data['error_msg'] ?? 'Generation failed';
} elseif ($api_status === 'failed' || $api_status === 'error' || $api_status === 'rejected') {
$is_failed = true;
$api_error_msg = $api_data['error'] ?? $api_data['msg'] ?? $api_data['error_msg'] ?? 'Generation failed';
$error_code = $api_data['code'] ?? 531;
} elseif ($api_status === 'processing') {
echo "<p class='info'>âšī¸ Track is still processing on API</p>";
$stats['still_processing']++;
echo "</div>";
continue;
} elseif ($api_status === 'completed' || $api_status === 'complete') {
echo "<p class='info'>âšī¸ Track is complete on API - this should be handled by callback system</p>";
echo "</div>";
continue;
}
// Check for content violation patterns in message
if (!$is_failed && !empty($api_data['msg'])) {
$msg_lower = strtolower($api_data['msg']);
if (strpos($msg_lower, 'contained artist name') !== false ||
strpos($msg_lower, 'song description') !== false ||
strpos($msg_lower, 'content violation') !== false ||
strpos($msg_lower, 'rejected') !== false) {
$is_failed = true;
$api_error_msg = $api_data['msg'];
$error_code = 400; // Content violation
}
}
if ($is_failed) {
// Sanitize error message - remove API.Box references only
$sanitized_error = preg_replace('/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/i', '', $api_error_msg);
$sanitized_error = trim($sanitized_error);
$sanitized_error = preg_replace('/\s+/', ' ', $sanitized_error);
if (empty($sanitized_error)) {
$sanitized_error = 'Generation failed';
}
echo "<p class='error'>â Track failed: <strong>" . htmlspecialchars($sanitized_error) . "</strong></p>";
echo "<p class='info'>đ Error code: " . ($error_code ?? 'N/A') . " | Original API message preserved</p>";
// Update metadata with exact error message
$error_metadata = json_encode([
'code' => $error_code ?? 531,
'msg' => $sanitized_error,
'error_type' => ($error_code == 400) ? 'content_violation' : 'generation_failed',
'data' => $api_data,
'timestamp' => date('Y-m-d H:i:s'),
'fixed_by' => 'fix_all_failed_tracks.php'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// Update track status and metadata
$update_stmt = $pdo->prepare("
UPDATE music_tracks
SET status = 'failed',
metadata = ?,
updated_at = NOW()
WHERE id = ?
");
if ($update_stmt->execute([$error_metadata, $trackId])) {
echo "<p class='success'>â
Updated track status and error message</p>";
$stats['updated']++;
if ($currentStatus === 'processing') {
$stats['marked_failed']++;
}
} else {
echo "<p class='error'>â Failed to update track</p>";
$stats['errors']++;
echo "</div>";
continue;
}
// Check if credit was already refunded
$check_stmt = $pdo->prepare("
SELECT COUNT(*)
FROM credit_transactions
WHERE user_id = ?
AND type = 'refund'
AND (description LIKE ? OR description LIKE ? OR description LIKE ?)
");
$check_stmt->execute([
$userId,
"%Track failed: {$trackId}%",
"%Track #{$trackId}%",
"%track {$trackId}%"
]);
$already_refunded = $check_stmt->fetchColumn() > 0;
if ($already_refunded) {
echo "<p class='info'>âšī¸ Credit already refunded</p>";
$stats['already_refunded']++;
} else {
// Refund credit
$refund_stmt = $pdo->prepare("UPDATE users SET credits = credits + 1 WHERE id = ?");
if ($refund_stmt->execute([$userId])) {
// Record refund transaction
$trans_stmt = $pdo->prepare("
INSERT INTO credit_transactions (user_id, amount, type, description, created_at)
VALUES (?, 1, 'refund', 'Track failed (fixed): {$trackId} - {$title}', NOW())
");
$trans_stmt->execute([$userId]);
echo "<p class='success'>â
Refunded 1 credit to user</p>";
$stats['refunded']++;
} else {
echo "<p class='error'>â Failed to refund credit</p>";
$stats['errors']++;
}
}
} else {
echo "<p class='info'>âšī¸ Track status on API: " . htmlspecialchars($api_status ?? 'N/A') . "</p>";
}
echo "</div>";
}
echo "<hr>";
echo "<div class='summary'>";
echo "<h2>đ Summary</h2>";
echo "<div class='summary-item'><strong>Tracks Updated:</strong> <span class='success'>{$stats['updated']}</span></div>";
echo "<div class='summary-item'><strong>Credits Refunded:</strong> <span class='success'>{$stats['refunded']}</span></div>";
echo "<div class='summary-item'><strong>Already Refunded:</strong> <span class='info'>{$stats['already_refunded']}</span></div>";
echo "<div class='summary-item'><strong>Marked as Failed:</strong> <span class='warning'>{$stats['marked_failed']}</span></div>";
echo "<div class='summary-item'><strong>Still Processing:</strong> <span class='info'>{$stats['still_processing']}</span></div>";
echo "<div class='summary-item'><strong>No Task ID:</strong> <span class='warning'>{$stats['no_task_id']}</span></div>";
echo "<div class='summary-item'><strong>API Errors:</strong> <span class='error'>{$stats['api_error']}</span></div>";
echo "<div class='summary-item'><strong>Other Errors:</strong> <span class='error'>{$stats['errors']}</span></div>";
echo "</div>";
if ($stats['updated'] > 0 || $stats['refunded'] > 0) {
echo "<p style='color: green; font-size: 18px; font-weight: bold; margin-top: 20px;'>â
Successfully fixed tracks and refunded credits!</p>";
}
echo "<p style='margin-top: 30px;'><a href='admin.php?tab=track-status'>â Back to Admin</a></p>";
echo "</body></html>";
?>