misuzu/src/Info/InfoRoutes.php

126 lines
3.9 KiB
PHP

<?php
namespace Misuzu\Info;
use Index\Http\Routing\{HttpGet,RouteHandler};
use Misuzu\Template;
use Misuzu\Parsers\Parser;
use Misuzu\URLs\URLInfo;
class InfoRoutes extends RouteHandler {
private const DOCS_PATH = MSZ_ROOT . '/docs';
private const PROJECT_PATHS = [
'misuzu' => MSZ_ROOT,
'index' => MSZ_ROOT . '/vendor/flashwave/index',
];
private const PROJECT_SUFFIXES = [
'misuzu' => 'Misuzu Project » %s',
'index' => 'Index Project » %s',
];
#[HttpGet('/info')]
#[URLInfo('info-index', '/info')]
public function getIndex() {
return Template::renderRaw('info.index');
}
#[HttpGet('/info/([A-Za-z0-9_]+)')]
#[URLInfo('info', '/info/<title>')]
#[URLInfo('info-doc', '/info/<title>')]
public function getDocsPage($response, $request, string $name) {
return $this->serveMarkdownDocument(
sprintf('%s/%s.md', self::DOCS_PATH, $name)
);
}
private static function findDocPath(string $projectPath, string $name): string {
// User provided case, without extension
$attempt = sprintf('%s/%s', $projectPath, $name);
if(is_file($attempt))
return $attempt;
// User provided case, with extension
$attempt = sprintf('%s/%s.md', $projectPath, $name);
if(is_file($attempt))
return $attempt;
$name = strtoupper($name);
// Uppercase, without extension
$attempt = sprintf('%s/%s', $projectPath, $name);
if(is_file($attempt))
return $attempt;
// Uppercase, with extension
$attempt = sprintf('%s/%s.md', $projectPath, $name);
if(is_file($attempt))
return $attempt;
$name = strtolower($name);
// Lowercase, without extension
$attempt = sprintf('%s/%s', $projectPath, $name);
if(is_file($attempt))
return $attempt;
// Lowercase, with extension
$attempt = sprintf('%s/%s.md', $projectPath, $name);
if(is_file($attempt))
return $attempt;
return '';
}
#[HttpGet('/info/([A-Za-z0-9_]+)/([A-Za-z0-9_]+)')]
#[URLInfo('info-project-doc', '/info/<project>/<title>')]
public function getProjectPage($response, $request, string $project, string $name) {
if(!array_key_exists($project, self::PROJECT_PATHS))
return 404;
$projectPath = self::PROJECT_PATHS[$project];
$titleSuffix = array_key_exists($project, self::PROJECT_SUFFIXES) ? self::PROJECT_SUFFIXES[$project] : '';
$path = self::findDocPath($projectPath, $name);
if($path === '') {
$isBritishLicense = strtolower($name) === 'licence';
$isAmericanLicence = strtolower($name) === 'license';
if($isBritishLicense || $isAmericanLicence) {
$name = $isAmericanLicence ? 'licence' : 'license';
$path = self::findDocPath($projectPath, $name);
if($path === '')
return 404;
} else
return 404;
}
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,
],
]);
}
}