@yazux

Yii2, как сделать загрузку изображения (аватара пользователя) в дефолтной модели User?

Проблема в следующем:
1) Когда прикрепляю изображение, в базу пишется только название изображения, без пути, хотя его я указываю.
2) UploadedFile в контроллере почему-то не работает, изображения не загружаются. добавил конструкцию:
if(!UploadedFile::getInstance($model,'avatar')){echo 'error!';}

И соответственно получил ошибку.

Подскажите в чём я ошибся при написании. Код прикрепляю:

Функция в контроллере:
use yii\web\UploadedFile;
 public function actionUpdateuserinfo($id)
    {   
        $model = User::find()->where('id = :id',[':id' => $id])->one();
        if( \Yii::$app->getRequest()->isPost ){
            if( $model->load( \Yii::$app->request->post() ) && $model->validate() ){
               
                $model->avatar = UploadedFile::getInstance($model,'avatar');
                
                if($model->avatar){
                    $dir = 'images/user_avatars/';
                    $path = $model->avatar->baseName.'.'.$model->avatar->extention;
                    $model->avatar->saveAs($dir.$path);
                    $model->attachImage($path);
                }
                $model->save();
                $user = User::find(
                    ['username','email','first_name','surname','date_of_birth','avatar']
                )->where(['id' => $model->id])->all();
                return $this->render('index', [
                    'user' => $user,
                    'model'     =>  $model
                ]);
            }
            
        }
        else{
                return $this->render('updateuserinfo', [
                    'model'     =>  $model
                ]);
            }
    }


Представление (форма)
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\widgets\Pjax;
?>
<?php  Pjax::begin(['id' => 'w0']); ?>
<?php 
$form = ActiveForm::begin([
    'id'                          =>    'about-form',
    'method'                      =>    'post',
    'options' => [
    	'onctype' => 'multipart/form-data',
    ],
]); ?>

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

    <?= $form->field($model, 'first_name')->textInput(['placeholder' => 'Ваше имя', 'value' => $model->first_name]) ?>

    <?= $form->field($model, 'email')->textInput(['placeholder' => 'Ваш Email', 'value' => $model->email]) ?>

    <?= $form->field($model, 'surname')->textInput(['placeholder' => 'Ваша фамилия', 'value' => $model->surname]) ?>

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

    <div class="form-group">
        <?= Html::submitButton('Отправить', ['class' => 'btn btn-primary']) ?>
    </div>

<?php ActiveForm::end(); ?>
<?php  Pjax::end(); ?>

В модели User имеется следующее:
use yii\web\UploadedFile;
public function rules()
    {
        return [
            ['status', 'default', 'value' => self::STATUS_ACTIVE],
            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
            [['email','first_name','surname','date_of_birth','avatar'], 'required'],
            ['email', 'email'],
            ['avatar','image','extensions'=> ['jpg','jpeg','png']],
        ];
    }
  • Вопрос задан
  • 3730 просмотров
Решения вопроса 3
@yazux Автор вопроса
В общем проблема решилась использованием стороннего плагина для загрузки изображений с помощью ajax, вот собственно ссылка на плагин, там же есть live demo и ссылка на проект на github. Сделал работу так: на форме есть , с помощью плагина валидирую и загружаю изображение на сервер, при успешной загрузке, js заносит в инпут путь к загруженному изображению, а далее всё стандартными средствами Yii2, форма работающая на pjax отправляется, валидируется и данные, включая адрес изображения, пишутся в базу, profit! Кто будет использовать данный метод, учитывайте то, что при загрузке нескольких изображений с одинаковыми именами, они друг друга заменят. По этому нужно хешировать названия перед загрузкой и в базу соответственно писать уже обновлённое имя. В моём случае перед хешированием к имени изображения добавляется ник пользователя т.к. он уникален, то и имя изображения генерируется уникальное.
Ответ написан
Комментировать
kompi
@kompi
nullstack devoops
Так как используется ajax, стоит сначала по-гуглить, как загружать файлы асинхронно.
Ответ написан
Комментировать
@lxShaDoWxl
не знаю как в pjax c отправкой изображений, я бы взял jquery.form malsup.com/jquery/form
насчёт сохранения фото в saveAs() лучше передавать абсолютный путь созданный с помощью Yii::getAlias('') www.yiiframework.com/doc-2.0/guide-concept-aliases.html
а в базе хранить путь вида $dir.$path
да и вполне достаточно хранить в базе название с расширением, а в модели создать переменную с папкой файлов и выводить склейку переменной с папкой и значением в базе
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@znepok
Попробуйте поменять
$model->attachImage($path);
на
$model->attachImage($dir.$path);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы