Script Captures Duplicate E-mail Entry in Database, but Doesn't Display User-end Msg

Hello everyone,

I’m back with another brain buster! :idea:

This time, I’m checking the database using a PDO connection for a duplicate email address in a column, emailaddress. The problem is not in finding out if the e-mail address is a duplicate entry. The problem is displaying the error message to the user (not just seeing it in Firebug).

All the other error messages this script detects are properly appended to a <p> element with an i.d. of errormessage. For some strange reason, this error goes unpublished and the form just sits there on submission. For example, if the user doesn’t input a name, an error message will appear saying, “Please enter a name”.

Here’s why I know the query and the detection of the duplicate entry is not the issue. I had set up the script to echo the variable, $dbCode, which is used to detect the results of the database writing. 3 corresponds to the e-mail being a duplicate (as you’ll see), and that is what is being returned and echoed into Firebug/developer tools. Not only that, but the error message reads, “That e-mail address already exists”, just like it should, as well as validation set to failure and database set to failure in my $response array that is sent back to JavaScript. :rolleyes: Everything seems in place!

confirmform.php (the file called by JavaScript):


<?php
	$instance = new CheckForm;
	$instance -> checkSubmission();
	
	class CheckForm
	{
		public function checkSubmission()
		{	
			$origEmail = $_POST['origEmail'];
			$confirmEmail = htmlspecialchars($_POST['confirmEmail']);
			$name = htmlspecialchars($_POST['name']);
			$ageRange = $_POST['age'];
			$gender = $_POST['gender'];
			$country = $_POST['country'];
			$catcher = htmlspecialchars($_POST['catcher']);
			$mathAnswer = htmlspecialchars($_POST['addition']);
			$rightAnswer = $_POST['mathAnswer'];
			$submissionTime = $_POST['submissionTime'];
			$status = 0;
		
			$response = array("validation" => " ", "message" => " ", "database" => " ");
			
			if (empty($confirmEmail) && empty($name) && $country === "Select Country") {
				$response['message'] = "That's not a valid submission.";
			} elseif (empty($confirmEmail) && $country === "Select Country"){
				$response['message'] = "Please confirm your e-mail and select a location.";
			} elseif (empty($name) && $country === "Select Country"){
				$response['message'] = "Please enter a name and select a location.";
			} elseif (empty($name)) {
				$response['message'] = "Please enter a name.";
			} elseif (empty($confirmEmail)) {
				$response['message'] = "No confirmation e-mail was entered.";
			} elseif ($origEmail != $confirmEmail) {
				$response['message'] = "E-mail addresses don't match.";
			} elseif ($country === "Select Country") { 
				$response['message'] = "Please select a location.";
			} elseif ($mathAnswer != $rightAnswer) {
				$response['message'] = "Math answer is incorrect.";
			} elseif (!empty($catcher)) {
				$response['message'] = "Bot submission.";
			} elseif ($submissionTime <= 8000) {
				$response['message'] = "Woah! Slow down and fill out the form.";
			} else
				$status = 1;
				
			if ($gender === "Male")
				$gender = "M";
			elseif ($gender === "Female")
				$gender = "F";
			else
				$gender = NULL;

			
			if ($status === 1) {
				require_once("categoryfinder.php");
				$categoryFinder = new CategoryFinder;
				$category = $categoryFinder -> getCategory();
				$response['validation'] = "pass";
				$response['message'] = "Thanks for joining the e-mail list, <b>" . $name . "</b>, under the e-mail address, <b>" . $confirmEmail . "</b>.";
						
				require_once('databasewriter.php');
				$dbWriter = new DatabaseWriter;
				$dbCode = $dbWriter -> writeUserToDatabase($confirmEmail, $name, $ageRange, $gender, $country, $category);
				

                               // I BELIEVE THE PROBLEM IS HERE SOMEWHERE
				if ($dbCode === 1) {
					$response['database'] = "pass";
					echo 'Database Write Successful';
				} else {
					$response['database'] = "fail";
					$response['validation'] = "fail";
					echo 'Database Write Failure';
				}
				if ($dbCode === 2) {
					$response['message'] = "Server error. Please try again later.";
				} elseif ($dbCode === 3) {
					$response['message'] = "That e-mail address already exists.";
				}
			}
		
			echo json_encode($response);
		}
	}
?>

databasewriter.php


<?php
	class DatabaseWriter
	{
		public function writeUserToDatabase($email , $name , $age , $gender , $country , $category)
		{	
			$host = 'test.testmysql.com';
			$dbname = 'testname';
			$user = 'testusername';
			$pass = 'mypassword';
			
			$connection = new PDO("mysql:host=" . $host . ";dbname=" . $dbname, $user, $pass);
			
			try {
				$connection -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
				$statement = $connection -> prepare("INSERT INTO emailcollection (emailaddress, name, age, gender, country, category) VALUES (:emailaddress, :name, :age, :gender, :country, :category)");
				$statement -> bindValue(':emailaddress', $email);
				$statement -> bindValue(':name', $name);
				$statement -> bindValue(':age', $age);
				$statement -> bindValue(':gender', $gender);
				$statement -> bindValue(':country', $country);
				$statement -> bindValue(':category', $category);
				$statement -> execute();
		
				return 1;
			}catch (PDOException $e){
				$dupeQuery = $connection -> prepare("SELECT * FROM emailcollection WHERE emailaddress = '" . $email . "'");
				$dupeQuery -> execute();
				$number = $dupeQuery -> rowCount();
				echo ' number of rows:     ' . $number . '    ';
				if ($number > 0){
					return 3;
				} else {
					//echo $e -> getMessage();
					return 2;
				}
			}
			$connection = NULL;
		}
	}
?>

Many thanks,
Tyler

Admins, I am not comfortable with my password and database information floating out here. Can it be edited out or removed?

I will P.M. some admin to see if this is possible. Shoot! I forgot to take it out!

Done. :slight_smile:

So where’s the javascript that’s meant to handle this page output? You’ve already told us the code is returning correctly, so your problem must be in your javascript’s handling of the return.

Hi, StarLion, and thanks for your reply. Here is the JavaScript that the PHP receives its data from, you will want to look at the function, TestSecondResults(), :


<script type="text/javascript"> 
	$("#go").focus(function(){
		if ($("#go").val() == $("#go").prop('defaultValue')){
			$("#go").val('');
		}
	});
 
	$("#go").on('focus blur', function(e) {
	  var v = $(this).val()
	  if (e.type == "focus"){
		v = (v == "your e-mail")? "" : v;
	  } else {
		v = (v == "")? "your e-mail" : v;
	  }
	  $(this).val(v);
	});
      
      //this is the function called by the success value of the first .ajax() call
      function testFirstResults(response){
        if (response.indexOf("Submission Successful") != -1){
		  $("#blackoverlay").fadeIn(400);
          $("#submissionform").fadeIn(400);
        } else if (response.indexOf("Invalid E-mail") != -1){
          //alert("Invalid mail");
		  $("#invalidemail").animate({"top": "+=36px"}, 700);
		}
      }
	  
	  function testSecondResults(data){
	  	if (data['validation'] == "pass"){
			$("#submissionform").css("display", "none");
			$("#submitstatus p").append(data['message']);
			$("#submitstatus").css("display", "block").delay(1400).fadeOut(800);
			$("#blackoverlay").delay(1400).click(function(e){
				$("#blackoverlay").remove();
				$("#submitstatus").remove();
			}).fadeOut(800);
			$("#submitstatus h3").append("Submission Successful");
			$("#emailbox input").each(function(){
                $(this).prop("disabled", "disabled");
            });
		} else {
			$("#errormessage").empty().append(data['message']);
		}
	  }
	  
	  var mathAnswer = 0;
	  var startTime = 0;
	  var endTime = 0;
	  var submissionTime;
	  
	  function generateEquation(){
	  	var num1 = Math.floor(Math.random() * 5) + 1;
		var num2 = Math.floor(Math.random() * 5) + 1;
		mathAnswer = num1 + num2;
		$("#math").append("What is " + num1 + " + " + num2 + "?");
	  }
	  
      $(document).ready(function(){
		
		generateEquation();
		
        $("#emailbox").submit(function(e){
		  startTime = jQuery.now();
		
          e.preventDefault();
          $.ajax({
            type: $(this).attr('method'),
            dataType: 'html',
            cache: false,
            url: "Scripts/emailtester.php",
            data: $(this).serialize(),
            success: function(data){
              testFirstResults(data);
			}
          });
        });
		
		$("#submissionform").submit(function(e){
			var origEmail = $('#go').val();
			var confirmEmail = $("#confirmemail").val();
			var name = $("#name").val();
			var age = $("#age").val();
			var gender = $("#gender").val();
			var country = $("#country").val();
			var catcher = $("#aicatcher").val();
			var addition = $("#addition").val();
			endTime = jQuery.now();
			submissionTime = endTime - startTime;
			
			e.preventDefault();
		
			$.ajax({
			  type: "POST",
			  dataType: 'json',
			  cache: false,
			  url: "Scripts/confirmform.php",
			  data: { origEmail: origEmail,
			        confirmEmail: confirmEmail,
					name: name,
					age: age,
					gender: gender,
					country: country,
					catcher: catcher,
					addition: addition,
					mathAnswer: mathAnswer,
					submissionTime: submissionTime },
			  success: function(data){
				  testSecondResults(data);
			  }
			});
		});
		
		$("#cancel").click(function(){
			$("#blackoverlay").fadeOut(300);
			$("#errormessage").empty();
			$("#submissionform").fadeOut(300);
		});
      });
</script>

Much thanks.

Hi etidd,

Add the following line to the top of TestSecondResults() function:

console.log(data);

i.e.

function testSecondResults(data){
  console.log(data);
  if (data['validation'] == "pass"){
    ...

Then submit your form with an email address that already exists in your DB and post the output of the above line here.
That way we can see what the PHP script is passing back to the JS and pinpoint what is causing the error.

Hi, Dave.

So, I seem to think now that the entire testSecondResults() function is not running at all. I put that console log statement along with an alert with a bunch of gibberish just so I would know if it is running- it is not appearing after I submit the form; hence, it’s not running. I’m not getting anything new back returned into the console that I haven’t seen already.

database code: 3 Database Write Failure {“validation”:“fail”,“message”:“That e-mail address already exists.”,“database”:“fail”}


	  function testSecondResults(data){
		alert('blah blah blah blah blah blah blah');
	  	console.log(data);
		if (data['validation'] == "pass"){
			$("#submissionform").css("display", "none");
			$("#submitstatus p").append(data['message']);
			$("#submitstatus").css("display", "block").delay(1400).fadeOut(800);
			$("#blackoverlay").delay(1400).click(function(e){
				$("#blackoverlay").remove();
				$("#submitstatus").remove();
			}).fadeOut(800);
			$("#submitstatus h3").append("Submission Successful");
			$("#emailbox input").each(function(){
                $(this).prop("disabled", "disabled");
            });
		} else {
			$("#errormessage").empty().append(data['message']);
		}
	  }

I had a hunch that this was the case since it’s been a long time since I saw the successful submission animation run if the submission was valid and database writing worked.

By the way, what tag are you using for enclosing JavaScript code?

If I submit a valid entry, it doesn’t display the success message and all the other things if it is a valid submission, but if I fill out the form with invalid info, the alert message will pop up and the error message displayed.

Also, I tried setting a breakpoint in Chrome Developer Tools on the line:


if (data['validation'] == "pass")

Then I tried using the forms as usual, and nothing seemed to happen. I didn’t know what to try next; so, I right-clicked that line and chose “Evaluate in console” which returned: SyntaxError: Unexpected end of input

I don’t know if this info is of any value.

Ok, let’s have a look at what te AJAX request is doing.

I’m assuming the server is reachable.

You currently have:

$.ajax({
  type: "POST",
  dataType: 'json',
  cache: false,
  url: "Scripts/confirmform.php",
  data: { origEmail: origEmail,
        confirmEmail: confirmEmail,
    name: name,
    age: age,
    gender: gender,
    country: country,
    catcher: catcher,
    addition: addition,
    mathAnswer: mathAnswer,
    submissionTime: submissionTime },
    success: function(data){
  testSecondResults(data);
  }
});

Change it to this:

$.ajax({
  type: "POST",
  dataType: 'json',
  cache: false,
  url: "Scripts/confirmform.php",
  data: { 
  origEmail: origEmail,
  confirmEmail: confirmEmail,
  name: name,
  age: age,
  gender: gender,
  country: country,
  catcher: catcher,
  addition: addition,
  mathAnswer: mathAnswer,
  submissionTime: submissionTime 
  },
  success: function(data) {
    alert("success");
    console.log(data);
  },
  error: function(data) {
    alert("error");
    console.log(data);   
  },
  complete: function() {
    alert("done");
  }
});

Then try submitting your form.

What happens when you submit valid data?
What happens when you submit invalid data?

The tag is


You can also hit "Go Advanced" in the WYSIWYG editor, highlight a portion of text, then select the appropriate language from the dropdown entitled "Syntax".

I changed the .ajax() request to what you posted, but I also put in a call to testSecondResults() in the success call.

If I put a valid submission on everything, I get the alert message of ‘error’. When using a unique e-mail not already in the database, the user’s data is written (success) but the AJAX call is an overall failure and won’t display what it should do as coded in testSecondResults().

If I do an invalid submission, the AJAX request is successful, and I see the success alert message. :unhappy:

This all seemed to be going wrong soon after I got the database writing set up.

It may mean that it does not like how my PHP is set up for some reason. If you look at confirmform.php, you’ll notice that all the common errors (no name, no e-mail submitted to compare to, no location set), those are all caught in the massive if-elseif block near the beginning. If the submission appears to be valid, a variable named $status is set to 1 and the following code is executed, which given the current behavior, may be where the problem is stemming from.


if ($status === 1) {
				require_once("categoryfinder.php");
				$categoryFinder = new CategoryFinder;
				$category = $categoryFinder -> getCategory();
				
				$response['validation'] = "pass";
				$response['message'] = "Thanks for joining the e-mail list, <b>" . $name . "</b>, under the e-mail address, <b>" . $confirmEmail . "</b>.";
						
				require_once('databasewriter.php');
				$dbWriter = new DatabaseWriter;
				$dbCode = $dbWriter -> writeUserToDatabase($confirmEmail, $name, $ageRange, $gender, $country, $category);
				
				echo '    database code: ' . $dbCode;
				if ($dbCode === 1) {
					$response['database'] = "pass";
					echo 'Database Write Successful';
				} else {
					$response['database'] = "fail";
					$response['validation'] = "fail";
					echo 'Database Write Failure';
				}
				if ($dbCode == 2) {
					$response['message'] = "Server error. Please try again later.";
				} elseif ($dbCode == 3) {
					$response['message'] = "That e-mail address already exists.";
				}
			}
		
			echo json_encode($response);
		}
	}

Many thanks as always.

Hi again,

So, it seems that your immediate problem is that the AJAX call with valid form data is returning an error.

In your $.ajax(), try replacing this:

error: function(data) {
    alert("error");
    console.log(data);   
}

With this:

error: function(jqXHR, textStatus, errorThrown) {
  console.log(textStatus, errorThrown);
}

Then submit the form with valid data and post back here with what is logged to the console.

This is what I just received in Firebug:

parsererror

SyntaxError: JSON.parse: unexpected character

return window.JSON.parse( data );

Ah, there’s the problem.
The $response string you are passing to the json_encode function is somehow malformed.

Change this:

echo json_encode($response);

to this:

echo ($response);

then the AJAX call should return successfully.

Make sure your success callback looks like this:

success: function(data) {
  alert("success");
  console.log(data);
},

Then submit the form again with valid form data and post back here with what is logged to the console (it should just be the string that the PHP script is trying to convert to JSON).

My goodness gracious…
I would love to say that worked, but I’m seeing the exact same error message posted in the console. What I’m seeing echoed back says “Array” instead of {“validation” : “pass”, “message”: "Thanks for signing up… etc.

Is there a little arrow by the array indicating that you can “open it up” and inspect its elements?

No, more precisely, the script is just returning the text.

“Database Write SuccessArray”

I looked at it in Chrome to see if it said anything different. I got the same error, plus it said “Unexpected token D”

OK.

You have a couple of syntax errors in your code from post 11.

Maybe you were just editing stuff for the purposes of posting it here, but let’s eliminate that as a cause of the error right away.

Change your PHP code to this:

if ($status === 1) { 
  require_once("categoryfinder.php"); 
  $categoryFinder = new CategoryFinder; 
  $category = $categoryFinder -> getCategory(); 
                 
  $response['validation'] = "pass"; 
  $response['message'] = "Thanks for joining the e-mail list, <b>" . $name . "</b>, under the e-mail address, <b>" . $confirmEmail . "</b>."; 
                         
  require_once('databasewriter.php'); 
  $dbWriter = new DatabaseWriter; 
  $dbCode = $dbWriter -> writeUserToDatabase($confirmEmail, $name, $ageRange, $gender, $country, $category); 
                 
  echo '    database code: ' . $dbCode;
   
  if ($dbCode === 1) { 
    $response['database'] = "pass"; 
    echo 'Database Write Successful'; 
  } else { 
    $response['database'] = "fail"; 
    $response['validation'] = "fail"; 
    echo 'Database Write Failure'; 
  } 
  
  if ($dbCode == 2) { 
    $response['message'] = "Server error. Please try again later."; 
  } elseif ($dbCode == 3) { 
    $response['message'] = "That e-mail address already exists."; 
  } 
  
  echo json_encode($response); 
}

Any improvement?

No change :frowning:

Shame!

Change your PHP to this:

if ($status === 1) {
  echo "All Good";
}

and your jQuery to this:

success: function(data) {
  console.log(data);
},

Submit the form with valid data.
What does the console output say?