From 2cc90d2c05a6ceb730fc5e6fb5df471f509436b7 Mon Sep 17 00:00:00 2001 From: Ollie Read Date: Mon, 16 Dec 2024 11:49:54 +0000 Subject: [PATCH] feat: Add core Sprout settings repository (#79) * chore: Add core Sprout settings repository * refactor: Replace cookie value overrides with usage of settings repository * refactor: Implement settings repository for overrides * refactor: Add helper methods for settings * fix: Fix database override setting --- src/Concerns/OverridesCookieSettings.php | 71 ------------------- src/Http/Resolvers/PathIdentityResolver.php | 5 +- .../Resolvers/SubdomainIdentityResolver.php | 5 +- src/Overrides/CookieOverride.php | 12 ++-- src/Overrides/SessionOverride.php | 53 +++++++------- src/Sprout.php | 37 +++++++++- src/SproutServiceProvider.php | 6 +- src/Support/Settings.php | 21 ++++++ src/Support/SettingsRepository.php | 71 +++++++++++++++++++ src/helpers.php | 13 +++- 10 files changed, 183 insertions(+), 111 deletions(-) delete mode 100644 src/Concerns/OverridesCookieSettings.php create mode 100644 src/Support/Settings.php create mode 100644 src/Support/SettingsRepository.php diff --git a/src/Concerns/OverridesCookieSettings.php b/src/Concerns/OverridesCookieSettings.php deleted file mode 100644 index 3ff4e86..0000000 --- a/src/Concerns/OverridesCookieSettings.php +++ /dev/null @@ -1,71 +0,0 @@ -parameterSetup($tenancy, $tenant); if ($tenant !== null) { - CookieOverride::setPath($this->getTenantRoutePrefix($tenancy)); - SessionOverride::setPath($this->getTenantRoutePrefix($tenancy)); + settings()->setUrlPath($this->getTenantRoutePrefix($tenancy)); } } } diff --git a/src/Http/Resolvers/SubdomainIdentityResolver.php b/src/Http/Resolvers/SubdomainIdentityResolver.php index 07b46ca..d01e79a 100644 --- a/src/Http/Resolvers/SubdomainIdentityResolver.php +++ b/src/Http/Resolvers/SubdomainIdentityResolver.php @@ -16,6 +16,8 @@ use Sprout\Overrides\CookieOverride; use Sprout\Overrides\SessionOverride; use Sprout\Support\BaseIdentityResolver; +use Sprout\Support\Settings; +use function Sprout\settings; /** * The Subdomain Identity Resolver @@ -172,8 +174,7 @@ public function setup(Tenancy $tenancy, ?Tenant $tenant): void $this->parameterSetup($tenancy, $tenant); if ($tenant !== null) { - CookieOverride::setDomain($this->getTenantRouteDomain($tenancy)); - SessionOverride::setDomain($this->getTenantRouteDomain($tenancy)); + settings()->setUrlDomain($this->getTenantRouteDomain($tenancy)); } } } diff --git a/src/Overrides/CookieOverride.php b/src/Overrides/CookieOverride.php index 798da88..f6c11c1 100644 --- a/src/Overrides/CookieOverride.php +++ b/src/Overrides/CookieOverride.php @@ -4,11 +4,11 @@ namespace Sprout\Overrides; use Illuminate\Cookie\CookieJar; -use Sprout\Concerns\OverridesCookieSettings; use Sprout\Contracts\DeferrableServiceOverride; use Sprout\Contracts\ServiceOverride; use Sprout\Contracts\Tenancy; use Sprout\Contracts\Tenant; +use function Sprout\settings; /** * Cookie Override @@ -20,8 +20,6 @@ */ final class CookieOverride implements ServiceOverride, DeferrableServiceOverride { - use OverridesCookieSettings; - /** * Get the service to watch for before overriding * @@ -47,10 +45,10 @@ public static function service(): string public function setup(Tenancy $tenancy, Tenant $tenant): void { // Collect the values - $path = self::$settings['path'] ?? config('session.path') ?? '/'; - $domain = self::$settings['domain'] ?? config('session.domain'); - $secure = self::$settings['secure'] ?? config('session.secure', false); - $sameSite = self::$settings['same_site'] ?? config('session.same_site'); + $path = settings()->getUrlPath(config('session.path') ?? '/'); // @phpstan-ignore-line + $domain = settings()->getUrlDomain(config('session.domain')); // @phpstan-ignore-line + $secure = settings()->shouldCookieBeSecure(config('session.secure', false)); // @phpstan-ignore-line + $sameSite = settings()->shouldCookeBeSameSite(config('session.same_site')); // @phpstan-ignore-line /** * This is here to make PHPStan quiet down diff --git a/src/Overrides/SessionOverride.php b/src/Overrides/SessionOverride.php index 8c250ca..8d2b5ff 100644 --- a/src/Overrides/SessionOverride.php +++ b/src/Overrides/SessionOverride.php @@ -8,7 +8,7 @@ use Illuminate\Session\DatabaseSessionHandler as OriginalDatabaseSessionHandler; use Illuminate\Session\FileSessionHandler; use Illuminate\Session\SessionManager; -use Sprout\Concerns\OverridesCookieSettings; +use Illuminate\Support\Arr; use Sprout\Contracts\BootableServiceOverride; use Sprout\Contracts\DeferrableServiceOverride; use Sprout\Contracts\Tenancy; @@ -19,6 +19,8 @@ use Sprout\Exceptions\TenantMissing; use Sprout\Overrides\Session\TenantAwareDatabaseSessionHandler; use Sprout\Sprout; +use Sprout\Support\Settings; +use function Sprout\settings; use function Sprout\sprout; /** @@ -31,23 +33,6 @@ */ final class SessionOverride implements BootableServiceOverride, DeferrableServiceOverride { - use OverridesCookieSettings; - - /** - * @var bool - */ - private static bool $overrideDatabase = true; - - /** - * Prevent this override from overriding the database driver - * - * @return void - */ - public static function doNotOverrideDatabase(): void - { - self::$overrideDatabase = false; - } - /** * Get the service to watch for before overriding * @@ -80,7 +65,7 @@ public function boot(Application $app, Sprout $sprout): void $sessionManager->extend('file', $fileCreator); $sessionManager->extend('native', $fileCreator); - if (self::$overrideDatabase) { + if (settings()->shouldNotOverrideTheDatabase(false) === false) { $sessionManager->extend('database', self::createDatabaseDriver()); } } @@ -99,13 +84,33 @@ public function boot(Application $app, Sprout $sprout): void */ public function setup(Tenancy $tenancy, Tenant $tenant): void { - $settings = self::$settings; - /** @var \Illuminate\Contracts\Config\Repository $config */ - $config = config(); + $config = config(); + $settings = settings(); + + if (! $settings->has('original.session')) { + /** @var array $original */ + $original = $config->get('session'); + $settings->set( + 'original.session', + Arr::only($original, ['path', 'domain', 'secure', 'same_site']) + ); + } + + if ($settings->has(Settings::URL_PATH)) { + $config->set('session.path', $settings->getUrlPath()); + } + + if ($settings->has(Settings::URL_DOMAIN)) { + $config->set('session.domain', $settings->getUrlDomain()); + } + + if ($settings->has(Settings::COOKIE_SECURE)) { + $config->set('session.secure', $settings->shouldCookieBeSecure()); + } - foreach ($settings as $setting => $value) { - $config->set('session.' . $setting, $value); + if ($settings->has(Settings::COOKIE_SAME_SITE)) { + $config->set('session.same_site', $settings->shouldCookeBeSameSite()); } $config->set('session.cookie', $this->getCookieName($tenancy, $tenant)); diff --git a/src/Sprout.php b/src/Sprout.php index 2d85ec8..1f69efb 100644 --- a/src/Sprout.php +++ b/src/Sprout.php @@ -11,6 +11,7 @@ use Sprout\Managers\ProviderManager; use Sprout\Managers\TenancyManager; use Sprout\Support\ResolutionHook; +use Sprout\Support\SettingsRepository; /** * Sprout @@ -38,14 +39,21 @@ final class Sprout */ private bool $withinContext = false; + /** + * @var \Sprout\Support\SettingsRepository + */ + private SettingsRepository $settings; + /** * Create a new instance * * @param \Illuminate\Contracts\Foundation\Application $app + * @param \Sprout\Support\SettingsRepository $settings */ - public function __construct(Application $app) + public function __construct(Application $app, SettingsRepository $settings) { - $this->app = $app; + $this->app = $app; + $this->settings = $settings; } /** @@ -63,6 +71,29 @@ public function config(string $key, mixed $default = null): mixed return $this->app->make('config')->get('sprout.' . $key, $default); } + /** + * Get a config item from the sprout config + * + * @param string $key + * @param mixed|null $default + * + * @return mixed + */ + public function setting(string $key, mixed $default = null): mixed + { + return $this->settings->get($key, $default); + } + + /** + * Get the Sprout settings repository + * + * @return \Sprout\Support\SettingsRepository + */ + public function settings(): SettingsRepository + { + return $this->settings; + } + /** * Set the current tenancy * @@ -222,7 +253,7 @@ public function withinContext(): bool * * If no tenancy name is provided, this method will use the current tenancy * or the default one. - * + * * If no resolver name is provided, this method will use the resolver * currently linked with the tenancy, or the default one. * diff --git a/src/SproutServiceProvider.php b/src/SproutServiceProvider.php index a3e3368..e9d61a6 100644 --- a/src/SproutServiceProvider.php +++ b/src/SproutServiceProvider.php @@ -15,6 +15,7 @@ use Sprout\Managers\ProviderManager; use Sprout\Managers\TenancyManager; use Sprout\Support\ResolutionHook; +use Sprout\Support\SettingsRepository; /** * Sprout Service Provider @@ -36,10 +37,13 @@ public function register(): void private function registerSprout(): void { - $this->sprout = new Sprout($this->app); + $this->sprout = new Sprout($this->app, new SettingsRepository()); $this->app->singleton(Sprout::class, fn () => $this->sprout); $this->app->alias(Sprout::class, 'sprout'); + + // Bind the settings repository too + $this->app->bind(SettingsRepository::class, fn () => $this->sprout->settings()); } private function registerManagers(): void diff --git a/src/Support/Settings.php b/src/Support/Settings.php new file mode 100644 index 0000000..c7dc2ea --- /dev/null +++ b/src/Support/Settings.php @@ -0,0 +1,21 @@ +set(Settings::URL_PATH, $path); + } + + public function getUrlPath(?string $default = null): ?string + { + /** @var string|null $path */ + $path = $this->get(Settings::URL_PATH, $default); + + return $path; + } + + public function setUrlDomain(?string $domain): void + { + $this->set(Settings::URL_DOMAIN, $domain); + } + + public function getUrlDomain(?string $default = null): ?string + { + /** @var string|null $domain */ + $domain = $this->get(Settings::URL_DOMAIN, $default); + + return $domain; + } + + public function setCookieSecure(bool $secure): void + { + $this->set(Settings::COOKIE_SECURE, $secure); + } + + public function shouldCookieBeSecure(?bool $default = null): bool + { + return $this->boolean(Settings::COOKIE_SECURE, $default); + } + + public function setCookieSameSite(bool $sameSite): void + { + $this->set(Settings::COOKIE_SAME_SITE, $sameSite); + } + + public function shouldCookeBeSameSite(?bool $default = null): bool + { + return $this->boolean(Settings::COOKIE_SAME_SITE, $default); + } + + public function doNotOverrideTheDatabase(): void + { + $this->set(Settings::NO_DATABASE_OVERRIDE, true); + } + + public function shouldNotOverrideTheDatabase(bool $default = null): bool + { + return $this->boolean(Settings::NO_DATABASE_OVERRIDE, $default); + } +} diff --git a/src/helpers.php b/src/helpers.php index c900d6f..941aea3 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -5,9 +5,10 @@ use Sprout\Contracts\IdentityResolver; use Sprout\Contracts\Tenancy; use Sprout\Contracts\TenantProvider; +use Sprout\Support\SettingsRepository; /** - * Get the core sprout class + * Get the core Sprout class * * @return \Sprout\Sprout */ @@ -16,6 +17,16 @@ function sprout(): Sprout return app(Sprout::class); } +/** + * Get the Sprout settings repository + * + * @return \Sprout\Support\SettingsRepository + */ +function settings(): SettingsRepository +{ + return sprout()->settings(); +} + /** * Get an identity resolver *