perf(modal): unify cancellable frontend modal flows
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+124
-262
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* VIP modal + card HTML (zibll pay-vip modal / vip-card parity).
|
||||
* VIP modal view model + card HTML (zibll pay-vip modal / vip-card parity).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -12,32 +12,133 @@ defined('ABSPATH') || exit;
|
||||
trait VipServiceModal {
|
||||
|
||||
/**
|
||||
* Build pay / renew / upgrade modal HTML for a user.
|
||||
* Build the minimal JSON view model consumed by pay-vip.js.
|
||||
*
|
||||
* The catalog, member state, package prices, payment methods, and allowed
|
||||
* actions are all calculated server-side. No payment gateway response or
|
||||
* server-rendered modal HTML is included in this payload.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function render_modal_html(int $user_id, int $prefer_level = 1): string {
|
||||
if ($user_id <= 0) {
|
||||
return '<div class="box-body payvip-modal text-center padding-20">'
|
||||
. esc_html__('请先登录后再开通会员。', 'aksrt')
|
||||
. '</div>';
|
||||
}
|
||||
|
||||
$vip = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_payment_vip_settings()
|
||||
: ['enabled' => false];
|
||||
if (empty($vip['enabled'])) {
|
||||
return '<div class="box-body payvip-modal text-center padding-20">'
|
||||
. esc_html__('会员功能未启用。', 'aksrt')
|
||||
. '</div>';
|
||||
}
|
||||
|
||||
public function get_modal_view_model(int $user_id, int $prefer_level = 1): array {
|
||||
$catalog = $this->get_catalog($user_id);
|
||||
$user_level = (int) ($catalog['user_level'] ?? 0);
|
||||
$vip = $this->get_vip_settings_context();
|
||||
$member = $this->get_vip_member_context($user_id);
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
$prefer_level = max(1, min(2, $prefer_level));
|
||||
|
||||
if ($user_level > 0) {
|
||||
return $this->render_modal_viped($user_id, $catalog, $vip, $prefer_level);
|
||||
$level_view = [];
|
||||
foreach ([1, 2] as $level) {
|
||||
if (empty($levels[$level]['enabled'])) {
|
||||
continue;
|
||||
}
|
||||
$equity = (string) ($levels[$level]['equity'] ?? '');
|
||||
$equity = function_exists('aksrt_format_vip_equity_html')
|
||||
? (string) aksrt_format_vip_equity_html($equity)
|
||||
: wp_kses_post($equity);
|
||||
$level_view[] = [
|
||||
'level' => $level,
|
||||
'name' => (string) ($levels[$level]['name'] ?? ('VIP' . $level)),
|
||||
'desc' => (string) ($levels[$level]['desc'] ?? ''),
|
||||
'equity' => $equity,
|
||||
];
|
||||
}
|
||||
return $this->render_modal_pay($user_id, $catalog, $vip, $prefer_level);
|
||||
|
||||
$package_ids = [];
|
||||
$has_renew = false;
|
||||
$has_upgrade = false;
|
||||
$groups = is_array($catalog['level_packages'] ?? null) ? $catalog['level_packages'] : [];
|
||||
foreach ($groups as $group) {
|
||||
if (!is_array($group)) {
|
||||
continue;
|
||||
}
|
||||
$action = sanitize_key((string) ($group['action'] ?? 'pay'));
|
||||
$has_renew = $has_renew || $action === 'renew';
|
||||
$has_upgrade = $has_upgrade || $action === 'upgrade';
|
||||
foreach ((array) ($group['items'] ?? []) as $item) {
|
||||
if (is_array($item) && (int) ($item['package_id'] ?? 0) > 0) {
|
||||
$package_ids[] = (int) $item['package_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$points_exchange = is_array($catalog['points_exchange'] ?? null) ? $catalog['points_exchange'] : [];
|
||||
$methods = is_array($catalog['payment_methods'] ?? null) ? $catalog['payment_methods'] : [];
|
||||
$no_payment_method = $methods === [];
|
||||
$action_reasons = [
|
||||
'purchase' => $no_payment_method
|
||||
? 'no_payment_method'
|
||||
: ($package_ids === [] ? 'no_package' : ''),
|
||||
'renew' => $no_payment_method
|
||||
? 'no_payment_method'
|
||||
: ($has_renew ? '' : 'not_available'),
|
||||
'upgrade' => $no_payment_method
|
||||
? 'no_payment_method'
|
||||
: ($has_upgrade ? '' : 'not_available'),
|
||||
'points_exchange' => !empty($points_exchange['enabled']) && !empty($points_exchange['packages'])
|
||||
? ''
|
||||
: 'not_available',
|
||||
];
|
||||
|
||||
$member_state = (string) ($member['state'] ?? 'unopened');
|
||||
$member_version = substr(hash('sha256', (string) wp_json_encode([
|
||||
'level' => (int) ($member['level'] ?? 0),
|
||||
'expires' => (int) ($member['expires'] ?? 0),
|
||||
'state' => $member_state,
|
||||
])), 0, 16);
|
||||
$catalog_version = substr(hash('sha256', (string) wp_json_encode([
|
||||
'packages' => $groups,
|
||||
'points' => $points_exchange,
|
||||
'methods' => $methods,
|
||||
'levels' => $level_view,
|
||||
])), 0, 16);
|
||||
|
||||
$user = get_userdata($user_id);
|
||||
$avatar_url = function_exists('get_avatar_url')
|
||||
? (string) get_avatar_url($user_id, ['size' => 42])
|
||||
: '';
|
||||
|
||||
return [
|
||||
'enabled' => !empty($catalog['enabled']),
|
||||
'prefer_level' => $prefer_level,
|
||||
'catalog' => [
|
||||
'desc' => (string) ($catalog['desc'] ?? ''),
|
||||
'help_text' => (string) ($catalog['help_text'] ?? ''),
|
||||
'more' => (string) ($vip['more'] ?? ''),
|
||||
'currency_name' => (string) ($catalog['currency_name'] ?? ''),
|
||||
'level_packages' => $groups,
|
||||
'points_exchange' => $points_exchange,
|
||||
'vip_url' => (string) ($catalog['vip_url'] ?? ''),
|
||||
],
|
||||
'member' => [
|
||||
'id' => $user_id,
|
||||
'name' => $user ? (string) $user->display_name : '',
|
||||
'avatar_url' => $avatar_url,
|
||||
'level' => (int) ($member['level'] ?? 0),
|
||||
'expires' => (int) ($member['expires'] ?? 0),
|
||||
'expires_label' => (string) ($member['expires_label'] ?? ''),
|
||||
'state' => (string) ($member['state'] ?? 'unopened'),
|
||||
'is_permanent' => !empty($member['is_permanent']),
|
||||
'points' => (int) ($catalog['user_points'] ?? 0),
|
||||
'logged_in' => $user_id > 0,
|
||||
],
|
||||
'levels' => $level_view,
|
||||
'payment_methods' => $methods,
|
||||
'allowed_actions' => [
|
||||
'purchase' => $package_ids !== [] && $methods !== [],
|
||||
'renew' => $has_renew && $methods !== [],
|
||||
'upgrade' => $has_upgrade && $methods !== [],
|
||||
'points_exchange' => !empty($points_exchange['enabled']) && !empty($points_exchange['packages']),
|
||||
],
|
||||
'action_reasons' => $action_reasons,
|
||||
'version' => [
|
||||
'schema' => 1,
|
||||
'member' => $member_version,
|
||||
'catalog' => $catalog_version,
|
||||
// Stable revision token; do not use request time and bust short cache.
|
||||
'updated_at' => $member_version . ':' . $catalog_version,
|
||||
'tags' => ['vip', 'orders'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,9 +146,7 @@ trait VipServiceModal {
|
||||
*/
|
||||
public function render_vip_card(int $level, int $user_id = 0): string {
|
||||
$level = max(1, min(2, $level));
|
||||
$vip = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_payment_vip_settings()
|
||||
: [];
|
||||
$vip = $this->get_vip_settings_context();
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
if (empty($levels[$level]['enabled'])) {
|
||||
return '';
|
||||
@@ -78,241 +177,4 @@ trait VipServiceModal {
|
||||
$html .= '</div></div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
private function render_modal_pay(int $user_id, array $catalog, array $vip, int $prefer_level): string {
|
||||
$user = get_userdata($user_id);
|
||||
$name = $user ? $user->display_name : '';
|
||||
$avatar = get_avatar($user_id, 42);
|
||||
$desc = (string) ($vip['desc'] ?? $catalog['desc'] ?? '');
|
||||
$more = (string) ($vip['more'] ?? '');
|
||||
$groups = is_array($catalog['level_packages'] ?? null) ? $catalog['level_packages'] : [];
|
||||
$methods = is_array($catalog['payment_methods'] ?? null) ? $catalog['payment_methods'] : [];
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
|
||||
$active_lv = !empty($levels[$prefer_level]['enabled']) ? $prefer_level : 0;
|
||||
if ($active_lv <= 0) {
|
||||
foreach ([1, 2] as $lv) {
|
||||
if (!empty($levels[$lv]['enabled'])) {
|
||||
$active_lv = $lv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tabs = '';
|
||||
$panes = '';
|
||||
foreach ([1, 2] as $lv) {
|
||||
if (empty($levels[$lv]['enabled'])) {
|
||||
continue;
|
||||
}
|
||||
$is_active = ($lv === $active_lv);
|
||||
$lv_name = (string) ($levels[$lv]['name'] ?? ('VIP' . $lv));
|
||||
$tabs .= '<li class="relative' . ($is_active ? ' active' : '') . '">'
|
||||
. '<a class="aksrt-vip-tab" href="javascript:;" data-vip-tab="tab-payvip-' . $lv . '">'
|
||||
. esc_html($lv_name)
|
||||
. '</a></li>';
|
||||
|
||||
$group_items = [];
|
||||
foreach ($groups as $g) {
|
||||
if ((int) ($g['level'] ?? 0) === $lv) {
|
||||
$group_items = is_array($g['items'] ?? null) ? $g['items'] : [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$products = $this->render_product_radios($group_items);
|
||||
$equity = (string) ($levels[$lv]['equity'] ?? '');
|
||||
$lv_desc = (string) ($levels[$lv]['desc'] ?? '');
|
||||
|
||||
$panes .= '<div class="tab-pane aksrt-vip-pane' . ($is_active ? ' active' : '') . '" id="tab-payvip-' . $lv . '"' . ($is_active ? '' : ' hidden') . '>';
|
||||
$panes .= '<div class="pay-vip-form-row">';
|
||||
$panes .= '<div class="pay-vip-info level-' . $lv . '">';
|
||||
$panes .= '<div class="v-name font-bold">' . esc_html($lv_name) . '</div>';
|
||||
if ($lv_desc !== '') {
|
||||
$panes .= '<div class="muted-2-color em09 mb6">' . esc_html($lv_desc) . '</div>';
|
||||
}
|
||||
if ($equity !== '') {
|
||||
$panes .= function_exists('aksrt_format_vip_equity_html')
|
||||
? aksrt_format_vip_equity_html($equity)
|
||||
: '<div class="v-equity">' . wp_kses_post($equity) . '</div>';
|
||||
}
|
||||
$panes .= '</div><div class="pay-vip-products">';
|
||||
$panes .= $products;
|
||||
$panes .= $this->render_pay_methods($methods);
|
||||
$panes .= '<button type="button" class="but jb-red btn-block padding-lg radius aksrt-vip-submit" data-vip-submit>'
|
||||
. esc_html__('立即开通', 'aksrt') . '</button>';
|
||||
$panes .= '<p class="aksrt-vip-modal-tip muted-2-color em09 mt10" data-aksrt-vip-tip></p>';
|
||||
$panes .= '</div></div></div>';
|
||||
}
|
||||
|
||||
$points = '';
|
||||
if (!empty($catalog['points_exchange']['enabled']) && !empty($catalog['points_exchange']['packages'])) {
|
||||
$points = '<div class="mt10"><a class="but c-green btn-block" href="'
|
||||
. esc_url(function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url('vip') : '#')
|
||||
. '">' . esc_html__('积分兑换会员', 'aksrt') . '</a></div>';
|
||||
}
|
||||
|
||||
$html = '<div class="box-body payvip-modal" data-aksrt-vip-modal>';
|
||||
$html .= '<button type="button" class="aksrt-modal-close" data-aksrt-modal-close aria-label="Close">×</button>';
|
||||
$html .= '<ul class="list-inline user-box flex ac mb10"><li class="avatar-img">' . $avatar . '</li>';
|
||||
$html .= '<li><b class="em12">' . esc_html($name) . '</b>';
|
||||
if ($desc !== '') {
|
||||
$html .= '<div class="muted-2-color em09">' . esc_html($desc) . '</div>';
|
||||
}
|
||||
$html .= '</li></ul>';
|
||||
$html .= '<ul class="flex jsb mt10 mb20 vip-cardminis gutters-5 nav">' . $tabs . '</ul>';
|
||||
$html .= '<div class="tab-content mt10">' . $panes . '</div>';
|
||||
if ($more !== '') {
|
||||
$html .= '<div class="muted-2-color mb10 em09 muted-box padding-10 mini-radius">' . $more . '</div>';
|
||||
}
|
||||
$html .= $points;
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $catalog
|
||||
* @param array<string,mixed> $vip
|
||||
*/
|
||||
private function render_modal_viped(int $user_id, array $catalog, array $vip, int $prefer_level): string {
|
||||
$user = get_userdata($user_id);
|
||||
$name = $user ? $user->display_name : '';
|
||||
$avatar = get_avatar($user_id, 42);
|
||||
$exp_label = (string) ($catalog['user_expires_label'] ?? '');
|
||||
$groups = is_array($catalog['level_packages'] ?? null) ? $catalog['level_packages'] : [];
|
||||
$methods = is_array($catalog['payment_methods'] ?? null) ? $catalog['payment_methods'] : [];
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
$more = (string) ($vip['more'] ?? '');
|
||||
|
||||
$tabs = '';
|
||||
$panes = '';
|
||||
$active_set = false;
|
||||
foreach ($groups as $g) {
|
||||
$lv = (int) ($g['level'] ?? 0);
|
||||
$action = (string) ($g['action'] ?? 'renew');
|
||||
$items = is_array($g['items'] ?? null) ? $g['items'] : [];
|
||||
if ($lv <= 0 || $items === []) {
|
||||
continue;
|
||||
}
|
||||
$is_active = !$active_set;
|
||||
if ($is_active) {
|
||||
$active_set = true;
|
||||
}
|
||||
$lv_name = (string) ($g['name'] ?? ($levels[$lv]['name'] ?? ('VIP' . $lv)));
|
||||
$badge = $action === 'upgrade' ? __('升级', 'aksrt') : __('续费', 'aksrt');
|
||||
$tab_id = 'tab-payvip-' . $lv . '-' . $action;
|
||||
$tabs .= '<li class="relative' . ($is_active ? ' active' : '') . '">'
|
||||
. '<a class="aksrt-vip-tab" href="javascript:;" data-vip-tab="' . esc_attr($tab_id) . '">'
|
||||
. esc_html($badge . $lv_name)
|
||||
. '</a></li>';
|
||||
$products = $this->render_product_radios($items);
|
||||
$equity = (string) ($levels[$lv]['equity'] ?? '');
|
||||
$panes .= '<div class="tab-pane aksrt-vip-pane' . ($is_active ? ' active' : '') . '" id="' . esc_attr($tab_id) . '"' . ($is_active ? '' : ' hidden') . '>';
|
||||
$panes .= '<div class="pay-vip-form-row">';
|
||||
$panes .= '<div class="pay-vip-info level-' . $lv . '">';
|
||||
$panes .= '<div class="v-name font-bold">' . esc_html($lv_name) . '</div>';
|
||||
if ($equity !== '') {
|
||||
$panes .= function_exists('aksrt_format_vip_equity_html')
|
||||
? aksrt_format_vip_equity_html($equity)
|
||||
: '<div class="v-equity">' . wp_kses_post($equity) . '</div>';
|
||||
}
|
||||
$panes .= '</div><div class="pay-vip-products">';
|
||||
$panes .= $products;
|
||||
$panes .= $this->render_pay_methods($methods);
|
||||
$cta = $action === 'upgrade' ? __('立即升级', 'aksrt') : __('立即续费', 'aksrt');
|
||||
$panes .= '<button type="button" class="but jb-red btn-block padding-lg radius aksrt-vip-submit" data-vip-submit>'
|
||||
. esc_html($cta) . '</button>';
|
||||
$panes .= '<p class="aksrt-vip-modal-tip muted-2-color em09 mt10" data-aksrt-vip-tip></p>';
|
||||
$panes .= '</div></div></div>';
|
||||
}
|
||||
|
||||
if ($tabs === '') {
|
||||
return '<div class="box-body payvip-modal text-center padding-20">'
|
||||
. esc_html__('当前没有可续费或升级的套餐。', 'aksrt')
|
||||
. '</div>';
|
||||
}
|
||||
|
||||
$html = '<div class="box-body payvip-modal" data-aksrt-vip-modal>';
|
||||
$html .= '<button type="button" class="aksrt-modal-close" data-aksrt-modal-close aria-label="Close">×</button>';
|
||||
$html .= '<ul class="list-inline user-box flex ac mb10"><li class="avatar-img">' . $avatar . '</li>';
|
||||
$html .= '<li><b class="em12">' . esc_html($name) . '</b>';
|
||||
$html .= '<div class="muted-2-color em09"><span class="badg c-yellow vip-expdate-tag">'
|
||||
. esc_html($exp_label) . '</span></div></li></ul>';
|
||||
$html .= '<ul class="flex jsb mt10 mb20 vip-cardminis gutters-5 nav">' . $tabs . '</ul>';
|
||||
$html .= '<div class="tab-content mt10">' . $panes . '</div>';
|
||||
if ($more !== '') {
|
||||
$html .= '<div class="muted-2-color mb10 em09 muted-box padding-10 mini-radius">' . $more . '</div>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int,array<string,mixed>> $items
|
||||
*/
|
||||
private function render_product_radios(array $items): string {
|
||||
if ($items === []) {
|
||||
return '<div class="muted-2-color text-center padding-10">'
|
||||
. esc_html__('暂无可用套餐', 'aksrt') . '</div>';
|
||||
}
|
||||
$html = '<div class="mb10 label-box charge-box aksrt-vip-products">';
|
||||
$i = 0;
|
||||
foreach ($items as $item) {
|
||||
$pid = (int) ($item['package_id'] ?? 0);
|
||||
if ($pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$i++;
|
||||
$price = (string) ($item['price_label'] ?? '');
|
||||
$show = (string) ($item['show_price_label'] ?? '');
|
||||
$tag = (string) ($item['discount_tag'] ?? '');
|
||||
$time = (string) ($item['days_label'] ?? '');
|
||||
$title = (string) ($item['title'] ?? '');
|
||||
$checked = $i === 1 ? ' checked' : '';
|
||||
$html .= '<label class="aksrt-vip-product-label">';
|
||||
$html .= '<input class="hide vip-product-input" type="radio" name="vip_product_id" value="'
|
||||
. esc_attr((string) $pid) . '"' . $checked . '>';
|
||||
$html .= '<div class="zib-widget vip-product relative text-center product-box">';
|
||||
if ($tag !== '') {
|
||||
$html .= '<div class="abs-right vip-tag badg jb-yellow">' . esc_html($tag) . '</div>';
|
||||
}
|
||||
if ($title !== '') {
|
||||
$html .= '<div class="em09 mb3">' . esc_html($title) . '</div>';
|
||||
}
|
||||
$html .= '<div class="flex abl gap6 jc"><div class="product-price c-red">' . esc_html($price) . '</div>';
|
||||
if ($show !== '') {
|
||||
$html .= '<div class="original-price relative muted-2-color"><s>' . esc_html($show) . '</s></div>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
if ($time !== '') {
|
||||
$html .= '<div class="muted-2-color c-blue em09 p2-10 badg radius">' . esc_html($time) . '</div>';
|
||||
}
|
||||
$html .= '</div></label>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int,array{id?:string,name?:string}> $methods
|
||||
*/
|
||||
private function render_pay_methods(array $methods): string {
|
||||
if ($methods === []) {
|
||||
return '<input type="hidden" name="aksrt_vip_pay_method" value="balance" data-aksrt-vip-method-fixed>';
|
||||
}
|
||||
if (count($methods) === 1) {
|
||||
$id = (string) ($methods[0]['id'] ?? 'balance');
|
||||
return '<input type="hidden" name="aksrt_vip_pay_method" value="' . esc_attr($id) . '" data-aksrt-vip-method-fixed>';
|
||||
}
|
||||
$html = '<div class="uc-vip-shop__methods mb10" data-aksrt-vip-methods>';
|
||||
$html .= '<span class="uc-vip-shop__methods-label">' . esc_html__('支付方式', 'aksrt') . '</span>';
|
||||
foreach ($methods as $i => $m) {
|
||||
$mid = (string) ($m['id'] ?? '');
|
||||
$mname = (string) ($m['name'] ?? $mid);
|
||||
$html .= '<label class="uc-vip-shop__method"><input type="radio" name="aksrt_vip_pay_method" value="'
|
||||
. esc_attr($mid) . '"' . ($i === 0 ? ' checked' : '') . '> <span>'
|
||||
. esc_html($mname) . '</span></label>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +534,10 @@ trait VipServicePackages {
|
||||
|
||||
private function format_cash_label(float $amount): string {
|
||||
$symbol = '¥';
|
||||
if (class_exists('\AKSRT\Settings\Settings')) {
|
||||
if (method_exists($this, 'get_paid_display_context')) {
|
||||
$paid = $this->get_paid_display_context();
|
||||
$symbol = (string) ($paid['display']['currency_symbol'] ?? '¥');
|
||||
} elseif (class_exists('\AKSRT\Settings\Settings')) {
|
||||
$paid = \AKSRT\Settings\Settings::get_paid_content_settings();
|
||||
$symbol = (string) ($paid['display']['currency_symbol'] ?? '¥');
|
||||
}
|
||||
|
||||
+186
-132
@@ -9,27 +9,114 @@ defined('ABSPATH') || exit;
|
||||
|
||||
trait VipServicePurchase {
|
||||
|
||||
/** @var array<string,mixed>|null */
|
||||
private $vip_settings_cache = null;
|
||||
|
||||
/** @var array<int,array<string,mixed>> */
|
||||
private $vip_member_cache = [];
|
||||
|
||||
/** @var array<int,array<string,mixed>> */
|
||||
private $vip_catalog_cache = [];
|
||||
|
||||
/** @var array<string,mixed>|null */
|
||||
private $vip_paid_display_cache = null;
|
||||
|
||||
/**
|
||||
* Read payment settings once per request. The cache is kept on the
|
||||
* singleton instance and is never shared between users or requests.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
private function get_vip_settings_context(): array {
|
||||
if (is_array($this->vip_settings_cache)) {
|
||||
return $this->vip_settings_cache;
|
||||
}
|
||||
|
||||
$settings = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_payment_vip_settings()
|
||||
: [];
|
||||
$this->vip_settings_cache = is_array($settings)
|
||||
? $settings
|
||||
: ['enabled' => false, 'levels' => [], 'renew' => [], 'upgrade' => [], 'points_exchange' => []];
|
||||
return $this->vip_settings_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the current member state once per request and user.
|
||||
*
|
||||
* @return array{level:int,expires:int,is_permanent:bool,state:string,expires_label:string}
|
||||
*/
|
||||
private function get_vip_member_context(int $user_id): array {
|
||||
$user_id = max(0, $user_id);
|
||||
if (array_key_exists($user_id, $this->vip_member_cache)) {
|
||||
return $this->vip_member_cache[$user_id];
|
||||
}
|
||||
|
||||
$level = $user_id > 0 && function_exists('aksrt_get_user_vip_level')
|
||||
? (int) aksrt_get_user_vip_level($user_id)
|
||||
: 0;
|
||||
$expires = $user_id > 0 ? (int) get_user_meta($user_id, 'aksrt_vip_expires', true) : 0;
|
||||
$member_state = 'unopened';
|
||||
if ($level > 0) {
|
||||
$member_state = $expires <= 0
|
||||
? 'permanent'
|
||||
: ($expires < time() ? 'expired' : 'active');
|
||||
} elseif ($expires > 0 && $expires < time()) {
|
||||
// aksrt_get_user_vip_level() lazily clears expired levels; retain
|
||||
// the observable expired state for this response without reviving it.
|
||||
$member_state = 'expired';
|
||||
}
|
||||
$state = [
|
||||
'level' => max(0, $level),
|
||||
'expires' => $expires,
|
||||
'is_permanent' => $level > 0 && $expires <= 0,
|
||||
'state' => $member_state,
|
||||
'expires_label' => $member_state === 'expired'
|
||||
? __('已过期', 'aksrt')
|
||||
: $this->format_expires_label($expires, $level),
|
||||
];
|
||||
$this->vip_member_cache[$user_id] = $state;
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache paid-content display settings alongside the VIP request context.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
private function get_paid_display_context(): array {
|
||||
if (is_array($this->vip_paid_display_cache)) {
|
||||
return $this->vip_paid_display_cache;
|
||||
}
|
||||
$settings = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_paid_content_settings()
|
||||
: [];
|
||||
$this->vip_paid_display_cache = is_array($settings) ? $settings : [];
|
||||
return $this->vip_paid_display_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function get_catalog(int $user_id = 0): array {
|
||||
$vip = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_payment_vip_settings()
|
||||
: ['enabled' => false, 'levels' => [], 'renew' => [], 'upgrade' => [], 'points_exchange' => []];
|
||||
$user_id = max(0, $user_id);
|
||||
if (array_key_exists($user_id, $this->vip_catalog_cache)) {
|
||||
return $this->vip_catalog_cache[$user_id];
|
||||
}
|
||||
|
||||
$level = function_exists('aksrt_get_user_vip_level') ? aksrt_get_user_vip_level($user_id) : 0;
|
||||
$expires = $user_id > 0 ? (int) get_user_meta($user_id, 'aksrt_vip_expires', true) : 0;
|
||||
$is_permanent = ($level > 0 && $expires <= 0);
|
||||
$vip = $this->get_vip_settings_context();
|
||||
$member = $this->get_vip_member_context($user_id);
|
||||
$level = (int) $member['level'];
|
||||
$expires = (int) $member['expires'];
|
||||
$is_permanent = !empty($member['is_permanent']);
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
$renew = is_array($vip['renew'] ?? null) ? $vip['renew'] : [];
|
||||
$upgrade = is_array($vip['upgrade'] ?? null) ? $vip['upgrade'] : [];
|
||||
$points_ex = is_array($vip['points_exchange'] ?? null) ? $vip['points_exchange'] : [];
|
||||
$renew_enabled = !isset($renew['enabled']) || !empty($renew['enabled']);
|
||||
$upgrade_enabled = !isset($upgrade['enabled']) || !empty($upgrade['enabled']);
|
||||
$points_enabled = !empty($points_ex['enabled'])
|
||||
&& (!class_exists('\AKSRT\Settings\Settings') || \AKSRT\Settings\Settings::credits_enabled());
|
||||
$credits_enabled = !class_exists('\AKSRT\Settings\Settings') || \AKSRT\Settings\Settings::credits_enabled();
|
||||
$points_enabled = !empty($points_ex['enabled']) && $credits_enabled;
|
||||
|
||||
$level_packages = [];
|
||||
foreach ([1, 2] as $lv) {
|
||||
@@ -141,19 +228,20 @@ trait VipServicePurchase {
|
||||
$methods = $this->available_payment_methods();
|
||||
$currency_name = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_currency_name() : __('积分', 'aksrt');
|
||||
|
||||
return [
|
||||
$catalog = [
|
||||
'enabled' => !empty($vip['enabled']),
|
||||
'desc' => (string) ($vip['desc'] ?? ''),
|
||||
'help_text' => (string) ($vip['help_text'] ?? ''),
|
||||
'user_level' => $level,
|
||||
'user_expires' => $expires,
|
||||
'user_is_permanent' => $is_permanent,
|
||||
'user_expires_label' => $this->format_expires_label($expires, $level),
|
||||
'user_expires_label' => (string) ($member['expires_label'] ?? ''),
|
||||
'user_points' => $points_balance,
|
||||
'wallet_balance' => $wallet_balance,
|
||||
'currency_name' => $currency_name,
|
||||
'renew_enabled' => $renew_enabled,
|
||||
'upgrade_enabled' => $upgrade_enabled,
|
||||
'credits_enabled' => $credits_enabled,
|
||||
'renew_desc' => (string) ($renew['desc'] ?? ''),
|
||||
'upgrade_desc' => (string) ($upgrade['desc'] ?? ''),
|
||||
'level_packages' => $level_packages,
|
||||
@@ -168,6 +256,36 @@ trait VipServicePurchase {
|
||||
: (function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : home_url('/')),
|
||||
'logged_in' => $user_id > 0,
|
||||
];
|
||||
$this->vip_catalog_cache[$user_id] = $catalog;
|
||||
return $catalog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a package in the server-derived catalog.
|
||||
*
|
||||
* The returned group name is request-local metadata used only for the
|
||||
* order subject; price and entitlement data remain server-derived.
|
||||
*
|
||||
* @param array<string,mixed> $catalog
|
||||
* @return array<string,mixed>|null
|
||||
*/
|
||||
private function find_catalog_package(array $catalog, int $package_id): ?array {
|
||||
$groups = is_array($catalog['level_packages'] ?? null) ? $catalog['level_packages'] : [];
|
||||
foreach ($groups as $group) {
|
||||
if (!is_array($group)) {
|
||||
continue;
|
||||
}
|
||||
$group_name = (string) ($group['name'] ?? '');
|
||||
$items = is_array($group['items'] ?? null) ? $group['items'] : [];
|
||||
foreach ($items as $item) {
|
||||
if (!is_array($item) || (int) ($item['package_id'] ?? 0) !== $package_id) {
|
||||
continue;
|
||||
}
|
||||
$item['_level_name'] = $group_name !== '' ? $group_name : ('VIP' . (int) ($item['level'] ?? 1));
|
||||
return $item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,106 +298,36 @@ trait VipServicePurchase {
|
||||
return new \WP_Error('aksrt_need_login', __('请先登录后再开通会员。', 'aksrt'), ['status' => 401]);
|
||||
}
|
||||
|
||||
$decoded = $this->decode_package_id($package_id);
|
||||
if (!$decoded) {
|
||||
return new \WP_Error('aksrt_invalid_package', __('套餐无效', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$level = (int) $decoded['level'];
|
||||
$index = (int) $decoded['index'];
|
||||
|
||||
$vip = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_payment_vip_settings()
|
||||
: ['enabled' => false, 'levels' => [], 'renew' => [], 'upgrade' => []];
|
||||
if (empty($vip['enabled'])) {
|
||||
$catalog = $this->get_catalog($user_id);
|
||||
if (empty($catalog['enabled'])) {
|
||||
return new \WP_Error('aksrt_vip_disabled', __('会员功能未启用', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
if (empty($levels[$level]['enabled'])) {
|
||||
return new \WP_Error('aksrt_vip_level_disabled', __('该会员等级未启用', 'aksrt'), ['status' => 400]);
|
||||
|
||||
$pkg = $this->find_catalog_package($catalog, $package_id);
|
||||
if (!$pkg) {
|
||||
return new \WP_Error('aksrt_invalid_package', __('套餐不存在或当前不可购买', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$user_level = function_exists('aksrt_get_user_vip_level') ? aksrt_get_user_vip_level($user_id) : 0;
|
||||
$expires = (int) get_user_meta($user_id, 'aksrt_vip_expires', true);
|
||||
$is_permanent = ($user_level > 0 && $expires <= 0);
|
||||
$renew = is_array($vip['renew'] ?? null) ? $vip['renew'] : [];
|
||||
$upgrade = is_array($vip['upgrade'] ?? null) ? $vip['upgrade'] : [];
|
||||
$renew_enabled = !isset($renew['enabled']) || !empty($renew['enabled']);
|
||||
$upgrade_enabled = !isset($upgrade['enabled']) || !empty($upgrade['enabled']);
|
||||
|
||||
if ($is_permanent && $level <= $user_level) {
|
||||
return new \WP_Error('aksrt_vip_permanent', __('您已是永久会员,无需续费。', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
if ($user_level > 0 && $level === $user_level && !$renew_enabled) {
|
||||
return new \WP_Error('aksrt_vip_renew_disabled', __('续费功能未开启。', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
if ($user_level > 0 && $level > $user_level && !$upgrade_enabled) {
|
||||
return new \WP_Error('aksrt_vip_upgrade_disabled', __('升级功能未开启。', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
if ($user_level > 0 && $level < $user_level) {
|
||||
return new \WP_Error('aksrt_vip_downgrade', __('不支持降级购买。', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$action = 'pay';
|
||||
if ($user_level > 0 && $level === $user_level) {
|
||||
$action = 'renew';
|
||||
} elseif ($user_level > 0 && $level > $user_level) {
|
||||
$action = 'upgrade';
|
||||
}
|
||||
|
||||
// Dedicated upgrade product:
|
||||
// 901 permanent/fixed, 902 unit remaining days, 903 jump permanent.
|
||||
$upgrade_mode = '';
|
||||
$pkg_time = 0;
|
||||
$pkg_unit = 'day';
|
||||
if (in_array($index, [901, 902, 903], true)) {
|
||||
$upgrade_items = $this->build_upgrade_items($user_id, $expires, $is_permanent, (string) ($upgrade['product'] ?? ''));
|
||||
$match = null;
|
||||
foreach ($upgrade_items as $ui) {
|
||||
if ((int) ($ui['package_id'] ?? 0) === $package_id) {
|
||||
$match = $ui;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$match || $level !== 2) {
|
||||
return new \WP_Error('aksrt_invalid_package', __('升级套餐不存在', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$pkg = [
|
||||
'price' => (float) $match['price'],
|
||||
'days' => (int) $match['days'],
|
||||
'title' => (string) $match['title'],
|
||||
];
|
||||
$amount = round((float) $match['price'], 2);
|
||||
$days = (int) $match['days'];
|
||||
$pkg_time = $days; // unit upgrade keeps days as remaining; jump/permanent use 0
|
||||
$level = (int) ($pkg['level'] ?? 0);
|
||||
$index = (int) ($pkg['index'] ?? 0);
|
||||
$action = sanitize_key((string) ($pkg['action'] ?? 'pay'));
|
||||
$amount = round((float) ($pkg['price'] ?? 0), 2);
|
||||
$base_price = (float) ($pkg['base_price'] ?? $amount);
|
||||
$days = (int) ($pkg['days'] ?? 0);
|
||||
$pkg_time = array_key_exists('time', $pkg) ? (int) $pkg['time'] : $days;
|
||||
$pkg_unit = sanitize_key((string) ($pkg['unit'] ?? 'day'));
|
||||
if (!in_array($pkg_unit, ['day', 'month'], true)) {
|
||||
$pkg_unit = 'day';
|
||||
$base_price = (float) ($match['base_price'] ?? $amount);
|
||||
$discount_tag = (string) ($match['discount_tag'] ?? __('升级专享', 'aksrt'));
|
||||
$upgrade_mode = sanitize_key((string) ($match['upgrade_mode'] ?? ''));
|
||||
$action = 'upgrade';
|
||||
if ($upgrade_mode === 'jump' || $upgrade_mode === 'permanent') {
|
||||
$pkg_time = 0;
|
||||
$days = 0;
|
||||
}
|
||||
} else {
|
||||
$level_cfg = is_array($levels[$level] ?? null) ? $levels[$level] : [];
|
||||
if (isset($level_cfg['product_s']) && empty($level_cfg['product_s'])) {
|
||||
return new \WP_Error('aksrt_vip_product_disabled', __('该等级暂不支持购买', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$packages = $this->parse_level_products((string) ($level_cfg['products_raw'] ?? ''));
|
||||
$pkg = $packages[$index - 1] ?? null;
|
||||
if (!$pkg) {
|
||||
return new \WP_Error('aksrt_invalid_package', __('套餐不存在', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$base_price = (float) $pkg['price'];
|
||||
$days = (int) $pkg['days'];
|
||||
$pkg_time = (int) ($pkg['time'] ?? 0);
|
||||
$pkg_unit = (string) ($pkg['unit'] ?? 'day');
|
||||
$priced = $this->apply_action_price($base_price, $action, $renew, $upgrade, $level, $user_level, $expires, $is_permanent, $days);
|
||||
if ($priced === null) {
|
||||
return new \WP_Error('aksrt_invalid_package', __('当前无法购买该套餐', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$amount = round((float) $priced['price'], 2);
|
||||
$discount_tag = (string) ($priced['tag'] ?? '');
|
||||
}
|
||||
$discount_tag = (string) ($pkg['discount_tag'] ?? '');
|
||||
$upgrade_mode = sanitize_key((string) ($pkg['upgrade_mode'] ?? ''));
|
||||
if (in_array($upgrade_mode, ['jump', 'permanent'], true)) {
|
||||
$pkg_time = 0;
|
||||
$days = 0;
|
||||
}
|
||||
|
||||
if ($level < 1 || $level > 2 || $index < 1 || $action === '') {
|
||||
return new \WP_Error('aksrt_invalid_package', __('套餐无效', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
|
||||
if ($amount <= 0) {
|
||||
@@ -310,6 +358,7 @@ trait VipServicePurchase {
|
||||
'discount_tag' => $discount_tag,
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$expires_at = gmdate('Y-m-d H:i:s', time() + 30 * MINUTE_IN_SECONDS);
|
||||
$order_number = \AKSRT\Payment\OrderRepository::get_instance()->create([
|
||||
'user_id' => $user_id,
|
||||
'product_type' => \AKSRT\Core\DomainModel::ORDER_PRODUCT_VIP,
|
||||
@@ -319,27 +368,36 @@ trait VipServicePurchase {
|
||||
'status' => \AKSRT\Payment\Order::STATUS_PENDING,
|
||||
'payment_method' => $payment_method,
|
||||
'note' => is_string($note) ? $note : '',
|
||||
'expires_at' => gmdate('Y-m-d H:i:s', time() + 30 * MINUTE_IN_SECONDS),
|
||||
'expires_at' => $expires_at,
|
||||
]);
|
||||
if ($order_number === '') {
|
||||
return new \WP_Error('aksrt_order_create_failed', __('创建订单失败', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
|
||||
$order = \AKSRT\Payment\OrderRepository::get_instance()->get($order_number);
|
||||
if (!$order) {
|
||||
return new \WP_Error('aksrt_order_create_failed', __('创建订单失败', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
|
||||
$level_name = (string) ($levels[$level]['name'] ?? ('VIP' . $level));
|
||||
// Build the request-local order context from the same server-derived
|
||||
// package used for validation. PaymentOrchestrator still reloads the
|
||||
// persisted row under its attempt lock before touching the gateway.
|
||||
$level_name = (string) ($pkg['_level_name'] ?? ('VIP' . $level));
|
||||
$action_label = $action === 'renew' ? __('续费', 'aksrt') : ($action === 'upgrade' ? __('升级', 'aksrt') : __('开通', 'aksrt'));
|
||||
$order['subject'] = sprintf(
|
||||
/* translators: 1: action 2: vip name 3: package title */
|
||||
__('%1$s%2$s · %3$s', 'aksrt'),
|
||||
$action_label,
|
||||
$level_name,
|
||||
(string) ($pkg['title'] ?? '')
|
||||
);
|
||||
$order['payment_method'] = $payment_method;
|
||||
$order = [
|
||||
'order_number' => $order_number,
|
||||
'user_id' => $user_id,
|
||||
'product_type' => \AKSRT\Core\DomainModel::ORDER_PRODUCT_VIP,
|
||||
'product_id' => $package_id,
|
||||
'amount' => $amount,
|
||||
'currency' => 'CNY',
|
||||
'status' => \AKSRT\Payment\Order::STATUS_PENDING,
|
||||
'payment_method' => $payment_method,
|
||||
'note' => is_string($note) ? $note : '',
|
||||
'expires_at' => $expires_at,
|
||||
'subject' => sprintf(
|
||||
/* translators: 1: action 2: vip name 3: package title */
|
||||
__('%1$s%2$s · %3$s', 'aksrt'),
|
||||
$action_label,
|
||||
$level_name,
|
||||
(string) ($pkg['title'] ?? '')
|
||||
),
|
||||
];
|
||||
|
||||
if (!class_exists('\AKSRT\Payment\Gateway')) {
|
||||
return new \WP_Error('aksrt_pay_unavailable', __('支付网关不可用', 'aksrt'), ['status' => 500]);
|
||||
@@ -355,6 +413,7 @@ trait VipServicePurchase {
|
||||
|
||||
$payment_result = \AKSRT\Payment\PaymentOrchestrator::pay($resolved['gateway'], $order, [
|
||||
'paid_note' => __('用户完成会员开通支付。', 'aksrt'),
|
||||
'order_context' => $order,
|
||||
]);
|
||||
if (empty($payment_result['success'])) {
|
||||
return new \WP_Error(
|
||||
@@ -568,28 +627,23 @@ trait VipServicePurchase {
|
||||
if (!class_exists('\AKSRT\Credits\Credits')) {
|
||||
return new \WP_Error('aksrt_credits_unavailable', __('积分系统不可用', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
if (class_exists('\AKSRT\Settings\Settings') && !\AKSRT\Settings\Settings::credits_enabled()) {
|
||||
$catalog = $this->get_catalog($user_id);
|
||||
if (array_key_exists('credits_enabled', $catalog) && empty($catalog['credits_enabled'])) {
|
||||
return new \WP_Error('aksrt_credits_disabled', __('积分功能未启用', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$vip = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_payment_vip_settings()
|
||||
: [];
|
||||
$points_ex = is_array($vip['points_exchange'] ?? null) ? $vip['points_exchange'] : [];
|
||||
$points_ex = is_array($catalog['points_exchange'] ?? null) ? $catalog['points_exchange'] : [];
|
||||
if (empty($points_ex['enabled'])) {
|
||||
return new \WP_Error('aksrt_points_exchange_disabled', __('积分兑换会员未启用', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$user_level = function_exists('aksrt_get_user_vip_level') ? aksrt_get_user_vip_level($user_id) : 0;
|
||||
if ($user_level > 0) {
|
||||
if ((int) ($catalog['user_level'] ?? 0) > 0) {
|
||||
return new \WP_Error('aksrt_already_vip', __('您已是会员,无法使用积分兑换。', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
$packages = $this->get_points_exchange_packages($vip, $levels);
|
||||
$match = null;
|
||||
$packages = is_array($points_ex['packages'] ?? null) ? $points_ex['packages'] : [];
|
||||
foreach ($packages as $pkg) {
|
||||
if ((int) ($pkg['package_id'] ?? 0) === $package_id) {
|
||||
if (is_array($pkg) && (int) ($pkg['package_id'] ?? 0) === $package_id) {
|
||||
$match = $pkg;
|
||||
break;
|
||||
}
|
||||
@@ -605,7 +659,7 @@ trait VipServicePurchase {
|
||||
return new \WP_Error('aksrt_invalid_price', __('兑换积分无效', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$balance = \AKSRT\Credits\Credits::balance($user_id);
|
||||
$balance = (int) ($catalog['user_points'] ?? 0);
|
||||
if ($balance < $cost) {
|
||||
return new \WP_Error('aksrt_credits_insufficient', __('积分不足,暂时无法兑换', 'aksrt'), [
|
||||
'status' => 402,
|
||||
|
||||
@@ -59,11 +59,10 @@ trait VipServiceRest {
|
||||
if ($level < 1 || $level > 2) {
|
||||
$level = 1;
|
||||
}
|
||||
$html = $this->render_modal_html($uid, $level);
|
||||
return new \WP_REST_Response([
|
||||
'html' => $html,
|
||||
'user_level' => function_exists('aksrt_get_user_vip_level') ? aksrt_get_user_vip_level($uid) : 0,
|
||||
], 200);
|
||||
return $this->no_store(new \WP_REST_Response([
|
||||
'success' => true,
|
||||
'data' => $this->get_modal_view_model($uid, $level),
|
||||
], 200));
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +89,7 @@ trait VipServiceRest {
|
||||
*/
|
||||
public function rest_catalog(\WP_REST_Request $request) {
|
||||
$uid = get_current_user_id();
|
||||
return new \WP_REST_Response($this->get_catalog($uid), 200);
|
||||
return $this->no_store(new \WP_REST_Response($this->get_catalog($uid), 200));
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +128,7 @@ trait VipServiceRest {
|
||||
['status' => (int) ($result['status'] ?? 400)]
|
||||
);
|
||||
}
|
||||
return new \WP_REST_Response($result, 200);
|
||||
return $this->no_store(new \WP_REST_Response($result, 200));
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +151,15 @@ trait VipServiceRest {
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
return new \WP_REST_Response($result, 200);
|
||||
return $this->no_store(new \WP_REST_Response($result, 200));
|
||||
}
|
||||
|
||||
/**
|
||||
* Private member/catalog payloads must not be stored by intermediaries.
|
||||
*/
|
||||
private function no_store(\WP_REST_Response $response): \WP_REST_Response {
|
||||
$response->header('Cache-Control', 'private, no-store, max-age=0');
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user