Sindbad~EG File Manager

Current Path : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/membership/
Upload File :
Current File : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/membership/bulk-update.php

<?php
require_once '../../config/config.php';
checkLogin();

$pageTitle = "Bulk Update Members - " . APP_NAME;
$db = Database::getInstance()->getConnection();
$success = '';
$error = '';

// Handle template downloads
if (isset($_GET['download_template'])) {
    $format = $_GET['download_template'];
    
    // Get member fields for template
    $fields = [
        'id', 'title', 'first_name', 'middle_name', 'last_name', 'gender', 'date_of_birth',
        'place_of_birth', 'phone', 'email', 'member_type', 'marital_status', 'address_line1',
        'gps_address', 'street_name', 'city', 'hometown', 'parent_name', 'parent_relationship',
        'occupation', 'level_of_education', 'water_baptism', 'date_of_baptism', 'place_of_baptism',
        'officiating_minister_baptism', 'holyghost_baptism', 'date_of_holyspirit_baptism',
        'communicant', 'dedicated', 'dedication_date'
    ];
    
    if ($format === 'csv') {
        // CSV Download
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=bulk_update_template_' . date('Ymd') . '.csv');
        
        $output = fopen('php://output', 'w');
        fputcsv($output, $fields);
        
        // Add one sample row
        $sampleRow = array_fill(0, count($fields), '');
        $sampleRow[0] = '1'; // id
        $sampleRow[2] = 'John'; // first_name
        $sampleRow[4] = 'Doe'; // last_name
        fputcsv($output, $sampleRow);
        
        fclose($output);
        exit();
    } elseif ($format === 'excel') {
        // Excel Download
        require_once '../../vendor/autoload.php';
        
        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        
        // Header row with styling
        $col = 'A';
        foreach ($fields as $field) {
            $sheet->setCellValue($col . '1', $field);
            $sheet->getStyle($col . '1')->applyFromArray([
                'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['rgb' => '1E40AF']]
            ]);
            $sheet->getColumnDimension($col)->setAutoSize(true);
            $col++;
        }
        
        // Sample row
        $sheet->setCellValue('A2', '1');
        $sheet->setCellValue('C2', 'John');
        $sheet->setCellValue('E2', 'Doe');
        
        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment; filename=bulk_update_template_' . date('Ymd') . '.xlsx');
        
        $writer->save('php://output');
        exit();
    }
}

// Handle file upload
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['update_file'])) {
    try {
        $file = $_FILES['update_file'];
        
        if ($file['error'] !== UPLOAD_ERR_OK) {
            throw new Exception("File upload error");
        }
        
        $fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        
        if ($fileExtension === 'csv') {
            // Process CSV file
            $handle = fopen($file['tmp_name'], 'r');
            $headers = fgetcsv($handle);
            
            $updateResults = [];
            $row = 1;
            
            while (($data = fgetcsv($handle)) !== false) {
                $row++;
                try {
                    $rowData = array_combine($headers, $data);
                    
                    // Must have member ID to update
                    if (empty($rowData['id'])) {
                        $updateResults[] = [
                            'row' => $row,
                            'status' => 'error',
                            'message' => 'Missing member ID'
                        ];
                        continue;
                    }
                    
                    $memberId = $rowData['id'];
                    
                    // Build update query dynamically based on provided fields
                    $updateFields = [];
                    $params = ['id' => $memberId];
                    
                    $allowedFields = [
                        'title', 'first_name', 'middle_name', 'last_name', 'gender',
                        'date_of_birth', 'place_of_birth', 'phone', 'email',
                        'member_type', 'marital_status', 'address_line1', 'gps_address',
                        'hometown', 'street_name', 'city', 'parent_name', 'parent_relationship',
                        'occupation', 'level_of_education', 'water_baptism', 'date_of_baptism',
                        'place_of_baptism', 'officiating_minister_baptism', 'holyghost_baptism',
                        'date_of_holyspirit_baptism', 'communicant', 'dedicated', 'dedication_date'
                    ];
                    
                    foreach ($allowedFields as $field) {
                        if (isset($rowData[$field]) && $rowData[$field] !== '') {
                            $updateFields[] = "$field = :$field";
                            $params[$field] = $rowData[$field];
                        }
                    }
                    
                    if (empty($updateFields)) {
                        $updateResults[] = [
                            'row' => $row,
                            'member_id' => $memberId,
                            'status' => 'warning',
                            'message' => 'No fields to update'
                        ];
                        continue;
                    }
                    
                    $sql = "UPDATE members SET " . implode(', ', $updateFields) . " WHERE id = :id";
                    $stmt = $db->prepare($sql);
                    $stmt->execute($params);
                    
                    // Get member name
                    $nameStmt = $db->prepare("SELECT first_name, last_name FROM members WHERE id = :id");
                    $nameStmt->execute(['id' => $memberId]);
                    $member = $nameStmt->fetch();
                    
                    $updateResults[] = [
                        'row' => $row,
                        'member_id' => $memberId,
                        'member_name' => $member ? $member['first_name'] . ' ' . $member['last_name'] : 'Unknown',
                        'status' => 'success',
                        'message' => count($updateFields) . ' fields updated'
                    ];
                    
                } catch (Exception $e) {
                    $updateResults[] = [
                        'row' => $row,
                        'status' => 'error',
                        'message' => $e->getMessage()
                    ];
                }
            }
            
            fclose($handle);
            $_SESSION['update_results'] = $updateResults;
            
        } elseif (in_array($fileExtension, ['xlsx', 'xls'])) {
            // Process Excel file
            require_once '../../vendor/autoload.php';
            
            $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file['tmp_name']);
            $worksheet = $spreadsheet->getActiveSheet();
            $rows = $worksheet->toArray();
            
            $headers = array_shift($rows);
            $updateResults = [];
            $rowNum = 1;
            
            foreach ($rows as $data) {
                $rowNum++;
                try {
                    $rowData = array_combine($headers, $data);
                    
                    if (empty($rowData['id'])) {
                        $updateResults[] = [
                            'row' => $rowNum,
                            'status' => 'error',
                            'message' => 'Missing member ID'
                        ];
                        continue;
                    }
                    
                    $memberId = $rowData['id'];
                    
                    $updateFields = [];
                    $params = ['id' => $memberId];
                    
                    $allowedFields = [
                        'title', 'first_name', 'middle_name', 'last_name', 'gender',
                        'date_of_birth', 'place_of_birth', 'phone', 'email',
                        'member_type', 'marital_status', 'address_line1', 'gps_address',
                        'hometown', 'street_name', 'city', 'parent_name', 'parent_relationship',
                        'occupation', 'level_of_education', 'water_baptism', 'date_of_baptism',
                        'place_of_baptism', 'officiating_minister_baptism', 'holyghost_baptism',
                        'date_of_holyspirit_baptism', 'communicant', 'dedicated', 'dedication_date'
                    ];
                    
                    foreach ($allowedFields as $field) {
                        if (isset($rowData[$field]) && $rowData[$field] !== null && $rowData[$field] !== '') {
                            $updateFields[] = "$field = :$field";
                            $params[$field] = $rowData[$field];
                        }
                    }
                    
                    if (empty($updateFields)) {
                        $updateResults[] = [
                            'row' => $rowNum,
                            'member_id' => $memberId,
                            'status' => 'warning',
                            'message' => 'No fields to update'
                        ];
                        continue;
                    }
                    
                    $sql = "UPDATE members SET " . implode(', ', $updateFields) . " WHERE id = :id";
                    $stmt = $db->prepare($sql);
                    $stmt->execute($params);
                    
                    $nameStmt = $db->prepare("SELECT first_name, last_name FROM members WHERE id = :id");
                    $nameStmt->execute(['id' => $memberId]);
                    $member = $nameStmt->fetch();
                    
                    $updateResults[] = [
                        'row' => $rowNum,
                        'member_id' => $memberId,
                        'member_name' => $member ? $member['first_name'] . ' ' . $member['last_name'] : 'Unknown',
                        'status' => 'success',
                        'message' => count($updateFields) . ' fields updated'
                    ];
                    
                } catch (Exception $e) {
                    $updateResults[] = [
                        'row' => $rowNum,
                        'status' => 'error',
                        'message' => $e->getMessage()
                    ];
                }
            }
            
            $_SESSION['update_results'] = $updateResults;
        } else {
            throw new Exception("Unsupported file format. Please upload CSV or Excel file.");
        }
        
        $success = "Bulk update completed! " . count($updateResults) . " records processed.";
        
    } catch (Exception $e) {
        $error = "Error processing file: " . $e->getMessage();
    }
}

$updateResults = $_SESSION['update_results'] ?? [];

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-6xl mx-auto">
        <div class="mb-6 flex justify-between items-center">
            <div>
                <h1 class="text-3xl font-bold text-gray-800">
                    <i class="fas fa-file-upload mr-2 text-blue-500"></i>Bulk Update Members
                </h1>
                <p class="text-gray-600 mt-2">Update multiple member records using CSV or Excel file</p>
            </div>
            <a href="index.php" class="bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition">
                <i class="fas fa-arrow-left mr-2"></i>Back to Members
            </a>
        </div>
        
        <?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; ?>
            </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; ?>
        
        <!-- Instructions -->
        <div class="bg-blue-50 rounded-xl shadow-lg p-6 mb-6">
            <h3 class="text-lg font-semibold text-blue-800 mb-4">
                <i class="fas fa-info-circle mr-2"></i>How to Use Bulk Update
            </h3>
            <ol class="space-y-2 text-blue-700">
                <li class="flex items-start">
                    <span class="font-bold mr-2">1.</span>
                    <span>Download the update template below (includes current member data)</span>
                </li>
                <li class="flex items-start">
                    <span class="font-bold mr-2">2.</span>
                    <span>Edit only the fields you want to update. <strong>Do not modify the 'id' column!</strong></span>
                </li>
                <li class="flex items-start">
                    <span class="font-bold mr-2">3.</span>
                    <span>Upload the modified file below</span>
                </li>
                <li class="flex items-start">
                    <span class="font-bold mr-2">4.</span>
                    <span>Review the results and verify changes</span>
                </li>
            </ol>
        </div>
        
        <!-- Download Template -->
        <div class="bg-white rounded-xl shadow-lg p-6 mb-6">
            <h3 class="text-lg font-semibold text-gray-800 mb-4">
                <i class="fas fa-download mr-2"></i>Step 1: Download Template with Current Data
            </h3>
            <p class="text-gray-600 mb-4">Download a template file containing current member data that you can update:</p>
            <div class="flex gap-4">
                <a href="?download_template=csv" 
                   class="bg-gradient-to-r from-orange-500 to-yellow-500 text-white px-6 py-3 rounded-lg hover:shadow-lg transition">
                    <i class="fas fa-file-csv mr-2"></i>Download CSV Template
                </a>
                <a href="?download_template=excel" 
                   class="bg-gradient-to-r from-blue-500 to-blue-700 text-white px-6 py-3 rounded-lg hover:shadow-lg transition">
                    <i class="fas fa-file-excel mr-2"></i>Download Excel Template
                </a>
            </div>
        </div>
        
        <!-- Upload Form -->
        <div class="bg-white rounded-xl shadow-lg p-6 mb-6">
            <h3 class="text-lg font-semibold text-gray-800 mb-4">
                <i class="fas fa-upload mr-2"></i>Step 2: Upload Updated File
            </h3>
            <form method="POST" enctype="multipart/form-data" class="space-y-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">
                        Select File (CSV or Excel)
                    </label>
                    <input type="file" name="update_file" accept=".csv,.xlsx,.xls" required
                           class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                </div>
                
                <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
                    <h4 class="font-semibold text-yellow-800 mb-2">
                        <i class="fas fa-exclamation-triangle mr-2"></i>Important Notes
                    </h4>
                    <ul class="text-sm text-yellow-700 space-y-1">
                        <li>• The 'id' column is required and must not be modified</li>
                        <li>• Only include members you want to update</li>
                        <li>• Empty cells will not update that field</li>
                        <li>• Boolean fields: use 1 for Yes, 0 for No</li>
                        <li>• Date format: YYYY-MM-DD</li>
                    </ul>
                </div>
                
                <div class="flex justify-center">
                    <button type="submit" class="bg-blue-500 text-white px-8 py-3 rounded-lg hover:bg-blue-600 transition">
                        <i class="fas fa-upload mr-2"></i>Upload & Update Members
                    </button>
                </div>
            </form>
        </div>
        
        <!-- Results -->
        <?php if (!empty($updateResults)): ?>
        <div class="bg-white rounded-xl shadow-lg p-6">
            <div class="flex justify-between items-center mb-4">
                <h3 class="text-lg font-semibold text-gray-800">
                    <i class="fas fa-list-check mr-2"></i>Update Results
                </h3>
                <button onclick="location.reload()" class="text-gray-600 hover:text-gray-800">
                    <i class="fas fa-times mr-2"></i>Clear Results
                </button>
            </div>
            
            <div class="mb-4 grid grid-cols-3 gap-4">
                <div class="bg-green-50 p-4 rounded-lg">
                    <div class="text-green-600 font-bold text-2xl">
                        <?php echo count(array_filter($updateResults, fn($r) => $r['status'] == 'success')); ?>
                    </div>
                    <div class="text-green-700 text-sm">Successful Updates</div>
                </div>
                <div class="bg-yellow-50 p-4 rounded-lg">
                    <div class="text-yellow-600 font-bold text-2xl">
                        <?php echo count(array_filter($updateResults, fn($r) => $r['status'] == 'warning')); ?>
                    </div>
                    <div class="text-yellow-700 text-sm">Warnings</div>
                </div>
                <div class="bg-red-50 p-4 rounded-lg">
                    <div class="text-red-600 font-bold text-2xl">
                        <?php echo count(array_filter($updateResults, fn($r) => $r['status'] == 'error')); ?>
                    </div>
                    <div class="text-red-700 text-sm">Errors</div>
                </div>
            </div>
            
            <div class="overflow-x-auto">
                <table class="min-w-full bg-white border border-gray-200">
                    <thead class="bg-gray-50">
                        <tr>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Row</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Member</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Status</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Message</th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-gray-200">
                        <?php foreach ($updateResults as $result): ?>
                        <tr>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                                <?php echo $result['row']; ?>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                                <?php echo $result['member_name'] ?? ($result['member_id'] ?? 'N/A'); ?>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap">
                                <?php if ($result['status'] == 'success'): ?>
                                    <span class="px-2 py-1 text-xs font-medium rounded-full bg-green-100 text-green-800">Success</span>
                                <?php elseif ($result['status'] == 'warning'): ?>
                                    <span class="px-2 py-1 text-xs font-medium rounded-full bg-yellow-100 text-yellow-800">Warning</span>
                                <?php else: ?>
                                    <span class="px-2 py-1 text-xs font-medium rounded-full bg-red-100 text-red-800">Error</span>
                                <?php endif; ?>
                            </td>
                            <td class="px-6 py-4 text-sm text-gray-600">
                                <?php echo htmlspecialchars($result['message']); ?>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        </div>
        <?php endif; ?>
    </div>
</div>
</main>

<?php include '../../includes/footer.php'; ?>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists