fix(pay): harden reading/gallery/video paywall unlock after purchase

Gate content filter to main loop, show free_preview teaser, avoid leaking full gallery/video when unpaid, and keep paid media enhance after cashier unlock.
This commit is contained in:
2026-07-14 20:46:52 +08:00
parent 79f8c43970
commit 528dca2d4c
+79 -37
View File
@@ -1113,6 +1113,9 @@ add_action('wp_head', function (): void {
.aksrt-paywall__btn{display:inline-flex;align-items:center;gap:8px} .aksrt-paywall__btn{display:inline-flex;align-items:center;gap:8px}
.aksrt-paywall__hint{font-size:12px;color:var(--color-ink-4,#8A8F98);margin:16px 0 0} .aksrt-paywall__hint{font-size:12px;color:var(--color-ink-4,#8A8F98);margin:16px 0 0}
.aksrt-gallery-locked{filter:blur(8px);pointer-events:none;user-select:none} .aksrt-gallery-locked{filter:blur(8px);pointer-events:none;user-select:none}
.aksrt-paywall-preview{margin:0 0 16px;padding:14px 16px;border-left:3px solid var(--color-primary,#f04494);background:var(--surface-2,#f8fafc);border-radius:0 10px 10px 0;color:var(--color-ink-2,#374151);line-height:1.7}
.aksrt-paywall-preview p:last-child{margin-bottom:0}
.aksrt-paid-gallery__overlay .but,.aksrt-paid-video__placeholder .but{margin-top:10px}
</style> </style>
<?php <?php
}); });
@@ -1150,21 +1153,27 @@ if (!function_exists('aksrt_render_paid_gallery')) {
<div class="swiper-button-next"></div> <div class="swiper-button-next"></div>
</div> </div>
<?php else : ?> <?php else : ?>
<!-- 未付费:模糊预览 + 付费墙 --> <!-- 未付费:仅首图模糊预览,不输出完整图库 URL 列表 -->
<div class="aksrt-paid-gallery__locked"> <div class="aksrt-paid-gallery__locked">
<div class="aksrt-paid-gallery__preview"> <div class="aksrt-paid-gallery__preview">
<img src="<?php echo esc_url($images[0]); ?>" alt="" class="aksrt-gallery-locked"> <img src="<?php echo esc_url((string) $images[0]); ?>" alt="" class="aksrt-gallery-locked" loading="lazy">
</div> </div>
<div class="aksrt-paid-gallery__overlay"> <div class="aksrt-paid-gallery__overlay">
<i class="fas fa-images" aria-hidden="true"></i> <i class="fas fa-images" aria-hidden="true"></i>
<p><?php esc_html_e('付费后即可查看全部图片', 'aksrt'); ?></p> <p><?php
<?php printf(
$price_label = aksrt_get_pay_price_label($post); /* translators: %d: image count */
$currency = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt'); esc_html__('共 %d 张图片,付费后可查看', 'aksrt'),
?> count($images)
<span class="aksrt-paid-gallery__price"> );
<?php echo esc_html($price_label['text']); ?> ?></p>
</span> <?php $price_label = function_exists('aksrt_get_pay_price_label') ? aksrt_get_pay_price_label($post) : ['text' => '']; ?>
<?php if (!empty($price_label['text'])) : ?>
<span class="aksrt-paid-gallery__price"><?php echo esc_html((string) $price_label['text']); ?></span>
<?php endif; ?>
<button type="button" class="but jb-red padding-lg cashier-link" data-aksrt-pay-content="<?php echo esc_attr((string) $post->ID); ?>">
<i class="fa fa-shopping-cart" aria-hidden="true"></i> <?php esc_html_e('立即购买', 'aksrt'); ?>
</button>
</div> </div>
</div> </div>
<?php endif; ?> <?php endif; ?>
@@ -1221,13 +1230,20 @@ if (!function_exists('aksrt_render_paid_video')) {
<?php endif; ?> <?php endif; ?>
</div> </div>
<?php else : ?> <?php else : ?>
<!-- 未付费:锁定预览 --> <!-- 未付费:锁定预览(不输出真实视频地址) -->
<div class="aksrt-paid-video__locked"> <div class="aksrt-paid-video__locked">
<div class="aksrt-paid-video__placeholder"> <div class="aksrt-paid-video__placeholder">
<i class="fas fa-play-circle" aria-hidden="true"></i> <i class="fas fa-play-circle" aria-hidden="true"></i>
<p><?php esc_html_e('付费后即可观看完整视频', 'aksrt'); ?></p> <p><?php esc_html_e('付费后即可观看完整视频', 'aksrt'); ?></p>
<?php $price_label = aksrt_get_pay_price_label($post); ?> <?php $price_label = function_exists('aksrt_get_pay_price_label') ? aksrt_get_pay_price_label($post) : ['text' => '']; ?>
<span class="aksrt-paid-video__price"><?php echo esc_html($price_label['text']); ?></span> <?php if (!empty($price_label['text'])) : ?>
<span class="aksrt-paid-video__price"><?php echo esc_html((string) $price_label['text']); ?></span>
<?php endif; ?>
<p style="margin-top:14px;">
<button type="button" class="but jb-red padding-lg cashier-link" data-aksrt-pay-content="<?php echo esc_attr((string) $post->ID); ?>">
<i class="fa fa-shopping-cart" aria-hidden="true"></i> <?php esc_html_e('立即购买', 'aksrt'); ?>
</button>
</p>
</div> </div>
</div> </div>
<?php endif; ?> <?php endif; ?>
@@ -1244,47 +1260,73 @@ if (!function_exists('aksrt_render_paid_video')) {
// 这些函数供 core-hooks.php 中的 the_content 过滤器调用 // 这些函数供 core-hooks.php 中的 the_content 过滤器调用
if (!function_exists('aksrt_paid_content_filter')) { if (!function_exists('aksrt_paid_content_filter')) {
function aksrt_paid_content_filter(string $content): string { function aksrt_paid_content_filter(string $content): string {
if (is_admin() || !is_singular()) return $content; if (is_admin() || !is_singular() || !in_the_loop() || !is_main_query()) {
return $content;
}
global $post; global $post;
if (!($post instanceof WP_Post)) return $content; if (!($post instanceof WP_Post)) {
if (aksrt_can_access_content($post)) return $content; return $content;
}
if (aksrt_can_access_content($post)) {
return $content;
}
// 图库类型:在内容末尾追加图库轮播
$meta = aksrt_get_pay_meta($post); $meta = aksrt_get_pay_meta($post);
if ($meta['pay_type'] === AKSRT_PAY_TYPE_GALLERY) { $pay_type = (string) ($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO);
return aksrt_get_paywall_html($post) . aksrt_render_paid_gallery($post); if (!in_array($pay_type, [AKSRT_PAY_TYPE_READING, AKSRT_PAY_TYPE_GALLERY, AKSRT_PAY_TYPE_VIDEO], true)) {
return $content;
} }
// 视频类型:在内容末尾追加视频播放器 // free_preview teaser + paywall. Never render full gallery/video media when unpaid.
if ($meta['pay_type'] === AKSRT_PAY_TYPE_VIDEO) { $preview = trim((string) ($meta['free_preview'] ?? ''));
return aksrt_get_paywall_html($post) . aksrt_render_paid_video($post); $out = '';
if ($preview !== '') {
$out .= '<div class="aksrt-paywall-preview">' . wp_kses_post($preview) . '</div>';
}
$out .= aksrt_get_paywall_html($post);
if ($pay_type === AKSRT_PAY_TYPE_GALLERY) {
$out .= aksrt_render_paid_gallery($post);
} elseif ($pay_type === AKSRT_PAY_TYPE_VIDEO) {
$out .= aksrt_render_paid_video($post);
} }
return aksrt_get_paywall_html($post); return $out;
} }
} }
// 已付费的内容增强 // 已付费的内容增强
if (!function_exists('aksrt_paid_content_enhance')) { if (!function_exists('aksrt_paid_content_enhance')) {
function aksrt_paid_content_enhance(string $content): string { function aksrt_paid_content_enhance(string $content): string {
if (is_admin() || !is_singular()) return $content; if (is_admin() || !is_singular() || !in_the_loop() || !is_main_query()) {
return $content;
}
global $post; global $post;
if (!($post instanceof WP_Post)) return $content; if (!($post instanceof WP_Post)) {
return $content;
$meta = aksrt_get_pay_meta($post);
if ($meta['pay_type'] === AKSRT_PAY_TYPE_NO) return $content;
if (!aksrt_has_paid_access($post)) return $content;
// 已付费的图库:追加 Swiper 轮播
if ($meta['pay_type'] === AKSRT_PAY_TYPE_GALLERY) {
$gallery_html = aksrt_render_paid_gallery($post);
if ($gallery_html) $content .= $gallery_html;
} }
// 已付费的视频:追加播放器 $meta = aksrt_get_pay_meta($post);
if ($meta['pay_type'] === AKSRT_PAY_TYPE_VIDEO) { $pay_type = (string) ($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO);
if ($pay_type === AKSRT_PAY_TYPE_NO) {
return $content;
}
if (!aksrt_has_paid_access($post)) {
return $content;
}
if ($pay_type === AKSRT_PAY_TYPE_GALLERY && strpos($content, 'aksrt-paid-gallery') === false) {
$gallery_html = aksrt_render_paid_gallery($post);
if ($gallery_html) {
$content .= $gallery_html;
}
}
if ($pay_type === AKSRT_PAY_TYPE_VIDEO && strpos($content, 'aksrt-paid-video') === false) {
$video_html = aksrt_render_paid_video($post); $video_html = aksrt_render_paid_video($post);
if ($video_html) $content .= $video_html; if ($video_html) {
$content .= $video_html;
}
} }
return $content; return $content;