По умолчанию форма регистрации в Laravel содержит только имя, почту и пароль, но часто нужно, чтобы пользователь мог загрузить фотографию или аватар. В этом уроке мы покажем вам простой способ сделать это при помощи пакета Media Library от Spatie.
Содержание страницы
Шаг 1. Меняем форму регистрации
Давайте добавим поле загрузки файла под именем Avatar к стандартной форме регистрации Laravel:
<!-- resources/views/auth/register.blade.php --> <div class="form-group row"> <label for="avatar" class="col-md-4 col-form-label text-md-right">{{ __('Avatar (optional)') }}</label> <div class="col-md-6"> <input id="avatar" type="file" class="form-control" name="avatar"> </div> </div>
Шаг 2. Загрузка и сохранение при помощи Media Library
По умолчанию регистрация в Laravel обрабатывается в app/Http/Controllers/Auth/RegisterController.php, в частности, в методе create():
/** * Create a new user instance after a valid registration. * * @param array $data * @return AppUser */ protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); }
Здесь мы добавим логику загрузки аватара и сохранение его в базе данных. С этим нам поможет Spatie Media Library. Давайте её установим:
composer require spatie/laravel-medialibrary:^7.0.0
После установки:
php artisan vendor:publish --provider="SpatieMediaLibraryMediaLibraryServiceProvider" --tag="migrations"
Делаем миграцию опубликованных таблиц:
php artisan migrate
Это создаст таблицу в базе данных под именем media, которая использует полиморфные отношения для хранения данных.
В нашем случае — мы прикрепляем медиа файлы к appUser.
Теперь давайте подготовим модель appUser.php для работы с Media Library. Вот что нам нужно добавить:
- Два оператора use вне класса
- Класс implements HasMedia
- Один оператор use внутри класса
// Эти два из Media Library use SpatieMediaLibraryHasMediaHasMediaTrait; use SpatieMediaLibraryHasMediaHasMedia; class User extends Authenticatable implements HasMedia { // ... use HasMediaTrait; }
Вернемся к нашему RegisterController и добавим немного кода в метод create():
protected function create(array $data) { $user = User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); if (isset($data['avatar'])) { $user->addMediaFromRequest('avatar')->toMediaCollection('avatars'); } return $user; }
Что мы здесь сделали:
- Проверка наличия аватара, затем мы используем Media Library для загрузки файла из запроса и добавления его в медиаколлекцию в базе данных;
- Мы можем сделать это только для существующего пользователя, поэтому мы делаем это после того, как пользователь создан, а затем возвращаем конечный результат как объект User.
Вот как хранится файл:
Примечание : по умолчанию Laravel хранит все файлы в storage/app/public, не забудьте запустить команду php artisan storage:link или изменить настройки папок в файле config/filesystems.php.
И как это хранится в базе данных:
Шаг 3. Показ аватара в верхней навигации
Самое простое использование этого аватара — показать его в правом верхнем углу рядом с именем пользователя. Давайте сделаем это.
Но что, если загруженный файл огромен? Как мы можем изменить его размер, скажем, до 50×50? И здесь Media Library снова нам поможет. Все, что нам нужно сделать, это определить правила изменения размера в той же самой модели appUser:
use SpatieMediaLibraryModelsMedia; class User extends Authenticatable implements HasMedia { // ... all other code public function registerMediaConversions(Media $media = null) { $this->addMediaConversion('thumb') ->width(50) ->height(50); } }
Теперь у нас есть правило под именем thumb которое мы можем использовать для отображения эскиза. При загрузке он будет автоматически сохранен в подкаталог conversions для этого элемента:
Вот так мы показываем аватар:
<!-- resources/views/layouts/app.blade.php --> <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre> <img src="{{ Auth::user()->getMedia('avatars')->first()->getUrl('thumb') }}"> {{ Auth::user()->name }} <span class="caret"></span> </a>
Да, именно, эта строка нам и нужна:
Auth::user()->getMedia('avatars')->first()->getUrl('thumb')
Мы берем объект модели User, затем получаем все файлы мультимедиа из коллекции avatars, затем берем первый и получаем URL на изображение сконвертированное как thumb.
Окончательно всё выглядит так:
Вот и все. Конечно, вы можете пойти дальше и, например, показать оригинальный аватар и позволить пользователям самим изменять его размер или обрезать с помощью некой библиотеки JavaScript, затем редактировать аватар на отдельной странице настроек и т.д. Я оставлю это вам, или, возможно, опишу в потенциальном будущем продолжении этой статьи.
Больше ссылок по теме этого урока:
- Документация Spatie Media Library
- Eloquent Отношения: Полное Руководство по Полиморфным Отношениям
- Загрузка файлов в Laravel: полное руководство
Автор: Povilas Korop
Перевод: Demiurge Ash
Источник: laravel.demiart.ru