3

I have a comment form at the end of my blog posts. In testing so far the vast majority of times the comments are successfully saved into the database, however very occasionally the page gives the impression of having posted the comment successfully - but after reloading the page the comment has disappeared (and checking the db table confirms it never made it that far). Is there a way of amending my code somewhere to catch these freak occurrences?

I am aware that $.ajax has an error function, but I don't think adding that in this instance will help. The actual ajax request seems to be working - because it always runs what is in the 'success' function. So perhaps it's postComment.php that needs the amendment?

Code behind the form submit:

if( $(".blogPost").length ) {
    $(".commentForm").submit(function(e) {
        e.preventDefault();
    }).validate({
            submitHandler: function (form) {
                var url = window.location.pathname;
                var post_url = url.substring(url.lastIndexOf('/') + 1);
                $("input[name=post_url]").val(post_url);
                var formData = $(form).serialize();
                var post_id = $(".post").attr("id");
                $.ajax({
                    url:"/postComment.php?PostID=" + post_id,
                    type:"POST",
                    data: formData,
                    success:function(data){
                        $(".comments").prepend(data);
                        $("#commentName").val("");
                        $("#commentEmail").val("");
                        $("#commentWebsite").val("");
                        $("#comment").val("");
                        $(".commentForm input[type='submit']").val('Success!').delay(5000).queue(function(){
                            $(".commentForm input[type='submit']").val('Post Comment');
                        });
                    }
                });
            }
        });

}

Code on postComment.php page:

<?php
include('dbconnect.php');

$name = $_POST['commentName'];
$email = $_POST['commentEmail'];

$website = $_POST['commentWebsite'];
if( $website != ''){
    if  ( $ret = parse_url($website) ) {

          if ( !isset($ret["scheme"]) )
           {
           $website = "http://{$website}";
           }
    }
}

$comment = $_POST['comment'];
$date = date('Y-m-d H:i:s');
$post_id = $_GET['PostID'];

$blogAuthor = '';
if( $name == "Luke Twomey"){
    $blogAuthor = "<span> - Blog Author</span>";
}else{
    $blogAuthor = false;
}

$SQL = "INSERT INTO comments (name, email, website, comment, date, post_id) VALUES ('$name', '$email', '$website', '$comment', '$date', '$post_id')";
mysqli_query($link, $SQL);

echo "<section class='comment'>
            <h3 class='commentAuthor'>$name$blogAuthor</h3>
            <a href='$website'><p class='commentAuthorWebsite'>$website</p></a>
            <p class='postDate'>$date</p>
            <p>$comment</p>
        </section>";

$subject = $name . $_POST['subject'];
$post_url = $_POST['post_url'];
$postedMessage = $_POST['comment'];
$contentForEmail = $postedMessage.'<br><a href="http://www.fakedomainhere.com/blog/'.$post_url.'#comments"><p>View comment on website</p></a>';

$header = "From: fake-email-here\n"
. "Reply-To: fake-email-here\n" . "Content-Type: text/html; charset=ISO-8859-1\r\n";

$email_to = "fake-email-here";

mail($email_to, $subject , $contentForEmail, $header );


?>
Luke Twomey
  • 1,245
  • 1
  • 9
  • 18
  • 1
    There's no error handler in the ajax call, so any errors will just be ignored, but are you saying you actually see "Success!" when it hasn't worked? If so then the issue is on the server so some logging may be required to figure out what's going wrong. – Reinstate Monica Cellio Nov 12 '15 at 09:34
  • Correct - I see "success!", and the comment is added to the page as per this section in postComment.php: echo "
    . Could you elaborate or point me in the right direction for how to add logging to the server?
    – Luke Twomey Nov 12 '15 at 09:38
  • I would suggest literally dumping some debug info into a text file, but the answers below should help see if there's a problem without going down that route. I generally have something like that in place when I start a new project, as you can pretty much guarantee you'll want it later :p – Reinstate Monica Cellio Nov 12 '15 at 09:44
  • OK thanks for the tip! – Luke Twomey Nov 12 '15 at 09:49
  • If you send a 404 or 500 HTTP code (when the insert didn't work), it will trigger the `error`. – FrancoisBaveye Nov 12 '15 at 09:53
  • 1
    @Heru-Luin Sorry, but that's bad advice. The best thing would be to send a regular 200 response with a flag in the response data that indicates an error (maybe with the error message itself as well). 404 and 500 errors are there for a specific reason. You shouldn't pretend they happened when something else did. – Reinstate Monica Cellio Nov 12 '15 at 09:56
  • @Archer If the comment cannot be saved (for any reason), there is definitely a server error, so 500 would be ok. – FrancoisBaveye Nov 12 '15 at 09:57
  • 1
    500 is better than 404, for sure, but you shouldn't be forcing errors when you can simply return a data object with error information in it. – Reinstate Monica Cellio Nov 12 '15 at 10:00
  • @Archer Can you point me in the right direction for how to return this data object and handle it in the original ajax request? – Luke Twomey Nov 12 '15 at 10:05
  • I'm not a PHP programmer, so I can't help with the specifics, but you can use JSON to return an object in string format. Have an error property that is either 0 or 1, true or false, and have your success function check that value. Have a look at this question... http://stackoverflow.com/questions/4417690/return-errors-from-php-run-via-ajax – Reinstate Monica Cellio Nov 12 '15 at 11:40

3 Answers3

0

First make sure that insert is success then only return the success message.

if(mysqli_query($link, $SQL)){
echo "<section class='comment'>
            <h3 class='commentAuthor'>$name$blogAuthor</h3>
            <a href='$website'><p class='commentAuthorWebsite'>$website</p></a>
            <p class='postDate'>$date</p>
            <p>$comment</p>
        </section>";
}else{
    echo "problem while inserting"; //or return an array with some status to tell the user to submit again.
// or header('HTTP/1.0 500 Internal Server Error'); exit;
    }
Suchit kumar
  • 11,809
  • 3
  • 22
  • 44
  • Thanks. Is there then a way to force the ajax request to fail? I'm thinking of the user - if they type a massive comment, then post it - the db insert fails and they see "Problem while inserting" from postComment.php, but the ajax request is still telling them it was a success - and the details they entered are cleared from the form. Can I make the ajax request fail - leaving their comment intact, so they can simply try to press "Submit" again? – Luke Twomey Nov 12 '15 at 09:48
  • @LukeTwomey add `header('HTTP/1.0 404 Not found'); exit; ` to else part – Suchit kumar Nov 12 '15 at 09:51
  • Since the page is found, there is no point to make it 404. Instead of this, you can use the HTTP code 500 ("Internal server error"). – FrancoisBaveye Nov 12 '15 at 09:59
  • @Heru-Luin then 500 Internal server error can be used but forcing error without knowing the cause is not a good practice. – Suchit kumar Nov 12 '15 at 10:01
0

Confirm that there's nothing wrong with the insert with something like this:

$result = mysqli_query($link, $SQL);

if(!$result) {
    printf("Error: %s\n", mysqli_error($link));
} else {
    echo "<section ...

And you should probably read up on how to properly escape the input: http://php.net/manual/en/mysqli.real-escape-string.php

walleboom
  • 31
  • 3
  • Thanks, I will read up on that. I'm rushing to get this site up and running, then going back to properly learn PHP afterwards. Not exactly the best way of doing things I'll be the first to admit! – Luke Twomey Nov 12 '15 at 09:51
0

Server Side:

  • Check if SQL Query was Successful.

  • echo true or false based on your Query's Success or Failure.

Client Side:

$.ajax({

  url: "/postComment.php?PostID=" + post_id,
  type: "POST",
  data: formData,

  success:function(data){

    if(data == 'true') { // Prepend only If Successful

      $(".comments").prepend(data);

      $("#commentName").val("");
      $("#commentEmail").val("");
      $("#commentWebsite").val("");
      $("#comment").val("");

      $(".commentForm 

      input[type='submit']").val('Success!').delay(5000).queue(function() {

        $(".commentForm input[type='submit']").val('Post Comment');

      });

    } else { // Error

      alert("There was an issue in submitting your Comment. Please try again.");

    }

  }

});
Ahsan
  • 1,084
  • 2
  • 15
  • 28