进行了一些小修复
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
!/tests/widget-system/pay-orders-filter-contract.test.cjs
|
||||
!/tests/widget-system/front-submit-editor-contract.test.cjs
|
||||
!/tests/widget-system/comment-smilies-removal-contract.test.cjs
|
||||
!/tests/widget-system/pay-card-contract.test.cjs
|
||||
!/tests/asset-ledger/
|
||||
!/tests/asset-ledger/*.php
|
||||
!/tests/visual/docker-compose.zibll.yml
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/* Canonical Zibll 9.0 paid-content card shell. */
|
||||
.zib-widget.pay-box {
|
||||
clear: both;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background-color: var(--main-bg-color);
|
||||
border-radius: var(--main-radius);
|
||||
box-shadow: 0 0 10px var(--main-shadow);
|
||||
}
|
||||
|
||||
.pay-widget__orb {
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.pay-widget__orb--right {
|
||||
top: -34%;
|
||||
left: 75%;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.pay-widget__orb--left {
|
||||
left: -229px;
|
||||
width: 337px;
|
||||
height: 305px;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.pay-thumb-placeholder {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: rgba(255, 255, 255, .82);
|
||||
background: linear-gradient(135deg, #59616d, #272b31);
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.pay-box .pay-attr {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.pay-box .pay-attr-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.pay-box .muted-2-color + .muted-2-color {
|
||||
margin-left: 10px;
|
||||
}
|
||||
@@ -226,18 +226,6 @@
|
||||
.single-head-cover .cover-meta.single-metabox {
|
||||
display: flex; flex-wrap: wrap; gap: 8px 12px; font-size: 12px; color: var(--color-ink-4);
|
||||
}
|
||||
/* Pay box root — legacy #posts-pay.aksrt-panel.pay-box */
|
||||
#posts-pay.aksrt-panel,
|
||||
#posts-pay.pay-box,
|
||||
.aksrt-single-pay-box {
|
||||
margin: 16px 0 20px;
|
||||
}
|
||||
#posts-pay .aksrt-paywall,
|
||||
.aksrt-single-pay-box .pay-box,
|
||||
.aksrt-single-pay-box .aksrt-paywall {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Cover meta pills + title-h-left */
|
||||
.single-cover-con .article-title.title-h-left,
|
||||
.single-cover .article-title.title-h-left {
|
||||
|
||||
@@ -119,117 +119,5 @@
|
||||
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%; }
|
||||
}
|
||||
|
||||
@@ -125,7 +125,6 @@
|
||||
.aksrt-term-aggregation { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 15px; }.aksrt-term-aggregation__card { padding: 15px; border-radius: var(--aksrt-widget-radius); background: var(--main-bg-color,#fff); box-shadow: 0 0 10px var(--main-shadow,rgba(116,116,116,.08)); }.aksrt-term-aggregation header a { display: flex; justify-content: space-between; }.aksrt-term-aggregation header span { color: var(--muted-color,#8a8c98); font-size: 13px; }.aksrt-term-aggregation ul { display: grid; gap: 10px; margin: 14px 0 0; padding: 0; list-style: none; }.aksrt-term-aggregation li a { display: flex; align-items: center; gap: 10px; }.aksrt-term-aggregation li img { width: 55px; height: 42px; border-radius: 6px; object-fit: cover; }
|
||||
.aksrt-widget-items { position: relative; min-height: 40px; }.aksrt-widget-items.is-loading { opacity: .72; pointer-events: none; }.aksrt-widget-skeleton { height: 180px; border-radius: 10px; background: linear-gradient(90deg,rgba(127,127,127,.08),rgba(127,127,127,.17),rgba(127,127,127,.08)); background-size: 200% 100%; animation: aksrt-shimmer 1.2s infinite; }.aksrt-widget-load-more { display: block; min-width: 120px; margin: 18px auto 0; padding: 9px 18px; border: 0; border-radius: 999px; background: rgba(127,127,127,.12); color: inherit; cursor: pointer; }.aksrt-widget-pagination { display:flex;justify-content:center;gap:6px;margin-top:18px; }.aksrt-widget-pagination button { min-width:34px;height:34px;border:0;border-radius:8px;background:rgba(127,127,127,.1);color:inherit;cursor:pointer; }.aksrt-widget-pagination button[aria-current="page"] { background:var(--focus-color,#ff5473);color:#fff; }@keyframes aksrt-shimmer { to { background-position: -200% 0; } }
|
||||
.aksrt-widget-oneline .swiper-slide { width: min(300px,78vw); }.aksrt-widget-tabs__nav { display: flex; gap: 8px; margin-bottom: 15px; overflow-x: auto; }.aksrt-widget-tabs__nav button { flex: none; padding: 7px 14px; border: 0; border-radius: 999px; background: rgba(127,127,127,.1); color: inherit; cursor: pointer; }.aksrt-widget-tabs__nav button[aria-selected="true"] { background: var(--focus-color,#ff5473); color: #fff; }
|
||||
.aksrt-post-pay { padding: 20px; border-radius: var(--aksrt-widget-radius); text-align: center; }.aksrt-post-pay.is-authorized { background: rgba(34,197,94,.1); }.aksrt-post-pay > i { display: block; margin-bottom: 9px; color: #22c55e; font-size: 30px; }.aksrt-post-pay p { color: var(--muted-color,#8a8c98); }
|
||||
|
||||
.aksrt-pricing-card { position: relative; display: flex; flex-direction: column; padding: 20px; border: 1px solid var(--main-border-color,rgba(127,127,127,.13)); border-radius: var(--main-radius,8px); background: var(--main-bg-color,#fff); box-shadow: 0 0 10px var(--main-shadow,rgba(116,116,116,.08)); }.aksrt-pricing-card.is-featured { border-color: var(--focus-color,#ff5473); }.aksrt-pricing-card__badge { position: absolute; top: 12px; right: 12px; padding: 4px 9px; border-radius: 999px; background: var(--focus-color,#ff5473); color: #fff; font-size: 12px; }.aksrt-pricing-card h3 { margin: 0 0 12px; }.aksrt-pricing-card__price { font-size: 34px; font-weight: 800; }.aksrt-pricing-card p { color: var(--muted-color,#8a8c98); }.aksrt-pricing-card ul { flex: 1; display: grid; gap: 9px; margin: 15px 0 22px; padding: 0; list-style: none; }.aksrt-pricing-card li i { margin-right: 8px; color: #22c55e; }
|
||||
.aksrt-reviews .swiper-slide { width: min(390px,86vw); height: auto; }.aksrt-review-card { height: 100%; padding: 20px; border-radius: var(--main-radius,8px); background: var(--main-bg-color,#fff); box-shadow: 0 0 10px var(--main-shadow,rgba(116,116,116,.08)); }.aksrt-review-card__rating { color: #f6b73c; }.aksrt-review-card blockquote { min-height: 80px; margin: 15px 0; line-height: 1.75; }.aksrt-review-card footer { display: flex; align-items: center; gap: 11px; }.aksrt-review-card__avatar { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }.aksrt-review-card footer span { display: flex; flex-direction: column; }.aksrt-review-card footer small { color: var(--muted-color,#8a8c98); }
|
||||
|
||||
@@ -240,15 +240,10 @@ add_action('init', function () {
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 未付费内容:替换为付费墙。
|
||||
* 未购买的图库/视频正文只保留公开预览;购买卡由 single 模板渲染。
|
||||
*/
|
||||
add_filter('the_content', 'aksrt_paid_content_filter', 20);
|
||||
|
||||
/**
|
||||
* 已付费内容增强:追加图库轮播/视频播放器。
|
||||
*/
|
||||
add_filter('the_content', 'aksrt_paid_content_enhance', 25);
|
||||
|
||||
/**
|
||||
* 付费/资源文章使用统一的 single.php。
|
||||
*/
|
||||
|
||||
+144
-244
@@ -157,25 +157,6 @@ if (!function_exists('aksrt_get_pay_meta')) {
|
||||
if (!function_exists('aksrt_default_pay_meta')) {
|
||||
function aksrt_default_pay_meta(): array {
|
||||
return \AKSRT\Core\DomainModel::default_pay_meta();
|
||||
|
||||
return [
|
||||
'pay_type' => AKSRT_PAY_TYPE_NO,
|
||||
'price' => 0.0,
|
||||
'original_price' => 0.0,
|
||||
'vip1_price' => 0.0,
|
||||
'vip2_price' => 0.0,
|
||||
'version' => '',
|
||||
'size' => '',
|
||||
'license' => '',
|
||||
'compat' => '',
|
||||
'demo_url' => '',
|
||||
'downloads' => [],
|
||||
'require_login' => false,
|
||||
'require_captcha' => false,
|
||||
'attributes' => [],
|
||||
'gallery' => [],
|
||||
'video_url' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1195,101 +1176,127 @@ if (!function_exists('aksrt_get_pay_attributes_html')) {
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_get_paywall_html')) {
|
||||
function aksrt_get_paywall_html(WP_Post $post, bool $is_fragment = false): string {
|
||||
function aksrt_get_paywall_html(WP_Post $post, array $args = []): string {
|
||||
$is_widget = ($args['layout'] ?? 'article') === 'widget';
|
||||
$theme = sanitize_html_class((string) ($args['theme'] ?? 'jb-red')) ?: 'jb-red';
|
||||
$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;
|
||||
$pay_modo = is_array($priced) ? ((($priced['modo'] ?? '0') === 'points') ? 'points' : '0') : ((($meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0');
|
||||
$price = is_array($priced)
|
||||
? ($priced['amount'] ?? ($pay_modo === 'points' ? 0 : '0.00'))
|
||||
: ($pay_modo === 'points' ? (int) ($meta['points_price'] ?? 0) : (string) ($meta['price'] ?? '0.00'));
|
||||
$price_minor = aksrt_asset_price_minor($price, $pay_modo);
|
||||
$vip_level = is_array($priced) ? (int) ($priced['vip_level'] ?? 0) : 0;
|
||||
$currency = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_currency_name() : __('积分', 'aksrt');
|
||||
$cash_symbol = '¥';
|
||||
if (class_exists('\AKSRT\Settings\Settings')) {
|
||||
$paid = \AKSRT\Settings\Settings::get_paid_content_settings();
|
||||
$cash_symbol = (string) ($paid['display']['currency_symbol'] ?? '¥');
|
||||
}
|
||||
$price_text = $pay_modo === 'points'
|
||||
? (aksrt_format_price($price) . ' ' . $currency)
|
||||
: ($cash_symbol . aksrt_format_price($price));
|
||||
$pay_type = (string) ($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO);
|
||||
if ($pay_type === AKSRT_PAY_TYPE_NO) return '';
|
||||
|
||||
$type_labels = [
|
||||
AKSRT_PAY_TYPE_READING => ['icon' => 'fa-lock', 'label' => __('付费阅读', 'aksrt'), 'desc' => __('付费后即可查看完整内容', 'aksrt')],
|
||||
AKSRT_PAY_TYPE_GALLERY => ['icon' => 'fa-image', 'label' => __('付费图库', 'aksrt'), 'desc' => __('付费后即可查看全部图片', 'aksrt')],
|
||||
AKSRT_PAY_TYPE_VIDEO => ['icon' => 'fa-play-circle', 'label' => __('付费视频', 'aksrt'), 'desc' => __('付费后即可观看完整视频', 'aksrt')],
|
||||
];
|
||||
|
||||
$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 = $pay_modo === 'points'
|
||||
? max(0, (int) ($meta['original_price'] ?? 0))
|
||||
: (string) ($meta['original_price'] ?? '0.00');
|
||||
$original_minor = aksrt_asset_price_minor($original_price, $pay_modo);
|
||||
$has_original = $original_minor > 0 && $original_minor > $price_minor;
|
||||
$pay_limit = (int) ($meta['pay_limit'] ?? 0);
|
||||
$priced = aksrt_get_user_pay_price($post);
|
||||
$modo = (string) ($priced['modo'] ?? '0');
|
||||
$amount = $priced['amount'] ?? 0;
|
||||
$amount_minor = aksrt_asset_price_minor($amount, $modo);
|
||||
$price_label = aksrt_get_pay_price_label($post);
|
||||
$price_text = (string) ($price_label['text'] ?? __('免费', 'aksrt'));
|
||||
$pay_limit = (int) ($priced['pay_limit'] ?? ($meta['pay_limit'] ?? 0));
|
||||
$vip_level = (int) ($priced['vip_level'] ?? 0);
|
||||
$member_blocked = $pay_limit > 0 && $vip_level < $pay_limit;
|
||||
$vip_url = function_exists('aksrt_get_user_center_tab_url')
|
||||
? aksrt_get_user_center_tab_url('credits')
|
||||
: (function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : home_url('/'));
|
||||
$type_labels = [
|
||||
AKSRT_PAY_TYPE_READING => __('付费阅读', 'aksrt'),
|
||||
AKSRT_PAY_TYPE_DOWNLOAD => __('付费下载', 'aksrt'),
|
||||
AKSRT_PAY_TYPE_GALLERY => __('付费图库', 'aksrt'),
|
||||
AKSRT_PAY_TYPE_VIDEO => __('付费视频', 'aksrt'),
|
||||
AKSRT_PAY_TYPE_VIP => __('VIP 专属', 'aksrt'),
|
||||
];
|
||||
$type_label = $type_labels[$pay_type] ?? __('付费内容', 'aksrt');
|
||||
$order_types = [
|
||||
AKSRT_PAY_TYPE_READING => 1,
|
||||
AKSRT_PAY_TYPE_DOWNLOAD => 2,
|
||||
AKSRT_PAY_TYPE_GALLERY => 5,
|
||||
AKSRT_PAY_TYPE_VIDEO => 6,
|
||||
AKSRT_PAY_TYPE_VIP => 4,
|
||||
];
|
||||
$order_type = (int) ($order_types[$pay_type] ?? 1);
|
||||
$title = get_the_title($post);
|
||||
$doc = trim((string) ($args['message'] ?? ''));
|
||||
if ($doc === '') {
|
||||
$doc = sprintf(__('此内容为%s,请付费后查看', 'aksrt'), $type_label);
|
||||
}
|
||||
$sales = max(0, (int) ($meta['virtual_sales'] ?? 0));
|
||||
$sales += max(0, (int) get_post_meta($post->ID, \AKSRT\Core\DomainModel::RESOURCE_SALES_VOLUME_KEY, true));
|
||||
$tag = $is_widget
|
||||
? '<badge class="pay-tag abs-center">' . esc_html($type_label) . '</badge>'
|
||||
: '<div class="pay-tag abs-center">' . esc_html($type_label) . '</div>';
|
||||
$block_class = $is_widget ? ' btn-block' : '';
|
||||
$button = '';
|
||||
if (!is_user_logged_in()) {
|
||||
if ($pay_limit <= 0 && $amount_minor > 0 && $modo === '0' && aksrt_allow_guest_content_pay($post)) {
|
||||
$button = '<button type="button" class="but jb-red padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fa-shopping-cart" aria-hidden="true"></i> ' . esc_html__('立即购买', 'aksrt') . '</button>';
|
||||
} else {
|
||||
$button = '<a href="' . esc_url(wp_login_url(get_permalink($post))) . '" class="but jb-blue padding-lg' . $block_class . '"><i class="fa fa-sign-in" aria-hidden="true"></i> ' . esc_html__('登录购买', 'aksrt') . '</a>';
|
||||
}
|
||||
} elseif ($member_blocked) {
|
||||
$vip_url = aksrt_get_user_center_tab_url('vip');
|
||||
$button = '<a href="' . esc_url($vip_url) . '" class="but jb-vip' . max(1, min(2, $pay_limit)) . ' padding-lg' . $block_class . '"><i class="fa fa-certificate" aria-hidden="true"></i> ' . esc_html__('开通会员后可查看', 'aksrt') . '</a>';
|
||||
} elseif ($amount_minor > 0) {
|
||||
$button = '<button type="button" class="but ' . ($modo === 'points' ? 'jb-yellow' : 'jb-red') . ' padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fa-shopping-cart" aria-hidden="true"></i> ' . esc_html__('立即购买', 'aksrt') . '</button>';
|
||||
} else {
|
||||
$button = '<button type="button" class="but jb-blue padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fa-eye" aria-hidden="true"></i> ' . esc_html__('查看内容', 'aksrt') . '</button>';
|
||||
}
|
||||
$price_color = ($price_label['free'] ?? false) ? 'c-green' : ($modo === 'points' ? 'c-yellow' : 'c-red');
|
||||
$price = '<div class="price-box"><div class="' . esc_attr($price_color) . '"><b class="em3x">' . esc_html($price_text) . '</b></div></div>';
|
||||
$vip_items = [];
|
||||
$base_minor = aksrt_asset_price_minor($priced['base'] ?? $amount, $modo);
|
||||
foreach ([1, 2] as $level) {
|
||||
$key = $modo === 'points' ? 'vip' . $level . '_points' : 'vip' . $level . '_price';
|
||||
$value = $meta[$key] ?? 0;
|
||||
$vip_minor = aksrt_asset_price_minor($value, $modo);
|
||||
if ($vip_minor > 0 && ($base_minor <= 0 || $vip_minor < $base_minor)) {
|
||||
$vip_items[] = '<span class="but vip-price"><span class="vip-price-text">' . esc_html(sprintf(__('VIP%d', 'aksrt'), $level)) . '</span><span class="em12 ml3">' . esc_html(aksrt_format_price($value)) . '</span></span>';
|
||||
}
|
||||
}
|
||||
$vip = implode('', $vip_items);
|
||||
if (count($vip_items) > 1) {
|
||||
$vip = '<span class="vip-price-buts but-average inline">' . $vip . '</span>';
|
||||
}
|
||||
$attrs = aksrt_get_pay_attributes_html($post, 'pay-attr');
|
||||
$count = $sales > 0 ? '<badge class="img-badge hot jb-blue px12">' . esc_html(sprintf(__('已售 %s', 'aksrt'), $sales)) . '</badge>' : '';
|
||||
$service = aksrt_get_pay_service_html('muted-2-color');
|
||||
$demo = aksrt_get_demo_link_html($post, 'but jb-yellow padding-lg');
|
||||
$demo_row = $demo !== '' ? '<div class="mt10">' . $demo . '</div>' : '';
|
||||
$discount = $modo === '0' ? aksrt_get_post_rebate_discount($post) : '0.00';
|
||||
$discount_text = aksrt_asset_price_minor($discount, '0') > 0
|
||||
? sprintf(__('推广优惠 %s', 'aksrt'), (string) ($priced['currency'] ?? '¥') . aksrt_format_price($discount))
|
||||
: '';
|
||||
$discount_banner = $discount_text !== '' ? '<div class="text-center padding-6 jb-yellow px12">' . esc_html($discount_text) . '</div>' : '';
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<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="fa <?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">
|
||||
<?php if ($member_blocked) : ?>
|
||||
<span class="aksrt-paywall__price-member"><?php esc_html_e('会员专属', 'aksrt'); ?></span>
|
||||
<?php elseif ($price > 0) : ?>
|
||||
<span class="aksrt-paywall__price-amount"><?php echo esc_html($price_text); ?></span>
|
||||
<?php if ($has_original) : ?>
|
||||
<span class="aksrt-paywall__price-original"><?php echo esc_html(($pay_modo === 'points' ? aksrt_format_price($original_price) . ' ' . $currency : $cash_symbol . aksrt_format_price($original_price))); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<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 fas fa-shopping-cart" aria-hidden="true"></i> <?php printf(esc_html__('游客购买(%s)', 'aksrt'), $price_text); ?>
|
||||
</button>
|
||||
<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 fas fa-sign-in-alt" 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">
|
||||
<i class="fa fas fa-certificate" aria-hidden="true"></i> <?php esc_html_e('开通会员后可查看', 'aksrt'); ?>
|
||||
</a>
|
||||
<?php elseif ($price > 0) : ?>
|
||||
<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 fas fa-shopping-cart" aria-hidden="true"></i> <?php printf(esc_html__('立即购买(%s)', 'aksrt'), $price_text); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<p class="aksrt-paywall__hint">
|
||||
<i class="fa fas fa-shield-alt" aria-hidden="true"></i> <?php esc_html_e('购买后永久有效,支持重复查看', 'aksrt'); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
if ($is_widget && aksrt_has_paid_access($post)) {
|
||||
$view_labels = [
|
||||
AKSRT_PAY_TYPE_DOWNLOAD => '<i class="fa fa-download fa-fw" aria-hidden="true"></i>' . esc_html__('获取下载地址', 'aksrt'),
|
||||
AKSRT_PAY_TYPE_GALLERY => '<i class="fa fa-file-image-o fa-fw" aria-hidden="true"></i>' . esc_html__('查看图片', 'aksrt'),
|
||||
AKSRT_PAY_TYPE_VIDEO => '<i class="fa fa-play-circle fa-fw" aria-hidden="true"></i>' . esc_html__('查看视频', 'aksrt'),
|
||||
];
|
||||
$view_label = $view_labels[$pay_type] ?? '<i class="fa fa-dot-circle-o fa-fw" aria-hidden="true"></i>' . esc_html__('查看内容', 'aksrt');
|
||||
return '<div class="zib-widget pay-box pay-widget paid-box order-type-' . $order_type . '" style="padding:0">' . $tag . '<div class="relative-h ' . esc_attr($theme) . '" style="background-size:120%"><div class="pay-widget__orb pay-widget__orb--right ' . esc_attr($theme) . '"></div><div class="pay-widget__orb pay-widget__orb--left ' . esc_attr($theme) . '"></div><div class="relative box-body"><div class="text-center mt10 box-body"><p><i class="fa fa-shopping-bag fa-3x" aria-hidden="true"></i></p><b class="em14">' . esc_html__('已购买', 'aksrt') . '</b></div></div></div><div class="box-body"><div class="px12 muted-2-color">' . $service . '</div><div class="mt10"><a href="#posts-pay" class="but padding-lg btn-block ' . esc_attr($theme) . '">' . $view_label . '</a></div>' . $demo_row . $attrs . '</div>' . $count . '</div>';
|
||||
}
|
||||
|
||||
if ($is_widget) {
|
||||
return '<div class="zib-widget pay-box pay-widget order-type-' . $order_type . '" style="padding:0">' . $tag . '<div class="relative-h ' . esc_attr($theme) . '" style="background-size:120%"><div class="pay-widget__orb pay-widget__orb--right ' . esc_attr($theme) . '"></div><div class="pay-widget__orb pay-widget__orb--left ' . esc_attr($theme) . '"></div><div class="relative box-body"><div class="text-center mt10">' . $price . '</div></div><div class="relative">' . $vip . '</div></div>' . $discount_banner . '<div class="box-body"><div class="px12 muted-2-color">' . $service . '</div><div class="mt10">' . $button . '</div>' . $demo_row . $attrs . '</div>' . $count . '</div>';
|
||||
}
|
||||
|
||||
$thumb = get_the_post_thumbnail($post, 'medium', ['class' => 'fit-cover', 'alt' => '']);
|
||||
if ($thumb === '') {
|
||||
$thumb = '<div class="pay-thumb-placeholder"><i class="fa fa-lock" aria-hidden="true"></i></div>';
|
||||
}
|
||||
$graphic_actions = '';
|
||||
if ($demo !== '' || $discount_text !== '') {
|
||||
$graphic_actions = '<div class="abs-center text-center left-bottom">';
|
||||
$graphic_actions .= $demo !== '' ? '<div>' . $demo . '</div>' : '';
|
||||
$graphic_actions .= $discount_text !== '' ? '<div class="padding-6 jb-red px12 hidden-xs">' . esc_html($discount_text) . '</div>' : '';
|
||||
$graphic_actions .= '</div>';
|
||||
}
|
||||
$discount_mobile = $discount_text !== '' ? '<div class="visible-xs-block badg c-red px12 mb6">' . esc_html($discount_text) . '</div>' : '';
|
||||
if ($pay_type === AKSRT_PAY_TYPE_GALLERY) {
|
||||
$gallery_count = count((array) ($meta['gallery'] ?? []));
|
||||
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic"><div class="blur-10 absolute">' . $thumb . '</div><div class="absolute graphic-mask" style="opacity:.3"></div><div class="abs-center text-center">' . esc_html(sprintf(__('共%s张图片', 'aksrt'), $gallery_count)) . '<br>' . esc_html__('请付费后查看', 'aksrt') . '</div>' . $graphic_actions . '</div></div>';
|
||||
} elseif ($pay_type === AKSRT_PAY_TYPE_VIDEO) {
|
||||
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic">' . $thumb . '<div class="absolute graphic-mask" style="opacity:.2"></div><div class="abs-center text-center"><i class="fa fa-play-circle-o fa-4x opacity8" aria-hidden="true"></i></div>' . $graphic_actions . '</div></div>';
|
||||
} else {
|
||||
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic">' . $thumb . $graphic_actions . '</div></div>';
|
||||
}
|
||||
$demo_mobile = $demo !== '' ? '<div class="mt10 visible-xs-block">' . $demo . '</div>' : '';
|
||||
return '<div class="zib-widget pay-box order-type-' . $order_type . '" id="posts-pay"><div class="flex pay-flexbox">' . $graphic . '<div class="flex-auto-h flex xx jsb"><dt class="text-ellipsis pay-title">' . esc_html($title) . '</dt><div class="mt6 em09 muted-2-color">' . wp_kses_post($doc) . '</div><div>' . $price . '</div>' . $discount_mobile . ($vip !== '' ? '<div>' . $vip . '</div>' : '') . '<div class="text-right mt10">' . $button . '</div></div></div><div class="px12 muted-2-color mt10 text-right">' . $service . '</div>' . $demo_mobile . $attrs . $tag . $count . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,51 +1312,23 @@ if (!function_exists('aksrt_render_paid_gallery')) {
|
||||
$images = $meta['gallery'] ?? [];
|
||||
if (empty($images)) return '';
|
||||
|
||||
$has_access = aksrt_has_paid_access($post);
|
||||
$base_uri = get_template_directory_uri();
|
||||
if (!aksrt_has_paid_access($post)) return '';
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="aksrt-paid-gallery" data-post-id="<?php echo esc_attr((string) $post->ID); ?>">
|
||||
<?php if ($has_access) : ?>
|
||||
<!-- 已付费:Swiper 轮播 -->
|
||||
<div class="new-swiper aksrt-paid-gallery__swiper" data-loop="true">
|
||||
<div class="swiper-wrapper">
|
||||
<?php foreach ($images as $img_url) : ?>
|
||||
<div class="swiper-slide">
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $img_url, '', aksrt_get_lazy_thumb('lg')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="">
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="swiper-pagination"></div>
|
||||
<div class="swiper-button-prev"></div>
|
||||
<div class="swiper-button-next"></div>
|
||||
<div class="new-swiper aksrt-paid-gallery__swiper" data-loop="true">
|
||||
<div class="swiper-wrapper">
|
||||
<?php foreach ($images as $img_url) : ?>
|
||||
<div class="swiper-slide">
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $img_url, '', aksrt_get_lazy_thumb('lg')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="">
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<!-- 未付费:仅首图模糊预览,不输出完整图库 URL 列表 -->
|
||||
<div class="aksrt-paid-gallery__locked">
|
||||
<div class="aksrt-paid-gallery__preview">
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $images[0], 'aksrt-gallery-locked', aksrt_get_lazy_thumb('lg')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="">
|
||||
</div>
|
||||
<div class="aksrt-paid-gallery__overlay">
|
||||
<i class="fa fas fa-image" aria-hidden="true"></i>
|
||||
<p><?php
|
||||
printf(
|
||||
/* translators: %d: image count */
|
||||
esc_html__('共 %d 张图片,付费后可查看', 'aksrt'),
|
||||
count($images)
|
||||
);
|
||||
?></p>
|
||||
<?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 fas fa-shopping-cart" aria-hidden="true"></i> <?php esc_html_e('立即购买', 'aksrt'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="swiper-pagination"></div>
|
||||
<div class="swiper-button-prev"></div>
|
||||
<div class="swiper-button-next"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
@@ -1369,42 +1348,22 @@ if (!function_exists('aksrt_render_paid_video')) {
|
||||
$video_url = $meta['video_url'] ?? '';
|
||||
if (empty($video_url)) return '';
|
||||
|
||||
$has_access = aksrt_has_paid_access($post);
|
||||
if (!aksrt_has_paid_access($post)) return '';
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="aksrt-paid-video" data-post-id="<?php echo esc_attr((string) $post->ID); ?>">
|
||||
<?php if ($has_access) : ?>
|
||||
<!-- 已付费:视频播放器 -->
|
||||
<div class="aksrt-paid-video__player">
|
||||
<?php if (preg_match('/\.(mp4|webm|ogg)$/i', $video_url)) : ?>
|
||||
<video controls preload="metadata"<?php echo aksrt_is_lazy('lazy_posts_content') ? ' class="lazyload" src="" data-src="' . esc_url($video_url) . '"' : ' src="' . esc_url($video_url) . '"'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> style="width:100%;border-radius:var(--radius-lg);">
|
||||
<?php esc_html_e('您的浏览器不支持视频播放。', 'aksrt'); ?>
|
||||
</video>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-paid-video__embed">
|
||||
<iframe<?php echo aksrt_is_lazy('lazy_posts_content') ? ' class="lazyload" src="" data-src="' . esc_url($video_url) . '"' : ' src="' . esc_url($video_url) . '"'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<!-- 未付费:锁定预览(不输出真实视频地址) -->
|
||||
<div class="aksrt-paid-video__locked">
|
||||
<div class="aksrt-paid-video__placeholder">
|
||||
<i class="fa fas fa-play-circle" aria-hidden="true"></i>
|
||||
<p><?php esc_html_e('付费后即可观看完整视频', 'aksrt'); ?></p>
|
||||
<?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-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 fas fa-shopping-cart" aria-hidden="true"></i> <?php esc_html_e('立即购买', 'aksrt'); ?>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-paid-video__player">
|
||||
<?php if (preg_match('/\.(mp4|webm|ogg)$/i', $video_url)) : ?>
|
||||
<video controls preload="metadata"<?php echo aksrt_is_lazy('lazy_posts_content') ? ' class="lazyload" src="" data-src="' . esc_url($video_url) . '"' : ' src="' . esc_url($video_url) . '"'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> style="width:100%;border-radius:var(--radius-lg);">
|
||||
<?php esc_html_e('您的浏览器不支持视频播放。', 'aksrt'); ?>
|
||||
</video>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-paid-video__embed">
|
||||
<iframe<?php echo aksrt_is_lazy('lazy_posts_content') ? ' class="lazyload" src="" data-src="' . esc_url($video_url) . '"' : ' src="' . esc_url($video_url) . '"'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
@@ -1439,59 +1398,10 @@ if (!function_exists('aksrt_paid_content_filter')) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
// free_preview teaser + paywall. Never render full gallery/video media when unpaid.
|
||||
// Only the configured teaser remains in the article body. The single
|
||||
// template owns the one canonical purchase card for gallery/video.
|
||||
$preview = trim((string) ($meta['free_preview'] ?? ''));
|
||||
$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 $out;
|
||||
}
|
||||
}
|
||||
|
||||
// 已付费的内容增强
|
||||
if (!function_exists('aksrt_paid_content_enhance')) {
|
||||
function aksrt_paid_content_enhance(string $content): string {
|
||||
if (is_admin() || !is_singular() || !in_the_loop() || !is_main_query()) {
|
||||
return $content;
|
||||
}
|
||||
global $post;
|
||||
if (!($post instanceof WP_Post)) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$meta = aksrt_get_pay_meta($post);
|
||||
$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);
|
||||
if ($video_html) {
|
||||
$content .= $video_html;
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
return $preview !== '' ? '<div class="aksrt-paywall-preview">' . wp_kses_post($preview) . '</div>' : '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1511,20 +1421,10 @@ add_action('wp_head', function (): void {
|
||||
.aksrt-paid-gallery{margin:24px 0}
|
||||
.aksrt-paid-gallery__swiper{border-radius:var(--radius-lg);overflow:hidden}
|
||||
.aksrt-paid-gallery__swiper img{width:100%;height:auto;display:block}
|
||||
.aksrt-paid-gallery__locked{position:relative;border-radius:var(--radius-lg);overflow:hidden}
|
||||
.aksrt-paid-gallery__preview img{width:100%;display:block}
|
||||
.aksrt-paid-gallery__overlay{position:absolute;inset:0;background:rgba(0,0,0,.5);display:flex;flex-direction:column;align-items:center;justify-content:center;color:#fff;gap:12px}
|
||||
.aksrt-paid-gallery__overlay i{font-size:48px;opacity:.8}
|
||||
.aksrt-paid-gallery__overlay p{font-size:16px;margin:0}
|
||||
.aksrt-paid-gallery__price{font-size:20px;font-weight:700;background:rgba(255,255,255,.2);padding:6px 16px;border-radius:20px}
|
||||
|
||||
.aksrt-paid-video{margin:24px 0}
|
||||
.aksrt-paid-video__embed{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;border-radius:var(--radius-lg)}
|
||||
.aksrt-paid-video__embed iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:none}
|
||||
.aksrt-paid-video__locked{background:var(--surface-2);border-radius:var(--radius-lg);padding:60px 20px;text-align:center}
|
||||
.aksrt-paid-video__placeholder i{font-size:64px;color:var(--color-ink-4);margin-bottom:16px}
|
||||
.aksrt-paid-video__placeholder p{font-size:16px;color:var(--color-ink-3);margin:0 0 12px}
|
||||
.aksrt-paid-video__price{font-size:20px;font-weight:700;color:var(--color-error)}
|
||||
</style>
|
||||
<?php
|
||||
});
|
||||
|
||||
@@ -753,32 +753,29 @@ if (!function_exists('aksrt_single_render_pay_box')) :
|
||||
}
|
||||
|
||||
$pay_type = (string) ($ctx['pay_type'] ?? 'no');
|
||||
if (!empty($ctx['has_download']) || $pay_type === 'download') {
|
||||
echo '<div class="aksrt-panel pay-box pay-type-download" id="posts-pay">';
|
||||
get_template_part('templates/parts/resource-download-box');
|
||||
echo '</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_get_pay_meta')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$has_access = function_exists('aksrt_has_paid_access') ? aksrt_has_paid_access($post) : false;
|
||||
$paid_class = $has_access ? 'paid-box' : 'pay-box';
|
||||
echo '<div class="aksrt-panel ' . esc_attr($paid_class) . ' pay-type-' . esc_attr($pay_type) . '" id="posts-pay">';
|
||||
if ($has_access) {
|
||||
if ($pay_type === 'gallery' && function_exists('aksrt_render_paid_gallery')) {
|
||||
if ($pay_type === 'download') {
|
||||
get_template_part('templates/parts/resource-download-box');
|
||||
return;
|
||||
}
|
||||
$order_type = $pay_type === 'gallery' ? 5 : ($pay_type === 'video' ? 6 : 4);
|
||||
echo '<div class="zib-widget pay-box paid-box order-type-' . esc_attr((string) $order_type) . '" id="posts-pay">';
|
||||
if ($pay_type === 'gallery') {
|
||||
echo aksrt_render_paid_gallery($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} elseif ($pay_type === 'video' && function_exists('aksrt_render_paid_video')) {
|
||||
} elseif ($pay_type === 'video') {
|
||||
echo aksrt_render_paid_video($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
echo '<div class="box-body"><span class="badg c-green hollow badg-sm mr6">' . esc_html__('已解锁', 'aksrt') . '</span><b>' . esc_html(get_the_title($post)) . '</b></div>';
|
||||
}
|
||||
} elseif (function_exists('aksrt_get_paywall_html')) {
|
||||
echo '</div>';
|
||||
} else {
|
||||
echo aksrt_get_paywall_html($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
|
||||
@@ -69,13 +69,12 @@ if (!function_exists('aksrt_single_build_context')) :
|
||||
}
|
||||
|
||||
$show_cover = !empty($settings['show_cover']) && (string) ($settings['cover_url'] ?? '') !== '';
|
||||
$has_download = function_exists('aksrt_is_downloadable_content') && aksrt_is_downloadable_content($post_id);
|
||||
$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);
|
||||
// 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));
|
||||
$show_pay_box = $is_paid_post && !in_array($pay_type, ['no', 'reading'], true);
|
||||
|
||||
$breadcrumbs_html = '';
|
||||
if (!empty($settings['breadcrumbs']) && function_exists('aksrt_breadcrumbs')) {
|
||||
@@ -136,7 +135,6 @@ if (!function_exists('aksrt_single_build_context')) :
|
||||
'front_content' => (string) ($settings['front_content'] ?? ''),
|
||||
'after_content' => (string) ($settings['after_content'] ?? ''),
|
||||
'content_maxheight' => !empty($settings['maxheight_enabled']) ? max(0, (int) ($settings['maxheight'] ?? 0)) : 0,
|
||||
'has_download' => $has_download,
|
||||
'show_pay_box' => $show_pay_box,
|
||||
'pay_type' => $pay_type,
|
||||
'is_paid_post' => $is_paid_post,
|
||||
|
||||
@@ -197,6 +197,7 @@ trait ScriptsPart1b {
|
||||
'needs_cover' => 'single-post/cover',
|
||||
'needs_related_toc' => 'single-post/related-toc',
|
||||
'has_hidden_content' => 'single-post/hidden-content',
|
||||
'needs_pay_box' => 'pay-box',
|
||||
];
|
||||
$single_feature_handles = [];
|
||||
foreach ($single_features as $requirement => $part) {
|
||||
|
||||
@@ -28,6 +28,7 @@ trait ScriptsPart1c {
|
||||
'has_toc' => false,
|
||||
'has_video' => false,
|
||||
'has_hidden_content' => false,
|
||||
'needs_pay_box' => false,
|
||||
'needs_cover' => false,
|
||||
'needs_navigation' => false,
|
||||
'needs_related_toc' => false,
|
||||
@@ -112,6 +113,7 @@ trait ScriptsPart1c {
|
||||
$requirements['has_toc'] = $is_article && $heading_count >= 2;
|
||||
$requirements['has_video'] = $has_video;
|
||||
$requirements['has_hidden_content'] = $has_hidden_content || $has_yiyan || $has_inserted_content;
|
||||
$requirements['needs_pay_box'] = $is_paid_content_single || (bool) preg_match('/\[(?:payshow|hidecontent)\b|wp:aksrt\/paid-fragment/i', $content);
|
||||
$requirements['needs_cover'] = $is_article && (
|
||||
$show_cover
|
||||
|| !empty($settings['breadcrumbs'])
|
||||
|
||||
+1
-16
@@ -120,22 +120,7 @@ class Shortcodes {
|
||||
}
|
||||
|
||||
$message = $atts['message'] ?: __('此内容需付费后查看', 'aksrt');
|
||||
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;
|
||||
}
|
||||
|
||||
return '<div class="aksrt-hidden-content aksrt-hidden-content--locked aksrt-hidden-content--payshow">'
|
||||
. '<div class="aksrt-hidden-content__message"><i class="fa fas fa-lock" aria-hidden="true"></i><span>'
|
||||
. esc_html($message)
|
||||
. '</span></div></div>';
|
||||
return aksrt_get_paywall_html($post, ['message' => $message]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,9 @@ final class AssetManager {
|
||||
|
||||
public static function enqueue_for(WidgetDefinition $definition): void {
|
||||
self::register();
|
||||
if ($definition->slug() === 'post_pay') {
|
||||
wp_enqueue_style('aksrt-pay-box');
|
||||
}
|
||||
foreach ($definition->assets() as $asset) {
|
||||
self::enqueue_optional($asset);
|
||||
}
|
||||
@@ -50,8 +53,10 @@ final class AssetManager {
|
||||
$root = get_template_directory();
|
||||
$uri = get_template_directory_uri();
|
||||
$css = $root . '/assets/widgets/frontend.css';
|
||||
$pay_css = $root . '/assets/css/frontend/pay-box.css';
|
||||
$js = $root . '/assets/widgets/frontend.js';
|
||||
wp_register_style(self::STYLE_HANDLE, $uri . '/assets/widgets/frontend.css', ['aksrt-public'], is_file($css) ? (string) filemtime($css) : null);
|
||||
wp_register_style('aksrt-pay-box', $uri . '/assets/css/frontend/pay-box.css', ['aksrt-public'], is_file($pay_css) ? (string) filemtime($pay_css) : null);
|
||||
wp_register_script(self::SCRIPT_HANDLE, $uri . '/assets/widgets/frontend.js', ['aksrt-runtime'], is_file($js) ? (string) filemtime($js) : null, true);
|
||||
$third_party = $uri . '/assets/widgets/third-party/';
|
||||
wp_register_script('aksrt-widget-hls', $third_party . 'hls.min.js', [], 'reference-pinned', true);
|
||||
|
||||
@@ -23,9 +23,9 @@ final class FrontendRenderer {
|
||||
}
|
||||
|
||||
AssetManager::enqueue_for($definition);
|
||||
if (in_array($definition->slug(), ['tab_posts', 'slider', 'slider_media_combo', 'icon_cards', 'icon_cover_cards', 'buttons', 'notice'], true)) {
|
||||
if (in_array($definition->slug(), ['post_pay', 'tab_posts', 'slider', 'slider_media_combo', 'icon_cards', 'icon_cover_cards', 'buttons', 'notice'], true)) {
|
||||
echo (string) ($args['before_widget'] ?? '');
|
||||
echo self::reference_title($instance);
|
||||
if ($definition->slug() !== 'post_pay') echo self::reference_title($instance);
|
||||
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo (string) ($args['after_widget'] ?? '');
|
||||
return;
|
||||
|
||||
@@ -145,14 +145,11 @@ final class ContentRenderer {
|
||||
}
|
||||
$meta = aksrt_get_pay_meta($post);
|
||||
if (($meta['pay_type'] ?? 'no') === 'no') {
|
||||
return RendererHelpers::empty_state(__('当前文章未配置付费内容', 'aksrt'));
|
||||
return '';
|
||||
}
|
||||
if (function_exists('aksrt_has_paid_access') && aksrt_has_paid_access($post)) {
|
||||
$html = '<div class="aksrt-post-pay is-authorized ' . esc_attr((string) $instance['theme']) . '"><i class="fa fas fa-check-circle" aria-hidden="true"></i><strong>' . esc_html__('内容已解锁', 'aksrt') . '</strong><p>' . esc_html__('你已拥有当前知识内容的访问权限。', 'aksrt') . '</p>';
|
||||
$html .= function_exists('aksrt_get_pay_attributes_html') ? aksrt_get_pay_attributes_html($post, 'aksrt-post-pay__attrs') : '';
|
||||
$html .= function_exists('aksrt_get_demo_link_html') ? aksrt_get_demo_link_html($post, 'aksrt-widget-button') : '';
|
||||
return $html . '</div>';
|
||||
}
|
||||
return function_exists('aksrt_get_paywall_html') ? aksrt_get_paywall_html($post, true) : RendererHelpers::empty_state(__('请登录或购买后查看', 'aksrt'));
|
||||
return aksrt_get_paywall_html($post, [
|
||||
'layout' => 'widget',
|
||||
'theme' => (string) $instance['theme'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const test = require('node:test');
|
||||
|
||||
const root = path.resolve(__dirname, '..', '..');
|
||||
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
|
||||
|
||||
test('paid article and sidebar widget use the Zibll purchase-card DOM', () => {
|
||||
const pay = read('inc/helpers/aksrt-pay.php');
|
||||
const widget = read('src/WidgetSystem/Renderers/ContentRenderer.php');
|
||||
const shell = read('src/WidgetSystem/FrontendRenderer.php');
|
||||
const single = read('inc/helpers/aksrt-single-render.php');
|
||||
const hooks = read('inc/core-hooks/part-3.php');
|
||||
|
||||
assert.match(pay, /zib-widget pay-box pay-widget/);
|
||||
assert.match(pay, /zib-widget pay-box order-type-/);
|
||||
assert.match(pay, /flex pay-flexbox/);
|
||||
assert.match(pay, /hide-sm pay-thumb/);
|
||||
assert.match(pay, /pay-tag abs-center/);
|
||||
assert.match(pay, /price-box/);
|
||||
assert.match(pay, /vip-price-buts but-average inline/);
|
||||
assert.match(pay, /cashier-link/);
|
||||
assert.match(widget, /'layout' => 'widget'/);
|
||||
assert.match(shell, /\['post_pay', 'tab_posts'/);
|
||||
assert.doesNotMatch(single, /aksrt-panel pay-box pay-type-download/);
|
||||
assert.doesNotMatch(hooks, /aksrt_paid_content_enhance/);
|
||||
});
|
||||
|
||||
test('the purchase card owns one direct stylesheet and no retired paywall path', () => {
|
||||
const pay = read('inc/helpers/aksrt-pay.php');
|
||||
const shortcodes = read('src/Core/Shortcodes.php');
|
||||
const assets = read('src/Core/ScriptsPart1b.php') + read('src/WidgetSystem/AssetManager.php');
|
||||
const hidden = read('assets/css/frontend/single-post/hidden-content.css');
|
||||
const widgets = read('assets/widgets/frontend.css');
|
||||
const css = read('assets/css/frontend/pay-box.css');
|
||||
const publicCss = read('assets/css/main.css');
|
||||
|
||||
assert.match(assets, /assets\/css\/frontend\/pay-box\.css|\'pay-box\'/);
|
||||
assert.match(shortcodes, /return aksrt_get_paywall_html\(\$post, \['message' => \$message\]\);/);
|
||||
assert.match(css, /\.zib-widget\.pay-box/);
|
||||
assert.doesNotMatch(css, /@media/);
|
||||
assert.match(publicCss, /\.pay-box\.pay-widget \.vip-price/);
|
||||
assert.match(publicCss, /\.pay-flexbox\s*\{\s*flex-wrap:\s*wrap;/);
|
||||
|
||||
const retired = pay + hidden + widgets + shortcodes;
|
||||
assert.doesNotMatch(retired, /aksrt-paywall__(?:card|icon|body|title|desc|price|actions|btn|hint|login-link)/);
|
||||
assert.doesNotMatch(retired, /aksrt-post-pay/);
|
||||
assert.doesNotMatch(retired, /str_replace\([\s\S]*aksrt-paywall__desc/);
|
||||
assert.doesNotMatch(pay, /aksrt-paid-(?:gallery|video)__(?:locked|preview|overlay|placeholder|price)/);
|
||||
});
|
||||
Reference in New Issue
Block a user