From f8272bfaaed275678a556282b678d3203d788299 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 30 Mar 2026 14:03:31 +0100 Subject: [PATCH] Fix FilamentManager::getUserName() returning null for users without a name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement HasName interface on User model with getFilamentName() that falls back to display_name → name → email, preventing the ViewException when the filament-impersonate banner renders for users with null names. Closes #48 Co-Authored-By: Claude Opus 4.6 --- app/Models/User.php | 8 ++++++- tests/Feature/UserModelTest.php | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/Feature/UserModelTest.php diff --git a/app/Models/User.php b/app/Models/User.php index b6465f5ce..82da10241 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -7,6 +7,7 @@ use App\Enums\Subscription; use App\Enums\TeamUserStatus; use Filament\Models\Contracts\FilamentUser; +use Filament\Models\Contracts\HasName; use Filament\Panel; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -18,7 +19,7 @@ use Laravel\Cashier\Billable; use Laravel\Sanctum\HasApiTokens; -class User extends Authenticatable implements FilamentUser +class User extends Authenticatable implements FilamentUser, HasName { use Billable, HasApiTokens, HasFactory, Notifiable; @@ -30,6 +31,11 @@ class User extends Authenticatable implements FilamentUser 'github_token', ]; + public function getFilamentName(): string + { + return $this->attributes['display_name'] ?? $this->name ?? $this->email; + } + public function canAccessPanel(Panel $panel): bool { return $this->isAdmin(); diff --git a/tests/Feature/UserModelTest.php b/tests/Feature/UserModelTest.php new file mode 100644 index 000000000..857336e50 --- /dev/null +++ b/tests/Feature/UserModelTest.php @@ -0,0 +1,40 @@ +create(['name' => 'John Doe']); + + $this->assertSame('John Doe', $user->getFilamentName()); + } + + public function test_get_filament_name_returns_display_name_when_name_is_null(): void + { + $user = User::factory()->create(['name' => null, 'display_name' => 'Custom Name']); + + $this->assertSame('Custom Name', $user->getFilamentName()); + } + + public function test_get_filament_name_returns_email_when_name_and_display_name_are_null(): void + { + $user = User::factory()->create(['name' => null, 'display_name' => null]); + + $this->assertSame($user->email, $user->getFilamentName()); + } + + public function test_get_filament_name_always_returns_string(): void + { + $user = User::factory()->create(['name' => null, 'display_name' => null]); + + $this->assertIsString($user->getFilamentName()); + } +}