Sindbad~EG File Manager
<?php
require_once '../../config/config.php';
checkLogin();
$pageTitle = 'Members Export - ' . APP_NAME;
$db = Database::getInstance()->getConnection();
// Access level
$accessLevel = $_SESSION['access_level'] ?? 'assembly';
$areaId = $_SESSION['area_id'] ?? null;
$districtId = $_SESSION['district_id'] ?? null;
$assemblyId = $_SESSION['assembly_id'] ?? null;
// Load districts and assemblies
$districts = [];
$assemblies = [];
try {
$districtsStmt = $db->query("SELECT id, district_name FROM districts WHERE is_active = 1 ORDER BY district_name");
$districts = $districtsStmt->fetchAll();
} catch (PDOException $e) {
}
try {
$assembliesStmt = $db->query("SELECT id, assembly_name, district_id FROM assemblies WHERE is_active = 1 ORDER BY assembly_name");
$assemblies = $assembliesStmt->fetchAll();
} catch (PDOException $e) {
}
// Build base FROM and WHERE with access level
$baseFrom = " FROM members m
JOIN areas a ON m.area_id = a.id
JOIN districts d ON m.district_id = d.id
JOIN assemblies asm ON m.assembly_id = asm.id
LEFT JOIN member_accounts ma ON ma.member_id = m.id AND ma.is_active = 1
LEFT JOIN memberuser_codes muc ON muc.member_id = m.id AND muc.is_active = 1
WHERE 1=1";
$where = '';
$params = [];
if ($accessLevel === 'assembly') {
$where .= " AND m.assembly_id = :assembly_id";
$params['assembly_id'] = $assemblyId;
} elseif ($accessLevel === 'district') {
$where .= " AND m.district_id = :district_id";
$params['district_id'] = $districtId;
} elseif ($accessLevel === 'area') {
$where .= " AND m.area_id = :area_id";
$params['area_id'] = $areaId;
}
// Optional filters
if (isset($_GET['district_filter']) && $_GET['district_filter'] !== '') {
$where .= " AND m.district_id = :filter_district_id";
$params['filter_district_id'] = (int)$_GET['district_filter'];
}
if (isset($_GET['assembly_filter']) && $_GET['assembly_filter'] !== '') {
$where .= " AND m.assembly_id = :filter_assembly_id";
$params['filter_assembly_id'] = (int)$_GET['assembly_filter'];
}
// Common SELECT for full details (members + account + tracking)
$selectFull = "SELECT
m.id,
m.membershipcard_id,
m.membership_id,
m.family_id,
m.title,
m.first_name,
m.middle_name,
m.last_name,
m.gender,
m.date_of_birth,
m.place_of_birth,
m.phone,
m.email,
m.member_type,
m.marital_status,
m.address_line1,
m.gps_address,
m.street_name,
m.city,
m.hometown,
m.area_id,
a.area_name,
m.district_id,
d.district_name,
m.assembly_id,
asm.assembly_name,
m.parent_name,
m.parent_relationship,
m.holyghost_baptism,
m.date_of_holyspirit_baptism,
m.water_baptism,
m.date_of_baptism,
m.date_of_conversion,
m.date_of_joining,
m.place_of_baptism,
m.officiating_minister_baptism,
m.officiating_ministers_district,
m.communicant,
m.occupation,
m.level_of_education,
m.dedicated,
m.dedication_date,
m.name_of_officiating_minister,
m.church_where_dedication_done,
m.is_active,
m.created_at,
ma.username AS account_username,
ma.email AS account_email,
muc.code AS tracking_code_id,
muc.tracking_code
";
// SELECT for custom fields only
$selectCustom = "SELECT
m.title,
m.first_name,
m.middle_name,
m.last_name,
m.gender,
m.date_of_birth,
m.place_of_birth,
m.phone,
m.email,
m.member_type,
m.marital_status,
m.address_line1,
m.gps_address,
m.hometown,
m.street_name,
m.city,
m.parent_name,
m.parent_relationship,
m.holyghost_baptism,
m.date_of_holyspirit_baptism,
m.water_baptism,
m.date_of_baptism,
m.date_of_conversion,
m.date_of_joining,
m.place_of_baptism,
m.officiating_minister_baptism,
m.officiating_ministers_district,
m.communicant,
m.occupation,
m.level_of_education,
m.dedicated,
m.dedication_date,
m.name_of_officiating_minister,
m.church_where_dedication_done
";
// Handle exports
if (isset($_GET['export']) && in_array($_GET['export'], ['all', 'filtered', 'custom'], true)) {
$exportType = $_GET['export'];
// For "all", ignore district/assembly filters but keep access-level constraints
$exportWhere = $where;
$exportParams = $params;
if ($exportType === 'all') {
// rebuild where only with access-level constraints
$exportWhere = '';
$exportParams = [];
if ($accessLevel === 'assembly') {
$exportWhere .= " AND m.assembly_id = :assembly_id";
$exportParams['assembly_id'] = $assemblyId;
} elseif ($accessLevel === 'district') {
$exportWhere .= " AND m.district_id = :district_id";
$exportParams['district_id'] = $districtId;
} elseif ($accessLevel === 'area') {
$exportWhere .= " AND m.area_id = :area_id";
$exportParams['area_id'] = $areaId;
}
}
if ($exportType === 'custom') {
$sql = $selectCustom . $baseFrom . $exportWhere . ' ORDER BY m.created_at DESC';
} else {
$sql = $selectFull . $baseFrom . $exportWhere . ' ORDER BY m.created_at DESC';
}
$stmt = $db->prepare($sql);
$stmt->execute($exportParams);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$filenamePrefix = 'members_export_' . $exportType . '_';
$filename = $filenamePrefix . date('Ymd_His') . '.csv';
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=' . $filename);
$output = fopen('php://output', 'w');
if (!empty($rows)) {
// Header row
fputcsv($output, array_keys($rows[0]));
foreach ($rows as $row) {
fputcsv($output, $row);
}
} else {
fputcsv($output, ['No data available for this export']);
}
fclose($output);
exit;
}
// For on-page listing, show filtered members (using current filters)
$listSql = $selectFull . $baseFrom . $where . ' ORDER BY m.created_at DESC LIMIT 500';
$listStmt = $db->prepare($listSql);
$listStmt->execute($params);
$members = $listStmt->fetchAll(PDO::FETCH_ASSOC);
include '../../includes/header.php';
include '../../includes/sidebar.php';
?>
<main class="flex-1 md:ml-64 mt-16">
<div class="container mx-auto px-4 py-8">
<!-- Page Header -->
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 gap-4">
<div>
<h1 class="text-3xl font-bold text-gray-800">
<i class="fas fa-file-export mr-2 text-blue-500"></i>Members Export
</h1>
<p class="text-gray-600 mt-2">Filter members and export full or custom details</p>
</div>
<div class="flex gap-3">
<a href="index.php" class="btn-gradient text-white px-6 py-3 rounded-full font-semibold transition shadow-lg hover:shadow-xl">
<i class="fas fa-users mr-2"></i>Back to Members
</a>
</div>
</div>
<!-- Filters & Export Actions -->
<div class="bg-white rounded-lg shadow-lg p-6 mb-6">
<form method="GET" action="" class="flex flex-col md:flex-row gap-4 items-center mb-4">
<div class="flex-1 w-full">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-semibold text-gray-600 mb-1">District</label>
<select name="district_filter" id="filterDistrictSelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm">
<option value="">All</option>
<?php foreach ($districts as $dist): ?>
<option value="<?php echo $dist['id']; ?>" <?php echo (isset($_GET['district_filter']) && $_GET['district_filter'] == $dist['id']) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($dist['district_name']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label class="block text-xs font-semibold text-gray-600 mb-1">Assembly</label>
<select name="assembly_filter" id="filterAssemblySelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm">
<option value="">All</option>
<?php foreach ($assemblies as $asm): ?>
<option value="<?php echo $asm['id']; ?>" data-district-id="<?php echo $asm['district_id']; ?>" <?php echo (isset($_GET['assembly_filter']) && $_GET['assembly_filter'] == $asm['id']) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($asm['assembly_name']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
<div class="flex items-center space-x-3">
<button type="submit" class="bg-blue-500 text-white px-6 py-3 rounded-lg hover:bg-blue-600 transition">
<i class="fas fa-filter mr-2"></i>Apply Filter
</button>
<a href="members_export.php" class="bg-gray-500 text-white px-6 py-3 rounded-lg hover:bg-gray-600 transition text-center">
<i class="fas fa-redo mr-2"></i>Reset
</a>
</div>
</form>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
<a href="?export=all" class="block text-center bg-green-600 text-white px-4 py-3 rounded-lg hover:bg-green-700 transition text-sm font-semibold">
<i class="fas fa-download mr-2"></i>Export ALL Members (Full Details)
</a>
<a href="?<?php echo http_build_query(array_merge($_GET, ['export' => 'filtered'])); ?>" class="block text-center bg-indigo-600 text-white px-4 py-3 rounded-lg hover:bg-indigo-700 transition text-sm font-semibold">
<i class="fas fa-filter mr-2"></i>Export Filtered Members (Full Details)
</a>
<a href="?<?php echo http_build_query(array_merge($_GET, ['export' => 'custom'])); ?>" class="block text-center bg-purple-600 text-white px-4 py-3 rounded-lg hover:bg-purple-700 transition text-sm font-semibold">
<i class="fas fa-list mr-2"></i>Export Custom Fields Only
</a>
</div>
<p class="mt-3 text-xs text-gray-500">Note: Filter by District/Assembly first, then use "Export Filtered" or "Export Custom" to export only those members.</p>
</div>
<!-- Members Preview Table -->
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
<div class="px-4 py-3 border-b border-gray-200 bg-gray-50 flex justify-between items-center">
<h2 class="text-sm font-semibold text-gray-700">Preview (showing up to 500 members)</h2>
<span class="text-xs text-gray-500"><?php echo count($members); ?> record(s)</span>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gradient-to-r from-blue-500 to-blue-600 text-white">
<tr>
<th class="px-4 py-2 text-left font-medium uppercase tracking-wider">Member</th>
<th class="px-4 py-2 text-left font-medium uppercase tracking-wider">Member ID</th>
<th class="px-4 py-2 text-left font-medium uppercase tracking-wider">Contact</th>
<th class="px-4 py-2 text-left font-medium uppercase tracking-wider">Location</th>
<th class="px-4 py-2 text-left font-medium uppercase tracking-wider">Tracking Code</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<?php if (empty($members)): ?>
<tr>
<td colspan="5" class="px-6 py-10 text-center text-gray-500">
<i class="fas fa-users text-4xl mb-3 text-gray-300"></i>
<p>No members found for the selected filters.</p>
</td>
</tr>
<?php else: ?>
<?php foreach ($members as $m): ?>
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 whitespace-nowrap">
<div class="font-semibold text-gray-800">
<?php echo htmlspecialchars(trim(($m['title'] ?? '') . ' ' . $m['first_name'] . ' ' . $m['last_name'])); ?>
</div>
<div class="text-xs text-gray-500"><?php echo htmlspecialchars($m['member_type'] ?? ''); ?></div>
</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="font-mono text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded">
<?php echo htmlspecialchars($m['membershipcard_id'] ?? ''); ?>
</span>
</td>
<td class="px-4 py-3 whitespace-nowrap">
<div class="text-xs text-gray-800"><?php echo htmlspecialchars($m['phone'] ?? ''); ?></div>
<div class="text-xs text-gray-500"><?php echo htmlspecialchars($m['email'] ?? ''); ?></div>
</td>
<td class="px-4 py-3">
<div class="text-xs text-gray-800"><?php echo htmlspecialchars($m['assembly_name'] ?? ''); ?></div>
<div class="text-xs text-gray-500"><?php echo htmlspecialchars($m['district_name'] ?? ''); ?></div>
</td>
<td class="px-4 py-3 whitespace-nowrap">
<div class="text-xs text-gray-800"><?php echo htmlspecialchars($m['tracking_code'] ?? ''); ?></div>
<div class="text-xs text-gray-500"><?php echo htmlspecialchars($m['tracking_code_id'] ?? ''); ?></div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<script>
// Filter Assembly options in the filter form based on selected District
document.addEventListener('DOMContentLoaded', function() {
var districtSelect = document.getElementById('filterDistrictSelect');
var assemblySelect = document.getElementById('filterAssemblySelect');
if (!districtSelect || !assemblySelect) return;
function filterAssemblyOptions() {
var selectedDistrict = districtSelect.value;
var options = assemblySelect.querySelectorAll('option');
options.forEach(function(opt) {
if (!opt.dataset.districtId) {
// Keep the "All" option visible
opt.style.display = '';
return;
}
if (selectedDistrict === '' || opt.dataset.districtId === selectedDistrict) {
opt.style.display = '';
} else {
opt.style.display = 'none';
}
});
}
filterAssemblyOptions();
districtSelect.addEventListener('change', function() {
assemblySelect.value = '';
filterAssemblyOptions();
});
});
</script>
</main>
<?php include '../../includes/footer.php'; ?>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists