![]() 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 Missing Title and Variations Script
* Repairs tracks that are missing titles or variations by extracting data from callback logs and task_results
*
* Usage: Run this script via browser or command line
* Example: https://soundstudiopro.com/fix_missing_title_and_variations.php?artist_id=22&confirm=yes
*/
session_start();
require_once 'config/database.php';
// Security: Only allow admins or run with confirmation
$is_admin = isset($_SESSION['is_admin']) && $_SESSION['is_admin'];
$confirm = $_GET['confirm'] ?? 'false';
// If not admin, require explicit confirmation
if (!$is_admin && $confirm !== 'yes') {
die("
<h2>Fix Missing Title and Variations</h2>
<p>This script will repair tracks missing titles or variations.</p>
<p><strong>WARNING:</strong> Only run this if you're certain a track needs repair.</p>
<p>To proceed, add <code>&confirm=yes</code> to the URL.</p>
<p>Example: <code>fix_missing_title_and_variations.php?artist_id=22&confirm=yes</code></p>
");
}
// Helper function to extract title from callback data (same logic as callback.php)
function extractTitleFromCallbackData($data) {
// Check multiple possible locations in the API response
if (isset($data['title']) && !empty($data['title']) && trim($data['title']) !== '') {
return trim($data['title']);
}
if (isset($data['data']['title']) && !empty($data['data']['title']) && trim($data['data']['title']) !== '') {
return trim($data['data']['title']);
}
// Check in data.data array (common API.Box format)
if (isset($data['data']['data']) && is_array($data['data']['data'])) {
foreach ($data['data']['data'] as $item) {
if (isset($item['title']) && !empty($item['title']) && trim($item['title']) !== '') {
return trim($item['title']);
}
}
}
// Check in direct data array
if (isset($data['data']) && is_array($data['data']) && !isset($data['data']['data'])) {
foreach ($data['data'] as $item) {
if (is_array($item) && isset($item['title']) && !empty($item['title']) && trim($item['title']) !== '') {
return trim($item['title']);
}
}
}
return null;
}
// Helper function to sanitize text (basic version)
function sanitizeText($text) {
return htmlspecialchars(strip_tags(trim($text)), ENT_QUOTES, 'UTF-8');
}
try {
$pdo = getDBConnection();
// Get parameters
$artist_id = intval($_GET['artist_id'] ?? 22);
$track_id = intval($_GET['track_id'] ?? 0); // Optional: specific track ID
echo "<h2>Fixing Missing Title and Variations</h2>";
echo "<p><strong>Artist ID:</strong> {$artist_id}</p>";
if ($track_id > 0) {
echo "<p><strong>Track ID:</strong> {$track_id} (specific track)</p>";
} else {
echo "<p><strong>Mode:</strong> All tracks for this artist</p>";
}
echo "<hr>";
// Find artist
$stmt = $pdo->prepare("SELECT id, name FROM users WHERE id = ? LIMIT 1");
$stmt->execute([$artist_id]);
$artist = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$artist) {
die("<p style='color: red;'><strong>ERROR:</strong> Artist ID {$artist_id} not found in database.</p>");
}
echo "<p>✅ Found artist: {$artist['name']} (ID: {$artist_id})</p>";
// Find tracks that need repair
if ($track_id > 0) {
$stmt = $pdo->prepare("
SELECT
mt.id,
mt.task_id,
mt.title,
mt.status,
mt.created_at,
(SELECT COUNT(*) FROM audio_variations WHERE track_id = mt.id) as actual_variations_count,
mt.variations_count as stored_variations_count
FROM music_tracks mt
WHERE mt.id = ? AND mt.user_id = ?
");
$stmt->execute([$track_id, $artist_id]);
} else {
// Find all tracks for this artist that might need repair
// Tracks with missing titles or mismatched variation counts
$stmt = $pdo->prepare("
SELECT
mt.id,
mt.task_id,
mt.title,
mt.status,
mt.created_at,
(SELECT COUNT(*) FROM audio_variations WHERE track_id = mt.id) as actual_variations_count,
mt.variations_count as stored_variations_count
FROM music_tracks mt
WHERE mt.user_id = ?
AND mt.status = 'complete'
AND (
mt.title IS NULL
OR mt.title = ''
OR mt.title = 'Untitled Track'
OR mt.title = 'Generated Track'
OR (SELECT COUNT(*) FROM audio_variations WHERE track_id = mt.id) != mt.variations_count
)
ORDER BY mt.created_at DESC
LIMIT 50
");
$stmt->execute([$artist_id]);
}
$tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($tracks)) {
die("<p style='color: green;'>✅ No tracks found that need repair.</p>");
}
echo "<p>Found " . count($tracks) . " track(s) that may need repair:</p>";
echo "<ul>";
foreach ($tracks as $track) {
$issues = [];
if (!$track['title'] || $track['title'] === '' || $track['title'] === 'Untitled Track' || $track['title'] === 'Generated Track') {
$issues[] = "Missing title";
}
if ($track['actual_variations_count'] != $track['stored_variations_count']) {
$issues[] = "Variation count mismatch (stored: {$track['stored_variations_count']}, actual: {$track['actual_variations_count']})";
}
echo "<li>Track ID {$track['id']} (Task: {$track['task_id']}) - " . implode(', ', $issues) . "</li>";
}
echo "</ul>";
echo "<hr>";
$fixed_count = 0;
$error_count = 0;
foreach ($tracks as $track) {
echo "<h3>Processing Track ID: {$track['id']}</h3>";
echo "<p><strong>Task ID:</strong> {$track['task_id']}</p>";
echo "<p><strong>Current Title:</strong> " . ($track['title'] ?: 'NULL/EMPTY') . "</p>";
echo "<p><strong>Variations:</strong> Stored={$track['stored_variations_count']}, Actual={$track['actual_variations_count']}</p>";
$needs_title_fix = (!$track['title'] || $track['title'] === '' || $track['title'] === 'Untitled Track' || $track['title'] === 'Generated Track');
$needs_variation_fix = ($track['actual_variations_count'] != $track['stored_variations_count']);
if (!$needs_title_fix && !$needs_variation_fix) {
echo "<p style='color: orange;'>⚠️ No issues detected for this track, skipping...</p><hr>";
continue;
}
// Try to load task_results JSON file
$taskResultsFile = __DIR__ . "/task_results/{$track['task_id']}.json";
$callbackData = null;
if (file_exists($taskResultsFile)) {
$jsonContent = file_get_contents($taskResultsFile);
$callbackData = json_decode($jsonContent, true);
echo "<p>✅ Found task_results JSON file</p>";
} else {
echo "<p style='color: orange;'>⚠️ task_results JSON file not found: {$taskResultsFile}</p>";
echo "<p>Trying to extract from callback log...</p>";
// Try to find in callback log (last resort)
$logFile = __DIR__ . "/callback_log.txt";
if (file_exists($logFile)) {
$logContent = file_get_contents($logFile);
// Look for the task_id in the log
$pattern = '/"task_id"\s*:\s*"' . preg_quote($track['task_id'], '/') . '"/';
if (preg_match($pattern, $logContent)) {
echo "<p>✅ Found task_id in callback log (manual extraction would be needed)</p>";
// For now, we'll skip if no JSON file
}
}
}
$pdo->beginTransaction();
try {
$updates = [];
$params = [];
// Fix title if needed
if ($needs_title_fix && $callbackData) {
$extractedTitle = extractTitleFromCallbackData($callbackData);
if ($extractedTitle) {
$extractedTitle = sanitizeText($extractedTitle);
$updates[] = "title = ?";
$params[] = $extractedTitle;
echo "<p style='color: green;'>✅ Extracted title: '{$extractedTitle}'</p>";
} else {
echo "<p style='color: orange;'>⚠️ Could not extract title from callback data</p>";
}
}
// Fix variation count if needed
if ($needs_variation_fix) {
// Update to match actual count in audio_variations table
$updates[] = "variations_count = ?";
$params[] = $track['actual_variations_count'];
echo "<p style='color: green;'>✅ Updating variations_count to {$track['actual_variations_count']}</p>";
}
if (!empty($updates)) {
$params[] = $track['id']; // Add track ID for WHERE clause
$sql = "UPDATE music_tracks SET " . implode(', ', $updates) . " WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
echo "<p style='color: green;'>✅ Successfully updated track {$track['id']}</p>";
$fixed_count++;
} else {
echo "<p style='color: orange;'>⚠️ No updates needed (could not extract data)</p>";
}
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
echo "<p style='color: red;'>❌ ERROR updating track {$track['id']}: " . htmlspecialchars($e->getMessage()) . "</p>";
$error_count++;
}
echo "<hr>";
}
echo "<h2>Summary</h2>";
echo "<p style='color: green;'>✅ Fixed: {$fixed_count} track(s)</p>";
if ($error_count > 0) {
echo "<p style='color: red;'>❌ Errors: {$error_count} track(s)</p>";
}
echo "<p><a href='/artist_profile.php?id={$artist_id}'>View Artist Profile</a></p>";
} catch (Exception $e) {
echo "<p style='color: red;'><strong>ERROR:</strong> " . htmlspecialchars($e->getMessage()) . "</p>";
echo "<p>Stack trace:</p><pre>" . htmlspecialchars($e->getTraceAsString()) . "</pre>";
}