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
Download code
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:
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($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:
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
Comment
1 Nice Work
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
Question
2 I cant get it to work
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?
Comment
3 I get it to work
very great component! thanks Spout.
i realize that after debug step by step the vendor captcha php.
Bug
4 FireFox is unable to work
Thank!!
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
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!
Comment
6 Captcha with CakePHP 1.2
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.
Question
7 reload image not working in Internet Explorer
Can any body suggest me actualy where i am wrong
Waiting for a reply
Question
8 Implementation
Your help is greatly appreciated.
Thank you.
Comment
9 v1.2
seems like the response headers are already sent and php-captcha.inc.php kannt set the mime-type header to image/jpg
Comment
10 solved
der was an space after my closing ?> tag in captcha.php which caused the headers to be send...
:-)
Comment
11 great component
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 :-)
Question
12 Problem to get this working
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?
Question
13 additional info
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 ^^ )
Question
14 Cant download Component
Comment
15 Working on 1.2
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();
}
Question
16 Problem to show the validation error for PhpCaptcha
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
Question
17 Problem With Add multiple component with Captcha.
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
Comment
18 Problem With Add multiple component with Captcha
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.
Comment
19 Headers and SESSION
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
Comment
20 reload image
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 ?
Comment
21 It works, cool
Question
22 Fatal Error Call to undefined Function
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
Comment
23 I solved it
Question
24 I see no Picture
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.
Comment
25 Solution to this problem
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.
Question
26 Can't get image
It shows me imagebox but I cant found image..
I tried almost every thing but cant get image..
Please help me out..
Comment
27 Component Problem
Only the reload image is shown.. help pls
Comment
28 Hey guys try this...
2) In controllers/components/captcha.php change the line
vendor('phpcaptcha'.DS.'php-captcha.inc');
to
App::import('Vendor', 'phpcaptcha/phpcaptcha');
Hope that works.
Question
29 View not found 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 :(
Bug
30 Same Problem
Can anyone pleasce help me out....