I was hoping I could solve this myself, but nothing I've tried works.
I've managed to cobble together a contact form using PHPMailer with the option of adding multiple attachments which works perfectly.
However, when I try adding a reCaptcha V2, it gets completely ignored and the contact form submits regardless of whether the Captcha is ticked or not.
I've tried numerous different methods posted online, but these just stop the form from submitting at all.
Could someone please advise where I'm going wrong:
HTML part of form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Contact Us:</title>
<link rel="canonical" href="" />
<link rel="stylesheet" type="text/css" href="css/normalise.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<div class="contact_form_container">
All fields marked with <span class="required">*</span> are required
<form id="form" action="mail-script.php" method="post" enctype="multipart/form-data">
<div class="elem-group">
<label class="form_label">Name <span class="required">*</span></label>
<input class="form-control form-control-name form_field" type="text" name="name" required>
</div>
<div class="elem-group">
<label class="form_label">Company</label>
<input class="form-control form-control-subject form_field" type="text" name="company">
</div>
<div class="elem-group">
<label class="form_label">Email Address <span class="required">*</span></label>
<input class="form-control form-control-email form_field" type="email" name="email" required>
</div>
<div class="elem-group">
<label class="form_label">Phone Number</label>
<input class="form-control form-control-phone form_field" type="tel" name="phone" pattern="\d*">
</div>
<div class="elem-group">
<label class="form_label">Message <span class="required">*</span></label>
<textarea name="message" rows="7" required class="form-control form-control-message form_field">
</textarea>
</div>
<div class="elem-group">
<label class="form_label">Upload Your Files</label>
<input type="file" name="attachment[]" class="form-control" multiple>
</div>
<div class="elem-group">
<label class="form_label"> </label>
<div class="g-recaptcha" data-sitekey="xxxxxx"></div>
</div>
<div class="elem-group">
<label class="form_label cft"> </label>
<button class="btn-primary button" type="submit" value="Send" name="submit" >Send Message</button>
</div>
</form>
</div>
</body>
</html>
PHP
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require './src/Exception.php';
require './src/PHPMailer.php';
require './src/SMTP.php';
class CaptchaTest
{
private $captchaSecretKey = 'XXX';
//call this function and pass in the response value from the form in order to get Google to test the captcha. Will return true or false.
public function testCaptchaResponse($captchaResponse)
{
//generate URL as per Google's documentation
$createGoogleUrl = 'https://www.google.com/recaptcha/api/siteverify?secret='.urlencode($this->captchaSecretKey).'&response='.urlencode($captchaResponse);
//send request to Google and get back the raw JSON response.
$verifyRecaptcha = $this->sendHttpRequest($createGoogleUrl);
//decode the JSON into a PHP array so we can examine individual data items within it
$decodeGoogleResponse = json_decode($verifyRecaptcha,true);
//examine the response from Google and return true/false accordingly.
if($decodeGoogleResponse['success'] == 1) return true;
else return false;
}
//send a HTTP request to the specified URL using cURL
private function sendHttpRequest($url)
{
$ch = curl_init();
$getUrl = $url;
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $getUrl);
curl_setopt($ch, CURLOPT_TIMEOUT, 80);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
//check form button and captcha field were submitted
if(isset($_POST['submit'], $_POST['g-recaptcha-response'])) {
//test the captcha
$cTest = new CaptchaTest();
$captchaResult = $cTest->testCaptchaResponse($_POST['g-recaptcha-response']); }
if ($captchaResult == true) {
$mail = new PHPMailer(true);
$mail->SMTPDebug = 0;
$mail->Host = 'in-v3.mailjet.com';
$mail->SMTPAuth = true;
$mail->Username = 'XXX';
$mail->Password = 'XXX';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom($_POST['email'], $_POST['name']);
$mail->addAddress('[email protected]');
$mail->addReplyTo($_POST['email'], $_POST['name']);
//Attach multiple files one by one
for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
$uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
$filename = $_FILES['userfile']['name'][$ct];
if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
$mail->addAttachment($uploadfile, $filename);
}
}
$mail->isHTML(true);
$mail->Subject = 'Website Enquiry';
$mail->Body = "<p>You received an enquiry from:</p>
<b>Name:</b> $_POST[name]<br><br>
<b>Company:</b> $_POST[company]<br><br>
<b>Phone Number:</b> $_POST[phone]<br><br>
<b>E-Mail:</b> $_POST[email]<br><br>
<b>Message:</b> $_POST[message]";
try {
$mail->send();
header('Location: thank.html');
exit('Redirecting you to thank.html');
} catch (Exception $e) {
echo "Your message could not be sent! PHPMailer Error: {$mail->ErrorInfo}";
}
}
else
{
echo "Captcha failed, please try again";
}
?>
Thanks in advance
$_POST['submit']
.if (!$response->success || !$mail->send());
is gibberish, I've no idea what you think this is doing, but it doesn't do anything (except possibly cause the email to be sent, even though you then send it again later on). You are never verifying the catpcha with google either. You define$url
but do nothing with it. There's no shortage of examples online using PHP and recaptcha to show how you should do this, so I can't really see why you'd be struggling.