public function contact_submit()
{
// ---- Basic validation ----
$this->form_validation->set_rules('name', 'Name', 'trim|required|min_length[2]|max_length[100]|xss_clean');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email|max_length[150]|xss_clean');
$this->form_validation->set_rules('message', 'Message', 'trim|required|min_length[5]|max_length[2000]|xss_clean');
if ($this->form_validation->run() == false) {
$this->session->set_flashdata('contact_error', validation_errors());
redirect('contact', 'refresh');
}
$name = trim($this->input->post('name'));
$email = trim($this->input->post('email'));
$message = trim($this->input->post('message'));
// ============================================================
// SPAM GUARD — silently rejects bots without revealing why
// ============================================================
// 1. Honeypot check — if "website" field has anything, it's a bot
$honeypot = $this->input->post('website');
if (!empty($honeypot)) {
log_message('error', 'Contact spam blocked [honeypot]: ' . $email);
$this->session->set_flashdata('contact_success', 'Thank you! Your message has been sent.');
redirect('contact', 'refresh');
}
// 2. Timestamp check — reject if submitted under 3 seconds (too fast for humans)
$loaded_at = (int) $this->input->post('form_loaded_at');
if ($loaded_at > 0 && (time() - $loaded_at) < 3) {
log_message('error', 'Contact spam blocked [too fast]: ' . $email);
$this->session->set_flashdata('contact_success', 'Thank you! Your message has been sent.');
redirect('contact', 'refresh');
}
// 3. Reject if message contains more than 2 URLs
$url_count = preg_match_all('#https?://#i', $message, $m);
if ($url_count > 2) {
log_message('error', 'Contact spam blocked [too many URLs]: ' . $email);
$this->session->set_flashdata('contact_success', 'Thank you! Your message has been sent.');
redirect('contact', 'refresh');
}
// 4. Reject BBCode-style link tags: [url=...], [link=...]
if (stripos($message, '[url=') !== false || stripos($message, '[link=') !== false) {
log_message('error', 'Contact spam blocked [bbcode link]: ' . $email);
$this->session->set_flashdata('contact_success', 'Thank you! Your message has been sent.');
redirect('contact', 'refresh');
}
// 5. Reject non-Latin scripts (Japanese, Chinese, Cyrillic, Arabic, etc.)
// If your audience is English-only, this catches 90% of SEO spam.
// Remove this check if you accept messages in other scripts.
if (preg_match('/[\x{0400}-\x{04FF}\x{0600}-\x{06FF}\x{3040}-\x{30FF}\x{4E00}-\x{9FAF}\x{AC00}-\x{D7AF}]/u', $name . $message)) {
log_message('error', 'Contact spam blocked [non-latin script]: ' . $email);
$this->session->set_flashdata('contact_success', 'Thank you! Your message has been sent.');
redirect('contact', 'refresh');
}
// 6. Reject classic spam keywords
$spam_keywords = ['viagra', 'casino', 'poker', 'cialis', 'tramadol', 'payday loan', 'bitcoin wallet', 'crypto wallet'];
$haystack = strtolower($name . ' ' . $message);
foreach ($spam_keywords as $kw) {
if (strpos($haystack, $kw) !== false) {
log_message('error', 'Contact spam blocked [keyword]: ' . $email);
$this->session->set_flashdata('contact_success', 'Thank you! Your message has been sent.');
redirect('contact', 'refresh');
}
}
// ============================================================
// END SPAM GUARD — clean submission, process normally
// ============================================================
// Save as visitor record (matches your existing system)
$visitor_data = array(
'name' => $name,
'source' => 'Online',
'email' => $email,
'purpose' => 'Contact Form',
'date' => date('Y-m-d'),
'note' => $message . " (Sent from contact form)",
);
$this->Visitors_model->add($visitor_data);
// Send email to the school
$setting_data = $this->setting_model->get();
$school_email = !empty($setting_data[0]['email']) ? $setting_data[0]['email'] : 'ycucampus@gmail.com';
$mail_subject = 'New Contact Form Submission — ' . $name;
$mail_body = "
Name: " . htmlspecialchars($name) . "
";
$mail_body .= "
Email: " . htmlspecialchars($email) . "
";
$mail_body .= "
Message:
" . nl2br(htmlspecialchars($message)) . "
";
$mail_body .= "
Sent from: " . $this->input->ip_address() . "
";
try {
$this->mailer->send_mail($school_email, $mail_subject, $mail_body);
} catch (Exception $e) {
log_message('error', 'Contact email failed: ' . $e->getMessage());
}
$this->session->set_flashdata('contact_success', 'Thank you! Your message has been sent. We will be in touch soon.');
redirect('contact', 'refresh');
}