Using reCaptcha with single page forms the Concrete5 5.6.1 way

Permalink
Hello everybody,

I'm building a rather complex application using Concrete5 5.6.1 and I've come across the need to extend the built-in Concrete5 functionality to the point of creating forms in single pages, with captcha validation. As I found the "built-in" captcha unsatisfactory, I decided to integrate reCaptcha with a completely customized theme and messages. Maybe some of you have already solved this, but just in case you haven't yet, I'll tell you how I did it.

I will assume you know your way around single pages. If not, check this: http://www.concrete5.org/documentation/how-tos/developers/build-a-s...

Prerequisites:
1. The single page view (sp_view.php)
2. The single page controller (sp_controller.php)
3. The recptchalib.php library from https://developers.google.com/recaptcha/docs/php...
4. $your_PUBLIC_recaptcha_key and $your_PRIVATE_recaptcha_key, which you can get from http://www.google.com/recaptcha....

Steps:

1. First of all, you need to save recaptchalib.php in your siteroot/libraries/recaptcha folder (first you need to create the recaptcha folder).

2. sp_view.php
Add this javascript BEFORE the beginning of your <form> tag:

<script type="text/javascript">
    var RecaptchaOptions = {
        theme: 'custom',
        custom_theme_widget: 'recaptcha' // id of the recaptcha wrapper div below
    };
</script>


Add your markup before the submit input:

<div id="recaptcha" style="display: none">
    <div class="r-image">
        <div id="recaptcha_image"></div><!-- this is important -->
        <p id="controls"><a onclick="Recaptcha.reload();"><? echo t('Generate a new code') ?></a></p>
    </div>
    <div class="r-response">
        <label for="recaptcha_response_field"><span class="recaptcha_only_if_image"><? echo t('Enter the words above:') ?></span></label>
        <input name="recaptcha_response_field" id="recaptcha_response_field" type="text" /><!-- name and id need to be recaptcha_response_field -->
        <label><? echo t("Capitalization doesn't matter.") ?></label>
    </div>
</div>


Load the library and get the reCaptcha html, after the markup above:

<?php
    Loader::library('recaptcha/recaptchalib');
    echo recaptcha_get_html($your_PUBLIC_recaptcha_key);
?>


3. sp_controller.php
Create your custom form validation rules in your save() function within the controller class, as described at http://www.concrete5.org/documentation/developers/forms/basic-valid...

Load the library and get the answer from the user:

Loader::library('recaptcha/recaptchalib');
$recaptchaResponse = recaptcha_check_answer($your_PRIVATE_recaptcha_key, $_SERVER["REMOTE_ADDR"], $this->post('recaptcha_challenge_field'), $this->post('recaptcha_response_field'));


Validate the form:

if($this->validation->test() and $recaptchaResponse->is_valid) {
    $validated = true;
} else {
    $validated = false;
    $error_array = $this->validation->getError()->getList();
    if(!$recaptchaResponse->is_valid)
        array_push($error_array, t('The captcha answer is incorrect.'));
}


This is pretty much it, and it works like a charm for me. You can style the id's and classes in your css to your liking.

I hope this will help and save you some time.

rainmanx