Captcha component with PhpCaptcha

By Spout (spout)
PhpCaptcha is a library for generating visual and audio CAPTCHAs (completely automated public Turing test to tell computers and humans apart).
Supported Features
  • Multiple random TrueType fonts
  • Character rotation
  • Optional chararacter shadow support
  • Optional site owner display text
  • Random custom background images
  • Font size selection
  • Greyscale or colour lines and characters
  • Character set selection
  • Integration of validation function for checking the user entered code with the generated code

NB: The audio CAPTCHA requires the Flite text to speech synthesis engine.


1.- Download PhpCaptcha http://www.ejeliot.com/pages/2 and unzip archive in /vendors/phpcaptcha directory
2.- Download Vera font files: http://ftp.gnome.org/pub/GNOME/sources/ttf-bitstream-vera/1.10/ttf-bitstream-vera-1.10.zip and unzip archive in /vendors/phpcaptcha/fonts/
3.- Create Captcha component:

Component Class:

Download code <?php 
vendor
('phpcaptcha'.DS.'php-captcha.inc');

class 
CaptchaComponent extends Object
{
    var 
$controller;
 
    function 
startup( &$controller ) {
        
$this->controller = &$controller;
    }

    function 
image(){
        
        
$imagesPath realpath(VENDORS 'phpcaptcha').'/fonts/';
        
        
$aFonts = array(
            
$imagesPath.'VeraBd.ttf',
            
$imagesPath.'VeraIt.ttf',
            
$imagesPath.'Vera.ttf'
        
);
        
        
$oVisualCaptcha = new PhpCaptcha($aFonts20060);
        
$oVisualCaptcha->UseColour(true);
        
//$oVisualCaptcha->SetOwnerText('Source: '.FULL_BASE_URL);
        
$oVisualCaptcha->SetNumChars(6);
        
$oVisualCaptcha->Create();
    }
    
    function 
audio(){
        
$oAudioCaptcha = new AudioPhpCaptcha('/usr/bin/flite''/tmp/');
        
$oAudioCaptcha->Create();
    }
    
    function 
check($userCode$caseInsensitive true){
        if (
$caseInsensitive) {
            
$userCode strtoupper($userCode);
        }
        
        if (!empty(
$_SESSION[CAPTCHA_SESSION_ID]) && $userCode == $_SESSION[CAPTCHA_SESSION_ID]) {
            
// clear to prevent re-use
            
unset($_SESSION[CAPTCHA_SESSION_ID]);
            
            return 
true;
        }
        else return 
false;
        
    }
}
?>

4.- Use it in your Users controller

Controller Class:

Download code <?php 
class UsersController extends AppController
{
    ...
    var 
$components = array('Captcha');
    ...
    function 
captcha_image()
    {
        
$this->Captcha->image();
    }
    
    function 
captcha_audio()
    {
        
$this->Captcha->audio();
    }
    ...
}
?>

5.- Display captcha image, in your template view:

View Template:

Download code
<img id="captcha" src="<?php echo $html->url('/users/captcha_image');?>" alt="" />
 <a href="javascript:void(0);" onclick="javascript:document.images.captcha.src='<?php echo $html->url('/users/captcha_image');?>?' + Math.round(Math.random(0)*1000)+1">Reload image</a>
Pretty cool, we can reload captcha image if unreadable ;o)

6.- Validate captcha code in your controllers with $this->Captcha->check() method.

With my cake apps I use the improved validation method explained on the bakery. http://bakery.cakephp.org/articles/view/more-improved-advanced-validation I've added this validation function to validation.php

Download code
function validateCaptcha($fieldName, $params){
        $caseInsensitive = true;
        
        $val = $this->data[$this->name][$fieldName];
        
        if ($caseInsensitive) {
            $val = strtoupper($val);
        }
        
        //php-captcha.inc.php
        if(!defined('CAPTCHA_SESSION_ID'))
            define('CAPTCHA_SESSION_ID', 'php_captcha');
         
         if (!empty($_SESSION[CAPTCHA_SESSION_ID]) && $val == $_SESSION[CAPTCHA_SESSION_ID]) {
            // clear to prevent re-use
            unset($_SESSION[CAPTCHA_SESSION_ID]);
            
            return true;
         }
         
         return false;
    }

And voil�

 

Comments 442

CakePHP Team Comments Author Comments
 

Comment

1 Nice Work

Hey, this is a handy component. I was just looking for this.

Here are a few things i noticed:

on line 14 of captcha.php:
$imagesPath = realpath(VENDORS . 'phpcaptcha').'/fonts/';
if your vendors path is inside your app directory, you need something like this:

$imagesPath = APP . 'vendors' . DS . 'phpcaptcha'.'/fonts/';

also, for the validation, i changed:

function validateCaptcha($fieldName, $params){
        $caseInsensitive = true;

to :

function validateCaptcha($fieldName, $caseInsensitive = true){

since the $params var is not used in the function, and it's handy to have the case sensitivity as a parameter.

Also, for anyone using this who is also using sessions (either Cake's or your own), be sure to look at the vendor file php-captcha.inc and comment out line 46, where the script calls session_start() , or you will definitely experience some session problems.

Thanks for the work, Spout.

dd
Posted Jun 13, 2007 by darius
 

Question

2 I cant get it to work

i tried in windows and linux, and i couldn't get it to work, gives me an 'X' image on IE and blank on FF.

when i am trying to debug by accesing directly to the url /users/captcha_image says that the view is missing.

what should i do?

Posted Jun 21, 2007 by Manuel Dorado
 

Comment

3 I get it to work

i tried in windows and linux, and i couldn't get it to work, gives me an 'X' image on IE and blank on FF.

when i am trying to debug by accesing directly to the url /users/captcha_image says that the view is missing.

what should i do?

i shold recompile my php to support gd libraries, and be carefull with the imagesPath directory...

very great component! thanks Spout.

i realize that after debug step by step the vendor captcha php.

Posted Jun 21, 2007 by Manuel Dorado
 

Bug

4 FireFox is unable to work

Have anybody got solution.
Thank!!
Posted Jul 11, 2007 by Jersus Soo
 

Question

5 How to add error message that captcha you typed is wrong

Ok, i was able to make this work.

Although, i am a bit clueless. On how will i add an error message on the template itself. Here are sample of my codes.

Controller Class:

<?php 
...
if (empty(
$this->data))
{
    
$this->render();
}
else
{

    if (
$this->Email->save($this->data))
    {
    if (
$this->Captcha->check($this->data['Email']['userCode'])) { 
        
    
// Flash that it has been sent
    
$this->flash('Your email has been sent.','/emails');
            
    }
        
    }
    else
    {
        
$this->set('errorMessage''Please correct errors below.');
        
$this->render();
    }

}
...
?>
I was able to validate the usual fields i added:

View Template:


...
<label>Name:</label>
<?php echo $html->input('Email/name', array('class' => 'input''style' => 'width: 200px;')); ?>
<?php 
echo $html->tagErrorMsg('Email/name''Name is required.'); ?>
<label>Message:</label>
<?php echo $html->textarea('Email/message', array('rows'=>'10''cols'=>'40')); ?>
<?php 
echo $html->tagErrorMsg('Email/message''Message is required.'); ?>

<label>Captcha:</label>
<?php echo $html->input('Email/userCode', array('class' => 'input''style' => 'width: 200px;')); ?>
<?php 
echo $html->tagErrorMsg('Email/userCode''Captcha is required.'); ?>
...

which is name and message and captcha (if its empty only).

But to show that what you typed is wrong, i don't know what to do.
Please help!

Posted Jul 26, 2007 by Louie Miranda
 

Comment

6 Captcha with CakePHP 1.2

This is what I had to do to get Captcha component working with validator (CakePHP 1.2). It is quiet easy but I had some troubles to understand the new validation process. Hope it will help somebody else.

Model Class:

<?php 

    $validate 
= array(
        
'captcha' => array (
            
'validateCaptcha' => array (
                
'rule' => 'validateCaptcha',
                
'message' => 'Your captcha error message'
            
)
        )
    );

    function 
validateCaptcha($check) {
        if (!
defined('CAPTCHA_SESSION_ID')) {
            
define('CAPTCHA_SESSION_ID''php_captcha');
        }

        if (!empty (
$_SESSION[CAPTCHA_SESSION_ID]) && $check == $_SESSION[CAPTCHA_SESSION_ID]) {
            unset (
$_SESSION[CAPTCHA_SESSION_ID]);
            return 
true;
        }
        return 
false;
    }
?>

Note that the field $validate has been declared in my child model class called "Post" and the method validateCaptcha is in the parent AppModel class.
Posted Jul 28, 2007 by Sam Contesse
 

Question

7 reload image not working in Internet Explorer

My captcha validation is working properly in FF,but the Reload Image link is not working in the internet explorer.

Can any body suggest me actualy where i am wrong

Waiting for a reply
Posted Aug 28, 2007 by sivaprasad
 

Question

8 Implementation

I tried it on Windows using CakePHP 1.2alpha and PHP 5. It's giving me an "X" image on IE and FF. I've read the post by Manuel Dorado but my gd library is already working.

Your help is greatly appreciated.

Thank you.
Posted Oct 14, 2007 by Wendell Malpas
 

Comment

9 v1.2

also trying to get it work on 1.2.
seems like the response headers are already sent and php-captcha.inc.php kannt set the mime-type header to image/jpg
Posted Nov 5, 2007 by danny thuering
 

Comment

10 solved

hehe

der was an space after my closing ?> tag in captcha.php which caused the headers to be send...

:-)
Posted Nov 5, 2007 by danny thuering
 

Comment

11 great component

Thanks for the submission, I had captcha working within minutes with no trouble at all!

p.s. it seems I'm not able to rate anything on Bakery, as soon as this issue is fixed I'll give it a 5 :-)
Posted Dec 17, 2007 by Hannibal Lecter
 

Question

12 Problem to get this working

hi ! first thanks for this great component.
phpcaptcha works fine on mine server as standalone. so all libs a working properly.

if i want to use it within my controller, i just got an "broken-image" in IE or the url in Firefox.
when viewing the source i noticed, that there are html-elements.. looks like some parts of my layout...
maybe this causes the failure?

i got absolutely no idea why my layout is used.
even a

Controller Class:

<?php 
    
function captcha_image()
    {    
        
$this->layout FALSE;
        
$this->Captcha->image();
    }
?>

won't work.. any ideas on that?
Posted Mar 31, 2008 by Lars
 

Question

13 additional info

i just noticed that before output, starts, there are
THREE BLANK SPACES and i can't explain where they are from. even with no layout - these spaces are there..

but guess what: they are on every page generated within cakephp. on every site 3 blank spaces at the beginning. anyone has an idea which scripts generates them? maybe because of them already html output has been startet and the image could be displayed.

thx in advance for every help ( if i get some ^^ )
Posted Apr 1, 2008 by Lars
 

Question

14 Cant download Component

I'm not seeing where I can download this component, something wrong with the bakery?
Posted Apr 29, 2008 by Mark
 

Comment

15 Working on 1.2

Hi, I see that many people have problems with phpcaptcha working on cakephp 1.2 so I paste here version which runs perfectly:

Component Class:

<?php 
App
::import('Vendor','PhpCaptcha' ,array('file'=>'phpcaptcha/php-captcha.php'));
        
class 
CaptchaComponent extends Object
{
    var 
$controller;
 
    function 
startup( &$controller ) {
        
$this->controller = &$controller;
    }

    function 
image(){
        
        
$imagesPath APP 'vendors' DS 'phpcaptcha'.'/fonts/';
        
        
$aFonts = array(
            
$imagesPath.'VeraBd.ttf',
            
$imagesPath.'VeraIt.ttf',
            
$imagesPath.'Vera.ttf'
        
);
        
        
$oVisualCaptcha = new PhpCaptcha($aFonts20060);
        
        
$oVisualCaptcha->UseColour(true);
        
//$oVisualCaptcha->SetOwnerText('Source: '.FULL_BASE_URL);
        //$oVisualCaptcha->SetNumChars(6);
        
$oVisualCaptcha->Create();
    }
    
    function 
audio(){
        
$oAudioCaptcha = new AudioPhpCaptcha('/usr/bin/flite''/tmp/');
        
$oAudioCaptcha->Create();
    }
    
    function 
check($userCode$caseInsensitive true){
        if (
$caseInsensitive) {
            
$userCode strtoupper($userCode);
        }
        
        if (!empty(
$_SESSION[CAPTCHA_SESSION_ID]) && $userCode == $_SESSION[CAPTCHA_SESSION_ID]) {
            
// clear to prevent re-use
            
unset($_SESSION[CAPTCHA_SESSION_ID]);
            
            return 
true;
        }
        else return 
false;
        
    }
}
?>

This is action which renders captcha:


  function captcha_image()
  {
    Configure::write('debug',0);
    $this->layout = null;  
    $this->Captcha2->image();
    $this->render();
  } 
Posted May 12, 2008 by Kubasko
 

Question

16 Problem to show the validation error for PhpCaptcha

Hi,

I am facing a big problem with show error massage while validating the Captcha code.

I am giving my code...

var $validate = array('captcha' => array('checkv' => array ('rule' =>'checkv','message' => 'put correct value')));

and my validation model function is

function checkv($userCode1){
$userCode = $userCode1['captcha'];
$caseInsensitive = true;
if ($caseInsensitive) {
$userCode = strtoupper($userCode);
}
//echo $userCode." ".$_SESSION[CAPTCHA_SESSION_ID];
if (!empty($_SESSION[CAPTCHA_SESSION_ID]) && $userCode == $_SESSION[CAPTCHA_SESSION_ID]) {
// clear to prevent re-use
unset($_SESSION[CAPTCHA_SESSION_ID]);

return true;
}
else return false;

}

But this code is giving an error massage...


Warning: preg_match() expects parameter 1 to be string, array given in cake/libs/model/model_php5.php on line 1385

And this is actually not validate when I am giving correct code for captche.

Please help me.

Thanks
Projjwal
Posted May 27, 2008 by Projjwal Bandyopadhyay
 

Question

17 Problem With Add multiple component with Captcha.

Hi All

I am facing a problem with adding multiple component.

I am giving my Controller code....


class ContactsController extends AppController
{
var $name = 'Contacts';
var $layout = 'contact_template';
var $components = array('Captcha','Email');
// use component email

function index()
{
if (!empty($this->data))
{
$this->Contact->set($this->data);

if($this->Contact->validates())
{
$postValid = TRUE;
if(!empty($this->data['Contact']['captcha']))
{
$trfl = $this->Captcha->check($this->data['Contact']['captcha']);
if($trfl == false)
{
$this->Contact->invalidate('captcha');
$postValid = FALSE;
}
}
if($postValid)
{
$tr = $this->Contact->sendmail($this->data['Contact']);
if($tr)
{

//@mail("projjwal@indusnet.co.in",$sub,$massage,"From: Projjwal ");
//$this->set('data', $this->data);
$this->Email->to = 'projjwal@indusnet.co.in';
$this->Email->subject = 'your new Contact';

$result = $this->Email->send();
$this->flash('A mail has been send to admin.','/contacts',2);
}else
{
$this->render();
}
}else
{

$this->render();
}
}else
{
$this->render();
}
}else
{
$this->render();
}

}
function captcha_image()
{
$this->Captcha->image();

}

function captcha_audio()
{
$this->Captcha->audio();
}

}
?>
When I am using this code the Captcha is not working.
When I am removing the Email from the $components array
it's working fine.

Can any one tell me why it's happenning?

Thanks in advance.

Projjwal
Posted May 28, 2008 by Projjwal Bandyopadhyay
 

Comment

18 Problem With Add multiple component with Captcha

Hi,

I had basically the same problem. When I noticed that the problem only occured with e-mail component, I realized that I copied and pasted the code of the e-mail component from the cakebaker website.

Another component did not have the issue. So I took the file of this component, copied the code for the captcha component into this file, removed the original code and renamed the file to captcha.php. And guess what .. it worked.

Really strange.
Posted Jun 16, 2008 by martijn gh
 

Comment

19 Headers and SESSION

Hi,

I have another problem with keeping the S_SESSION variables. I found out that in some circumstances, the $_SESSION varialbes are unset when vendor phpcaprcha.php send a header request, telling the browser that a jpeg file is send. Commenting out this line, and the $_SESSION variables can be retrieved later on.

The strange thing is that it happens not always. I have a test and a stage environment, on the test environment the issue does not occur, while the ocde is the same. Aslo it worked on the stage environment, until today.

Anybody has a clue why this is happening ?

Thanks in advance,

Martijn
Posted Jun 16, 2008 by martijn gh
 

Comment

20 reload image

Hi,
When I try something like http://localhost/myapplication/webusers/captcha_image?1234, it works well but I always get the same picture, whatever the number I use.
What could I do ? An idea ?
Posted Jul 17, 2008 by limule
 

Comment

21 It works, cool

good job, this is exactly what am looking for
Posted Oct 29, 2008 by Jolly Lengkono
 

Question

22 Fatal Error Call to undefined Function

Hello together,

i started to develop PHP5. And i started also with cakephp. Its very good how fast and easy i get an result. But now i tried to use this captcha with CakePHP 1.2.0.7692. I'm at that point that i want to try out i had copied it into Netbeans 6.5 and uploaded it on my Apache...
This is my Strukture

app
-vendors
--phpcaptcha
---fonts
--+php-captcha.inc

-controllers
+mycontrollerclass.php
--components
--+captcha.php
-models
+mymodelclass.php
-views
--myviews
--+myviews.ctp

in the vendors folder(not under app) are the files

when i try to call my application i get such error
Fatal error: Call to undefined function vendor() in /opt/lampp/htdocs/cakePHP/app/controllers/components/captcha.php on line 2
all files of the captcha Components are copied from this page and pasted into my cakePHP environmemt.
Where should is the place for the phpcaptcha and the fonts? In the app folder or in the cakePHP Folder?

thanks for the help.

Many greetings

Marcus Radisch
Posted Dec 17, 2008 by Marcus Radisch
 

Comment

23 I solved it

I solved it, because there are a solution for cake 1.2

Posted Dec 17, 2008 by Marcus Radisch
 

Question

24 I see no Picture

Hello together,

i used this code in cakePHP 1.2
in my template.

<img id="captcha" src="<?php echo $html->url('/users/captcha_image');?>" alt="" />
 <a href="javascript:void(0);" onclick="javascript:document.images.captcha.src='<?php echo $html->url('/users/captcha_image');?>?' + Math.round(Math.random(0)*1000)+1">Reload image</a> 

But i get no Picture there ar only a link 'Reload Image'. But No Pict. I allowed all scripts and use ff. What sould i do now. In Konqueror it doesn't run.
Posted Dec 17, 2008 by Marcus Radisch
 

Comment

25 Solution to this problem

I solved it, because there are a solution for cake 1.2


The solution to this problem is to replace (in captcha.php),

vendor('phpcaptcha'.DS.'php-captcha.inc');

with

App::import('Vendor', 'phpcaptcha/php-captcha.inc');

since vendor(); is depreciated.
Posted Feb 2, 2009 by William Muterspaugh
 

Question

26 Can't get image

I follow all the rules for creating components but still cant get image..
It shows me imagebox but I cant found image..

I tried almost every thing but cant get image..

Please help me out..
Posted Mar 2, 2009 by Vikas Tamakuwala
 

Comment

27 Component Problem

What should i name my component..

Only the reload image is shown.. help pls
Posted Apr 14, 2009 by james
 

Comment

28 Hey guys try this...

1) Rename vendors/phpcaptcha/php-captcha.inc.php file to phpcaptcha.php

2) In controllers/components/captcha.php change the line
vendor('phpcaptcha'.DS.'php-captcha.inc');
to
App::import('Vendor', 'phpcaptcha/phpcaptcha');

Hope that works.
Posted May 11, 2009 by Mohan
 

Question

29 View not found in 1.2

I'm having problems getting this working in 1.2

Checklist:
- vendors/phpcaptcha
- vendors/phpcaptcha/fonts
- rename phpcaptcha.inc.php to phpcaptcha.php
- update the App:import
- update the $imagesPath variable

When I run /controller/captcha_image I get an error saying that the view does not exist.

Do I need to create a views/controller/captcha_image.ctp ? If so what do I need to insert into that?

Great plugin though - just wish I could get it to work :(
Posted May 17, 2009 by Bryan Paddock
 

Bug

30 Same Problem

i also get the same problem, Image is not shown in myn browser only image reload link only shown..

Can anyone pleasce help me out....
Posted Jun 5, 2009 by Madhan