1
0
mirror of https://github.com/suk-ws/ph-Bookshelf.git synced 2024-12-05 01:16:53 +08:00

添加了一个简单的资源文件输出功能,实现了标题跳转

- 现在无法被解析为页面的请求会尝试从 /data/%assets/ 中寻找资源文件
- 给标题解析添加了和内容相同的 id 生成,从而可以使用跳转了
This commit is contained in:
A.C.Sukazyo Eyre 2021-05-05 14:57:15 +08:00
parent f00a421c31
commit 8f43bdc2c1
Signed by: Eyre_S
GPG Key ID: EFB47D98FE082FAD
4 changed files with 156 additions and 21 deletions

View File

@ -4,6 +4,8 @@
require_once "./src/Data/SiteMeta.php";
require_once "./src/Data/PageMeta.php";
require_once "./lib/Parsedown/Parsedown.php";
require_once "./src/Utils/PageParse.php";
require_once "./src/Utils/RequestNotExistException.php";
$parser = new Parsedown();
@ -15,29 +17,52 @@ try {
SiteMeta::load();
// 格式化所给链接,并将链接转化为路径字符串数组
$tmp = $_GET['p'];
if (strlen($tmp) > 0 && $tmp[strlen($tmp) - 1] === '/')
$tmp = substr($tmp, 0, -1);
$uri = explode("/", $tmp, 2);
$req = $_GET['p'];
if (strlen($req) > 0 && $req[strlen($req) - 1] === '/')
$tmp = substr($req, 0, -1);
$uri = explode("/", $req, 2);
if (sizeof($uri) > 0 && $uri[0] != null) {
// 非主页面,判定当前定义的 book
$tmp = SiteMeta::getBookshelf()->getBook($uri[0]);
if ($tmp == null) throw new Exception("Book required \"$uri[0]\" not found!");
PageMeta::$book = $tmp->getContentedNode();
// 判定当前页面
if (sizeof($uri) > 1 && $uri[1] != null) {
$tmp = PageMeta::$book->getPage($uri[1]);
if ($tmp == null) throw new Exception("Page required \"$uri[1]\" not found on book \"$uri[0]\"!");
PageMeta::$page = $tmp;
try {
// 寻找页面
if (sizeof($uri) > 0 && $uri[0] != null) {
// 非主页面,判定当前定义的 book
$tmp = SiteMeta::getBookshelf()->getBook($uri[0]);
if ($tmp == null) throw new RequestNotExistException("Book required \"$uri[0]\" not found!");
PageMeta::$book = $tmp->getContentedNode();
// 判定当前页面
if (sizeof($uri) > 1 && $uri[1] != null) {
$tmp = PageMeta::$book->getPage($uri[1]);
if ($tmp == null) throw new RequestNotExistException("Page required \"$uri[1]\" not found on book \"$uri[0]\"!");
PageMeta::$page = $tmp;
} else {
PageMeta::$page = PageMeta::$book->getChilds()->getChilds()[0];
}
} else {
// 主页面
PageMeta::$book = SiteMeta::getBookshelf()->getRootBook();
PageMeta::$page = PageMeta::$book->getChilds()->getChilds()[0];
PageMeta::$isMainPage = true;
}
} else {
// 主页面
PageMeta::$book = SiteMeta::getBookshelf()->getRootBook();
PageMeta::$page = PageMeta::$book->getChilds()->getChilds()[0];
PageMeta::$isMainPage = true;
} catch (RequestNotExistException $e) {
// 页面寻找失败,寻找资源文件
if (!is_file($resLoc = "./data/%assets/$req")) { // 全局文件夹的资源文件
// if (!is_file($resLoc = sprintf("./data/%s/%s", PageParse::genPathFromUriArray($uri), $req))) { // 以当前页面为基准位置的资源文件
// if (!is_file($resLoc = sprintf("./data/%s/%s", PageParse::genPathFromUriArray(array_slice($uri, 0, -1)), $req))) { // 以当前页面为基准位置的资源文件(fallback版)
// if (!is_file($resLoc = sprintf("./data/%s/%s", PageMeta::$book->getId(), $req))) { // 以当前书籍为基准位置的资源文件
// if (!is_file($resLoc = "./data/$req")) { // 全局的资源文件
throw $e;
// }
// }
// }
// }
}
PageParse::outputBinaryFile($resLoc);
}
require "./template/header.php";
@ -90,7 +115,7 @@ try {
<div id="book-search-results">
<div class="search-noresults">
<section class="normal markdown-section">
<h1 id="workshop-services"><?= PageMeta::$page->getName() ?></h1>
<h1 id="<?= PageMeta::$page->getId() ?>"><?= PageMeta::$page->getName() ?></h1>
<?= $parser->text(PageMeta::$page->getMarkdownContent()) ?>
</section>
</div>

View File

@ -561,7 +561,20 @@ class Parsedown
'function' => 'lineElements',
'argument' => $text,
'destination' => 'elements',
)
),
/**
* Custom Start
*
* 生成标题的跳转用id
*
* @author Sukazyo
*/
'attributes' => array(
'id' => $text,
),
/**
* Custom End
*/
),
);

87
src/Utils/PageParse.php Normal file
View File

@ -0,0 +1,87 @@
<?php
require_once "./src/Utils/StringUtils.php";
class PageParse {
/**
* 按照原样输出资源文件
*
* @link https://segmentfault.com/a/1190000010912097
*
* @return bool 是否成功输出文件
*/
public static function outputBinaryFile (string $filePath): bool {
// 获取文件名和文件后缀名
$fileInfo = pathinfo($filePath);
$filename = $fileInfo['basename'];
$fileExtension = $fileInfo['extension'];
// 将utf8编码转换成gbk编码否则中文名称的文件无法打开
// $filePath = iconv('UTF-8', 'gbk', $filePath);
// 检查文件是否可读
if (!is_file($filePath) || !is_readable($filePath)) {
exit("File Can't Read!");
}
// 判定文件类型
$fileMime = mime_content_type($filePath);
$isText = false;
if ($fileMime == "text/plain") {
$isText = true;
switch ($fileExtension) {
case "css":
$fileMime = "text/css";
break;
case "js":
$fileMime = "application/javascript";
break;
default:
}
}
// 文件类型是二进制流。设置为utf8编码支持中文文件名称
header('Content-type:'.$fileMime.'; charset=utf-8');
header("Access-Control-Allow-Origin: * ");
if (isset($_GET['download'])) {
// 触发浏览器文件下载功能
header('Content-Disposition:attachment;filename="'.urlencode($filename).'"');
}
if ($isText) {
echo file_get_contents($filePath);
} else {
// 二进制文件数据头
header("Accept-Ranges: bytes");
header("Content-Length: ".filesize($filePath));
// 以只读方式打开文件,并强制使用二进制模式
$fileHandle = fopen($filePath, "rb");
if ($fileHandle === false) {
exit("read false");
}
// 循环读取文件内容,并输出
while (!feof($fileHandle)) {
// 从文件指针 handle 读取最多 length 个字节每次输出10k
echo fread($fileHandle, 10240);
}
// 关闭文件流
fclose($fileHandle);
}
return true;
}
/**
* 根据链接数组生成对应的链接/路径
*
* eg.
* ["a2d", "WAE42WR6", "39272833"] => "a2d/WAE42WR6/39272833"
*
* @param string[] $uri
* @return string
*/
public static function genPathFromUriArray (array $uri): string {
$result = "";
foreach ($uri as $n) {
$result .= $n . "/";
}
return substr($result, 0, -1);
}
}

View File

@ -0,0 +1,10 @@
<?php
class RequestNotExistException extends Exception {
public function __construct ($message = "", $code = 0, Throwable $previous = null) {
parent::__construct($message, $code, $previous);
}
}