1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Charcoal\App\Handler; |
4
|
|
|
|
5
|
|
|
// Dependencies from PSR-7 (HTTP Messaging) |
6
|
|
|
use Psr\Http\Message\ServerRequestInterface; |
7
|
|
|
use Psr\Http\Message\ResponseInterface; |
8
|
|
|
|
9
|
|
|
// Local Dependencies |
10
|
|
|
use Charcoal\App\Handler\AbstractHandler; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Shutdown Handler |
14
|
|
|
* |
15
|
|
|
* It outputs a simple message in either JSON, XML, or HTML based on the Accept header. |
16
|
|
|
* |
17
|
|
|
* A maintenance mode check is included in the default middleware stack for your application. |
18
|
|
|
* This is a practical feature to "disable" your application while performing an update |
19
|
|
|
* or maintenance. |
20
|
|
|
*/ |
21
|
|
|
class Shutdown extends AbstractHandler |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* HTTP methods allowed by the current request. |
25
|
|
|
* |
26
|
|
|
* @var string $methods |
27
|
|
|
*/ |
28
|
|
|
protected $methods; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Invoke "Maintenance" Handler |
32
|
|
|
* |
33
|
|
|
* @param ServerRequestInterface $request The most recent Request object. |
34
|
|
|
* @param ResponseInterface $response The most recent Response object. |
35
|
|
|
* @param string[] $methods Allowed HTTP methods. |
36
|
|
|
* @return ResponseInterface |
37
|
|
|
*/ |
38
|
|
|
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $methods) |
39
|
|
|
{ |
40
|
|
|
$this->setMethods($methods); |
41
|
|
|
|
42
|
|
|
if ($request->getMethod() === 'OPTIONS') { |
43
|
|
|
$contentType = 'text/plain'; |
44
|
|
|
$output = $this->renderPlainOutput(); |
45
|
|
View Code Duplication |
} else { |
|
|
|
|
46
|
|
|
$contentType = $this->determineContentType($request); |
47
|
|
|
switch ($contentType) { |
48
|
|
|
case 'application/json': |
49
|
|
|
$output = $this->renderJsonOutput(); |
50
|
|
|
break; |
51
|
|
|
|
52
|
|
|
case 'text/xml': |
53
|
|
|
case 'application/xml': |
54
|
|
|
$output = $this->renderXmlOutput(); |
55
|
|
|
break; |
56
|
|
|
|
57
|
|
|
case 'text/html': |
58
|
|
|
default: |
59
|
|
|
$output = $this->renderHtmlOutput(); |
60
|
|
|
break; |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
$response->getBody()->write($output); |
65
|
|
|
|
66
|
|
|
return $response |
67
|
|
|
->withStatus(503) |
68
|
|
|
->withHeader('Content-type', $contentType); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Set the HTTP methods allowed by the current request. |
73
|
|
|
* |
74
|
|
|
* @param array $methods Case-sensitive array of methods. |
75
|
|
|
* @return Shutdown Chainable |
76
|
|
|
*/ |
77
|
|
|
protected function setMethods(array $methods) |
78
|
|
|
{ |
79
|
|
|
$this->methods = implode(', ', $methods); |
80
|
|
|
|
81
|
|
|
return $this; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Retrieves the HTTP methods allowed by the current request. |
86
|
|
|
* |
87
|
|
|
* @return string Returns the allowed request methods. |
88
|
|
|
*/ |
89
|
|
|
public function methods() |
90
|
|
|
{ |
91
|
|
|
return $this->methods; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Render Plain/Text Error |
96
|
|
|
* |
97
|
|
|
* @return string |
98
|
|
|
*/ |
99
|
|
|
protected function renderPlainOutput() |
100
|
|
|
{ |
101
|
|
|
$message = $this->translator()->translate('Down for maintenance!'); |
102
|
|
|
|
103
|
|
|
return $this->render($message); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Render JSON Error |
108
|
|
|
* |
109
|
|
|
* @return string |
110
|
|
|
*/ |
111
|
|
|
protected function renderJsonOutput() |
112
|
|
|
{ |
113
|
|
|
$message = $this->translator()->translate('We are currently unavailable. Check back in 15 minutes.'); |
114
|
|
|
|
115
|
|
|
return $this->render('{"message":"'.$message.'"}'); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Render XML Error |
120
|
|
|
* |
121
|
|
|
* @return string |
122
|
|
|
*/ |
123
|
|
|
protected function renderXmlOutput() |
124
|
|
|
{ |
125
|
|
|
$message = $this->translator()->translate('We are currently unavailable. Check back in 15 minutes.'); |
126
|
|
|
|
127
|
|
|
return $this->render('<root><message>'.$message.'</message></root>'); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Render title of error |
132
|
|
|
* |
133
|
|
|
* @return string |
134
|
|
|
*/ |
135
|
|
|
public function messageTitle() |
136
|
|
|
{ |
137
|
|
|
return $this->translator()->translate('Down for maintenance!'); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Render body of HTML error |
142
|
|
|
* |
143
|
|
|
* @return string |
144
|
|
|
*/ |
145
|
|
|
public function renderHtmlMessage() |
146
|
|
|
{ |
147
|
|
|
$title = $this->messageTitle(); |
148
|
|
|
$notice = $this->translator()->translate('currently-unavailable'); |
149
|
|
|
$message = '<h1>'.$title."</h1>\n\t\t<p>".$notice."</p>\n"; |
150
|
|
|
|
151
|
|
|
return $message; |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.