PHP code example of eugenefvdm / multi-tenancy-pwa
1. Go to this page and download the library: Download eugenefvdm/multi-tenancy-pwa library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Tenant extends Model
{
/** @use HasFactory<\Database\Factories\TenantFactory> */
use HasFactory;
protected $fillable = [
'name',
];
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
}
use Eugenefvdm\MultiTenancyPWA\Traits\HasTenantRelationship;
namespace App\Http\Middleware;
use App\Models\Category;
use App\Models\Todo;
use Closure;
use Filament\Facades\Filament;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ApplyTenantScopes
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
Category::addGlobalScope(
fn (Builder $query) => $query->whereBelongsTo(Filament::getTenant()),
);
Todo::addGlobalScope(
fn (Builder $query) => $query->whereBelongsTo(Filament::getTenant()),
);
return $next($request);
}
}
use App\Http\Middleware\ApplyTenantScopes;
use App\Models\Tenant;
use Eugenefvdm\MultiTenancyPWA\Filament\Pages\Tenancy\RegisterNewTenant;
// Filament AdminPanelProvider extra sections
->colors([ // Already exists
'primary' => Color::Cyan
]);
->profile(\App\Filament\Pages\Auth\EditProfile::class);
->tenant(Tenant::class)
->registration()
->tenantRegistration(RegisterNewTenant::class)
->tenantProfile(EditMyTenantProfile::class)
->renderHook(
'panels::auth.login.form.after',
fn () => view('multi-tenancy-pwa::auth.socialite.google')
->tenantMiddleware([
ApplyTenantScopes::class,
], isPersistent: true)
->databaseNotifications();
namespace App\Notifications;
use Filament\Facades\Filament;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use NotificationChannels\WebPush\WebPushChannel;
use NotificationChannels\WebPush\WebPushMessage;
class WebpushNotification extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*/
public function __construct(private string $title = 'Default Title', private string $body = 'Default Body Text')
{
//
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return [WebPushChannel::class];
}
public function toWebPush($notifiable, $notification): WebPushMessage
{
$tenantId = Filament::getTenant()->id ?? 1;
return (new WebPushMessage)
->title($this->title)
->body($this->body)
->action('Call to action', 'do_something') // This appears as a button on the notification
->options(['TTL' => 10000])
->vibrate([300, 100, 400])
->data(['url' => config('app.url') . '/admin/' . $tenantId . '/notifications']);
// ->icon('/approved-icon.png')
// ->data(['id' => $notification->id])
// ->badge()
// ->dir()
// ->image()
// ->lang()
// ->renotify()
// ->
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasDefaultTenant;
use Filament\Models\Contracts\HasTenants;
use Filament\Panel;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable implements FilamentUser, HasDefaultTenant, HasTenants
{
use HasPushSubscriptions;
// ...
protected $fillable = [
'google_id'
];
// ...
public function canAccessPanel(Panel $panel): bool
{
return true;
}
public function tenants(): BelongsToMany
{
return $this->belongsToMany(Tenant::class);
}
public function getTenants(Panel $panel): Collection
{
return $this->tenants;
}
public function canAccessTenant(Model $tenant): bool
{
return $this->tenants()->whereKey($tenant)->exists();
}
public function getDefaultTenant(): ?Model
{
return $this->latestTenant()->first();
}
public function latestTenant(): BelongsTo
{
return $this->belongsTo(Tenant::class, 'latest_tenant_id');
}
}
use Filament\Resources\Resource;
protected static bool $isScopedToTenant = false;