feat(vip): add default icons and remove download speed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-08-11 17:48:10 +08:00
1 parent 77d54b3b9d
commit 18da39788f
15 files changed
+105 -74

No files matched your search

@@ -21,11 +21,8 @@ export const vipSchema = {
pay_user_vip_desc: '', pay_user_vip_desc: '',
pay_user_vip_more: '', pay_user_vip_more: '',
pay_download_limit: 0, pay_download_limit: 0,
pay_download_speed: 0,
pay_download_limit_vip_1: 0, pay_download_limit_vip_1: 0,
pay_download_speed_vip_1: 0,
pay_download_limit_vip_2: 0, pay_download_limit_vip_2: 0,
pay_download_speed_vip_2: 0,
pay_vip_pass_charge_s: false, pay_vip_pass_charge_s: false,
pay_vip_pass_charge_desc: '', pay_vip_pass_charge_desc: '',
pay_vip_pass_charge_only_password: true, pay_vip_pass_charge_only_password: true,
@@ -51,12 +48,12 @@ export const vipSchema = {
{ key: 'pay_user_vip_1_name', label: '一级会员名称', type: 'input', default: '一级会员', dependsOn: { key: 'pay_user_vip_1_s', value: true } }, { key: 'pay_user_vip_1_name', label: '一级会员名称', type: 'input', default: '一级会员', dependsOn: { key: 'pay_user_vip_1_s', value: true } },
{ key: 'pay_user_vip_1_desc', label: '一级会员一句话简介', type: 'input', default: '尊享一级会员特权', dependsOn: { key: 'pay_user_vip_1_s', value: true } }, { key: 'pay_user_vip_1_desc', label: '一级会员一句话简介', type: 'input', default: '尊享一级会员特权', dependsOn: { key: 'pay_user_vip_1_s', value: true } },
{ key: 'pay_user_vip_1_equity', label: '一级会员权益 HTML', type: 'textarea', default: '<li>免费下载部分资源</li><li>会员专属身份标识</li><li>付费内容会员价</li>', dependsOn: { key: 'pay_user_vip_1_s', value: true }, help: '建议使用 <li> 列表项' }, { key: 'pay_user_vip_1_equity', label: '一级会员权益 HTML', type: 'textarea', default: '<li>免费下载部分资源</li><li>会员专属身份标识</li><li>付费内容会员价</li>', dependsOn: { key: 'pay_user_vip_1_s', value: true }, help: '建议使用 <li> 列表项' },
{ key: 'vip_1_img_icon', label: '一级会员图标 URL', type: 'input', default: '', dependsOn: { key: 'pay_user_vip_1_s', value: true } }, { key: 'vip_1_img_icon', label: '一级会员图标 URL', type: 'input', default: '', dependsOn: { key: 'pay_user_vip_1_s', value: true }, help: '留空使用内置 vip-1.svg 图标' },
{ key: 'pay_user_vip_2_s', label: '启用二级会员', type: 'switch', default: true }, { key: 'pay_user_vip_2_s', label: '启用二级会员', type: 'switch', default: true },
{ key: 'pay_user_vip_2_name', label: '二级会员名称', type: 'input', default: '二级会员', dependsOn: { key: 'pay_user_vip_2_s', value: true } }, { key: 'pay_user_vip_2_name', label: '二级会员名称', type: 'input', default: '二级会员', dependsOn: { key: 'pay_user_vip_2_s', value: true } },
{ key: 'pay_user_vip_2_desc', label: '二级会员一句话简介', type: 'input', default: '尊享二级会员特权', dependsOn: { key: 'pay_user_vip_2_s', value: true } }, { key: 'pay_user_vip_2_desc', label: '二级会员一句话简介', type: 'input', default: '尊享二级会员特权', dependsOn: { key: 'pay_user_vip_2_s', value: true } },
{ key: 'pay_user_vip_2_equity', label: '二级会员权益 HTML', type: 'textarea', default: '<li>更高免费下载额度</li><li>更高等级身份标识</li><li>更多付费内容会员价</li>', dependsOn: { key: 'pay_user_vip_2_s', value: true } }, { key: 'pay_user_vip_2_equity', label: '二级会员权益 HTML', type: 'textarea', default: '<li>更高免费下载额度</li><li>更高等级身份标识</li><li>更多付费内容会员价</li>', dependsOn: { key: 'pay_user_vip_2_s', value: true } },
{ key: 'vip_2_img_icon', label: '二级会员图标 URL', type: 'input', default: '', dependsOn: { key: 'pay_user_vip_2_s', value: true } }, { key: 'vip_2_img_icon', label: '二级会员图标 URL', type: 'input', default: '', dependsOn: { key: 'pay_user_vip_2_s', value: true }, help: '留空使用内置 vip-2.svg 图标' },
{ key: 'pay_user_vip_desc', label: '弹窗顶部会员说明', type: 'textarea', default: '' }, { key: 'pay_user_vip_desc', label: '弹窗顶部会员说明', type: 'textarea', default: '' },
{ key: 'pay_user_vip_more', label: '弹窗底部补充说明 HTML', type: 'textarea', default: '' }, { key: 'pay_user_vip_more', label: '弹窗底部补充说明 HTML', type: 'textarea', default: '' },
], ],
@@ -109,11 +106,8 @@ export const vipSchema = {
icon: 'fas fa-gift', icon: 'fas fa-gift',
fields: [ fields: [
{ key: 'pay_download_limit', label: '普通用户下载限制', type: 'number', default: 0, min: 0, max: 9999, help: '0为不限制' }, { key: 'pay_download_limit', label: '普通用户下载限制', type: 'number', default: 0, min: 0, max: 9999, help: '0为不限制' },
{ key: 'pay_download_speed', label: '普通用户下载速度(KB/s)', type: 'number', default: 0, min: 0, max: 99999, help: '0为不限制' },
{ key: 'pay_download_limit_vip_1', label: '一级会员下载限制', type: 'number', default: 0, min: 0, max: 9999, dependsOn: { key: 'pay_user_vip_1_s', value: true } }, { key: 'pay_download_limit_vip_1', label: '一级会员下载限制', type: 'number', default: 0, min: 0, max: 9999, dependsOn: { key: 'pay_user_vip_1_s', value: true } },
{ key: 'pay_download_speed_vip_1', label: '一级会员下载速度(KB/s)', type: 'number', default: 0, min: 0, max: 99999, dependsOn: { key: 'pay_user_vip_1_s', value: true } },
{ key: 'pay_download_limit_vip_2', label: '二级会员下载限制', type: 'number', default: 0, min: 0, max: 9999, dependsOn: { key: 'pay_user_vip_2_s', value: true } }, { key: 'pay_download_limit_vip_2', label: '二级会员下载限制', type: 'number', default: 0, min: 0, max: 9999, dependsOn: { key: 'pay_user_vip_2_s', value: true } },
{ key: 'pay_download_speed_vip_2', label: '二级会员下载速度(KB/s)', type: 'number', default: 0, min: 0, max: 99999, dependsOn: { key: 'pay_user_vip_2_s', value: true } },
{ key: 'pay_vip_pass_charge_s', label: '会员卡密兑换', type: 'switch', default: false }, { key: 'pay_vip_pass_charge_s', label: '会员卡密兑换', type: 'switch', default: false },
{ key: 'pay_vip_pass_charge_desc', label: '卡密兑换说明', type: 'textarea', default: '', dependsOn: { key: 'pay_vip_pass_charge_s', value: true } }, { key: 'pay_vip_pass_charge_desc', label: '卡密兑换说明', type: 'textarea', default: '', dependsOn: { key: 'pay_vip_pass_charge_s', value: true } },
{ key: 'pay_vip_pass_charge_only_password', label: '仅密码兑换', type: 'switch', default: true, dependsOn: { key: 'pay_vip_pass_charge_s', value: true }, help: '开启后只需输入卡密;关闭则需卡号+卡密。' }, { key: 'pay_vip_pass_charge_only_password', label: '仅密码兑换', type: 'switch', default: true, dependsOn: { key: 'pay_vip_pass_charge_s', value: true }, help: '开启后只需输入卡密;关闭则需卡号+卡密。' },
+16
View File
@@ -361,6 +361,22 @@
vertical-align: middle; vertical-align: middle;
} }
.aksrt-vip-level-icon {
display: inline-block;
width: 1.4em;
height: 1.4em;
object-fit: contain;
vertical-align: middle;
}
.aksrt-vip-badge__icon {
display: inline-block;
width: 1.1em;
height: 1.1em;
object-fit: contain;
vertical-align: -.15em;
}
.aksrt-vip-badge i { .aksrt-vip-badge i {
font-size: 10px; font-size: 10px;
} }
+13
View File
@@ -691,6 +691,19 @@ body.uc-modal-open {
padding: 22px; padding: 22px;
color: #fff; color: #fff;
} }
.aksrt-vip-level-icon {
display: inline-block;
width: 1.4em;
height: 1.4em;
object-fit: contain;
vertical-align: middle;
}
.uc-vip-card__icon .aksrt-vip-level-icon {
width: 28px;
height: 28px;
}
.uc-vip-card__header { .uc-vip-card__header {
display: flex; display: flex;
align-items: center; align-items: center;
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024"><defs><linearGradient id="a"><stop offset="0" stop-color="#fcdba2"/><stop offset="1" stop-color="#fdf6d8"/></linearGradient><linearGradient id="e"><stop offset="0" stop-color="#f8b446"/><stop offset="1" stop-color="#fdf4cf"/></linearGradient><linearGradient xlink:href="#a" id="j" x1="523.292" x2="521.856" y1="345.301" y2="627.851" gradientTransform="translate(8.2904476 3.9483139) scale(.96795)" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#b" id="f" x1="143.09692" x2="898.33069" y1="164.29646" y2="810.88257" gradientTransform="translate(-.00191063 -.00196486) scale(1.0005)" gradientUnits="userSpaceOnUse"/><linearGradient id="b"><stop offset="0" stop-color="#fbe2c9"/><stop offset="1" stop-color="#eea36b"/></linearGradient><linearGradient xlink:href="#c" id="g" x1="1274.6226" x2="1902.6591" y1="-291.49371" y2="204.04561" gradientTransform="translate(-1063.8611 567.31936) scale(1.0005)" gradientUnits="userSpaceOnUse"/><linearGradient id="c"><stop offset="0" stop-color="#e2a576"/><stop offset="1" stop-color="#f9e7d6"/></linearGradient><linearGradient xlink:href="#d" id="h" x1="-285.41812" x2="285.38971" y1="-257.87775" y2="255.19093" gradientTransform="translate(512.02424 518.02725) scale(1.0005)" gradientUnits="userSpaceOnUse"/><linearGradient id="d"><stop offset="0" stop-color="#facda1"/><stop offset="1" stop-color="#e3814e"/></linearGradient><radialGradient xlink:href="#e" id="i" cx="521.652" cy="617.926" r="257.943" fx="521.652" fy="617.926" gradientTransform="matrix(.9934 .00447 -.0041 .91186 -2.4439201 11.161921)" gradientUnits="userSpaceOnUse"/></defs><circle cx="512" cy="512" r="508" fill="url(#f)"/><circle cx="513.64362" cy="515.61957" r="425.46204" fill="url(#g)"/><circle cx="512.02417" cy="518.02716" r="386.19312" fill="url(#h)"/><path fill="url(#i)" d="M260.93578 362.19446v273.13658c0 31.70185 13.987 57.984 47.47974 57.984h404.12609c23.37369 0 47.64683-21.11456 47.74888-58.93648 0-32.14907-.27014-278.28715-.27014-278.28715l-246.59831 255.5878z"/><path fill="url(#j)" d="M517.23194 291.90631 362.70967 569.71123c-37.86393 67.97299 24.27614 70.95448 24.27614 70.95448h241.41372s66.13307 1.85993 33.10956-68.66634z"/><circle cx="516.09039" cy="286.75574" r="39.223614" fill="#fdf9e1"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024"><circle cx="511.746" cy="511.746" r="507.746" style="fill:url(#a)"/><circle cx="513.389" cy="515.364" r="425.249" style="fill:url(#b)"/><circle cx="511.77" cy="517.77" r="386" style="fill:url(#c)"/><defs><linearGradient id="g"><stop offset="0" style="stop-color:#dfd9fb;stop-opacity:1"/><stop offset="1" style="stop-color:#7b74bf;stop-opacity:1"/></linearGradient><linearGradient id="f"><stop offset="0" style="stop-color:#766fb8;stop-opacity:1"/><stop offset="1" style="stop-color:#dbd9f3;stop-opacity:1"/></linearGradient><linearGradient id="e"><stop offset="0" style="stop-color:#dcdaf3;stop-opacity:1"/><stop offset="1" style="stop-color:#8d86d4;stop-opacity:1"/></linearGradient><linearGradient id="d" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1200.85 0 0 -1200.85 10872.1 5348.5)" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" style="stop-opacity:1;stop-color:#7646a7"/><stop offset="1" style="stop-opacity:1;stop-color:#774aaa"/></linearGradient><linearGradient id="i" x1=".017" x2="1.011" y1=".044" y2=".035" gradientTransform="matrix(0 -2490.67 -2490.67 0 14782.2 7118)" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" style="stop-opacity:1;stop-color:#7d74d7"/><stop offset="1" style="stop-opacity:1;stop-color:#383492"/></linearGradient><linearGradient id="k" x1="0" x2=".752" y1="-.009" y2=".29" gradientTransform="matrix(0 -1550.32 -1550.32 0 14760 6177.7)" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" style="stop-opacity:1;stop-color:#998fe4"/><stop offset="1" style="stop-opacity:1;stop-color:#5145a4"/></linearGradient><linearGradient id="m" x1="0" x2="1.498" y1="0" y2="-.015" gradientTransform="matrix(0 -940.355 -940.355 0 14760 7118)" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" style="stop-opacity:1;stop-color:#6d65b6"/><stop offset="1" style="stop-opacity:1;stop-color:#c6bce8"/></linearGradient><linearGradient id="o" x1=".457" x2="1" y1=".436" y2="-.015" gradientTransform="matrix(0 -940.355 -940.355 0 14760 7118)" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" style="stop-opacity:1;stop-color:#b4aef0"/><stop offset="1" style="stop-opacity:1;stop-color:#dfdafa"/></linearGradient><linearGradient id="p" x1="-.002" x2=".685" y1="-.402" y2=".224" gradientTransform="scale(223.40193 198.80753) rotate(90 .402 2.11)" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" style="stop-opacity:1;stop-color:#8e84d6"/><stop offset="1" style="stop-opacity:1;stop-color:#b2a1e4"/></linearGradient><linearGradient id="q" x1=".057" x2=".653" y1=".237" y2="-.115" gradientTransform="scale(368.31247 327.76481) rotate(90 .115 1.509)" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" style="stop-opacity:1;stop-color:#6e5edf"/><stop offset="1" style="stop-opacity:1;stop-color:#40388a"/></linearGradient><linearGradient xlink:href="#e" id="a" x1="143.097" x2="898.331" y1="164.296" y2="810.883" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#f" id="b" x1="1274.623" x2="1902.659" y1="-291.494" y2="204.046" gradientTransform="translate(-1063.327 567.038)" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#g" id="c" x1="-285.418" x2="285.39" y1="-257.878" y2="255.191" gradientTransform="translate(511.77 517.77)" gradientUnits="userSpaceOnUse"/><clipPath id="h" clipPathUnits="userSpaceOnUse"><path d="M15779.8 7118h-2039.6l-571.8-940.3 1613.8-1550.3 1613.9 1550.3z"/></clipPath><clipPath id="j" clipPathUnits="userSpaceOnUse"><path d="m14782.2 4627.4-1042 1550.3h2039.6z"/></clipPath><clipPath id="l" clipPathUnits="userSpaceOnUse"><path d="M13740.2 6177.7V7118h2039.6v-940.3z"/></clipPath><clipPath id="n" clipPathUnits="userSpaceOnUse"><path d="M13740.2 6177.7 14760 7118l1019.8-940.3Z"/></clipPath></defs><g clip-path="url(#h)" transform="matrix(.20263 0 0 -.21142 -2483.133 1781.498)"><path d="M15687.3 7076.28H13659.7l-568.5-934.79 1604.4-1541.21L16300 6141.49l-612.7 934.79" style="fill:url(#i);fill-opacity:1;fill-rule:nonzero;stroke:none" transform="scale(1.0059)"/></g><g clip-path="url(#j)" transform="matrix(.23757 0 0 -.21142 -2998.804 1781.498)"><path d="m14782.2 4627.4-1042 1550.3h2039.6z" style="fill:url(#k);fill-opacity:1;fill-rule:nonzero;stroke:none"/></g><g clip-path="url(#l)" transform="matrix(.23757 0 0 -.21142 -2998.804 1781.498)"><path d="m13740.2 6177.7 479.039 935.626 1159.972-.292L15779.8 6177.7h-2039.6" style="fill:url(#m);fill-opacity:1;fill-rule:nonzero;stroke:none"/></g><g clip-path="url(#n)" transform="matrix(.23757 0 0 -.21142 -2998.804 1781.498)"><path d="M13740.2 6177.7 14760 7118l1019.8-940.3Z" style="fill:url(#o);fill-opacity:1;fill-rule:nonzero;stroke:none"/></g><path d="m511.085 475.424-3.328-198.796 242.276 198.796z" style="fill:url(#p);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.224114"/><path d="m513.031 803.184-1.946-327.76h238.9Line truncated

After

Width:  |  Height:  |  Size: 5.0 KiB

+8
View File
@@ -297,6 +297,14 @@
var row = node("div", "pay-vip-form-row"); var row = node("div", "pay-vip-form-row");
var info = node("div", "pay-vip-info level-" + level); var info = node("div", "pay-vip-info level-" + level);
var levelInfo = levels[String(level)] || {}; var levelInfo = levels[String(level)] || {};
if (levelInfo.img_icon) {
var levelIcon = node("img", "aksrt-vip-level-icon");
levelIcon.src = text(levelInfo.img_icon);
levelIcon.alt = "";
levelIcon.loading = "lazy";
levelIcon.decoding = "async";
append(info, levelIcon);
}
append(info, node("div", "v-name font-bold", group.name || levelInfo.name || "VIP" + level)); append(info, node("div", "v-name font-bold", group.name || levelInfo.name || "VIP" + level));
if (levelInfo.desc) append(info, node("div", "muted-2-color em09 mb6", levelInfo.desc)); if (levelInfo.desc) append(info, node("div", "muted-2-color em09 mb6", levelInfo.desc));
renderEquity(info, levelInfo.equity); renderEquity(info, levelInfo.equity);
+10 -26
View File
@@ -230,31 +230,6 @@ if (!function_exists('aksrt_get_user_free_download_limit')) {
} }
} }
/**
* Download speed cap in KB/s for a user (0 = unlimited).
*/
if (!function_exists('aksrt_get_user_download_speed')) {
function aksrt_get_user_download_speed(int $user_id = 0): int {
if ($user_id <= 0) {
$user_id = get_current_user_id();
}
if ($user_id <= 0 || !class_exists('\AKSRT\Settings\Settings')) {
return 0;
}
$vip = \AKSRT\Settings\Settings::get_payment_vip_settings();
$level = function_exists('aksrt_get_user_vip_level') ? aksrt_get_user_vip_level($user_id) : 0;
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
$benefit = is_array($vip['benefit'] ?? null) ? $vip['benefit'] : [];
if ($level >= 1 && !empty($levels[$level]['enabled'])) {
return max(0, (int) ($levels[$level]['download_speed'] ?? 0));
}
return max(0, (int) ($benefit['download_speed'] ?? 0));
}
}
/** /**
* Count free downloads used today for a user (zibll pay_down_number). * Count free downloads used today for a user (zibll pay_down_number).
*/ */
@@ -383,7 +358,16 @@ function aksrt_render_vip_badge(int $user_id = 0, string $size = 'sm'): string {
$size_class = 'aksrt-vip-badge--' . $size; $size_class = 'aksrt-vip-badge--' . $size;
$level_class = $level >= 2 ? 'aksrt-vip-badge--vip2' : 'aksrt-vip-badge--vip1'; $level_class = $level >= 2 ? 'aksrt-vip-badge--vip2' : 'aksrt-vip-badge--vip1';
return '<span class="aksrt-vip-badge aksrt-vip-badge--gold ' . esc_attr($size_class . ' ' . $level_class) . '"><i class="fas fa-crown"></i> ' . esc_html($badge_text) . '</span>'; $icon_url = '';
if (class_exists('\AKSRT\Settings\Settings')) {
$vip_settings = \AKSRT\Settings\Settings::get_payment_vip_settings();
$icon_url = esc_url((string) ($vip_settings['levels'][$level]['img_icon'] ?? ''));
}
$icon = $icon_url !== ''
? '<img class="aksrt-vip-badge__icon" src="' . $icon_url . '" alt="" loading="lazy" decoding="async" />'
: '<i class="fas fa-crown" aria-hidden="true"></i>';
return '<span class="aksrt-vip-badge aksrt-vip-badge--gold ' . esc_attr($size_class . ' ' . $level_class) . '">' . $icon . ' ' . esc_html($badge_text) . '</span>';
} }
/** /**
@@ -50,7 +50,10 @@ if ($vip_level >= 1 && !empty($vip_settings['levels'][$vip_level]['name'])) {
$level_name = (string) $vip_settings['levels'][$vip_level]['name']; $level_name = (string) $vip_settings['levels'][$vip_level]['name'];
} }
$cash_symbol = '¥'; $level_icon_url = esc_url((string) ($vip_settings['levels'][$vip_level]['img_icon'] ?? ''));
$level_icon = $level_icon_url !== ''
? '<img class="aksrt-vip-level-icon" src="' . $level_icon_url . '" alt="" loading="lazy" decoding="async">'
: '<i class="fas fa-crown" aria-hidden="true"></i>';
if (class_exists('\AKSRT\Settings\Settings')) { if (class_exists('\AKSRT\Settings\Settings')) {
$paid_display = \AKSRT\Settings\Settings::get_paid_content_settings(); $paid_display = \AKSRT\Settings\Settings::get_paid_content_settings();
$cash_symbol = (string) ($paid_display['display']['currency_symbol'] ?? '¥'); $cash_symbol = (string) ($paid_display['display']['currency_symbol'] ?? '¥');
@@ -79,7 +82,7 @@ if (class_exists('\AKSRT\Payment\ChargeCard')) {
<div class="uc-vip-card__content"> <div class="uc-vip-card__content">
<div class="uc-vip-card__header"> <div class="uc-vip-card__header">
<div class="uc-vip-card__icon"> <div class="uc-vip-card__icon">
<i class="fas fa-crown" aria-hidden="true"></i> <?php echo $level_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div> </div>
<div class="uc-vip-card__info"> <div class="uc-vip-card__info">
<span class="uc-vip-card__label"><?php echo esc_html($level_name); ?></span> <span class="uc-vip-card__label"><?php echo esc_html($level_name); ?></span>
@@ -30,7 +30,7 @@ if ($status === '') {
if ($vip_level > 0) { if ($vip_level > 0) {
$title = (string) ($vip_levels[$vip_level]['name'] ?? ('VIP' . $vip_level)); $title = (string) ($vip_levels[$vip_level]['name'] ?? ('VIP' . $vip_level));
if ($expires <= 0 && $vip_state_source !== 'order') { if ($expires <= 0 && ($vip_state['source'] ?? 'none') !== 'order') {
$status = __('永久会员', 'aksrt'); $status = __('永久会员', 'aksrt');
} else { } else {
$remaining_days = max(1, (int) ceil(($expires - time()) / DAY_IN_SECONDS)); $remaining_days = max(1, (int) ceil(($expires - time()) / DAY_IN_SECONDS));
@@ -44,9 +44,15 @@ if ($vip_level > 0) {
$title = (string) ($vip_levels[$expired_level]['name'] ?? ('VIP' . $expired_level)); $title = (string) ($vip_levels[$expired_level]['name'] ?? ('VIP' . $expired_level));
$status = __('已过期', 'aksrt'); $status = __('已过期', 'aksrt');
} }
$sidebar_level = $vip_level > 0 ? $vip_level : $expired_level;
$sidebar_icon_url = esc_url((string) ($vip_levels[$sidebar_level]['img_icon'] ?? ''));
$sidebar_icon = $sidebar_icon_url !== ''
? '<img class="aksrt-vip-level-icon" src="' . $sidebar_icon_url . '" alt="" loading="lazy" decoding="async">'
: '<i class="fas fa-crown" aria-hidden="true"></i>';
?> ?>
<a class="uc-sidebar-vip" href="<?php echo esc_url($vip_url); ?>"> <a class="uc-sidebar-vip" href="<?php echo esc_url($vip_url); ?>">
<span class="uc-sidebar-vip__icon"><i class="fas fa-crown" aria-hidden="true"></i></span> <span class="uc-sidebar-vip__icon"><?php echo $sidebar_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
<span class="uc-sidebar-vip__content"> <span class="uc-sidebar-vip__content">
<strong><?php echo esc_html($title); ?></strong> <strong><?php echo esc_html($title); ?></strong>
<small><?php echo esc_html($status); ?></small> <small><?php echo esc_html($status); ?></small>
+10 -2
View File
@@ -90,13 +90,17 @@ if ($level > 0) {
: __('到期时间:已过期', 'aksrt'); : __('到期时间:已过期', 'aksrt');
} }
$status_icon_url = esc_url((string) ($levels[$vip_level_number]['img_icon'] ?? ''));
$status_icon = $status_icon_url !== ''
? '<img class="aksrt-vip-level-icon" src="' . $status_icon_url . '" alt="" loading="lazy" decoding="async">'
: '<i class="fas fa-crown"></i>';
$status_html = '<div class="uc-vip-status" role="status">' $status_html = '<div class="uc-vip-status" role="status">'
. '<div class="uc-vip-status__heading">' . '<div class="uc-vip-status__heading">'
. '<h2 class="uc-vip-status__label">' . esc_html__('我的会员', 'aksrt') . '</h2>' . '<h2 class="uc-vip-status__label">' . esc_html__('我的会员', 'aksrt') . '</h2>'
. '<span class="uc-vip-status__state">' . esc_html($vip_state_label) . '</span>' . '<span class="uc-vip-status__state">' . esc_html($vip_state_label) . '</span>'
. '</div>' . '</div>'
. '<div class="uc-vip-status__main uc-vip-status__main--level-' . (int) $vip_level_number . '">' . '<div class="uc-vip-status__main uc-vip-status__main--level-' . (int) $vip_level_number . '">'
. '<span class="uc-vip-status__icon" aria-hidden="true"><i class="fas fa-crown"></i></span>' . '<span class="uc-vip-status__icon" aria-hidden="true">' . $status_icon . '</span>'
. '<span class="uc-vip-status__level">' . esc_html($vip_level_name) . '</span>' . '<span class="uc-vip-status__level">' . esc_html($vip_level_name) . '</span>'
. '</div>' . '</div>'
. '<div class="uc-vip-status__desc">' . esc_html($vip_description) . '</div>' . '<div class="uc-vip-status__desc">' . esc_html($vip_description) . '</div>'
@@ -118,6 +122,10 @@ foreach ([1, 2] as $lv) {
: ''; : '';
$cta = sprintf(__('开通%s', 'aksrt'), $lv_name); $cta = sprintf(__('开通%s', 'aksrt'), $lv_name);
$vip_attr = $lv; $vip_attr = $lv;
$lv_icon_url = esc_url((string) ($levels[$lv]['img_icon'] ?? ''));
$lv_icon = $lv_icon_url !== ''
? '<img class="aksrt-vip-level-icon" src="' . $lv_icon_url . '" alt="" loading="lazy" decoding="async">'
: '<i class="fas fa-crown" aria-hidden="true"></i>';
if (str_starts_with($btn_type, 'renew_')) { if (str_starts_with($btn_type, 'renew_')) {
$renew_lv = (int) substr($btn_type, 6); $renew_lv = (int) substr($btn_type, 6);
if ($lv === $renew_lv) { if ($lv === $renew_lv) {
@@ -144,7 +152,7 @@ foreach ([1, 2] as $lv) {
$cards .= '<div class="vip-baicon" aria-hidden="true"><i class="fas fa-gem"></i></div>'; $cards .= '<div class="vip-baicon" aria-hidden="true"><i class="fas fa-gem"></i></div>';
$cards .= '<div class="relative uc-vip-level-card__inner">'; $cards .= '<div class="relative uc-vip-level-card__inner">';
$cards .= '<div class="v-iconbox mb10 flex jc ac">'; $cards .= '<div class="v-iconbox mb10 flex jc ac">';
$cards .= '<div class="v-icon flex jc ac"><i class="fas fa-crown" aria-hidden="true"></i></div>'; $cards .= '<div class="v-icon flex jc ac">' . $lv_icon . '</div>';
$cards .= '<div class="v-info text-left"><div class="v-name font-bold">' . esc_html($lv_name) . '</div>'; $cards .= '<div class="v-info text-left"><div class="v-name font-bold">' . esc_html($lv_name) . '</div>';
if ($lv_desc !== '') { if ($lv_desc !== '') {
$cards .= '<div class="v-desc em09 muted-2-color">' . esc_html($lv_desc) . '</div>'; $cards .= '<div class="v-desc em09 muted-2-color">' . esc_html($lv_desc) . '</div>';
+2 -5
View File
@@ -112,12 +112,12 @@ class SchemaPayment {
['key' => 'pay_user_vip_1_name', 'label' => '一级会员名称', 'type' => 'input', 'default' => '一级会员', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]], ['key' => 'pay_user_vip_1_name', 'label' => '一级会员名称', 'type' => 'input', 'default' => '一级会员', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]],
['key' => 'pay_user_vip_1_desc', 'label' => '一级会员一句话简介', 'type' => 'input', 'default' => '尊享一级会员特权', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]], ['key' => 'pay_user_vip_1_desc', 'label' => '一级会员一句话简介', 'type' => 'input', 'default' => '尊享一级会员特权', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]],
['key' => 'pay_user_vip_1_equity', 'label' => '一级会员权益 HTML', 'type' => 'textarea', 'default' => '<li>免费下载部分资源</li><li>会员专属身份标识</li><li>付费内容会员价</li>', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]], ['key' => 'pay_user_vip_1_equity', 'label' => '一级会员权益 HTML', 'type' => 'textarea', 'default' => '<li>免费下载部分资源</li><li>会员专属身份标识</li><li>付费内容会员价</li>', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]],
['key' => 'vip_1_img_icon', 'label' => '一级会员图标 URL', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]], ['key' => 'vip_1_img_icon', 'label' => '一级会员图标 URL', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true], 'help' => '留空使用内置 vip-1.svg 图标'],
['key' => 'pay_user_vip_2_s', 'label' => '启用二级会员', 'type' => 'switch', 'default' => true], ['key' => 'pay_user_vip_2_s', 'label' => '启用二级会员', 'type' => 'switch', 'default' => true],
['key' => 'pay_user_vip_2_name', 'label' => '二级会员名称', 'type' => 'input', 'default' => '二级会员', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]], ['key' => 'pay_user_vip_2_name', 'label' => '二级会员名称', 'type' => 'input', 'default' => '二级会员', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]],
['key' => 'pay_user_vip_2_desc', 'label' => '二级会员一句话简介', 'type' => 'input', 'default' => '尊享二级会员特权', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]], ['key' => 'pay_user_vip_2_desc', 'label' => '二级会员一句话简介', 'type' => 'input', 'default' => '尊享二级会员特权', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]],
['key' => 'pay_user_vip_2_equity', 'label' => '二级会员权益 HTML', 'type' => 'textarea', 'default' => '<li>更高免费下载额度</li><li>更高等级身份标识</li><li>更多付费内容会员价</li>', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]], ['key' => 'pay_user_vip_2_equity', 'label' => '二级会员权益 HTML', 'type' => 'textarea', 'default' => '<li>更高免费下载额度</li><li>更高等级身份标识</li><li>更多付费内容会员价</li>', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]],
['key' => 'vip_2_img_icon', 'label' => '二级会员图标 URL', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]], ['key' => 'vip_2_img_icon', 'label' => '二级会员图标 URL', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true], 'help' => '留空使用内置 vip-2.svg 图标'],
['key' => 'pay_user_vip_desc', 'label' => '弹窗顶部会员说明', 'type' => 'textarea', 'default' => ''], ['key' => 'pay_user_vip_desc', 'label' => '弹窗顶部会员说明', 'type' => 'textarea', 'default' => ''],
['key' => 'pay_user_vip_more', 'label' => '弹窗底部补充说明 HTML', 'type' => 'textarea', 'default' => ''], ['key' => 'pay_user_vip_more', 'label' => '弹窗底部补充说明 HTML', 'type' => 'textarea', 'default' => ''],
]], ]],
@@ -134,11 +134,8 @@ class SchemaPayment {
]], ]],
['key' => 'benefit', 'title' => '下载权益', 'fields' => [ ['key' => 'benefit', 'title' => '下载权益', 'fields' => [
['key' => 'pay_download_limit', 'label' => '普通用户下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999], ['key' => 'pay_download_limit', 'label' => '普通用户下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999],
['key' => 'pay_download_speed', 'label' => '普通用户下载速度(KB/s)', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 99999],
['key' => 'pay_download_limit_vip_1', 'label' => '一级会员下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999, 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]], ['key' => 'pay_download_limit_vip_1', 'label' => '一级会员下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999, 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]],
['key' => 'pay_download_speed_vip_1', 'label' => '一级会员下载速度(KB/s)', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 99999, 'dependsOn' => ['key' => 'pay_user_vip_1_s', 'value' => true]],
['key' => 'pay_download_limit_vip_2', 'label' => '二级会员下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999, 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]], ['key' => 'pay_download_limit_vip_2', 'label' => '二级会员下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 9999, 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]],
['key' => 'pay_download_speed_vip_2', 'label' => '二级会员下载速度(KB/s)', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 99999, 'dependsOn' => ['key' => 'pay_user_vip_2_s', 'value' => true]],
['key' => 'pay_vip_pass_charge_s', 'label' => '会员卡密兑换', 'type' => 'switch', 'default' => false], ['key' => 'pay_vip_pass_charge_s', 'label' => '会员卡密兑换', 'type' => 'switch', 'default' => false],
['key' => 'pay_vip_pass_charge_desc', 'label' => '卡密兑换说明', 'type' => 'textarea', 'default' => '', 'dependsOn' => ['key' => 'pay_vip_pass_charge_s', 'value' => true]], ['key' => 'pay_vip_pass_charge_desc', 'label' => '卡密兑换说明', 'type' => 'textarea', 'default' => '', 'dependsOn' => ['key' => 'pay_vip_pass_charge_s', 'value' => true]],
['key' => 'pay_vip_pass_charge_only_password', 'label' => '仅密码兑换', 'type' => 'switch', 'default' => true, 'dependsOn' => ['key' => 'pay_vip_pass_charge_s', 'value' => true]], ['key' => 'pay_vip_pass_charge_only_password', 'label' => '仅密码兑换', 'type' => 'switch', 'default' => true, 'dependsOn' => ['key' => 'pay_vip_pass_charge_s', 'value' => true]],
-1
View File
@@ -127,7 +127,6 @@ class SchemaPermissions {
['key' => 'download_credits_cost', 'label' => '默认积分价参考', 'type' => 'number', 'default' => 1, 'min' => 0, 'max' => 100, 'help' => '仅运营参考/兼容;实际价格以文章付费设置为准。'], ['key' => 'download_credits_cost', 'label' => '默认积分价参考', 'type' => 'number', 'default' => 1, 'min' => 0, 'max' => 100, 'help' => '仅运营参考/兼容;实际价格以文章付费设置为准。'],
['key' => 'download_daily_limit', 'label' => '每日下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'help' => '0为不限制'], ['key' => 'download_daily_limit', 'label' => '每日下载限制', 'type' => 'number', 'default' => 0, 'min' => 0, 'help' => '0为不限制'],
['key' => 'download_link_expire', 'label' => '下载链接有效期(分钟)', 'type' => 'number', 'default' => 30, 'min' => 5, 'max' => 1440], ['key' => 'download_link_expire', 'label' => '下载链接有效期(分钟)', 'type' => 'number', 'default' => 30, 'min' => 5, 'max' => 1440],
['key' => 'download_speed_limit', 'label' => '下载速度限制(KB/s)', 'type' => 'number', 'default' => 0, 'min' => 0, 'help' => '0为不限制'],
]], ]],
['key' => 'vip', 'title' => 'VIP 特权', 'fields' => [ ['key' => 'vip', 'title' => 'VIP 特权', 'fields' => [
['key' => 'download_vip_free', 'label' => 'VIP 免费下载', 'type' => 'switch', 'default' => false], ['key' => 'download_vip_free', 'label' => 'VIP 免费下载', 'type' => 'switch', 'default' => false],
+5 -22
View File
@@ -295,16 +295,11 @@ class Download {
} }
$target_url = esc_url_raw((string) $meta['downloads'][$idx]['url']); $target_url = esc_url_raw((string) $meta['downloads'][$idx]['url']);
$speed_kb = 0;
$uid_speed = (int) ($row['user_id'] ?? 0);
if ($uid_speed > 0 && function_exists('aksrt_get_user_download_speed')) {
$speed_kb = aksrt_get_user_download_speed($uid_speed);
}
// Local attachment / uploads file: optional throttled stream (Zibll speed limit). // Local attachment / uploads file: stream without artificial throttling.
$local_path = $this->resolve_local_download_path($target_url); $local_path = $this->resolve_local_download_path($target_url);
if ($local_path !== '' && is_readable($local_path)) { if ($local_path !== '' && is_readable($local_path)) {
$this->stream_local_file($local_path, $speed_kb); $this->stream_local_file($local_path);
exit; exit;
} }
@@ -347,9 +342,9 @@ class Download {
} }
/** /**
* Stream a local file with optional KB/s throttle. * Stream a local file.
*/ */
private function stream_local_file(string $path, int $speed_kb = 0): void { private function stream_local_file(string $path): void {
$filename = basename($path); $filename = basename($path);
$size = filesize($path); $size = filesize($path);
if ($size === false) { if ($size === false) {
@@ -364,21 +359,12 @@ class Download {
header('Content-Length: ' . (string) $size); header('Content-Length: ' . (string) $size);
$chunk = 1024 * 64; // 64KB $chunk = 1024 * 64; // 64KB
$sleep_us = 0;
if ($speed_kb > 0) {
// Emit ~speed_kb KB per second using fixed 64KB chunks when possible.
$bytes_per_sec = max(1024, $speed_kb * 1024);
$chunk = min(1024 * 64, $bytes_per_sec);
$chunk = max(1024, $chunk);
// Sleep so chunk_bytes / second ≈ bytes_per_sec.
$sleep_us = (int) max(0, (int) round(($chunk / $bytes_per_sec) * 1000000) - 1000);
}
$fh = fopen($path, 'rb'); $fh = fopen($path, 'rb');
if (!$fh) { if (!$fh) {
$this->fail_410(); $this->fail_410();
} }
// Disable output compression for accurate Content-Length / throttle. // Disable output compression so Content-Length remains accurate.
if (function_exists('apache_setenv')) { if (function_exists('apache_setenv')) {
@apache_setenv('no-gzip', '1'); @apache_setenv('no-gzip', '1');
} }
@@ -392,9 +378,6 @@ class Download {
if (function_exists('flush')) { if (function_exists('flush')) {
flush(); flush();
} }
if ($sleep_us > 0) {
usleep($sleep_us);
}
} }
fclose($fh); fclose($fh);
} }
+5 -1
View File
@@ -41,6 +41,7 @@ trait VipServiceModal {
'name' => (string) ($levels[$level]['name'] ?? ('VIP' . $level)), 'name' => (string) ($levels[$level]['name'] ?? ('VIP' . $level)),
'desc' => (string) ($levels[$level]['desc'] ?? ''), 'desc' => (string) ($levels[$level]['desc'] ?? ''),
'equity' => $equity, 'equity' => $equity,
'img_icon' => esc_url_raw((string) ($levels[$level]['img_icon'] ?? '')),
]; ];
} }
@@ -161,7 +162,10 @@ trait VipServiceModal {
? aksrt_format_vip_equity_html($equity, 'mb10 relative') ? aksrt_format_vip_equity_html($equity, 'mb10 relative')
: ''; : '';
$icon = '<i class="fas fa-gem" aria-hidden="true"></i>'; $icon_url = esc_url((string) ($levels[$level]['img_icon'] ?? ''));
$icon = $icon_url !== ''
? '<img class="aksrt-vip-level-icon" src="' . $icon_url . '" alt="" loading="lazy" decoding="async" />'
: '<i class="fas fa-gem" aria-hidden="true"></i>';
$html = '<div class="vip-card pointer level-' . $level . ' vip-theme' . $level . $cls . '" vip-level="' . $level . '">'; $html = '<div class="vip-card pointer level-' . $level . ' vip-theme' . $level . $cls . '" vip-level="' . $level . '">';
$html .= '<div class="vip-baicon" aria-hidden="true">' . $icon . '</div>'; $html .= '<div class="vip-baicon" aria-hidden="true">' . $icon . '</div>';
$html .= '<div class="vip-img abs-right">' . $icon . '</div>'; $html .= '<div class="vip-img abs-right">' . $icon . '</div>';
+19 -5
View File
@@ -122,6 +122,23 @@ class PaymentRuntime {
]; ];
} }
/**
* Resolve a configured VIP icon, falling back to the bundled level asset.
*/
private static function get_vip_icon_url(int $level, string $configured): string {
$configured = esc_url_raw($configured);
if ($configured !== '') {
return $configured;
}
$filename = 'vip-' . $level . '.svg';
if (defined('AKSRT_DIR') && is_file(AKSRT_DIR . '/assets/img/user/vip/' . $filename)) {
return defined('AKSRT_URI') ? AKSRT_URI . '/assets/img/user/vip/' . $filename : '';
}
return '';
}
/** /**
* Dual-level VIP settings (Zibll pay_user_vip_1 / pay_user_vip_2). * Dual-level VIP settings (Zibll pay_user_vip_1 / pay_user_vip_2).
* *
@@ -190,27 +207,24 @@ class PaymentRuntime {
'name' => $name1, 'name' => $name1,
'desc' => sanitize_text_field((string) ($settings['pay_user_vip_1_desc'] ?? __('尊享一级会员特权', 'aksrt'))), 'desc' => sanitize_text_field((string) ($settings['pay_user_vip_1_desc'] ?? __('尊享一级会员特权', 'aksrt'))),
'equity' => wp_kses((string) (($settings['pay_user_vip_1_equity'] ?? '') !== '' ? $settings['pay_user_vip_1_equity'] : '<li>免费下载部分资源</li><li>会员专属身份标识</li><li>付费内容会员价</li>'), $allowed_equity), 'equity' => wp_kses((string) (($settings['pay_user_vip_1_equity'] ?? '') !== '' ? $settings['pay_user_vip_1_equity'] : '<li>免费下载部分资源</li><li>会员专属身份标识</li><li>付费内容会员价</li>'), $allowed_equity),
'img_icon' => esc_url_raw((string) ($settings['vip_1_img_icon'] ?? '')), 'img_icon' => self::get_vip_icon_url(1, (string) ($settings['vip_1_img_icon'] ?? '')),
'product_s' => !isset($settings['vip_1_product_s']) || !empty($settings['vip_1_product_s']), 'product_s' => !isset($settings['vip_1_product_s']) || !empty($settings['vip_1_product_s']),
'products_raw' => $products_1, 'products_raw' => $products_1,
'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit_vip_1'] ?? 0))), 'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit_vip_1'] ?? 0))),
'download_speed' => max(0, min(99999, (int) ($settings['pay_download_speed_vip_1'] ?? 0))),
], ],
2 => [ 2 => [
'enabled' => $vip2_enabled, 'enabled' => $vip2_enabled,
'name' => $name2, 'name' => $name2,
'desc' => sanitize_text_field((string) ($settings['pay_user_vip_2_desc'] ?? __('尊享二级会员特权', 'aksrt'))), 'desc' => sanitize_text_field((string) ($settings['pay_user_vip_2_desc'] ?? __('尊享二级会员特权', 'aksrt'))),
'equity' => wp_kses((string) (($settings['pay_user_vip_2_equity'] ?? '') !== '' ? $settings['pay_user_vip_2_equity'] : '<li>更高免费下载额度</li><li>更高等级身份标识</li><li>更多付费内容会员价</li>'), $allowed_equity), 'equity' => wp_kses((string) (($settings['pay_user_vip_2_equity'] ?? '') !== '' ? $settings['pay_user_vip_2_equity'] : '<li>更高免费下载额度</li><li>更高等级身份标识</li><li>更多付费内容会员价</li>'), $allowed_equity),
'img_icon' => esc_url_raw((string) ($settings['vip_2_img_icon'] ?? '')), 'img_icon' => self::get_vip_icon_url(2, (string) ($settings['vip_2_img_icon'] ?? '')),
'product_s' => !isset($settings['vip_2_product_s']) || !empty($settings['vip_2_product_s']), 'product_s' => !isset($settings['vip_2_product_s']) || !empty($settings['vip_2_product_s']),
'products_raw' => $products_2, 'products_raw' => $products_2,
'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit_vip_2'] ?? 0))), 'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit_vip_2'] ?? 0))),
'download_speed' => max(0, min(99999, (int) ($settings['pay_download_speed_vip_2'] ?? 0))),
], ],
], ],
'benefit' => [ 'benefit' => [
'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit'] ?? 0))), 'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit'] ?? 0))),
'download_speed' => max(0, min(99999, (int) ($settings['pay_download_speed'] ?? 0))),
'pass_charge' => !empty($settings['pay_vip_pass_charge_s']), 'pass_charge' => !empty($settings['pay_vip_pass_charge_s']),
'pass_charge_desc' => sanitize_textarea_field((string) ($settings['pay_vip_pass_charge_desc'] ?? '')), 'pass_charge_desc' => sanitize_textarea_field((string) ($settings['pay_vip_pass_charge_desc'] ?? '')),
'pass_charge_only_password' => !isset($settings['pay_vip_pass_charge_only_password']) || !empty($settings['pay_vip_pass_charge_only_password']), 'pass_charge_only_password' => !isset($settings['pay_vip_pass_charge_only_password']) || !empty($settings['pay_vip_pass_charge_only_password']),