-
-
Save nathandaly/44a83df5e3ea735eae91652c7a4894c9 to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| * Below is an the extended Filament resource your tenant panel resources | |
| * will have to extend so that the queries are scoped properly. | |
| */ | |
| namespace App\Filament; | |
| use Filament\Resources\Resource; | |
| use Illuminate\Database\Eloquent\Builder; | |
| class BaseResource extends Resource | |
| { | |
| public static function getEloquentQuery(): Builder | |
| { | |
| return static::getModel()::query(); | |
| } | |
| } |
| @if(\Filament\Facades\Filament::getTenant() !== null) | |
| <x-filament::button | |
| color="danger" | |
| icon="gmdi-logout" | |
| :href="config('app.url') . '/admin/tenancy/tenants'" | |
| tag="a" | |
| > | |
| Exit Tenant | |
| </x-filament::button> | |
| @endif |
| <?php | |
| /** | |
| * This middleware extends the Tenancy for Laravel one to catch | |
| * tenant ID and scope future requests in the tenant panel. | |
| */ | |
| declare(strict_types=1); | |
| namespace App\Http\Middleware; | |
| use App\Context\Tenant\Models\Tenant; | |
| use Illuminate\Contracts\Auth\Factory as AuthFactory; | |
| use Illuminate\Contracts\Auth\Guard; | |
| use Illuminate\Contracts\Session\Middleware\AuthenticatesSessions; | |
| use Illuminate\Http\Request; | |
| use Stancl\Tenancy\Middleware\InitializeTenancyBySubdomain as BaseMiddleware; | |
| use Closure; | |
| use Stancl\Tenancy\Resolvers\DomainTenantResolver; | |
| use Stancl\Tenancy\Tenancy; | |
| class InitializeTenancyBySubdomain extends BaseMiddleware implements AuthenticatesSessions | |
| { | |
| public function __construct( | |
| protected Tenancy $tenancy, | |
| protected DomainTenantResolver $resolver, | |
| protected AuthFactory $auth | |
| ) { | |
| parent::__construct($tenancy, $resolver); | |
| } | |
| public function handle(Request $request, Closure $next): mixed | |
| { | |
| $route = $request->route(); | |
| $record = $route->parameter('tenant'); | |
| if ($record && $tenant = Tenant::find($record)) { | |
| if ($domain = $tenant->domain) { | |
| $this->initializeTenancy($request, $next, $domain->domain); | |
| } | |
| } | |
| return $next($request); | |
| } | |
| protected function guard(): AuthFactory|Guard | |
| { | |
| return $this->auth; | |
| } | |
| } |
| <?php | |
| /** | |
| * The below is an example Tenant panel provider created with the following command: | |
| * php artisan make:filament-panel tenant | |
| * | |
| * The following code assumes you already have a central app scoped admin panel. | |
| */ | |
| declare(strict_types=1); | |
| namespace App\Providers\Filament; | |
| use App\Context\Tenant\Models\Tenant; | |
| use App\Filament\Pages\Login; | |
| use App\Http\Middleware\InitializeTenancyBySubdomain; | |
| use Filament\Facades\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\Contracts\View\View; | |
| 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\Support\Facades\Blade; | |
| use Illuminate\View\Middleware\ShareErrorsFromSession; | |
| class TenantPanelProvider extends PanelProvider | |
| { | |
| public function panel(Panel $panel): Panel | |
| { | |
| return $panel | |
| ->id('tenant') | |
| ->path('tenant') | |
| ->viteTheme([ | |
| 'resources/css/tailwind.css', | |
| 'resources/js/app.js', | |
| 'resources/css/filament/admin/theme.css', | |
| ]) | |
| ->login(Login::class) | |
| ->tenant(Tenant::class) | |
| ->discoverResources(in: app_path('Filament/Tenant/Resources'), for: 'App\\Filament\\Tenant\\Resources') | |
| ->discoverPages(in: app_path('Filament/Tenant/Pages'), for: 'App\\Filament\\Tenant\\Pages') | |
| ->discoverWidgets(in: app_path('Filament/Tenant/Widgets'), for: 'App\\Filament\\Tenant\\Widgets') | |
| ->pages([ | |
| Pages\Dashboard::class, | |
| ]) | |
| ->renderHook('panels::user-menu.before', fn (): View => view('components.button.exit-tenancy')) | |
| ->widgets([ | |
| Widgets\AccountWidget::class, | |
| Widgets\FilamentInfoWidget::class, | |
| ]) | |
| ->middleware([ | |
| InitializeTenancyBySubdomain::class, | |
| EncryptCookies::class, | |
| AddQueuedCookiesToResponse::class, | |
| StartSession::class, | |
| AuthenticateSession::class, | |
| ShareErrorsFromSession::class, | |
| VerifyCsrfToken::class, | |
| SubstituteBindings::class, | |
| DisableBladeIconComponents::class, | |
| DispatchServingFilamentEvent::class, | |
| ]) | |
| ->authMiddleware([ | |
| Authenticate::class, | |
| ]); | |
| } | |
| } |
| <?php | |
| /** | |
| * Below is an example of the Filament tenant resource in the central app. | |
| * When you click on a tenant row your app will redirect to the tenant panel scoped to the selected tenant. | |
| */ | |
| declare(strict_types=1); | |
| namespace App\Filament\Central\Tenancy; | |
| use Filament\Resources\Resource; | |
| class TenantsResource extends Resource | |
| { | |
| public static function table(Table $table): Table | |
| { | |
| return $table | |
| ->recordUrl( | |
| fn (Model $record): string => route('filament.tenant.pages.dashboard', ['tenant' => $record]), | |
| ) | |
| // Rest of your table definition... | |
| ; | |
| } | |
| // Rest of your resource code... | |
| } |
| <?php | |
| declare(strict_types=1); | |
| namespace App\Models; | |
| class User extends Authenticatable implements Syncable, MustVerifyEmail, HasTenants | |
| { | |
| use ResourceSyncing; | |
| // Your other model logic... | |
| /** | |
| * Add the `HasTenants` interface. | |
| * Add the below methods required by the above trait. | |
| */ | |
| public function getTenants(Panel $panel): Collection | |
| { | |
| return $this->tenants; | |
| } | |
| public function canAccessTenant(Model $tenant): bool | |
| { | |
| return true; | |
| } | |
| } |
Hello nathandaly, Are there any your public repository for the Laravel, FilamentPHP & stancl/tenancy all together. Please kindly share link with me. I really appreciate it. Thank you
I hope this will help:
https://github.com/savannabits/filament-tenancy-starter
Hello nathandaly, Are there any your public repository for the Laravel, FilamentPHP & stancl/tenancy all together. Please kindly share link with me. I really appreciate it. Thank you
I hope this will help: https://github.com/savannabits/filament-tenancy-starter
Thank you very much
Hello nathandaly, Are there any your public repository for the Laravel, FilamentPHP & stancl/tenancy all together. Please kindly share link with me. I really appreciate it. Thank you
I hope this will help: https://github.com/savannabits/filament-tenancy-starter
Hi Coolsam did you try it also with multi databases? im using multi db, using it with central domain it works properly, but when i try to add InitializeTenancyBySubdomain in the tenantPanel middleware, i got error Tenant could not be identified on domain test.
Hi @nathandaly I see the video you share in filament community until now I just try to do same think for my next project but until now I don't get that works fine. if you can share only the starter for that like login tenant / exit, add new tenant will be awesome.
I already tried this starter as well https://github.com/savannabits/filament-tenancy-starter but not working very well and missing a lot of logics
Does artisan route:cache work for you with this setup? I'm having trouble with route names being unique from central to tenants I think.
Unable to prepare route [admin/login] for serialization. Another route has already been assigned name [filament.admin.auth.login]
Edit: Ended up being caused by having multiple 'central_domains' set in my tenancy.php.
Thank you for putting this repo together, it was a huge help getting things moving!
@mstrihi mind sharing the link with @nathandaly video... cannot find it in filament community :(
Hi
Type of App\Http\Middleware\InitializeTenancyBySubdomain::$tenancy must not be defined (as in class Stancl\Tenancy\Middleware\InitializeTenancyByDomain)
Hi
Type of App\Http\Middleware\InitializeTenancyBySubdomain::$tenancy must not be defined (as in class Stancl\Tenancy\Middleware\InitializeTenancyByDomain)
In InitializeTenancyBySubdomain replace the code with:
<?php
/**
* This middleware extends the Tenancy for Laravel one to catch
* tenant ID and scope future requests in the tenant panel.
*/
declare(strict_types=1);
namespace App\Http\Middleware;
use App\Models\Tenant;
use Illuminate\Contracts\Auth\Factory as AuthFactory;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Session\Middleware\AuthenticatesSessions;
use Illuminate\Http\Request;
use Stancl\Tenancy\Middleware\InitializeTenancyBySubdomain as BaseMiddleware;
use Closure;
use Stancl\Tenancy\Resolvers\DomainTenantResolver;
use Stancl\Tenancy\Tenancy;
class InitializeTenancyBySubdomain extends BaseMiddleware implements AuthenticatesSessions
{
protected $tenancy;
protected $resolver;
public function __construct(
Tenancy $tenancy,
DomainTenantResolver $resolver,
protected AuthFactory $auth
)
{
$this->tenancy = $tenancy;
$this->resolver = $resolver;
parent::__construct($tenancy, $resolver);
}
public function handle($request, Closure $next): mixed
{
$route = $request->route();
$record = $route->parameter('tenant');
if ($record && $tenant = Tenant::find($record)) {
if ($domain = $tenant->domain) {
$this->initializeTenancy($request, $next, $domain->domain);
}
}
return $next($request);
}
protected function guard(): AuthFactory|Guard
{
return $this->auth;
}
}
filament
please share the video with me
@mstrihi mind sharing the link with @nathandaly video... cannot find it in filament community :(
Do you have a video
@MuhammedKkhaled @Waguilar33
here the link for the video https://www.answeroverflow.com/m/1135627479562854581
Hello nathandaly, Are there any your public repository for the Laravel, FilamentPHP & stancl/tenancy all together. Please kindly share link with me. I really appreciate it. Thank you