diff --git a/src/Contracts/TenantProvider.php b/src/Contracts/TenantProvider.php index 441d554..e975712 100644 --- a/src/Contracts/TenantProvider.php +++ b/src/Contracts/TenantProvider.php @@ -55,4 +55,25 @@ public function retrieveByIdentifier(string $identifier): ?Tenant; * @phpstan-return TenantClass|null */ public function retrieveByKey(int|string $key): ?Tenant; + + /** + * Retrieve a tenant by its resource key + * + * Gets an instance of the tenant implementation the provider represents, + * using a resource key. + * The tenant class must implement the {@see \Sprout\Contracts\TenantHasResources} + * interface for this method to work. + * + * @param string $resourceKey + * + * @return (\Sprout\Contracts\Tenant&\Sprout\Contracts\TenantHasResources)|null + * + * @throws \Sprout\Exceptions\MisconfigurationException + * + * @phpstan-return (TenantClass&\Sprout\Contracts\TenantHasResources)|null + * + * @see \Sprout\Contracts\Tenant::getTenantKeyName() + * @see \Sprout\Contracts\Tenant::getTenantKey() + */ + public function retrieveByResourceKey(string $resourceKey): (Tenant&TenantHasResources)|null; } diff --git a/src/Providers/DatabaseTenantProvider.php b/src/Providers/DatabaseTenantProvider.php index 5e9f46a..e294313 100644 --- a/src/Providers/DatabaseTenantProvider.php +++ b/src/Providers/DatabaseTenantProvider.php @@ -5,7 +5,8 @@ use Illuminate\Database\ConnectionInterface; use Sprout\Contracts\Tenant; -use Sprout\Contracts\TenantProvider; +use Sprout\Contracts\TenantHasResources; +use Sprout\Exceptions\MisconfigurationException; use Sprout\Support\BaseTenantProvider; use Sprout\Support\GenericTenant; @@ -131,7 +132,7 @@ private function makeEntity(array|object $attributes): object * @see \Sprout\Contracts\Tenant::getTenantIdentifier() * @see \Sprout\Contracts\Tenant::getTenantIdentifierName() * - * @phpstan-return Tenant|null + * @phpstan-return EntityClass|null */ public function retrieveByIdentifier(string $identifier): ?Tenant { @@ -160,7 +161,7 @@ public function retrieveByIdentifier(string $identifier): ?Tenant * @see \Sprout\Contracts\Tenant::getTenantKey() * @see \Sprout\Contracts\Tenant::getTenantKeyName() * - * @phpstan-return Tenant|null + * @phpstan-return EntityClass|null */ public function retrieveByKey(int|string $key): ?Tenant { @@ -175,4 +176,42 @@ public function retrieveByKey(int|string $key): ?Tenant return null; } + + /** + * Retrieve a tenant by its resource key + * + * Gets an instance of the tenant implementation the provider represents, + * using a resource key. + * The tenant class must implement the {@see \Sprout\Contracts\TenantHasResources} + * interface for this method to work. + * + * @param string $resourceKey + * + * @return (\Sprout\Contracts\Tenant&\Sprout\Contracts\TenantHasResources)|null + * + * @throws \Sprout\Exceptions\MisconfigurationException + * + * @phpstan-return (EntityClass&\Sprout\Contracts\TenantHasResources)|null + * + * @see \Sprout\Contracts\TenantHasResources::getTenantResourceKeyName() + * @see \Sprout\Contracts\TenantHasResources::getTenantResourceKey() + */ + public function retrieveByResourceKey(string $resourceKey): (Tenant&TenantHasResources)|null + { + $entity = $this->getEntity(); + + if (! ($entity instanceof TenantHasResources)) { + throw MisconfigurationException::misconfigured('tenant', $entity::class, 'resources'); + } + + $attributes = $this->connection->table($this->table) + ->where($entity->getTenantResourceKeyName(), '=', $resourceKey) + ->first(); + + if ($attributes !== null) { + return $this->makeEntity($attributes); // @phpstan-ignore-line + } + + return null; + } } diff --git a/src/Providers/EloquentTenantProvider.php b/src/Providers/EloquentTenantProvider.php index a356e24..597f312 100644 --- a/src/Providers/EloquentTenantProvider.php +++ b/src/Providers/EloquentTenantProvider.php @@ -5,7 +5,8 @@ use Illuminate\Database\Eloquent\Model; use Sprout\Contracts\Tenant; -use Sprout\Contracts\TenantProvider; +use Sprout\Contracts\TenantHasResources; +use Sprout\Exceptions\MisconfigurationException; use Sprout\Support\BaseTenantProvider; /** @@ -133,4 +134,36 @@ public function retrieveByKey(int|string $key): ?Tenant ->where($model->getTenantKeyName(), $key) ->first(); } + + /** + * Retrieve a tenant by its resource key + * + * Gets an instance of the tenant implementation the provider represents, + * using a resource key. + * The tenant class must implement the {@see \Sprout\Contracts\TenantHasResources} + * interface for this method to work. + * + * @param string $resourceKey + * + * @return (\Sprout\Contracts\Tenant&\Sprout\Contracts\TenantHasResources)|null + * + * @throws \Sprout\Exceptions\MisconfigurationException + * + * @phpstan-return (TenantModel&\Sprout\Contracts\TenantHasResources)|null + * + * @see \Sprout\Contracts\TenantHasResources::getTenantResourceKeyName() + * @see \Sprout\Contracts\TenantHasResources::getTenantResourceKey() + */ + public function retrieveByResourceKey(string $resourceKey): (Tenant&TenantHasResources)|null + { + $model = $this->getModel(); + + if (! ($model instanceof TenantHasResources)) { + throw MisconfigurationException::misconfigured('tenant', $model::class, 'resources'); + } + + return $model->newModelQuery() + ->where($model->getTenantResourceKeyName(), $resourceKey) + ->first(); + } }