/home/awneajlw/www/codestechvista.com/includes/email.php
<?php
/**
* Email Configuration and Functions
* This file contains email sending functionality for OTP and notifications
*/
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
// Email configuration
class EmailConfig {
const SMTP_HOST = 'smtp.gmail.com';
const SMTP_PORT = 587;
const SMTP_USERNAME = 'info.optislip@gmail.com';
const SMTP_PASSWORD = 'optislip12345';
const FROM_EMAIL = 'info.optislip@gmail.com';
const FROM_NAME = 'OPTI SLIP';
}
/**
* Send OTP Email using SMTP
* @param string $email Recipient email address
* @param string $otp OTP code
* @param string $userName User name (optional)
* @return bool Success status
*/
function sendOTPEmail($email, $otp, $userName = '') {
try {
// Create beautiful HTML email template
$subject = 'OPTI SLIP - Email Verification Code';
$htmlBody = createOTPEmailTemplate($otp, $userName);
// Use PHP's built-in mail function with proper headers
$headers = array(
'MIME-Version: 1.0',
'Content-type: text/html; charset=UTF-8',
'From: ' . EmailConfig::FROM_NAME . ' <' . EmailConfig::FROM_EMAIL . '>',
'Reply-To: ' . EmailConfig::FROM_EMAIL,
'X-Mailer: PHP/' . phpversion(),
'X-Priority: 1',
'X-MSMail-Priority: High'
);
// Configure SMTP settings if available
$originalSMTP = ini_get('SMTP');
$originalPort = ini_get('smtp_port');
$originalAuth = ini_get('auth_username');
// Set SMTP configuration
ini_set('SMTP', EmailConfig::SMTP_HOST);
ini_set('smtp_port', EmailConfig::SMTP_PORT);
ini_set('sendmail_from', EmailConfig::FROM_EMAIL);
// Send email
$result = mail($email, $subject, $htmlBody, implode("\r\n", $headers));
// Restore original settings
ini_set('SMTP', $originalSMTP);
ini_set('smtp_port', $originalPort);
// Log email attempt
error_log("OTP Email sent to: $email, Result: " . ($result ? 'Success' : 'Failed'));
return $result;
} catch (Exception $e) {
error_log("Email sending failed: " . $e->getMessage());
return false;
}
}
/**
* Create Beautiful OTP Email Template
* @param string $otp OTP code
* @param string $userName User name
* @return string HTML email content
*/
function createOTPEmailTemplate($otp, $userName = '') {
$greeting = $userName ? "Dear $userName," : "Hello,";
return '
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OPTI SLIP - Email Verification</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
color: #333333;
background-color: #f8f9fa;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.email-header {
background: linear-gradient(135deg, #169D53, #22c55e);
color: white;
padding: 40px 30px;
text-align: center;
}
.logo {
width: 80px;
height: 80px;
background: white;
border-radius: 50%;
margin: 0 auto 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
color: #169D53;
}
.email-title {
font-size: 28px;
font-weight: 700;
margin-bottom: 10px;
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.email-subtitle {
font-size: 16px;
opacity: 0.9;
}
.email-body {
padding: 40px 30px;
}
.greeting {
font-size: 18px;
margin-bottom: 20px;
color: #333;
}
.message {
font-size: 16px;
line-height: 1.7;
color: #555;
margin-bottom: 30px;
}
.otp-container {
background: linear-gradient(135deg, #f8f9fa, #e9ecef);
border-radius: 12px;
padding: 30px;
text-align: center;
margin: 30px 0;
border: 2px dashed #169D53;
}
.otp-label {
font-size: 14px;
font-weight: 600;
color: #666;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 1px;
}
.otp-code {
font-size: 36px;
font-weight: 800;
color: #169D53;
letter-spacing: 8px;
font-family: "Courier New", monospace;
text-shadow: 0 2px 4px rgba(22, 157, 83, 0.2);
}
.otp-note {
font-size: 12px;
color: #888;
margin-top: 15px;
font-style: italic;
}
.security-note {
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 8px;
padding: 20px;
margin: 25px 0;
}
.security-title {
font-size: 16px;
font-weight: 600;
color: #856404;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.security-icon {
margin-right: 8px;
font-size: 18px;
}
.security-text {
font-size: 14px;
color: #856404;
line-height: 1.5;
}
.email-footer {
background: #f8f9fa;
padding: 30px;
text-align: center;
border-top: 1px solid #e9ecef;
}
.footer-text {
font-size: 14px;
color: #666;
margin-bottom: 10px;
}
.company-name {
font-weight: 700;
color: #169D53;
}
.footer-links {
margin-top: 20px;
}
.footer-link {
color: #169D53;
text-decoration: none;
margin: 0 15px;
font-size: 14px;
}
.footer-link:hover {
text-decoration: underline;
}
/* Mobile Responsive */
@media (max-width: 600px) {
.email-container {
margin: 10px;
border-radius: 8px;
}
.email-header {
padding: 30px 20px;
}
.email-title {
font-size: 24px;
}
.email-body {
padding: 30px 20px;
}
.otp-container {
padding: 20px;
margin: 20px 0;
}
.otp-code {
font-size: 28px;
letter-spacing: 4px;
}
.email-footer {
padding: 20px;
}
}
</style>
</head>
<body>
<div class="email-container">
<div class="email-header">
<h1 class="email-title">OPTI SLIP</h1>
<p class="email-subtitle">Email Verification Required</p>
</div>
<div class="email-body">
<div class="greeting">' . $greeting . '</div>
<div class="message">
Thank you for registering with <strong>OPTI SLIP</strong>! To complete your account setup and ensure the security of your account, please verify your email address using the verification code below.
</div>
<div class="otp-container">
<div class="otp-label">Your Verification Code</div>
<div class="otp-code">' . $otp . '</div>
<div class="otp-note">This code will expire in 10 minutes</div>
</div>
<div class="message">
Enter this code on the verification page to activate your account and start using our optical management system.
</div>
<div class="security-note">
<div class="security-title">
<span class="security-icon">🔒</span>
Security Notice
</div>
<div class="security-text">
This verification code is confidential. Never share it with anyone. OPTI SLIP will never ask for your verification code via phone or email.
</div>
</div>
</div>
<div class="email-footer">
<div class="footer-text">
This email was sent by <span class="company-name">OPTI SLIP</span>
</div>
<div class="footer-text">
Professional Optical Management System
</div>
<div class="footer-links">
<a href="#" class="footer-link">Privacy Policy</a>
<a href="#" class="footer-link">Terms of Service</a>
<a href="#" class="footer-link">Contact Support</a>
</div>
</div>
</div>
</body>
</html>';
}
/**
* Generate OTP Code
* @return string 6-digit OTP
*/
function generateOTP() {
return sprintf("%06d", rand(100000, 999999));
}
/**
* Save OTP to Database
* @param string $email User email
* @param string $otp OTP code
* @return bool Success status
*/
function saveOTPToDatabase($email, $otp) {
try {
$database = new Database();
$db = $database->getConnection();
// Create OTP table if it doesn't exist
$createTable = "CREATE TABLE IF NOT EXISTS otp_verifications (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
otp_code VARCHAR(6) NOT NULL,
expires_at TIMESTAMP NOT NULL,
is_used BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_email (email),
INDEX idx_otp (otp_code),
INDEX idx_expires (expires_at)
)";
$db->exec($createTable);
// Set expiration time (10 minutes from now)
$expiresAt = date('Y-m-d H:i:s', strtotime('+10 minutes'));
// Mark previous OTPs for this email as used
$updateQuery = "UPDATE otp_verifications SET is_used = TRUE WHERE email = ? AND is_used = FALSE";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->execute([$email]);
// Insert new OTP
$insertQuery = "INSERT INTO otp_verifications (email, otp_code, expires_at) VALUES (?, ?, ?)";
$insertStmt = $db->prepare($insertQuery);
$result = $insertStmt->execute([$email, $otp, $expiresAt]);
if ($result) {
error_log("OTP saved successfully: Email=$email, OTP=$otp, Expires=$expiresAt");
} else {
error_log("Failed to save OTP: Email=$email, OTP=$otp");
}
return $result;
} catch (Exception $e) {
error_log("OTP Database Error: " . $e->getMessage());
return false;
}
}
/**
* Verify OTP Code
* @param string $email User email
* @param string $otp OTP code to verify
* @return bool Verification status
*/
function verifyOTP($email, $otp) {
try {
$database = new Database();
$db = $database->getConnection();
// Debug: Check all OTPs for this email
$debugQuery = "SELECT otp_code, expires_at, is_used, created_at FROM otp_verifications WHERE email = ? ORDER BY created_at DESC";
$debugStmt = $db->prepare($debugQuery);
$debugStmt->execute([$email]);
$allOTPs = $debugStmt->fetchAll(PDO::FETCH_ASSOC);
error_log("All OTPs for $email: " . json_encode($allOTPs));
// Check if OTP exists and is valid
$query = "SELECT id FROM otp_verifications
WHERE email = ? AND otp_code = ?
AND expires_at > NOW() AND is_used = FALSE
ORDER BY created_at DESC LIMIT 1";
$stmt = $db->prepare($query);
$stmt->execute([$email, $otp]);
$otpRecord = $stmt->fetch(PDO::FETCH_ASSOC);
error_log("OTP verification query result: " . json_encode($otpRecord));
if ($otpRecord) {
// Mark OTP as used
$updateQuery = "UPDATE otp_verifications SET is_used = TRUE WHERE id = ?";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->execute([$otpRecord['id']]);
error_log("OTP marked as used for email: $email");
return true;
}
error_log("No valid OTP found for email: $email, OTP: $otp");
return false;
} catch (Exception $e) {
error_log("OTP Verification Error: " . $e->getMessage());
return false;
}
}
function sendResetEmail($email, $reset_link) {
try {
$subject = 'OPTI SLIP - Password Reset Request';
$htmlBody = "
<html>
<body>
<h2>Password Reset Request</h2>
<p>Hello,</p>
<p>Click the link below to reset your password:</p>
<p><a href='$reset_link'>Reset Password</a></p>
<p>This link will expire in 1 hour.</p>
</body>
</html>";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= "From: noreply@codestechvista.com\r\n";
return mail($email, $subject, $htmlBody, $headers);
} catch (Exception $e) {
error_log("Email Error: " . $e->getMessage());
return false;
}
}
?>