![]() 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
// Automated Track Status Monitor API
// This endpoint checks and updates processing tracks automatically
// Can be called via cron job, web request, or JavaScript polling
header('Content-Type: application/json');
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '../config/database.php';
// Security key to prevent unauthorized access
$monitor_key = 'soundstudiopro_monitor_2025';
$provided_key = $_GET['key'] ?? $_POST['key'] ?? '';
if ($provided_key !== $monitor_key) {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized access']);
exit;
}
$pdo = getDBConnection();
if (!$pdo) {
http_response_code(500);
echo json_encode(['error' => 'Database connection failed']);
exit;
}
// Check if called from a logged-in user session (for user-specific filtering)
// Start session if not already started
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$user_id = $_SESSION['user_id'] ?? null;
$is_user_request = $user_id !== null && is_numeric($user_id);
$user_id = $is_user_request ? intval($user_id) : null;
// Debug logging (can be removed later)
if ($is_user_request) {
error_log("Monitor API: Filtering for user_id: $user_id");
} else {
error_log("Monitor API: No user session, checking all tracks");
}
// Get processing tracks (filtered by user if logged in)
if ($is_user_request) {
$stmt = $pdo->prepare("
SELECT * FROM music_tracks
WHERE status = 'processing'
AND user_id = ?
ORDER BY created_at DESC
");
$stmt->execute([$user_id]);
} else {
$stmt = $pdo->query("
SELECT * FROM music_tracks
WHERE status = 'processing'
ORDER BY created_at DESC
");
}
$processing_tracks = $stmt->fetchAll();
// Also get tracks that might have temporary task IDs but are actually complete
if ($is_user_request) {
$stmt = $pdo->prepare("
SELECT * FROM music_tracks
WHERE status = 'processing'
AND task_id LIKE 'temp_%'
AND user_id = ?
ORDER BY created_at DESC
");
$stmt->execute([$user_id]);
} else {
$stmt = $pdo->query("
SELECT * FROM music_tracks
WHERE status = 'processing'
AND task_id LIKE 'temp_%'
ORDER BY created_at DESC
");
}
$temp_task_tracks = $stmt->fetchAll();
$results = [
'timestamp' => date('Y-m-d H:i:s'),
'total_processing' => count($processing_tracks),
'temp_task_tracks' => count($temp_task_tracks),
'fixed_tracks' => [],
'failed_tracks' => [],
'still_processing' => [],
'matched_temp_tracks' => []
];
foreach ($processing_tracks as $track) {
$task_id = $track['task_id'];
$result_file = "../task_results/{$task_id}.json";
// Check if result file exists
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'])) {
$audio_url = $audio_data['audio_url'];
$duration = $audio_data['duration'] ?? 30;
// Update the track to complete
$update_success = updateMusicTrack($task_id, 'complete', $audio_url, null, null, json_encode($result_data), $duration);
if ($update_success) {
// Only include track if it still exists (not deleted) AND belongs to current user (if user is logged in)
$check_stmt = $pdo->prepare("SELECT id, user_id FROM music_tracks WHERE id = ?");
$check_stmt->execute([$track['id']]);
$existing_track = $check_stmt->fetch(PDO::FETCH_ASSOC);
if ($existing_track && (!$is_user_request || $existing_track['user_id'] == $user_id)) {
$results['fixed_tracks'][] = [
'track_id' => $track['id'],
'task_id' => $task_id,
'title' => $track['title'],
'audio_url' => $audio_url,
'duration' => $duration,
'user_id' => $track['user_id']
];
}
}
}
} else {
// Check if it's been too long (more than 10 minutes)
$created_time = strtotime($track['created_at']);
$time_diff = time() - $created_time;
if ($time_diff > 600) { // 10 minutes
// Mark as failed if it's been too long
updateMusicTrack($task_id, 'failed', null, null, null, json_encode($result_data));
// Only include track if it still exists (not deleted) AND belongs to current user (if user is logged in)
$check_stmt = $pdo->prepare("SELECT id, user_id FROM music_tracks WHERE id = ?");
$check_stmt->execute([$track['id']]);
$existing_track = $check_stmt->fetch(PDO::FETCH_ASSOC);
if ($existing_track && (!$is_user_request || $existing_track['user_id'] == $user_id)) {
$results['failed_tracks'][] = [
'track_id' => $track['id'],
'task_id' => $task_id,
'title' => $track['title'],
'reason' => 'Timeout - no completion after 10 minutes',
'user_id' => $track['user_id']
];
}
} else {
$results['still_processing'][] = [
'track_id' => $track['id'],
'task_id' => $task_id,
'title' => $track['title'],
'created_at' => $track['created_at'],
'time_elapsed' => $time_diff . ' seconds'
];
}
}
} else {
// No result file - check if it's been too long
$created_time = strtotime($track['created_at']);
$time_diff = time() - $created_time;
if ($time_diff > 600) { // 10 minutes
// Mark as failed if it's been too long
updateMusicTrack($task_id, 'failed', null, null, null, null);
// Only include track if it still exists (not deleted) AND belongs to current user (if user is logged in)
$check_stmt = $pdo->prepare("SELECT id, user_id FROM music_tracks WHERE id = ?");
$check_stmt->execute([$track['id']]);
$existing_track = $check_stmt->fetch(PDO::FETCH_ASSOC);
if ($existing_track && (!$is_user_request || $existing_track['user_id'] == $user_id)) {
$results['failed_tracks'][] = [
'track_id' => $track['id'],
'task_id' => $task_id,
'title' => $track['title'],
'reason' => 'Timeout - no result file after 10 minutes',
'user_id' => $track['user_id']
];
}
} else {
$results['still_processing'][] = [
'track_id' => $track['id'],
'task_id' => $task_id,
'title' => $track['title'],
'created_at' => $track['created_at'],
'time_elapsed' => $time_diff . ' seconds'
];
}
}
}
// Process tracks with temporary task IDs - match them with completed results
foreach ($temp_task_tracks as $track) {
$temp_task_id = $track['task_id'];
$track_created_at = $track['created_at'];
// Look for completed result files that might match this track
$result_files = glob("../task_results/*.json");
$matched = false;
foreach ($result_files as $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') {
// Check if this result matches the track based on creation time and metadata
$result_created_at = $result_data['data']['created_at'] ?? null;
$result_user_id = $result_data['data']['user_id'] ?? null;
$result_title = $result_data['data']['title'] ?? null;
// Match based on user_id and creation time (within 5 minutes)
if ($result_user_id == $track['user_id']) {
$track_time = strtotime($track_created_at);
$result_time = $result_created_at ? strtotime($result_created_at) : null;
if ($result_time && abs($track_time - $result_time) <= 300) { // 5 minutes tolerance
$audio_data = $result_data['data']['data'][0] ?? null;
if ($audio_data && isset($audio_data['audio_url'])) {
$audio_url = $audio_data['audio_url'];
$duration = $audio_data['duration'] ?? 30;
$real_task_id = basename($result_file, '.json');
// Update the track with the real task ID and mark as complete
$update_success = updateMusicTrack($real_task_id, 'complete', $audio_url, null, null, json_encode($result_data), $duration);
if ($update_success) {
// Only include track if it still exists (not deleted) AND belongs to current user (if user is logged in)
$check_stmt = $pdo->prepare("SELECT id, user_id FROM music_tracks WHERE id = ?");
$check_stmt->execute([$track['id']]);
$existing_track = $check_stmt->fetch(PDO::FETCH_ASSOC);
if ($existing_track && (!$is_user_request || $existing_track['user_id'] == $user_id)) {
$results['matched_temp_tracks'][] = [
'track_id' => $track['id'],
'temp_task_id' => $temp_task_id,
'real_task_id' => $real_task_id,
'title' => $track['title'],
'audio_url' => $audio_url,
'duration' => $duration,
'matched_by' => 'user_id_and_time',
'user_id' => $track['user_id']
];
}
$matched = true;
break;
}
}
}
}
}
}
// If no match found and it's been more than 10 minutes, mark as failed
if (!$matched) {
$created_time = strtotime($track_created_at);
$time_diff = time() - $created_time;
if ($time_diff > 600) { // 10 minutes
updateMusicTrack($temp_task_id, 'failed', null, null, null, null);
// Only include track if it still exists (not deleted) AND belongs to current user (if user is logged in)
$check_stmt = $pdo->prepare("SELECT id, user_id FROM music_tracks WHERE id = ?");
$check_stmt->execute([$track['id']]);
$existing_track = $check_stmt->fetch(PDO::FETCH_ASSOC);
if ($existing_track && (!$is_user_request || $existing_track['user_id'] == $user_id)) {
$results['failed_tracks'][] = [
'track_id' => $track['id'],
'task_id' => $temp_task_id,
'title' => $track['title'],
'reason' => 'Timeout - no matching result found for temp task ID',
'user_id' => $track['user_id']
];
}
} else {
$results['still_processing'][] = [
'track_id' => $track['id'],
'task_id' => $temp_task_id,
'title' => $track['title'],
'created_at' => $track_created_at,
'time_elapsed' => $time_diff . ' seconds',
'note' => 'Temporary task ID - waiting for completion'
];
}
}
}
// Log the results
$log_entry = "[" . date('Y-m-d H:i:s') . "] Monitor run: " .
count($results['fixed_tracks']) . " fixed, " .
count($results['failed_tracks']) . " failed, " .
count($results['still_processing']) . " still processing, " .
count($results['matched_temp_tracks']) . " temp tracks matched\n";
file_put_contents('../monitor_log.txt', $log_entry, FILE_APPEND | LOCK_EX);
echo json_encode($results, JSON_PRETTY_PRINT);
?>