How to use php validation in ajax request in wordpress? - php

I made a contact form(custom) that uses AJAX to send out the message. Now I am unclear on how to validate the form.
AJAX Request:
$("#contact-form").on("submit", function (e) {
e.preventDefault();
var action = "contact_form";
$("#submit, #clear").prop("disabled", true);
$("#submit").html("Sending");
$.ajax({
url: $(this).attr("action"),
method: "post",
data: {
name: $("#name").val(),
email: $("#email").val(),
phone: $("#phone").val(),
subject: $("#subject").val(),
message: $("#message").val(),
action: action,
},
success: function () {
$("header").append(
"<div id='alert' class='alert alert-success alert-dismissible fixed-top' role='alert' >" +
"<p class='text-center'>Success</p>" +
"<button type = 'button' class='close' data-dismiss = 'alert'>×</button>" +
"</div>"
);
$("#submit, #clear").prop("disabled", false);
// $("#contact-form input,textarea").val("");
grecaptcha.reset();
$("#submit").html("Send");
},
error: function () {
$("header").append(
"<div id='alert' class='alert alert-danger alert-dismissible fixed-top' role='alert' >" +
"<p class='text-center'>Error</p>" +
"<button type = 'button' class='close' data-dismiss = 'alert'>×</button>" +
"</div>"
);
$("#submit, #clear").prop("disabled", false);
grecaptcha.reset();
$("#submit").html("Send");
},
});
});
});
Functions.php:
function contact_form() // this is the action data variable we set in ajax
{
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// preparing parameters for wp_mail();
$to = "mail#example.com";
$msg = "
Name: $name
Email: $email
Phone: $phone
$message
";
// sending mail using wp_mail function
wp_mail($to, $subject, $msg);
wp_die(); // must use wp_die() to avoid unwanted output from wordpress
}
// in first parameter prefix function name with wp_ajax_
// this action is required in order to recieve data sent from ajax
add_action( 'wp_ajax_contact_form', 'contact_form' );
add_action( 'wp_ajax_nopriv_contact_form', 'contact_form' );
Now what I usually do when I am not trying to use ajax is preform validaiton in the php file and for example if captcha is invalid I append status to GET method and return error. If anyone can point me in the right directon on how to validate in php file and return info to frontend or should I do the validation in the js file? I'm quite confused there is so many articles on the web I honestly have no idea where to look.
P.S Everything is working perfectly just left to validate it.

Validate both ways. JS validation makes for a smooth UX and takes care of most concerns regarding valid email addresses, non-empty fields etc.
PHP validation will ensure that your functions don't error out and can allow you to do some server side checks (like exact message hasn't been sent before etc)
In php, do your validation checks and prepare a json response of any errors, then echo that back (rather than proceed with the code) if there are errors. In JS catch the errors in your success block - which right now doesn't listen for any response.
PHP:
if ($errors) {
echo json_encode(array('status' => 'error', 'message' => 'Your email message has objectionable content'));
wp_die();
}
if (!wp_mail($to, $subject, $msg)) {
echo json_encode(array('status' => 'error', 'message' => 'Your email message did not send for some reason'));
wp_die();
}
echo json_encode(array('status' => 'success');
wp_die();
Your JS
// ajax...
$.ajax({
... your props
dataType: 'json',
success: function (response) {
if (response && response.status == 'error'){
$('errors').html("Sorry, your message did not get sent due to these errors: " + response.message);
return;
} else {
// .. success

Related

405 error with Ajax POST / Nginx configuration

I'm trying to send email with an Ajax form and swiftmailer. It works in local but not in production.
When contact_me.php takes parameters not from form but written explicitly the email is sent even from the server so I think Swiftmailer is working.
contact_me.js
// Contact Form Scripts
$(function() {
$("#contactForm input,#contactForm textarea").jqBootstrapValidation({
preventSubmit: true,
submitError: function($form, event, errors) {
// additional error messages or events
},
submitSuccess: function($form, event) {
event.preventDefault(); // prevent default submit behaviour
// get values from FORM
var name = $("input#name").val();
var email = $("input#email").val();
var phone = $("input#phone").val();
var message = $("textarea#message").val();
var firstName = name; // For Success/Failure Message
// Check for white space in name for Success/Fail message
if (firstName.indexOf(' ') >= 0) {
firstName = name.split(' ').slice(0, -1).join(' ');
}
$.ajax({
url: "././mail/contact_me.php",
type: "POST",
data: {
name: name,
phone: phone,
email: email,
message: message
},
dataType: "text",
cache: false,
success: function() {
// Success message
},
error: function() {
// Fail message
},
});
},
filter: function() {
return $(this).is(":visible");
},
});
$("a[data-toggle=\"tab\"]").click(function(e) {
e.preventDefault();
$(this).tab("show");
});
});
/*When clicking on Full hide fail/success boxes */
$('#name').focus(function() {
$('#success').html('');
});
contact_me.php
<?php
// Autoload for swiftmailer
require_once '../vendor/autoload.php';
// Check for empty fields
if(empty($_POST['name']) ||
empty($_POST['email']) ||
empty($_POST['phone']) ||
empty($_POST['message']) ||
!filter_var($_POST['email'],FILTER_VALIDATE_EMAIL))
{
echo "No arguments Provided!";
return false;
}
$name = strip_tags(htmlspecialchars($_POST['name']));
$email_address = strip_tags(htmlspecialchars($_POST['email']));
$phone = strip_tags(htmlspecialchars($_POST['phone']));
$message = strip_tags(htmlspecialchars($_POST['message']));
// Create the email and send the message
$email_subject = "TrustPair nouveau contact : $name";
$email_body = "New form.\n\n"."Here are the details:\n\nName: $name\n\nEmail: $email_address\n\nPhone: $phone\n\nMessage:\n$message";
// Add here swiftmailer code, need to return true
// Create the Transport
$transport = (new Swift_SmtpTransport('mail.gandi.net', 465, "ssl"))
->setUsername('name#domain.com')
->setPassword('password')
;
// Create the Mailer using your created Transport
$mailer = new Swift_Mailer($transport);
// Create the message
$message = (new Swift_Message())
// Give the message a subject
->setSubject($email_subject)
// Set the From address with an associative array
->setFrom(['noreply#domain.com' => 'Domain no reply'])
// Set the To addresses
->setTo(['firstmailto#gmail.com', 'secondmailto#gmail.com'])
// Give it a body
->setBody($email_body)
;
// Send the message
$result = $mailer->send($message);
echo $result;
// result is equal to the nbr of message recipients
if ($result == 0) {
return false;
} else {
return true;
}
?>
Nginx server doesn't allow POST request with static page (ie. *.html).
There are hacks to handle the problem. In my case, it fix the 405 error but the emails weren't send.
The solution was to change the index.html to index.php, be sure to adapt your Nginx configuration to reflect this changes.

jQuery ajax post doesn't redirect to php page

I have a contact form on my website with a jQuery ajax call, but I don't see the .php page when I click on the button.
Here's the ajax call:
var data = {
name: $("input.userName").val(),
email: $("input.userEmail").val(),
tel: $('input.userPhone').val(),
message: "Projet de "+$("input.userName").val() + ", Tel : " + $('input.userPhone').val(),
body: body
};
$.ajax({
type: "POST",
url: "acerola.php",
data: data,
success: function(data){
console.log('ajax sucessfully sent');
}
});
With acerola.php:
<html>
<head><title>PHP Mail Sender</title></head>
<body>
<h1>OUIIiiii</h1>
<?php
echo "<h1>Coucou</h1>";
/* All form fields are automatically passed to the PHP script through the array $HTTP_POST_VARS. */
$name = $HTTP_POST_VARS['name'];
$email = $HTTP_POST_VARS['email'];
$tel = $HTTP_POST_VARS['tel'];
$message = $HTTP_POST_VARS['message'];
$body = $HTTP_POST_VARS['body'];
/* PHP form validation: the script checks that the Email field contains a valid email address and the Subject field isn't empty. preg_match performs a regular expression match. It's a very powerful PHP function to validate form fields and other strings - see PHP manual for details. */
if (!preg_match("/\w+([-+.]\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*/", $email)) {
echo "<h4>Invalid email address</h4>";
echo "<a href='javascript:history.back(1);'>Back</a>";
} elseif ($subject == "") {
echo "<h4>No subject</h4>";
echo "<a href='javascript:history.back(1);'>Back</a>";
} elseif ( /* Sends the mail and outputs the "Thank you" string if the mail is successfully sent, or the error string otherwise. */
mail("plu#gmail.com", "Demande de devis web", $message . $body, "From:" . $email)
) {
echo "<h4>Thank you for sending email</h4>";
echo "<div>Thank you for sending email</div>";
} else {
echo "<h4>Can't send email to $email</h4>";
}
?>
</body>
</html>
I would like the user to be redirected to acerola.php. But the user stays on the original page.
After the ajax response, fire a redirect with javascript.
$.ajax({
type: "POST",
url: "acerola.php",
data: data,
success: function(data){
console.log('ajax sucessfully sent');
window.location.replace('URL HERE')
}
});

How to redirect successful form submission to another page in PHP [duplicate]

This question already has answers here:
Redirect PHP contact form to another page upon success [closed]
(3 answers)
Closed 8 years ago.
How can I redirect to another page in PHP upon successful form submission?
Right now I have the code that shows a Green Message under Submit button: Your message was successfully submitted!
I'd like to redirect to success.php and in case of an error to resubmit.php
//try to send a message
if(mail(MY_EMAIL, EMAIL_SUBJECT, setMessageBody($fields_req), "From: $email")) {
echo json_encode(array('message' => 'Your message was successfully submitted.'));
} else {
header('HTTP/1.1 500 Internal Server Error');
echo json_encode(array('message' => 'Unexpected error while attempting to send e-mail.'));
}
When I use:
{
header('location: success.php');
}
else {
header('location: resubmit.php');
}
I'm getting an error message here: Uncaught type error: Cannot read property 'message' of undefined. It shows up under the contactform.addAjaxMessage. Do I need to update that code as well? This is my contact-form.js file:
$(document).ready(function() {
$("#feedbackSubmit").click(function() {
//clear any errors
contactForm.clearErrors();
//do a little client-side validation -- check that each field has a value and e-mail field is in proper format
var hasErrors = false;
$('#feedbackForm input,textarea').not('.optional').each(function() {
if (!$(this).val()) {
hasErrors = true;
contactForm.addError($(this));
}
});
var $email = $('#email');
if (!contactForm.isValidEmail($email.val())) {
hasErrors = true;
contactForm.addError($email);
}
var $phone = $('#phone');
if (!contactForm.isValidPhone($phone.val())) {
hasErrors = true;
contactForm.addError($phone);
}
//if there are any errors return without sending e-mail
if (hasErrors) {
return false;
}
//send the feedback e-mail
$.ajax({
type: "POST",
url: "library/sendmail.php",
data: $("#feedbackForm").serialize(),
success: function(data)
{
contactForm.addAjaxMessage(data.message, false);
//get new Captcha on success
$('#captcha').attr('src', 'library/securimage/securimage_show.php?' + Math.random());
},
error: function(response)
{
contactForm.addAjaxMessage(response.responseJSON.message, true);
}
});
return false;
});
});
//namespace as not to pollute global namespace
var contactForm = {
isValidEmail: function (email) {
var regex = /^([a-zA-Z0-9_.+-])+\#(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
},
/**
* Validates that phone number has 10 digits.
*
* #param {String} phone phone number to validate
* #return {Boolean} if phone number is valid
*/
isValidPhone: function (phone) {
phone = phone.replace(/[^0-9]/g, '');
return (phone.length === 10);
},
clearErrors: function () {
$('#emailAlert').remove();
$('#feedbackForm .help-block').hide();
$('#feedbackForm .form-group').removeClass('has-error');
},
addError: function ($input) {
$input.siblings('.help-block').show();
$input.parent('.form-group').addClass('has-error');
},
addAjaxMessage: function(msg, isError) {
$("#feedbackSubmit").after('<div id="emailAlert" class="alert alert-' + (isError ? 'danger' : 'success') + '" style="margin-top: 5px;">' + $('<div/>').text(msg).html() + '</div>');
}
};
You can simple use header function:
Success case:
Header('location:success.php');
Error case:
Header('location:error.php');
Easy! Just use the PHP header function like so. Just be sure to replace the value of success.php with the actual final location you want users to end up in:
//try to send a message
if(mail(MY_EMAIL, EMAIL_SUBJECT, setMessageBody($fields_req), "From: $email")) {
// echo json_encode(array('message' => 'Your message was successfully submitted.'));
header('Location: success.php');
exit;
} else {
header('HTTP/1.1 500 Internal Server Error');
echo json_encode(array('message' => 'Unexpected error while attempting to send e-mail.'));
}
You can also set the specific HTTP response code by changing this:
header('Location: success.php');
To this:
header('Location: success.php', false, 200);
The 200 response code means “OK” which means the page will be loaded as expected; 100% OK. But you might want to change that to 302 which means the URL has moved temporarilly.

Ajax process PHP form with different results from multiple conditionals

I've currently got a working form right now that just uses a conditional to check if it's been submitted and processes the form on the same page: https://gist.github.com/adrianrodriguez/48cd90067a63691adc6a
But obviously the caveat is that it refreshes the page. Which in reality is fine, I just used a little bit of JS to fadeIN the results after the form echos it with
style="display:none"
And that's sorta fine...but I want to spice it up and use ajax.
Below is the js without ajax (just using validation.js for validating)
JS UPDATED WITH ANSWER
$(document).ready(function(){
// Jquery Form Functions
$('#redeem').validate( { // initialize the plugin
rules: {
fullname: {
required: true
},
cardnumber: {
required: true,
digits: true
},
email: {
email: true,
required: true
},
confirmation: {
email: true,
required: true,
equalTo: "#email"
}
},
invalidHandler: function (event, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
var message = "<p>All fields in red must be filled*</p>";
$("#redeem .message").html(message);
$("#redeem .message").show();
} else {
$("#redeem .message").hide();
}
},
submitHandler: function (form) { // for demo
//form.submit();
$.ajax({
url: form.action,
type: form.method,
data: $(form).serialize(),
dataType: "json", // Recognize JSON Data
success: function(data) {
$.each(data, function(key, value) {
// Loop with key and value from conditional
console.log(key + " " + value);
});
}
});
return false;
}
});
if ($('.result')) {
$('.result').fadeIn(400);
}
});
I know how to process with ajax using:
$.ajax({
url: form.action,
type: form.method,
data: $(form).serialize(),
success: function(data) {
console.log(data);
}
});
return false;
And it works fine, but the problem I run into is when I want to echo specific strings based on some of the conditionals in the form.
A) I can't echo the information out since the form is separate from the page it's processed on...
B)...and I don't know how to pull in that information to the current page it's being processed on.
Is this even possible? If so, how? Or do I just need to stay with what I have going on now?
Here is a video of what I have working now (without ajax): http://screencast.com/t/196P9ugso2L and notice how if a page is long it won't feel like the form is being processed real time (instead of refresh). Like I said, in all honestly, I just want to give a better user experience and spice things up.
UPDATE
PHP with array (which I think I am doing wrong, I tried three different ways, all failing noob style).
<?php
include('db-connect.php');
$fullname = $_POST['fullname'];
$email = $_POST['email'];
$cardnumber = $_POST['cardnumber'];
$select = "SELECT * FROM cardholders WHERE cardnumber = $cardnumber";
$selectfrom = mysql_query($select);
if ($info = mysql_fetch_assoc($selectfrom)) {
if ($fullname == $info['name'] && $info['used'] == 0) {
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
// $headers .= 'CC: $email' . "\r\n";
$headers .= 'From: Comanche Nation Casinos <no-reply#comanchenationcasinos.com>';
$confirmation = '<h1>Hi ' . $info['name'] . ' you\'ve won <b>$' . $info['amount'] . '</b> in Comanche Credit!</h1>
<p>Thank you for being such a valuable C Club member. Print or Show this email and redeem this at your Comanche Nation Casino.</p>
<p>Save this email just incase something happens so that the staff can ensure your reward at the kiosk.</p>';
// mail("web#icgadv.com", "Care Center Gala Sponsorship Request", $staff, $headers);
// mail($email, "Care Center Gala Sponsorship Request Confirmation", $confirmation, $headers);
// $message = "<p>Congratulations!" . $info['name'] . "!</p> <p>You've won! Please check your email for your winnings and futher information.</p>";
$winner = true;
$message = array( 'winner' => true, 'message' => 'This is a test');
$updateUser = "UPDATE cardholders SET email='$email', used=1 WHERE cardnumber = $cardnumber";
$update = mysql_query($updateUser);
} else if ($fullname != $info['name'] && $info['used'] == 0) {
// $message = "Sorry but your name does not match the name in our database.";
$noname = true;
$message = array( 'winner' => true, 'message' => 'This is a test');
} else {
// $string = "<p>Sorry but this offer has already been redeemed to this account</p>";
$redeemed = true;
$message = array( 'winner' => true, 'message' => 'This is a test');
}
} else {
// $message = array( 'status' => true, 'message' => "<p>Sorry but this card number does not exist.</p>" );
$invalid = true;
$message = array( 'winner' => true, 'message' => 'This is a test');
}
echo json_encode($message);
?>
As #TomToms posted above the problem is you need to pass a result back from the Ajax page called, the one processing. As mentioned, you do this using a JSON array. I will give you a brief example of this below:
$.ajax({
url: form.action,
type: form.method,
data: $(form).serialize(),
dataType: "json",
success: function(data) {
console.log(data);
}
});
Note the added dataType, this states you are expecting a JSON string back, and will convert it into an array in data for you.
On you processing page, the form.action you would have this:
// ... code that loads form information and all your current processing.
$example = array(
'prize' => true, // true or false on whether they get the prize.
'status' => 'Show Status Message' // put any message for the show status box here.
);
echo json_encode($example);
Now if you look in console at the end data will be an object with the prize and status in it.
I'd also recommend you have a look through the JSON website for more information on JSON.
If I understand your question correctly what you need is to send back a JSON array with a status code for each field or something along those lines and then parse that in your javascript to warn the user appropriately.
As per documentation, .ajax() always goes inside of the submitHandler callback function.
Replace this...
submitHandler: function (form) { // fires on submit when form is valid
form.submit(); // regular submit action
}
With something like this...
submitHandler: function (form) { // fires on submit when form is valid
$.ajax({
url: $(form).action,
type: $(form).method,
data: $(form).serialize(),
success: function(data) {
console.log(data);
}
});
return false; // block the default form action
}

Why is this ajax call to the correct php script not returning anything?

I have this AJAX:
function sendMail () {
$.post('php/sendMail.php', function(result){
alert(result);
})
}
$('#submitContact').click(function(){
sendMail();
})
and this PHP:
<?php
$trimmed = array_map('trim', $_POST);
$message = $trimmed['message'];
$email = $trimmed['email'];
$name = $trimmed['name'];
if (empty($message)) {
$message = FALSE;
}
if (empty($email)) {
$message = FALSE;
}
if (empty($name)) {
$message = FALSE;
}
if ($message && $email && $name){
$body = "From: $name.\n \n $message";
mail(/*some email*/, 'Website Contact Form Submission', $body, "From: $email");
echo ('success');
}
echo($message.' '.$email.' '.$name);
?>
All the html elements defined exist. When I run it all that returns is a blank alert box (meaning that the PHP script did not print out success). Any idea why it is not sending the mail?
You don't appear to be sending any data with your POST.
If you're trying to submit a form, try this:
$.post('php/sendMail.php',$('form').serialize(), function(result){
alert(result);
})
Edit: As Tomalak rightly points out in the comments, you'll need to specify which form you are serializing. I'd normally give the form an id and use that:- $('#myform').serialize()
You're not sending any data to that URL.
The reason you are seeing an empty alert box is because $email and $name is empty because you didn't pass any $_POST variable.
And $message = FALSE is blank when you echo it.
Try changing this line
echo($message.' '.$email.' '.$name);
To
var_dump($message.' '.$email.' '.$name);
And you'll see the value of $message.' '.$email.' '.$name.
Any idea why it is not sending the mail?
Put simply, you didn't ask it to.
The syntax for $.post is:
jQuery.post( url, [data,] [success(data, textStatus, jqXHR),] [dataType] )
The way jQuery works, you may skip the data argument and still provide the following ones, but in this case you're simply not passing any data for your PHP script to work with.
Assuming that #submitContact is a button in the form that you want to submit, you should serialise that form's contents and send that as the POST data:
function sendMail($form) {
$.post('php/sendMail.php', $form.serialize(), function(result) {
alert(result);
});
}
var $btn = $('#submitContact');
var $frm = $btn.parents('form');
$btn.click(function() {
sendMail($frm);
});
The documentation is your friend. Use it.
(Note: The $ at the start of some of my variables is deliberate; it's a personal choice that jQuery objects have names starting with $ in my code.)

Categories