We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 10487 MODX Staff
    • 1,535 Posts
    Hi all,

    Recently I did say that I’d look at how Captcha could be added into UserComments. Well, I sat down over a coffee today and decided to draw up a tutorial on how to do this - mainly because there are various versions of UserComments available and so hopefully this tutorial will help you modify whichever version you’re currently using.

    First things first, I have attached a copy of the basic UserComments snippet with my modifications, and all my changes are commented with //-- CAPTCHA and //-- END CAPTCHA.

    Either if you’re using my attached version or modifying your own versions, just add &useCaptcha=`1` to your snippet call to enable Captcha.


    So, here’s what to do ...

    Step 1: Adding the snippet parameter and the HTML output for the Captcha image

    The following code, which is added immediately after the snippet comments (for ease of access) sets a snippet parameter that can be used to toggle the Captcha image on and off. Secondly, a variable is created to hold the HTML output for the Captcha image and necessary form field:

    //set snippet parameter
    $useCaptcha = (isset ($useCaptcha)) ? true : false;
    
    //set 'captcha' placeholder
    $phCaptcha = 'Form Code:<br /><input type="text" name="formcode" class="inputBox" style="width:150px" size="20">
    <a href="[+action+]"><img align="top" src="manager/includes/veriword.php?rand=' . rand() . '" width="148" height="60" alt="If you have trouble reading the code, click on the code itself to generate a new random code." style="border: 1px solid #003399"></a>';
    
    //replace the 'action' placeholder with the page url
    $phCaptcha = str_replace("[+action+]", $modx->makeUrl($modx->getDocumentIdentifier('id'), '', ''), $phCaptcha);


    (Some of the code was taken directly from the WebLogin snippet in case anybody recognises it tongue Style as you wish)

    Step 2: Preventing the comment from being submitted if the Captcha code is incorrect

    To prevent the posting of comments if the Captcha code is incorrect, it is necessary to wrap a quick check around the existing code that detects if the comments form has been submitted and that the Captcha code is correctly entered:
    if ((!$useCaptcha || isset ($_POST['formcode']) && isset ($_SESSION['veriword']) && $_SESSION['veriword'] == $_POST['formcode'])) {
    	// get postback status
    	$isPostBack = isset ($_POST['UserCommentForm' . $tagid]) ? true : false;
    } else {
    	$isPostBack = false;
    }


    Step 3: Modifying the form template

    Here, I have modified the default template in the snippet but the same process applies to any custom templates you may be using. The modification adds in placeholders where the form values can be inserted back into the template should the Captcha code not validate and the page has to be reloaded.

    $formTpl = '
    		<form method="post" action="[~[*id*]~]">
    			<input name="[+tagname+]" type="hidden" value="on" />
    			Subject:<br /><input name="subject" type="text" size="40" value="[+subject+]" /><br />
    			Comment:<br /><textarea name="comment" cols="50" rows="8">[+comment+]</textarea><br />
    			[+captcha+]
    			<input name="send" type="submit" value="Submit" />
    		</form>
    		';


    Notice the addition of the [+subject+] and [+comment+] compared to the standard default template. The placeholders you add should correspond to the names you have used for your form fields (including any additional fields you have added) Also, notice the addition of the [+captcha+] tag that will render the captcha image and form field.

    Step 4: Substituting the Captcha HTML and any form values into the form template

    To complete the process, the only remaining step is to substitute all the values into the form template. The following code does just that:

    if ($useCaptcha == true)
    	$formTpl = str_replace("[+captcha+]", $phCaptcha, $formTpl);
    
    if (!$isPostBack) {
    	foreach ($_POST as $n => $v) {
    		$formTpl = str_replace("[+$n+]", $v, $formTpl);
    	}
    }

    The MODx document parser will remove any empty placeholder tags that haven’t been replaced by this code when the page is rendered.


    And that’s it, you now have a Captcha-enabled UserComments snippet. Well, I hope that helps everybody out anyway. Comments welcome,

    Garry
      Garry Nutting
      Senior Developer
      MODX, LLC

      Email: [email protected]
      Twitter: @garryn
      Web: modx.com
      • 33337
      • 3,975 Posts
      Great tutorial Garry!

      Thanks for sharing this!!! smiley

      Best regards,

      zi
        Zaigham R - MODX Professional | Skype | Email | Twitter

        Digging the interwebs for #MODX gems and bringing it to you. modx.link
        • 33175
        • 711 Posts
        Thanks to you Garry for this tutorial smiley
          Sorry for my english. I&#39;m french... My dictionary is near me, but it&#39;s only a dictionary !
          • 4195
          • 398 Posts
          I will implement this for Replix smiley
            Armand Pondman
            MODx Coding Team
            :: Jot :: PHx
            • 4195
            • 398 Posts
            //replace the 'action' placeholder with the page url
            $phCaptcha = str_replace("[+action+]", $modx->makeUrl($modx->getDocumentIdentifier('id'), '', ''), $phCaptcha);
            


            this part is obsolete.. you can use [~[*id*]~] instead of [+action+] and the replace routine or maybe i’m missing something ? smiley
              Armand Pondman
              MODx Coding Team
              :: Jot :: PHx
              • 10487 MODX Staff
              • 1,535 Posts
              Hi bS,

              In the past I’ve encountered issues with using [~[*id*]~] from within snippets because, in some instances, I’ve found the id value may not get correctly parsed. In particular, this happened on the Polls snippet I wrote.

              Even though it seems to probably only affect a few setups, I remember the three hours I spent debugging the problem well wink

              So, personally, I will always opt to use the above method over [~[*id*]~]. It just removes the possibility of the snippet not working on different setups.

              Hope that helps,

              Garry
                Garry Nutting
                Senior Developer
                MODX, LLC

                Email: [email protected]
                Twitter: @garryn
                Web: modx.com
                • 4195
                • 398 Posts
                actually I got an weird error when using the replace methode.. I removed it and used the ID and it worked without problems :S
                but maybe that is just my snippet smiley

                thanks for the tutorial btw smiley
                  Armand Pondman
                  MODx Coding Team
                  :: Jot :: PHx
                  • 16610
                  • 634 Posts
                  Thank you very much Garryn!
                  And bye-bye my guestbook spam-problems grin
                    Mikko Lammi, Owner at Maagit
                    • 34162
                    • 1 Posts
                    hey guys i’m pretty new to all this stuff. installed modx about a month or so ago and would love to add this captcha to any comments pages. but not sure what i’m adding the code to exactly, am i creating new snippets and chunks, modifying old ones etc? sorry can anyone help me out. thanks.