T.ME/BIBIL_0DAY
CasperSecurity


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/.cursor-server/data/User/History/-60baea9/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/.cursor-server/data/User/History/-60baea9/Mv8V.php
<?php
// Database configuration for SoundStudioPro
// Store this file outside of web root in production

define('DB_HOST', 'localhost');
define('DB_NAME', 'gositeme_soundstudiopro');
define('DB_USER', 'gositeme_soundstudiopro');
define('DB_PASS', 'ttkKaHQunYYwgLCn6GxZ');

// Create database connection
function getDBConnection() {
    try {
        $pdo = new PDO(
            "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
            DB_USER,
            DB_PASS,
            [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false
            ]
        );
        return $pdo;
    } catch (PDOException $e) {
        error_log("Database connection failed: " . $e->getMessage());
        return null;
    }
}

// Initialize database tables
function initializeDatabase() {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        // Users table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS users (
                id INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(255) NOT NULL,
                email VARCHAR(255) UNIQUE NOT NULL,
                password VARCHAR(255) NOT NULL,
                credits INT DEFAULT 5,
                plan ENUM('free', 'starter', 'pro') DEFAULT 'free',
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
            )
        ");
        
        // Music tracks table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS music_tracks (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                task_id VARCHAR(255) UNIQUE NOT NULL,
                title VARCHAR(255) NOT NULL,
                prompt TEXT NOT NULL,
                music_type ENUM('music', 'lyrics', 'wav', 'vocal-removal', 'music-video', 'extend') NOT NULL,
                model_version VARCHAR(10) DEFAULT 'v3',
                duration INT DEFAULT 30,
                status ENUM('processing', 'complete', 'failed') DEFAULT 'processing',
                audio_url TEXT,
                video_url TEXT,
                lyrics TEXT,
                metadata JSON,
                price DECIMAL(10,2) DEFAULT 0.00,
                is_public BOOLEAN DEFAULT TRUE,
                is_featured BOOLEAN DEFAULT FALSE,
                is_vip_sample BOOLEAN DEFAULT FALSE,
                playlist_order INT DEFAULT 0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");
        
        // Add missing metadata columns if they don't exist
        $pdo->exec("
            ALTER TABLE music_tracks 
            ADD COLUMN IF NOT EXISTS genre VARCHAR(100),
            ADD COLUMN IF NOT EXISTS style VARCHAR(100),
            ADD COLUMN IF NOT EXISTS bpm INT,
            ADD COLUMN IF NOT EXISTS `key` VARCHAR(50),
            ADD COLUMN IF NOT EXISTS time_signature VARCHAR(20),
            ADD COLUMN IF NOT EXISTS mood VARCHAR(100),
            ADD COLUMN IF NOT EXISTS energy VARCHAR(50),
            ADD COLUMN IF NOT EXISTS instruments TEXT,
            ADD COLUMN IF NOT EXISTS tags TEXT,
            ADD COLUMN IF NOT EXISTS audio_quality JSON,
            ADD COLUMN IF NOT EXISTS generation_parameters JSON,
            ADD COLUMN IF NOT EXISTS processing_info JSON,
            ADD COLUMN IF NOT EXISTS cost_info JSON,
            ADD COLUMN IF NOT EXISTS waveform_data JSON,
            ADD COLUMN IF NOT EXISTS spectrum_analysis JSON,
            ADD COLUMN IF NOT EXISTS audio_segments JSON,
            ADD COLUMN IF NOT EXISTS error_details JSON,
            ADD COLUMN IF NOT EXISTS audio_analysis JSON,
            ADD COLUMN IF NOT EXISTS system_info JSON
        ");
        
        // User sessions table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS user_sessions (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                session_token VARCHAR(255) UNIQUE NOT NULL,
                expires_at TIMESTAMP NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");
        
        // Credits transactions table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS credit_transactions (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                amount INT NOT NULL,
                type ENUM('purchase', 'usage', 'bonus', 'refund') NOT NULL,
                description VARCHAR(255),
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");
        
        // Email logs table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS email_logs (
                id INT AUTO_INCREMENT PRIMARY KEY,
                recipient_email VARCHAR(255) NOT NULL,
                recipient_name VARCHAR(255),
                subject VARCHAR(255) NOT NULL,
                email_type VARCHAR(50) NOT NULL,
                status ENUM('sent', 'failed', 'pending') DEFAULT 'pending',
                error_message TEXT,
                sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                user_id INT,
                order_id VARCHAR(100),
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // Security events table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS security_events (
                id INT AUTO_INCREMENT PRIMARY KEY,
                event_type VARCHAR(100) NOT NULL,
                details TEXT,
                user_id INT,
                admin_id INT,
                ip_address VARCHAR(45),
                user_agent TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL,
                FOREIGN KEY (admin_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // User login history table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS user_login_history (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                ip_address VARCHAR(45),
                user_agent TEXT,
                login_success BOOLEAN DEFAULT TRUE,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");
        
        // User follows table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS user_follows (
                id INT AUTO_INCREMENT PRIMARY KEY,
                follower_id INT NOT NULL,
                following_id INT NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (follower_id) REFERENCES users(id) ON DELETE CASCADE,
                FOREIGN KEY (following_id) REFERENCES users(id) ON DELETE CASCADE,
                UNIQUE KEY unique_follow (follower_id, following_id)
            )
        ");
        
        // Audio variations table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS audio_variations (
                id INT AUTO_INCREMENT PRIMARY KEY,
                track_id INT NOT NULL,
                variation_index INT NOT NULL,
                audio_url TEXT,
                duration INT,
                title VARCHAR(255),
                tags TEXT,
                image_url TEXT,
                source_audio_url TEXT,
                stream_audio_url TEXT,
                metadata JSON,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE
            )
        ");
        
        // Add missing metadata column if it doesn't exist
        $pdo->exec("
            ALTER TABLE audio_variations 
            ADD COLUMN IF NOT EXISTS metadata JSON
        ");
        
        // Track likes table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_likes (
                id INT AUTO_INCREMENT PRIMARY KEY,
                track_id INT NOT NULL,
                user_id INT NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
                UNIQUE KEY unique_like (track_id, user_id)
            )
        ");
        
        // Track plays table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_plays (
                id INT AUTO_INCREMENT PRIMARY KEY,
                track_id INT NOT NULL,
                user_id INT,
                ip_address VARCHAR(45),
                played_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // Create performance indexes
        $indexes = [
            // Music tracks indexes
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_user_status ON music_tracks(user_id, status)",
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_created_at ON music_tracks(created_at)",
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_status ON music_tracks(status)",
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_task_id ON music_tracks(task_id)",
            
            // User follows indexes
            "CREATE INDEX IF NOT EXISTS idx_user_follows_follower ON user_follows(follower_id)",
            "CREATE INDEX IF NOT EXISTS idx_user_follows_following ON user_follows(following_id)",
            
            // Audio variations indexes
            "CREATE INDEX IF NOT EXISTS idx_audio_variations_track ON audio_variations(track_id)",
            
            // Track likes indexes
            "CREATE INDEX IF NOT EXISTS idx_track_likes_track ON track_likes(track_id)",
            
            // Track plays indexes
            "CREATE INDEX IF NOT EXISTS idx_track_plays_track ON track_plays(track_id)",
            
            // Credit transactions indexes
            "CREATE INDEX IF NOT EXISTS idx_credit_transactions_user ON credit_transactions(user_id, created_at)",
            
            // Email logs indexes
            "CREATE INDEX IF NOT EXISTS idx_email_logs_sent_at ON email_logs(sent_at)",
            "CREATE INDEX IF NOT EXISTS idx_email_logs_user ON email_logs(user_id)",
            
            // Security events indexes
            "CREATE INDEX IF NOT EXISTS idx_security_events_type ON security_events(event_type, created_at)",
            "CREATE INDEX IF NOT EXISTS idx_security_events_user ON security_events(user_id)",
            
            // User login history indexes
            "CREATE INDEX IF NOT EXISTS idx_user_login_history_user ON user_login_history(user_id, created_at)",
            "CREATE INDEX IF NOT EXISTS idx_user_login_history_ip ON user_login_history(ip_address)"
        ];
        
        foreach ($indexes as $index_sql) {
            try {
                $pdo->exec($index_sql);
            } catch (Exception $e) {
                // Index might already exist, continue
            }
        }
        
        // Security flags table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS security_flags (
                id INT AUTO_INCREMENT PRIMARY KEY,
                flag_type VARCHAR(100) NOT NULL,
                flag_value TEXT,
                severity ENUM('low', 'medium', 'high', 'critical') DEFAULT 'medium',
                is_active BOOLEAN DEFAULT TRUE,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                resolved_at TIMESTAMP NULL
            )
        ");
        
        // IP blacklist table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS ip_blacklist (
                id INT AUTO_INCREMENT PRIMARY KEY,
                ip_address VARCHAR(45) UNIQUE NOT NULL,
                reason TEXT,
                blocked_by INT,
                blocked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                expires_at TIMESTAMP NULL,
                FOREIGN KEY (blocked_by) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // User login history table
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS user_login_history (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                ip_address VARCHAR(45),
                user_agent TEXT,
                login_success BOOLEAN DEFAULT TRUE,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");
        
        // Add security-related columns to users table
        $pdo->exec("
            ALTER TABLE users 
            ADD COLUMN IF NOT EXISTS is_admin BOOLEAN DEFAULT FALSE,
            ADD COLUMN IF NOT EXISTS is_blocked BOOLEAN DEFAULT FALSE,
            ADD COLUMN IF NOT EXISTS block_reason TEXT,
            ADD COLUMN IF NOT EXISTS blocked_at TIMESTAMP NULL,
            ADD COLUMN IF NOT EXISTS last_login_ip VARCHAR(45),
            ADD COLUMN IF NOT EXISTS last_login_at TIMESTAMP NULL,
            ADD COLUMN IF NOT EXISTS failed_login_attempts INT DEFAULT 0,
            ADD COLUMN IF NOT EXISTS last_failed_login TIMESTAMP NULL
        ");
        
        // User follows table (for social features)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS user_follows (
                id INT AUTO_INCREMENT PRIMARY KEY,
                follower_id INT NOT NULL,
                following_id INT NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE KEY unique_follow (follower_id, following_id),
                FOREIGN KEY (follower_id) REFERENCES users(id) ON DELETE CASCADE,
                FOREIGN KEY (following_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");
        
        // Track likes table (for track likes)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_likes (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                track_id INT NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE KEY unique_like (user_id, track_id),
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE
            )
        ");
        
        // Track comments table (for track comments)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_comments (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                track_id INT NOT NULL,
                comment TEXT NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE
            )
        ");
        
        // Track views table (for view tracking)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_views (
                id INT AUTO_INCREMENT PRIMARY KEY,
                track_id INT NOT NULL,
                user_id INT,
                ip_address VARCHAR(45),
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // Track shares table (for share tracking)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_shares (
                id INT AUTO_INCREMENT PRIMARY KEY,
                track_id INT NOT NULL,
                user_id INT,
                share_type VARCHAR(50) DEFAULT 'social',
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // Track purchases table (for user purchases)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_purchases (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL,
                track_id INT NOT NULL,
                price_paid DECIMAL(10,2) NOT NULL,
                credits_used INT NOT NULL,
                purchase_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                download_count INT DEFAULT 0,
                last_downloaded TIMESTAMP NULL,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE,
                UNIQUE KEY unique_purchase (user_id, track_id)
            )
        ");
        
        // User profiles table (for additional profile info)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS user_profiles (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NOT NULL UNIQUE,
                bio TEXT,
                location VARCHAR(255),
                website VARCHAR(255),
                social_links JSON,
                profile_image VARCHAR(255),
                genres JSON,
                music_style TEXT,
                artist_highlights JSON,
                influences TEXT,
                equipment TEXT,
                achievements JSON,
                featured_tracks JSON,
                artist_statement TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
            )
        ");
        
        // Track plays table (for play count tracking)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS track_plays (
                id INT AUTO_INCREMENT PRIMARY KEY,
                track_id INT NOT NULL,
                user_id INT,
                ip_address VARCHAR(45),
                user_agent TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE,
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // Admin logs table (for tracking admin actions)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS admin_logs (
                id INT AUTO_INCREMENT PRIMARY KEY,
                admin_id INT NOT NULL,
                action VARCHAR(100) NOT NULL,
                target_user_id INT,
                details TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (admin_id) REFERENCES users(id) ON DELETE CASCADE,
                FOREIGN KEY (target_user_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // Site settings table (for global site configuration)
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS site_settings (
                id INT AUTO_INCREMENT PRIMARY KEY,
                setting_key VARCHAR(100) UNIQUE NOT NULL,
                setting_value TEXT,
                setting_description TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
            )
        ");
        
        // Email logs table for tracking email activity
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS email_logs (
                id INT AUTO_INCREMENT PRIMARY KEY,
                recipient_email VARCHAR(255) NOT NULL,
                recipient_name VARCHAR(255),
                subject VARCHAR(255) NOT NULL,
                email_type VARCHAR(50) NOT NULL,
                status ENUM('sent', 'failed', 'pending') DEFAULT 'pending',
                error_message TEXT,
                sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                user_id INT,
                order_id VARCHAR(100),
                FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
            )
        ");
        
        // Insert default site settings if they don't exist
        $defaultSettings = [
            ['global_player_enabled', '1', 'Enable global music player'],
            ['auto_play_enabled', '0', 'Enable auto-play for music player'],
            ['shuffle_enabled', '0', 'Enable shuffle mode for playlists'],
            ['ajax_enabled', '1', 'Enable AJAX navigation'],
            ['debug_mode', '0', 'Enable debug mode'],
            ['stripe_live_mode', '1', 'Use Stripe live mode'],
            ['auto_refresh_payment_methods', '0', 'Auto-refresh payment methods']
        ];
        
        foreach ($defaultSettings as $setting) {
            try {
                $stmt = $pdo->prepare("
                    INSERT IGNORE INTO site_settings (setting_key, setting_value, setting_description) 
                    VALUES (?, ?, ?)
                ");
                $stmt->execute($setting);
            } catch (Exception $e) {
                // If setting_description column doesn't exist, try without it
                try {
                    $stmt = $pdo->prepare("
                        INSERT IGNORE INTO site_settings (setting_key, setting_value) 
                        VALUES (?, ?)
                    ");
                    $stmt->execute([$setting[0], $setting[1]]);
                } catch (Exception $e2) {
                    error_log("Failed to insert site setting: " . $e2->getMessage());
                }
            }
        }
        
        return true;
    } catch (PDOException $e) {
        error_log("Database initialization failed: " . $e->getMessage());
        return false;
    }
}

// User management functions
function createUser($name, $email, $password) {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
        
        $stmt = $pdo->prepare("
            INSERT INTO users (name, email, password, credits, plan) 
            VALUES (?, ?, ?, 5, 'free')
        ");
        
        return $stmt->execute([$name, $email, $hashedPassword]);
    } catch (PDOException $e) {
        error_log("User creation failed: " . $e->getMessage());
        return false;
    }
}

function authenticateUser($email, $password) {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
        $stmt->execute([$email]);
        $user = $stmt->fetch();
        
        if ($user && password_verify($password, $user['password'])) {
            return $user;
        }
        
        return false;
    } catch (PDOException $e) {
        error_log("User authentication failed: " . $e->getMessage());
        return false;
    }
}

function getUserById($id) {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
        $stmt->execute([$id]);
        return $stmt->fetch();
    } catch (PDOException $e) {
        error_log("Get user failed: " . $e->getMessage());
        return false;
    }
}

function updateUserCredits($userId, $credits) {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        $stmt = $pdo->prepare("UPDATE users SET credits = ? WHERE id = ?");
        return $stmt->execute([$credits, $userId]);
    } catch (PDOException $e) {
        error_log("Update credits failed: " . $e->getMessage());
        return false;
    }
}

// Music track management functions
function createMusicTrack($userId, $taskId, $title, $prompt, $musicType, $modelVersion = 'v3', $duration = 30) {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        // Check user credits first
        $stmt = $pdo->prepare("SELECT credits FROM users WHERE id = ?");
        $stmt->execute([$userId]);
        $user = $stmt->fetch();
        
        if (!$user || $user['credits'] < 1) {
            error_log("Insufficient credits for user $userId to create track");
            return false;
        }
        
        // Deduct credit
        $newCredits = $user['credits'] - 1;
        $stmt = $pdo->prepare("UPDATE users SET credits = ? WHERE id = ?");
        $stmt->execute([$newCredits, $userId]);
        
        // Record credit transaction
        $stmt = $pdo->prepare("
            INSERT INTO credit_transactions (user_id, amount, type, description, created_at) 
            VALUES (?, -1, 'usage', 'Music track creation via createMusicTrack: $title', NOW())
        ");
        $stmt->execute([$userId]);
        
        // Create the track
        $stmt = $pdo->prepare("
            INSERT INTO music_tracks (user_id, task_id, title, prompt, music_type, model_version, duration) 
            VALUES (?, ?, ?, ?, ?, ?, ?)
        ");
        
        $result = $stmt->execute([$userId, $taskId, $title, $prompt, $musicType, $modelVersion, $duration]);
        
        if ($result) {
            error_log("Credit deducted for user $userId: 1 credit, new balance: $newCredits");
        }
        
        return $result;
    } catch (PDOException $e) {
        error_log("Create music track failed: " . $e->getMessage());
        return false;
    }
}

function updateMusicTrack($taskId, $status, $audioUrl = null, $videoUrl = null, $lyrics = null, $metadata = null, $duration = null) {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        // Parse metadata to extract individual fields
        $metadataArray = $metadata ? json_decode($metadata, true) : [];
        
        // Build the update query dynamically based on what's provided
        $updates = ['status = ?'];
        $params = [$status];
        
        if ($audioUrl !== null) {
            $updates[] = 'audio_url = ?';
            $params[] = $audioUrl;
        }
        
        if ($videoUrl !== null) {
            $updates[] = 'video_url = ?';
            $params[] = $videoUrl;
        }
        
        if ($lyrics !== null) {
            $updates[] = 'lyrics = ?';
            $params[] = $lyrics;
        }
        
        if ($metadata !== null) {
            $updates[] = 'metadata = ?';
            $params[] = $metadata;
        }
        
        if ($duration !== null) {
            $updates[] = 'duration = ?';
            $params[] = $duration;
        }
        
        // Update individual metadata fields to their own columns
        if (isset($metadataArray['genre'])) {
            $updates[] = 'genre = ?';
            $params[] = $metadataArray['genre'];
        }
        
        if (isset($metadataArray['style'])) {
            $updates[] = 'style = ?';
            $params[] = $metadataArray['style'];
        }
        
        if (isset($metadataArray['bpm'])) {
            $updates[] = 'bpm = ?';
            $params[] = $metadataArray['bpm'];
        }
        
        if (isset($metadataArray['key'])) {
            $updates[] = 'key = ?';
            $params[] = $metadataArray['key'];
        }
        
        if (isset($metadataArray['time_signature'])) {
            $updates[] = 'time_signature = ?';
            $params[] = $metadataArray['time_signature'];
        }
        
        if (isset($metadataArray['mood'])) {
            $updates[] = 'mood = ?';
            $params[] = $metadataArray['mood'];
        }
        
        if (isset($metadataArray['energy'])) {
            $updates[] = 'energy = ?';
            $params[] = $metadataArray['energy'];
        }
        
        if (isset($metadataArray['instruments'])) {
            $updates[] = 'instruments = ?';
            $params[] = is_array($metadataArray['instruments']) ? implode(', ', $metadataArray['instruments']) : $metadataArray['instruments'];
        }
        
        if (isset($metadataArray['tags'])) {
            $updates[] = 'tags = ?';
            $params[] = is_array($metadataArray['tags']) ? implode(', ', $metadataArray['tags']) : $metadataArray['tags'];
        }
        
        // Also store the detailed metadata in JSON columns for advanced features
        if (isset($metadataArray['audio_quality'])) {
            $updates[] = 'audio_quality = ?';
            $params[] = json_encode($metadataArray['audio_quality']);
        }
        
        if (isset($metadataArray['generation_parameters'])) {
            $updates[] = 'generation_parameters = ?';
            $params[] = json_encode($metadataArray['generation_parameters']);
        }
        
        if (isset($metadataArray['processing_info'])) {
            $updates[] = 'processing_info = ?';
            $params[] = json_encode($metadataArray['processing_info']);
        }
        
        if (isset($metadataArray['cost_info'])) {
            $updates[] = 'cost_info = ?';
            $params[] = json_encode($metadataArray['cost_info']);
        }
        
        if (isset($metadataArray['waveform_data'])) {
            $updates[] = 'waveform_data = ?';
            $params[] = json_encode($metadataArray['waveform_data']);
        }
        
        if (isset($metadataArray['spectrum_analysis'])) {
            $updates[] = 'spectrum_analysis = ?';
            $params[] = json_encode($metadataArray['spectrum_analysis']);
        }
        
        if (isset($metadataArray['audio_segments'])) {
            $updates[] = 'audio_segments = ?';
            $params[] = json_encode($metadataArray['audio_segments']);
        }
        
        if (isset($metadataArray['error_details'])) {
            $updates[] = 'error_details = ?';
            $params[] = json_encode($metadataArray['error_details']);
        }
        
        if (isset($metadataArray['audio_analysis'])) {
            $updates[] = 'audio_analysis = ?';
            $params[] = json_encode($metadataArray['audio_analysis']);
        }
        
        if (isset($metadataArray['system_info'])) {
            $updates[] = 'system_info = ?';
            $params[] = json_encode($metadataArray['system_info']);
        }
        
        $params[] = $taskId;
        
        $sql = "UPDATE music_tracks SET " . implode(', ', $updates) . " WHERE task_id = ?";
        $stmt = $pdo->prepare($sql);
        
        $result = $stmt->execute($params);
        
        if ($result) {
            // Log successful updates for debugging
            error_log("✅ Successfully updated music track: task_id=$taskId, status=$status, rows_affected=" . $stmt->rowCount());
        } else {
            // Log detailed error information
            $errorInfo = $stmt->errorInfo();
            error_log("❌ Failed to update music track: task_id=$taskId, status=$status, SQL=$sql, Error: " . json_encode($errorInfo));
        }
        
        return $result;
    } catch (PDOException $e) {
        error_log("❌ PDO Exception in updateMusicTrack: task_id=$taskId, status=$status, Error: " . $e->getMessage());
        return false;
    }
}

function getUserMusicTracks($userId, $limit = 50) {
    $pdo = getDBConnection();
    if (!$pdo) return [];
    
    try {
        $stmt = $pdo->prepare("
            SELECT * FROM music_tracks 
            WHERE user_id = ? 
            ORDER BY created_at DESC 
            LIMIT ?
        ");
        
        $stmt->execute([$userId, $limit]);
        return $stmt->fetchAll();
    } catch (PDOException $e) {
        error_log("Get user music tracks failed: " . $e->getMessage());
        return [];
    }
}

function getMusicTrackByTaskId($taskId) {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        $stmt = $pdo->prepare("SELECT * FROM music_tracks WHERE task_id = ?");
        $stmt->execute([$taskId]);
        return $stmt->fetch();
    } catch (PDOException $e) {
        error_log("Get music track failed: " . $e->getMessage());
        return false;
    }
}

// Database initialization is handled separately to avoid output issues

// Initialize database tables if not already done
if (!function_exists('databaseInitialized')) {
    function databaseInitialized() {
        return true;
    }
    initializeDatabase();
}

// Function to optimize database performance (can be called from any page)
function optimizeDatabasePerformance() {
    $pdo = getDBConnection();
    if (!$pdo) return false;
    
    try {
        // Create performance indexes if they don't exist
        $indexes = [
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_user_status ON music_tracks(user_id, status)",
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_created_at ON music_tracks(created_at)",
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_status ON music_tracks(status)",
            "CREATE INDEX IF NOT EXISTS idx_music_tracks_task_id ON music_tracks(task_id)",
            "CREATE INDEX IF NOT EXISTS idx_user_follows_follower ON user_follows(follower_id)",
            "CREATE INDEX IF NOT EXISTS idx_user_follows_following ON user_follows(following_id)",
            "CREATE INDEX IF NOT EXISTS idx_audio_variations_track ON audio_variations(track_id)",
            "CREATE INDEX IF NOT EXISTS idx_track_likes_track ON track_likes(track_id)",
            "CREATE INDEX IF NOT EXISTS idx_track_plays_track ON track_plays(track_id)",
            "CREATE INDEX IF NOT EXISTS idx_credit_transactions_user ON credit_transactions(user_id, created_at)",
            "CREATE INDEX IF NOT EXISTS idx_email_logs_sent_at ON email_logs(sent_at)",
            "CREATE INDEX IF NOT EXISTS idx_email_logs_user ON email_logs(user_id)",
            "CREATE INDEX IF NOT EXISTS idx_security_events_type ON security_events(event_type, created_at)",
            "CREATE INDEX IF NOT EXISTS idx_security_events_user ON security_events(user_id)",
            "CREATE INDEX IF NOT EXISTS idx_user_login_history_user ON user_login_history(user_id, created_at)",
            "CREATE INDEX IF NOT EXISTS idx_user_login_history_ip ON user_login_history(ip_address)"
        ];
        
        foreach ($indexes as $index_sql) {
            try {
                $pdo->exec($index_sql);
            } catch (Exception $e) {
                // Index might already exist, continue
            }
        }
        
        return true;
    } catch (Exception $e) {
        error_log("Database optimization failed: " . $e->getMessage());
        return false;
    }
}

// Cache cleanup disabled during development
function cleanupCache() {
    // Cache cleanup disabled to prevent issues during development
    return 0;
} 

CasperSecurity Mini