Dynamic Frontend Routing prefix when using Filament V3 Multi Tenancy #92
Replies: 2 comments 3 replies
-
What I always do when it comes to third-party modules and overriding some of their features: I create a class that extends from the one I want to override, and bind it in the container in a service provider. You could do that and use something like this: public function getRoutingPrefix(): ?string {
$user = Auth::user();
$tenant = $user->tenant;
return Str::start($tenant->slug, '/');
} And then bind the override: // in a ServiceProvider#register
$this->app->scoped(FilamentFabricatorManager::ID, MyFilamentFabricatorManagerOverride::class); |
Beta Was this translation helpful? Give feedback.
-
Here was my attempt. I have made changes to FilamentFabricatorServiceProvider for development and it works great, but I don't know how to override the base service provider. In my implementation I have internal pages, tenant shared pages, customizations of these shared pages and unique pages only for tenant. I collect domain information in a middleware to identify tenant class DomainDetectMiddleware {
public function handle($request, Closure $next) {
$domainName = $request->getHost();
$website = Website::whereHas('domains',function ($query) use ($domainName) {
$query->where('main_domain', $domainName);
})->first();
if ($website) {
config(['app.current_website' => $website]);
}
return $next($request);
}
} Then in the FilamentFabricatorServiceProvider I retrieve all published pages that are shared or unique to the domain. If a result has a public function bootingPackage(): void
{
Route::bind('filamentFabricatorPage', function ($value) {
// REMOVE THIS LINE AND REPLACE -> $pageUrls = FilamentFabricator::getPageUrls();
$pageUrls = $this->getPageUrlFromWebsite();
}
protected function getPageUrlFromWebsite(): array
{
$website = config('app.current_website');
$pagesQuery = FilamentFabricator::getPageModel()::query()
->select('id', 'slug', 'title', 'website_id', 'page_id', 'is_published')
->with(['allChildren']);
// Apply different conditions based on the 'is_internal' flag
if ($website->is_internal) {
$pagesQuery->where('website_id', $website->id)
->where('is_published', true);
} else {
$pagesQuery->where(function ($query) use ($website) {
$query->whereNull('website_id')
->orWhere(function ($query) use ($website) {
$query->where('website_id', $website->id)
->where('is_published', true);
});
});
}
$pages = $pagesQuery->get();
// Mapping pages to their related page's slug or themselves
$pages->each(function ($page) {
if (!blank($page->page_id)) {
$page->slug = FilamentFabricator::getPageModel()::find($page->page_id)?->slug ?? $page->slug;
}
});
// Filter and prioritize pages
$filteredPages = $pages->filter(fn($page) => is_null($page->website_id) || ($page->website_id == $website->id && $page->is_published))
->groupBy('slug')
->map(fn($groupedPages) => $groupedPages->sortByDesc(fn($page) => $page->website_id == $website->id)->first());
if ($filteredPages->isEmpty()) {
return [];
}
$filteredPages->each(fn(PageContract $page) => $this->setPageUrl($page));
return $this->pageUrls;
}
protected function setPageUrl(PageContract $page, string $parentUrl = null): string
{
$pageUrl = $parentUrl ? $parentUrl . '/' . trim($page->slug, " \n\r\t\v\x00/") : trim($page->slug);
if (filled($page->allChildren)) {
foreach ($page->allChildren as $child) {
$this->setPageUrl($child, $pageUrl);
}
}
return $this->pageUrls[$page->id] = Str::start($pageUrl, '/');
} This implementation will correctly display the correct page blocks and also not allow access to pages that are not available to tenant. So it all works, I just don't know how to get out of vendor package so the changes are not overwritten. Any thoughts? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
For fronteend routing when using Filament V3s Multi Tenancy, I am having an issue where the prefix in the config isn't enough to distinguish between frontend of different tenants.
I would ideally want to pass the tenant's slug or a unique identifier from users table in the url for the frontend so that different tenants can have /home or /about or /contact urls.
What would be the best way to override the FilamentFabricatorManager class's getRoutingPrefix method?
FilamentFabricatorManager.php
`public function getRoutingPrefix(): ?string
{
$prefix = config('filament-fabricator.routing.prefix');
Would appreciate any pointers. Happy to add a PR to make the package filament multitenant compatible.
Beta Was this translation helpful? Give feedback.
All reactions