From 489fbb9402c529255fb5fd8b4f1d4e9f3c93e52c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sat, 6 Apr 2024 01:22:14 +0200 Subject: [PATCH] add prompts to tenant:tinker --- composer.json | 3 +- src/Commands/Tinker.php | 58 ++++++++++++++++++++++++-- src/Resolvers/DomainTenantResolver.php | 23 ++++++---- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index c9a4e259..bd023fad 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "ramsey/uuid": "^4.7.3", "stancl/jobpipeline": "2.0.0-rc2", "stancl/virtualcolumn": "dev-master", - "spatie/invade": "^1.1" + "spatie/invade": "^1.1", + "laravel/prompts": "^0.1.17" }, "require-dev": { "laravel/framework": "^10.1|^11.2", diff --git a/src/Commands/Tinker.php b/src/Commands/Tinker.php index ce8a972e..c5b1093d 100644 --- a/src/Commands/Tinker.php +++ b/src/Commands/Tinker.php @@ -4,7 +4,10 @@ declare(strict_types=1); namespace Stancl\Tenancy\Commands; +use function Laravel\Prompts\search; +use function Laravel\Prompts\select; use Laravel\Tinker\Console\TinkerCommand as BaseTinker; +use Stancl\Tenancy\Resolvers\DomainTenantResolver; use Symfony\Component\Console\Input\InputArgument; class Tinker extends BaseTinker @@ -20,11 +23,58 @@ class Tinker extends BaseTinker public function handle() { - // ?: to support empty strings so that the original argument (`include`) can be reached even with a falsy tenant argument + /** @var string|int|null $tenantKey */ + $tenantKey = $this->argument('tenant'); - /** @var \Stancl\Tenancy\Contracts\Tenant|string|int $tenantKey */ - $tenantKey = $this->argument('tenant') ?: tenancy()->model()::first(); - tenancy()->initialize($tenantKey); + /** @var (\Stancl\Tenancy\Contracts\Tenant&\Illuminate\Database\Eloquent\Model)|null $firstTenant */ + $firstTenant = tenancy()->model()::first(); + + /** @var string|int|null $firstTenantKey */ + $firstTenantKey = $firstTenant?->getTenantKey(); + + $tenant = null; + + if (! $tenantKey) { + $select = select('Which tenant do you want to run Tinker as?', [ + 'first' => "First tenant ($firstTenantKey)", + 'searchById' => 'Search by id', + 'searchByDomain' => 'Search by domain', + ]); + + if ($select === 'first') { + $tenant = $firstTenant; + } elseif ($select === 'searchById') { + /** @var string $tenantKey */ + $tenantKey = search( + 'Enter the tenant key:', + fn (string $search) => strlen($search) > 0 + ? tenancy()->model()::where(tenancy()->model()->getTenantKeyName(), 'like', "$search%")->pluck(tenancy()->model()->getTenantKeyName())->all() + : [] + ); + + $tenant = tenancy()->find($tenantKey); + } elseif ($select === 'searchByDomain') { + /** @var string $domain */ + $domain = search( + 'Enter the tenant domain:', + fn (string $search) => strlen($search) > 0 + ? config('tenancy.models.domain')::where('domain', 'like', "$search%")->pluck('domain')->all() + : [] + ); + + $tenant = DomainTenantResolver::findTenantByDomain($domain); + } + } else { + $tenant = tenancy()->find($tenantKey); + } + + if (! $tenant) { + $this->components->error('No tenant found.'); + + return 1; + } + + tenancy()->initialize($tenant); return parent::handle(); } diff --git a/src/Resolvers/DomainTenantResolver.php b/src/Resolvers/DomainTenantResolver.php index da010dc8..6675972b 100644 --- a/src/Resolvers/DomainTenantResolver.php +++ b/src/Resolvers/DomainTenantResolver.php @@ -21,6 +21,20 @@ class DomainTenantResolver extends Contracts\CachedTenantResolver { $domain = $args[0]; + $tenant = static::findTenantByDomain($domain); + + /** @var (Tenant&Model)|null $tenant */ + if ($tenant) { + static::setCurrentDomain($tenant, $domain); + + return $tenant; + } + + throw new TenantCouldNotBeIdentifiedOnDomainException($domain); + } + + public static function findTenantByDomain(string $domain): (Tenant&Model)|null + { /** @var Tenant&Model $tenantModel */ $tenantModel = tenancy()->model(); @@ -36,13 +50,8 @@ class DomainTenantResolver extends Contracts\CachedTenantResolver } /** @var (Tenant&Model)|null $tenant */ - if ($tenant) { - $this->setCurrentDomain($tenant, $domain); - return $tenant; - } - - throw new TenantCouldNotBeIdentifiedOnDomainException($domain); + return $tenant; } public function resolved(Tenant $tenant, mixed ...$args): void @@ -50,7 +59,7 @@ class DomainTenantResolver extends Contracts\CachedTenantResolver $this->setCurrentDomain($tenant, $args[0]); } - protected function setCurrentDomain(Tenant $tenant, string $domain): void + protected static function setCurrentDomain(Tenant $tenant, string $domain): void { /** @var Tenant&Model $tenant */ if (! $tenant instanceof SingleDomainTenant) {