405 error with Ajax POST / Nginx configuration - php

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.

Related

How to use php validation in ajax request in wordpress?

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

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')
}
});

Getting PHP AJAX response data with Angular $http Service

I'm sorry if this is repeating previous questions, but i haven't been able to find a solution which seems to work with my problem & im new to Angular.
I have an Angular form, which communicates data with PHP to send an email, and my problem is with handling the JSON response from the PHP (as the PHP communicates back whether it succeeded within the JSON itself, along with a message).
I can't seem to get the code to respond based on the "success" value contained within the JSON, nor actually display the "message.
The JSON response data looks like this (when it fails due to an email issue):
So my angular code needs to respond based on "success" being true or false, while also displaying the "message" which is passed by AJAX in JSON.
My Angular Controller code:
app.controller('ContactController', function ($scope, $http) {
$scope.result = 'hidden'
$scope.resultMessage;
$scope.formData; //formData is an object holding the name, email, subject, and message
$scope.submitButtonDisabled = false;
$scope.submitted = false;
$scope.submit = function(contactform) {
$scope.submitted = true;
$scope.submitButtonDisabled = true;
if (contactform.$valid) {
var request = $http({
method : 'POST',
url : 'php/contact.php',
data : $.param($scope.formData), //param method from jQuery
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
});
if (request.success) {
console.log(request);
$scope.submitButtonDisabled = false;
$scope.result='bg-success';
$scope.resultMessage = request.message;
} else {
$scope.submitButtonDisabled = true;
$scope.resultMessage = request.message;
//$scope.resultMessage = "Opps!... something went wrong. Please Contact OpenHouse directly to let them know of this error.";
$scope.result='bg-danger';
};
//};
} else {
$scope.submitButtonDisabled = false;
$scope.resultMessage = 'Failed <img src="http://www.chaosm.net/blog/wp-includes/images/smilies/icon_sad.gif" alt=":(" class="wp-smiley"> Please fill out all the fields.';
$scope.result='bg-danger';
}
}
});
My PHP Code:
<?php
require_once ("class.phpmailer.php"); // Include phpmailer class
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
if (isset($_POST['inputFirstName']) && isset($_POST['inputLastName']) && isset($_POST['inputEmail']) && isset($_POST['inputPhone']) && isset($_POST['inputMessage'])) {
//check if any of the inputs are empty
if (empty($_POST['inputFirstName']) || empty($_POST['inputLastName']) || empty($_POST['inputEmail']) || empty($_POST['inputPhone']) || empty($_POST['inputMessage'])) {
$data = array('success' => false, 'message' => 'Please fill out the form completely.');
echo json_encode($data);
exit;
}
$message=
'First Name: '.$_POST['inputFirstName'].'<br />
Last Name: '.$_POST['inputLastName'].'<br />
Phone: '.$_POST['inputPhone'].'<br />
Email: '.$_POST['inputEmail'].'<br />
Comments: '.$_POST['inputMessage'].'
';
$mail = new PHPMailer(); // Instantiate the PHPMailer Class
$mail->IsSMTP(); // enable SMTP
$mail->SMTPDebug = 1; // debugging: 1 = errors and messages, 2 = messages only
$mail->SMTPAuth = true; // SMTP authentication enabled
$mail->SMTPSecure = 'ssl'; // secure transfer enabled + REQUIRED for Gmail (either SSL or TLS)
$mail->Host = "smtp.gmail.com"; //Gmail SMTP Server to relay thru
$mail->Port = 465; // Port 465 as we're using SSL... or use Port 587 for TLS
$mail->IsHTML(true); // We're sending a HTML formatted message
$mail->Username = "....#gmail.com"; // Gmail account for authentication
$mail->Password = "*********"; // Gmail password for authentication
$mail->SetFrom("....#gmail.com"); // The email is being sent from this address
$mail->Subject = "Website Contact Form Enquiry"; // The subject line of the email
$mail->Body = ($message); // The actual email message to be sent
$mail->AddAddress("....#gmail.com"); // The email is being sent to this address
if(!$mail->send()) {
echo json_encode(['success' => false, 'message' => 'Message could not be sent. Mailer Error: ' . $mail->ErrorInfo]);
exit;
}
error_log("Data: ".$data['success']." Message: ".$data['message']);
echo json_encode(['success' => true, 'message' => 'Thanks! We have received your message.']);
} else {
echo json_encode(['success' => false, 'message' => 'Please fill out the form completely.']);
}
?>
To start, the $http does not return a request object, it returns a promise that resolves with a response object:
//var request = $http({
//It returns a promise
var promise = $http({
method : 'POST',
url : 'php/contact.php',
data : $.param($scope.formData), //param method from jQuery
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
});
//Use .then method to receive response
promise.then(function (response) {
var request = response.data;
if (request.success) {
console.log(request);
$scope.submitButtonDisabled = false;
$scope.result='bg-success';
$scope.resultMessage = request.message;
}
});
It is important to realize that the $http service immediately returns a pending promise. The promise is later resolved (either fulfilled or rejected) when the response comes back from the server.
Use the .then method of the promise to provide success and rejection handlers that resolve with either the fulfilled or rejected response.
For more information, see: AngularJS $http Service API Reference - General Usage
UPDATE
The AngularJS framework by default encodes and posts using Content-Type: 'application/json'.
To receive JSON data in a PHP backend, do something like:
$json = file_get_contents('php://input');
$obj = json_decode($json);
Then the POST with AngularJS can be simplified:
var promise = $http({
method : 'POST',
url : 'php/contact.php',
//data : $.param($scope.formData), //param method from jQuery
data: $scope.data;
//headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
//Defaults to:
//headers: {'Content-Type': 'application/json'}
});
//Use .then method to receive response
promise.then(function (response) {
var request = response.data;
if (request.success) {
console.log(request);
$scope.submitButtonDisabled = false;
$scope.result='bg-success';
$scope.resultMessage = request.message;
}
});
Thanks everyone for the help;
I was able to return a response after the asyn http call & display it on the screen...
But no matter what i tried, it always packages the HTTP headers with the data, within the data response.
If the PHP didn't send an email (I removed all commands for sending email), then the data response would be just data.
If the PHP did send an email, then the response would be HTTP headers + data within the data response.
So in the end on the Angular side, i converted the data response to a string, split that string based up { which would give me a new string with just the data (and no headers), some extra \separating the values in the string, and obviously and ending }
So thus, by string manipulation, i was able to get the response i wanted.
Here's the working Angular Controller:
app.controller('ContactController', function ($scope, $http) {
$scope.result = 'hidden'
$scope.resultMessage;
$scope.formData; //formData is an object holding the name, email, subject, and message
$scope.submitButtonDisabled = false;
$scope.submitted = false;
$scope.submit = function(contactform) {
$scope.submitted = true;
$scope.submitButtonDisabled = true;
var promise = $http({
method : 'POST',
url : 'php/contact.php',
data : {
firstname: $scope.formData.inputFirstName,
lastname: $scope.formData.inputLastName,
emailid: $scope.formData.inputEmail,
phoneno: $scope.formData.inputPhone,
message: $scope.formData.inputMessage
},
headers : {'Content-Type': 'application/json'}
})
promise.then(function (response) {
var request = JSON.stringify(response.data); //convert JSON data to string for manipulation
var startpos = request.indexOf("{"); //locate '{' as its the start of the data we want
var endpos = request.lastIndexOf("}"); //locate '}' as its the end of the data we want
var res = request.slice(startpos, endpos); //Extract the actual data now we know where it is.
var newresponse = res.split("\\"); //Split the data into new array
var answer = request.search("true"); //search the string to see if it contains the word "true" meaning an email was sent.
if (answer >= 0) {
$scope.submitButtonDisabled = false;
$scope.result='bg-success';
$scope.resultMessage = newresponse[5].replace('"', " ");
} else {
$scope.submitButtonDisabled = true;
$scope.resultMessage = newresponse[5].replace('"', " ");
$scope.result='bg-danger';
}
});
}
});

Form can't submit with remote method in Jquery. I can't submit form

I added form in php with jquery validation.recently i added Remote technique for check email in registration.After the added it my form does not submit. What should i do ?
<script type="text/javascript">
runAllForms();
// Validation
$(function() {
// Validation
$("form_id_name").validate({
// Rules for form validation
rules : {
email : {
required : true,
email : true,
remote: 'page.php' // page where i am checking email from database.
}
},
// Messages for form validation
messages : {
email : {
required : 'Please enter your email address',
email : 'Please enter a VALID email address',
remote: 'This email address is already taken! Try another.'
}
},
// Ajax form submition
submitHandler : function(form) {
$(form).ajaxSubmit({
success : function() {
$("from_id_name").addClass('submited');
}
});
},
// Do not change code below
errorPlacement : function(error, element) {
error.insertAfter(element.parent());
}
});
});
Page.php
<?php
include("connect_file.php"); // connection file
header('Content-type: application/json');
$email = $_REQUEST['email'];
$query=mysql_query("select email_col from table_name where email_col = '$email' ");
if (mysql_num_rows($query) == 0) {
$output = 'true';
}
else {
$output = 'false';
}
echo $output;
?>
What should i do ? I am begginer for jquery. please help me.

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.

Categories