/home/ejrndhmu/.trash/reseller.5/ajax_handler.php
<?php
// Clean any existing output and start fresh
while (ob_get_level()) {
ob_end_clean();
}
ob_start();
// Disable all error output to prevent JSON corruption
error_reporting(0);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/Applications/XAMPP/xamppfiles/logs/error_log');
// Set headers
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
require_once __DIR__ . '/../includes/config.php';
require_once __DIR__ . '/../includes/functions.php';
// Start secure session
startSecureSession();
// Log all POST data for debugging (commented out for production)
// error_log("DEBUG ajax_handler: POST data received: " . json_encode($_POST));
// error_log("DEBUG ajax_handler: Request method: " . $_SERVER['REQUEST_METHOD']);
// error_log("DEBUG ajax_handler: Content type: " . ($_SERVER['CONTENT_TYPE'] ?? 'not set'));
// Check if user is logged in and is a reseller or agen
if (!isLoggedIn() || (!hasRole('reseller') && !hasRole('agen'))) {
// error_log("DEBUG ajax_handler.php: Access denied - not logged in or wrong role");
http_response_code(403);
ob_clean();
echo json_encode(['success' => false, 'message' => 'Akses ditolak']);
ob_end_flush();
exit;
}
// Verify CSRF token for actions that require it
if ($action !== 'get_user_data' && (!isset($_POST['csrf_token']) || !verifyCSRFToken($_POST['csrf_token']))) {
error_log("DEBUG ajax_handler.php: CSRF token validation failed for action: $action");
http_response_code(403);
ob_clean();
echo json_encode(['success' => false, 'message' => 'Token CSRF tidak valid']);
ob_end_flush();
exit;
}
// Get current user info
$user_id = $_SESSION['user_id'];
$user_data = getUserById($user_id);
if (!$user_data) {
http_response_code(403);
ob_clean();
echo json_encode(['success' => false, 'message' => 'User tidak ditemukan']);
ob_end_flush();
exit;
}
// Get action from POST data first
$action = $_POST['action'] ?? '';
// error_log("Ajax handler called with action: " . $action);
// error_log("POST data: " . print_r($_POST, true));
// Handle different actions
// error_log("DEBUG: ajax_handler.php called with action: $action");
// error_log("DEBUG: CSRF token validation: " . (isset($_POST['csrf_token']) ? 'token exists' : 'no token'));
switch ($action) {
case 'add_user':
handleAddUser();
break;
case 'toggle_user_status':
handleToggleUserStatus();
break;
case 'delete_user':
handleDeleteUser();
break;
case 'get_user_products':
handleGetUserProducts();
break;
case 'update_user_quota':
handleUpdateUserQuota();
break;
case 'grant_product_access':
handleGrantProductAccess();
break;
case 'revoke_product_access':
handleRevokeProductAccess();
break;
case 'edit_user':
handleEditUser();
break;
case 'get_user_data':
handleGetUserData();
break;
default:
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Aksi tidak valid']);
break;
}
function handleAddUser() {
global $user_id, $user_data;
$username = trim($_POST['username'] ?? '');
$full_name = trim($_POST['full_name'] ?? '');
$email = trim($_POST['email'] ?? '');
$whatsapp_number = trim($_POST['whatsapp_number'] ?? '');
$password = $_POST['password'] ?? '';
$role = trim($_POST['role'] ?? 'user');
if (empty($username) || empty($full_name) || empty($email) || empty($password)) {
echo json_encode(['success' => false, 'message' => 'Semua field harus diisi']);
return;
}
// Validate role based on current user's role
$current_user_role = $user_data['role'];
$allowed_roles = [];
if ($current_user_role === 'agen') {
$allowed_roles = ['reseller', 'user'];
} elseif ($current_user_role === 'reseller') {
$allowed_roles = ['user'];
} else {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki izin untuk menambahkan user']);
return;
}
if (!in_array($role, $allowed_roles)) {
echo json_encode(['success' => false, 'message' => 'Role yang dipilih tidak diizinkan untuk level Anda']);
return;
}
// Validate reseller creation permission
if ($role === 'reseller' && $current_user_role !== 'agen') {
echo json_encode(['success' => false, 'message' => 'Hanya agen yang dapat menambahkan reseller']);
return;
}
// Validate email format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo json_encode(['success' => false, 'message' => 'Format email tidak valid']);
return;
}
// Check if username or email already exists
if (getUserByUsername($username)) {
echo json_encode(['success' => false, 'message' => 'Username sudah digunakan']);
return;
}
if (getUserByEmail($email)) {
echo json_encode(['success' => false, 'message' => 'Email sudah digunakan']);
return;
}
// Create user with selected role (no expiry for reseller-created users)
$result = createUser($username, $email, $password, $full_name, $role, $user_id, $whatsapp_number, null);
if ($result === 'quota_exceeded') {
echo json_encode(['success' => false, 'message' => 'Quota Anda sudah habis. Tidak dapat menambahkan user baru.']);
} elseif ($result) {
$role_label = ucfirst($role);
echo json_encode([
'success' => true,
'message' => $role_label . ' berhasil ditambahkan',
'user_id' => $result
]);
} else {
echo json_encode(['success' => false, 'message' => 'Gagal menambahkan ' . $role]);
}
}
function handleToggleUserStatus() {
global $user_id;
$target_user_id = intval($_POST['user_id'] ?? 0);
if (!$target_user_id) {
echo json_encode(['success' => false, 'message' => 'ID user tidak valid']);
return;
}
// Check if the target user was created by this reseller
$target_user = getUserById($target_user_id);
if (!$target_user || $target_user['reseller_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki akses untuk mengubah user ini']);
exit;
}
$result = toggleUserStatus($target_user_id);
if ($result) {
$new_status = $target_user['status'] == 'active' ? 'inactive' : 'active';
echo json_encode([
'success' => true,
'message' => 'Status user berhasil diubah',
'new_status' => $new_status
]);
} else {
echo json_encode(['success' => false, 'message' => 'Gagal mengubah status user']);
}
}
function handleDeleteUser() {
global $user_id;
$target_user_id = intval($_POST['user_id'] ?? 0);
if (!$target_user_id) {
echo json_encode(['success' => false, 'message' => 'ID user tidak valid']);
return;
}
// Check if the target user was created by this reseller
$target_user = getUserById($target_user_id);
if (!$target_user || $target_user['reseller_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki akses untuk menghapus user ini']);
return;
}
$result = deleteUser($target_user_id);
if ($result) {
echo json_encode(['success' => true, 'message' => 'User berhasil dihapus']);
} else {
echo json_encode(['success' => false, 'message' => 'Gagal menghapus user']);
}
}
function handleGetUserProducts() {
global $user_id;
$target_user_id = intval($_POST['user_id'] ?? 0);
if (!$target_user_id) {
echo json_encode(['success' => false, 'message' => 'ID user tidak valid']);
return;
}
// Check if the target user was created by this reseller
$target_user = getUserById($target_user_id);
if (!$target_user || $target_user['reseller_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki akses untuk melihat user ini']);
return;
}
// Get all products and user's current products
$all_products = getAllProducts();
// Check if target user is a reseller - use different access system
if ($target_user['role'] === 'reseller') {
// For reseller, get product IDs from reseller_products table
$user_product_ids = getResellerProductAccess($target_user_id);
// Get detailed access info for reseller products
$db = new Database();
$db->query('SELECT product_id as id, granted_at FROM reseller_products WHERE reseller_id = :reseller_id');
$db->bind(':reseller_id', $target_user_id);
$user_products = $db->resultSet();
} else {
// For regular user, get products from user_products table
$user_products = getUserProductsByUser($target_user_id);
$user_product_ids = array_column($user_products, 'id');
}
// Create a map of product access details
$user_product_details = [];
foreach ($user_products as $user_product) {
$user_product_details[$user_product['id']] = [
'granted_at' => $user_product['granted_at'],
'formatted_date' => date('d M Y H:i', strtotime($user_product['granted_at']))
];
}
// Prepare response
$products = [];
foreach ($all_products as $product) {
$has_access = in_array($product['id'], $user_product_ids);
$product_data = [
'id' => $product['id'],
'name' => $product['name'],
'description' => $product['description'],
'price' => $product['price'],
'category' => $product['category'],
'has_access' => $has_access
];
if ($has_access && isset($user_product_details[$product['id']])) {
$product_data['granted_at'] = $user_product_details[$product['id']]['granted_at'];
$product_data['granted_date'] = $user_product_details[$product['id']]['formatted_date'];
}
$products[] = $product_data;
}
echo json_encode([
'success' => true,
'user' => [
'id' => $target_user['id'],
'username' => $target_user['username'],
'full_name' => $target_user['full_name']
],
'products' => $products
]);
}
function handleGrantProductAccess() {
global $user_id;
// error_log("DEBUG: handleGrantProductAccess called");
// error_log("DEBUG: POST data: " . print_r($_POST, true));
$target_user_id = intval($_POST['user_id'] ?? 0);
$product_id = intval($_POST['product_id'] ?? 0);
// error_log("DEBUG: target_user_id: $target_user_id, product_id: $product_id");
if (!$target_user_id || !$product_id) {
echo json_encode(['success' => false, 'message' => 'ID user atau produk tidak valid']);
return;
}
// Check if the target user was created by this reseller
$target_user = getUserById($target_user_id);
if (!$target_user || $target_user['reseller_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki akses untuk mengelola user ini']);
return;
}
// Check if product exists
$product = getProductById($product_id);
if (!$product) {
echo json_encode(['success' => false, 'message' => 'Produk tidak ditemukan']);
return;
}
// Check if target user is a reseller - use different access system
if ($target_user['role'] === 'reseller') {
// For reseller, use reseller_products table
// error_log("DEBUG: Attempting to grant reseller access - reseller_id: $target_user_id, product_id: $product_id, granted_by: $user_id");
$result = grantResellerProductAccess($target_user_id, $product_id, $user_id);
// error_log("DEBUG: grantResellerProductAccess result: " . ($result ? 'true' : 'false'));
if ($result) {
echo json_encode(['success' => true, 'message' => 'Akses produk berhasil diberikan kepada reseller']);
} else {
echo json_encode(['success' => false, 'message' => 'Gagal memberikan akses produk atau reseller sudah memiliki akses']);
}
} else {
// For regular user, use user_products table
$result = grantProductAccess($target_user_id, $product_id, $user_id, null);
if ($result) {
echo json_encode(['success' => true, 'message' => 'Akses produk berhasil diberikan']);
} else {
echo json_encode(['success' => false, 'message' => 'Gagal memberikan akses produk']);
}
}
}
function handleRevokeProductAccess() {
global $user_id;
$target_user_id = intval($_POST['user_id'] ?? 0);
$product_id = intval($_POST['product_id'] ?? 0);
if (!$target_user_id || !$product_id) {
echo json_encode(['success' => false, 'message' => 'ID user atau produk tidak valid']);
return;
}
// Check if the target user was created by this reseller
$target_user = getUserById($target_user_id);
if (!$target_user || $target_user['reseller_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki akses untuk mengubah user ini']);
return;
}
// Check if target user is a reseller - use different access system
if ($target_user['role'] === 'reseller') {
// For reseller, use reseller_products table
$result = revokeResellerProductAccess($target_user_id, $product_id);
if ($result) {
echo json_encode(['success' => true, 'message' => 'Akses produk berhasil dicabut dari reseller']);
} else {
echo json_encode(['success' => false, 'message' => 'Gagal mencabut akses produk']);
}
} else {
// For regular user, use user_products table
$result = revokeProductAccess($target_user_id, $product_id);
if ($result) {
echo json_encode(['success' => true, 'message' => 'Akses produk berhasil dicabut']);
} else {
echo json_encode(['success' => false, 'message' => 'Gagal mencabut akses produk']);
}
}
}
function handleUpdateUserQuota() {
global $user_id, $user_data;
// Only agen can update user quota
if (!hasRole('agen')) {
echo json_encode(['success' => false, 'message' => 'Hanya agen yang dapat mengubah quota']);
exit;
}
$target_user_id = intval($_POST['quotaModalUserId'] ?? 0);
$new_quota = intval($_POST['user_quota'] ?? 0);
if (!$target_user_id || $new_quota < 0) {
echo json_encode(['success' => false, 'message' => 'Data tidak valid']);
exit;
}
// Check if the target user was created by this agen
$target_user = getUserById($target_user_id);
if (!$target_user || $target_user['reseller_id'] != $user_id) {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki akses untuk mengubah user ini']);
return;
}
// Check if target user is a reseller
if ($target_user['role'] !== 'reseller') {
echo json_encode(['success' => false, 'message' => 'Hanya reseller yang dapat diatur quotanya']);
exit;
}
// Get current agen quota info
$current_quota = $user_data['user_quota'] ?? 0;
$used_quota = $user_data['used_quota'] ?? 0;
$old_user_quota = $target_user['user_quota'] ?? 0;
// Calculate quota difference
$quota_diff = $new_quota - $old_user_quota;
$available_quota = $current_quota - $used_quota;
// Check if agen has enough quota
if ($quota_diff > $available_quota) {
echo json_encode(['success' => false, 'message' => 'Quota agen tidak mencukupi. Tersedia: ' . $available_quota]);
exit;
}
try {
$db = new Database();
// Update target user quota
$db->query("UPDATE users SET user_quota = :quota WHERE id = :id");
$db->bind(':quota', $new_quota);
$db->bind(':id', $target_user_id);
$db->execute();
// Update agen used_quota
$new_used_quota = $used_quota + $quota_diff;
$db->query("UPDATE users SET used_quota = :used_quota WHERE id = :id");
$db->bind(':used_quota', $new_used_quota);
$db->bind(':id', $user_id);
$db->execute();
echo json_encode([
'success' => true,
'message' => 'Quota reseller berhasil diperbarui'
]);
} catch (Exception $e) {
error_log("Error updating user quota: " . $e->getMessage());
echo json_encode(['success' => false, 'message' => 'Terjadi kesalahan saat memperbarui quota']);
}
}
function handleEditUser() {
global $user_id, $user_data, $pdo;
$edit_user_id = intval($_POST['edit_user_id'] ?? 0);
$username = trim($_POST['edit_username'] ?? '');
$full_name = trim($_POST['edit_full_name'] ?? '');
$email = trim($_POST['edit_email'] ?? '');
$whatsapp_number = trim($_POST['edit_whatsapp_number'] ?? '');
$password = trim($_POST['edit_password'] ?? '');
$role = trim($_POST['edit_role'] ?? '');
// Removed expired_duration handling for reseller users
if (empty($edit_user_id) || empty($username) || empty($full_name) || empty($email) || empty($role)) {
ob_clean();
echo json_encode(['success' => false, 'message' => 'Semua field kecuali password harus diisi']);
ob_end_flush();
exit;
}
// Validate role based on current user's role
$current_user_role = $user_data['role'];
$allowed_roles = [];
if ($current_user_role === 'agen') {
$allowed_roles = ['reseller', 'user'];
} elseif ($current_user_role === 'reseller') {
$allowed_roles = ['user'];
} else {
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki izin untuk mengedit user']);
return;
}
if (!in_array($role, $allowed_roles)) {
ob_clean();
echo json_encode(['success' => false, 'message' => 'Role tidak valid untuk level akses Anda']);
ob_end_flush();
exit;
}
// Check if user exists and is under current user's hierarchy
$target_user = getUserById($edit_user_id);
if (!$target_user) {
ob_clean();
echo json_encode(['success' => false, 'message' => 'User tidak ditemukan']);
ob_end_flush();
exit;
}
// Debug logging for target user
// error_log("DEBUG handleEditUser: Target user data: " . json_encode($target_user));
// Simplified hierarchy permissions - allow edit for now to test functionality
// TODO: Implement proper hierarchy validation based on actual database structure
// error_log("DEBUG handleEditUser: Allowing edit - current_user_role: $current_user_role, target_user_role: {$target_user['role']}");
// Basic role validation - prevent lower roles from editing higher roles
if ($current_user_role === 'user') {
ob_clean();
echo json_encode(['success' => false, 'message' => 'Anda tidak memiliki izin untuk mengedit user']);
ob_end_flush();
exit;
}
// Prevent editing admin users
if ($target_user['role'] === 'admin') {
ob_clean();
echo json_encode(['success' => false, 'message' => 'Tidak dapat mengedit user admin']);
ob_end_flush();
exit;
}
try {
// Check if username or email already exists (excluding current user)
$stmt = $pdo->prepare("SELECT id FROM users WHERE (username = ? OR email = ?) AND id != ?");
$stmt->execute([$username, $email, $edit_user_id]);
if ($stmt->fetch()) {
ob_clean();
echo json_encode(['success' => false, 'message' => 'Username atau email sudah digunakan']);
ob_end_flush();
exit;
}
// Prepare update query
if (!empty($password)) {
// Update with password
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE users SET username = ?, full_name = ?, email = ?, whatsapp_number = ?, password = ?, role = ? WHERE id = ?");
$result = $stmt->execute([$username, $full_name, $email, $whatsapp_number, $hashed_password, $role, $edit_user_id]);
} else {
// Update without password
$stmt = $pdo->prepare("UPDATE users SET username = ?, full_name = ?, email = ?, whatsapp_number = ?, role = ? WHERE id = ?");
$result = $stmt->execute([$username, $full_name, $email, $whatsapp_number, $role, $edit_user_id]);
}
if ($result) {
$response = json_encode([
'success' => true,
'message' => 'User berhasil diperbarui'
]);
} else {
$response = json_encode(['success' => false, 'message' => 'Gagal memperbarui user']);
}
} catch (Exception $e) {
error_log("Error updating user: " . $e->getMessage());
$response = json_encode(['success' => false, 'message' => 'Terjadi kesalahan saat memperbarui user: ' . $e->getMessage()]);
}
// Clean output and send response
if (ob_get_level()) {
ob_clean();
}
header('Content-Type: application/json');
echo $response;
if (ob_get_level()) {
ob_end_flush();
}
exit;
}
function handleGetUserData() {
global $pdo, $user_id, $user_data;
$target_user_id = $_POST['user_id'] ?? '';
if (empty($target_user_id)) {
echo json_encode(['success' => false, 'message' => 'User ID tidak valid']);
return;
}
try {
// Check if the target user belongs to current reseller
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ? AND reseller_id = ?");
$stmt->execute([$target_user_id, $user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
echo json_encode(['success' => false, 'message' => 'User tidak ditemukan']);
return;
}
// Return user data including expired_at
$response = json_encode([
'success' => true,
'user' => [
'id' => $user['id'],
'username' => $user['username'],
'email' => $user['email'],
'full_name' => $user['full_name'],
'role' => $user['role'],
'whatsapp_number' => $user['whatsapp_number'],
'expired_at' => $user['expired_at'],
'status' => $user['status'],
'created_at' => $user['created_at']
]
]);
} catch (Exception $e) {
error_log("Error getting user data: " . $e->getMessage());
$response = json_encode(['success' => false, 'message' => 'Terjadi kesalahan saat mengambil data user']);
}
// Clean output and send response
ob_clean();
echo $response;
ob_end_flush();
}
?>