CCaptchaAction
Package | system.web.widgets.captcha |
---|---|
Inheritance | class CCaptchaAction » CAction » CComponent |
Implements | IAction |
Since | 1.0 |
Source Code | framework/web/widgets/captcha/CCaptchaAction.php |
CCaptchaAction is used together with CCaptcha and CCaptchaValidator to provide the CAPTCHA feature.
You must configure properties of CCaptchaAction to customize the appearance of the generated image.
Note, CCaptchaAction requires PHP GD2 extension.
Using CAPTCHA involves the following steps:
- Override CController::actions() and register an action of class CCaptchaAction with ID 'captcha'.
- In the form model, declare an attribute to store user-entered verification code, and declare the attribute to be validated by the 'captcha' validator.
- In the controller view, insert a CCaptcha widget in the form.
Public Properties
Property | Type | Description | Defined By |
---|---|---|---|
backColor | integer | the background color. | CCaptchaAction |
backend | string | the graphic extension that will be used to draw CAPTCHA image. | CCaptchaAction |
controller | CController | the controller who owns this action. | CAction |
fixedVerifyCode | string | the fixed verification code. | CCaptchaAction |
fontFile | string | the TrueType font file. | CCaptchaAction |
foreColor | integer | the font color. | CCaptchaAction |
height | integer | the height of the generated CAPTCHA image. | CCaptchaAction |
id | string | id of this action | CAction |
maxLength | integer | the maximum length for randomly generated word. | CCaptchaAction |
minLength | integer | the minimum length for randomly generated word. | CCaptchaAction |
offset | integer | the offset between characters. | CCaptchaAction |
padding | integer | padding around the text. | CCaptchaAction |
testLimit | integer | how many times should the same CAPTCHA be displayed. | CCaptchaAction |
transparent | boolean | whether to use transparent background. | CCaptchaAction |
verifyCode | string | Gets the verification code. | CCaptchaAction |
width | integer | the width of the generated CAPTCHA image. | CCaptchaAction |
Protected Properties
Property | Type | Description | Defined By |
---|---|---|---|
sessionKey | string | Returns the session variable name used to store verification code. | CCaptchaAction |
Public Methods
Method | Description | Defined By |
---|---|---|
__call() | Calls the named method which is not a class method. | CComponent |
__construct() | Constructor. | CAction |
__get() | Returns a property value, an event handler list or a behavior based on its name. | CComponent |
__isset() | Checks if a property value is null. | CComponent |
__set() | Sets value of a component property. | CComponent |
__unset() | Sets a component property to be null. | CComponent |
asa() | Returns the named behavior object. | CComponent |
attachBehavior() | Attaches a behavior to this component. | CComponent |
attachBehaviors() | Attaches a list of behaviors to the component. | CComponent |
attachEventHandler() | Attaches an event handler to an event. | CComponent |
canGetProperty() | Determines whether a property can be read. | CComponent |
canSetProperty() | Determines whether a property can be set. | CComponent |
detachBehavior() | Detaches a behavior from the component. | CComponent |
detachBehaviors() | Detaches all behaviors from the component. | CComponent |
detachEventHandler() | Detaches an existing event handler. | CComponent |
disableBehavior() | Disables an attached behavior. | CComponent |
disableBehaviors() | Disables all behaviors attached to this component. | CComponent |
enableBehavior() | Enables an attached behavior. | CComponent |
enableBehaviors() | Enables all behaviors attached to this component. | CComponent |
evaluateExpression() | Evaluates a PHP expression or callback under the context of this component. | CComponent |
generateValidationHash() | Generates a hash code that can be used for client side validation. | CCaptchaAction |
getController() | Returns the controller who owns this action. | CAction |
getEventHandlers() | Returns the list of attached event handlers for an event. | CComponent |
getId() | Returns id of this action | CAction |
getVerifyCode() | Gets the verification code. | CCaptchaAction |
hasEvent() | Determines whether an event is defined. | CComponent |
hasEventHandler() | Checks whether the named event has attached handlers. | CComponent |
hasProperty() | Determines whether a property is defined. | CComponent |
raiseEvent() | Raises an event. | CComponent |
run() | Runs the action. | CCaptchaAction |
runWithParams() | Runs the action with the supplied request parameters. | CAction |
validate() | Validates the input to see if it matches the generated code. | CCaptchaAction |
Protected Methods
Method | Description | Defined By |
---|---|---|
generateVerifyCode() | Generates a new verification code. | CCaptchaAction |
getSessionKey() | Returns the session variable name used to store verification code. | CCaptchaAction |
renderImage() | Renders the CAPTCHA image based on the code using library specified in the $backend property. | CCaptchaAction |
renderImageGD() | Renders the CAPTCHA image based on the code using GD library. | CCaptchaAction |
renderImageImagick() | Renders the CAPTCHA image based on the code using ImageMagick library. | CCaptchaAction |
runWithParamsInternal() | Executes a method of an object with the supplied named parameters. | CAction |
Property Details
backColor property
public integer $backColor;
the background color. For example, 0x55FF00. Defaults to 0xFFFFFF, meaning white color.
backend property (available since v1.1.13)
public string $backend;
the graphic extension that will be used to draw CAPTCHA image. Possible values are 'gd', 'imagick' and null. Null value means that fallback mode will be used: ImageMagick is preferred over GD. Default value is null.
fixedVerifyCode property (available since v1.1.4)
public string $fixedVerifyCode;
the fixed verification code. When this is property is set, getVerifyCode will always return this value. This is mainly used in automated tests where we want to be able to reproduce the same verification code each time we run the tests. Defaults to null, meaning the verification code will be randomly generated.
fontFile property
public string $fontFile;
the TrueType font file. Defaults to SpicyRice.ttf which is provided with the Yii release. Note that non-free Duality.ttf has been changed to open/free SpicyRice.ttf since 1.1.14.
foreColor property
public integer $foreColor;
the font color. For example, 0x55FF00. Defaults to 0x2040A0 (blue color).
height property
public integer $height;
the height of the generated CAPTCHA image. Defaults to 50.
maxLength property
public integer $maxLength;
the maximum length for randomly generated word. Defaults to 7.
minLength property
public integer $minLength;
the minimum length for randomly generated word. Defaults to 6.
offset property (available since v1.1.7)
public integer $offset;
the offset between characters. Defaults to -2. You can adjust this property in order to decrease or increase the readability of the captcha.
padding property
public integer $padding;
padding around the text. Defaults to 2.
sessionKey property read-only
protected string getSessionKey()
Returns the session variable name used to store verification code.
testLimit property
public integer $testLimit;
how many times should the same CAPTCHA be displayed. Defaults to 3. A value less than or equal to 0 means the test is unlimited (available since version 1.1.2).
transparent property
public boolean $transparent;
whether to use transparent background. Defaults to false.
verifyCode property read-only
public string getVerifyCode(boolean $regenerate=false)
Gets the verification code.
width property
public integer $width;
the width of the generated CAPTCHA image. Defaults to 120.
Method Details
generateValidationHash() method (available since v1.1.7)
public string generateValidationHash(string $code) | ||
$code | string | the CAPTCHA code |
{return} | string | a hash code generated from the CAPTCHA code |
public function generateValidationHash($code)
{
for($h=0,$i=strlen($code)-1;$i>=0;--$i)
$h+=ord($code[$i]);
return $h;
}
Generates a hash code that can be used for client side validation.
generateVerifyCode() method
protected string generateVerifyCode() | ||
{return} | string | the generated verification code |
protected function generateVerifyCode()
{
if($this->minLength > $this->maxLength)
$this->maxLength = $this->minLength;
if($this->minLength < 3)
$this->minLength = 3;
if($this->maxLength > 20)
$this->maxLength = 20;
$length = mt_rand($this->minLength,$this->maxLength);
$letters = 'bcdfghjklmnpqrstvwxyz';
$vowels = 'aeiou';
$code = '';
for($i = 0; $i < $length; ++$i)
{
if($i % 2 && mt_rand(0,10) > 2 || !($i % 2) && mt_rand(0,10) > 9)
$code.=$vowels[mt_rand(0,4)];
else
$code.=$letters[mt_rand(0,20)];
}
return $code;
}
Generates a new verification code.
getSessionKey() method
protected string getSessionKey() | ||
{return} | string | the session variable name |
protected function getSessionKey()
{
return self::SESSION_VAR_PREFIX . Yii::app()->getId() . '.' . $this->getController()->getUniqueId() . '.' . $this->getId();
}
Returns the session variable name used to store verification code.
getVerifyCode() method
public string getVerifyCode(boolean $regenerate=false) | ||
$regenerate | boolean | whether the verification code should be regenerated. |
{return} | string | the verification code. |
public function getVerifyCode($regenerate=false)
{
if($this->fixedVerifyCode !== null)
return $this->fixedVerifyCode;
$session = Yii::app()->session;
$session->open();
$name = $this->getSessionKey();
if($session[$name] === null || $regenerate)
{
$session[$name] = $this->generateVerifyCode();
$session[$name . 'count'] = 1;
}
return $session[$name];
}
Gets the verification code.
renderImage() method
protected void renderImage(string $code) | ||
$code | string | the verification code |
protected function renderImage($code)
{
if($this->backend===null && CCaptcha::checkRequirements('imagick') || $this->backend==='imagick')
$this->renderImageImagick($code);
else if($this->backend===null && CCaptcha::checkRequirements('gd') || $this->backend==='gd')
$this->renderImageGD($code);
}
Renders the CAPTCHA image based on the code using library specified in the $backend property.
renderImageGD() method (available since v1.1.13)
protected void renderImageGD(string $code) | ||
$code | string | the verification code |
protected function renderImageGD($code)
{
$image = imagecreatetruecolor($this->width,$this->height);
$backColor = imagecolorallocate($image,
(int)($this->backColor % 0x1000000 / 0x10000),
(int)($this->backColor % 0x10000 / 0x100),
$this->backColor % 0x100);
imagefilledrectangle($image,0,0,$this->width,$this->height,$backColor);
imagecolordeallocate($image,$backColor);
if($this->transparent)
imagecolortransparent($image,$backColor);
$foreColor = imagecolorallocate($image,
(int)($this->foreColor % 0x1000000 / 0x10000),
(int)($this->foreColor % 0x10000 / 0x100),
$this->foreColor % 0x100);
if($this->fontFile === null)
$this->fontFile = dirname(__FILE__).DIRECTORY_SEPARATOR.'SpicyRice.ttf';
$length = strlen($code);
$box = imagettfbbox(30,0,$this->fontFile,$code);
$w = $box[4] - $box[0] + $this->offset * ($length - 1);
$h = $box[1] - $box[5];
$scale = min(($this->width - $this->padding * 2) / $w,($this->height - $this->padding * 2) / $h);
$x = 10;
$y = round($this->height * 27 / 40);
for($i = 0; $i < $length; ++$i)
{
$fontSize = (int)(rand(26,32) * $scale * 0.8);
$angle = rand(-10,10);
$letter = $code[$i];
$box = imagettftext($image,$fontSize,$angle,$x,$y,$foreColor,$this->fontFile,$letter);
$x = $box[2] + $this->offset;
}
imagecolordeallocate($image,$foreColor);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Transfer-Encoding: binary');
header("Content-Type: image/png");
imagepng($image);
imagedestroy($image);
}
Renders the CAPTCHA image based on the code using GD library.
renderImageImagick() method (available since v1.1.13)
protected void renderImageImagick(string $code) | ||
$code | string | the verification code |
protected function renderImageImagick($code)
{
$backColor=$this->transparent ? new ImagickPixel('transparent') : new ImagickPixel(sprintf('#%06x',$this->backColor));
$foreColor=new ImagickPixel(sprintf('#%06x',$this->foreColor));
$image=new Imagick();
$image->newImage($this->width,$this->height,$backColor);
if($this->fontFile===null)
$this->fontFile=dirname(__FILE__).DIRECTORY_SEPARATOR.'SpicyRice.ttf';
$draw=new ImagickDraw();
$draw->setFont($this->fontFile);
$draw->setFontSize(30);
$fontMetrics=$image->queryFontMetrics($draw,$code);
$length=strlen($code);
$w=(int)($fontMetrics['textWidth'])-8+$this->offset*($length-1);
$h=(int)($fontMetrics['textHeight'])-8;
$scale=min(($this->width-$this->padding*2)/$w,($this->height-$this->padding*2)/$h);
$x=10;
$y=round($this->height*27/40);
for($i=0; $i<$length; ++$i)
{
$draw=new ImagickDraw();
$draw->setFont($this->fontFile);
$draw->setFontSize((int)(rand(26,32)*$scale*0.8));
$draw->setFillColor($foreColor);
$image->annotateImage($draw,$x,$y,rand(-10,10),$code[$i]);
$fontMetrics=$image->queryFontMetrics($draw,$code[$i]);
$x+=(int)($fontMetrics['textWidth'])+$this->offset;
}
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Transfer-Encoding: binary');
header("Content-Type: image/png");
$image->setImageFormat('png');
echo $image->getImageBlob();
}
Renders the CAPTCHA image based on the code using ImageMagick library.
run() method
public void run() |
public function run()
{
if(isset($_GET[self::REFRESH_GET_VAR])) // AJAX request for regenerating code
{
$code=$this->getVerifyCode(true);
echo CJSON::encode(array(
'hash1'=>$this->generateValidationHash($code),
'hash2'=>$this->generateValidationHash(strtolower($code)),
// we add a random 'v' parameter so that FireFox can refresh the image
// when src attribute of image tag is changed
'url'=>$this->getController()->createUrl($this->getId(),array('v' => uniqid())),
));
}
else
$this->renderImage($this->getVerifyCode());
Yii::app()->end();
}
Runs the action.
validate() method
public boolean validate(string $input, boolean $caseSensitive) | ||
$input | string | user input |
$caseSensitive | boolean | whether the comparison should be case-sensitive |
{return} | boolean | whether the input is valid |
public function validate($input,$caseSensitive)
{
$code = $this->getVerifyCode();
$valid = $caseSensitive ? ($input === $code) : strcasecmp($input,$code)===0;
$session = Yii::app()->session;
$session->open();
$name = $this->getSessionKey() . 'count';
$session[$name] = $session[$name] + 1;
if($session[$name] > $this->testLimit && $this->testLimit > 0)
$this->getVerifyCode(true);
return $valid;
}
Validates the input to see if it matches the generated code.
© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc/api/1.1/CCaptchaAction