Sindbad~EG File Manager
<?php
require_once '../config/config.php';
require_once '../classes/EmailService.php';
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
exit;
}
$data = json_decode(file_get_contents('php://input'), true);
$membershipId = trim($data['membership_id'] ?? '');
if (empty($membershipId)) {
echo json_encode(['success' => false, 'message' => 'Membership ID is required']);
exit;
}
try {
$db = Database::getInstance()->getConnection();
// Find member by membership card ID
$stmt = $db->prepare("
SELECT m.id, m.membershipcard_id, m.first_name, m.last_name, m.email,
mc.card_number
FROM members m
LEFT JOIN membership_cards mc ON m.id = mc.member_id
WHERE (m.membershipcard_id = :membership_id OR mc.card_number = :membership_id2)
AND m.is_active = 1
LIMIT 1
");
$stmt->execute([
'membership_id' => $membershipId,
'membership_id2' => $membershipId
]);
$member = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$member) {
echo json_encode(['success' => false, 'message' => 'Membership ID not found. Please check and try again.']);
exit;
}
if (empty($member['email'])) {
echo json_encode(['success' => false, 'message' => 'No email address found for this membership. Please contact the admin.']);
exit;
}
// Clean up expired codes
$stmt = $db->prepare("DELETE FROM public_directory_access WHERE expires_at < NOW() AND is_verified = FALSE");
$stmt->execute();
// Check if there's a recent verification attempt (within 2 minutes)
$stmt = $db->prepare("
SELECT id, created_at
FROM public_directory_access
WHERE membership_id = :membership_id
AND created_at > DATE_SUB(NOW(), INTERVAL 2 MINUTE)
ORDER BY created_at DESC
LIMIT 1
");
$stmt->execute(['membership_id' => $membershipId]);
$recentAttempt = $stmt->fetch(PDO::FETCH_ASSOC);
if ($recentAttempt) {
$waitTime = 120 - (time() - strtotime($recentAttempt['created_at']));
echo json_encode([
'success' => false,
'message' => "Please wait {$waitTime} seconds before requesting a new code."
]);
exit;
}
// Generate 6-digit verification code
$verificationCode = sprintf('%06d', mt_rand(0, 999999));
// Set expiration time (15 minutes from now)
$expiresAt = date('Y-m-d H:i:s', strtotime('+15 minutes'));
// Store verification code
$stmt = $db->prepare("
INSERT INTO public_directory_access
(membership_id, member_id, email, verification_code, expires_at, ip_address)
VALUES (:membership_id, :member_id, :email, :verification_code, :expires_at, :ip_address)
");
$stmt->execute([
'membership_id' => $membershipId,
'member_id' => $member['id'],
'email' => $member['email'],
'verification_code' => $verificationCode,
'expires_at' => $expiresAt,
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null
]);
// Queue email with verification code using EmailService
$emailService = new EmailService();
$memberName = trim($member['first_name'] . ' ' . $member['last_name']);
$emailSubject = 'Directory Access Verification Code';
$emailBody = "
<div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;'>
<div style='background: linear-gradient(135deg, #1E40AF 0%, #9333EA 50%, #F97316 100%); padding: 30px; text-align: center; border-radius: 10px 10px 0 0;'>
<h1 style='color: white; margin: 0;'>Directory Access Code</h1>
</div>
<div style='background: #f9fafb; padding: 30px; border-radius: 0 0 10px 10px;'>
<p style='font-size: 16px; color: #374151; margin-bottom: 20px;'>Dear {$memberName},</p>
<p style='font-size: 16px; color: #374151; margin-bottom: 20px;'>
You requested access to the public member directory. Use the verification code below to continue:
</p>
<div style='background: white; padding: 20px; border-radius: 8px; text-align: center; margin: 30px 0;'>
<p style='font-size: 14px; color: #6B7280; margin-bottom: 10px;'>Your Verification Code</p>
<p style='font-size: 36px; font-weight: bold; color: #1E40AF; letter-spacing: 8px; margin: 0;'>{$verificationCode}</p>
</div>
<p style='font-size: 14px; color: #6B7280; margin-bottom: 10px;'>
<strong>Important:</strong>
</p>
<ul style='font-size: 14px; color: #6B7280;'>
<li>This code will expire in <strong>15 minutes</strong></li>
<li>Do not share this code with anyone</li>
<li>If you didn't request this code, please ignore this email</li>
</ul>
<p style='font-size: 14px; color: #9CA3AF; margin-top: 30px; padding-top: 20px; border-top: 1px solid #E5E7EB;'>
This is an automated message. Please do not reply to this email.
</p>
</div>
</div>
";
// Queue the email (will be processed by email processor)
$emailQueued = $emailService->queueEmail(
$member['email'],
$memberName,
$emailSubject,
$emailBody,
'directory_verification'
);
if (!$emailQueued) {
// If email system is disabled, still return success (code is saved in database)
// But notify user that email might be delayed
if (!$emailService->isEnabled()) {
echo json_encode([
'success' => true,
'message' => 'Verification code generated. Email system is currently disabled, please contact admin for the code.',
'warning' => 'Email service is disabled'
]);
exit;
}
echo json_encode([
'success' => false,
'message' => 'Failed to queue verification code email. Please try again later.'
]);
exit;
}
// Process the email immediately if possible
try {
$emailService->processPendingEmails(1);
} catch (Exception $e) {
// If processing fails, email is still queued for later
error_log('Immediate email processing failed: ' . $e->getMessage());
}
echo json_encode([
'success' => true,
'message' => 'Verification code sent to your email address.',
'email' => substr($member['email'], 0, 3) . '***@' . substr(strrchr($member['email'], '@'), 1)
]);
} catch (Exception $e) {
error_log('Directory code send error: ' . $e->getMessage());
// Show detailed error in development mode
$errorMessage = 'An error occurred. Please try again later.';
if (defined('APP_ENV') && APP_ENV === 'development') {
$errorMessage = 'Error: ' . $e->getMessage();
}
echo json_encode([
'success' => false,
'message' => $errorMessage,
'debug' => (defined('APP_ENV') && APP_ENV === 'development') ? $e->getTraceAsString() : null
]);
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists