DownCommand.php
TLDR
The DownCommand.php
file is part of the Illuminate\Foundation\Console
namespace in the Demo Projects
project. This file contains the DownCommand
class that is responsible for putting the application into maintenance or demo mode. It provides methods for executing the console command, getting the payload to be placed in the "down" file, getting the paths that should be excluded from maintenance mode, getting the path that users should be redirected to, prerendering a specified view, getting the number of seconds the client should wait before retrying their request, and getting the secret phrase that may be used to bypass maintenance mode.
Methods
handle
The handle
method executes the console command. It checks if the application is already in maintenance mode and activates the maintenance mode if it is not. It writes the maintenance file payload to the storage directory, dispatches the MaintenanceModeEnabled
event, and displays relevant information about the maintenance mode.
getDownFilePayload
The getDownFilePayload
method returns an array of data that will be placed in the "down" file. It includes the paths that should be excluded from maintenance mode, the redirect path for users, the retry time, the refresh time, the secret phrase, the status code, and the prerendered template view.
excludedPaths
The excludedPaths
method retrieves the paths that should be excluded from maintenance mode. It uses the PreventRequestsDuringMaintenance
middleware to get the excluded paths.
redirectPath
The redirectPath
method retrieves the path that users should be redirected to during maintenance mode. It checks if the --redirect
option is provided and trims it if necessary.
prerenderView
The prerenderView
method prerenders a specified view so that it can be rendered even before loading Composer. It registers the error view paths and renders the view with the specified options.
getRetryTime
The getRetryTime
method retrieves the number of seconds the client should wait before retrying their request. It checks the --retry
option and returns the value if it is a positive integer.
getSecret
The getSecret
method retrieves the secret phrase that may be used to bypass maintenance mode. It checks various conditions and returns the appropriate value.
Classes
No classes in this file.
<?php
namespace Illuminate\Foundation\Console;
use App\Http\Middleware\PreventRequestsDuringMaintenance;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Foundation\Events\MaintenanceModeEnabled;
use Illuminate\Foundation\Exceptions\RegisterErrorViewPaths;
use Illuminate\Support\Str;
use Symfony\Component\Console\Attribute\AsCommand;
use Throwable;
#[AsCommand(name: 'down')]
class DownCommand extends Command
{
/**
* The console command signature.
*
* @var string
*/
protected $signature = 'down {--redirect= : The path that users should be redirected to}
{--render= : The view that should be prerendered for display during maintenance mode}
{--retry= : The number of seconds after which the request may be retried}
{--refresh= : The number of seconds after which the browser may refresh}
{--secret= : The secret phrase that may be used to bypass maintenance mode}
{--with-secret : Generate a random secret phrase that may be used to bypass maintenance mode}
{--status=503 : The status code that should be used when returning the maintenance mode response}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Put the application into maintenance / demo mode';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
try {
if ($this->laravel->maintenanceMode()->active()) {
$this->components->info('Application is already down.');
return 0;
}
$downFilePayload = $this->getDownFilePayload();
$this->laravel->maintenanceMode()->activate($downFilePayload);
file_put_contents(
storage_path('framework/maintenance.php'),
file_get_contents(__DIR__.'/stubs/maintenance-mode.stub')
);
$this->laravel->get('events')->dispatch(new MaintenanceModeEnabled());
$this->components->info('Application is now in maintenance mode.');
if ($downFilePayload['secret'] !== null) {
$this->components->info('You may bypass maintenance mode via ['.config('app.url')."/{$downFilePayload['secret']}].");
}
} catch (Exception $e) {
$this->components->error(sprintf(
'Failed to enter maintenance mode: %s.',
$e->getMessage(),
));
return 1;
}
}
/**
* Get the payload to be placed in the "down" file.
*
* @return array
*/
protected function getDownFilePayload()
{
return [
'except' => $this->excludedPaths(),
'redirect' => $this->redirectPath(),
'retry' => $this->getRetryTime(),
'refresh' => $this->option('refresh'),
'secret' => $this->getSecret(),
'status' => (int) $this->option('status', 503),
'template' => $this->option('render') ? $this->prerenderView() : null,
];
}
/**
* Get the paths that should be excluded from maintenance mode.
*
* @return array
*/
protected function excludedPaths()
{
try {
return $this->laravel->make(PreventRequestsDuringMaintenance::class)->getExcludedPaths();
} catch (Throwable) {
return [];
}
}
/**
* Get the path that users should be redirected to.
*
* @return string
*/
protected function redirectPath()
{
if ($this->option('redirect') && $this->option('redirect') !== '/') {
return '/'.trim($this->option('redirect'), '/');
}
return $this->option('redirect');
}
/**
* Prerender the specified view so that it can be rendered even before loading Composer.
*
* @return string
*/
protected function prerenderView()
{
(new RegisterErrorViewPaths)();
return view($this->option('render'), [
'retryAfter' => $this->option('retry'),
])->render();
}
/**
* Get the number of seconds the client should wait before retrying their request.
*
* @return int|null
*/
protected function getRetryTime()
{
$retry = $this->option('retry');
return is_numeric($retry) && $retry > 0 ? (int) $retry : null;
}
/**
* Get the secret phrase that may be used to bypass maintenance mode.
*
* @return string|null
*/
protected function getSecret()
{
return match (true) {
! is_null($this->option('secret')) => $this->option('secret'),
$this->option('with-secret') => Str::random(),
default => null,
};
}
}