38751-vm/app/Controllers/AdminController.php
2026-02-25 12:21:34 +00:00

348 lines
13 KiB
PHP

<?php
namespace App\Controllers;
use App\Core\Controller;
use App\Services\ApkService;
class AdminController extends Controller {
private function checkAuth() {
if (!isset($_SESSION['user_id']) || ($_SESSION['role'] ?? '') !== 'admin') {
$this->redirect('/admin/login');
}
}
public function loginForm() {
if (isset($_SESSION['user_id']) && ($_SESSION['role'] ?? '') === 'admin') {
$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 = ? AND role = 'admin'");
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['role'] = $user['role'];
$this->redirect('/admin/dashboard');
} else {
$error = "Invalid username or password, or you are not an admin";
$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();
$search = $_GET['search'] ?? null;
$apkService = new ApkService();
$apks = $apkService->getAllApks(null, $search);
$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 = !empty($_POST['category_id']) ? $_POST['category_id'] : null;
$status = $_POST['status'] ?? 'published';
$is_vip = isset($_POST['is_vip']) ? 1 : 0;
$icon_path = $this->handleUpload('icon_file', true);
$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 massUploadForm() {
$this->checkAuth();
$db = db_pdo();
$categories = $db->query("SELECT * FROM categories")->fetchAll();
$this->view('admin/apks/mass_upload', ['categories' => $categories]);
}
public function massUpload() {
$this->checkAuth();
$titles = $_POST['titles'] ?? [];
$versions = $_POST['versions'] ?? [];
$download_urls = $_POST['download_urls'] ?? [];
$category_id = !empty($_POST['category_id']) ? $_POST['category_id'] : null;
$status = $_POST['status'] ?? 'published';
$db = db_pdo();
$stmt = $db->prepare("INSERT INTO apks (title, slug, description, version, icon_path, download_url, category_id, status, is_vip, display_order) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, 0)");
foreach ($titles as $index => $title) {
if (empty($title)) continue;
$slug = $this->slugify($title);
$version = $versions[$index] ?? '';
$download_url = $download_urls[$index] ?? '';
$description = $title; // Default description to title for mass upload
$icon_path = $this->handleMassUploadFile('icon_files', $index, true);
$stmt->execute([$title, $slug, $description, $version, $icon_path, $download_url, $category_id, $status]);
}
$this->redirect('/admin/apks');
}
private function handleMassUploadFile($field, $index, $compress = false) {
if (!isset($_FILES[$field]['name'][$index]) || $_FILES[$field]['error'][$index] !== UPLOAD_ERR_OK) {
return null;
}
$uploadDir = 'assets/uploads/icons/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0775, true);
}
$ext = pathinfo($_FILES[$field]['name'][$index], PATHINFO_EXTENSION);
$fileName = uniqid() . '.' . $ext;
$targetPath = $uploadDir . $fileName;
if ($compress) {
if (compress_image($_FILES[$field]['tmp_name'][$index], $targetPath, 75)) {
return $targetPath;
}
} else {
if (move_uploaded_file($_FILES[$field]['tmp_name'][$index], $targetPath)) {
return $targetPath;
}
}
return null;
}
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 = !empty($_POST['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', true) ?: $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, $compress = false) {
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 ($compress) {
if (compress_image($_FILES[$field]['tmp_name'], $targetPath, 75)) {
return $targetPath;
}
} else {
if (move_uploaded_file($_FILES[$field]['tmp_name'], $targetPath)) {
return $targetPath;
}
}
return null;
}
// Settings Management
public function settingsForm() {
$this->checkAuth();
$settings = [
'site_name' => get_setting('site_name'),
'site_icon' => get_setting('site_icon'),
'site_favicon' => get_setting('site_favicon'),
'meta_description' => get_setting('meta_description'),
'meta_keywords' => get_setting('meta_keywords'),
'head_js' => get_setting('head_js'),
'body_js' => get_setting('body_js'),
];
$this->view('admin/settings', ['settings' => $settings]);
}
public function saveSettings() {
$this->checkAuth();
$db = db_pdo();
$fields = ['site_name', 'meta_description', 'meta_keywords', 'head_js', 'body_js'];
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$stmt = $db->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = ?");
$stmt->execute([$_POST[$field], $field]);
}
}
$site_icon = $this->handleUpload('site_icon_file');
if ($site_icon) {
$stmt = $db->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = 'site_icon'");
$stmt->execute([$site_icon]);
}
$site_favicon = $this->handleUpload('site_favicon_file');
if ($site_favicon) {
$stmt = $db->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = 'site_favicon'");
$stmt->execute([$site_favicon]);
}
$this->redirect('/admin/settings');
}
// 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();
$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;
}
}