Assets::replaceContent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ublaboo\Anabelle\Generator;
6
7
use MatthiasMullie\Minify\CSS;
8
use MatthiasMullie\Minify\JS;
9
use Ublaboo\Anabelle\Http\AuthCredentials;
10
11
final class Assets
12
{
13
14
	/**
15
	 * @var string
16
	 */
17
	private $layoutFile;
18
19
	/**
20
	 * @var array
21
	 */
22
	private $layoutStylesPaths;
23
24
	/**
25
	 * @var array
26
	 */
27
	private $layoutSriptsPaths;
28
29
	/**
30
	 * @var string|null
31
	 */
32
	private $layoutStyles;
33
34
	/**
35
	 * @var string
36
	 */
37
	private $layoutFavicon;
38
39
	/**
40
	 * @var string|null
41
	 */
42
	private $sectionStyles;
43
44
	/**
45
	 * @var AuthCredentials
46
	 */
47
	private $authCredentials;
48
49
50
	public function __construct(AuthCredentials $authCredentials)
51
	{
52
		$this->layoutFile = __DIR__ . '/../../assets/layout.php';
53
		$this->layoutStylesPaths = [
54
			__DIR__ . '/../../assets/highlight-json.css',
55
			__DIR__ . '/../../assets/layout.css'
56
		];
57
		$this->layoutSriptsPaths = [
58
			__DIR__ . '/../../assets/highlight-json.min.js',
59
			__DIR__ . '/../../assets/layout.js'
60
		];
61
		$this->layoutFavicon = __DIR__ . '/../../assets/favicon.ico';
62
63
		$this->authCredentials = $authCredentials;
64
	}
65
66
67
	public function saveFile(string $content, string $outputFile, bool $isLayout): void
68
	{
69
		if ($isLayout) {
70
			$this->saveLayout($content, $outputFile);
71
			copy($this->layoutFavicon, dirname($outputFile) . '/favicon.ico');
72
		} else {
73
			$this->saveSection($content, $outputFile);
74
		}
75
	}
76
77
78
	private function saveLayout(string $content, string $outputFile): void
79
	{
80
		$template = file_get_contents($this->layoutFile);
81
82
		$this->replaceHttpAuth($template);
83
		$this->replaceTitle($template, $content);
84
85
		$content = preg_replace('/^<h1>.*<\/h1>\w*$/mU', '', $content);
86
		$this->replaceContent($template, $content);
87
88
		$template = str_replace('{styles}', $this->getLayoutStyles(), $template);
89
		$template = str_replace('{scripts}', $this->getLayoutSripts(), $template);
90
91
		file_put_contents($outputFile, $this->minifyHtml($template));
92
	}
93
94
95
	private function saveSection(string $content, string $outputFile): void
96
	{
97
		file_put_contents($outputFile, $this->minifyHtml($content));
98
	}
99
100
101
	public function replaceHttpAuth(string & $template): void // Intentionally &
102
	{
103
		$template = str_replace('{httpAuth}', $this->getHttpAuthSnippet(), $template);
104
	}
105
106
107
	private function replaceTitle(string & $template, string $content): void // Intentionally &
108
	{
109
		if (preg_match('/<h1>(.+)<\/h1>/', $content, $matches)) {
110
			$template = str_replace('{title}', $matches[1], $template);
111
		} else {
112
			$template = str_replace('{title}', 'API Docs', $template);
113
		}
114
	}
115
116
117
	private function replaceContent(string & $template, string $content): void // Intentionally &
118
	{
119
		$template = str_replace('{content}', $content, $template);
120
	}
121
122
123
	private function getLayoutStyles(): string
124
	{
125
		if ($this->layoutStyles === null) {
126
			$minifier = new CSS;
127
128
			foreach ($this->layoutStylesPaths as $file) {
129
				$minifier->add($file);
130
			}
131
132
			$this->layoutStyles = $minifier->minify();
133
		}
134
135
		return $this->layoutStyles;
136
	}
137
138
139
	private function getLayoutSripts(): string
140
	{
141
		$minifier = new JS;
142
143
		foreach ($this->layoutSriptsPaths as $file) {
144
			$minifier->add($file);
145
		}
146
147
		return $minifier->minify();
148
	}
149
150
151
	private function minifyHtml(string $html): string
152
	{
153
		return preg_replace(
154
			'#(?ix)(?>[^\S ]\s*|\s{2,})(?=(?:(?:[^<]++|<(?!/?(?:textarea|pre)\b))*+)(?:<(?>textarea|pre)\b|\z))#',
155
			' ',
156
			$html
157
		);
158
	}
159
160
161
	public function getHttpAuthSnippet(): string
162
	{
163
		if ($this->authCredentials->getUser() !== null) {
164
			$u = $this->authCredentials->getUser();
165
			$p = $this->authCredentials->getPass();
166
167
			return "<?php if (!isset(\$_SERVER['PHP_AUTH_USER']) || \$_SERVER['PHP_AUTH_USER'] !== '{$u}' || \$_SERVER['PHP_AUTH_PW'] !== '{$p}') {"
168
				. "	header('WWW-Authenticate: Basic realm=\"API Docu\"');"
169
				. "	header('HTTP/1.0 401 Unauthorized');"
170
				. "	die('Invalid authentication');"
171
				. '} ?>';
172
		}
173
174
		return '';
175
	}
176
}
177