weixin_33735077 2015-03-26 09:25 采纳率: 0%
浏览 25

Yii2更新个人资料照片

I have here an Edit Profile page where user can change his/her profile photo/avatar.

enter image description here

The avatar displayed is the photo of the current user (of course) and when I click the Update Avatar button, the user can select an image, and then the selected image will preview replacing the current user avatar.

enter image description here

Here's the code in my view:

<div class="fileUpload btn btn-warning">
    <span>Update Avatar</span>
    <input type="file" accept="image/*" onchange="loadFile(event)" class="upload"/>
</div>
<script>
    var loadFile = function(event) {
    var output = document.getElementById('output');
    output.src = URL.createObjectURL(event.target.files[0]);
  };
</script>

The problem is that, whenever I click the Update button at the end of the form, the avatar does not change. I know that this is because it's all in the front end. How do I get the newly selected image and save it to the database? Or are there other implementation aside from this one?

BTW, I chose this method because I want to preview the image before and after selection. I tried Kartik's FileInput widget but I don't know where to put the onchange="loadFile(event)" event in the plugin.

If you need more code, like my action controller or the model, just let me know.

I really need help in this one.

  • 写回答

1条回答 默认 最新

  • weixin_33743880 2015-04-12 02:36
    关注

    I don't know if you have found the solution or not.

    You can save the picture in directory and filename in DB table as soon as the user selects the picture.

    Use this widget 2amigon File Upload Widget to start uploading picture as soon as user selects the picture. This widget renders jQuery File Upload.

    Usage:

    view

    use dosamigos\fileupload\FileUploadUI;
    
    <?= FileUploadUI::widget([
            'model' => $model,
            'attribute' => 'profile_pic',
            'url' => ['user-profile/upload-profile-picture', 'id' => $model->id],
             'gallery' => false,
             'fieldOptions' => [
                 'accept' => 'image/*',
             ],
             'clientOptions' => [  
                 'maxFileSize' => 2000000,
                 'autoUpload' => true,
              ],
              'clientEvents' => [
                  'fileuploaddone' => 'function(e, data) {
                                          jQuery(".fb-image-profile").attr("src",data.result);
                                      }',
                  'fileuploadfail' => 'function(e, data) {
                                          alert("Image Upload Failed, please try again.");
                                      }',
              ],
    ]);
    ?>
    

    Controller :This will call UserProfileController/actionUploadProfilePicture method.

    public function actionUploadProfilePicture($id)
    {
        $model = $this->findModel($id);
        $oldFile = $model->getProfilePictureFile();
        $oldProfilePic = $model->profile_pic;
    
        if ($model->load(Yii::$app->request->post())) {
    
            // process uploaded image file instance
            $image = $model->uploadProfilePicture();
    
            if($image === false && !empty($oldProfilePic)) {
                $model->profile_pic = $oldProfilePic;
            }
    
            if ($model->save()) {
                // upload only if valid uploaded file instance found
                if ($image !== false) { // delete old and overwrite
                    if(!empty($oldFile) && file_exists($oldFile)) {
                        unlink($oldFile);
                    }
                    $path = $model->getProfilePictureFile();
                    $image->saveAs($path);
                }
                \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
                return $model->getProfilePictureUrl();
            }
        }
    }
    

    Model

    public function getProfilePictureFile()
    {
        return isset($this->profile_pic) ? Yii::$app->params['uploadPath'] . 'user/profile/' . $this->profile_pic : null;
    }
    
    public function getProfilePictureUrl()
    {
        // return a default image placeholder if your source profile_pic is not found
        $profile_pic = isset($this->profile_pic) ? $this->profile_pic : 'default_user.jpg';
        return Yii::$app->params['uploadUrl'] . 'user/profile/' . $profile_pic;
    }
    
    /**
    * Process upload of profile picture
    *
    * @return mixed the uploaded profile picture instance
    */
    public function uploadProfilePicture() {
        // get the uploaded file instance. for multiple file uploads
        // the following data will return an array (you may need to use
        // getInstances method)
        $image = UploadedFile::getInstance($this, 'profile_pic');
    
        // if no image was uploaded abort the upload
        if (empty($image)) {
            return false;
        }
    
        // store the source file name
        //$this->filename = $image->name;
        $ext = end((explode(".", $image->name)));
    
        // generate a unique file name
        $this->profile_pic = Yii::$app->security->generateRandomString().".{$ext}";
    
        // the uploaded profile picture instance
        return $image;
    }
    

    Apart from this, you can use Advanced upload using Yii2 FileInput widget tutorial for more details in picture uploading.

    I hope this helps and clear your issues regarding file upload.

    评论

报告相同问题?