diff options
author | 2024-01-25 16:06:24 +0100 | |
---|---|---|
committer | 2024-01-25 16:06:24 +0100 | |
commit | d08d13f2c87b24fadb92e31c50dedc6e56c3c088 (patch) | |
tree | a2fd66aa0cdd091ad34a135cf8222847f025f6f3 /lib | |
parent | 9574c17ddc4c55ab191878164627c4501a565221 (diff) | |
download | rss-bridge-d08d13f2c87b24fadb92e31c50dedc6e56c3c088.tar.gz rss-bridge-d08d13f2c87b24fadb92e31c50dedc6e56c3c088.tar.zst rss-bridge-d08d13f2c87b24fadb92e31c50dedc6e56c3c088.zip |
refactor: introduce http Request object (#3926)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ActionInterface.php | 2 | ||||
-rw-r--r-- | lib/BridgeCard.php | 12 | ||||
-rw-r--r-- | lib/FeedExpander.php | 1 | ||||
-rw-r--r-- | lib/FormatFactory.php | 26 | ||||
-rw-r--r-- | lib/RssBridge.php | 32 | ||||
-rw-r--r-- | lib/bootstrap.php | 6 | ||||
-rw-r--r-- | lib/http.php | 40 |
7 files changed, 73 insertions, 46 deletions
diff --git a/lib/ActionInterface.php b/lib/ActionInterface.php index 220dfa50..c0ddcf9f 100644 --- a/lib/ActionInterface.php +++ b/lib/ActionInterface.php @@ -5,5 +5,5 @@ interface ActionInterface /** * @return string|Response */ - public function execute(array $request); + public function execute(Request $request); } diff --git a/lib/BridgeCard.php b/lib/BridgeCard.php index 6b835c15..6b812740 100644 --- a/lib/BridgeCard.php +++ b/lib/BridgeCard.php @@ -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 = '', diff --git a/lib/FeedExpander.php b/lib/FeedExpander.php index c0d7e878..35b75249 100644 --- a/lib/FeedExpander.php +++ b/lib/FeedExpander.php @@ -26,6 +26,7 @@ abstract class FeedExpander extends BridgeAbstract $badStrings = [ ' ', '»', + '’', ]; $xmlString = str_replace($badStrings, '', $xmlString); $feedParser = new FeedParser(); diff --git a/lib/FormatFactory.php b/lib/FormatFactory.php index 042dcf31..e9cbe597 100644 --- a/lib/FormatFactory.php +++ b/lib/FormatFactory.php @@ -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]; diff --git a/lib/RssBridge.php b/lib/RssBridge.php index 5938f824..c8d11596 100644 --- a/lib/RssBridge.php +++ b/lib/RssBridge.php @@ -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); diff --git a/lib/bootstrap.php b/lib/bootstrap.php index 01828f67..48db871c 100644 --- a/lib/bootstrap.php +++ b/lib/bootstrap.php @@ -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 diff --git a/lib/http.php b/lib/http.php index 90b65a6e..d53909b4 100644 --- a/lib/http.php +++ b/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 = [ |