Captcha component with PhpCaptcha
PhpCaptcha is a library for generating visual and audio CAPTCHAs (completely automated public Turing test to tell computers and humans apart).
Supported Features
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:
4.- Use it in your Users controller
5.- Display captcha image, in your template view:
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
And voil�
- 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:
<?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($aFonts, 200, 60);
$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:
<?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:
<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
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�








yesterday i downloaded phpcaptcha library from here, i was trying to use it in my application registeration page.
Well i was following this article for using component for phpcaptch, but i saw strange behaviour by the captcha component.
The Problem was that the captcha was showing me 5 letters and in the session variable 'php_captcha' has 6 letters, every time i reload it the image always had one letters less then the session and the result was mismatch Captcha Code.
I google it but did not find any help so i tried to see the php captcha library code, phpcatcha.php you put in /app/vendors/ dir, and here i have found that the default number of characters specified are 5, so i changed it and it worked like a charm.
see the line below i modified:
Line 53: define('CAPTCHA_NUM_CHARS', 5);
i change it to 6:
Line 53: define('CAPTCHA_NUM_CHARS', 6);
if you always get mismatched error please debug your session and check whether image letters and session letters are same or not, if not then may you can fix it by above change.
Thank you.
Can I suggest that you have white space in a php after the end of php declaration
( ie ?> ) I had this and it was inserting blank spaced as the first byte in the jpeg file
so all browser declared the image corrupt. ( the result of a bad cut and paste !!!)
You can check if this is the case by altering the controller action
function captcha_image()
{
Configure::write( 'debug', 0 );
//$this->Captcha->image(); // comment this line out for testing !!!!!
$this->autoRender = false;
}
With the line commented out - check in fire-bug and look at the size of the payload, in my case it was 1 byte .... and should be zero..
Hope this helps
I am also facing the problems as the others are facing
1) The captcha is not being generate in any version of cakephp
2) If i am using it from the webroot folder the images is being generate but the session is not working then for captcha ... and the session is being unset for the captcha .....
At last this article wasted a lot of time of mine and was useless at all ......
i am begginer in cakePHP, i can show the image but i not understand the validation..
thanks
I know I'm starting with CakePHP, but I think the installation of this component need more comments and infos. It'll be helpful ;) !
Captcha is not displayed in that form
And on line 316 imagecolordeallocate($this->oImage, $iTextColour);
This sorted the white text issue for me!
Can anyone pleasce help me out....
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 :(
2) In controllers/components/captcha.php change the line
vendor('phpcaptcha'.DS.'php-captcha.inc');
to
App::import('Vendor', 'phpcaptcha/phpcaptcha');
Hope that works.
Only the reload image is shown.. help pls
It shows me imagebox but I cant found image..
I tried almost every thing but cant get image..
Please help me out..
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.
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 2all 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
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.
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 ?
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
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.
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
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
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($aFonts, 200, 60);
$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();
}
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:
<?phpfunction captcha_image()
{
$this->layout = FALSE;
$this->Captcha->image();
}
?>
won't work.. any ideas on that?
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 ^^ )
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 :-)
seems like the response headers are already sent and php-captcha.inc.php kannt set the mime-type header to image/jpg
der was an space after my closing ?> tag in captcha.php which caused the headers to be send...
:-)
Your help is greatly appreciated.
Thank you.
Can any body suggest me actualy where i am wrong
Waiting for a reply
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.
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
I was able to validate the usual fields i added:...
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();
}
}
...
?>
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!
Thank!!
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?
very great component! thanks Spout.
i realize that after debug step by step the vendor captcha php.
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
$paramsvar 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
Comments are closed for articles over a year old