Yii Captcha不在模块内显示图像,适用于siteController

时间:2013-09-12 15:22:15

标签: php yii captcha yii-components

我正在使用Yii用户管理模块,当用户在我的网站上注册时,验证码图像不会显示在表单上,​​但是在Yii生成的联系表单上,会显示验证码。这是我的视图< / p> 编辑:当我使用firebug或chrome开发人员工具时,我看到链接工作正常,即使我刷新它,代码更改但图像没有打印但img及其attirbute在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;
}

  }

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:1)

简短回答

将CaptchaValidator上的captchaAction设置为与小部件中相同的值

答案很长

我遇到了同样的问题:验证码在联系人页面上工作但在另一个控制器/操作页面上我没有图像。将窗口小部件上的captchaAction更改为“site / captcha”会使图像显示但验证无效!

经过一些研究后我发现:

  • 没有在小部件上设置captchaAction,调用CCaptchaAction :: renderImageImagick()或CCaptchaAction :: renderImageGD()会产生无效的PNG文件(不知道为什么)
  • 根据Yii CAPTCHA url is brokenhttps://github.com/yiisoft/yii2/issues/693我还需要在CCaptchaValidator上将captchaAction添加到CCaptcha小部件上的相同值

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

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

希望这有助于某人。

答案 2 :(得分:1)

还需要写,因为当你覆盖accessRules()时,你需要为所有人提供验证码操作,如下所示:

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

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

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

Add Captcha Yii Framework – Yii tutorial
Why does yii captcha not display “Get new code” ?

相关问题