Completed
Branch middleware (801be0)
by Julián
03:06
created

Render::getMaintenanceMessage()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
/**
3
 * Effortless maintenance management (http://juliangut.com/janitor)
4
 *
5
 * @link https://github.com/juliangut/janitor for the canonical source repository
6
 *
7
 * @license https://github.com/juliangut/janitor/blob/master/LICENSE
8
 */
9
10
namespace Janitor\Handler;
11
12
use Janitor\Handler as HandlerInterface;
13
use Janitor\Watcher;
14
use Janitor\ScheduledWatcher;
15
use Psr\Http\Message\ServerRequestInterface;
16
use Psr\Http\Message\ResponseInterface;
17
use Zend\Diactoros\Stream;
18
19
/**
20
 * Render HTML page maintenance handler.
21
 */
22
class Render implements HandlerInterface
23
{
24
    /**
25
     * Known handled content types.
26
     *
27
     * @var array
28
     */
29
    protected $knownContentTypes = [
30
        'application/json',
31
        'application/xml',
32
        'text/xml',
33
        'text/html',
34
    ];
35
36
    /**
37
     * {@inheritdoc}
38
     */
39
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, Watcher $watcher)
40
    {
41
        $contentType = $this->determineContentType($request);
42
        switch ($contentType) {
43
            case 'application/json':
44
                $content = $this->renderJson($watcher);
45
                break;
46
            case 'text/xml':
47
            case 'application/xml':
48
                $content = $this->renderXml($watcher);
49
                break;
50
            case 'text/html':
51
                $content = $this->renderHtml($watcher);
52
                break;
53
        }
54
55
        $body = new Stream('php://temp', 'r+');
56
        $body->write($content);
0 ignored issues
show
Bug introduced by
The variable $content does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
57
58
        if ($watcher instanceof ScheduledWatcher) {
59
            $response = $response->withHeader('Expires', $watcher->getEnd()->format('D, d M Y H:i:s e'));
60
        } else {
61
            $response = $response->withHeader('Cache-Control', 'max-age=0')
62
                ->withHeader('Cache-Control', 'no-cache, must-revalidate')
63
                ->withHeader('Pragma', 'no-cache');
64
        }
65
66
        return $response->withStatus(503)
67
            ->withHeader('Content-Type', $contentType)
68
            ->withBody($body);
69
    }
70
71
    /**
72
     * Render HTML maintenance message.
73
     *
74
     * @param \Janitor\Watcher $watcher
75
     *
76
     * @return string
77
     */
78
    protected function renderHtml(Watcher $watcher)
79
    {
80
        $title = 'Maintenance';
81
        $message = $this->getMaintenanceMessage($watcher);
82
83
        return sprintf(
84
            "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>" .
85
            "<title>%s</title><style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana," .
86
            "sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{" .
87
            "display:inline-block;width:65px;}</style></head><body><h1>%s</h1>%s</body></html>",
88
            $title,
89
            $title,
90
            $message
91
        );
92
    }
93
94
    /**
95
     * Render JSON maintenance message.
96
     *
97
     * @param \Janitor\Watcher $watcher
98
     *
99
     * @return string
100
     */
101
    protected function renderJson(Watcher $watcher)
102
    {
103
        return json_encode(['message' => $this->getMaintenanceMessage($watcher)], JSON_PRETTY_PRINT);
104
    }
105
106
    /**
107
     * Render XML maintenance message.
108
     *
109
     * @param \Janitor\Watcher $watcher
110
     *
111
     * @return string
112
     */
113
    protected function renderXml(Watcher $watcher)
114
    {
115
        return sprintf(
116
            "<maintenance>\n  <message>%s</message>\n</maintenance>",
117
            $this->getMaintenanceMessage($watcher)
118
        );
119
    }
120
121
    /**
122
     * Retrieve custom maintenance message.
123
     *
124
     * @param \Janitor\Watcher $watcher
125
     *
126
     * @return string
127
     */
128
    protected function getMaintenanceMessage(Watcher $watcher)
129
    {
130
        $message = 'Maintenance mode is not active!';
131
        if ($watcher->isActive()) {
132
            $message = $watcher instanceof ScheduledWatcher
133
                ? 'Undergoing maintenance tasks until ' . $watcher->getEnd()->format('Y/m/d H:i:s')
134
                : 'Undergoing maintenance tasks';
135
        }
136
137
        return $message;
138
    }
139
140
    /**
141
     * Determine content type using Accept header.
142
     *
143
     * @param \Psr\Http\Message\ServerRequestInterface $request
144
     *
145
     * @return string
146
     */
147
    private function determineContentType(ServerRequestInterface $request)
148
    {
149
        $acceptHeader = $request->getHeaderLine('Accept');
150
        $selectedContentTypes = array_intersect(explode(',', $acceptHeader), $this->knownContentTypes);
151
        if (count($selectedContentTypes)) {
152
            return $selectedContentTypes[0];
153
        }
154
        return 'text/html';
155
    }
156
}
157