Simple captcha component for CakePHP (New)
Updated on – December 23, 2011
Follow these simple steps to make it working. (I assume that someone trying it has proficient knowledge of CakePHP framework. I may or may not help in problems which are related to knowledge of CakePHP rather than component itself).
Copy attached font file (monofont) to ‘webroot’ folder.
Copy component file (captcha.php) to app/controllers/components
Create a function similar to the following in your controller. (NOTE: I have used “signups” controller for demonstration purpose only. You should change controller name accordingly.)
function captcha() {
$this->autoRender = false;
$this->layout='ajax';
if(!isset($this->Captcha)) { //if Component was not loaded throug $components array()
App::import('Component','Captcha'); //load it
$this->Captcha = new CaptchaComponent(); //make instance
$this->Captcha->startup($this); //and do some manual calling
}
//$width = isset($_GET['width']) ? $_GET['width'] : '120';
//$height = isset($_GET['height']) ? $_GET['height'] : '40';
//$characters = isset($_GET['characters']) && $_GET['characters'] > 1 ? $_GET['characters'] : '6';
//$this->Captcha->create($width, $height, $characters); //options, default are 120, 40, 6.
$this->Captcha->create();
}
Call the captcha action from within your img tag in the view file as below:
echo $form->create("Signups");
echo $html->image($html->url(array('controller'=>'signups', 'action'=>'captcha'), true),array('style'=>'','vspace'=>2)); ?>
echo 'Enter the given security code:';
echo $form->input('Signup.captcha',array('autocomplete'=>'off','label'=>false,'class'=>'','error'=>__('Failed validating code',true)));
echo $form->submit(__(' Submit ',true));
echo $form->end();
And you are done! The captcha image should look like ![]()
Also, you can re-generate the captcha by adding (replacing code in line 2 of the above) ajax code something similar to the following:
<div id="captchaID" ><?php
echo $html->image($html->url(array('controller'=>'signups', 'action'=>'captcha'), true),array('style'=>'','vspace'=>2)); ?></div>
<?php echo $ajax->link('Can not read this code? Reload.','regenerate code',array('url'=>'reload_captcha','update'=>'captchaID')); ?>
In the code above it calls a reload_captcha function of the current controller. You can place reload_captcha in current controller or preferrably in the app_controller to make it available universally. Here’s the code:
function reload_captcha() {
App::import('Component','Captcha'); //load it
$this->Captcha = new CaptchaComponent(); //make instance
$this->Captcha->startup($this); //and do some manually calling
$this->layout='ajax';
Configure::write('debug',0);
$this->viewPath = 'elements'.DS;
$this->render('reload_captcha');
}
Obviousaly it renders a reload_captcha element. So create a reload_captcha.ctp file and place it in views/elements with the following code in it:
<?php echo $html->image($html->url(array('controller'=>'signups', 'action'=>'captcha'), true),array('style'=>'','vspace'=>2)); ?>
There is model validation code included in the files with example of how to validate it. Files include a model with new validation entry along with two function.
You can see it in working here. Let me know if you discover any issue while implementing it. Your suggestions to improve it are always welcome.
Possibly Related posts:
- Simple captcha component for CakePHP
This post is deprecated. Please check this post instead. Captcha is the basic necessity in today’s data submission processes where numerous spammers are looking for... - TinyMce and Captcha collide in my cakephp application
I was struck in a very strange problem today. I was using captcha component to create and set a captcha session and image for view... - getid3 component for cakephp
What is getID3? getID3() is an open-source, cross-platform software library for the PHP language written by James Heinrich and Allan Hansen. getID3() can extract information... - Security component black hole, form submit dies on a blank page with no error
The problem started when i used Auth component in my current CakePHP project. Everything seemed working fine until i created an html form, submitted it... - Cakephp important facts you must know – Part 3
You load a plugin model like this: $this->loadModel(“Forum.Topic”) You output requestAction result using $this->requestAction(array(‘controller’ => ‘articles’, ‘action’ => ‘featured’), array(‘return’)); // see array(‘return’) In controller,...
If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.






Hi..i would like to share in Display problem in captcha in cakephp2.0
I change something in captcha.php in controller/component folder
1. I rename captcha.php into CaptchaComponent.php
2. class CaptchaComponent extend Component … instead of “Object”
3. there is an error in:
function startup( &$controller ) {
$this->Controller =& $controller;
}
.. delete the “&” in it would be like this $this->Controller = $controller
and there the captcha showed up!.. I HOPE IT HELP!
Great component! Thumbs up!
There is already an example included in the signup Modal. If you check around:
var $validate = array(
‘captcha’=>array(
‘rule’ => array(‘matchCaptcha’)
),
);
function matchCaptcha($inputValue) {
return $inputValue['captcha']==$this->getCaptcha(); //return true or false after comparing submitted value with set value of captcha
}
I hope that helps.
great component!
After editing captcha.php component like WWW_ROOT.DS.$this->font, it all worked fine for me. Well, not the reload stuff.
I am just wondering how to validate the captcha. I played around with this: ‘captcha’=>array(
‘rule’ => array(‘equalTo’, $this->captcha),
‘message’ => ‘You lie!’,
‘allowEmpty’ => false
)
And its just not working. but i dont know why
great component!
After editing captcha.php component like WWW_ROOT.DS.$this->font, it all worked fine for me. Well, not the reload stuff.
i am just wondering how to validate the captcha. I played around with
Hi Amir,
Apologies for late reply. I didn’t get sufficient time yet to make it working with 2.0. I think i will do it soon.
Thanks,
Arvind.
Hi, Thanks for your great component.I need it for cakephp2. Can you help me to use your great component in cakephp2?
Thanks alot
@m16u – No. No 2.0 version yet.. I am hoping for someone make a 2.0 version of it and post it. Anyways I will check if i get time in near future to do it.
For someone who follows the 2.0 migration guide it should not be very difficult to make it working with 2.0 in no time.
hi, there is a cakephp 2 version???
I got this to work except for the reload part. I am using cake 2 and changed the reload code to the following:
Js->link(‘Can not read this code? Reload.’, ‘add’, array(‘update’=>’captchaID’)); ?>
… this refreshes the whole form so the users data is lost.
I also tried putting reload_captcha into the Elements folder and tried the following:
Js->link(‘Can not read this code? Reload.’, ‘reload_captcha’, array(‘update’=>’captchaID’)); ?>
.. but this just causes the captcha to display on it’s own without the form.
Thanks a lot for such a simple captcha..
I am working on my cakePHP 1.3 in ubuntu OS..My images are not displaying with captcha..I tried signup controller and its related file…Even if i am not getting any error i have this problem with my project
1.Result I got when i submit captcha form empty:Captcha code validated!
2.Captcha image is not displayed
3.I am working in local.And i checked font permission and tried executing with all possible debug value…But no way out..
Can you please help me
@Binoy – Still need some work in order to make it working with cakephp 2.0
Got it working.
1. You have to apply random string (or time stamp) to the src as parameter to prevent caching.
2. For IE, AJAX request caching must be disabled (explicit)… gotta love IE
Hi Arvind,
I’ve tried the demo of your captcha implementation @ givebackindia.com and the reload function is not working under Firefox 9, Opera 11.6 and IE 8. It appears to be working only under Chrome.
Add WWW_ROOT . DS before $this->font in imagettfbbox and in imagettftext. which will solve imagettfbbox(): Could not find/open font error
Tried to use with cakephp2.0
showing error
call_user_func_array() expects parameter 1 to be a valid callback, class ‘CaptchaComponent’ does not have a method ‘initialize’
Hi Arvind,
Thank for your quick response.
Anyway, I have fixed that issue. That was just a small issue of Out Buffer.
But, finally its work like a charm.
Thanks for such a nice component.
What is the src of your captcha image in your view?
hi arvind,
First of all thanks for a nice component. !!
But i am getting some problem to display a image captcha on my one of the project.even i have done all the required steps to integrate it.but still image is not displaying on my captcha form.
it would be great if you can help me here.
Thank in Advance.
Did you solve it, yet?
hi can u plz help me the captcha image is not getting displayed on my site
Try uploading and replacing the font file again in binary mode rather than automatic or ascii mode. (Your FTP client might have those options). If it still does not work try using some other font file.
Hi, I have the same problem as @chellapa.. monofont.tff have all permits, how can I fix it?
Im usin 1.3.10
Thank’s!
thnx ,,it has done my job
Grate article..
Its helped a lot for me.. Thank you very much
@chellapa – check that you have font file named monofont.ttf in your webroot folder and it is accessible.
hi there,
while using this captcha following error occurs
Warning (2): imagettfbbox() [http://php.net/function.imagettfbbox]: Could not find/open font [APP/controllers/components/captcha.php, line 51]
could u pls tell me the way to fix it?
Can you provide a url to your page?
Hi,
I am able to view the captcha string while debugging SESSION .. but I am not able to view any image .. I have checked the font file .. I am able to view it from browser
Simple and Great example of Captcha in CakePHP
Excellent example of Captcha in CakePHP. Thanks a lot
Thank you for this awesome component!
Had it running in a couple of minutes on my Cake 1.3 projekt.
Clean and simple to set up, i love it.
For those who cant get the captcha image show up, make sure the captcha action is accessable by cake.
Maybe you need to set a $this->Auth->allow(‘captcha’); in your beforeFilter() Function in your controller, if youre using admin routing.
Thanks again Arvind, best Captcha for Cake yet imho.
@HT – This is only an idea of how to re-generate the captcha. You may have to supply proper controller and action of captcha. For example if your controller name is “users” and captcha action name is “captcha” only then this url users/captcha is valid. Also you should have some knowledge of showing view content with the help of ajax. As you said you are new i would suggest you to just skip the “re-generate” thing, the characters shown in captcha are quite clear to read i guess.
I try to re-generate captcha, but have an error missing view, I don’t know why. Maybe I don’t understand your code want to do.
link(‘Can not read this code?’,'re-generate captcha’,array(‘url’=>’users/captcha’,'update’=>’captchaID’,'loading’=>’do this’,'loaded’=>’do that’)); ?>
Can you explain it clearly? What is ‘re-generate captcha’? (I’m new) Thanks
@Urdesh – It is working just fine with 1.3.7. You can see it here http://www.rfdf.org/signup/student/account_information.
Try accessing http://yourhost/yourcontroller/captcha and see what happens.. Try view source in debug=1 mode. Should help to figure it out. Let me know if you find any bug or anything. Thanks, Arvind.
It is not working properly with cakePHP 1.3.Image is not displaying.
@Forst – I think you have got my email id.. If you wish you can send me your controller, component and view files so i could try to find out the issue for you. This captcha component is working just fine on number of websites hosted on linux with similar configuration to as you mention.
@To All,
I uploaded latest package today on 03 March, 2011. add.ctp file was modified for the image url. In the previous version it had $html->url(‘captcha’, true) assuming that you were on the same view file of the resident controller i.e. “signups”. I have replace it with more explanatory $html->url(array(‘controller’=>’signups’, ‘action’=>’captcha’)).
You can even set this image source as a string, that is something like:
image(“http://yourdomain.com/yourcontrollername/captcha”,array(‘style’=>”,’vspace’=>2)); ?>.
Or even:
<img src=”http://yourdomain.com/yourcontrollername/captcha” /> should equally work.
I work fine locally on my pc with wamp (with php 5.3 ) but on my server (linux, php 5.2.6) , the captcha is not displayed . I saw that Php GD is correctly installed.
I don’t understand
@Forst
There must be some error or anything at least. Do you try it while debug=2?
Fyi, in the view file where you want to show captcha, you must have to set the correct path of capthca image. The “captcha” action of “signups” controller outputs captcha image so your captcha image source in your view file must include correct controller name and captcha action name. For example if you place captcha action inside you users controller, in your view file you should call captcha something like this (while referring to line 5 of views/signups/add.ctp file in original package):
<?php echo $html->image($html->url(array('controller'=>'users', 'action'=>'captcha'), true),array('style'=>'','vspace'=>2)); ?>I hope that helps.
This component is “TESTED OK” with CakePHP 1.3.7.
Thanks , I’ve no error but I had a other problem: the image was not displayed..
@Forst – try to open font file using url, that is, http://yoursite.com/fontfilename and see what happens. This is certainly something related to file structure, access rights etc., i don’t think it has something to do with the captcha component itself.
My ‘ webroot’ directory is already have read permissions because i have also image, css and other on this directory
@Forst – Please check that your ‘webroot’ directory and font file have proper ‘read’ permissions.
I have problem with font dir , i’ve placed monofont.ttf in the directory ‘webroot’ but I have this error :
”
Warning (2): imagettfbbox() [function.imagettfbbox]: Could not find/open font [APP/controllers/components/captcha.php”
@Ahmad
Can you or can’t you? If you can, i guess you do include Captcha in $components array at the top of controller. Do you? Anyway i am adding new updated code with entire directory structure with corresponding files. This one is more clearer and also i have included model validation in this one.
I have cakephp 1.2
when I remove this line
$this->Captcha = new CaptchaComponent();
I can write/read the security code into the session
Great plugin. Just required to add the the form helper in the controller in cake 1.3.
Great work though…
Fyi, if you are including “Captcha” component in your controller’s var $components variable (at the top of controller) you must do $this->Captcha->controller = $this just before calling the $this->Captcha->create() method to access the Session property of the controller (required to create the session variable ’security_code’).
$this->Captcha->controller = $this ??? what’s the continuation?
Hi Arvind,
I guess the problem is I don’t set var $validate, but declare the validation rules inside the __construct() function, (because __(”, true) doesn’t work in var declarations!)
The rest is the same though…
I tried to declare var $validate but doesn’t allow ‘rule’ => array(‘equalTo’, $this->captcha) either, so I am forced to declare it in __constrcut(). but then there is the problem of setting the $this->captcha value before it created the validation rule.
The only solution I could think of was to create the validation rule in the beforeValidate function.
You are right that beforeValidate is called automatically
Thanks for support and all!
Sorry for the confusion, Pim. The suggestion i offered is only in the context of code written by you. Let me explain.
In controller you still need
$this->User->setCaptchaCode($this->Session->read('security_code'));
before calling save function and
private $captchin the model as well.Skipping the use of beforeValidate you could simply define ‘captcha’ rule in User model’s $validate property along with other rules you may have as below:
//validation rules start
var $validate = array(
....................................
....................................
'captcha'=>array(
'rule' => array('equalTo', $this->captcha),
'message' => __('Captcha verification failure', true)
)
....................................
....................................
); //validation rules end
And it should work just fine.
Eventually this is exactly what you had been doing so far, i just wanted to skip the user of beforeValidate there. Anyway never mind it
Hi Arvind,
I wonder how you set the $this->captcha property, especially where and when.
If I change my code, i.e. removing the beforeValidation call from the controller and function from the model(since there is nothing else in my case to do there) and move the validation from the beforeValidation function to the __construct() and leave everything else the same, the validation fails because $this->captcha is null.
Btw i’m fairly new to CakePHP but the code i provided in my previous post worked fine for me
Hi Pim,
Thanks for your thoughts. This is exactly what i did except once change. I did not use beforeValidate.
I don’t think we need a check inside beforeValidate function. In fact a validation rule runs if the submitted form data has that particular field set within which we create a rule for. So just adding a rule should be okay. This is what i mean and doing here without any issue.
//validation rules start
var $validate = array(
....................................
....................................
'captcha'=>array(
'rule' => array('equalTo', $this->captcha),
'message' => __('Captcha verification failure', true)
)
....................................
....................................
); //validation rules end
And then of course you would not need to call $this->User->beforeValidate(); in your controller. In fact we don’t need to call the callback functions like beforeValidate, beforeSave, AfterSave etc manually as they are called automatically. Don’t they?
First of all, I want to thank you for sharing this!
Since all the validation rules are check in the model, I wanted to check the captcha code in the model also.
To do so I did the following:
in the action in the controller that is called when you submit the form I added these lines:
$this->User->create();
$this->User->setCaptchaCode($this->Session->read('security_code'));
$this->User->beforeValidate();
User model:
Add this at the top:
private $captcha = null;
create this method:
function setCaptchaCode($captcha) {
$this->captcha = $captcha;
}
finaly, add this piece of code to the beforeValidate function:
if(isset($this->captcha)) {
$this->validate['captcha'] = array(
'rule' => array('equalTo', $this->captcha),
'message' => __('Captcha verification failure', true)
);
}
Hope this helps someone
Happy baking
So let me explain. I have Captcha controller with the funti on Captchatest. The Captchatest has
App::import('Component','Captcha');$this->Captcha->controller = $this;
$this->Captcha->create();
in the contacts controller i am using the component Captcha as well as Session. In the view of contacts i use
echo $html->image('http://www.site.com/captcha/captchatest', array('style'=>'border:1px #ccc solid','vspace'=>2));to load the captcha image and it works … but when i try to see the generated code in the contact us controller fails.P.S. I did some changes to the Captcha Component:
Replaced
————————————————–
function CaptchaComponent( $controller ) {
$this->controller = $controller;
}
—————————————————
With
—————————————————
function startup($controller)
{
$this->controller = $controller;
}
It should simply be accessible using $this->Session->read(’security_code’) in any controller provided the component is able to create ’security_code’ session variable successfully (see $this->controller->Session->write(‘security_code’,$code) near the bottom of the component file)
Fyi, if you are including “Captcha” component in your controller’s var $components variable (at the top of controller) you must do $this->Captcha->controller = $this just before calling the $this->Captcha->create() method to access the Session property of the controller (required to create the session variable ’security_code’).
The session variable is not passed on from captcha.php… can you show me an example how to verify the $this->Session->read(’security_code’) in other controllers for ex.
Thanks