Skip to content

Commit

Permalink
refactor(resolvers): Abstract out resolution logic to avoid duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
ollieread committed Sep 10, 2024
1 parent 9aaacba commit 933d630
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 46 deletions.
19 changes: 8 additions & 11 deletions src/Http/Middleware/TenantRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Sprout\Managers\IdentityResolverManager;
use Sprout\Managers\TenancyManager;
use Sprout\Sprout;
use Sprout\Support\ResolutionHelper;
use Sprout\Support\ResolutionHook;

/**
* Tenant Routes Middleware
Expand Down Expand Up @@ -51,17 +53,12 @@ public function handle(Request $request, Closure $next, string ...$options): Res
$resolverName = $tenancyName = null;
}

$resolver = $this->sprout->resolvers()->get($resolverName);
$tenancy = $this->sprout->tenancies()->get($tenancyName);

/**
* @var \Sprout\Contracts\IdentityResolver $resolver
* @var \Sprout\Contracts\Tenancy<\Sprout\Contracts\Tenant> $tenancy
*/

if (! $tenancy->check()) {
throw NoTenantFound::make($resolver->getName(), $tenancy->getName());
}
ResolutionHelper::handleResolution(
$request,
ResolutionHook::Middleware,
$resolverName,
$tenancyName
);

// TODO: Decide whether to do anything with the following conditions
//if (! $tenancy->wasResolved()) {
Expand Down
44 changes: 9 additions & 35 deletions src/Listeners/IdentifyTenantOnRouting.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
use Illuminate\Routing\Route;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Sprout\Contracts\IdentityResolverUsesParameters;
use Sprout\Exceptions\NoTenantFound;
use Sprout\Http\Middleware\TenantRoutes;
use Sprout\Managers\IdentityResolverManager;
use Sprout\Managers\TenancyManager;
use Sprout\Sprout;
use Sprout\Support\ResolutionHelper;
use Sprout\Support\ResolutionHook;

final class IdentifyTenantOnRouting
{
Expand Down Expand Up @@ -55,39 +55,13 @@ public function handle(RouteMatched $event): void

[$resolverName, $tenancyName] = $options;

$resolver = $this->resolverManager->get($resolverName);
$tenancy = $this->tenancyManager->get($tenancyName);

$this->sprout->setCurrentTenancy($tenancy);

/**
* @var \Sprout\Contracts\IdentityResolver $resolver
* @var \Sprout\Contracts\Tenancy<\Sprout\Contracts\Tenant> $tenancy
*/

// Is the resolver using a parameter, and is the parameter present?
if (
$resolver instanceof IdentityResolverUsesParameters
&& $event->route->hasParameter($resolver->getRouteParameterName($tenancy))
) {
// Use the route to resolve the identity from the parameter
$identity = $resolver->resolveFromRoute($event->route, $tenancy, $event->request);
$event->route->forgetParameter($resolver->getRouteParameterName($tenancy));
} else {
// If we reach here, either the resolver doesn't use parameters, or
// the parameter isn't present in the URL, so we'll default to
// using the request
$identity = $resolver->resolveFromRequest($event->request, $tenancy);
}

// Make sure the tenancy knows which resolver resolved it
$tenancy->resolvedVia($resolver);

if ($identity === null || $tenancy->identify($identity) === false) {
throw NoTenantFound::make($resolver->getName(), $tenancy->getName());
}

return;
ResolutionHelper::handleResolution(
$event->request,
ResolutionHook::Routing,
$resolverName,
$tenancyName,
false
);
}

/**
Expand Down
73 changes: 73 additions & 0 deletions src/Support/ResolutionHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);

namespace Sprout\Support;

use Illuminate\Http\Request;
use Sprout\Contracts\IdentityResolverUsesParameters;
use Sprout\Exceptions\NoTenantFound;
use Sprout\Sprout;

class ResolutionHelper
{
/**
* @param \Illuminate\Http\Request $request
* @param \Sprout\Support\ResolutionHook $hook
* @param string|null $resolverName
* @param string|null $tenancyName
*
* @return bool
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
* @throws \Sprout\Exceptions\NoTenantFound
*/
public static function handleResolution(Request $request, ResolutionHook $hook, ?string $resolverName = null, ?string $tenancyName = null, bool $throw = true): bool
{
$sprout = app()->make(Sprout::class);
$resolver = $sprout->resolvers()->get($resolverName);
$tenancy = $sprout->tenancies()->get($tenancyName);

/**
* @var \Sprout\Contracts\IdentityResolver $resolver
* @var \Sprout\Contracts\Tenancy<\Sprout\Contracts\Tenant> $tenancy
*/

if ($tenancy->check() || ! $resolver->canResolve($request, $tenancy, $hook)) {
return false;
}

$sprout->setCurrentTenancy($tenancy);

/** @var \Illuminate\Routing\Route|null $route */
$route = $request->route();

// Is the resolver using a parameter, and is the parameter present?
if (
$resolver instanceof IdentityResolverUsesParameters
&& $route !== null
&& $route->hasParameter($resolver->getRouteParameterName($tenancy))
) {
// Use the route to resolve the identity from the parameter
$identity = $resolver->resolveFromRoute($route, $tenancy, $request);
$route->forgetParameter($resolver->getRouteParameterName($tenancy));
} else {
// If we reach here, either the resolver doesn't use parameters, or
// the parameter isn't present in the URL, so we'll default to
// using the request
$identity = $resolver->resolveFromRequest($request, $tenancy);
}

// Make sure the tenancy knows which resolver resolved it
$tenancy->resolvedVia($resolver)->resolvedAt($hook);

if ($identity === null || $tenancy->identify($identity) === false) {
if ($throw) {
throw NoTenantFound::make($resolver->getName(), $tenancy->getName());
}

return false;
}

return true;
}
}

0 comments on commit 933d630

Please sign in to comment.