Merge pull request 'fix(pay): render paid reading as fragments' (#11) from worktree/fix-posts-pay into main
Reviewed-on: #11
This commit is contained in:
@@ -119,3 +119,117 @@
|
||||
opacity: .85;
|
||||
}
|
||||
|
||||
/* ---- Paid fragment purchase card ---- */
|
||||
.aksrt-paywall {
|
||||
position: relative;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.aksrt-paywall__card {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
padding: 22px 24px;
|
||||
background: linear-gradient(135deg, var(--surface-1, #fff) 0%, var(--surface-2, #f8fafc) 100%);
|
||||
border: 1px solid var(--color-line, #e5e7eb);
|
||||
border-radius: var(--radius-lg, 14px);
|
||||
box-shadow: 0 10px 28px rgba(15, 23, 42, .08);
|
||||
}
|
||||
|
||||
.aksrt-paywall--fragment .aksrt-paywall__card {
|
||||
border-style: dashed;
|
||||
border-color: color-mix(in srgb, var(--color-primary, #f04494) 42%, var(--color-line, #e5e7eb));
|
||||
}
|
||||
|
||||
.aksrt-paywall__icon {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
color: var(--color-primary, #f04494);
|
||||
background: color-mix(in srgb, var(--color-primary, #f04494) 12%, transparent);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.aksrt-paywall__body { min-width: 0; }
|
||||
|
||||
.aksrt-paywall__title {
|
||||
margin: 0 0 4px;
|
||||
color: var(--color-ink, #15171a);
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.aksrt-paywall__desc {
|
||||
margin: 0;
|
||||
color: var(--color-ink-3, #525866);
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.aksrt-paywall__price { margin-top: 8px; }
|
||||
.aksrt-paywall__price-amount { color: var(--color-error, #ef4444); font-size: 20px; font-weight: 700; }
|
||||
.aksrt-paywall__price-member { color: var(--color-primary, #f04494); font-size: 16px; font-weight: 700; }
|
||||
.aksrt-paywall__price-free { color: var(--color-success, #10b981); font-size: 16px; font-weight: 700; }
|
||||
.aksrt-paywall__price-original { margin-left: 8px; color: var(--color-ink-4, #8a8f98); font-size: 13px; text-decoration: line-through; }
|
||||
|
||||
.aksrt-paywall__actions {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.aksrt-paywall__btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 40px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.aksrt-paywall__btn:focus-visible,
|
||||
.aksrt-paywall__login-link:focus-visible {
|
||||
outline: 3px solid color-mix(in srgb, var(--color-primary, #f04494) 35%, transparent);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
.aksrt-paywall__hint,
|
||||
.aksrt-paywall__login-link {
|
||||
margin: 0;
|
||||
color: var(--color-ink-4, #8a8f98);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.aksrt-paywall__login-link { text-decoration: underline; }
|
||||
.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; }
|
||||
|
||||
@media (max-width: 680px) {
|
||||
.aksrt-paywall__card {
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.aksrt-paywall__actions {
|
||||
grid-column: 1 / -1;
|
||||
align-items: stretch;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aksrt-paywall__btn { width: 100%; }
|
||||
}
|
||||
|
||||
@@ -363,6 +363,37 @@
|
||||
background: var(--surface-2, #f8fafc);
|
||||
}
|
||||
|
||||
/* ---- Paid Fragment ---- */
|
||||
|
||||
.aksrt-paid-fragment-block {
|
||||
margin: 16px 0;
|
||||
border: 1px dashed #ec4899;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background: #fff7fb;
|
||||
}
|
||||
|
||||
.aksrt-paid-fragment-block .components-notice {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.aksrt-paid-fragment-block__label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 9px 14px;
|
||||
color: #9d174d;
|
||||
background: #fce7f3;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.aksrt-paid-fragment-block__content {
|
||||
min-height: 72px;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* ── Responsive ── */
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
var el = wp.element.createElement;
|
||||
var Fragment = wp.element.Fragment;
|
||||
var RawHTML = wp.element.RawHTML;
|
||||
var registerBlockTypeRaw = wp.blocks.registerBlockType;
|
||||
var blockEditor = wp.blockEditor || wp.editor || {};
|
||||
var InspectorControls = blockEditor.InspectorControls || null;
|
||||
@@ -28,6 +29,8 @@
|
||||
var TextControl = wp.components.TextControl;
|
||||
var ToggleControl = wp.components.ToggleControl;
|
||||
var RangeControl = wp.components.RangeControl;
|
||||
var Notice = wp.components.Notice;
|
||||
var useSelect = window.wp.data && window.wp.data.useSelect;
|
||||
|
||||
if (!registerBlockTypeRaw || !el) return;
|
||||
|
||||
@@ -750,4 +753,58 @@
|
||||
});
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 9. Paid Fragment Block
|
||||
// ================================================================
|
||||
|
||||
function usePaidReadingConfigured() {
|
||||
if (!useSelect) return true;
|
||||
return useSelect(function (select) {
|
||||
var editor = select('core/editor');
|
||||
if (!editor || !editor.getEditedPostAttribute) return true;
|
||||
|
||||
var meta = editor.getEditedPostAttribute('meta') || {};
|
||||
var pay = meta._aksrt_pay || {};
|
||||
if (pay.pay_type !== 'reading') return false;
|
||||
return pay.pay_modo === 'points'
|
||||
? Number(pay.points_price || 0) > 0
|
||||
: Number(pay.price || 0) > 0;
|
||||
}, []);
|
||||
}
|
||||
|
||||
registerBlockType('aksrt/paid-fragment', {
|
||||
title: '付费可见',
|
||||
icon: 'lock',
|
||||
category: CATEGORY,
|
||||
description: '仅购买文章付费阅读后可见的片段。',
|
||||
attributes: {
|
||||
content: { type: 'string', default: '' },
|
||||
},
|
||||
edit: function (props) {
|
||||
var configured = usePaidReadingConfigured();
|
||||
return h('div', { className: 'aksrt-paid-fragment-block' },
|
||||
!configured && Notice ? h(Notice, { status: 'warning', isDismissible: false },
|
||||
'请在“付费内容设置”中选择“付费阅读”并设置有效价格;未配置时此片段会公开显示。'
|
||||
) : null,
|
||||
h('div', { className: 'aksrt-paid-fragment-block__label' },
|
||||
h('span', { className: 'dashicons dashicons-lock', 'aria-hidden': true }),
|
||||
'付费可见片段'
|
||||
),
|
||||
h(RichText, {
|
||||
tagName: 'div',
|
||||
className: 'aksrt-paid-fragment-block__content',
|
||||
value: props.attributes.content,
|
||||
onChange: function (value) { props.setAttributes({ content: value }); },
|
||||
placeholder: '输入购买后可见的内容…',
|
||||
})
|
||||
);
|
||||
},
|
||||
save: function (props) {
|
||||
// Save a single canonical shortcode so hand-written and block-authored
|
||||
// content use the identical server-side rendering path.
|
||||
var shortcode = '[hidecontent type="payshow"]' + props.attributes.content + '[/hidecontent]';
|
||||
return RawHTML ? h(RawHTML, null, shortcode) : shortcode;
|
||||
},
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
@@ -139,7 +139,7 @@ add_action('enqueue_block_editor_assets', function () {
|
||||
'aksrt-gutenberg-blocks',
|
||||
$base_uri . '/assets/js/gutenberg-blocks.js',
|
||||
// wp-media-utils: MediaUpload for carousel block
|
||||
['wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-hooks', 'wp-media-utils'],
|
||||
['wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-hooks', 'wp-media-utils', 'wp-data'],
|
||||
(string) filemtime($blocks_js),
|
||||
true
|
||||
);
|
||||
|
||||
+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;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,9 @@ if (!function_exists('aksrt_single_build_context')) :
|
||||
$pay_meta = function_exists('aksrt_get_pay_meta') ? aksrt_get_pay_meta($post_id) : ['pay_type' => 'no'];
|
||||
$pay_type = (string) ($pay_meta['pay_type'] ?? 'no');
|
||||
$is_paid_post = function_exists('aksrt_is_paid_post') && aksrt_is_paid_post($post_id);
|
||||
// Pay module: download box OR non-download paid types (reading/gallery/video/vip).
|
||||
$show_pay_box = $has_download || ($is_paid_post && $pay_type !== 'no' && $pay_type !== 'download');
|
||||
// Paid-reading purchase is rendered inline by each payshow shortcode.
|
||||
// Keep the article-level module for download, gallery, video and VIP only.
|
||||
$show_pay_box = $has_download || ($is_paid_post && !in_array($pay_type, ['no', 'download', 'reading'], true));
|
||||
|
||||
$breadcrumbs_html = '';
|
||||
if (!empty($settings['breadcrumbs']) && function_exists('aksrt_breadcrumbs')) {
|
||||
|
||||
@@ -89,6 +89,10 @@ class ResourceMetaBox {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="aksrt-pmb__hint" id="aksrt-pmb-reading-hint" hidden>
|
||||
<?php esc_html_e('付费阅读价格只作用于正文中的“付费可见”片段;未插入片段时,正文保持公开。', 'aksrt'); ?>
|
||||
</p>
|
||||
|
||||
<div class="aksrt-pmb__fields" id="aksrt-pmb-fields" data-disabled="<?php echo $is_paid ? '0' : '1'; ?>">
|
||||
|
||||
<!-- 基础价格 -->
|
||||
@@ -378,6 +382,9 @@ class ResourceMetaBox {
|
||||
var isPaid = t !== 'no';
|
||||
fields.setAttribute('data-disabled', isPaid ? '0' : '1');
|
||||
|
||||
var readingHint = document.getElementById('aksrt-pmb-reading-hint');
|
||||
if (readingHint) readingHint.hidden = t !== 'reading';
|
||||
|
||||
// 根据付费类型显示/隐藏相关字段
|
||||
if (dlFields) dlFields.style.display = (t === 'download') ? '' : 'none';
|
||||
if (galleryFields) galleryFields.style.display = (t === 'gallery') ? '' : 'none';
|
||||
|
||||
@@ -163,10 +163,15 @@ class Setup {
|
||||
'type' => 'string',
|
||||
'enum' => array_keys(DomainModel::pay_type_labels()),
|
||||
],
|
||||
'pay_modo' => ['type' => 'string', 'enum' => ['0', 'points']],
|
||||
'price' => ['type' => 'number'],
|
||||
'points_price' => ['type' => 'integer'],
|
||||
'original_price' => ['type' => 'number'],
|
||||
'vip1_price' => ['type' => 'number'],
|
||||
'vip2_price' => ['type' => 'number'],
|
||||
'vip1_points' => ['type' => 'integer'],
|
||||
'vip2_points' => ['type' => 'integer'],
|
||||
'pay_limit' => ['type' => 'integer', 'enum' => [0, 1, 2]],
|
||||
'version' => ['type' => 'string'],
|
||||
'size' => ['type' => 'string'],
|
||||
'license' => ['type' => 'string'],
|
||||
|
||||
+26
-11
@@ -101,6 +101,17 @@ class Shortcodes {
|
||||
$atts = shortcode_atts(['message' => ''], $atts, 'payshow');
|
||||
$pid = get_the_ID();
|
||||
|
||||
$post = $pid > 0 ? get_post($pid) : null;
|
||||
// Payshow is a paid-reading fragment, not a generic hide mechanism.
|
||||
// Until the post has an active reading price, keep its content public
|
||||
// so authors can compose and publish before completing price setup.
|
||||
if (!($post instanceof \WP_Post)
|
||||
|| !function_exists('aksrt_is_payshow_purchase_enabled')
|
||||
|| !aksrt_is_payshow_purchase_enabled($post)) {
|
||||
return '<div class="aksrt-hidden-content aksrt-hidden-content--unlocked aksrt-hidden-content--payshow">'
|
||||
. do_shortcode($content) . '</div>';
|
||||
}
|
||||
|
||||
$can_view = $this->viewer_can_see_paid_block($pid);
|
||||
|
||||
if ($can_view) {
|
||||
@@ -109,18 +120,22 @@ class Shortcodes {
|
||||
}
|
||||
|
||||
$message = $atts['message'] ?: __('此内容需付费后查看', 'aksrt');
|
||||
$uid = get_current_user_id();
|
||||
$html = '<div class="aksrt-hidden-content aksrt-hidden-content--locked aksrt-hidden-content--payshow">';
|
||||
$html .= '<div class="aksrt-hidden-content__message">';
|
||||
$html .= '<i class="fas fa-lock" aria-hidden="true"></i> ';
|
||||
$html .= '<span>' . esc_html($message) . '</span>';
|
||||
$html .= '</div>';
|
||||
if ($uid <= 0) {
|
||||
$html .= '<a href="' . esc_url(wp_login_url(get_permalink())) . '" class="aksrt-hidden-content__login-btn btn-primary btn-sm">';
|
||||
$html .= esc_html__('登录后购买查看', 'aksrt') . '</a>';
|
||||
if (function_exists('aksrt_get_paywall_html')) {
|
||||
$paywall = aksrt_get_paywall_html($post, true);
|
||||
if ($message !== '') {
|
||||
$paywall = str_replace(
|
||||
'<p class="aksrt-paywall__desc">',
|
||||
'<p class="aksrt-paywall__desc">' . esc_html($message) . ' ',
|
||||
$paywall
|
||||
);
|
||||
}
|
||||
return $paywall;
|
||||
}
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
|
||||
return '<div class="aksrt-hidden-content aksrt-hidden-content--locked aksrt-hidden-content--payshow">'
|
||||
. '<div class="aksrt-hidden-content__message"><i class="fas fa-lock" aria-hidden="true"></i><span>'
|
||||
. esc_html($message)
|
||||
. '</span></div></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user