CakePHP 2 Form Model Validation BotDetect CAPTCHA Example
This code example shows how to integrate BotDetect PHP Captcha validation and
CakePHP data validation
functionality. It uses Cake's
FormHelper
and Model validation, which provide a lot of out-the-box functionality when used together.
First Time Here?
Check the BotDetect CakePHP 2 Captcha Quickstart for key integration steps.
The 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.
To keep the example brief, it doesn't use a database backend. Still, this type of Model integration is ideal for protecting database-driven forms that take advantage of the CakePHP Model infrastructure.
Files for this ('bd-captcha-cakephp-2-examples') example:
/app/Config/captcha.php
/app/View/Contact/index.ctp
/app/Model/Contact.php
/app/Controller/ContactController.php
The files are available for download as a part of the BotDetect Captcha CakePHP integration package.
Config – /app/Config/captcha.php
<?php if (!class_exists('CaptchaConfiguration')) { return; } // BotDetect PHP Captcha configuration options return array( // Captcha configuration for contact page 'ContactCaptcha' => array( 'UserInputID' => 'CaptchaCode', 'CodeLength' => CaptchaRandomization::GetRandomCodeLength(4, 6), 'ImageStyle' => ImageStyle::AncientMosaic, ), );
In order to use the CakePHP CAPTCHA Plugin, we have declared Captcha configuration which will be used when loading Captcha component in ContactController. Detailed description of this approach is available in a BotDetect CakePHP 2 integration guide.
View – /app/View/Contact/index.ctp
<h1>CakePHP Form Model Validation BotDetect CAPTCHA Example</h1> <?php // include the BotDetect layout stylesheet echo $this->Html->css(captcha_layout_stylesheet_url(), array('inline' => false)); echo $this->Form->create(null, array('url' => array('controller' => 'contact', 'action' => 'index'))); echo $this->Form->input('name'); echo $this->Form->input('email'); echo $this->Form->input('subject'); echo $this->Form->input('message'); // display Captcha markup, wrapped in an extra div for layout purposes echo $this->Html->div('captcha', captcha_image_html(), false); // Captcha code user input textbox echo $this->Form->input('CaptchaCode', array( 'label' => 'Retype the characters from the picture:', 'maxlength' => '10' )); echo $this->Form->end('Submit'); ?>
The View part of this example is straightforward. The FormHelper
creates input fields of proper type and length in conjuction with the Model. We display the image by calling the captcha_image_html() helper function, and the View utilizes the HtmlHelper::css()
method to add the required stylesheet.
Model – /app/Model/Contact.php
<?php class Contact extends AppModel { public $name = 'Contact'; public $useTable = false; public $validate = array( 'name' => array( 'rule' => '/.+/', 'allowEmpty' => false, 'required' => true ), 'subject' => array( 'rule' => array('minLength', 10), 'message' => 'Please enter at least 10 characters' ), 'email' => array( 'rule' => 'email', 'message' => 'Please enter your email address correctly' ), // Captcha code user input validation rules 'CaptchaCode' => array( 'rule' => 'checkIsCaptchaValid', 'message' => 'Please retype the characters from the picture' ) ); // simply return the Captcha validation status function checkIsCaptchaValid($check) { $value = array_values($check); $value = $value[0]; return captcha_validate($value); } function schema($field = false) { return array ( 'name' => array('type' => 'string', 'length' => 64), 'email' => array('type' => 'string', 'length' => 64), 'message' => array('type' => 'text', 'length' => 256), 'subject' => array('type' => 'string', 'length' => 128), ); } }
The Model implements a custom rule and supplies with a custom callback for the CaptchaCode
field. The callback checkIsCaptchaValid()
wraps BotDetect Captcha validation calls and provides the result to the CakePHP Data Validation.
Controller – /app/Controller/ContactController.php
<?php App::uses('Controller', 'Controller'); class ContactController extends Controller { public $name = 'Contact'; public $uses = 'Contact'; public $helpers = array('Html', 'Form', 'Js'); public $components = array( 'Email', 'Session', // load the BotDetect Captcha component and set its parameter 'BotDetect.Captcha' => array( 'captchaConfig' => 'ContactCaptcha' ) ); public function index() { if ($this->request->is('post')) { $this->Contact->set($this->request->data); // clear previous user input, since each Captcha code can only be validated once unset($this->request->data['Contact']['CaptchaCode']); if ($this->Contact->validates()) { // TODO: send email $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash('Please correct the errors'); } } } }
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 CakePHP 2 integration guide.
After loading the component, the $this->request
variable is checked to see if the form was submitted or not. The form data is encapsulated in the Contact
array which coresponds with the Model used by the Controller, and which the FormHelper
creates automatically. The user-entered Captcha code coresponds to the CaptchaCode
field inside that array.
Notice that the code proceeds to send the email only if the whole Model state validates, which includes the Captcha validation result we provided from inside of the model.
Current BotDetect Versions
-
BotDetect ASP.NET CAPTCHA
2019-07-22v4.4.2 -
BotDetect Java CAPTCHA
2019-07-22v4.0.Beta3.7 -
BotDetect PHP CAPTCHA
2019-07-22v4.2.5