mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 11:34:03 +00:00
phpstan, global_cache, resolver improvements, InitializationHelpers trait
This commit is contained in:
parent
fd65cf1754
commit
87212e5390
35 changed files with 170 additions and 231 deletions
|
|
@ -10,6 +10,7 @@ parameters:
|
|||
|
||||
universalObjectCratesClasses:
|
||||
- Illuminate\Routing\Route
|
||||
- Illuminate\Database\Eloquent\Model
|
||||
|
||||
ignoreErrors:
|
||||
-
|
||||
|
|
@ -20,6 +21,14 @@ parameters:
|
|||
message: '#invalid type Laravel\\Telescope\\IncomingEntry#'
|
||||
paths:
|
||||
- src/Features/TelescopeTags.php
|
||||
-
|
||||
message: '#Parameter \#1 \$key of method Illuminate\\Contracts\\Cache\\Repository::put\(\) expects string#'
|
||||
paths:
|
||||
- src/helpers.php
|
||||
-
|
||||
message: '#PHPDoc tag \@param has invalid value \(dynamic#'
|
||||
paths:
|
||||
- src/helpers.php
|
||||
|
||||
checkMissingIterableValueType: false
|
||||
treatPhpDocTypesAsCertain: false
|
||||
|
|
|
|||
|
|
@ -8,24 +8,11 @@ use Illuminate\Console\Command;
|
|||
|
||||
class Install extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'tenancy:install';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Install stancl/tenancy.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
$this->comment('Installing stancl/tenancy...');
|
||||
$this->callSilent('vendor:publish', [
|
||||
|
|
|
|||
|
|
@ -15,30 +15,15 @@ class Link extends Command
|
|||
{
|
||||
use HasATenantsOption;
|
||||
|
||||
/**
|
||||
* The console command signature.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'tenants:link
|
||||
{--tenants=* : The tenant(s) to run the command for. Default: all}
|
||||
{--relative : Create the symbolic link using relative paths}
|
||||
{--force : Recreate existing symbolic links}
|
||||
{--remove : Remove symbolic links}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create or remove tenant symbolic links.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
$tenants = $this->getTenants();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ namespace Stancl\Tenancy\Commands;
|
|||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Database\Console\Migrations\MigrateCommand;
|
||||
use Illuminate\Database\Migrations\Migrator;
|
||||
use Stancl\Tenancy\Concerns\DealsWithMigrations;
|
||||
use Stancl\Tenancy\Concerns\ExtendsLaravelCommand;
|
||||
use Stancl\Tenancy\Concerns\HasATenantsOption;
|
||||
use Stancl\Tenancy\Events\DatabaseMigrated;
|
||||
|
|
@ -15,7 +14,7 @@ use Stancl\Tenancy\Events\MigratingDatabase;
|
|||
|
||||
class Migrate extends MigrateCommand
|
||||
{
|
||||
use HasATenantsOption, DealsWithMigrations, ExtendsLaravelCommand;
|
||||
use HasATenantsOption, ExtendsLaravelCommand;
|
||||
|
||||
protected $description = 'Run migrations for tenant(s)';
|
||||
|
||||
|
|
@ -31,10 +30,7 @@ class Migrate extends MigrateCommand
|
|||
$this->specifyParameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
foreach (config('tenancy.migration_parameters') as $parameter => $value) {
|
||||
if (! $this->input->hasParameterOption($parameter)) {
|
||||
|
|
@ -43,10 +39,10 @@ class Migrate extends MigrateCommand
|
|||
}
|
||||
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) {
|
||||
tenancy()->runForMultiple($this->getTenants(), function ($tenant) {
|
||||
$this->line("Tenant: {$tenant->getTenantKey()}");
|
||||
|
||||
event(new MigratingDatabase($tenant));
|
||||
|
|
@ -56,5 +52,7 @@ class Migrate extends MigrateCommand
|
|||
|
||||
event(new DatabaseMigrated($tenant));
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,19 +5,13 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Stancl\Tenancy\Concerns\DealsWithMigrations;
|
||||
use Stancl\Tenancy\Concerns\HasATenantsOption;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
final class MigrateFresh extends Command
|
||||
{
|
||||
use HasATenantsOption, DealsWithMigrations;
|
||||
use HasATenantsOption;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Drop all tables and re-run all migrations for tenant(s)';
|
||||
|
||||
public function __construct()
|
||||
|
|
@ -29,12 +23,9 @@ final class MigrateFresh extends Command
|
|||
$this->setName('tenants:migrate-fresh');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) {
|
||||
tenancy()->runForMultiple($this->getTenants(), function ($tenant) {
|
||||
$this->info('Dropping tables.');
|
||||
$this->call('db:wipe', array_filter([
|
||||
'--database' => 'tenant',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ namespace Stancl\Tenancy\Commands;
|
|||
|
||||
use Illuminate\Database\Console\Migrations\RollbackCommand;
|
||||
use Illuminate\Database\Migrations\Migrator;
|
||||
use Stancl\Tenancy\Concerns\DealsWithMigrations;
|
||||
use Stancl\Tenancy\Concerns\ExtendsLaravelCommand;
|
||||
use Stancl\Tenancy\Concerns\HasATenantsOption;
|
||||
use Stancl\Tenancy\Events\DatabaseRolledBack;
|
||||
|
|
@ -14,25 +13,10 @@ use Stancl\Tenancy\Events\RollingBackDatabase;
|
|||
|
||||
class Rollback extends RollbackCommand
|
||||
{
|
||||
use HasATenantsOption, DealsWithMigrations, ExtendsLaravelCommand;
|
||||
use HasATenantsOption, ExtendsLaravelCommand;
|
||||
|
||||
protected static function getTenantCommandName(): string
|
||||
{
|
||||
return 'tenants:rollback';
|
||||
}
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Rollback migrations for tenant(s).';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Migrator $migrator)
|
||||
{
|
||||
parent::__construct($migrator);
|
||||
|
|
@ -40,10 +24,7 @@ class Rollback extends RollbackCommand
|
|||
$this->specifyTenantSignature();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
foreach (config('tenancy.migration_parameters') as $parameter => $value) {
|
||||
if (! $this->input->hasParameterOption($parameter)) {
|
||||
|
|
@ -52,7 +33,7 @@ class Rollback extends RollbackCommand
|
|||
}
|
||||
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) {
|
||||
|
|
@ -65,5 +46,12 @@ class Rollback extends RollbackCommand
|
|||
|
||||
event(new DatabaseRolledBack($tenant));
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected static function getTenantCommandName(): string
|
||||
{
|
||||
return 'tenants:rollback';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,27 +11,14 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||
|
||||
class Run extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Run a command for tenant(s)';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'tenants:run {commandname : The artisan command.}
|
||||
{--tenants=* : The tenant(s) to run the command for. Default: all}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
$argvInput = $this->ArgvInput();
|
||||
$argvInput = $this->argvInput();
|
||||
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) use ($argvInput) {
|
||||
$this->line("Tenant: {$tenant->getTenantKey()}");
|
||||
|
||||
|
|
@ -41,10 +28,7 @@ class Run extends Command
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get command as ArgvInput instance.
|
||||
*/
|
||||
protected function ArgvInput(): ArgvInput
|
||||
protected function argvInput(): ArgvInput
|
||||
{
|
||||
// Convert string command to array
|
||||
$subCommand = explode(' ', $this->argument('commandname'));
|
||||
|
|
|
|||
|
|
@ -14,29 +14,16 @@ class Seed extends SeedCommand
|
|||
{
|
||||
use HasATenantsOption;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Seed tenant database(s).';
|
||||
|
||||
protected $name = 'tenants:seed';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ConnectionResolverInterface $resolver)
|
||||
{
|
||||
parent::__construct($resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
foreach (config('tenancy.seeder_parameters') as $parameter => $value) {
|
||||
if (! $this->input->hasParameterOption($parameter)) {
|
||||
|
|
@ -45,7 +32,7 @@ class Seed extends SeedCommand
|
|||
}
|
||||
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) {
|
||||
|
|
@ -58,5 +45,7 @@ class Seed extends SeedCommand
|
|||
|
||||
event(new DatabaseSeeded($tenant));
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,24 +9,11 @@ use Stancl\Tenancy\Contracts\Tenant;
|
|||
|
||||
class TenantList extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'tenants:list';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'List tenants.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
$this->info('Listing all tenants.');
|
||||
tenancy()
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ namespace Stancl\Tenancy\Concerns;
|
|||
|
||||
trait DealsWithMigrations
|
||||
{
|
||||
protected function getMigrationPaths()
|
||||
protected function getMigrationPaths(): array
|
||||
{
|
||||
if ($this->input->hasOption('path') && $this->input->getOption('path')) {
|
||||
return parent::getMigrationPaths();
|
||||
}
|
||||
|
||||
return database_path('migrations/tenant');
|
||||
return [database_path('migrations/tenant')];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Stancl\Tenancy\Contracts;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
interface UniqueIdentifierGenerator
|
||||
{
|
||||
/**
|
||||
* Generate a unique identifier.
|
||||
* Generate a unique identifier for a model.
|
||||
*/
|
||||
public static function generate($resource): string;
|
||||
public static function generate(Model $model): string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ use Stancl\Tenancy\Contracts\Domain;
|
|||
|
||||
/**
|
||||
* @property-read Domain[]|\Illuminate\Database\Eloquent\Collection $domains
|
||||
* @mixin \Illuminate\Database\Eloquent\Model
|
||||
* @mixin \Stancl\Tenancy\Contracts\Tenant
|
||||
*/
|
||||
trait HasDomains
|
||||
{
|
||||
|
|
|
|||
19
src/Database/Concerns/InitializationHelpers.php
Normal file
19
src/Database/Concerns/InitializationHelpers.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Stancl\Tenancy\Database\Concerns;
|
||||
|
||||
/**
|
||||
* @mixin \Stancl\Tenancy\Contracts\Tenant
|
||||
*/
|
||||
trait InitializationHelpers
|
||||
{
|
||||
public function enter(): void
|
||||
{
|
||||
tenancy()->initialize($this);
|
||||
}
|
||||
|
||||
public function leave(): void
|
||||
{
|
||||
tenancy()->end();
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ class Tenant extends Model implements Contracts\Tenant
|
|||
Concerns\HasDataColumn,
|
||||
Concerns\HasInternalKeys,
|
||||
Concerns\TenantRun,
|
||||
Concerns\InitializationHelpers,
|
||||
Concerns\InvalidatesResolverCache;
|
||||
|
||||
protected $table = 'tenants';
|
||||
|
|
|
|||
|
|
@ -8,11 +8,7 @@ use Stancl\Tenancy\Tenancy;
|
|||
|
||||
abstract class TenancyEvent
|
||||
{
|
||||
/** @var Tenancy */
|
||||
public $tenancy;
|
||||
|
||||
public function __construct(Tenancy $tenancy)
|
||||
{
|
||||
$this->tenancy = $tenancy;
|
||||
}
|
||||
public function __construct(
|
||||
public Tenancy $tenancy,
|
||||
) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,20 +4,18 @@ declare(strict_types=1);
|
|||
|
||||
namespace Stancl\Tenancy\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Stancl\Tenancy\Contracts\TenantCouldNotBeIdentifiedException;
|
||||
use Stancl\Tenancy\Contracts\TenantResolver;
|
||||
use Stancl\Tenancy\Tenancy;
|
||||
|
||||
/**
|
||||
* @property Tenancy $tenancy
|
||||
* @property TenantResolver $resolver
|
||||
*/
|
||||
abstract class IdentificationMiddleware
|
||||
{
|
||||
/** @var callable */
|
||||
public static $onFail;
|
||||
|
||||
/** @var Tenancy */
|
||||
protected $tenancy;
|
||||
|
||||
/** @var TenantResolver */
|
||||
protected $resolver;
|
||||
public static ?Closure $onFail = null;
|
||||
|
||||
public function initializeTenancy($request, $next, ...$resolverArguments)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,32 +5,21 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Stancl\Tenancy\Resolvers\DomainTenantResolver;
|
||||
use Stancl\Tenancy\Tenancy;
|
||||
|
||||
class InitializeTenancyByDomain extends IdentificationMiddleware
|
||||
{
|
||||
/** @var callable|null */
|
||||
public static $onFail;
|
||||
public static ?Closure $onFail = null;
|
||||
|
||||
/** @var Tenancy */
|
||||
protected $tenancy;
|
||||
public function __construct(
|
||||
protected Tenancy $tenancy,
|
||||
protected DomainTenantResolver $resolver,
|
||||
) {}
|
||||
|
||||
/** @var DomainTenantResolver */
|
||||
protected $resolver;
|
||||
|
||||
public function __construct(Tenancy $tenancy, DomainTenantResolver $resolver)
|
||||
{
|
||||
$this->tenancy = $tenancy;
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
/** @return \Illuminate\Http\Response|mixed */
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
return $this->initializeTenancy(
|
||||
$request,
|
||||
|
|
|
|||
|
|
@ -5,16 +5,13 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class InitializeTenancyByDomainOrSubdomain
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
/** @return \Illuminate\Http\Response|mixed */
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
if ($this->isSubdomain($request->getHost())) {
|
||||
return app(InitializeTenancyBySubdomain::class)->handle($request, $next);
|
||||
|
|
|
|||
|
|
@ -16,22 +16,15 @@ use Stancl\Tenancy\Tenancy;
|
|||
|
||||
class InitializeTenancyByPath extends IdentificationMiddleware
|
||||
{
|
||||
/** @var callable|null */
|
||||
public static $onFail;
|
||||
public static ?Closure $onFail = null;
|
||||
|
||||
/** @var Tenancy */
|
||||
protected $tenancy;
|
||||
public function __construct(
|
||||
protected Tenancy $tenancy,
|
||||
protected PathTenantResolver $resolver,
|
||||
) {}
|
||||
|
||||
/** @var PathTenantResolver */
|
||||
protected $resolver;
|
||||
|
||||
public function __construct(Tenancy $tenancy, PathTenantResolver $resolver)
|
||||
{
|
||||
$this->tenancy = $tenancy;
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
|
||||
public function handle(Request $request, Closure $next)
|
||||
/** @return \Illuminate\Http\Response|mixed */
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
/** @var Route $route */
|
||||
$route = $request->route();
|
||||
|
|
|
|||
|
|
@ -11,33 +11,17 @@ use Stancl\Tenancy\Tenancy;
|
|||
|
||||
class InitializeTenancyByRequestData extends IdentificationMiddleware
|
||||
{
|
||||
/** @var string|null */
|
||||
public static $header = 'X-Tenant';
|
||||
public static string $header = 'X-Tenant';
|
||||
public static string $queryParameter = 'tenant';
|
||||
public static ?Closure $onFail = null;
|
||||
|
||||
/** @var string|null */
|
||||
public static $queryParameter = 'tenant';
|
||||
public function __construct(
|
||||
protected Tenancy $tenancy,
|
||||
protected RequestDataTenantResolver $resolver,
|
||||
) {}
|
||||
|
||||
/** @var callable|null */
|
||||
public static $onFail;
|
||||
|
||||
/** @var Tenancy */
|
||||
protected $tenancy;
|
||||
|
||||
/** @var TenantResolver */
|
||||
protected $resolver;
|
||||
|
||||
public function __construct(Tenancy $tenancy, RequestDataTenantResolver $resolver)
|
||||
{
|
||||
$this->tenancy = $tenancy;
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
/** @return \Illuminate\Http\Response|mixed */
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
if ($request->method() !== 'OPTIONS') {
|
||||
return $this->initializeTenancy($request, $next, $this->getPayload($request));
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ namespace Stancl\Tenancy\Middleware;
|
|||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Str;
|
||||
use Stancl\Tenancy\Exceptions\NotASubdomainException;
|
||||
|
|
@ -21,15 +22,10 @@ class InitializeTenancyBySubdomain extends InitializeTenancyByDomain
|
|||
*/
|
||||
public static $subdomainIndex = 0;
|
||||
|
||||
/** @var callable|null */
|
||||
public static $onFail;
|
||||
public static ?Closure $onFail = null;
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
/** @return Response|mixed */
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
$subdomain = $this->makeSubdomain($request->getHost());
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,11 @@ class PreventAccessFromCentralDomains
|
|||
{
|
||||
/**
|
||||
* Set this property if you want to customize the on-fail behavior.
|
||||
*
|
||||
* @var callable|null
|
||||
*/
|
||||
public static $abortRequest;
|
||||
public static ?Closure $abortRequest;
|
||||
|
||||
public function handle(Request $request, Closure $next)
|
||||
/** @return \Illuminate\Http\Response|mixed */
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
if (in_array($request->getHost(), config('tenancy.central_domains'))) {
|
||||
$abortRequest = static::$abortRequest ?? function () {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ class ScopeSessions
|
|||
{
|
||||
public static $tenantIdKey = '_tenant_id';
|
||||
|
||||
public function handle(Request $request, Closure $next)
|
||||
/** @return \Illuminate\Http\Response|mixed */
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
if (! tenancy()->initialized) {
|
||||
throw new TenancyNotInitializedException('Tenancy needs to be initialized before the session scoping middleware is executed');
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ abstract class CachedTenantResolver implements TenantResolver
|
|||
|
||||
abstract public function resolveWithoutCache(mixed ...$args): Tenant;
|
||||
|
||||
public function resolved(Tenant $tenant, ...$args): void
|
||||
public function resolved(Tenant $tenant, mixed ...$args): void
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ class DomainTenantResolver extends Contracts\CachedTenantResolver
|
|||
{
|
||||
$domain = $args[0];
|
||||
|
||||
/** @var Tenant|null $tenant */
|
||||
$tenant = config('tenancy.tenant_model')::query()
|
||||
->whereHas('domains', fn (Builder $query) => $query->where('domain', $domain))
|
||||
->with('domains')
|
||||
|
|
@ -39,7 +38,7 @@ class DomainTenantResolver extends Contracts\CachedTenantResolver
|
|||
throw new TenantCouldNotBeIdentifiedOnDomainException($args[0]);
|
||||
}
|
||||
|
||||
public function resolved(Tenant $tenant, ...$args): void
|
||||
public function resolved(Tenant $tenant, mixed ...$args): void
|
||||
{
|
||||
$this->setCurrentDomain($tenant, $args[0]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class PathTenantResolver extends Contracts\CachedTenantResolver
|
|||
/** @var Route $route */
|
||||
$route = $args[0];
|
||||
|
||||
if ($id = $route->parameter(static::$tenantParameterName)) {
|
||||
if ($id = (string) $route->parameter(static::$tenantParameterName)) {
|
||||
$route->forgetParameter(static::$tenantParameterName);
|
||||
|
||||
if ($tenant = tenancy()->find($id)) {
|
||||
|
|
@ -37,7 +37,7 @@ class PathTenantResolver extends Contracts\CachedTenantResolver
|
|||
public function getArgsForTenant(Tenant $tenant): array
|
||||
{
|
||||
return [
|
||||
[$tenant->id],
|
||||
[$tenant->getTenantKey()],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class RequestDataTenantResolver extends Contracts\CachedTenantResolver
|
|||
|
||||
public function resolveWithoutCache(mixed ...$args): Tenant
|
||||
{
|
||||
$payload = $args[0];
|
||||
$payload = (string) $args[0];
|
||||
|
||||
if ($payload && $tenant = tenancy()->find($payload)) {
|
||||
return $tenant;
|
||||
|
|
@ -29,7 +29,7 @@ class RequestDataTenantResolver extends Contracts\CachedTenantResolver
|
|||
public function getArgsForTenant(Tenant $tenant): array
|
||||
{
|
||||
return [
|
||||
[$tenant->id],
|
||||
[$tenant->getTenantKey()],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Stancl\Tenancy;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
||||
|
||||
|
|
@ -11,7 +12,7 @@ use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
|||
|
||||
class UUIDGenerator implements UniqueIdentifierGenerator
|
||||
{
|
||||
public static function generate($resource): string
|
||||
public static function generate(Model $model): string
|
||||
{
|
||||
return Uuid::uuid4()->toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Stancl\Tenancy\CacheManager;
|
||||
use Stancl\Tenancy\Contracts\Tenant;
|
||||
use Stancl\Tenancy\Tenancy;
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ if (! function_exists('tenant')) {
|
|||
|
||||
if (! function_exists('tenant_asset')) {
|
||||
// todo docblock
|
||||
// todo add an option to generate paths respecting the ASSET_URL
|
||||
function tenant_asset(string|null $asset): string
|
||||
{
|
||||
return route('stancl.tenancy.asset', ['path' => $asset]);
|
||||
|
|
@ -42,17 +44,43 @@ if (! function_exists('tenant_asset')) {
|
|||
}
|
||||
|
||||
if (! function_exists('global_asset')) {
|
||||
function global_asset(string $asset) // todo types, also inside the globalUrl implementation
|
||||
function global_asset(string $asset): string
|
||||
{
|
||||
return app('globalUrl')->asset($asset);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('global_cache')) {
|
||||
function global_cache()
|
||||
/**
|
||||
* Get / set the specified cache value in the global cache store.
|
||||
*
|
||||
* If an array is passed, we'll assume you want to put to the cache.
|
||||
*
|
||||
* @param dynamic key|key,default|data,expiration|null
|
||||
* @return mixed|\Illuminate\Cache\CacheManager
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
function global_cache(): mixed
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
|
||||
if (empty($arguments)) {
|
||||
return app('globalCache');
|
||||
}
|
||||
|
||||
if (is_string($arguments[0])) {
|
||||
return app('globalCache')->get(...$arguments);
|
||||
}
|
||||
|
||||
if (!is_array($arguments[0])) {
|
||||
throw new InvalidArgumentException(
|
||||
'When setting a value in the cache, you must pass an array of key / value pairs.'
|
||||
);
|
||||
}
|
||||
|
||||
return app('globalCache')->put(key($arguments[0]), reset($arguments[0]), $arguments[1] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('tenant_route')) {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ test('tenant can be identified by domain', function () {
|
|||
|
||||
test('onfail logic can be customized', function () {
|
||||
InitializeTenancyByDomain::$onFail = function () {
|
||||
return 'foo';
|
||||
return response('foo');
|
||||
};
|
||||
|
||||
pest()
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ use Stancl\Tenancy\Database\Concerns\HasDatabase;
|
|||
use Stancl\Tenancy\Database\Concerns\HasDomains;
|
||||
use Stancl\Tenancy\Database\Models;
|
||||
|
||||
/**
|
||||
* @method static static create(array $attributes = [])
|
||||
*/
|
||||
class Tenant extends Models\Tenant implements TenantWithDatabase
|
||||
{
|
||||
use HasDatabase, HasDomains;
|
||||
|
|
|
|||
|
|
@ -50,3 +50,17 @@ test('global cache manager stores data in global cache', function () {
|
|||
expect(cache('def'))->toBe('ghi');
|
||||
});
|
||||
|
||||
test('the global_cache helper supports the same syntax as the cache helper', function () {
|
||||
$tenant = Tenant::create();
|
||||
$tenant->enter();
|
||||
|
||||
expect(cache('foo'))->toBe(null); // tenant cache is empty
|
||||
|
||||
global_cache(['foo' => 'bar']);
|
||||
expect(global_cache('foo'))->toBe('bar');
|
||||
|
||||
global_cache()->set('foo', 'baz');
|
||||
expect(global_cache()->get('foo'))->toBe('baz');
|
||||
|
||||
expect(cache('foo'))->toBe(null); // tenant cache is not affected
|
||||
});
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ test('exception is thrown when tenant cannot be identified by path', function ()
|
|||
|
||||
test('onfail logic can be customized', function () {
|
||||
InitializeTenancyByPath::$onFail = function () {
|
||||
return 'foo';
|
||||
return response('foo');
|
||||
};
|
||||
|
||||
pest()
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ test('header identification works', function () {
|
|||
});
|
||||
|
||||
test('query parameter identification works', function () {
|
||||
InitializeTenancyByRequestData::$header = null;
|
||||
InitializeTenancyByRequestData::$queryParameter = 'tenant';
|
||||
|
||||
$tenant = Tenant::create();
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ test('tenant can be identified by subdomain', function () {
|
|||
|
||||
test('onfail logic can be customized', function () {
|
||||
InitializeTenancyBySubdomain::$onFail = function () {
|
||||
return 'foo';
|
||||
return response('foo');
|
||||
};
|
||||
|
||||
pest()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue