refactor: extract index.php to RssBridge.php (#2961)

* refactor: extract entry point into class

* refactor: js

* refactor: extract frontpage action
This commit is contained in:
Dag 2022-08-18 22:52:01 +02:00 committed by GitHub
parent 372eccd7b2
commit 0de1694371
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 116 additions and 171 deletions

View File

@ -1,57 +1,27 @@
<?php
/**
* This file is part of RSS-Bridge, a PHP project capable of generating RSS and
* Atom feeds for websites that don't have one.
*
* For the full license information, please view the UNLICENSE file distributed
* with this source code.
*
* @package Core
* @license http://unlicense.org/ UNLICENSE
* @link https://github.com/rss-bridge/rss-bridge
*/
/**
* A generator class for the home page of RSS-Bridge.
*
* This class generates the HTML content for displaying all bridges on the home
* page of RSS-Bridge.
*
* @todo Return error if a caller creates an object of this class.
*/
final class BridgeList
final class FrontpageAction implements ActionInterface
{
/**
* Create the entire home page
*
* @param bool $showInactive Inactive bridges are displayed on the home page,
* if enabled.
* @return string The home page
*/
public static function create($showInactive = true)
public function execute(array $request)
{
$showInactive = (bool) ($request['show_inactive'] ?? null);
$totalBridges = 0;
$totalActiveBridges = 0;
return '<!DOCTYPE html><html lang="en">'
. BridgeList::getHead()
. '<body onload="rssbridge_list_search()">'
. BridgeList::getHeader()
. BridgeList::getSearchbar()
. BridgeList::getBridges($showInactive, $totalBridges, $totalActiveBridges)
. BridgeList::getFooter($totalBridges, $totalActiveBridges, $showInactive)
. '</body></html>';
$html = self::getHead()
. self::getHeader()
. self::getSearchbar()
. self::getBridges($showInactive, $totalBridges, $totalActiveBridges)
. self::getFooter($totalBridges, $totalActiveBridges, $showInactive);
print $html;
}
/**
* Get the document head
*
* @return string The document head
*/
private static function getHead()
{
return <<<EOD
<!DOCTYPE html><html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@ -59,62 +29,15 @@ final class BridgeList
<title>RSS-Bridge</title>
<link href="static/style.css" rel="stylesheet">
<link rel="icon" type="image/png" href="static/favicon.png">
<script src="static/search.js"></script>
<script src="static/select.js"></script>
<noscript>
<style>
.searchbar {
display: none;
}
</style>
</noscript>
<script src="static/rss-bridge.js"></script>
<script>
document.addEventListener('DOMContentLoaded', rssbridge_toggle_bridge);
</script>
</head>
<body onload="rssbridge_list_search()">
EOD;
}
/**
* Get the document body for all bridge cards
*
* @param bool $showInactive Inactive bridges are visible on the home page if
* enabled.
* @param int $totalBridges (ref) Returns the total number of bridges.
* @param int $totalActiveBridges (ref) Returns the number of active bridges.
* @return string The document body for all bridge cards.
*/
private static function getBridges($showInactive, &$totalBridges, &$totalActiveBridges)
{
$body = '';
$totalActiveBridges = 0;
$inactiveBridges = '';
$bridgeFactory = new BridgeFactory();
$bridgeClassNames = $bridgeFactory->getBridgeClassNames();
$formatFactory = new FormatFactory();
$formats = $formatFactory->getFormatNames();
$totalBridges = count($bridgeClassNames);
foreach ($bridgeClassNames as $bridgeClassName) {
if ($bridgeFactory->isWhitelisted($bridgeClassName)) {
$body .= BridgeCard::displayBridgeCard($bridgeClassName, $formats);
$totalActiveBridges++;
} elseif ($showInactive) {
// inactive bridges
$inactiveBridges .= BridgeCard::displayBridgeCard($bridgeClassName, $formats, false) . PHP_EOL;
}
}
$body .= $inactiveBridges;
return $body;
}
/**
* Get the document header
*
* @return string The document header
*/
private static function getHeader()
{
$warning = '';
@ -141,11 +64,6 @@ EOD;
EOD;
}
/**
* Get the searchbar
*
* @return string The searchbar
*/
private static function getSearchbar()
{
$query = filter_input(INPUT_GET, 'q', \FILTER_SANITIZE_SPECIAL_CHARS);
@ -166,23 +84,41 @@ EOD;
EOD;
}
/**
* Get the document footer
*
* @param int $totalBridges The total number of bridges, shown in the footer
* @param int $totalActiveBridges The total number of active bridges, shown
* in the footer.
* @param bool $showInactive Sets the 'Show active'/'Show inactive' text in
* the footer.
* @return string The document footer
*/
private static function getBridges($showInactive, &$totalBridges, &$totalActiveBridges)
{
$body = '';
$totalActiveBridges = 0;
$inactiveBridges = '';
$bridgeFactory = new BridgeFactory();
$bridgeClassNames = $bridgeFactory->getBridgeClassNames();
$formatFactory = new FormatFactory();
$formats = $formatFactory->getFormatNames();
$totalBridges = count($bridgeClassNames);
foreach ($bridgeClassNames as $bridgeClassName) {
if ($bridgeFactory->isWhitelisted($bridgeClassName)) {
$body .= BridgeCard::displayBridgeCard($bridgeClassName, $formats);
$totalActiveBridges++;
} elseif ($showInactive) {
$inactiveBridges .= BridgeCard::displayBridgeCard($bridgeClassName, $formats, false) . PHP_EOL;
}
}
$body .= $inactiveBridges;
return $body;
}
private static function getFooter($totalBridges, $totalActiveBridges, $showInactive)
{
$version = Configuration::getVersion();
$email = Configuration::getConfig('admin', 'email');
$admininfo = '';
if (!empty($email)) {
if ($email) {
$admininfo = <<<EOD
<br />
<span>
@ -210,6 +146,7 @@ EOD;
{$inactive}
{$admininfo}
</section>
</body></html>
EOD;
}
}

View File

@ -2,55 +2,6 @@
require_once __DIR__ . '/lib/rssbridge.php';
try {
Configuration::verifyInstallation();
Configuration::loadConfiguration();
$rssBridge = new RssBridge();
date_default_timezone_set(Configuration::getConfig('system', 'timezone'));
define('CUSTOM_CACHE_TIMEOUT', Configuration::getConfig('cache', 'custom_timeout'));
$authenticationMiddleware = new AuthenticationMiddleware();
if (Configuration::getConfig('authentication', 'enable')) {
$authenticationMiddleware();
}
if (isset($argv)) {
parse_str(implode('&', array_slice($argv, 1)), $cliArgs);
$request = $cliArgs;
} else {
$request = $_GET;
}
foreach ($request as $key => $value) {
if (! is_string($value)) {
throw new \Exception("Query parameter \"$key\" is not a string.");
}
}
$actionFactory = new ActionFactory();
if (array_key_exists('action', $request)) {
$action = $actionFactory->create($request['action']);
$action->execute($request);
} else {
$showInactive = filter_input(INPUT_GET, 'show_inactive', FILTER_VALIDATE_BOOLEAN);
echo BridgeList::create($showInactive);
}
} catch (\Throwable $e) {
error_log($e);
$message = sprintf(
'Uncaught Exception %s: %s at %s line %s',
get_class($e),
$e->getMessage(),
trim_path_prefix($e->getFile()),
$e->getLine()
);
http_response_code(500);
print render('error.html.php', [
'message' => $message,
'stacktrace' => create_sane_stacktrace($e),
]);
}
$rssBridge->main($argv ?? []);

58
lib/RssBridge.php Normal file
View File

@ -0,0 +1,58 @@
<?php
final class RssBridge
{
public function main(array $argv = [])
{
if ($argv) {
parse_str(implode('&', array_slice($argv, 1)), $cliArgs);
$request = $cliArgs;
} else {
$request = $_GET;
}
try {
$this->run($request);
} catch (\Throwable $e) {
error_log($e);
$message = sprintf(
'Uncaught Exception %s: %s at %s line %s',
get_class($e),
$e->getMessage(),
trim_path_prefix($e->getFile()),
$e->getLine()
);
http_response_code(500);
print render('error.html.php', [
'message' => $message,
'stacktrace' => create_sane_stacktrace($e),
]);
}
}
private function run($request): void
{
Configuration::verifyInstallation();
Configuration::loadConfiguration();
date_default_timezone_set(Configuration::getConfig('system', 'timezone'));
define('CUSTOM_CACHE_TIMEOUT', Configuration::getConfig('cache', 'custom_timeout'));
$authenticationMiddleware = new AuthenticationMiddleware();
if (Configuration::getConfig('authentication', 'enable')) {
$authenticationMiddleware();
}
foreach ($request as $key => $value) {
if (!is_string($value)) {
throw new \Exception("Query parameter \"$key\" is not a string.");
}
}
$actionFactory = new ActionFactory();
$action = $request['action'] ?? 'Frontpage';
$action = $actionFactory->create($action);
$action->execute($request);
}
}

View File

@ -38,3 +38,12 @@ function rssbridge_list_search() {
}
}
}
function rssbridge_toggle_bridge(){
var fragment = window.location.hash.substr(1);
var bridge = document.getElementById(fragment);
if(bridge !== null) {
bridge.getElementsByClassName('showmore-box')[0].checked = true;
}
}

View File

@ -1,10 +0,0 @@
function select(){
var fragment = window.location.hash.substr(1);
var bridge = document.getElementById(fragment);
if(bridge !== null) {
bridge.getElementsByClassName('showmore-box')[0].checked = true;
}
}
document.addEventListener('DOMContentLoaded', select);