feat: introduce template engine (#2899)

This commit is contained in:
Dag 2022-07-08 14:17:25 +02:00 committed by GitHub
parent 951092eef3
commit abfc6b4633
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 92 additions and 20 deletions

View File

@ -47,7 +47,7 @@ class DetectAction implements ActionInterface
$bridgeParams['format'] = $format;
header('Location: ?action=display&' . http_build_query($bridgeParams), true, 301);
die();
exit;
}
returnClientError('No bridge found for given URL: ' . $targetURL);

View File

@ -63,7 +63,7 @@ class DisplayAction implements ActionInterface
unset($this->userData['_cache_timeout']);
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) . '?' . http_build_query($this->userData);
header('Location: ' . $uri, true, 301);
die();
exit;
}
$cache_timeout = filter_var($this->userData['_cache_timeout'], FILTER_VALIDATE_INT);
@ -126,7 +126,7 @@ class DisplayAction implements ActionInterface
if ($mtime <= $stime) { // Cached data is older or same
header('Last-Modified: ' . gmdate('D, d M Y H:i:s ', $mtime) . 'GMT', true, 304);
die();
exit;
}
}
@ -193,7 +193,9 @@ class DisplayAction implements ActionInterface
$items[] = $item;
} elseif (Configuration::getConfig('error', 'output') === 'http') {
header('Content-Type: text/html', true, $this->getReturnCode($e));
die(buildTransformException($e, $bridge));
$response = buildTransformException($e, $bridge);
print $response;
exit;
}
}
}
@ -224,7 +226,9 @@ class DisplayAction implements ActionInterface
} catch (\Throwable $e) {
error_log($e);
header('Content-Type: text/html', true, $e->getCode());
die(buildTransformException($e, $bridge));
$response = buildTransformException($e, $bridge);
print $response;
exit;
}
}
}

View File

@ -13,7 +13,8 @@ class SQLiteCache implements CacheInterface
public function __construct()
{
if (!extension_loaded('sqlite3')) {
die('"sqlite3" extension not loaded. Please check "php.ini"');
print render('error.html.php', ['message' => '"sqlite3" extension not loaded. Please check "php.ini"']);
exit;
}
if (!is_writable(PATH_CACHE)) {
@ -25,12 +26,16 @@ class SQLiteCache implements CacheInterface
$file = Configuration::getConfig(get_called_class(), 'file');
if (empty($file)) {
die('Configuration for ' . get_called_class() . ' missing. Please check your ' . FILE_CONFIG);
$message = sprintf('Configuration for %s missing. Please check your %s', get_called_class(), FILE_CONFIG);
print render('error.html.php', ['message' => $message]);
exit;
}
if (dirname($file) == '.') {
$file = PATH_CACHE . $file;
} elseif (!is_dir(dirname($file))) {
die('Invalid configuration for ' . get_called_class() . '. Please check your ' . FILE_CONFIG);
$message = sprintf('Invalid configuration for %s. Please check your %s', get_called_class(), FILE_CONFIG);
print render('error.html.php', ['message' => $message]);
exit;
}
if (!is_file($file)) {

View File

@ -26,13 +26,7 @@ try {
}
} catch (\Throwable $e) {
error_log($e);
$code = $e->getCode();
if ($code !== -1) {
header('Content-Type: text/plain', true, $code);
}
$message = sprintf("Uncaught Exception %s: '%s'\n", get_class($e), $e->getMessage());
print $message;
print render('error.html.php', [
'message' => sprintf("Uncaught Exception %s: '%s'\n", get_class($e), $e->getMessage()),
]);
}

View File

@ -58,7 +58,9 @@ class Authentication
if (Configuration::getConfig('authentication', 'enable') === true) {
if (!Authentication::verifyPrompt()) {
header('WWW-Authenticate: Basic realm="RSS-Bridge"', true, 401);
die('Please authenticate in order to access this instance !');
$message = 'Please authenticate in order to access this instance !';
print $message;
exit;
}
}
}

View File

@ -317,7 +317,10 @@ final class Configuration
*/
private static function reportError($message)
{
header('Content-Type: text/plain', true, 500);
die('Configuration error' . PHP_EOL . $message);
http_response_code(500);
print render('error.html.php', [
'message' => "Configuration error: $message",
]);
exit;
}
}

View File

@ -12,6 +12,44 @@
* @link https://github.com/rss-bridge/rss-bridge
*/
function render(string $template, array $context = []): string
{
$context['page'] = render_template($template, $context);
return render_template('base.html.php', $context);
}
function render_template(string $template, array $context = []): string
{
if (isset($context['template'])) {
throw new \Exception("Don't use `template` as a context key");
}
extract($context);
ob_start();
try {
require __DIR__ . '/../templates/' . $template;
} catch (\Throwable $e) {
ob_end_clean();
throw $e;
}
return ob_get_clean();
}
/**
* Escape for html context
*/
function e(string $s): string
{
return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
/**
* Explicitly don't escape
*/
function raw(string $s): string
{
return $s;
}
/**
* Removes unwanted tags from a given HTML text.
*

17
templates/base.html.php Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="RSS-Bridge" />
<title><?= e($title ?? 'RSS-Bridge') ?></title>
<link href="static/style.css" rel="stylesheet">
<link rel="icon" type="image/png" href="static/favicon.png">
</head>
<body>
<header>
<div class="logo"></div>
</header>
<?= raw($page) ?>
</html>

9
templates/error.html.php Normal file
View File

@ -0,0 +1,9 @@
<section>
<h2>Something went wrong</h2>
<br>
<p>
<?= e($message) ?>
</p>
</section>