MSZ_ROOT, 'index' => MSZ_ROOT . '/vendor/flashwave/index', ]; private const PROJECT_SUFFIXES = [ 'misuzu' => 'Misuzu Project » %s', 'index' => 'Index Project » %s', ]; public function __construct(IRouter $router) { $router->get('/info', [$this, 'getIndex']); $router->get('/info/:name', [$this, 'getDocsPage']); $router->get('/info/:project/:name', [$this, 'getProjectPage']); $router->get('/info.php', function($response) { $response->redirect(url('info'), true); }); $router->get('/info.php/:name', function($response, $request, string $name) { $response->redirect(url('info', ['title' => $name]), true); }); $router->get('/info.php/:project/:name', function($response, $request, string $project, string $name) { $response->redirect(url('info', ['title' => $project . '/' . $name]), true); }); } private static function checkName(string $name): bool { return preg_match('#^([A-Za-z0-9_]+)$#', $name) === 1; } public function getIndex() { return Template::renderRaw('info.index'); } public function getDocsPage($response, $request, string $name) { if(!self::checkName($name)) return 404; return $this->serveMarkdownDocument( sprintf('%s/%s.md', self::DOCS_PATH, $name) ); } public function getProjectPage($response, $request, string $project, string $name) { if(!array_key_exists($project, self::PROJECT_PATHS)) return 404; if(!self::checkName($name)) return 404; $projectPath = self::PROJECT_PATHS[$project]; $titleSuffix = array_key_exists($project, self::PROJECT_SUFFIXES) ? self::PROJECT_SUFFIXES[$project] : ''; $attempts = 0; $licenceHack = false; for(;;) { $path = match(++$attempts) { 1 => sprintf('%s/%s', $projectPath, $name), 2 => sprintf('%s/%s.md', $projectPath, $name), 3 => sprintf('%s/%s', $projectPath, strtoupper($name)), 4 => sprintf('%s/%s.md', $projectPath, strtoupper($name)), 5 => sprintf('%s/%s', $projectPath, strtolower($name)), 6 => sprintf('%s/%s.md', $projectPath, strtolower($name)), default => '', }; if($path === '') { if(!$licenceHack) { $isBritish = strtolower($name) === 'licence'; $isAmerican = strtolower($name) === 'license'; if($isBritish || $isAmerican) { $attempts = 0; $licenceHack = true; $name = $isAmerican ? 'licence' : 'license'; continue; } } return 404; } if(is_file($path)) break; } return $this->serveMarkdownDocument($path, $titleSuffix); } private function serveMarkdownDocument(string $path, string $titleFormat = '') { if(!is_file($path)) return 404; $body = file_get_contents($path); if(str_starts_with($body, '#')) { $offset = strpos($body, "\n"); $title = trim(substr($body, 1, $offset)); $body = substr($body, $offset); } else $title = ucfirst(basename($path)); if($titleFormat !== '') $title = sprintf($titleFormat, $title); $body = Parser::instance(Parser::MARKDOWN)->parseText($body); return Template::renderRaw('info.view', [ 'document' => [ 'title' => $title, 'content' => $body, ], ]); } }