Sindbad~EG File Manager
<?php
require_once '../../config/config.php';
checkLogin();
// Only superusers and admins can edit users
if (!isSuperuser() && getAccessLevel() !== 'area') {
redirect('../../dashboard.php');
}
$pageTitle = "Edit User - " . APP_NAME;
$db = Database::getInstance()->getConnection();
$success = '';
$error = '';
// Get user ID
if (!isset($_GET['id'])) {
redirect('index.php');
}
$userId = $_GET['id'];
// Get user details
$stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $userId]);
$user = $stmt->fetch();
if (!$user) {
redirect('index.php');
}
// Prevent non-superusers from editing superusers
if ($user['is_superuser'] && !isSuperuser()) {
redirect('index.php');
}
// Get areas, districts, assemblies
$areas = $db->query("SELECT * FROM areas WHERE is_active = 1 ORDER BY area_name")->fetchAll();
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = sanitize($_POST['username']);
$email = sanitize($_POST['email']);
$fullName = sanitize($_POST['full_name']);
$phone = sanitize($_POST['phone']);
$accessLevel = $_POST['access_level'];
$areaId = $_POST['area_id'] ?: null;
$districtId = $_POST['district_id'] ?: null;
$assemblyId = $_POST['assembly_id'] ?: null;
$isActive = isset($_POST['is_active']) ? 1 : 0;
// Handle profile photo upload
$profilePhoto = $user['profile_photo']; // Keep existing photo by default
if (isset($_FILES['profile_photo']) && $_FILES['profile_photo']['error'] === UPLOAD_ERR_OK) {
$uploadDir = '../../uploads/profiles/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$fileExtension = strtolower(pathinfo($_FILES['profile_photo']['name'], PATHINFO_EXTENSION));
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
if (in_array($fileExtension, $allowedExtensions)) {
$fileName = 'user_' . $userId . '_' . time() . '.' . $fileExtension;
$targetPath = $uploadDir . $fileName;
if (move_uploaded_file($_FILES['profile_photo']['tmp_name'], $targetPath)) {
// Delete old photo if it exists
if (!empty($user['profile_photo']) && file_exists($uploadDir . $user['profile_photo'])) {
unlink($uploadDir . $user['profile_photo']);
}
$profilePhoto = $fileName;
} else {
$error = "Failed to upload profile photo.";
}
} else {
$error = "Invalid file type. Only JPG, JPEG, PNG, and GIF files are allowed.";
}
}
// Validate
if (empty($username) || empty($email) || empty($fullName)) {
$error = "Please fill all required fields";
} else {
try {
// Check if username/email exists for other users
$stmt = $db->prepare("SELECT id FROM users WHERE (username = :username OR email = :email) AND id != :id");
$stmt->execute(['username' => $username, 'email' => $email, 'id' => $userId]);
if ($stmt->fetch()) {
$error = "Username or email already exists";
} else {
// Update user
$sql = "UPDATE users SET
username = :username,
email = :email,
full_name = :full_name,
phone = :phone,
access_level = :access_level,
area_id = :area_id,
district_id = :district_id,
assembly_id = :assembly_id,
is_active = :is_active,
profile_photo = :profile_photo";
// Update password if provided
$params = [
'username' => $username,
'email' => $email,
'full_name' => $fullName,
'phone' => $phone,
'access_level' => $accessLevel,
'area_id' => $areaId,
'district_id' => $districtId,
'assembly_id' => $assemblyId,
'is_active' => $isActive,
'profile_photo' => $profilePhoto,
'id' => $userId
];
if (!empty($_POST['password'])) {
if (strlen($_POST['password']) < 6) {
$error = "Password must be at least 6 characters";
} else {
$sql .= ", password_hash = :password_hash";
$params['password_hash'] = password_hash($_POST['password'], PASSWORD_BCRYPT);
}
}
if (empty($error)) {
$sql .= " WHERE id = :id";
$stmt = $db->prepare($sql);
$stmt->execute($params);
// Log the action
$auditLog = new AuditLog();
$auditLog->log($_SESSION['user_id'], 'update', 'users', $userId);
$success = "User updated successfully!";
// Refresh user data
$stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $userId]);
$user = $stmt->fetch();
}
}
} catch (PDOException $e) {
$error = "Error updating user: " . $e->getMessage();
}
}
}
include '../../includes/header.php';
?>
<?php include '../../includes/sidebar.php'; ?>
<!-- Main Content -->
<main class="flex-1 md:ml-64 mt-16">
<div class="container mx-auto px-4 py-8">
<div class="max-w-4xl mx-auto">
<!-- Page Header -->
<div class="mb-6">
<h1 class="text-3xl font-bold text-gray-800">
<i class="fas fa-user-edit mr-2 text-blue-500"></i>Edit User
</h1>
<p class="text-gray-600 mt-2">Update user account information</p>
</div>
<!-- Messages -->
<?php if ($success): ?>
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg mb-6">
<i class="fas fa-check-circle mr-2"></i><?php echo $success; ?>
<a href="index.php" class="float-right text-green-800 hover:text-green-900">View All Users →</a>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg mb-6">
<i class="fas fa-exclamation-circle mr-2"></i><?php echo $error; ?>
</div>
<?php endif; ?>
<!-- Form -->
<form method="POST" enctype="multipart/form-data" class="bg-white rounded-xl shadow-lg p-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Full Name *</label>
<input type="text" name="full_name" value="<?php echo htmlspecialchars($user['full_name']); ?>" required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Username *</label>
<input type="text" name="username" value="<?php echo htmlspecialchars($user['username']); ?>" required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Email *</label>
<input type="email" name="email" value="<?php echo htmlspecialchars($user['email']); ?>" required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Phone</label>
<input type="tel" name="phone" value="<?php echo htmlspecialchars($user['phone'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
</div>
<div class="md:col-span-2">
<label class="block text-sm font-medium text-gray-700 mb-2">Profile Photo</label>
<div class="flex items-center space-x-4">
<?php if (!empty($user['profile_photo'])): ?>
<img src="<?php echo BASE_URL . 'uploads/profiles/' . $user['profile_photo']; ?>"
alt="Current Photo"
class="w-16 h-16 rounded-full object-cover border-2 border-gray-300">
<?php else: ?>
<div class="w-16 h-16 rounded-full bg-gray-200 flex items-center justify-center border-2 border-gray-300">
<i class="fas fa-user text-gray-400 text-xl"></i>
</div>
<?php endif; ?>
<div class="flex-1">
<input type="file" name="profile_photo" accept="image/*"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<p class="text-sm text-gray-500 mt-1">Upload JPG, JPEG, PNG, or GIF files only</p>
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">New Password</label>
<input type="password" name="password" minlength="6"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<p class="text-xs text-gray-500 mt-1">Leave empty to keep current password</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Access Level *</label>
<select name="access_level" id="accessLevel" required onchange="updateLocationFields()"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
<?php echo $user['is_superuser'] ? 'disabled' : ''; ?>>
<?php if ($user['is_superuser']): ?>
<option value="superuser" selected>Superuser</option>
<?php else: ?>
<option value="">Select Access Level</option>
<?php if (isSuperuser()): ?>
<option value="area" <?php echo $user['access_level'] === 'area' ? 'selected' : ''; ?>>Area Admin</option>
<?php endif; ?>
<option value="district" <?php echo $user['access_level'] === 'district' ? 'selected' : ''; ?>>District Admin</option>
<option value="assembly" <?php echo $user['access_level'] === 'assembly' ? 'selected' : ''; ?>>Assembly Admin</option>
<?php endif; ?>
</select>
<?php if ($user['is_superuser']): ?>
<input type="hidden" name="access_level" value="superuser">
<?php endif; ?>
</div>
<div id="areaField" class="<?php echo in_array($user['access_level'], ['area', 'district', 'assembly']) ? '' : 'hidden'; ?>">
<label class="block text-sm font-medium text-gray-700 mb-2">Area</label>
<select name="area_id" id="areaSelect" onchange="loadDistricts(this.value)"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">Select Area</option>
<?php foreach ($areas as $area): ?>
<option value="<?php echo $area['id']; ?>" <?php echo $user['area_id'] == $area['id'] ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($area['area_name']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div id="districtField" class="<?php echo in_array($user['access_level'], ['district', 'assembly']) ? '' : 'hidden'; ?>">
<label class="block text-sm font-medium text-gray-700 mb-2">District</label>
<select name="district_id" id="districtSelect" onchange="loadAssemblies(this.value)"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">Select District</option>
</select>
</div>
<div id="assemblyField" class="<?php echo $user['access_level'] === 'assembly' ? '' : 'hidden'; ?>">
<label class="block text-sm font-medium text-gray-700 mb-2">Assembly</label>
<select name="assembly_id" id="assemblySelect"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">Select Assembly</option>
</select>
</div>
<div class="md:col-span-2">
<label class="flex items-center">
<input type="checkbox" name="is_active" value="1" <?php echo $user['is_active'] ? 'checked' : ''; ?>
class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
<span class="ml-2 text-sm text-gray-700">Active Account</span>
</label>
</div>
</div>
<div class="mt-6 flex justify-end space-x-4">
<a href="index.php" class="px-6 py-2 border border-gray-300 rounded-lg hover:bg-gray-100 transition">
Cancel
</a>
<button type="submit" class="bg-gradient-to-r from-blue-500 to-blue-600 text-white px-6 py-2 rounded-lg hover:from-blue-600 hover:to-blue-700 transition">
<i class="fas fa-save mr-2"></i>Update User
</button>
</div>
</form>
</div>
</div>
</main>
<script>
// Initial load
document.addEventListener('DOMContentLoaded', function() {
<?php if ($user['area_id']): ?>
loadDistricts(<?php echo $user['area_id']; ?>, <?php echo $user['district_id'] ?? 'null'; ?>);
<?php endif; ?>
<?php if ($user['district_id']): ?>
loadAssemblies(<?php echo $user['district_id']; ?>, <?php echo $user['assembly_id'] ?? 'null'; ?>);
<?php endif; ?>
});
function updateLocationFields() {
const level = document.getElementById('accessLevel').value;
const areaField = document.getElementById('areaField');
const districtField = document.getElementById('districtField');
const assemblyField = document.getElementById('assemblyField');
areaField.classList.add('hidden');
districtField.classList.add('hidden');
assemblyField.classList.add('hidden');
if (level === 'area') {
areaField.classList.remove('hidden');
} else if (level === 'district') {
areaField.classList.remove('hidden');
districtField.classList.remove('hidden');
} else if (level === 'assembly') {
areaField.classList.remove('hidden');
districtField.classList.remove('hidden');
assemblyField.classList.remove('hidden');
}
}
function loadDistricts(areaId, selectedDistrict = null) {
if (!areaId) {
document.getElementById('districtSelect').innerHTML = '<option value="">Select District</option>';
document.getElementById('assemblySelect').innerHTML = '<option value="">Select Assembly</option>';
return;
}
fetch('<?php echo BASE_URL; ?>api/get-districts.php?area_id=' + areaId)
.then(response => response.json())
.then(data => {
let html = '<option value="">Select District</option>';
data.forEach(district => {
const selected = (selectedDistrict && district.id == selectedDistrict) ? 'selected' : '';
html += `<option value="${district.id}" ${selected}>${district.district_name}</option>`;
});
document.getElementById('districtSelect').innerHTML = html;
document.getElementById('assemblySelect').innerHTML = '<option value="">Select Assembly</option>';
});
}
function loadAssemblies(districtId, selectedAssembly = null) {
if (!districtId) {
document.getElementById('assemblySelect').innerHTML = '<option value="">Select Assembly</option>';
return;
}
fetch('<?php echo BASE_URL; ?>api/get-assemblies.php?district_id=' + districtId)
.then(response => response.json())
.then(data => {
let html = '<option value="">Select Assembly</option>';
data.forEach(assembly => {
const selected = (selectedAssembly && assembly.id == selectedAssembly) ? 'selected' : '';
html += `<option value="${assembly.id}" ${selected}>${assembly.assembly_name}</option>`;
});
document.getElementById('assemblySelect').innerHTML = html;
});
}
</script>
<?php include '../../includes/footer.php'; ?>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists