Yii Framework – reCAPTCHA with Active Form

CAPTCHA example
CAPTCHA example

CAPTCHAs on the Internet are as prevalent as they are annoying.  Unfortunately, these squiggly words are sometimes the best protection from automated attacks.  In our applications, we try to reduce use of CAPTCHAs, but when we do have to use them, we utilize the reCAPTCHA service from Google.  The nice thing about this service is that it is used to verify text from old publications, allowing for better scans of these publications and digitizing them for the common good.

Readers of our blog know that we love the Yii Framework, and luckily, an extension for this framework allows for very easy reCAPTCHA verification.  Here are the steps:

1. Download the reCAPTCHA extension for Yii.

2. Export the ZIP file contents into your protected/extensions folder.  After you do that, you will have a recaptcha folder in your extensions folder that contains the EReCaptcha.php and EReCaptchaValidator.php files.  There is also a subdirectory that contains the reCAPTCHA PHP library.

3. Visit Google’s reCAPTCHA site to receive your public and private key. At this point, you may want to get 2 keys – one for development purposes, and one for production purposes. We apply for a production key that can only be used on a specific domain, and a global key that can be used during development on any developer’s workstation. If this is the case, see our next post that will detail how to utilize different configuration files depending on the environment the script is currently running in.

4. Add your public and private key to your configuration file in the ‘params’ section:

'recaptcha' => array(
     'publicKey' => 'INSERT_YOUR_PUBLIC_KEY_HERE',
     'privateKey' => 'INSERT_YOUR_PRIVATE_KEY_HERE',
),

5. If you want to add the reCAPTCHA to an ActiveForm, add this to your view:

echo $form->labelEx($model, 'validation');
$this->widget('application.extensions.recaptcha.EReCaptcha',
   array('model'=>$account, 'attribute'=>'validation',
         'theme'=>'red', 'language'=>'en_US',
         'publicKey'=>Yii::app()->params['recaptcha']['publicKey']));
echo $form->error($model, 'validation');

6. In your model, add a line to your ‘rules’. ‘resetPasswordWithCaptcha’ will be used below as the scenario, so keep track of what you name it!

array(
    'validation',
    'application.extensions.recaptcha.EReCaptchaValidator',
    'privateKey'=> Yii::app()->params['recaptcha']['privateKey'],
    'on' => 'resetPasswordWithCaptcha'
),

7. In your controller, add a unique scenario to your model.  For example:

$model = new User;
$model->scenario = "resetPasswordWithCaptcha";

8. Now, validate and save if necessary.

if ($model->validate()) {
    // Put false in this save action so we don't validate again - or the CAPTCHA
    //  will be invalid!
    if ($model->save(false)) {
    }
}

We hope this helps someone use the reCAPTCHA extension with the Yii Framework! Not only are you protecting your site from automated attacks, you are also helping digitize the written word!

Read More

Yii Framework Test Script Submitting to Production

Edit: It looks like our RewriteRule directives in Apache may have been the culprit. We rarely use a .htaccess file and instead use configuration files to speed up Apache. Since we didn’t change index.php to index-test.php in the configuration, it was redirecting to the index.php!

In the Yii Framework, you can always call index-test.php to use your test settings & database connection. This is handy in a variety of ways. However, we recently found that some actions (redirects) that occurred after a page submit were redirecting us to the index.php – the production site. Luckily, we were still on our local machine, so we had no test cases misdirecting from test to production. To fix this, we set the URL Manager’s showScriptName to true in our test configuration. After we did this, everything worked as expected.

Snippet from our test configuration file:

// uncomment the following to enable URLs in path-format
'urlManager'=>array(
   'urlFormat'=>'path',
   'showScriptName' => true,
   'rules'=>array(
       '/'=>'/view',
       '//'=>'/',
       '/'=>'/',
   ),
),

Read More

CJuiDatePicker/CActiveForm Yii Framework

 

CJuiDatePicker Example
CJuiDatePicker Example

 

For many of our web applications, we utilize the Yii Framework extensively.  A great feature of the framework is the CActiveForm, which allows you to link up your Model to your View in a very easy manner.  (See Model-View-Controller Architecture on Wikipedia for a good explanation of this concept.)

If you also use the Yii Framework, you might find yourself in a dilemma that we recently experienced.  We had a date field on our form, and wanted to use the CJuiDatePicker widget so that users get a nifty dropdown where they can select a date.  We also wanted to link it to the model, defaulting it to the field in our database if there was already an instance of the object.  Most Yii widgets only need you to link up with the ‘model’ option, but CJuiDatePicker is different.  To default the value, the ‘value’ line below must be used.

$this->widget('zii.widgets.jui.CJuiDatePicker', array(
  'model'=>$model,
  'attribute'=>'StartDate',
  'value'=>$model->StartDate,
  // additional javascript options for the date picker plugin
  'options'=>array(
    'showAnim'=>'fold',
    'showButtonPanel'=>true,
    'autoSize'=>true,
    'dateFormat'=>'yy-mm-dd',
    'defaultDate'=>$model->StartDate,
   ),
));

Do you know of other ways to accomplish this? Let us know in the comments!

Read More