Help with Captcha - font

I wonder if anyone can help me with what is probably a fairly minor problem.

I wanted to modify the captcha so that I generated words related to the website subject matter.

Actually I am not generating words just pulling words from database, so I randomize a number if the number matches the id I just return the word.

Anyway, I am I copied the CCaptchAction.php into /extensions/sbcaptcha and renamed it SBCaptcha.php

In my controller


public function actions()

	{

		return array(

			// captcha action renders the CAPTCHA image displayed on the contact page

			'captcha'=>array(

				'class'=>'ext.sbcaptcha.SBCaptchaAction',

				'backColor'=>0x000000,

                                'foreColor'=>0xFFFF00,

                            'width'=>170,

                            'height'=>80

                          // 'fontFile'=>'application.extensions.sbcaptcha.Duality.ttf'

                          // 'fontFile'=>'ext.sbcaptcha.Duality.ttf'

			),

Anyway everything is working, the word is being displayed wiggly like it should. However I seem to be unable to use a different font. Duality.ttf is the original font so I copied that into that directory along with a couple of other fonts I wanted to try. FYI Duality.ttf is the default.

Below is the code that sets the font. This is the same as the YII core file.




        if($this->fontFile===null)

        	$this->fontFile=dirname(__FILE__).'/Duality.ttf';


		$offset=2;

		$length=strlen($code);

		$box=imagettfbbox(30,0,$this->fontFile,$code);

		$w=$box[4]-$box[0]-$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.<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />;

			$angle=rand(-10,10);

			$letter=$code[$i];

            $box=imagettftext($image,$fontSize,$angle,$x,$y,$foreColor,$this->fontFile,$letter);

            $x=$box[2]-$offset;

In my original code above you can see a couple of approaches that didn’t work, any idea how to point to this file?

doodle

You have to define the file path, not an alias (e.g. application.fonts.*)

Thanks Y!! I don’t quite understand your answer, could you supply a snippet of code?

FWIW I modified the code so it works now.


if($this->fontFile===null)

        {

        	$this->fontFile=dirname(__FILE__).'/Duality.ttf';

        } else {

            $this->fontFile=dirname(__FILE__).'/'.$this->fontFile;

        }

This is code from SBCaptchaAction.php a copy of CCaptchaAction.php.

so now in my directory /extensions/sbcaptcha I have the php file above and a few font files.

This is the routine that returns the word, modified from the original.


protected function generateVerifyCode()

	{


             $words = Captchas::model()->findAll();

             $wordCount = Captchas::model()->count();

             $seed = rand(1,$wordCount);

             

             /* this might be faster than looping through the results

              * needs some testing

              * 

              * $words = Captchas::model()->findAll();

              * $seed = rand(1,$wordCount);

              * return Captchas::model()->findByPk($seed)->word;

              */

             

             foreach($words as $word)

             {

                 if($word->id == $seed)

                         return $word->word;

             }


	}

One problem I see with this code is that it doesn’t take into account the very real possibility that a word would be deleted and the id (which is autonumber) will have gaps. So to make it more robust I would probably take all the results and put them in an array and randomize between 0 and the array_count.

doodle