2009年3月21日星期六

Re: [fw-core] My_Captcha_Image

*SOLVED* and found a bug or strange behavior

Hi Matthew, the problem was not the use of a relative path to the font, but
the fact that I needed to pass an array of options to my custom captcha
image adapter. Here is what worked for me based on my previous code:

<?php
class TakeFoodOut_SignupForm extends Zend_Form
{
public function init()
{
// add the captcha element
$this->addElement('captcha', 'captcha', array(
'label' => 'Word Verification',
'description' => 'Please verify that you are human',
'helper' => null,
'order' => 4,
'captcha' => array(
'captcha' => 'Image',
'wordLen' => 6,
'timeout' => 300,
'font' => 'pics/captcha/DeJaVuSansMono.ttf',
'fontSize' => 30,
'imgDir' => 'pics/captcha/img',
'imgUrl' => 'http://takefoodout/pics/captcha/img'
)
));
$this->getElement('captcha')
->setCaptcha(new TakeFoodOut_Captcha_Image(array(
'captcha'=>'Image',
'wordLen' => 6,
'timeout' => 300,
'font' => 'pics/captcha/DeJaVuSansMono.ttf',
'fontSize' => 30,
'imgDir' => 'pics/captcha/img',
'imgUrl' => 'http://takefoodout/pics/captcha/img'
)));
}
}

Note how the instance of TakeFoodOut_Captcha_Image is passed an array of
options including the font. I think what confused me was that I was already
passing an array of options to addElement() so I didn't think that I needed
to do it again in setConfig().

Now I would like to share my preferred way of creating a captcha element
using a custom captcha image adapter and addPrefixPath(). I would also like
to explain a potential bug when you use this method and how to avoid the
bug. Please take a look at two versions of my code. The commented code is
just another way of writing the code above it. The first one causes a bug,
and the second one works fine.

Buggy:
<?php
class TakeFoodOut_SignupForm extends Zend_Form
{
public function init()
{
$this->addElement(new Zend_Form_Element_Captcha('captcha',
array('captcha'=>'Image')));
// OR $this->addElement('captcha', 'captcha', array('captcha' =>
'Image'));
// OR $this->addElement('captcha', 'captcha', array('captcha'=>
array('captcha' => 'Image')));

$this->getElement('captcha')
->addPrefixPath('TakeFoodOut_Captcha', 'TakeFoodOut/Captcha/', 'captcha')
->setOptions(array(
'label' => 'Word Verification',
'description' => 'Please verify that you are human',
'helper' => null,
'order' => 4
))
->setCaptcha('Image', array('font'=>'images/font/DeJaVuSansMono.ttf'));
/* OR
$this->getElement('captcha')
->addPrefixPath('TakeFoodOut_Captcha', 'TakeFoodOut/Captcha/', 'captcha')
->setOptions(array(
'label' => 'Word Verification',
'description' => 'Please verify that you are human',
'helper' => null,
'order' => 4,
'captcha' => array(
'captcha'=>'Image',
'wordLen' => 6,
'timeout' => 300,
'font' => 'pics/captcha/DeJaVuSansMono.ttf',
'fontSize' => 30,
'imgDir' => 'pics/captcha/img',
'imgUrl' => 'http://takefoodout/pics/captcha/img'
)
));
*/
}
}

Works fine:
<?php
class TakeFoodOut_SignupForm extends Zend_Form
{
public function init()
{
$this->addElement(new Zend_Form_Element_Captcha('captcha',
array('captcha'=>'Image')));
// OR $this->addElement('captcha', 'captcha', array('captcha' =>
'Image'));
// OR $this->addElement('captcha', 'captcha', array('captcha'=>
array('captcha' => 'Image')));

$this->getElement('captcha')
->addPrefixPath('TakeFoodOut_Captcha', 'TakeFoodOut/Captcha/', 'captcha')
->setOptions(array(
'label' => 'Word Verification',
'description' => 'Please verify that you are human',
'helper' => null,
'order' => 4
))
->setCaptcha('Foo', array('font'=>'images/font/DeJaVuSansMono.ttf'));
/* OR
$this->getElement('captcha')
->addPrefixPath('TakeFoodOut_Captcha', 'TakeFoodOut/Captcha/', 'captcha')
->setOptions(array(
'label' => 'Word Verification',
'description' => 'Please verify that you are human',
'helper' => null,
'order' => 4,
'captcha' => array(
'captcha'=>'Foo',
'wordLen' => 6,
'timeout' => 300,
'font' => 'pics/captcha/DeJaVuSansMono.ttf',
'fontSize' => 30,
'imgDir' => 'pics/captcha/img',
'imgUrl' => 'http://takefoodout/pics/captcha/img'
)
));
*/
}
}

Notice the difference between the two codes? They are exactly the same
except for setConfig() method:

Buggy: setCaptcha('Image', array('font'=>'images/font/DeJaVuSansMono.ttf'));
Works fine: setCaptcha('Foo',
array('font'=>'images/font/DeJaVuSansMono.ttf'));

Basically, setCaptcha('Image') calls Zend_Captcha_Image instead of
TakeFoodOut_Captcha_Image, even though I added prefix path:
addPrefixPath('TakeFoodOut_Captcha', 'TakeFoodOut/Captcha/', 'captcha'). To
prevent this from happening, I had to rename class TakeFoodOut_Captcha_Image
to class TakeFoodOut_Captcha_Foo and rename TakeFoodOut/Captcha/Image.php to
TakeFoodOut/Captcha/Foo.php. Once I made the change, it now works.

I hope this helps someone in their attempts to customize the captcha form
element. Prior to this, I thought that I can customize the captcha form
element using just form decorators. However, I now realize that there are
times when form decorators are insufficient and the only way is to create
custom captcha adapters.

Matthew Weier O'Phinney-3 wrote:
>
> -- zendlearner <kimbaudi@gmail.com> wrote
> (on Saturday, 21 March 2009, 01:26 PM -0700):
>> Thanks for your response. Unfortunately, neither 'captcha' =>
>> $captchaimage
>> nor 'captcha' => 'My_Captcha_Image' works. You seem to be on the right
>> track, but I get an exception:
>>
>> Warning: Exception caught by form: Image CAPTCHA requires font Stack
>> Trace:
>
> This is telling you exactly the problem -- you either didn't specify the
> font to use, or specified an invalid path. Looking further...
>
> <snip>
>> 'font' => 'pics/captcha/DeJaVuSansMono.ttf',
>
> ... the problem is you are using a relative path to the font... but
> you're not saying where it's relative _to_. Specify a full path to the
> font, based on some known path (document root, APPLICATION_PATH constant
> if you've set it, dirname(__FILE__) from the file where you create the
> form, whatever), and you should be fine.
>
>
> --
> Matthew Weier O'Phinney
> Software Architect | matthew@zend.com
> Zend Framework | http://framework.zend.com/
>
>

--
View this message in context: http://www.nabble.com/My_Captcha_Image-tp21663845p22642248.html
Sent from the Zend Core mailing list archive at Nabble.com.

没有评论: