Yii 2 file input renders hidden file input tag

你离开我真会死。 提交于 2021-01-29 07:15:52

问题


I am using yii2 to build a simple application with a signup feature. Problem is when I render a file input tag using active forms, it render a file input field and a hidden field. The validator then picks the one which is hidden and always says that profile image is required though it saves it in my upload directory and also adds the path to the database but still returns with this error. Thanks for any help.

Here is the code: View:

<?php $form = ActiveForm::begin(['id' => 'form-signup' , 'options' => ['enctype' => 'multipart/form-data']]); ?>

   <?= $form->field($model, 'username') ?>

   <?= $form->field($model, 'email') ?>
   <?= $form->field($model, 'profile_path')->widget(FileInput::classname(), [
                    'options' => ['accept' => 'image/*'],
                ]); ?>
   <?= $form->field($model, 'password')->passwordInput() ?>
   <div class="form-group">
   <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
    </div>
<?php ActiveForm::end(); ?>

SignupForm // model class

class SignupForm extends Model
{
    public $username;
    public $email;
    public $password;
    public $profile_path;

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        ['username', 'filter', 'filter' => 'trim'],
        ['username', 'required'],
        ['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
        ['username', 'string', 'min' => 2, 'max' => 255],

        ['email', 'filter', 'filter' => 'trim'],
        ['email', 'required'],
        ['email', 'email'],
        ['email', 'string', 'max' => 255],
        ['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],

        ['password', 'required'],
        ['password', 'string', 'min' => 6],
        [['profile_path'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
    ];
}

/**
 * Signs user up.
 *
 * @return User|null the saved model or null if saving fails
 */
public function signup()
{
    if ($this->validate()) {
        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();
        $user->setProfilePicture($this->profile_path);
        if ($user->save(false)) {
            return $user;
        }
    }

    return null;
}

public function upload()
{
    if ($this->validate()) {
        $this->profile_path->saveAs('uploads/' . $this->profile_path->baseName . date('Y-m-d H:i:s') . '.' . $this->profile_path->extension);
        $this->profile_path = 'uploads/' . $this->profile_path->baseName . '.' . $this->profile_path->extension;

        return true;
    } else {
        return false;
    }
}

}

Output:

<label class="control-label" for="signupform-profile_path">Profile Path</label>
<input type="hidden" value="" name="SignupForm[profile_path]">
<input id="signupform-profile_path" type="file" name="SignupForm[profile_path]">
<p class="help-block help-block-error">Please upload a file.</p>

回答1:


I think you should use different scenario avoiding the validation of input hidden when not necessary.. see this doc for a brief guide

And this is a sample of scenario use

Define the rules and scenarios

<?php

class User extends Model
{
    public $name;
    public $email;
    public $password;

    public function rules(){
        return [
            [['name','email','password'],'required'],
            ['email','email'],
            [['name', 'email', 'password'], 'required', 'on' => 'register'],
            ];
    }
    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios['login'] = ['name','password'];//Scenario Values Only Accepted
        return $scenarios;
    }
}
?>

Apply scenario

<?php
...
class UserController extends Controller
{
    ..
    // APPLY SCENARIOS
    // scenario is set as a property
    ............
    public function  actionLogin(){
        $model = new User;
        $model->scenario = 'login';
        .............
    }
    // scenario is set through configuration
    public function  actionRegister(){
        $model = new User(['scenario' => 'register']);
        ..............
    }
}

In login scenario only name and password are required in register scenario name, email and password are required




回答2:


Need set value attribute in hiddenOptions

<?= $form->field($model, 'profile_path')->widget(FileInput::class, ['options' => ['accept' => 'image/*', 'hiddenOptions' => ['value' => $model->profile_path]]]) ?>



回答3:


Ok guys i figured out that the issue was with the validator i was using. Using image validator instead of file validator solved my problem. Here is the updated code for validation.

['profile_path', 'image', 'extensions' => 'png, jpg',
       'minWidth' => 100, 'maxWidth' => 2000,
       'minHeight' => 100, 'maxHeight' => 2000,
],


来源:https://stackoverflow.com/questions/34593023/yii-2-file-input-renders-hidden-file-input-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!