mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2025-08-01 16:45:02 +02:00
refactor: introduce http Request object (#3926)
This commit is contained in:
parent
9574c17ddc
commit
d08d13f2c8
19 changed files with 125 additions and 94 deletions
|
@ -5,5 +5,5 @@ interface ActionInterface
|
|||
/**
|
||||
* @return string|Response
|
||||
*/
|
||||
public function execute(array $request);
|
||||
public function execute(Request $request);
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
final class BridgeCard
|
||||
{
|
||||
/**
|
||||
* Gets a single bridge card
|
||||
* Render bridge card
|
||||
*
|
||||
* @param class-string<BridgeAbstract> $bridgeClassName The bridge name
|
||||
* @param bool $isActive Indicates if the bridge is active or not
|
||||
* @return string The bridge card
|
||||
*/
|
||||
public static function displayBridgeCard($bridgeClassName, $isActive = true)
|
||||
public static function render($bridgeClassName, $isActive = true)
|
||||
{
|
||||
$bridgeFactory = new BridgeFactory();
|
||||
|
||||
|
@ -56,10 +56,10 @@ final class BridgeCard
|
|||
// If we don't have any parameter for the bridge, we print a generic form to load it.
|
||||
if (count($contexts) === 0) {
|
||||
// The bridge has zero parameters
|
||||
$card .= self::getForm($bridgeClassName, $isActive);
|
||||
$card .= self::renderForm($bridgeClassName, $isActive);
|
||||
} elseif (count($contexts) === 1 && array_key_exists('global', $contexts)) {
|
||||
// The bridge has a single context with key 'global'
|
||||
$card .= self::getForm($bridgeClassName, $isActive, '', $contexts['global']);
|
||||
$card .= self::renderForm($bridgeClassName, $isActive, '', $contexts['global']);
|
||||
} else {
|
||||
// The bridge has one or more contexts (named or unnamed)
|
||||
foreach ($contexts as $contextName => $contextParameters) {
|
||||
|
@ -77,7 +77,7 @@ final class BridgeCard
|
|||
$card .= '<h5>' . $contextName . '</h5>' . PHP_EOL;
|
||||
}
|
||||
|
||||
$card .= self::getForm($bridgeClassName, $isActive, $contextName, $contextParameters);
|
||||
$card .= self::renderForm($bridgeClassName, $isActive, $contextName, $contextParameters);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ final class BridgeCard
|
|||
return $card;
|
||||
}
|
||||
|
||||
private static function getForm(
|
||||
private static function renderForm(
|
||||
string $bridgeClassName,
|
||||
bool $isActive = false,
|
||||
string $contextName = '',
|
||||
|
|
|
@ -26,6 +26,7 @@ abstract class FeedExpander extends BridgeAbstract
|
|||
$badStrings = [
|
||||
' ',
|
||||
'»',
|
||||
'’',
|
||||
];
|
||||
$xmlString = str_replace($badStrings, '', $xmlString);
|
||||
$feedParser = new FeedParser();
|
||||
|
|
|
@ -2,32 +2,26 @@
|
|||
|
||||
class FormatFactory
|
||||
{
|
||||
private $folder;
|
||||
private $formatNames;
|
||||
private array $formatNames = [];
|
||||
|
||||
public function __construct(string $folder = PATH_LIB_FORMATS)
|
||||
public function __construct()
|
||||
{
|
||||
$this->folder = $folder;
|
||||
|
||||
// create format names
|
||||
foreach (scandir($this->folder) as $file) {
|
||||
if (preg_match('/^([^.]+)Format\.php$/U', $file, $m)) {
|
||||
$iterator = new \FilesystemIterator(__DIR__ . '/../formats');
|
||||
foreach ($iterator as $file) {
|
||||
if (preg_match('/^([^.]+)Format\.php$/U', $file->getFilename(), $m)) {
|
||||
$this->formatNames[] = $m[1];
|
||||
}
|
||||
}
|
||||
sort($this->formatNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException
|
||||
* @param string $name The name of the format e.g. "Atom", "Mrss" or "Json"
|
||||
*/
|
||||
public function create(string $name): FormatAbstract
|
||||
{
|
||||
if (! preg_match('/^[a-zA-Z0-9-]*$/', $name)) {
|
||||
throw new \InvalidArgumentException('Format name invalid!');
|
||||
}
|
||||
$sanitizedName = $this->sanitizeFormatName($name);
|
||||
if ($sanitizedName === null) {
|
||||
$sanitizedName = $this->sanitizeName($name);
|
||||
if (!$sanitizedName) {
|
||||
throw new \InvalidArgumentException(sprintf('Unknown format given `%s`', $name));
|
||||
}
|
||||
$className = '\\' . $sanitizedName . 'Format';
|
||||
|
@ -39,15 +33,13 @@ class FormatFactory
|
|||
return $this->formatNames;
|
||||
}
|
||||
|
||||
protected function sanitizeFormatName(string $name)
|
||||
protected function sanitizeName(string $name): ?string
|
||||
{
|
||||
$name = ucfirst(strtolower($name));
|
||||
|
||||
// Trim trailing '.php' if exists
|
||||
if (preg_match('/(.+)(?:\.php)/', $name, $matches)) {
|
||||
$name = $matches[1];
|
||||
}
|
||||
|
||||
// Trim trailing 'Format' if exists
|
||||
if (preg_match('/(.+)(?:Format)/i', $name, $matches)) {
|
||||
$name = $matches[1];
|
||||
|
|
|
@ -27,9 +27,17 @@ final class RssBridge
|
|||
{
|
||||
if ($argv) {
|
||||
parse_str(implode('&', array_slice($argv, 1)), $cliArgs);
|
||||
$request = $cliArgs;
|
||||
$request = Request::fromCli($cliArgs);
|
||||
} else {
|
||||
$request = array_merge($_GET, $_POST);
|
||||
$request = Request::fromGlobals();
|
||||
}
|
||||
|
||||
foreach ($request->toArray() as $key => $value) {
|
||||
if (!is_string($value)) {
|
||||
return new Response(render(__DIR__ . '/../templates/error.html.php', [
|
||||
'message' => "Query parameter \"$key\" is not a string.",
|
||||
]), 400);
|
||||
}
|
||||
}
|
||||
|
||||
if (Configuration::getConfig('system', 'enable_maintenance_mode')) {
|
||||
|
@ -43,8 +51,8 @@ final class RssBridge
|
|||
if (Configuration::getConfig('authentication', 'password') === '') {
|
||||
return new Response('The authentication password cannot be the empty string', 500);
|
||||
}
|
||||
$user = $_SERVER['PHP_AUTH_USER'] ?? null;
|
||||
$password = $_SERVER['PHP_AUTH_PW'] ?? null;
|
||||
$user = $request->server('PHP_AUTH_USER');
|
||||
$password = $request->server('PHP_AUTH_PW');
|
||||
if ($user === null || $password === null) {
|
||||
$html = render(__DIR__ . '/../templates/error.html.php', [
|
||||
'message' => 'Please authenticate in order to access this instance!',
|
||||
|
@ -63,16 +71,8 @@ final class RssBridge
|
|||
// At this point the username and password was correct
|
||||
}
|
||||
|
||||
foreach ($request as $key => $value) {
|
||||
if (!is_string($value)) {
|
||||
return new Response(render(__DIR__ . '/../templates/error.html.php', [
|
||||
'message' => "Query parameter \"$key\" is not a string.",
|
||||
]), 400);
|
||||
}
|
||||
}
|
||||
|
||||
$actionName = $request['action'] ?? 'Frontpage';
|
||||
$actionName = strtolower($actionName) . 'Action';
|
||||
$action = $request->get('action', 'Frontpage');
|
||||
$actionName = strtolower($action) . 'Action';
|
||||
$actionName = implode(array_map('ucfirst', explode('-', $actionName)));
|
||||
$filePath = __DIR__ . '/../actions/' . $actionName . '.php';
|
||||
if (!file_exists($filePath)) {
|
||||
|
@ -80,9 +80,9 @@ final class RssBridge
|
|||
}
|
||||
|
||||
$className = '\\' . $actionName;
|
||||
$action = new $className();
|
||||
$actionObject = new $className();
|
||||
|
||||
$response = $action->execute($request);
|
||||
$response = $actionObject->execute($request);
|
||||
|
||||
if (is_string($response)) {
|
||||
$response = new Response($response);
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
<?php
|
||||
|
||||
// Path to the formats library
|
||||
const PATH_LIB_FORMATS = __DIR__ . '/../formats/';
|
||||
|
||||
/** Path to the caches library */
|
||||
const PATH_LIB_CACHES = __DIR__ . '/../caches/';
|
||||
|
||||
/** Path to the cache folder */
|
||||
const PATH_CACHE = __DIR__ . '/../cache/';
|
||||
|
||||
// Allow larger files for simple_html_dom
|
||||
|
|
40
lib/http.php
40
lib/http.php
|
@ -166,6 +166,46 @@ final class CurlHttpClient implements HttpClient
|
|||
}
|
||||
}
|
||||
|
||||
final class Request
|
||||
{
|
||||
private array $get;
|
||||
private array $server;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromGlobals(): self
|
||||
{
|
||||
$self = new self();
|
||||
$self->get = $_GET;
|
||||
$self->server = $_SERVER;
|
||||
return $self;
|
||||
}
|
||||
|
||||
public static function fromCli(array $cliArgs): self
|
||||
{
|
||||
$self = new self();
|
||||
$self->get = $cliArgs;
|
||||
return $self;
|
||||
}
|
||||
|
||||
public function get(string $key, $default = null): ?string
|
||||
{
|
||||
return $this->get[$key] ?? $default;
|
||||
}
|
||||
|
||||
public function server(string $key, string $default = null): ?string
|
||||
{
|
||||
return $this->server[$key] ?? $default;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->get;
|
||||
}
|
||||
}
|
||||
|
||||
final class Response
|
||||
{
|
||||
public const STATUS_CODES = [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue