proofdb/app/service/AdminConsole/AdminDocService.php
2026-05-08 00:05:51 +08:00

77 lines
2.1 KiB
PHP

<?php
namespace app\service\AdminConsole;
use RuntimeException;
class AdminDocService
{
public function __construct(private readonly ?MarkdownRenderer $renderer = null)
{
}
public function list(): array
{
$items = [];
foreach (glob(base_path('apidoc/*.md')) ?: [] as $path) {
$name = basename($path);
$content = (string) file_get_contents($path);
$items[] = [
'name' => $name,
'title' => $this->title($content, $name),
];
}
usort($items, fn (array $a, array $b): int => strcmp($a['name'], $b['name']));
return $items;
}
public function read(string $name): array
{
$safeName = basename($name);
$path = base_path('apidoc/' . $safeName);
if (!is_file($path) || pathinfo($path, PATHINFO_EXTENSION) !== 'md') {
throw new RuntimeException('API doc not found.');
}
$content = (string) file_get_contents($path);
return [
'name' => $safeName,
'title' => $this->title($content, $safeName),
'content' => $content,
'html' => $this->renderer()->render($content),
];
}
public function readScriptDoc(string $name): array
{
$safeName = basename($name);
$path = base_path('scriptdoc/' . $safeName);
if (!is_file($path) || pathinfo($path, PATHINFO_EXTENSION) !== 'md') {
throw new RuntimeException('Script doc not found.');
}
$content = (string) file_get_contents($path);
return [
'name' => $safeName,
'title' => $this->title($content, $safeName),
'content' => $content,
'html' => $this->renderer()->render($content),
];
}
private function title(string $content, string $fallback): string
{
if (preg_match('/^#\s+(.+)$/m', $content, $matches)) {
return trim($matches[1]);
}
return $fallback;
}
private function renderer(): MarkdownRenderer
{
return $this->renderer ?? new MarkdownRenderer();
}
}