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, '该文章需要访问密码'); } } }