![]() 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/api/ |
<?php
session_start();
header('Content-Type: application/json');
// Include translation system
require_once __DIR__ . '/../includes/translations.php';
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
echo json_encode([
'success' => false,
'message' => 'User not logged in'
]);
exit;
}
$track_id = $_GET['track_id'] ?? null;
if (!$track_id) {
echo json_encode([
'success' => false,
'message' => 'Track ID required'
]);
exit;
}
try {
require_once '../config/database.php';
$pdo = getDBConnection();
// Get track details and verify ownership
$stmt = $pdo->prepare("
SELECT id, title, prompt, status, user_id
FROM music_tracks
WHERE id = ? AND user_id = ? AND status = 'failed'
");
$stmt->execute([$track_id, $_SESSION['user_id']]);
$track = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$track) {
echo json_encode([
'success' => false,
'message' => 'Track not found or not eligible for retry'
]);
exit;
}
// Check if user has enough credits
$stmt = $pdo->prepare("SELECT credits FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user['credits'] < 1) {
echo json_encode([
'success' => false,
'message' => 'Insufficient credits to retry track'
]);
exit;
}
// Get full track data including metadata
$stmt = $pdo->prepare("
SELECT id, title, prompt, status, user_id, metadata, music_type
FROM music_tracks
WHERE id = ? AND user_id = ?
");
$stmt->execute([$track_id, $_SESSION['user_id']]);
$fullTrack = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$fullTrack) {
echo json_encode([
'success' => false,
'message' => 'Track not found'
]);
exit;
}
// Parse metadata to get original parameters
$metadata = json_decode($fullTrack['metadata'], true) ?: [];
// Generate new task ID
$temp_task_id = 'retry_' . time() . '_' . rand(1000, 9999);
// Update track status to processing with new task_id
$stmt = $pdo->prepare("
UPDATE music_tracks
SET status = 'processing', task_id = ?, updated_at = NOW()
WHERE id = ?
");
$stmt->execute([$temp_task_id, $track_id]);
// Deduct credits
$stmt = $pdo->prepare("UPDATE users SET credits = credits - 1 WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
// Record credit transaction
$stmt = $pdo->prepare("
INSERT INTO credit_transactions (user_id, amount, type, description, created_at)
VALUES (?, -1, 'usage', 'Music track retry: {$fullTrack['title']}', NOW())
");
$stmt->execute([$_SESSION['user_id']]);
// Call the music generation API with original parameters
$api_url = 'https://api.api.box/api/v1/generate';
$api_key = '63edba40620216c5aa2c04240ac41dbd';
$api_data = [
'prompt' => $fullTrack['prompt'],
'model' => $metadata['model_name'] ?? 'melody',
'style' => $metadata['genre'] ?? 'Pop',
'title' => $fullTrack['title'],
'customMode' => $metadata['customMode'] ?? 'false',
'instrumental' => $metadata['instrumental'] ?? 'false',
'duration' => $metadata['duration'] ?? 180,
'callBackUrl' => 'https://soundstudiopro.com/callback.php'
];
// Add advanced parameters if they exist
if (!empty($metadata['tempo'])) $api_data['tempo'] = $metadata['tempo'];
if (!empty($metadata['key'])) $api_data['key'] = $metadata['key'];
if (!empty($metadata['scale'])) $api_data['scale'] = $metadata['scale'];
if (!empty($metadata['energy'])) $api_data['energy'] = $metadata['energy'];
if (!empty($metadata['excitement'])) $api_data['excitement'] = $metadata['excitement'];
if (!empty($metadata['mood'])) $api_data['mood'] = $metadata['mood'];
if (!empty($metadata['tags'])) $api_data['tags'] = $metadata['tags'];
if (!empty($metadata['variations']) && $metadata['variations'] > 1) $api_data['variations'] = $metadata['variations'];
// Make API call
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($api_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $api_key,
'Content-Type: application/json',
'User-Agent: SoundStudioPro-Retry/1.0'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curl_error = curl_error($ch);
curl_close($ch);
// Log the retry attempt
error_log("Retry track API Request for track $track_id: " . json_encode($api_data));
error_log("Retry track API Response: HTTP $http_code, Response: " . $response);
// Handle response
if ($curl_error || $http_code !== 200 || !$response) {
// API call failed - mark as failed
$stmt = $pdo->prepare("UPDATE music_tracks SET status = 'failed', updated_at = NOW() WHERE id = ?");
$stmt->execute([$track_id]);
// Refund the credit
$stmt = $pdo->prepare("UPDATE users SET credits = credits + 1 WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
echo json_encode([
'success' => false,
'message' => 'Failed to start track generation. Credit refunded.'
]);
exit;
}
$api_result = json_decode($response, true);
// Check if API returned an error
if (isset($api_result['code']) && $api_result['code'] != 200) {
// API returned an error (400, 429, 531, etc.) - mark as failed immediately
$error_msg = $api_result['msg'] ?? 'Generation failed';
// Sanitize error message - remove any references to API.Box or supplier names
$error_msg = 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);
$error_msg = trim($error_msg);
if (empty($error_msg)) {
$error_msg = 'Generation failed';
}
$api_error_code = $api_result['code'];
// Special handling for 429 (insufficient credits on API side)
$user_friendly_message = '';
if ($api_error_code == 429) {
// This is an API-side credit issue, not a user account issue
$user_friendly_message = t('error.api.service_unavailable.retry');
} else {
// For other errors, use the API's message but make it clear credit was refunded
$user_friendly_message = 'Track generation failed: ' . htmlspecialchars($error_msg) . ' Your credit has been refunded.';
}
$error_metadata = json_encode([
'code' => $api_error_code,
'msg' => $error_msg,
'error_type' => $api_error_code == 400 ? 'content_violation' : ($api_error_code == 429 ? 'service_unavailable' : 'generation_failed'),
'data' => $api_result,
'timestamp' => date('Y-m-d H:i:s'),
'retry_failed' => true
]);
$stmt = $pdo->prepare("UPDATE music_tracks SET status = 'failed', metadata = ?, updated_at = NOW() WHERE id = ?");
$stmt->execute([$error_metadata, $track_id]);
// Refund the credit
$stmt = $pdo->prepare("UPDATE users SET credits = credits + 1 WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
// Record refund transaction
$stmt = $pdo->prepare("
INSERT INTO credit_transactions (user_id, amount, type, description, created_at)
VALUES (?, 1, 'refund', 'Credit refund for failed retry: {$fullTrack['title']}', NOW())
");
$stmt->execute([$_SESSION['user_id']]);
echo json_encode([
'success' => false,
'message' => $user_friendly_message,
'error_code' => $api_error_code
]);
exit;
}
// Update with real task ID if provided
if (isset($api_result['taskId']) || isset($api_result['id']) || (isset($api_result['data']['taskId']))) {
$real_task_id = $api_result['taskId'] ?? $api_result['id'] ?? $api_result['data']['taskId'] ?? null;
if ($real_task_id) {
$stmt = $pdo->prepare("UPDATE music_tracks SET task_id = ? WHERE id = ?");
$stmt->execute([$real_task_id, $track_id]);
error_log("Retry track $track_id: Updated with real task_id $real_task_id");
}
} else {
// No task ID in response - might be an error or different format
error_log("Retry track $track_id: Warning - No task_id in API response. Response: " . $response);
}
echo json_encode([
'success' => true,
'message' => t('success.track_retry.started')
]);
} catch (Exception $e) {
error_log("Error retrying track: " . $e->getMessage());
echo json_encode([
'success' => false,
'message' => 'Internal server error'
]);
}
?>