Passed
Push — 2.x ( 83ed90...3181da )
by Terry
02:10
created

Asset::getResponseWithContentType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 10
rs 10
1
<?php
2
/**
3
 * This file is part of the Shieldon package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 * 
10
 * php version 7.1.0
11
 * 
12
 * @category  Web-security
13
 * @package   Shieldon
14
 * @author    Terry Lin <[email protected]>
15
 * @copyright 2019 terrylinooo
16
 * @license   https://github.com/terrylinooo/shieldon/blob/2.x/LICENSE MIT
17
 * @link      https://github.com/terrylinooo/shieldon
18
 * @see       https://shieldon.io
19
 */
20
21
declare(strict_types=1);
22
23
namespace Shieldon\Firewall\Panel;
24
25
use Psr\Http\Message\ResponseInterface;
26
use Shieldon\Firewall\HttpFactory;
27
use function Shieldon\Firewall\get_response;
28
29
/**
30
 * The static asset files such as CSS, JavaScript.
31
 */
32
class Asset extends BaseController
33
{
34
    /**
35
     * The directory in where the static assets of the firewall panel are placed.
36
     */
37
    const PANEL_ASSET_DIR = __DIR__ . '/../../../assets';
38
39
    /**
40
     * Constructor.
41
     */
42
    public function __construct() 
43
    {
44
        parent::__construct();
45
    }
46
47
    /**
48
     * The content output to be a CSS file.
49
     *
50
     * @return ResponseInterface
51
     */
52
    public function css(): ResponseInterface
53
    {
54
        return $this->getResponseWithContentType(
55
            'text/css; charset=UTF-8',
56
            $this->loadCss()
57
        );
58
    }
59
60
    /**
61
     * The content output to be a JavaScript file.
62
     *
63
     * @return ResponseInterface
64
     */
65
    public function js(): ResponseInterface
66
    {
67
        return $this->getResponseWithContentType(
68
            'text/javascript; charset=UTF-8',
69
            $this->loadJs()
70
        );
71
    }
72
73
    /**
74
     * The content output to be a favicon.
75
     *
76
     * @return ResponseInterface
77
     */
78
    public function favicon(): ResponseInterface
79
    {
80
        return $this->getResponseWithContentType(
81
            'image/x-icon',
82
            $this->loadFavicon()
83
        );
84
    }
85
86
    /**
87
     * The content output to be a logo image.
88
     *
89
     * @return ResponseInterface
90
     */
91
    public function logo(): ResponseInterface
92
    {
93
        return $this->getResponseWithContentType(
94
            'image/png',
95
            $this->loadLogo()
96
        );
97
    }
98
99
/**
100
     * Load CSS content.
101
     *
102
     * @return string
103
     */
104
    protected function loadJs(): string
105
    {
106
        ob_start();
107
        echo file_get_contents(self::PANEL_ASSET_DIR . '/dist/app-packed.js');
108
        $output = ob_get_contents();
109
        ob_end_clean();
110
    
111
        return $this->filterString($output);
112
    }
113
114
    /**
115
     * Load CSS content.
116
     *
117
     * @return string
118
     */
119
    protected function loadCss(): string
120
    {
121
        ob_start();
122
        echo file_get_contents(self::PANEL_ASSET_DIR . '/dist/app-packed.css');
123
        $output = ob_get_contents();
124
        ob_end_clean();
125
    
126
        return $this->filterString($output);
127
    }
128
129
    /**
130
     * Load Shieldon's favicon.
131
     *
132
     * @return string
133
     */
134
    protected function loadFavicon(): string
135
    {
136
        ob_start();
137
        echo file_get_contents(self::PANEL_ASSET_DIR . '/src/images/favicon.ico');
138
        $output = ob_get_contents();
139
        ob_end_clean();
140
141
        return $output;
142
    }
143
144
    /**
145
     * Load Shieldon's logo.
146
     *
147
     * @return string
148
     */
149
    protected function loadLogo(): string
150
    {
151
        ob_start();
152
        echo file_get_contents(self::PANEL_ASSET_DIR . '/src/images/logo.png');
153
        $output = ob_get_contents();
154
        ob_end_clean();
155
156
        return $output;
157
    }
158
159
    /**
160
     * Get server response with content.
161
     *
162
     * @param string $contentType The content type.
163
     * @param string $body        The data sring.
164
     *
165
     * @return ResponseInterface
166
     */
167
    private function getResponseWithContentType(string $contentType, string $body): ResponseInterface
168
    {
169
        $response = get_response();
170
        $response = $response->withHeader('Content-Type', $contentType);
171
        $stream = HttpFactory::createStream();
172
        $stream->write($body);
173
        $stream->rewind();
174
        $response = $response->withBody($stream);
175
176
        return $this->withCacheHeader($response);
177
    }
178
179
    /**
180
     * Return the header with cache parameters.
181
     *
182
     * @param ResponseInterface $response The PSR-7 server response.
183
     *
184
     * @return ResponseInterface
185
     */
186
    private function withCacheHeader(ResponseInterface $response): ResponseInterface
187
    {
188
        $seconds = 86400; // 24 hours
189
        $response = $response->withHeader('Expires', gmdate('D, d M Y H:i:s', time() + $seconds) . ' GMT');
190
        $response = $response->withHeader('Pragma', 'cache');
191
        $response = $response->withHeader('Cache-Control', 'max-age=' . $seconds);
192
193
        return $response;
194
    }
195
196
    /**
197
     * Remove the PHP syntax, prevent the possible security issues.
198
     *
199
     * @param string $string
200
     *
201
     * @return string
202
     */
203
    private function filterString(string $string): string
204
    {
205
        return str_replace(['<?php', '<?', '?>'], '', $string);
206
    }
207
}
208