redirect('/admin/login'); } } public function loginForm() { if (isset($_SESSION['user_id'])) { $this->redirect('/admin/dashboard'); } $this->view('admin/login'); } public function login() { $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; $db = db_pdo(); $stmt = $db->prepare("SELECT * FROM users WHERE username = ?"); $stmt->execute([$username]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password'])) { $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $this->redirect('/admin/dashboard'); } else { $error = "Invalid username or password"; $this->view('admin/login', ['error' => $error]); } } public function logout() { session_destroy(); $this->redirect('/admin/login'); } public function dashboard() { $this->checkAuth(); $apkService = new ApkService(); $db = db_pdo(); $stats = [ 'total_apks' => count($apkService->getAllApks()), 'total_downloads' => $this->getTotalDownloads(), 'total_users' => $db->query("SELECT COUNT(*) FROM users")->fetchColumn(), 'pending_withdrawals' => $db->query("SELECT COUNT(*) FROM withdrawals WHERE status = 'pending'")->fetchColumn(), 'recent_apks' => array_slice($apkService->getAllApks(), 0, 5) ]; $this->view('admin/dashboard', $stats); } private function getTotalDownloads() { $db = db_pdo(); return $db->query("SELECT SUM(total_downloads) FROM apks")->fetchColumn() ?: 0; } // APK Management public function apks() { $this->checkAuth(); $apkService = new ApkService(); $apks = $apkService->getAllApks(); $this->view('admin/apks/index', ['apks' => $apks]); } public function addApkForm() { $this->checkAuth(); $db = db_pdo(); $categories = $db->query("SELECT * FROM categories")->fetchAll(); $this->view('admin/apks/form', ['action' => 'add', 'categories' => $categories]); } public function addApk() { $this->checkAuth(); $title = $_POST['title']; $slug = $this->slugify($title); $description = $_POST['description']; $version = $_POST['version']; $image_url = $_POST['image_url']; $download_url = $_POST['download_url']; $category_id = $_POST['category_id'] ?? null; $status = $_POST['status'] ?? 'published'; $is_vip = isset($_POST['is_vip']) ? 1 : 0; $icon_path = $this->handleUpload('icon_file'); $db = db_pdo(); $stmt = $db->prepare("INSERT INTO apks (title, slug, description, version, image_url, icon_path, download_url, category_id, status, is_vip, display_order) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)"); $stmt->execute([$title, $slug, $description, $version, $image_url, $icon_path, $download_url, $category_id, $status, $is_vip]); $this->redirect('/admin/apks'); } public function editApkForm($params) { $this->checkAuth(); $apkService = new ApkService(); $apk = $apkService->getApkById($params['id']); $db = db_pdo(); $categories = $db->query("SELECT * FROM categories")->fetchAll(); $this->view('admin/apks/form', ['action' => 'edit', 'apk' => $apk, 'categories' => $categories]); } public function editApk($params) { $this->checkAuth(); $title = $_POST['title']; $description = $_POST['description']; $version = $_POST['version']; $image_url = $_POST['image_url']; $download_url = $_POST['download_url']; $category_id = $_POST['category_id'] ?? null; $status = $_POST['status']; $is_vip = isset($_POST['is_vip']) ? 1 : 0; $db = db_pdo(); $apk = $db->query("SELECT * FROM apks WHERE id = " . $params['id'])->fetch(); $icon_path = $this->handleUpload('icon_file') ?: $apk['icon_path']; $stmt = $db->prepare("UPDATE apks SET title = ?, description = ?, version = ?, image_url = ?, icon_path = ?, download_url = ?, category_id = ?, status = ?, is_vip = ? WHERE id = ?"); $stmt->execute([$title, $description, $version, $image_url, $icon_path, $download_url, $category_id, $status, $is_vip, $params['id']]); $this->redirect('/admin/apks'); } public function updateOrder() { $this->checkAuth(); $order = $_POST['order'] ?? []; $db = db_pdo(); foreach ($order as $index => $id) { $stmt = $db->prepare("UPDATE apks SET display_order = ? WHERE id = ?"); $stmt->execute([$index, $id]); } header('Content-Type: application/json'); echo json_encode(['success' => true]); } private function handleUpload($field) { if (!isset($_FILES[$field]) || $_FILES[$field]['error'] !== UPLOAD_ERR_OK) { return null; } $uploadDir = 'assets/uploads/icons/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0775, true); } $ext = pathinfo($_FILES[$field]['name'], PATHINFO_EXTENSION); $fileName = uniqid() . '.' . $ext; $targetPath = $uploadDir . $fileName; if (move_uploaded_file($_FILES[$field]['tmp_name'], $targetPath)) { return $targetPath; } return null; } // Category Management public function categories() { $this->checkAuth(); $db = db_pdo(); $categories = $db->query("SELECT * FROM categories")->fetchAll(); $this->view('admin/categories/index', ['categories' => $categories]); } public function addCategory() { $this->checkAuth(); $name = $_POST['name']; $slug = $this->slugify($name); $db = db_pdo(); $stmt = $db->prepare("INSERT INTO categories (name, slug) VALUES (?, ?)"); $stmt->execute([$name, $slug]); $this->redirect('/admin/categories'); } public function deleteCategory($params) { $this->checkAuth(); $db = db_pdo(); $stmt = $db->prepare("DELETE FROM categories WHERE id = ?"); $stmt->execute([$params['id']]); $this->redirect('/admin/categories'); } // Withdrawal Management public function withdrawals() { $this->checkAuth(); $db = db_pdo(); $withdrawals = $db->query("SELECT w.*, u.username FROM withdrawals w JOIN users u ON w.user_id = u.id ORDER BY w.created_at DESC")->fetchAll(); $this->view('admin/withdrawals/index', ['withdrawals' => $withdrawals]); } public function approveWithdrawal($params) { $this->checkAuth(); $db = db_pdo(); $stmt = $db->prepare("UPDATE withdrawals SET status = 'approved' WHERE id = ?"); $stmt->execute([$params['id']]); $this->redirect('/admin/withdrawals'); } public function rejectWithdrawal($params) { $this->checkAuth(); $db = db_pdo(); // Refund balance if rejected? The user didn't specify, but let's do it for fairness $wd = $db->query("SELECT * FROM withdrawals WHERE id = " . $params['id'])->fetch(); if ($wd && $wd['status'] === 'pending') { $stmt = $db->prepare("UPDATE users SET balance = balance + ? WHERE id = ?"); $stmt->execute([$wd['amount'], $wd['user_id']]); $stmt = $db->prepare("UPDATE withdrawals SET status = 'rejected' WHERE id = ?"); $stmt->execute([$params['id']]); } $this->redirect('/admin/withdrawals'); } public function deleteApk($params) { $this->checkAuth(); $db = db_pdo(); $stmt = $db->prepare("DELETE FROM apks WHERE id = ?"); $stmt->execute([$params['id']]); $this->redirect('/admin/apks'); } private function slugify($text) { $text = preg_replace('~[^\pL\d]+~u', '-', $text); $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); $text = preg_replace('~[^-\w]+~', '', $text); $text = trim($text, '-'); $text = preg_replace('~-+~', '-', $text); $text = strtolower($text); return empty($text) ? 'n-a' : $text; } }