Split related style/source settings, add subtitle/meta/allow-view helpers, align cover/author/tags/pay shell markup and CSS with Zibll single.
684 lines
29 KiB
PHP
684 lines
29 KiB
PHP
<?php
|
||
/**
|
||
* AKSRT Pay System — 统一付费内容系统(1:1 对齐 zibll)
|
||
*
|
||
* 核心机制:
|
||
* - 任何 post 通过 _aksrt_pay meta 成为付费文章
|
||
* - pay_type 驱动行为(no/reading/download/gallery/video/vip)
|
||
* - 统一的价格、VIP 价、下载源、属性、图库、视频管理
|
||
*
|
||
* @package AKSRT
|
||
*/
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
// ============================================================
|
||
// 付费类型常量
|
||
// ============================================================
|
||
|
||
if (!defined('AKSRT_PAY_TYPE_NO')) {
|
||
define('AKSRT_PAY_TYPE_NO', AKSRT_Domain_Model::PAY_TYPE_NO);
|
||
}
|
||
if (!defined('AKSRT_PAY_TYPE_READING')) {
|
||
define('AKSRT_PAY_TYPE_READING', AKSRT_Domain_Model::PAY_TYPE_READING);
|
||
}
|
||
if (!defined('AKSRT_PAY_TYPE_DOWNLOAD')) {
|
||
define('AKSRT_PAY_TYPE_DOWNLOAD', AKSRT_Domain_Model::PAY_TYPE_DOWNLOAD);
|
||
}
|
||
if (!defined('AKSRT_PAY_TYPE_GALLERY')) {
|
||
define('AKSRT_PAY_TYPE_GALLERY', AKSRT_Domain_Model::PAY_TYPE_GALLERY);
|
||
}
|
||
if (!defined('AKSRT_PAY_TYPE_VIDEO')) {
|
||
define('AKSRT_PAY_TYPE_VIDEO', AKSRT_Domain_Model::PAY_TYPE_VIDEO);
|
||
}
|
||
if (!defined('AKSRT_PAY_TYPE_VIP')) {
|
||
define('AKSRT_PAY_TYPE_VIP', AKSRT_Domain_Model::PAY_TYPE_VIP);
|
||
}
|
||
|
||
/**
|
||
* 检查用户是否为 VIP 豁免用户(免扣积分下载)。
|
||
*
|
||
* @param int $user_id
|
||
* @return bool
|
||
*/
|
||
if (!function_exists('aksrt_is_vip_exempt')) {
|
||
function aksrt_is_vip_exempt(int $user_id = 0): bool {
|
||
if ($user_id <= 0) {
|
||
$user_id = get_current_user_id();
|
||
}
|
||
if ($user_id <= 0) {
|
||
return false;
|
||
}
|
||
// 优先使用 aksrt_is_download_credit_exempt_user(如果已定义)
|
||
if (function_exists('aksrt_is_download_credit_exempt_user')) {
|
||
return aksrt_is_download_credit_exempt_user($user_id);
|
||
}
|
||
// 回退:直接检查 VIP 角色
|
||
if (function_exists('aksrt_is_vip') && aksrt_is_vip($user_id)) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function aksrt_get_pay_types(): array {
|
||
return AKSRT_Domain_Model::pay_type_labels();
|
||
|
||
return [
|
||
AKSRT_PAY_TYPE_NO => __('不付费', 'aksrt'),
|
||
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'),
|
||
];
|
||
}
|
||
|
||
// ============================================================
|
||
// 元数据读取
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_get_pay_meta')) {
|
||
function aksrt_get_pay_meta($post = null): array {
|
||
$p = get_post($post);
|
||
if (!($p instanceof WP_Post)) return aksrt_default_pay_meta();
|
||
|
||
$meta = get_post_meta($p->ID, AKSRT_Domain_Model::PAY_META_KEY, true);
|
||
if (is_array($meta) && isset($meta['pay_type'])) {
|
||
return wp_parse_args(AKSRT_Domain_Model::sanitize_pay_meta($meta), aksrt_default_pay_meta());
|
||
}
|
||
|
||
return aksrt_default_pay_meta();
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_default_pay_meta')) {
|
||
function aksrt_default_pay_meta(): array {
|
||
return AKSRT_Domain_Model::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' => '',
|
||
];
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_is_downloadable_content')) {
|
||
function aksrt_is_downloadable_content($post = null): bool {
|
||
$p = get_post($post);
|
||
if (!($p instanceof WP_Post)) {
|
||
return false;
|
||
}
|
||
|
||
$meta = aksrt_get_pay_meta($p);
|
||
if (($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO) !== AKSRT_PAY_TYPE_DOWNLOAD) {
|
||
return false;
|
||
}
|
||
|
||
return !empty($meta['downloads']) && is_array($meta['downloads']);
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_get_download_box_meta')) {
|
||
function aksrt_get_download_box_meta($post = null): array {
|
||
$p = get_post($post);
|
||
if (!($p instanceof WP_Post)) {
|
||
return [];
|
||
}
|
||
|
||
if (function_exists('aksrt_get_resource_meta') && function_exists('aksrt_is_resource_post') && aksrt_is_resource_post($p)) {
|
||
$meta = aksrt_get_resource_meta($p);
|
||
$meta['subject_label'] = __('资源', 'aksrt');
|
||
return $meta;
|
||
}
|
||
|
||
$pay_meta = aksrt_get_pay_meta($p);
|
||
$download_count = (int) get_post_meta($p->ID, AKSRT_Domain_Model::RESOURCE_DOWNLOAD_COUNT_KEY, true);
|
||
$view_count = (int) get_post_meta($p->ID, AKSRT_Domain_Model::POST_VIEW_COUNT_KEY, true);
|
||
|
||
return [
|
||
'version' => (string) ($pay_meta['version'] ?? ''),
|
||
'size' => (string) ($pay_meta['size'] ?? ''),
|
||
'price' => (float) ($pay_meta['price'] ?? 0),
|
||
'original_price' => (float) ($pay_meta['original_price'] ?? 0),
|
||
'vip1_price' => (float) ($pay_meta['vip1_price'] ?? 0),
|
||
'vip2_price' => (float) ($pay_meta['vip2_price'] ?? 0),
|
||
'pay_type' => (string) ($pay_meta['pay_type'] ?? AKSRT_PAY_TYPE_NO),
|
||
'license' => (string) ($pay_meta['license'] ?? ''),
|
||
'compat' => (string) ($pay_meta['compat'] ?? ''),
|
||
'demo_url' => (string) ($pay_meta['demo_url'] ?? ''),
|
||
'downloads' => array_values(is_array($pay_meta['downloads'] ?? null) ? $pay_meta['downloads'] : []),
|
||
'download_count' => max(0, $download_count),
|
||
'view_count' => max(0, $view_count),
|
||
'require_login' => !empty($pay_meta['require_login']),
|
||
'require_captcha' => !empty($pay_meta['require_captcha']),
|
||
'subject_label' => __('内容', 'aksrt'),
|
||
];
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 状态判断
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_is_paid_post')) {
|
||
function aksrt_is_paid_post($post = null): bool {
|
||
return aksrt_get_pay_meta($post)['pay_type'] !== AKSRT_PAY_TYPE_NO;
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_is_paid_reading')) {
|
||
function aksrt_is_paid_reading($post = null): bool {
|
||
return aksrt_get_pay_meta($post)['pay_type'] === AKSRT_PAY_TYPE_READING;
|
||
}
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_is_paid_gallery')) {
|
||
function aksrt_is_paid_gallery($post = null): bool {
|
||
return aksrt_get_pay_meta($post)['pay_type'] === AKSRT_PAY_TYPE_GALLERY;
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_is_paid_video')) {
|
||
function aksrt_is_paid_video($post = null): bool {
|
||
return aksrt_get_pay_meta($post)['pay_type'] === AKSRT_PAY_TYPE_VIDEO;
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_is_vip_only')) {
|
||
function aksrt_is_vip_only($post = null): bool {
|
||
return aksrt_get_pay_meta($post)['pay_type'] === AKSRT_PAY_TYPE_VIP;
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 付费状态检查
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_has_paid_access')) {
|
||
function aksrt_has_paid_access($post = null, int $user_id = 0): bool {
|
||
$p = get_post($post);
|
||
if (!($p instanceof WP_Post)) return true;
|
||
|
||
// 单一真相:付费访问由 AKSRT_Content_Visibility(基于订单 + VIP)裁决。
|
||
if (class_exists('AKSRT_Content_Visibility')) {
|
||
$state = AKSRT_Content_Visibility::get_post_access_state($p, $user_id);
|
||
return !empty($state['has_paid_access']);
|
||
}
|
||
|
||
// 兜底:仅在 service 不可用时使用,避免离线环境直接拒绝。
|
||
$meta = aksrt_get_pay_meta($p);
|
||
if ($meta['pay_type'] === AKSRT_PAY_TYPE_NO) return true;
|
||
if ((float) $meta['price'] <= 0 && $meta['pay_type'] !== AKSRT_PAY_TYPE_VIP) return true;
|
||
|
||
$uid = $user_id > 0 ? $user_id : get_current_user_id();
|
||
|
||
if ($uid > 0 && function_exists('aksrt_is_vip_exempt') && aksrt_is_vip_exempt($uid)) return true;
|
||
if ($uid > 0 && get_user_meta($uid, '_aksrt_paid_' . $p->ID, true)) return true;
|
||
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_can_access_content')) {
|
||
function aksrt_can_access_content($post = null): bool {
|
||
$p = get_post($post);
|
||
if (!($p instanceof WP_Post)) return true;
|
||
|
||
if (class_exists('AKSRT_Content_Visibility')) {
|
||
return AKSRT_Content_Visibility::can_view_paid_content($p);
|
||
}
|
||
|
||
$pay_type = aksrt_get_pay_meta($p)['pay_type'];
|
||
if ($pay_type === AKSRT_PAY_TYPE_NO) return true;
|
||
|
||
// 只有 reading/gallery/video 需要隐藏内容
|
||
if (!in_array($pay_type, [AKSRT_PAY_TYPE_READING, AKSRT_PAY_TYPE_GALLERY, AKSRT_PAY_TYPE_VIDEO], true)) {
|
||
return true;
|
||
}
|
||
|
||
return aksrt_has_paid_access($p);
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_can_download')) {
|
||
/**
|
||
* 下载授权门禁 —— 单一合同。
|
||
*
|
||
* 实际判定全部交给 AKSRT_Content_Visibility::can_download_resource()
|
||
* (由 inc/helpers/aksrt-resource.php 的同名 helper 在更早加载时定义)。
|
||
* 此处仅作为该 helper 不可用时的兜底,避免出现第二套下载真相。
|
||
*
|
||
* @param int|WP_Post|null $post
|
||
* @param int $user_id 0 表示当前用户
|
||
* @return true|WP_Error
|
||
*/
|
||
function aksrt_can_download($post = null, int $user_id = 0) {
|
||
if (class_exists('AKSRT_Content_Visibility')) {
|
||
return AKSRT_Content_Visibility::can_download_resource($post, $user_id);
|
||
}
|
||
|
||
$p = get_post($post);
|
||
if (!($p instanceof WP_Post)) {
|
||
return new WP_Error('aksrt_invalid', __('无效内容。', 'aksrt'));
|
||
}
|
||
|
||
$meta = aksrt_get_pay_meta($p);
|
||
if ($meta['pay_type'] !== AKSRT_PAY_TYPE_DOWNLOAD) {
|
||
return new WP_Error('aksrt_not_downloadable', __('该内容不是可下载资源。', 'aksrt'));
|
||
}
|
||
|
||
$paid_settings = class_exists('AKSRT_Settings')
|
||
? AKSRT_Settings::get_paid_content_settings()
|
||
: ['download_login' => true, 'download_credit' => true];
|
||
|
||
$uid = $user_id > 0 ? $user_id : get_current_user_id();
|
||
|
||
if (!empty($paid_settings['download_login']) && $uid <= 0) {
|
||
$login_url = wp_login_url(get_permalink($p));
|
||
return new WP_Error('aksrt_need_login', __('请先登录。', 'aksrt'), ['login_url' => $login_url]);
|
||
}
|
||
|
||
if ($uid > 0 && aksrt_has_paid_access($p, $uid)) return true;
|
||
if ($uid > 0 && function_exists('aksrt_is_vip_exempt') && aksrt_is_vip_exempt($uid)) return true;
|
||
|
||
$cost = aksrt_get_download_cost($p);
|
||
if ($cost > 0 && !empty($paid_settings['download_credit'])) {
|
||
$balance = function_exists('aksrt_user_credits') ? aksrt_user_credits($uid) : 0;
|
||
if ($balance < $cost) {
|
||
return new WP_Error('aksrt_credits_insufficient', __('积分不足。', 'aksrt'), [
|
||
'balance' => $balance,
|
||
'cost' => $cost,
|
||
]);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_get_download_cost')) {
|
||
function aksrt_get_download_cost($post = null): int {
|
||
if (function_exists('aksrt_resource_download_cost')) {
|
||
return (int) aksrt_resource_download_cost($post);
|
||
}
|
||
|
||
$meta = aksrt_get_pay_meta($post);
|
||
return (int) ceil((float) $meta['price']);
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 价格显示
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_get_pay_price_label')) {
|
||
function aksrt_get_pay_price_label($post = null): array {
|
||
$meta = aksrt_get_pay_meta($post);
|
||
$price = (float) $meta['price'];
|
||
$currency = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt');
|
||
|
||
if ($meta['pay_type'] === AKSRT_PAY_TYPE_VIP) {
|
||
return ['text' => __('VIP 专属', 'aksrt'), 'free' => false, 'amount' => 0];
|
||
}
|
||
|
||
if ($price <= 0) {
|
||
return ['text' => __('免费', 'aksrt'), 'free' => true, 'amount' => 0];
|
||
}
|
||
|
||
$amount = aksrt_format_price($price);
|
||
return ['text' => sprintf(__('%s %s', 'aksrt'), $amount, $currency), 'free' => false, 'amount' => $price];
|
||
}
|
||
}
|
||
|
||
if (!function_exists('aksrt_format_price')) {
|
||
function aksrt_format_price(float $price): string {
|
||
if (fmod($price, 1.0) === 0.0) return (string) (int) $price;
|
||
return rtrim(rtrim(number_format($price, 2, '.', ''), '0'), '.');
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 付费类型徽章
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_get_pay_type_badge')) {
|
||
function aksrt_get_pay_type_badge(string $pay_type): string {
|
||
$badges = [
|
||
AKSRT_PAY_TYPE_READING => ['label' => __('付费阅读', 'aksrt'), 'color' => '#EF4444', 'icon' => 'fa-lock'],
|
||
AKSRT_PAY_TYPE_DOWNLOAD => ['label' => __('付费下载', 'aksrt'), 'color' => '#F97316', 'icon' => 'fa-download'],
|
||
AKSRT_PAY_TYPE_GALLERY => ['label' => __('付费图库', 'aksrt'), 'color' => '#10B981', 'icon' => 'fa-images'],
|
||
AKSRT_PAY_TYPE_VIDEO => ['label' => __('付费视频', 'aksrt'), 'color' => '#8B5CF6', 'icon' => 'fa-play-circle'],
|
||
AKSRT_PAY_TYPE_VIP => ['label' => __('VIP 专属', 'aksrt'), 'color' => '#3B82F6', 'icon' => 'fa-crown'],
|
||
];
|
||
|
||
if (!isset($badges[$pay_type])) return '';
|
||
$b = $badges[$pay_type];
|
||
return sprintf(
|
||
'<span class="aksrt-pay-badge" style="background:%s"><i class="fas %s"></i> %s</span>',
|
||
esc_attr($b['color']), esc_attr($b['icon']), esc_html($b['label'])
|
||
);
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 付费墙 HTML
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_get_paywall_html')) {
|
||
function aksrt_get_paywall_html(WP_Post $post): string {
|
||
$meta = aksrt_get_pay_meta($post);
|
||
$pay_type = $meta['pay_type'];
|
||
$price = (float) $meta['price'];
|
||
$currency = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt');
|
||
|
||
$type_labels = [
|
||
AKSRT_PAY_TYPE_READING => ['icon' => 'fa-lock', 'label' => __('付费阅读', 'aksrt'), 'desc' => __('付费后即可查看完整内容', 'aksrt')],
|
||
AKSRT_PAY_TYPE_GALLERY => ['icon' => 'fa-images', '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];
|
||
$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);
|
||
$has_original = $original_price > 0 && $original_price > $price;
|
||
|
||
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); ?>">
|
||
<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>
|
||
<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 ($price > 0) : ?>
|
||
<span class="aksrt-paywall__price-amount"><?php echo esc_html(aksrt_format_price($price) . ' ' . $currency); ?></span>
|
||
<?php if ($has_original) : ?>
|
||
<span class="aksrt-paywall__price-original"><?php echo esc_html(aksrt_format_price($original_price) . ' ' . $currency); ?></span>
|
||
<?php endif; ?>
|
||
<?php else : ?>
|
||
<span class="aksrt-paywall__price-free"><?php esc_html_e('免费', 'aksrt'); ?></span>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php if (!$is_logged_in) : ?>
|
||
<a href="<?php echo esc_url($login_url); ?>" class="but jb-red padding-lg cashier-link aksrt-paywall__btn">
|
||
<i class="fa fa-sign-in" aria-hidden="true"></i> <?php esc_html_e('登录后购买', 'aksrt'); ?>
|
||
</a>
|
||
<?php elseif ($price > 0) : ?>
|
||
<button type="button" class="but 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'), aksrt_format_price($price) . ' ' . $currency); ?>
|
||
</button>
|
||
<?php endif; ?>
|
||
<p class="aksrt-paywall__hint">
|
||
<i class="fas fa-shield-alt"></i> <?php esc_html_e('购买后永久有效,支持重复查看', 'aksrt'); ?>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 付费墙样式注入
|
||
// ============================================================
|
||
|
||
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}
|
||
</style>
|
||
<?php
|
||
});
|
||
|
||
// ============================================================
|
||
// 付费图库轮播(Swiper)
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_render_paid_gallery')) {
|
||
function aksrt_render_paid_gallery(WP_Post $post): string {
|
||
$meta = aksrt_get_pay_meta($post);
|
||
if ($meta['pay_type'] !== AKSRT_PAY_TYPE_GALLERY) return '';
|
||
|
||
$images = $meta['gallery'] ?? [];
|
||
if (empty($images)) return '';
|
||
|
||
$has_access = aksrt_has_paid_access($post);
|
||
$base_uri = get_template_directory_uri();
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="aksrt-paid-gallery" data-post-id="<?php echo esc_attr((string) $post->ID); ?>">
|
||
<?php if ($has_access) : ?>
|
||
<!-- 已付费:Swiper 轮播 -->
|
||
<div class="swiper aksrt-paid-gallery__swiper">
|
||
<div class="swiper-wrapper">
|
||
<?php foreach ($images as $img_url) : ?>
|
||
<div class="swiper-slide">
|
||
<img src="<?php echo esc_url($img_url); ?>" alt="" loading="lazy">
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<div class="swiper-pagination"></div>
|
||
<div class="swiper-button-prev"></div>
|
||
<div class="swiper-button-next"></div>
|
||
</div>
|
||
<?php else : ?>
|
||
<!-- 未付费:模糊预览 + 付费墙 -->
|
||
<div class="aksrt-paid-gallery__locked">
|
||
<div class="aksrt-paid-gallery__preview">
|
||
<img src="<?php echo esc_url($images[0]); ?>" alt="" class="aksrt-gallery-locked">
|
||
</div>
|
||
<div class="aksrt-paid-gallery__overlay">
|
||
<i class="fas fa-images" aria-hidden="true"></i>
|
||
<p><?php esc_html_e('付费后即可查看全部图片', 'aksrt'); ?></p>
|
||
<?php
|
||
$price_label = aksrt_get_pay_price_label($post);
|
||
$currency = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt');
|
||
?>
|
||
<span class="aksrt-paid-gallery__price">
|
||
<?php echo esc_html($price_label['text']); ?>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php if ($has_access) : ?>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css">
|
||
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
new Swiper('.aksrt-paid-gallery__swiper', {
|
||
loop: true,
|
||
pagination: { el: '.swiper-pagination', clickable: true },
|
||
navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev' },
|
||
lazy: true,
|
||
});
|
||
});
|
||
</script>
|
||
<?php endif; ?>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 付费视频播放器
|
||
// ============================================================
|
||
|
||
if (!function_exists('aksrt_render_paid_video')) {
|
||
function aksrt_render_paid_video(WP_Post $post): string {
|
||
$meta = aksrt_get_pay_meta($post);
|
||
if ($meta['pay_type'] !== AKSRT_PAY_TYPE_VIDEO) return '';
|
||
|
||
$video_url = $meta['video_url'] ?? '';
|
||
if (empty($video_url)) return '';
|
||
|
||
$has_access = aksrt_has_paid_access($post);
|
||
|
||
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" style="width:100%;border-radius:var(--radius-lg);">
|
||
<source src="<?php echo esc_url($video_url); ?>">
|
||
<?php esc_html_e('您的浏览器不支持视频播放。', 'aksrt'); ?>
|
||
</video>
|
||
<?php else : ?>
|
||
<div class="aksrt-paid-video__embed">
|
||
<iframe src="<?php echo esc_url($video_url); ?>" frameborder="0" allowfullscreen></iframe>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php else : ?>
|
||
<!-- 未付费:锁定预览 -->
|
||
<div class="aksrt-paid-video__locked">
|
||
<div class="aksrt-paid-video__placeholder">
|
||
<i class="fas fa-play-circle" aria-hidden="true"></i>
|
||
<p><?php esc_html_e('付费后即可观看完整视频', 'aksrt'); ?></p>
|
||
<?php $price_label = aksrt_get_pay_price_label($post); ?>
|
||
<span class="aksrt-paid-video__price"><?php echo esc_html($price_label['text']); ?></span>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 内容过滤钩子(注册在 core-hooks.php)
|
||
// ============================================================
|
||
|
||
// 这些函数供 core-hooks.php 中的 the_content 过滤器调用
|
||
if (!function_exists('aksrt_paid_content_filter')) {
|
||
function aksrt_paid_content_filter(string $content): string {
|
||
if (is_admin() || !is_singular()) return $content;
|
||
global $post;
|
||
if (!($post instanceof WP_Post)) return $content;
|
||
if (aksrt_can_access_content($post)) return $content;
|
||
|
||
// 图库类型:在内容末尾追加图库轮播
|
||
$meta = aksrt_get_pay_meta($post);
|
||
if ($meta['pay_type'] === AKSRT_PAY_TYPE_GALLERY) {
|
||
return aksrt_get_paywall_html($post) . aksrt_render_paid_gallery($post);
|
||
}
|
||
|
||
// 视频类型:在内容末尾追加视频播放器
|
||
if ($meta['pay_type'] === AKSRT_PAY_TYPE_VIDEO) {
|
||
return aksrt_get_paywall_html($post) . aksrt_render_paid_video($post);
|
||
}
|
||
|
||
return aksrt_get_paywall_html($post);
|
||
}
|
||
}
|
||
|
||
// 已付费的内容增强
|
||
if (!function_exists('aksrt_paid_content_enhance')) {
|
||
function aksrt_paid_content_enhance(string $content): string {
|
||
if (is_admin() || !is_singular()) return $content;
|
||
global $post;
|
||
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;
|
||
}
|
||
|
||
// 已付费的视频:追加播放器
|
||
if ($meta['pay_type'] === AKSRT_PAY_TYPE_VIDEO) {
|
||
$video_html = aksrt_render_paid_video($post);
|
||
if ($video_html) $content .= $video_html;
|
||
}
|
||
|
||
return $content;
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 付费图库/视频样式
|
||
// ============================================================
|
||
|
||
add_action('wp_head', function (): void {
|
||
if (is_admin() || !is_singular()) return;
|
||
global $post;
|
||
if (!($post instanceof WP_Post)) return;
|
||
|
||
$meta = aksrt_get_pay_meta($post);
|
||
if (!in_array($meta['pay_type'], [AKSRT_PAY_TYPE_GALLERY, AKSRT_PAY_TYPE_VIDEO], true)) return;
|
||
?>
|
||
<style>
|
||
.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
|
||
});
|