Yii 验证码不显示模块内的图像,适用于站点控制器


Yii Captcha not showing image inside a module,works on siteController

我正在使用Yii用户管理模块,当我一个用户在我的网站上注册时,验证码图像没有显示在表格上,但是在Yii生成的联系表格上,验证码会显示。这是我的观点

编辑:当我使用Firebug或chrome开发人员工具时,即使刷新它,我看到链接工作正常,代码更改但图像未打印,但img及其属性在html文件中

<?php $this->breadcrumbs = array(Yum::t('Registration')); ?>
<div class="form">
<?php $activeform = $this->beginWidget('CActiveForm', array(
        'id'=>'registration-form',
        'enableAjaxValidation'=>true,
        'enableClientValidation'=>true,
        'focus'=>array($form,'username'),
        ));
?>
<?php echo Yum::requiredFieldNote(); ?>
<?php echo CHtml::errorSummary(array($form, $profile)); ?>
<div class="row"> <?php
echo $activeform->labelEx($form,'username');
echo $activeform->textField($form,'username');
?> </div>
<div class="row">
<?php
echo $activeform->labelEx($profile,'email');
echo $activeform->textField($profile,'email');
?> </div>  
<div class="row"> <?php
echo $activeform->labelEx($profile,'firstname');
echo $activeform->textField($profile,'firstname'); 
?> </div>  
    <div class="row"> <?php
   echo $activeform->labelEx($profile,'lastname');
   echo $activeform->textField($profile,'lastname');
   ?> </div>  
<div class="row">
<?php echo $activeform->labelEx($form,'password'); ?>
<?php echo $activeform->passwordField($form,'password'); ?>
</div>
<div class="row">
<?php echo $activeform->labelEx($form,'verifyPassword'); ?>
<?php echo $activeform->passwordField($form,'verifyPassword'); ?>
</div>
 <?php if(extension_loaded('gd') 
        && Yum::module('registration')->enableCaptcha): ?>
  <div class="row">
    <?php echo CHtml::activeLabelEx($form,'verifyCode'); ?>
    <div>
    <?php $this->widget('CCaptcha', array('captchaAction'=>'//registration/registration/captcha')); ?>
    </br>
    <?php echo CHtml::activeTextField($form,'verifyCode'); ?>
    </div>
    <p class="hint">
    <?php echo Yum::t('Please enter the letters as they are shown in the image above.'); ?>
    <br/><?php echo Yum::t('Letters are not case-sensitive.'); ?></p>
</div>
<?php endif; ?>
<div class="row submit">
    <?php echo CHtml::submitButton(Yum::t('Registration')); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->

这是我的控制器

<?php
/* This file handles a example registration process logic and some of the
* most used functions for Registration and Activation. It is recommended to
* extend from this class and implement your own, project-specific 
* Registration process. If this example does exactly what you want in your
* Project, then you can feel lucky already! */
Yii::import('application.modules.user.controllers.YumController');
Yii::import('application.modules.user.models.*');
Yii::import('application.modules.profile.models.*');
Yii::import('application.modules.registration.models.*');
class YumRegistrationController extends YumController {
  public $defaultAction = 'registration';
// Only allow the registration if the user is not already logged in and
// the function is activated in the Module Configuration
public function beforeAction($action) {
    if (!Yii::app()->user->isGuest) 
        $this->redirect(Yii::app()->user->returnUrl);
    $this->layout = Yum::module('registration')->layout;
    return parent::beforeAction($action);
}
public function accessRules() {
    return array(
            array('allow',
                'actions' => array('index', 'registration', 'recovery', 'activation','captcha', 'resendactivation'),
                'users' => array('*'),
                ),
            array('deny', // deny all other users
                'users' => array('*'),
                ),
            );
}
public function actions() {
    return array(
            'captcha' => array(
                'class' => 'CCaptchaAction',
                'backColor' => 0xFFFFFF,
                ),
            );
}
/*
 * an Example implementation of an registration of an new User in the system.
 *
 * please see the documentation of yii-user-management for examples on how to
 * extend from this class and implement your own registration logic in
 * user/docs/registration.txt
 */
public function actionRegistration() {
    // When we overrie the registrationUrl, this one is not valid anymore!
    if(Yum::module('registration')->registrationUrl != array(
                '//registration/registration/registration'))
        throw new CHttpException(403);
    Yii::import('application.modules.profile.models.*');
    $form = new YumRegistrationForm;
    $profile = new YumProfile;
    $this->performAjaxValidation('YumRegistrationForm', $form);
    if (isset($_POST['YumRegistrationForm'])) { 
        $form->attributes = $_POST['YumRegistrationForm'];
        $profile->attributes = $_POST['YumProfile'];
        $form->validate();
        $profile->validate();
        if(!$form->hasErrors() && !$profile->hasErrors()) {
            $user = new YumUser;
            $user->register($form->username, $form->password, $profile->email);
            $profile->user_id = $user->id;
            $profile->save();
            $this->sendRegistrationEmail($user);
            Yum::setFlash('Thank you for your registration. Please check your email.');
            $this->redirect(Yum::module()->loginUrl);
        }
    } 
    $this->render(Yum::module()->registrationView, array(
                'form' => $form,
                'profile' => $profile,
                )
            );  
}
// Send the Email to the given user object. $user->email needs to be set.
public static function sendRegistrationEmail($user) {
    if (!isset($user->profile->email)) {
        throw new CException(Yum::t('Email is not set when trying to send Registration Email'));
    }
    $activation_url = $user->getActivationUrl();
    // get the text to sent from the yumtextsettings table
    $content = YumTextSettings::model()->find('language = :lang', array(
                'lang' => Yii::app()->language));
    $sent = null;
    if (is_object($content)) {
        $body = strtr($content->text_email_registration, array(
                    '{username}' => $user->username,
                    '{activation_url}' => $activation_url));
        $mail = array(  'from_name'=>Yii::app()->name,
                'from' => Yum::module('registration')->registrationEmail,
                'to' => $user->profile->email,
                'to_name'=>$user->profile->firstname,
                'subject' => strtr($content->subject_email_registration, array(
                        '{username}' => $user->username)),
                'body' => $body,
                );
        $sent = YumMailer::send($mail);
    }
    else {
        throw new CException(Yum::t('The messages for your application language are not defined.'));
    }
    return $sent;
}
/**
 * Activation of an user account. The Email and the Activation key send
 * by email needs to correct in order to continue. The Status will
 * be initially set to 1 (active - first Visit) so the administrator
 * can see, which accounts have been activated, but not yet logged in 
 * (more than once)
 */
public function actionActivation($email, $key) {
    // If already logged in, we dont activate anymore
    if (!Yii::app()->user->isGuest) {
        Yum::setFlash('You are already logged in, please log out to activate your account');
        $this->redirect(Yii::app()->user->returnUrl);
    }
    // If everything is set properly, let the model handle the Validation
    // and do the Activation
    $status = YumUser::activate($email, $key);

    if($status instanceof YumUser) {
        if(Yum::module('registration')->loginAfterSuccessfulActivation) {
            $login = new YumUserIdentity($status->username, false); 
            $login->authenticate(true);
            Yii::app()->user->login($login);    
        } 
        $this->render(Yum::module('registration')->activationSuccessView);
    }
    else
        $this->render(Yum::module('registration')->activationFailureView, array(
                    'error' => $status));
}
/**
 * Password recovery routine. The User will receive an email with an
 * activation link. If clicked, he will be prompted to enter his new
 * password.
 */
public function actionRecovery($email = null, $key = null) {
    $form = new YumPasswordRecoveryForm;
    if ($email != null && $key != null) {
        if($profile = YumProfile::model()->find('email = :email', array(
                        'email' =>  $email))) {
            $user = $profile->user;
            if($user->activationKey == $key) {
                $passwordform = new YumUserChangePassword;
                if (isset($_POST['YumUserChangePassword'])) {
                    $passwordform->attributes = $_POST['YumUserChangePassword'];
                    if ($passwordform->validate()) {
                        $user->password = YumUser::encrypt($passwordform->password);
                        $user->activationKey = YumUser::encrypt(microtime() . $passwordform->password);
                        $user->save();
                        Yum::setFlash('Your new password has been saved.');
                        $this->redirect(Yum::module()->loginUrl);
                    }
                }
                $this->render(
                        Yum::module('registration')->changePasswordView, array(
                            'form' => $passwordform));
                Yii::app()->end();
            } else {
                $form->addError('login_or_email', Yum::t('Invalid recovery key'));
                Yum::log(Yum::t(
                            'Someone tried to recover a password, but entered a wrong recovery key. Email is {email}, associated user is {username} (id: {uid})', array(
                                '{email}' => $email,
                                '{uid}' => $user->id,
                                '{username}' => $user->username)));
            }
        }
    } else {
        if (isset($_POST['YumPasswordRecoveryForm'])) {
            $form->attributes = $_POST['YumPasswordRecoveryForm'];
            if ($form->validate()) {
                Yum::setFlash(
                        'Instructions have been sent to you. Please check your email.');
                if($form->user instanceof YumUser) {
                    $form->user->generateActivationKey();
                    $recovery_url = $this->createAbsoluteUrl(
                            Yum::module('registration')->recoveryUrl[0], array(
                                'key' => $form->user->activationKey,
                                'email' => $form->user->profile->email));
                    Yum::log(Yum::t(
                                '{username} successfully requested a new password in the password recovery form. A email with the password recovery url {recovery_url} has been sent to {email}', array(
                                    '{email}' => $form->user->profile->email,
                                    '{recovery_url}' => $recovery_url,
                                    '{username}' => $form->user->username)));
                    $content = YumTextSettings::model()->find(
                            'language = :lang', array('lang' => Yii::app()->language));
                    $sent = null;
                    if (is_object($content)) {
                        $mail = array(
                                'from' => Yii::app()->params['adminEmail'],
                                'to' => $form->user->profile->email,
                                'subject' => $content->subject_email_registration,
                                'body' => strtr($content->text_email_recovery, array(
                                        '{recovery_url}' => $recovery_url)),
                                );
                        $sent = YumMailer::send($mail);
                    } else {
                        throw new CException(Yum::t('The messages for your application language are not defined.'));
                    }
                } else
                    Yum::log(Yum::t(
                                'A password has been requested, but no associated user was found in the database. Requested user/email is: {username}', array(
                                    '{username}' => $form->login_or_email)));
                $this->redirect(Yum::module()->loginUrl);
            }
        }
    }
 $this->render(Yum::module('registration')->recoverPasswordView, array(
                'form' => $form));
    }
  }

这是我的模型

<?php
/**
* RegistrationForm class.
* RegistrationForm is the data structure for keeping
* user registration form data. It is used by the 'registration' action of       'YumUserController'.
* @package Yum.models
*/
   class YumRegistrationForm extends YumUser {
public $verifyPassword;
/**
 * @var string
 */
public $verifyCode;
public function rules() 
{
    $rules = parent::rules();
    if(Yii::app()->getModule('user')->loginType != 'LOGIN_BY_EMAIL' || Yum::module()->registrationType ==REG_NO_USERNAME_OR_PASSWORD || Yum::module()->registrationType == REG_NO_USERNAME_OR_PASSWORD_ADMIN)
        $rules[] = array('username', 'required');
    $rules[] = array('password, verifyPassword', 'required');
    $rules[] = array('password', 'compare', 'compareAttribute'=>'verifyPassword', 'message' => Yii::t("UserModule.user", "Retype password is incorrect."));
    $rules[] = array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(),'on'=>'insert');
    return $rules;

}
public function genRandomString( $length = 10)
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
$string ='';    
for ($p = 0; $p < $length; $p++)
 {
    $string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
  }

在您的视图中将其更改为此内容。默认情况下,验证码图像是从站点控制器加载的,其中验证码是操作(您可以在"操作"下看到它)。你指的是//registration/registration/captcha,它不存在:

<?php $this->widget('CCaptcha', array('captchaAction'=>'site/captcha')); ?>

简答

将验证码验证

器上的验证码操作设置为与小部件中相同的值

长答案

我遇到了同样的问题:验证码在联系人页面上工作,但在另一个控制器/操作页面上我没有图像。将小部件上的验证码操作更改为"站点/验证码"使图像出现,但验证不起作用!

经过一些研究,我发现:

  • 没有在小部件上设置验证码操作调用 CCaptchaAction::renderImageImagick() 或 CCaptchaAction::renderImageGD() 生成无效的 PNG 文件(不知道为什么)
  • 根据 Yii 验证码 url 被破坏 https://github.com/yiisoft/yii2/issues/693 我还需要在 CCaptchaValidator 上将验证码操作添加到 CCaptcha 小部件上的相同值

现在我的CFormModel::rules()返回一个包含此元素的数组:

array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(), 'message'=>'Código incorreto.', 'captchaAction'=>'site/captcha'),

希望这对某人有所帮助。

还需要编写,因为当您被覆盖 accessRules() 时,您需要使验证码操作可供所有人使用,如下所示:

class MyController extends Controller
{
    public function accessRules() {
        return array('allow', 'actions' => array('captcha'), 'users' => array('*'));
    }
}

array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()),

请从这些教程中找到最佳帮助 -

添加验证码 Yii 框架 – Yii tutorial
为什么 yii 验证码不显示"获取新代码"?