Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions src/Illuminate/Foundation/CacheBasedMaintenanceMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace Illuminate\Foundation;

use Illuminate\Contracts\Cache\Factory;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Contracts\Foundation\MaintenanceMode;

class CacheBasedMaintenanceMode implements MaintenanceMode
{
/**
* The cache factory.
*
* @var \Illuminate\Contracts\Cache\Factory
*/
protected $cache;

/**
* The cache store that should be utilized.
*
* @var string
*/
protected $store;

/**
* The cache key to use when storing maintenance mode information.
*
* @var string
*/
protected $key;

/**
* Create a new cache based maintenance mode implementation.
*
* @param \Illuminate\Contracts\Cache\Factory $cache
* @param string $store
* @param string $key
* @return void
*/
public function __construct(Factory $cache, string $store, string $key)
{
$this->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);
}
}
44 changes: 44 additions & 0 deletions src/Illuminate/Foundation/MaintenanceModeManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Illuminate\Foundation;

use Illuminate\Support\Manager;

class MaintenanceModeManager extends Manager
{
/**
* Create an instance of the file based maintenance driver.
*
* @return \Illuminate\Foundation\FileBasedMaintenanceMode
*/
protected function createFileDriver(): FileBasedMaintenanceMode
{
return new FileBasedMaintenanceMode();
}

/**
* Create an instance of the cache based maintenance driver.
*
* @return \Illuminate\Foundation\CacheBasedMaintenanceMode
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function createCacheDriver(): CacheBasedMaintenanceMode
{
return new CacheBasedMaintenanceMode(
$this->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');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
);
}
}
62 changes: 62 additions & 0 deletions tests/Foundation/FoundationCacheBasedMaintenanceModeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Illuminate\Tests\Foundation;

use Illuminate\Contracts\Cache\Factory;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Foundation\CacheBasedMaintenanceMode;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use Mockery as m;
use PHPUnit\Framework\TestCase;

class FoundationCacheBasedMaintenanceModeTest extends TestCase
{
use MockeryPHPUnitIntegration;

public function test_it_determines_whether_maintenance_mode_is_active()
{
$cache = m::mock(Factory::class, Repository::class);
$cache->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');
}
}