PHP code example of worldesports / laravel-auto-tenancy

1. Go to this page and download the library: Download worldesports/laravel-auto-tenancy 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/ */

    

worldesports / laravel-auto-tenancy example snippets




return [
    // Your User model
    'user_model' => App\\Models\\User::class,
    
    // Main database connection
    'main_connection' => config('database.default', 'mysql'),
    
    // Auto-create tenant on user registration (optional)
    'auto_create_tenant' => false,

    // Optional email-domain detection; disabled by default for security
    'auto_detect_by_email' => false,
    
    // Performance optimizations
    'cache_connections' => true,
    
    // Security features
    'encrypt_connection_details' => false,
    
    // ... more options
];

// In config/multi-tenancy.php
'user_model' => App\Models\CustomUser::class,

// In routes/web.php or routes/api.php
Route::middleware(['auth', 'tenant'])->group(function () {
    // Your tenant-aware routes here
});

Route::middleware(['auth', 'tenant', 'tenant.);



namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Worldesports\MultiTenancy\Traits\BelongsToTenant;

class Post extends Model
{
    use BelongsToTenant; // Automatically uses tenant database
    
    // Your model code...
}



namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Worldesports\MultiTenancy\Traits\TenantScoped;

class Document extends Model
{
    use TenantScoped; // Automatically scopes by tenant_id
    
    protected $fillable = ['title', 'content', 'tenant_id'];
}

'tenant_migrations_path' => database_path('migrations/tenant'),

use Worldesports\MultiTenancy\Facades\MultiTenancy;
use Worldesports\MultiTenancy\Models\Tenant;
use Worldesports\MultiTenancy\Models\TenantDatabase;

// Get current tenant
$tenant = MultiTenancy::getTenant();

// Manually set a tenant
$tenant = Tenant::find(1);
MultiTenancy::setTenant($tenant);

// Manually set a tenant and pick a specific tenant database
$database = TenantDatabase::find(5);
MultiTenancy::useDatabase($database); // switches default connection to this DB

// Or pass a database ID when setting the tenant (falls back to primary/first if null)
MultiTenancy::setTenant($tenant, $databaseId = 5);

// Check if tenant is set
if (MultiTenancy::hasTenant()) {
    // Tenant is active, queries will use tenant database
}

// Switch back to main connection
MultiTenancy::switchToMainConnection();

// Reset tenant context completely
MultiTenancy::resetTenant();

// Purge all cached connections
MultiTenancy::purgeConnections();

// Scope a model to a tenant (uses its primary DB)
Invoice::forTenant($tenantId = 10)->get();

// Scope a model to a specific tenant *database* without switching the app default
Invoice::forTenant($tenantId = 10, $databaseId = 22)->get();

'auto_detect_by_email' => true,

'security' => [
    'allow_email_domain_access' => true,
],

'subdomain' => [
    'enabled' => true,
    'base_domain' => 'example.com',
],

'auto_create_tenant' => true,

// Apply the tenant middleware after auth on routes that should resolve tenant context
Route::middleware(['auth', \Worldesports\MultiTenancy\Middleware\SetTenant::class])
    ->get('/dashboard', [DashboardController::class, 'index']);

// With error handling options
Route::middleware(['auth', \Worldesports\MultiTenancy\Middleware\SetTenant::class . ':error'])
    ->get('/api/data', [ApiController::class, 'index']);

// Require a tenant to be present (403s if missing)
Route::middleware(['auth', 'tenant', 'tenant.

'auto_create_tenant' => false,

'auto_detect_by_email' => false,

'subdomain' => [
    'enabled' => false,
    'base_domain' => null,
],

'tenant_migrations_path' => database_path('migrations/tenant'),

'cache_connections' => true,

'encrypt_connection_password' => true,

'security' => [
    'check_user_tenant_access' => true,
    'allow_email_domain_access' => false,
],

// Auto-set tenant on user login
Event::listen(Login::class, SetTenantOnLogin::class);

// Auto-create tenant on user registration (optional)
Event::listen(Registered::class, CreateTenantOnRegistration::class);

// Check if user has access to tenant
if (!MultiTenancy::userHasAccessToTenant($user, $tenant)) {
    throw new UnauthorizedException('Access denied');
}

// Sanitized connection details (excludes sensitive info)
$safeDetails = $tenantDatabase->safe_connection_details;

// Using BelongsToTenant trait
class Invoice extends Model
{
    use BelongsToTenant;
    
    // Automatically queries tenant database
    public static function recent()
    {
        return static::where('created_at', '>', now()->subDays(30))->get();
    }
}

// Using TenantScoped trait (for models with tenant_id)
class Order extends Model
{
    use TenantScoped;
    
    // Automatically scoped to current tenant
    public function scopeUnpaid($query)
    {
        return $query->where('paid', false);
    }
    
    // Bypass tenant scoping when needed
    public static function allTenantsOrders()
    {
        return static::withoutTenantScoping()->get();
    }
}

// User A logs in → uses the tenant database provisioned for User A
// User B logs in → uses the tenant database provisioned for User B
// User C logs in → uses the tenant database provisioned for User C

// All three users can be using the app simultaneously with different tenant databases!

// Web users (sessions)
Route::middleware(['auth:web', SetTenant::class])->group(function () {
    // Each web session gets its tenant context
});

// API users (tokens) 
Route::middleware(['auth:sanctum', SetTenant::class])->group(function () {
    // Each API request gets tenant context based on the authenticated user
});

// In your SocialAuthController (using Laravel Socialite)
class SocialAuthController extends Controller
{
    public function redirectToProvider($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    public function handleProviderCallback($provider)
    {
        $socialUser = Socialite::driver($provider)->user();
        
        // Find or create user
        $user = User::firstOrCreate(
            ['email' => $socialUser->getEmail()],
            [
                'name' => $socialUser->getName(),
                'password' => bcrypt(Str::random(16)), // Random password for social users
            ]
        );

        // Log the user in
        Auth::login($user);
        
        // The login listener can set tenant context for this request.
        // Keep the tenant middleware on authenticated routes for later requests.
        
        return redirect()->intended('/dashboard');
    }
}

// API route with post-auth tenant switching
Route::middleware(['auth:sanctum', 'tenant'])->group(function () {
    // The tenant middleware applies tenant context for the authenticated user
    Route::get('/api/tenant-data', function (Request $request) {
        // All queries automatically use the user's tenant database
        $data = SomeModel::all(); // Automatically scoped to tenant
        return response()->json($data);
    });
});

// Add tenant.

// If using custom authentication guard
'guards' => [
    'custom' => [
        'driver' => 'session',
        'provider' => 'custom_users',
    ],
],

'providers' => [
    'custom_users' => [
        'driver' => 'eloquent',
        'model' => App\Models\CustomUser::class,
    ],
],

// In your config/multi-tenancy.php
'user_model' => App\Models\CustomUser::class,

// The package works automatically with any authentication guard!

// For applications with multiple user types (admin, customer, etc.)
Route::middleware(['auth:web'])->group(function () {
    // Add 'tenant' to regular customer routes that need tenant context
});

Route::middleware(['auth:admin'])->group(function () {
    // Admin routes - can bypass tenant scoping when needed
    Route::get('/admin/all-tenants', function () {
        return Tenant::withoutGlobalScopes()->get(); // See all tenants
    });
});

// Enable auto-tenant creation in config/multi-tenancy.php
'auto_create_tenant' => true,

// When this optional listener is enabled, newly registered users get a tenant row:
// - Social media registration
// - Email/password registration  
// - API registration
// - SSO registration
// - Any custom registration flow
//
// Production apps should still provision tenant database credentials with tenant:create.
bash
php artisan tenant:install --force --migrate
bash
composer jetstream:install livewire
npm install && npm run build
php artisan migrate
bash
# Publish and run the migrations
php artisan vendor:publish --tag="multi-tenancy-migrations"
php artisan migrate

# Optionally, publish the config file
php artisan vendor:publish --tag="multi-tenancy-config"
bash
php artisan tenant:create 123 "Acme Store" \
  --db-driver=mysql \
  --db-host=127.0.0.1 \
  --db-name=acme_store \
  --db-username=acme_user \
  --db-password=secret \
  --force
bash
php artisan tenant:create 1 "MySQL Company" \
  --db-name=tenant_mysql_db \
  --db-driver=mysql \
  --db-host=127.0.0.1 \
  --db-port=3306 \
  --db-username=mysql_user \
  --db-password=secret \
  --force
bash
php artisan tenant:create 1 "MySQL Company" \
  --db-name=tenant_mysql_db \
  --db-driver=mysql \
  --db-host=127.0.0.1 \
  --db-port=3306 \
  --db-username=mysql_user \
  --db-password=secret \
  --create-db \
  --root-username=root \
  --root-password=root_secret \
  --force
bash
php artisan tenant:create 2 "PostgreSQL Company" \
  --db-name=tenant_postgres_db \
  --db-driver=pgsql \
  --db-host=127.0.0.1 \
  --db-port=5432 \
  --db-username=postgres_user \
  --db-password=secret \
  --force
bash
php artisan tenant:create 4 "SQL Server Company" \
  --db-name=tenant_sqlserver_db \
  --db-driver=sqlsrv \
  --db-host=127.0.0.1 \
  --db-port=1433 \
  --db-username=sa \
  --db-password=secret \
  --force
bash
php artisan tenant:create 123 "Manual Tenant"
bash
# Create tenant for a company
php artisan tenant:create 1 "ACME Corporation" --domain=acme.com
bash
php artisan tenant:create 123 "Manual Tenant"