diff --git a/src/Illuminate/Foundation/CacheBasedMaintenanceMode.php b/src/Illuminate/Foundation/CacheBasedMaintenanceMode.php new file mode 100644 index 000000000000..01ff30d4b6a4 --- /dev/null +++ b/src/Illuminate/Foundation/CacheBasedMaintenanceMode.php @@ -0,0 +1,97 @@ +cache = $cache; + $this->store = $store; + $this->key = $key; + } + + /** + * Take the application down for maintenance. + * + * @param array $payload + * @return void + */ + public function activate(array $payload): void + { + $this->getStore()->put($this->key, $payload); + } + + /** + * Take the application out of maintenance. + * + * @return void + */ + public function deactivate(): void + { + $this->getStore()->forget($this->key); + } + + /** + * Determine if the application is currently down for maintenance. + * + * @return bool + */ + public function active(): bool + { + return $this->getStore()->has($this->key); + } + + /** + * Get the data array which was provided when the application was placed into maintenance. + * + * @return array + */ + public function data(): array + { + return $this->getStore()->get($this->key); + } + + /** + * Get the cache store to use. + * + * @return \Illuminate\Contracts\Cache\Repository + */ + protected function getStore(): Repository + { + return $this->cache->store($this->store); + } +} diff --git a/src/Illuminate/Foundation/MaintenanceModeManager.php b/src/Illuminate/Foundation/MaintenanceModeManager.php new file mode 100644 index 000000000000..4d233f44f3e3 --- /dev/null +++ b/src/Illuminate/Foundation/MaintenanceModeManager.php @@ -0,0 +1,44 @@ +container->make('cache'), + $this->config->get('app.maintenance.store') ?: $this->config->get('cache.default'), + 'illuminate:foundation:down' + ); + } + + /** + * Get the default driver name. + * + * @return string + */ + public function getDefaultDriver(): string + { + return $this->config->get('app.maintenance.driver', 'file'); + } +} diff --git a/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php b/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php index c0b5ca1eb836..2deea7af44bf 100644 --- a/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php +++ b/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php @@ -3,7 +3,7 @@ namespace Illuminate\Foundation\Providers; use Illuminate\Contracts\Foundation\MaintenanceMode as MaintenanceModeContract; -use Illuminate\Foundation\FileBasedMaintenanceMode; +use Illuminate\Foundation\MaintenanceModeManager; use Illuminate\Http\Request; use Illuminate\Log\Events\MessageLogged; use Illuminate\Support\AggregateServiceProvider; @@ -128,6 +128,11 @@ protected function registerExceptionTracking() */ public function registerMaintenanceModeManager() { - $this->app->bind(MaintenanceModeContract::class, FileBasedMaintenanceMode::class); + $this->app->singleton(MaintenanceModeManager::class); + + $this->app->bind( + MaintenanceModeContract::class, + fn () => $this->app->make(MaintenanceModeManager::class)->driver() + ); } } diff --git a/tests/Foundation/FoundationCacheBasedMaintenanceModeTest.php b/tests/Foundation/FoundationCacheBasedMaintenanceModeTest.php new file mode 100644 index 000000000000..19d41cf0aca3 --- /dev/null +++ b/tests/Foundation/FoundationCacheBasedMaintenanceModeTest.php @@ -0,0 +1,62 @@ +shouldReceive('store')->with('store-key')->andReturnSelf(); + + $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key'); + + $cache->shouldReceive('has')->once()->with('key')->andReturnFalse(); + $this->assertFalse($manager->active()); + + $cache->shouldReceive('has')->once()->with('key')->andReturnTrue(); + $this->assertTrue($manager->active()); + } + + public function test_it_retrieves_payload_from_cache() + { + $cache = m::mock(Factory::class, Repository::class); + $cache->shouldReceive('store')->with('store-key')->andReturnSelf(); + + $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key'); + + $cache->shouldReceive('get')->once()->with('key')->andReturn(['payload']); + $this->assertSame(['payload'], $manager->data()); + } + + public function test_it_stores_payload_in_cache() + { + $cache = m::spy(Factory::class, Repository::class); + $cache->shouldReceive('store')->with('store-key')->andReturnSelf(); + + $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key'); + $manager->activate(['payload']); + + $cache->shouldHaveReceived('put')->once()->with('key', ['payload']); + } + + public function test_it_removes_payload_from_cache() + { + $cache = m::spy(Factory::class, Repository::class); + $cache->shouldReceive('store')->with('store-key')->andReturnSelf(); + + $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key'); + $manager->deactivate(); + + $cache->shouldHaveReceived('forget')->once()->with('key'); + } +}