- /show-{id}.shtml (comments page: /show-{id}-{page}.shtml)
- /category-{cid}.shtml / /category-{cid}-{page}.shtml
- /archives-{YYYYMM}.shtml / /archives-{YYYYMM}-{page}.shtml
- /tag/{name}, /tagslist.shtml, /index-{page}.shtml
- slug 时代的 /posts/{slug} 等旧格式全部 301 到 sablog 格式
64 lines
1.7 KiB
PHP
64 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
namespace App\Blog\Controllers;
|
|
|
|
use App\Blog\Services\PostContentRenderer;
|
|
use App\Models\Post;
|
|
|
|
class PostController extends Controller
|
|
{
|
|
public function __construct(private PostContentRenderer $renderer)
|
|
{
|
|
}
|
|
|
|
public function show(string $id, ?string $page = null)
|
|
{
|
|
$post = Post::query()
|
|
->where('id', (int) $id)
|
|
->orWhere('slug', $id)
|
|
->first();
|
|
|
|
abort_unless($post && $post->status === 'published', 404);
|
|
|
|
$this->ensureReadable($post);
|
|
|
|
// sablog 式 /show-{id}-{page}.shtml 的评论分页
|
|
if ($page !== null) {
|
|
\Illuminate\Pagination\Paginator::currentPageResolver(fn () => max(1, (int) $page));
|
|
}
|
|
|
|
// 浏览量由 /track-view 端点统计(页面整页缓存下控制器不执行,避免双计)
|
|
|
|
$comments = $post->comments()
|
|
->where('status', 'published')
|
|
->orderBy('created_at', (int) blog_setting('comment_order', 1) === 1 ? 'asc' : 'desc')
|
|
->paginate(20);
|
|
|
|
$rendered = $this->renderer->renderWithToc($post);
|
|
|
|
return theme_view('show', [
|
|
'post' => $post,
|
|
'comments' => $comments,
|
|
'contentHtml' => $rendered['html'],
|
|
'toc' => $rendered['toc'],
|
|
]);
|
|
}
|
|
|
|
private function ensureReadable(Post $post): void
|
|
{
|
|
if (! $post->read_password) {
|
|
return;
|
|
}
|
|
|
|
$granted = session()->get("post_read_password.{$post->id}") === $post->read_password;
|
|
$isEditor = auth()->check() && (auth()->user()->isAdmin() || auth()->user()->hasRole('editor'));
|
|
|
|
if (! $granted && ! $isEditor) {
|
|
abort(403, '该文章需要访问密码');
|
|
}
|
|
}
|
|
}
|