* @license MIT */ declare(strict_types=1); use BitBadger\PDODocument\Configuration; use FeedReaderCentral\{Key, Security, User}; require 'app-config.php'; session_start([ 'name' => 'FRCSESSION', 'use_strict_mode' => true, 'cookie_httponly' => true, 'cookie_samesite' => 'Strict']); /** * Add a message to be displayed at the top of the page * * @param string $level The level (type) of the message * @param string $message The message itself */ function add_message(string $level, string $message): void { if (!key_exists(Key::UserMsg, $_SESSION)) $_SESSION[Key::UserMsg] = []; $_SESSION[Key::UserMsg][] = ['level' => $level, 'message' => $message]; } /** * Add an error message to be displayed at the top of the page * * @param string $message The message to be displayed */ function add_error(string $message): void { add_message('ERROR', $message); } /** * Add an error message to be displayed at the top of the page * * @param string $message The message to be displayed */ function add_info(string $message): void { add_message('INFO', $message); } /** True if this request was initiated by htmx, false if not */ $is_htmx = key_exists('HTTP_HX_REQUEST', $_SERVER) && !key_exists('HTTP_HX_HISTORY_RESTORE_REQUEST', $_SERVER); /** * Create a navigation link in the top right nav bar * * @param string $link The link to be placed * @param bool $isFirst True if this is the first link being placed, false if not */ function nav_link(string $link, bool $isFirst = false): void { $sep = $isFirst ? '' : ' | '; echo "$sep$link"; } /** * Render the title bar for the page */ function title_bar(): void { $version = display_version(); echo "
" . "
Feed Reader Central$version
" . "
' . '
'; } /** * Render the page title * @param string $title The title of the page being displayed */ function page_head(string $title): void { global $is_htmx; echo '' . "$title | Feed Reader Central"; if (!$is_htmx) { echo '' . "" . ''; } echo ''; if (!$is_htmx) title_bar(); if (sizeof($messages = $_SESSION[Key::UserMsg] ?? []) > 0) { echo '
'; array_walk($messages, function ($msg) { echo '
' . ($msg['level'] === 'INFO' ? '' : "{$msg['level']}
") . $msg['message'] . '
'; }); echo '
'; $_SESSION[Key::UserMsg] = []; } } /** * Render the end of the page */ function page_foot(): void { global $is_htmx; echo '
' . ($is_htmx ? '' : '') . ''; session_commit(); } /** * Redirect the user to the given URL * * @param string $value A local URL to which the user should be redirected */ function frc_redirect(string $value): never { if (str_starts_with($value, 'http')) { http_response_code(400); die(); } session_commit(); header("Location: $value", true, 303); Configuration::resetPDO(); die(); } /** * Convert a date/time string to a date/time in the configured format * * @param string $value The date/time string * @return string The standard format of a date/time, or '(invalid date)' if the date could not be parsed */ function date_time(string $value): string { try { return (new DateTimeImmutable($value))->format(DATE_TIME_FORMAT); } catch (Exception) { return '(invalid date)'; } } /** * Create an anchor tag with both `href` and `hx-get` attributes * * @param string $url The URL to which navigation should occur * @param string $text The text for the link * @param string $extraAttrs Extra attributes for the anchor tag (must be attribute-encoded) * @return string The anchor tag with both `href` and `hx-get` attributes */ function hx_get(string $url, string $text, string $extraAttrs = ''): string { $attrs = $extraAttrs !== '' ? " $extraAttrs" : ''; return "$text"; } /** * Return a 404 Not Found */ function not_found(): never { http_response_code(404); die('Not Found'); }