I am using Filament and using multi tenancy of Filament v3 of documentation, but the problem Filament\FilamentManager::getTenantName(): Return value must be of type string, null returned when I make a login of an user role http://127.0.0.1:8000/user/ beacause the panel.
- Company.php (Model)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\{Model,SoftDeletes};
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Str;
class Company extends Model
{
use HasFactory, SoftDeletes;
protected $table="companies";
protected $primaryKey = 'id';
protected $fillable = [
'uuid',
'name_company',
];
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->uuid = (string) Str::uuid();
});
}
public function getRouteKeyName()
{
return 'uuid';
}
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'users_companies');
}
}
- User.php (Model)
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Filament\Models\Contracts\FilamentUser;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
use Filament\Panel;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;
use Filament\Models\Contracts\HasTenants;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class User extends Authenticatable implements FilamentUser, HasTenants
{
use HasFactory, Notifiable, SoftDeletes, HasRoles;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'uuid',
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->uuid = (string) Str::uuid();
});
}
public function getRouteKeyName()
{
return 'uuid';
}
public function companies(): BelongsToMany
{
return $this->belongsToMany(Company::class, 'users_companies');
}
public function getTenants(Panel $panel): Collection
{
return $this->companies;
}
public function canAccessTenant(Model $tenant): bool
{
return $this->companies()->whereKey($tenant->getKey())->exists();
}
public function canAccessPanel(Panel $panel): bool
{
$user = Auth::user();
$role = $user->getRoleNames();
$panel_role = [
'admin' => 'Admin',
'user' => 'User',
];
return isset($panel_role[$panel->getId()]) && $role->contains($panel_role[$panel->getId()]);
}
}
- migration.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('users_empresas', function (Blueprint $table) {
$table->id();
$table->foreignId("user_id")->constrained("users");
$table->foreignId("company_id")->constrained("companies");
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users_companies');
}
};
- AdminPanelProvider.php
<?php
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use App\Models\Company;
use App\Filament\Resources\UserResource;
class UserPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->sidebarCollapsibleOnDesktop()
->id('user')
->path('user')
->login()
->profile()
->passwordReset()
->tenant(Company::class)
->colors([
'primary' => "#6D4AFF",
])
->discoverResources(in: app_path('Filament/User/Resources'), for: 'App\\Filament\\User\\Resources')
->discoverPages(in: app_path('Filament/User/Pages'), for: 'App\\Filament\\User\\Pages')
->pages([
Pages\Dashboard::class,
])
->discoverWidgets(in: app_path('Filament/User/Widgets'), for: 'App\\Filament\\User\\Widgets')
->widgets([
//Widgets\AccountWidget::class,
//Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([
Authenticate::class,
]);
}
}
The erron happen when I decide make a login in user role because the multi tenancy structure of Filament version 3.
You need to sign in to view this answers