Jump to content

Implementing captcha to my dynamically generated forms


Go to solution Solved by gizmola,

Recommended Posts

As you may know by now... I have some functions that generate the articles on my page + the comments associated with them (thanks to Barand and mac_gyver)

function comment_form($id) { // generates a comment box form for every article on the page
    global $user_data;
    if (logged_in() === true) {
        echo "
        <form method='post' action='' class='comments_form'>
            <input type='text' name='username' placeholder='your name... *' id='name' value='{$user_data['username']}'>
            <div class='captcha'>" . create_captcha() .  "</div> 
            <textarea name='comments' id='textarea' placeholder='your comment... *' cols='30' rows='6'></textarea>
            <input type='hidden' name='blog_id' value='$id'>
            <input type='submit' name='submit' id='post' value='post'>
        </form>
        <hr class='artline'>";
    }
}

function list_articles($rows) { 
    if(empty($rows)){
        return "There are no Articles to display";
    }

    $previous_blog_id = 0; 
    $content = '';

    foreach($rows as $row) {
        if ($previous_blog_id != $row['content_id']) { // the blog id changed
            if($previous_blog_id != 0) { // not the first section, close out the previous section
                $content .= comment_form($previous_blog_id); 
            }
            // start a new blog section
            $content .= "<h5 class='posted_by'>Posted by {$row['posted_by']} on {$row['date']}</h5>
                        <h1 class='content_headers'>{$row['title']}</h1>
                        <article>{$row['content']}</article>
                        <hr class='artline'>";
            $previous_blog_id = $row['content_id'];
        }
        if (!empty($row['comment_by']) && !empty($row['comments'])) {
             $content .= "<div class='commented_by'>User: {$row['comment_by']} </div>
                   <div class='comments'>Comment: {$row['comments']}</div>
                   <hr class='artline2'>";
        }
    }

    if($previous_blog_id != 0){ 
        $content .= comment_form($previous_blog_id); 
    }

    return $content;
}

function insert_comments($comments, $comment_by, $blog_id) {
    include('core/db/db_connection.php');
    $comment_by = sanitize($comment_by);
    $comments = sanitize($comments);
    $blog_id = (int)$blog_id;
    $sql = "INSERT INTO article_comments (comments, comment_by, blog_id)
            VALUES ('$comments', '$comment_by', '$blog_id')";
    mysqli_query($dbCon, $sql);
}

I generate a simple math captcha like per below:

function generate_captcha($num1, $num2) { // generates 2 random numbers
    $num1 = (int)$num1;
    $num2 = (int)$num2;
    $rand_num_1 = mt_rand($num1, $num2);
    $rand_num_2 = mt_rand($num1, $num2);
    $result = $rand_num_1 + $rand_num_2;
    return $result;
} 

function create_captcha() { // displays captcha on the page
    $num1 = generate_captcha(1, 20);
    $num2 = generate_captcha(1, 20);
    echo  $num1 . ' + ' . $num2 . ' = ';
    echo '<input type="text" name="captcha_results" size="2">';
    echo '<input type="hidden" name=\'num1\' value=' . $num1 . '; ?>';
    echo '<input type="hidden" name=\'num2\' value=' . $num2 . '; ?>';
}

As you can see, I'm using the create_captcha() function into my comment_form() function because I want every comment box to have a captcha associated with it. The same way every article has it's own comment box.

The above code is displaying a captcha field for each comment box I have, which is what I want. However - it moves all the comment boxes above the content making it look something like this:

|-------------------------------------| // comments form for article 1
|Name: New User                       |
|Comment: New comment !               |
|                                     | 
|-------------------------------------|
[Submit] [captcha field]

|-------------------------------------| // comments form for article 2
|Name: New User                       |
|Comment: New comment !               |
|                                     | 
|-------------------------------------|
[Submit] [captcha field]

==========================================================

Article_1 title: LOREM IPSUM
Content: LOREM IPSUM DOLOR SIT AMET....
-------------------------------------- //comments
Name: User0
Comment: Great article!
--------------------------------------
Name: User1
Comment: Great article! - 2nd comment 
-------------------------------------- // end comments

============================================================

Article_2 title: LOREM IPSUM
Content: LOREM IPSUM DOLOR SIT AMET....
-------------------------------------- //comments
Name: User0
Comment: Great article!
--------------------------------------
Name: User1
Comment: Great article! - 2nd comment 
-------------------------------------- // end comments

The behavior I am expecting is this:

Article_1 title: LOREM IPSUM
Content: LOREM IPSUM DOLOR SIT AMET....
-------------------------------------- //comments
Name: User0
Comment: Great article!
--------------------------------------
Name: User1
Comment: Great article! - 2nd comment 
-------------------------------------- // end comments
|-------------------------------------| // comments form for article 1
|Name: New User                       |
|Comment: New comment !               |
|                                     | 
|-------------------------------------|
[Submit] [captcha field]

============================================================

Article_2 title: LOREM IPSUM
Content: LOREM IPSUM DOLOR SIT AMET....
-------------------------------------- //comments
Name: User0
Comment: Great article!
--------------------------------------
Name: User1
Comment: Great article! - 2nd comment 
-------------------------------------- // end comments
|-------------------------------------| // comments form for article 2
|Name: New User                       |
|Comment: New comment !               |
|                                     | 
|-------------------------------------|
[Submit] [captcha field]

Is it something to do with the position in which I'm inserting the generate_captcha function that causes the comment boxes to float above content? I figured that in order to execute the captcha function I must insert in into the one that generates the comment form for the articles.

 

Thank you.

Edited by VanityCrush

It seems that it has to do with the fact that I'm echoing the comment forms instead of returning the results like so

function comment_form($id) {
    global $user_data;
    if (logged_in() === true) {
        return <<<EOT
        <form method='post' action='' class='comments_form'>
            <input type='text' name='username' placeholder='your name... *' id='name' value='{$user_data['username']}'>
            <textarea name='comments' id='textarea' placeholder='your comment... *' cols='30' rows='6'></textarea>
            <input type='hidden' name='blog_id' value='$id'>
            <input type='submit' name='submit' id='post' value='post'>
        </form>
        <hr class='artline'>
EOT;

However, I cannot insert a function because of the <<<EOT I had to use. How can I insert the create_captcha function into the above? Is it even possible?

  • Solution

Heredocs will interpolate variables.

 

 

So something like this should work:

 



function comment_form($id, $captcha) {
    global $user_data;
    if (logged_in() === true) {
        return <<<EOT
        <form method='post' action='' class='comments_form'>
            <input type='text' name='username' placeholder='your name... *' id='name' value='{$user_data['username']}'>
            <textarea name='comments' id='textarea' placeholder='your comment... *' cols='30' rows='6'></textarea>
            <input type='hidden' name='blog_id' value='$id'>
            <input type='submit' name='submit' id='post' value='post'>
            $captcha
        </form>
        <hr class='artline'>
EOT;
}

$captcha = create_captcha();
echo comment_form($id, $captcha)

Of course you need to alter the create_captcha function so that it returns a string rather than echoing out the markup directly, but that is a general pattern you should be using in all your functions. It will start to improve the separation of concerns.
  • Like 1

Heredocs will interpolate variables.

 

 

So something like this should work:

 



function comment_form($id, $captcha) {
    global $user_data;
    if (logged_in() === true) {
        return <<<EOT
        <form method='post' action='' class='comments_form'>
            <input type='text' name='username' placeholder='your name... *' id='name' value='{$user_data['username']}'>
            <textarea name='comments' id='textarea' placeholder='your comment... *' cols='30' rows='6'></textarea>
            <input type='hidden' name='blog_id' value='$id'>
            <input type='submit' name='submit' id='post' value='post'>
            $captcha
        </form>
        <hr class='artline'>
EOT;
}

$captcha = create_captcha();
echo comment_form($id, $captcha)

Of course you need to alter the create_captcha function so that it returns a string rather than echoing out the markup directly, but that is a general pattern you should be using in all your functions. It will start to improve the separation of concerns.

 

 

You mean something like this? 

function comment_form($id, $captcha) { 
	global $user_data;
	if (logged_in() === true) {
		return <<<EOT
	    <form method='post' action='' class='comments_form'>
		    <input type='text' name='username' placeholder='your name... *' id='name' value='{$user_data['username']}'>
		    <textarea name='comments' id='textarea' placeholder='your comment... *' cols='30' rows='6'></textarea>
		    <input type='hidden' name='blog_id' value='$id'>
		    <input type='submit' name='submit' id='post' value='post'>
	    </form>
	    <hr class='artline'>
EOT;
	}
}

function list_articles($rows) {
    if(empty($rows)){
        return "There are no Articles to display";
    }

    $create_blog_captcha = create_blog_captcha();
    $previous_blog_id = 0; 
    $content = '';

    foreach($rows as $row) {
        if ($previous_blog_id != $row['content_id']) { // the blog id changed
            if($previous_blog_id != 0) { // not the first section, close out the previous section
                $content .= comment_form($previous_blog_id, $create_blog_captcha); 
            }
            // start a new blog section
            $content .= "<h5 class='posted_by'>Posted by {$row['posted_by']} on {$row['date']}</h5>
		                <h1 class='content_headers'>{$row['title']}</h1>
		                <article>{$row['content']}</article>
		                <hr class='artline'>";
            $previous_blog_id = $row['content_id'];
        }
        if (!empty($row['comment_by']) && !empty($row['comments'])) {
             $content .= "<div class='commented_by'>User: {$row['comment_by']} </div>
                   <div class='comments'>Comment: {$row['comments']}</div>
                   <hr class='artline2'>";
        }
    }
    
    if($previous_blog_id != 0){ 
        $content .= comment_form($previous_blog_id, $create_blog_captcha); 
    }

    return $content;
}

function create_blog_captcha() { 
	$num1 = generate_captcha(1, 20);
	$num2 = generate_captcha(1, 20);
	$captchanum = $num1 . ' + ' . $num2 . ' = ';
	$captchanum .= '<input type="text" name="captcha_results" size="2">
			       <input type="hidden" name=\'num1\' value=' . $num1 . '>
			       <input type="hidden" name=\'num2\' value=' . $num2 . '>';
	return $captchanum;
}

I don't get a captcha box returned. Am I doing it completely wrong?

Edited by VanityCrush

In your function comment_form($id, $captcha), you added the $captcha as a param but you never use it in function.

 

Probably after this line you would use it:

 

<input type='hidden' name='blog_id' value='$id'>
$captcha
<input type='submit' name='submit' id='post' value='post'>
  • Like 1

Ah, I understand now. Thank you both !

 

I can't help but wonder though. Am I returning the create_blog_captcha() value correctly doing this? It works, but it seems a bit awkward

        $captchanum = $num1 . ' + ' . $num2 . ' = ';
	$captchanum .= '<input type="text" name="captcha_results" size="2">
			<input type="hidden" name=\'num1\' value=' . $num1 . '>
			<input type="hidden" name=\'num2\' value=' . $num2 . '>';
	return $captchanum;
Edited by VanityCrush
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.