fix(pay): render paid reading as fragments
This commit is contained in:
1 parent
4cc1f2b2ea
commit
f040a680d6
9 files changed
+316
-65
No files matched your search
+72
-51
@@ -675,6 +675,53 @@ if (!function_exists('aksrt_is_paid_reading')) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the canonical paid-fragment shortcode in a post's raw content.
|
||||
*
|
||||
* The editor writes this exact shortcode format, so this is the single
|
||||
* source of truth for whether a reading price has any protected fragment to
|
||||
* apply to. It deliberately does not inspect rendered content.
|
||||
*/
|
||||
if (!function_exists('aksrt_post_has_payshow_shortcode')) {
|
||||
function aksrt_post_has_payshow_shortcode($post = null): bool {
|
||||
$p = get_post($post);
|
||||
if (!($p instanceof WP_Post)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return preg_match(
|
||||
'/\[hidecontent\b[^\]]*\btype\s*=\s*(?:"payshow"|\'payshow\'|payshow)[^\]]*\]/i',
|
||||
(string) $p->post_content
|
||||
) === 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A paid fragment is active only for an explicitly priced paid-reading post.
|
||||
*
|
||||
* A zero-price reading configuration is intentionally public: authors can
|
||||
* save content before setting a price without accidentally hiding it.
|
||||
*/
|
||||
if (!function_exists('aksrt_is_payshow_purchase_enabled')) {
|
||||
function aksrt_is_payshow_purchase_enabled($post = null): bool {
|
||||
if (!aksrt_post_has_payshow_shortcode($post)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$meta = aksrt_get_pay_meta($post);
|
||||
if (($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO) !== AKSRT_PAY_TYPE_READING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pay_modo = ($meta['pay_modo'] ?? '0') === 'points' ? 'points' : '0';
|
||||
$price = $pay_modo === 'points'
|
||||
? (float) ($meta['points_price'] ?? 0)
|
||||
: (float) ($meta['price'] ?? 0);
|
||||
|
||||
return $price > 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_is_paid_download')) {
|
||||
function aksrt_is_paid_download($post = null): bool {
|
||||
return aksrt_get_pay_meta($post)['pay_type'] === AKSRT_PAY_TYPE_DOWNLOAD;
|
||||
@@ -1093,7 +1140,7 @@ if (!function_exists('aksrt_get_pay_attributes_html')) {
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_get_paywall_html')) {
|
||||
function aksrt_get_paywall_html(WP_Post $post): string {
|
||||
function aksrt_get_paywall_html(WP_Post $post, bool $is_fragment = false): string {
|
||||
$meta = aksrt_get_pay_meta($post);
|
||||
$pay_type = $meta['pay_type'];
|
||||
$priced = function_exists('aksrt_get_user_pay_price') ? aksrt_get_user_pay_price($post) : null;
|
||||
@@ -1117,6 +1164,9 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
||||
];
|
||||
|
||||
$type_info = $type_labels[$pay_type] ?? $type_labels[AKSRT_PAY_TYPE_READING];
|
||||
if ($is_fragment && $pay_type === AKSRT_PAY_TYPE_READING) {
|
||||
$type_info['desc'] = __('付费后即可查看此片段内容', 'aksrt');
|
||||
}
|
||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink($post));
|
||||
$is_logged_in = is_user_logged_in();
|
||||
$original_price = (float) ($meta['original_price'] ?? 0);
|
||||
@@ -1129,13 +1179,12 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="aksrt-paywall" data-post-id="<?php echo esc_attr((string) $post->ID); ?>" data-pay-type="<?php echo esc_attr($pay_type); ?>" data-pay-modo="<?php echo esc_attr($pay_modo); ?>">
|
||||
<div class="aksrt-paywall__overlay">
|
||||
<div class="aksrt-paywall__blur"></div>
|
||||
<div class="aksrt-paywall__card">
|
||||
<div class="aksrt-paywall__icon">
|
||||
<i class="fas <?php echo esc_attr($type_info['icon']); ?>" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="aksrt-paywall<?php echo $is_fragment ? ' aksrt-paywall--fragment' : ''; ?>" data-post-id="<?php echo esc_attr((string) $post->ID); ?>" data-pay-type="<?php echo esc_attr($pay_type); ?>" data-pay-modo="<?php echo esc_attr($pay_modo); ?>">
|
||||
<div class="aksrt-paywall__card" role="group" aria-label="<?php esc_attr_e('付费内容购买', 'aksrt'); ?>">
|
||||
<div class="aksrt-paywall__icon">
|
||||
<i class="fas <?php echo esc_attr($type_info['icon']); ?>" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="aksrt-paywall__body">
|
||||
<h3 class="aksrt-paywall__title"><?php echo esc_html($type_info['label']); ?></h3>
|
||||
<p class="aksrt-paywall__desc"><?php echo esc_html($type_info['desc']); ?></p>
|
||||
<div class="aksrt-paywall__price">
|
||||
@@ -1150,18 +1199,18 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
||||
<span class="aksrt-paywall__price-free"><?php esc_html_e('免费', 'aksrt'); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aksrt-paywall__actions">
|
||||
<?php if (!$is_logged_in) : ?>
|
||||
<?php if ($pay_limit <= 0 && $price > 0 && $pay_modo !== 'points' && function_exists('aksrt_allow_guest_content_pay') && aksrt_allow_guest_content_pay($post)) : ?>
|
||||
<button type="button" class="but <?php echo $pay_modo === 'points' ? 'jb-yellow' : 'jb-red'; ?> padding-lg cashier-link aksrt-paywall__btn" data-aksrt-pay-content="<?php echo esc_attr((string) $post->ID); ?>">
|
||||
<i class="fa fa-shopping-cart" aria-hidden="true"></i> <?php printf(esc_html__('游客购买(%s)', 'aksrt'), $price_text); ?>
|
||||
</button>
|
||||
<p class="aksrt-paywall__hint" style="margin-top:10px;">
|
||||
<a href="<?php echo esc_url($login_url); ?>"><?php esc_html_e('已有账号?登录后购买', 'aksrt'); ?></a>
|
||||
</p>
|
||||
<a href="<?php echo esc_url($login_url); ?>" class="aksrt-paywall__login-link"><?php esc_html_e('已有账号?登录后购买', 'aksrt'); ?></a>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url($login_url); ?>" class="but jb-red padding-lg aksrt-paywall__btn">
|
||||
<i class="fa fa-sign-in" aria-hidden="true"></i> <?php esc_html_e('登录后购买', 'aksrt'); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url($login_url); ?>" class="but jb-red padding-lg aksrt-paywall__btn">
|
||||
<i class="fa fa-sign-in" aria-hidden="true"></i> <?php esc_html_e('登录后购买', 'aksrt'); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php elseif ($member_blocked) : ?>
|
||||
<a href="<?php echo esc_url($vip_url); ?>" class="but jb-vip padding-lg aksrt-paywall__btn">
|
||||
@@ -1173,7 +1222,7 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<p class="aksrt-paywall__hint">
|
||||
<i class="fas fa-shield-alt"></i> <?php esc_html_e('购买后永久有效,支持重复查看', 'aksrt'); ?>
|
||||
<i class="fas fa-shield-alt" aria-hidden="true"></i> <?php esc_html_e('购买后永久有效,支持重复查看', 'aksrt'); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1183,38 +1232,6 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 付费墙样式注入
|
||||
// ============================================================
|
||||
|
||||
add_action('wp_head', function (): void {
|
||||
if (is_admin() || !is_singular()) return;
|
||||
global $post;
|
||||
if (!($post instanceof WP_Post)) return;
|
||||
if (!function_exists('aksrt_can_access_content') || aksrt_can_access_content($post)) return;
|
||||
?>
|
||||
<style>
|
||||
.aksrt-paywall{position:relative;margin:24px 0}
|
||||
.aksrt-paywall__overlay{position:relative}
|
||||
.aksrt-paywall__blur{filter:blur(12px);pointer-events:none;user-select:none;max-height:200px;overflow:hidden;opacity:.3}
|
||||
.aksrt-paywall__card{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--surface-1,#fff);border:1px solid var(--color-line,#e5e7eb);border-radius:var(--radius-lg,14px);padding:40px;text-align:center;box-shadow:0 12px 40px rgba(0,0,0,.12);min-width:320px;max-width:420px}
|
||||
.aksrt-paywall__icon{font-size:48px;color:var(--color-primary,#f04494);margin-bottom:16px}
|
||||
.aksrt-paywall__title{font-size:20px;font-weight:700;margin:0 0 8px;color:var(--color-ink,#15171A)}
|
||||
.aksrt-paywall__desc{font-size:14px;color:var(--color-ink-3,#525866);margin:0 0 20px}
|
||||
.aksrt-paywall__price{margin-bottom:20px}
|
||||
.aksrt-paywall__price-amount{font-size:28px;font-weight:700;color:var(--color-error,#EF4444)}
|
||||
.aksrt-paywall__price-original{font-size:14px;color:var(--color-ink-4,#8A8F98);text-decoration:line-through;margin-left:8px}
|
||||
.aksrt-paywall__price-free{font-size:20px;font-weight:600;color:var(--color-success,#10B981)}
|
||||
.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-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>
|
||||
<?php
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// 付费图库轮播(Swiper)
|
||||
// ============================================================
|
||||
@@ -1362,13 +1379,17 @@ if (!function_exists('aksrt_paid_content_filter')) {
|
||||
if (!($post instanceof WP_Post)) {
|
||||
return $content;
|
||||
}
|
||||
$meta = aksrt_get_pay_meta($post);
|
||||
$pay_type = (string) ($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO);
|
||||
// Reading is protected only by the payshow shortcode. Never replace
|
||||
// the entire article body with a post-level purchase wall.
|
||||
if ($pay_type === AKSRT_PAY_TYPE_READING) {
|
||||
return $content;
|
||||
}
|
||||
if (aksrt_can_access_content($post)) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$meta = aksrt_get_pay_meta($post);
|
||||
$pay_type = (string) ($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO);
|
||||
if (!in_array($pay_type, [AKSRT_PAY_TYPE_READING, AKSRT_PAY_TYPE_GALLERY, AKSRT_PAY_TYPE_VIDEO], true)) {
|
||||
if (!in_array($pay_type, [AKSRT_PAY_TYPE_GALLERY, AKSRT_PAY_TYPE_VIDEO], true)) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user