Tricks

Uploading profile image

Oct 24, 2022
Arthur Minasyan
Form builder, Admin panel

Create trait for user model

trait HasProfilePhoto
{
public function getProfilePhotoUrlAttribute(): string
{
return $this->profile_photo_path
? Storage::disk($this->profilePhotoDisk())->url($this->profile_photo_path)
: $this->defaultProfilePhotoUrl();
}
 
public function updateProfilePhoto(null|string $photo): void
{
tap($this->profile_photo_path, function ($previous) use ($photo) {
$this->forceFill([
'profile_photo_path' => $photo,
])->save();
 
if ($previous && ! $photo) {
Storage::disk($this->profilePhotoDisk())->delete($previous);
}
});
}
 
protected function defaultProfilePhotoUrl(): string
{
$name = trim(collect(explode(' ', $this->name))->map(function ($segment) {
return mb_substr($segment, 0, 1);
})->join(' '));
 
return 'https://ui-avatars.com/api/?name='.urlencode($name).'&color=7F9CF5&background=EBF4FF';
}
 
public function profilePhotoDisk(): string
{
return isset($_ENV['VAPOR_ARTIFACT_NAME']) ? 's3' : config('your-config.profile_photo_disk', 'public');
}
 
public function profilePhotoDirectory(): string
{
return config('your-config.profile_photo_directory', 'profile-photos');
}
}

Update your user model

use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasAvatar;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Traits\HasProfilePhoto;
 
class User extends Authenticatable implements FilamentUser, HasAvatar
{
use HasProfilePhoto;
 
protected $appends = [
'profile_photo_url',
];
 
public function canAccessFilament(): bool
{
return condition;
}
 
public function getFilamentAvatarUrl(): ?string
{
return $this->profile_photo_url;
}
}

Finally, we create a filament page and place the given code there. /app/Filament/Pages/Profile

use Filament\Pages\Page;
use Filament\Facades\Filament;
use Filament\Forms\Components\FileUpload;
use App\Models\User;
 
class Profile extends Page
{
public array $updateProfileInformationState = [];
 
protected static string $view = 'filament.pages.profile';
 
/**
* Get the current user of the application.
*
* @return mixed
*/
public function getUserProperty()
{
return Filament::auth()->user();
}
 
protected function getForms(): array
{
return [
'updateProfileInformationForm' => $this->makeForm()
->model(User::class)
->schema([
FileUpload::make('profile_photo_path')
->image()
->avatar()
->disk($this->user->profilePhotoDisk())
->directory($this->user->profilePhotoDirectory())
->rules(['nullable', 'mimes:jpg,jpeg,png', 'max:1024'])
])
->statePath('updateProfileInformationState'),
];
}
 
public function updateProfilePhoto()
{
$this->user->updateProfilePhoto($this->updateProfileInformationForm->getState());
}
}

Page view /resources/views/filament/pages/profile.blade.php

<x-filament::page>
<form wire:submit.prevent="updateProfilePhoto">
{{ $this->updateProfileInformationForm }}
</form>
</x-filament::page>
avatar

I'm getting an error updateProfileInformationState.profile_photo_path' cannot be found, when profile page loads, and is not storing the image, any advice? thank you

avatar

have you tried storage link command?

avatar

yes, i guess I am missing something