setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, phone TEXT UNIQUE, name TEXT, created_at TEXT)"); $pdo->exec("CREATE TABLE IF NOT EXISTS songs (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, artist TEXT, isrc TEXT, upc TEXT, language TEXT, release_date TEXT, cover TEXT, audio TEXT, status TEXT DEFAULT 'pending', uploaded_by TEXT, created_at TEXT)"); } catch (Exception $e) { die('DB error: ' . htmlspecialchars($e->getMessage())); } // Simple helper function e($s){ return htmlspecialchars($s, ENT_QUOTES); } // Routes handling (very small router) $action = $_REQUEST['action'] ?? 'home'; // --- Artist actions: signup / login (phone) --- if ($action === 'send_otp' && $_SERVER['REQUEST_METHOD']==='POST') { $phone = preg_replace('/\D+/', '', $_POST['phone'] ?? ''); if (!$phone) { echo json_encode(['ok'=>false,'msg'=>'Invalid phone']); exit; } // For demo generate a 4-digit OTP and store in session $otp = rand(1000,9999); $_SESSION['otp_for_' . $phone] = $otp; $_SESSION['otp_time_' . $phone] = time(); // In production: send via SMS provider. Here we'll return OTP for demo. echo json_encode(['ok'=>true,'otp'=>$otp,'msg'=>'OTP (demo) generated — use it to login.']); exit; } if ($action === 'verify_otp' && $_SERVER['REQUEST_METHOD']==='POST') { $phone = preg_replace('/\D+/', '', $_POST['phone'] ?? ''); $otp = $_POST['otp'] ?? ''; if (!$phone || !$otp) { echo json_encode(['ok'=>false,'msg'=>'Missing fields']); exit; } $key = 'otp_for_' . $phone; if (!isset($_SESSION[$key]) || $_SESSION[$key] != $otp || (time() - ($_SESSION['otp_time_'.$phone] ?? 0)) > 300) { echo json_encode(['ok'=>false,'msg'=>'OTP invalid or expired']); exit; } // create or fetch user $stmt = $pdo->prepare('SELECT * FROM users WHERE phone = :phone'); $stmt->execute([':phone'=>$phone]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if (!$user) { $stmt = $pdo->prepare('INSERT INTO users (phone, name, created_at) VALUES (:phone, :name, :created_at)'); $stmt->execute([':phone'=>$phone, ':name'=>'Artist '.$phone, ':created_at'=>date('c')]); $userId = $pdo->lastInsertId(); } else { $userId = $user['id']; } $_SESSION['user_id'] = $userId; $_SESSION['user_phone'] = $phone; echo json_encode(['ok'=>true,'msg'=>'Logged in','user_id'=>$userId]); exit; } // Artist logout if ($action === 'artist_logout') { unset($_SESSION['user_id'], $_SESSION['user_phone']); header('Location: ?'); exit; } // Upload handler (AJAX) if ($action === 'upload_song' && $_SERVER['REQUEST_METHOD']==='POST') { if (empty($_SESSION['user_id'])) { echo json_encode(['ok'=>false,'msg'=>'Not logged in']); exit; } $title = trim($_POST['title'] ?? ''); $artist = trim($_POST['artist'] ?? ''); $isrc = trim($_POST['isrc'] ?? ''); $upc = trim($_POST['upc'] ?? ''); $language = trim($_POST['language'] ?? '']); $release_date = trim($_POST['release_date'] ?? '']); // Basic validation if (!$title || !$artist) { echo json_encode(['ok'=>false,'msg'=>'Title and artist required']); exit; } // Handle files $coverPath = null; $audioPath = null; if (!empty($_FILES['cover']) && $_FILES['cover']['error'] === UPLOAD_ERR_OK) { $f = $_FILES['cover']; $ext = strtolower(pathinfo($f['name'], PATHINFO_EXTENSION)); $allowedImg = ['jpg','jpeg','png','webp']; if (!in_array($ext, $allowedImg)) { echo json_encode(['ok'=>false,'msg'=>'Cover must be image (jpg/png/webp)']); exit; } $dest = $coverDir . '/' . time() . '_' . preg_replace('/[^a-z0-9._-]+/i','_', $f['name']); if (!move_uploaded_file($f['tmp_name'], $dest)) { echo json_encode(['ok'=>false,'msg'=>'Cover upload failed']); exit; } $coverPath = str_replace(__DIR__, '', $dest); } if (!empty($_FILES['audio']) && $_FILES['audio']['error'] === UPLOAD_ERR_OK) { $f = $_FILES['audio']; $ext = strtolower(pathinfo($f['name'], PATHINFO_EXTENSION)); $allowedAudio = ['mp3','wav','m4a','flac']; if (!in_array($ext, $allowedAudio)) { echo json_encode(['ok'=>false,'msg'=>'Audio must be mp3/wav/m4a/flac']); exit; } $dest = $audioDir . '/' . time() . '_' . preg_replace('/[^a-z0-9._-]+/i','_', $f['name']); if (!move_uploaded_file($f['tmp_name'], $dest)) { echo json_encode(['ok'=>false,'msg'=>'Audio upload failed']); exit; } $audioPath = str_replace(__DIR__, '', $dest); } $stmt = $pdo->prepare('INSERT INTO songs (title, artist, isrc, upc, language, release_date, cover, audio, uploaded_by, created_at) VALUES (:title,:artist,:isrc,:upc,:language,:release_date,:cover,:audio,:uploaded_by,:created_at)'); $stmt->execute([ ':title'=>$title,':artist'=>$artist,':isrc'=>$isrc,':upc'=>$upc,':language'=>$language,':release_date'=>$release_date,':cover'=>$coverPath,':audio'=>$audioPath,':uploaded_by'=>$_SESSION['user_phone'] ?? 'guest',':created_at'=>date('c') ]); echo json_encode(['ok'=>true,'msg'=>'Uploaded — pending admin approval']); exit; } // Admin login if ($action === 'admin_login' && $_SERVER['REQUEST_METHOD']==='POST') { $u = $_POST['username'] ?? ''; $p = $_POST['password'] ?? ''; if ($u === $adminUser && $p === $adminPass) { $_SESSION['admin'] = true; echo json_encode(['ok'=>true]); exit; } echo json_encode(['ok'=>false,'msg'=>'Invalid']); exit; } // Admin logout if ($action === 'admin_logout') { unset($_SESSION['admin']); header('Location:?'); exit; } // Admin approve/reject if ($action === 'admin_change_status' && $_SERVER['REQUEST_METHOD']==='POST') { if (empty($_SESSION['admin'])) { echo json_encode(['ok'=>false,'msg'=>'Not admin']); exit; } $id = intval($_POST['id'] ?? 0); $status = $_POST['status'] ?? 'pending'; $stmt = $pdo->prepare('UPDATE songs SET status = :status WHERE id = :id'); $stmt->execute([':status'=>$status, ':id'=>$id]); echo json_encode(['ok'=>true]); exit; } // Fetch songs (for listing) - used by JS if ($action === 'list_songs') { $for = $_GET['for'] ?? 'public'; // public/admin/my if ($for === 'admin' && empty($_SESSION['admin'])) { echo json_encode(['ok'=>false,'msg'=>'Not admin']); exit; } if ($for === 'my' && empty($_SESSION['user_id'])) { echo json_encode(['ok'=>false,'msg'=>'Not logged']); exit; } if ($for === 'admin') { $stmt = $pdo->query('SELECT * FROM songs ORDER BY id DESC'); } elseif ($for === 'my') { $phone = $_SESSION['user_phone']; $stmt = $pdo->prepare('SELECT * FROM songs WHERE uploaded_by = :phone ORDER BY id DESC'); $stmt->execute([':phone'=>$phone]); } else { $stmt = $pdo->query("SELECT * FROM songs WHERE status='approved' ORDER BY id DESC"); } $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['ok'=>true,'rows'=>$rows]); exit; } // File serving helper - allow direct file URL by path relative to __DIR__ // but for simplicity we'll rely on the relative paths stored in DB. // --- End backend. Now render front-end --- ?>
Upload your tracks, manage releases, and get distributed to streaming platforms. Fast review, clean dashboard, and monetization support.