По умолчанию форма регистрации в Laravel содержит только имя, почту и пароль, но часто нужно, чтобы пользователь мог загрузить фотографию или аватар. В этом уроке мы покажем вам простой способ сделать это при помощи пакета Media Library от Spatie.
Давайте добавим поле загрузки файла под именем 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>
По умолчанию регистрация в Laravel обрабатывается в app/Http/Controllers/Auth/RegisterController.php, в частности, в методе create():
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
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="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"
Делаем миграцию опубликованных таблиц:
php artisan migrate
Это создаст таблицу в базе данных под именем media, которая использует полиморфные отношения для хранения данных.
В нашем случае — мы прикрепляем медиа файлы к app\User.
Теперь давайте подготовим модель app\User.php для работы с Media Library. Вот что нам нужно добавить:
// Эти два из Media Library
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\HasMedia\HasMedia;
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;
}
Что мы здесь сделали:
Вот как хранится файл:
Примечание : по умолчанию Laravel хранит все файлы в storage/app/public, не забудьте запустить команду php artisan storage:link или изменить настройки папок в файле config/filesystems.php.
И как это хранится в базе данных:
Самое простое использование этого аватара — показать его в правом верхнем углу рядом с именем пользователя. Давайте сделаем это.
Но что, если загруженный файл огромен? Как мы можем изменить его размер, скажем, до 50×50? И здесь Media Library снова нам поможет. Все, что нам нужно сделать, это определить правила изменения размера в той же самой модели app\User:
use Spatie\MediaLibrary\Models\Media;
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, затем редактировать аватар на отдельной странице настроек и т.д. Я оставлю это вам, или, возможно, опишу в потенциальном будущем продолжении этой статьи.
Больше ссылок по теме этого урока: