fix: 已解锁后 [paid] 标签裸露——替换为付费内容块

post.rendered 过滤原只在无权限时替换 [paid];有权限时原始标签直接显示在页面。现在:
- 有权限:替换为 <div class="paid-content"> 付费内容块(带「付费内容」小标签),三套主题补齐样式
- 先去掉 Markdown 转换产生的 <p>[paid]</p> 包裹,避免替换后残留未闭合标签
- 测试:游客与会员均断言不出现裸 [paid]
This commit is contained in:
ak
2026-08-12 17:40:53 +08:00
parent 2089832dc0
commit d7a9135456
5 changed files with 30 additions and 6 deletions
@@ -53,15 +53,24 @@ class ServiceProvider extends PluginServiceProvider
}
}, 10);
// 付费文章:[paid]...[/paid] 无权限访客隐藏为 teaser整篇锁定渲染 paywall
// 付费文章:[paid]...[/paid] —— 无权限访客替换为 teaser有权限替换为付费内容块(避免原始标签裸露在页面)
$manager->addFilter('post.rendered', function (string $html, \App\Models\Post $post) {
$service = app(Services\MembershipService::class);
$user = auth()->user();
if (preg_match('/\[paid\](.*?)\[\/paid\]/s', $html) && ! $service->canReadPaidContent($user, $post)) {
if (preg_match('/\[paid\](.*?)\[\/paid\]/s', $html)) {
// Markdown 转换会给短代码包上 <p>,先去掉,避免替换后残留未闭合标签
$html = preg_replace('/<p>\s*\[(\/?paid)\]\s*<\/p>/i', '[$1]', $html);
$html = preg_replace_callback(
'/\[paid\](.*?)\[\/paid\]/s',
fn () => view('membership.paid-teaser', ['post' => $post])->render(),
function (array $m) use ($service, $user, $post) {
if ($service->canReadPaidContent($user, $post)) {
return '<div class="paid-content"><div class="paid-content-label">付费内容</div>'.trim($m[1]).'</div>';
}
return view('membership.paid-teaser', ['post' => $post])->render();
},
$html
);
}