CodeIgniter 3.0 Form Validation BotDetect CAPTCHA Example

First Time Here?

Check the BotDetect CodeIgniter 3.0 Captcha Quickstart for key integration steps.

This code example shows how to integrate BotDetect PHP Captcha validation and CodeIgniter form validation functionality. It uses the CodeIgniter Form helper and the Form Validation library.

The brief example is based around a contact form which sends email if the user input is considered valid – a likely real world scenario for Captcha protection integration.

BotDetect CodeIgniter CAPTCHA Form Captcha validation screenshot

Files for this ('codeigniter_form_validation_captcha_example') example:

The files are available for download as a part of the BotDetect Captcha CodeIgniter integration package.

Routing – /application/config/routes.php

$route['botdetect/captcha-handler'] = 'botdetect/captcha_handler/index';

In the code above we have registered default route of the Captcha library.

Config – /application/config/captcha.php

<?php
// BotDetect PHP Captcha configuration options

$config = array(
  // Captcha configuration for contact page
  'ContactCaptcha' => array(
    'UserInputID' => 'CaptchaCode',
    'CodeLength' => CaptchaRandomization::GetRandomCodeLength(4, 6),
    'ImageStyle' => ImageStyle::AncientMosaic,
  ),

);

In order to use the BotDetect CAPTCHA CodeIgniter Library, we have declared Captcha configuration which will be used when loading the library in ContactController. Detailed description of this approach is available in a BotDetect CodeIgniter 3.0 integration guide.

View – /application/views/botdetect/contact.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>CodeIgniter Form Validation BotDetect CAPTCHA Example</title>
  <link type="text/css" rel="Stylesheet" href="<?php echo CaptchaUrls::
    LayoutStylesheetUrl() ?>" />
  <link type="text/css" rel="Stylesheet" href="<?php echo base_url(); ?>
    css/style.css" />
</head>
<body>

<div id="container">
  <h1>CodeIgniter Form Validation BotDetect CAPTCHA Example</h1>

  <div id="body">

    <?php if ($emailSent) { ?>
    
      <h2>Thank you!</h2>
      <p>Your message was sent succesfully.</p>
      <p><?php echo anchor('contact', 'Try it again!'); ?></p>
      
    <?php } else { ?>
    
      <?php echo form_open('contact'); ?>
      
      <h5>Your email</h5>
      <?php echo form_input(
        array(
          'name'        => 'Email',
          'id'          => 'Email',
          'value'       => set_value('Email'),
          'maxlength'   => '100',
          'size'        => '50'
        )
      );?>
      <?php echo form_error('Email'); ?>
      
      <h5>Message</h5>
      <div>
      <?php echo form_textarea(
        array(
          'name'        => 'Message',
          'id'          => 'Message',
          'value'       => set_value('Message'),
          'maxlength'   => '100',
          'size'        => '50'
        )
      );?>
      </div>
      <?php echo form_error('Message'); ?>
      
      <?php // Captcha is only shown if not already solved
      if (!$captchaSolved) { ?>
        <h5>Captcha</h5>
        <div>
        <?php echo $captchaHtml; ?>
        <?php echo form_input(
          array(
            'name'        => 'CaptchaCode',
            'id'          => 'CaptchaCode',
            'value'       => '',
            'maxlength'   => '100',
            'size'        => '50'
          )
        );?>
        </div>
        <?php echo form_error('CaptchaCode'); ?>
      <?php }; // end if(!$captchaSolved) ?>
      
      <div><?php echo form_submit('submit', 'Submit'); ?></div>
    
      </form>
    <?php }; // end if($emailSent) ?>
  </div>
</div>

</body>
</html>

The View part of this example is straightforward. We add input fields of supplied type and length. Our Captcha Html is placed above the form field designated for retyping in the characters from the Captcha image, and only shown if the user hasn't already solved the Captcha challenge.

Controller – /application/controllers/Contact.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Contact extends CI_Controller {

  public function index()
  {
    // load the BotDetect Captcha library and set its parameter
    $this->load->library('botdetect/BotDetectCaptcha', array(
      'captchaConfig' => 'ContactCaptcha'
    ));

    $this->load->helper(array('form', 'url'));
    $this->load->library(array('form_validation', 'email'));

    $this->form_validation->set_error_delimiters('<p class="validation_errors">', '</p>');

    $validationConfig = array(
      array(
        'field'   => 'Email', 
        'label'   => 'Email', 
        'rules'   => 'required|valid_email'
      ),
      array(
        'field'   => 'Message', 
        'label'   => 'Message', 
        'rules'   => 'required|min_length[6]'
      ),
      array( // Captcha code user input validation rules
        'field'   => 'CaptchaCode', 
        'label'   => 'Captcha code', 
        'rules'   => 'callback_captcha_validate'
      )
    );
    $this->form_validation->set_rules($validationConfig);

    $data['emailSent'] = false;

    if ($_POST) {
      // run form validation when the form is submitted
      if ($this->form_validation->run() == true) {
        // the form validation (including Captcha validation) passed, send email;
        // we'll include some code showing how to send mail from CodeIgniter, but
        // please note that this code is not production safe, and is simplified 
        // for the purposes of this sample
        $from = $this->input->post('email');
        $message = $this->input->post('message');

        $this->email->from($from);
        $this->email->to('TODO: email address of recipient'); 
        $this->email->subject('TODO: subject');
        $this->email->message($message);  
        // TODO: uncomment only after you have configured your email settings
        //$this->email->send();

        // reset Captcha status after each email sent, since we don't want the user to
        // be able to send an unlimited number of emails after solving the Captcha once
        $this->botdetectcaptcha->Reset(); 

        $data['emailSent'] = true;
      } else {
        // the form validation failed, don't send email
      }
    }

    // the Captcha is not shown if the user already solved it but validation of
    // other form fields failed
    if (!$this->botdetectcaptcha->IsSolved) {
      $data['captchaSolved'] = false;
      $data['captchaHtml'] = $this->botdetectcaptcha->Html();
    } else {
      $data['captchaSolved'] = true;
      $data['captchaHtml'] = '';
    }

    $this->load->view('botdetect/contact', $data);
  }

  // Captcha validation callback used in form validation
  public function captcha_validate($code)
  {
    // user considered human if they previously solved the Captcha...
    $isHuman = $this->botdetectcaptcha->IsSolved;
    if (!$isHuman) {
      // ...or if they solved the current Captcha
      $isHuman = $this->botdetectcaptcha->Validate($code);
    }

    // set error if Captcha validation failed
    if (!$isHuman) {
      $this->form_validation->set_message('captcha_validate', 'Please retype the characters from the image correctly.');
    }

    return $isHuman;
  }
  
}

The Controller part of the example provides the necessary helpers and data for the View to use, adding Captcha validation functionality as outlined in the BotDetect CodeIgniter 3.0 integration guide.

The Captcha library is loaded and provided with a unique ID and the name of the corresponding form field that the user enters the code into.

Form helper is loaded and provides a way to compose the form in the View. The Form validation library is configured with validation rules for each field and supplied with a custom callback for the Captcha input field. The callback captcha_validate() wraps BotDetect Captcha validation calls and provides the result to the CodeIgniter Form Validation Library.

The $_POST variable is checked to see if the form was submitted, in which case, the form validation runs. Note that the code does not display the Captcha if it was solved once and the other fields fail to validate. In case that the whole form, including the Captcha is considered valid, the code proceeds to compose and send a email using the CodeIgniter email library.