Skip to content

Commit

Permalink
feat: Add initial resolution stage support in using resolution hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
ollieread committed Nov 6, 2024
1 parent 0950104 commit bf0b18a
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 20 deletions.
18 changes: 10 additions & 8 deletions resources/config/sprout.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@

/*
|--------------------------------------------------------------------------
| Should Sprout listen for routing?
| Enabled hooks
|--------------------------------------------------------------------------
|
| This value decides whether Sprout listens for the RouteMatched event to
| identify tenants.
|
| Setting it to false will disable the pre-middleware identification,
| which in turn will make tenant-aware dependency injection no longer
| functionality.
| This value contains an array of resolution hooks that should be enabled.
| The handling of each hook is different, but if a hook is missing from
| here, some things, such as listeners, may not be registered.
|
*/

'listen_for_routing' => true,
'hooks' => [
// \Sprout\Support\ResolutionHook::Bootstrapping,
// \Sprout\Support\ResolutionHook::Booting,
\Sprout\Support\ResolutionHook::Routing,
\Sprout\Support\ResolutionHook::Middleware,
],

/*
|--------------------------------------------------------------------------
Expand Down
14 changes: 14 additions & 0 deletions src/Exceptions/MisconfigurationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

namespace Sprout\Exceptions;

use Sprout\Support\ResolutionHook;

/**
* Misconfiguration Exception
*
Expand Down Expand Up @@ -81,4 +83,16 @@ public static function noDefault(string $type): self
{
return new self('There is no default ' . $type . ' set');
}

/**
* Create a new exception for when a resolution hook is not supported
*
* @param \Sprout\Support\ResolutionHook $hook
*
* @return self
*/
public static function unsupportedHook(ResolutionHook $hook): self
{
return new self('The resolution hook [' . $hook->name . '] is not supported');
}
}
36 changes: 28 additions & 8 deletions src/Http/Middleware/TenantRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Sprout\Sprout;
use Sprout\Support\ResolutionHelper;
use Sprout\Support\ResolutionHook;

Expand All @@ -25,6 +26,21 @@ final class TenantRoutes
*/
public const ALIAS = 'sprout.tenanted';

/**
* @var \Sprout\Sprout
*/
private Sprout $sprout;

/**
* Create a new instance of the middleware
*
* @param \Sprout\Sprout $sprout
*/
public function __construct(Sprout $sprout)
{
$this->sprout = $sprout;
}

/**
* Handle the request
*
Expand All @@ -35,17 +51,21 @@ final class TenantRoutes
* @return \Illuminate\Http\Response
*
* @throws \Sprout\Exceptions\NoTenantFound
* @throws \Illuminate\Contracts\Container\BindingResolutionException
* @throws \Sprout\Exceptions\MisconfigurationException
*/
public function handle(Request $request, Closure $next, string ...$options): Response
{
[$resolverName, $tenancyName] = ResolutionHelper::parseOptions($options);

ResolutionHelper::handleResolution(
$request,
ResolutionHook::Middleware,
$resolverName,
$tenancyName,
);
if ($this->sprout->supportsHook(ResolutionHook::Middleware)) {
[$resolverName, $tenancyName] = ResolutionHelper::parseOptions($options);

ResolutionHelper::handleResolution(
$request,
ResolutionHook::Middleware,
$resolverName,
$tenancyName,
);
}

return $next($request);
}
Expand Down
18 changes: 18 additions & 0 deletions src/Sprout.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Sprout\Managers\IdentityResolverManager;
use Sprout\Managers\ProviderManager;
use Sprout\Managers\TenancyManager;
use Sprout\Support\ResolutionHook;

/**
* Sprout
Expand Down Expand Up @@ -192,4 +193,21 @@ public function getOverrides(): array
{
return $this->overrides;
}

/**
* Check if a resolution hook is enabled
*
* @param \Sprout\Support\ResolutionHook $hook
*
* @return bool
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function supportsHook(ResolutionHook $hook): bool
{
/** @var array<ResolutionHook> $enabledHooks */
$enabledHooks = $this->config('hooks', []);

return in_array($hook, $enabledHooks, true);
}
}
3 changes: 2 additions & 1 deletion src/SproutServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Sprout\Managers\IdentityResolverManager;
use Sprout\Managers\ProviderManager;
use Sprout\Managers\TenancyManager;
use Sprout\Support\ResolutionHook;

/**
* Sprout Service Provider
Expand Down Expand Up @@ -120,7 +121,7 @@ private function registerEventListeners(): void
$events = $this->app->make(Dispatcher::class);

// If we should be listening for routing
if ($this->sprout->shouldListenForRouting()) {
if ($this->sprout->supportsHook(ResolutionHook::Routing)) {
$events->listen(RouteMatched::class, IdentifyTenantOnRouting::class);
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/Support/ResolutionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

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

Expand Down Expand Up @@ -38,12 +39,20 @@ public static function parseOptions(array $options): array
*
* @return bool
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
* @throws \Sprout\Exceptions\MisconfigurationException
* @throws \Sprout\Exceptions\NoTenantFound
*/
public static function handleResolution(Request $request, ResolutionHook $hook, ?string $resolverName = null, ?string $tenancyName = null, bool $throw = true): bool
{
/** @var \Sprout\Sprout $sprout */
$sprout = app(Sprout::class);
$sprout = app(Sprout::class);

// If the resolution hook is disabled, throw an exception
if (! $sprout->supportsHook($hook)) {
throw MisconfigurationException::unsupportedHook($hook);
}

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

Expand Down
5 changes: 3 additions & 2 deletions tests/SproutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
use Sprout\Sprout;
use Sprout\Support\ResolutionHook;
use Workbench\App\Models\TenantModel;

#[Group('core')]
Expand Down Expand Up @@ -49,13 +50,13 @@ public function hasHelperForListeningToRoutingEvents(): void

$this->assertFalse($sprout->config('listen_for_routing'));
$this->assertFalse(config('sprout.listen_for_routing'));
$this->assertFalse($sprout->shouldListenForRouting());
$this->assertFalse($sprout->supportsHook(ResolutionHook::Routing));

app()['config']->set('sprout.listen_for_routing', true);

$this->assertTrue($sprout->config('listen_for_routing'));
$this->assertTrue(config('sprout.listen_for_routing'));
$this->assertTrue($sprout->shouldListenForRouting());
$this->assertTrue($sprout->supportsHook(ResolutionHook::Routing));
}

#[Test]
Expand Down

0 comments on commit bf0b18a

Please sign in to comment.