true]); $twig->addExtension(new Twig\Extra\Markdown\MarkdownExtension()); use Twig\Extra\Markdown\DefaultMarkdown; use Twig\Extra\Markdown\MarkdownRuntime; use Twig\RuntimeLoader\RuntimeLoaderInterface; function deduce_user_agent() { $real_agent=$_SERVER['HTTP_USER_AGENT']; if(preg_match('/(Googlebot|\w*Google\w*)/', $real_agent, $match)) { return "bot/google/" . $match[1]; } elseif(preg_match('/(Mozilla|Chrome|Chromium)/', $real_agent, $match)) { return "user/" . $match[1]; } else { return "unidentified"; } } function log_and_die($path, $die_code = 0, $referrer = null) { global $data_time_start; global $adapter; $data_time_end = microtime(true); if(!isset($referrer)) { $referrer = 'magic'; if(isset($_SERVER['HTTP_REFERER'])) { $referrer = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); } } $adapter->log_post_access($path, deduce_user_agent(), $referrer, $data_time_end - $data_time_start); die($die_code); } $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface { public function load($class) { if (MarkdownRuntime::class === $class) { return new MarkdownRuntime(new DefaultMarkdown()); } } }); function render_twig($template, $args = []) { global $twig; global $FONT_AWESOME_ARRAY; $args['fa'] = $FONT_AWESOME_ARRAY; $post = $args['post'] ?? []; $settings = $post['settings'] ?? []; $meta = $post['post_metadata'] ?? []; $args['banner'] ??= $settings['banners'] ?? [ ["src"=> "/static/banner/0.png"], ["src" => "/static/banner/1.png"] ]; $args['og'] = array_merge([ "title" => $meta['title'] ?? "Dergennibble", "url" => $_SERVER['REQUEST_URI'], "description" => $meta['description'] ?? $settings['description'] ?? "The softest spot to find dragons on" ], $args['og'] ?? []); if(($meta['type'] ?? '') == 'image') { $args['og']['image'] ??= "https://lucidragons.de" . $post['post_file_dir']; } $args['og']['image'] ??= 'https://lucidragons.de' . $args['banner'][0]["src"]; $args['banner'] = json_encode($args['banner']); echo $twig->render($template, $args); } function try_render_post($SURI) { global $adapter; $post = $adapter->get_post_by_path($SURI); if(!$post['found']) { echo render_twig('post_types/rrror.html',[ "error_code" => '404 Hoard not found!', "error_description" => "Well, we searched far and wide for `" . $SURI . "` but somehow it must have gotten lost... Sorry!", "post" => array_merge($post, [ "post_metadata" => ["title" => "404 ???"] ]) ]); log_and_die('/404', referrer: ($_SERVER['HTTP_REFERER'] ?? 'magic')); } switch($post['post_metadata']['type']) { case 'directory': if(preg_match('/^(.*[^\/])((?:#.*)?)$/', $SURI, $match)) { header('Location: ' . $match[1] . '/' . $match[2]); die(); } echo render_twig('post_types/directory.html', [ "post" => $post, "subposts" => $adapter->get_subposts_by_path($SURI) ]); break; case 'text/markdown': echo render_twig('post_types/markdown.html', [ "post" => $post ]); break; case 'image': echo render_twig('post_types/image.html', [ "post" => $post, ]); break; } } function generate_website($SURI) { global $adapter; global $FONT_AWESOME_ARRAY; if(preg_match('/^\/api\/admin/', $SURI)) { header('Content-Type: application/json'); $user_api_key = ''; if(isset($_GET['api_key'])) { $user_api_key = $_GET['api_key']; } if(isset($_POST['api_key'])) { $user_api_key = $_POST['api_key']; } if($user_api_key != file_get_contents('secrets/api_admin_key')) { http_response_code(401); echo json_encode([ "authorized" => false ]); log_and_die('/api/401'); } if($SURI = '/api/admin/upload') { $adapter->handle_upload($_POST['post_path'], $_FILES['post_data']['tmp_name']); echo json_encode(["ok" => true]); } } elseif(preg_match('/^\/api/', $SURI)) { if($SURI == '/api/post_counters') { header('Content-Type: application/json'); echo json_encode($adapter->get_post_access_counters()); } elseif($SURI == '/api/metrics') { header('Content-Type: application/line'); echo $adapter->get_post_access_counters_line(); } elseif(preg_match('/^\/api\/posts(.*)$/', $SURI, $match)) { header('Content-Type: application/json'); echo json_encode($adapter->get_post_by_path($match[1])); } elseif(preg_match('/^\/api\/subposts(.*)$/', $SURI, $match)) { header('Content-Type: application/json'); echo json_encode(get_subposts($match[1])); } elseif($SURI == '/api/upload') { echo $twig->render('upload.html'); } } elseif(preg_match('/^\/feed(?:\/(rss|atom)(.*))?$/', $SURI, $match)) { $feed = $adapter->get_laminas_feed($match[2] ?? '/', $match[1] ?? 'rss'); header('Content-Type: application/xml'); header('Cache-Control: max-age=1800'); header('Etag: W/"' . $SURI . '/' . strtotime($feed['feed_ts']) . '"'); echo $feed['feed']; } elseif(!preg_match('/^\s*text\/html/', $_SERVER['HTTP_ACCEPT'])) { header('Location: /raw' . $SURI); exit(0); } elseif(true) { try_render_post($SURI); } } $URL_PATH = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); generate_website($URL_PATH); log_and_die($URL_PATH); ?>