[yii2] Comment rafraîchir un captcha avec un bouton ou recharger une page ?

74
yii2 captcha refreshable

Par défaut, Yii2 captcha ne comporte pas de lien/bouton « refresh » permettant de rafraîchir les images captcha. De même, lorsque l’on recharge la page de l’image captcha, celle-ci reste inchangée. Cela peut être frustrant car les images captcha sont souvent illisibles (même pour les humains).

Dans ce tutoriel, nous allons apprendre à créer un lien/bouton pour « refresh » les images captcha et également rafraîchir les images captcha à chaque fois qu’ils rechargent la page.

1. Créer CaptchaRefreshable

La première étape consiste à créer une classe CaptchaRefreshable dans le répertoire models ou commons\models si vous utilisez le modèle avancé yii2.

<?php
 
namespace common\models;
 
class CaptchaRefreshable extends \yii\captcha\Captcha
{
    /**
     * Overrides the $template HTML
     */
    public function init()
    {
        $refresh_a = \yii\helpers\Html::a('refresh', '#', [
            'id' => 'refresh-captcha',
            'class' => 'text-small' // .text-small { font-size: 0.85em; } - include in your CSS
        ]);
 
        $this->template = '
            <div id="verify-code" class="row">
            <div class="large-3 columns">{image} ' . $refresh_a . '</div>
            <div class="large-6 columns">{input}</div>
            </div>';
        parent::init();
    }
 
    /** 
     * Register the refresh JS 
     */
    public function registerClientScript()
    {
        $view = $this->getView();
        $view->registerJs(" $('#refresh-captcha').on('click', function(e){ e.preventDefault(); $('#verify-code img').yiiCaptcha('refresh'); }) ");
        parent::registerClientScript();
    }
}

2. Créer CaptchaRefreshableAction

Ensuite, nous créons une classe CaptchaRefreshableAction dans le répertoire models ou commonsmodels si vous utilisez le modèle avancé yii2.

<?php
 
 
namespace common\models;
 
use Yii;
 
 
class CaptchaRefreshableAction extends \yii\captcha\CaptchaAction
{
    public function validate($input, $caseSensitive)
    {
        // Skip validation on AJAX requests, as it expires the captcha.
        if (Yii::$app->request->isAjax) {
            return true;
        }
        return parent::validate($input, $caseSensitive);
    }
 
}

3. Ajouter des widgets à views/site/login.php

.............
.............
 
<div class="site-login">
    .............
    .............
 
    <div class="row">
        <div class="col-lg-5">
            <?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
 
                .............
                .............
 
                <?= $form->field($model, 'verifyCode')->widget(\common\models\CaptchaRefreshable::class) ?>
 
                .............
                .............
     
            <?php ActiveForm::end(); ?>
        </div>
    </div>
</div>

4. Ajouter une action au contrôleur/SiteController.php

.............
.............
 
class SiteController extends Controller
{
    .............
    .............
     
public function actions()
    {
        return [
            .............
            .............
             
'captcha' = > [
                'class' => 'common\models\CaptchaRefreshableAction',
            ],
            .............
            .............
        ];
    }
     
.............
    .............   
}

5. Ajouter une action pour rafraîchir le captcha lors du rechargement de la page

Dans les étapes 1 à 4 ci-dessus, nous avons créé un bouton/lien pour rafraîchir l’image captcha. Le problème est que lors du rechargement de la page, l’image captcha affichée ne change pas. Pour que l’image captcha change à chaque rechargement de la page, nous devons ajouter un script à la fonction de connexion dans le contrôleur / SiteController.php.

.............
.............
  
class SiteController extends Controller
{
    .............
    .............
      
    public function actionLogin()
    {
 
        $this->createAction('captcha')->getVerifyCode(true);
 
        .............
        ............. 
     
    }
      
    .............
    .............   
}