How to override laravel filament vendor method/function

1.5k views Asked by At

I am using Laravel with FilamentPhp and as per requirements I changes default "name" to "username" in my migration and when I login I am getting errors because I changed name to username and If I update the name to username in vendor filamentmanager.php then It's working but it's bad practise

Filament\FilamentManager::getUserName(): Return value must be of type string, null returned

How can I override that function from this

public function getUserName(Model | Authenticatable $user): string
    {
        if ($user instanceof HasName) {
            return $user->getFilamentName();
        }

        return $user->getAttributeValue('name');
    }

to this

public function getUserName(Model | Authenticatable $user): string
    {
        if ($user instanceof HasName) {
            return $user->getFilamentName();
        }

        **return $user->getAttributeValue('username');**
    }

Please advice, I tried creating custom service provide but not succeed.

2

There are 2 answers

0
AmooAti On BEST ANSWER

Filament did that for you, there's no need to override anything.

Custom behavior can be achieved with the help of below lines of core code:

if ($user instanceof HasName) {
    return $user->getFilamentName();
}

This means Filament checks whether your model implements that interface. If implemented, it will use the interface method to return a custom value instead of the default name column.

First, your User model class needs to implement HasName interface, then you must implement the interface's method to return your desired value.

Here's an example:


<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Filament\Models\Contracts\HasName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable implements HasName
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'username',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];

    public function getFilamentName(): string
    {
        return $this->getAttributeValue('username');
    }
}

1
arpan.r On

a custom service provider

php artisan make:provider CustomFilamentServiceProvider

register custom provider using config/app.php

'providers' => [
    App\Providers\CustomFilamentServiceProvider::class,
],

then override the method

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Filament\FilamentManager;

class CustomFilamentServiceProvider extends ServiceProvider
{
    public function register()
    {
        
    }

    public function boot()
    {
        $this->app->extend(FilamentManager::class, function ($manager) {
            $manager->macro('getUserName', function ($user) {
                if ($user instanceof HasName) {
                    return $user->getFilamentName();
                }

                return $user->getAttributeValue('username');
            });

            return $manager;
        });
    }
}

then clear cache

php artisan optimize:clear