Captcha within a ActiveRecord

Hi folks,

I have a little problem with using a captcha to verify the data within a model based on an ActiveRecord.

Do I have to do something else or in addition, like I would do when using an model based on a CFormModel?

What I have done is: declaring a public variable $verifyCode within my ActiveRecord, inserting a rule to verify that the given text is the same like in the captcha:


class Subscriber extends CActiveRecord

{

....

	public $verifyCode;

....

	public function rules()

	{

		return array(

...

			array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd')),

		);

	}

...

	public function attributeLabels()

	{

		return array(

			'verifyCode'=>'Verification Code',

...

		);

	}

}

overwriting the action method in my controller:


class SiteController extends CController

{

	public function actions()

	{

		return array(

			'captcha'=>array(

				'class'=>'CCaptchaAction',

				'backColor'=>0xEBF4FB,

			),

		);

	}

..

}

and inserting the widget into the formView:


...

<?php if(extension_loaded('gd')): ?>

<div class="simple">

	<?php echo CHtml::activeLabel($model,'verifyCode'); ?>

	<div>

	<?php $this->widget('CCaptcha'); ?>

	<?php echo CHtml::activeTextField($model,'verifyCode'); ?>

	</div>

	<p class="hint">Bitte gib die Buchstaben so ein wie du sie im Bild siehst.

	<br/>Buchstaben sind nicht Case-Sensitive.</p>

</div>

<?php endif; ?>

...

All the times I submit this form, the validation says that the code is not right.

If I’ve understand the whole thing in the right way, this should work, or not?

Do the validation in the active record depends on a column in my db or something like this? Did I forgot something else?

Would be nice if someone could help me out with this.

regards,

  • mageta

There should be no problem. I did the very same thing and it works.

well… it was a pain to figure out what’s going on. But I did :wink:

Looks like that it matters, on what your model is based on. After having an other look at the guide I found this interesting sentence: "By default, the method returns all public member variables as safe attributes for CFormModel, while it returns all table columns except the primary key as safe attributes for CActiveRecord."

And without being found as safe the value is not stored in the public variable (by using ‘massive assignment’). And without being stored in it, the validator can’t compare it successfully with the value of the captcha.

So, what I had to do was to overwrite safeAttributes() to declare my verifyCode as safe (in addition to the non pk-values of the table).


	public function safeAttributes()

	{

		$attributes=parent::safeAttributes();

		$attributes[]='verifyCode';

		

	    return $attributes;

	}

regards,

  • mageta

Oh you are using version 1.0.10 or earlier. It worked for me because i’m using version 1.1rc-dev.

From what i understand, the difference is that in 1.1rc-dev, an attribute will be found as safe is there is a validation rule specified for it, so just


array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd')),

would suffice.