优化了一些问题
This commit is contained in:
@@ -73,13 +73,16 @@ class SchemaPermissions {
|
||||
'download' => [
|
||||
'key' => 'download',
|
||||
'title' => '下载配置',
|
||||
'version' => '1.0.0',
|
||||
'version' => '1.1.0',
|
||||
'option_key' => 'aksrt_download_config',
|
||||
'groups' => [
|
||||
['key' => 'basic', 'title' => '链接规则', 'fields' => [
|
||||
['key' => 'url_alias', 'label' => '下载链接 URL 别名', 'type' => 'input', 'default' => 'download', 'required' => true, 'help' => '仅允许英文字母、数字、连字符和下划线;禁止中文、空格和 / \\ ? # & 等特殊符号。修改后旧别名路由立即失效,需重新获取下载地址。'],
|
||||
['key' => 'default_max_uses', 'label' => '下载链接默认使用次数', 'type' => 'number', 'default' => 1, 'min' => 1, 'max' => 100, 'help' => '单个链接可完成下载的次数;文件完整送达后才计次(HEAD 探测、传输中断不计次)。耗尽后链接返回 410,需重新获取。'],
|
||||
['key' => 'ttl_minutes', 'label' => '下载链接默认有效期限(分钟)', 'type' => 'number', 'default' => 10, 'min' => 1, 'max' => 1440, 'help' => '链接签发后超过该时长即失效并返回 410,不自动续期,需重新获取。'],
|
||||
['key' => 'basic', 'title' => '下载总开关', 'fields' => [
|
||||
['key' => 'enabled', 'label' => '启用本站下载链接', 'type' => 'switch', 'default' => true, 'help' => '总开关:开启后下载通过本站中转链接(别名、次数、有效期生效);关闭后下载按钮直接使用原始下载地址(直连),下方链接规则全部不生效,旧的中转链接同步失效。'],
|
||||
]],
|
||||
['key' => 'rules', 'title' => '链接规则', 'fields' => [
|
||||
['key' => 'url_alias', 'label' => '下载链接 URL 别名', 'type' => 'input', 'default' => 'download', 'required' => true, 'dependsOn' => ['key' => 'enabled', 'value' => true], 'help' => '仅允许英文字母、数字、连字符和下划线;禁止中文、空格和 / \\ ? # & 等特殊符号。修改后旧别名路由立即失效,需重新获取下载地址。'],
|
||||
['key' => 'default_max_uses', 'label' => '下载链接默认使用次数', 'type' => 'number', 'default' => 1, 'min' => 1, 'max' => 100, 'dependsOn' => ['key' => 'enabled', 'value' => true], 'help' => '单个链接可完成下载的次数;文件完整送达后才计次(HEAD 探测、传输中断不计次)。耗尽后链接返回 410,需重新获取。'],
|
||||
['key' => 'ttl_minutes', 'label' => '下载链接默认有效期限(分钟)', 'type' => 'number', 'default' => 10, 'min' => 1, 'max' => 1440, 'dependsOn' => ['key' => 'enabled', 'value' => true], 'help' => '链接签发后超过该时长即失效并返回 410,不自动续期,需重新获取。'],
|
||||
]],
|
||||
],
|
||||
],
|
||||
|
||||
+30
-66
@@ -68,6 +68,19 @@ class Download {
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Master switch for the site-routed download system (aksrt_download_config
|
||||
* "enabled", default true). When off, download buttons render the raw
|
||||
* source URLs directly and every token route/endpoint below stays dormant.
|
||||
*/
|
||||
public function is_enabled(): bool {
|
||||
$cfg = get_option('aksrt_download_config', []);
|
||||
if (!is_array($cfg)) {
|
||||
return true;
|
||||
}
|
||||
return !isset($cfg['enabled']) || !empty($cfg['enabled']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Effective download settings (aksrt_download_config), clamped so a
|
||||
* corrupted option can never break routing or accounting.
|
||||
@@ -97,6 +110,10 @@ class Download {
|
||||
}
|
||||
|
||||
public function register_rewrite(): void {
|
||||
if (!$this->is_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_rewrite_rule(
|
||||
'^' . preg_quote($this->config()['endpoint'], '/') . '/([A-Za-z0-9]{1,64})/?$',
|
||||
'index.php?' . self::QUERY_VAR . '=$matches[1]',
|
||||
@@ -105,11 +122,12 @@ class Download {
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-flush rewrite rules whenever the configured alias changes, using
|
||||
* the same version-marker approach as Auth\Router.
|
||||
* Re-flush rewrite rules whenever the configured alias or the master
|
||||
* switch changes, using the same version-marker approach as Auth\Router.
|
||||
*/
|
||||
public function maybe_flush_rewrite(): void {
|
||||
$version = AKSRT_VERSION . ':download-endpoint:' . $this->config()['endpoint'];
|
||||
$endpoint = $this->is_enabled() ? $this->config()['endpoint'] : 'off';
|
||||
$version = AKSRT_VERSION . ':download-endpoint:' . $endpoint;
|
||||
if ((string) get_option('aksrt_dl_rewrite_version') !== $version) {
|
||||
flush_rewrite_rules(false);
|
||||
update_option('aksrt_dl_rewrite_version', $version);
|
||||
@@ -122,17 +140,15 @@ class Download {
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
if (!$this->is_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
register_rest_route('aksrt/v1', '/download/request', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'rest_request'],
|
||||
'permission_callback' => [$this, 'check_rest_nonce'],
|
||||
]);
|
||||
|
||||
register_rest_route('aksrt/v1', '/download/policy/(?P<id>\d+)', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'rest_policy'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
}
|
||||
|
||||
public function check_rest_nonce(\WP_REST_Request $request) {
|
||||
@@ -155,63 +171,6 @@ class Download {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rest_policy(\WP_REST_Request $request) {
|
||||
$post_id = (int) $request['id'];
|
||||
$post = get_post($post_id);
|
||||
if (!$post || !function_exists('aksrt_is_downloadable_content') || !aksrt_is_downloadable_content($post)) {
|
||||
return new \WP_Error('aksrt_invalid', __('内容不存在或未启用下载能力', 'aksrt'), ['status' => 404]);
|
||||
}
|
||||
|
||||
$meta = function_exists('aksrt_get_download_box_meta') ? aksrt_get_download_box_meta($post) : [];
|
||||
$cost = aksrt_resource_download_cost($post);
|
||||
$uid = get_current_user_id();
|
||||
$priced = function_exists('aksrt_get_user_pay_price') ? aksrt_get_user_pay_price($post, $uid) : null;
|
||||
$pay_modo = is_array($priced)
|
||||
? ((($priced['modo'] ?? '0') === 'points') ? 'points' : '0')
|
||||
: ((($meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0');
|
||||
$display_price = is_array($priced)
|
||||
? ($priced['amount'] ?? ($pay_modo === 'points' ? 0 : '0.00'))
|
||||
: (($pay_modo === 'points') ? (int) ($meta['points_price'] ?? 0) : (string) ($meta['price'] ?? '0.00'));
|
||||
|
||||
$access = class_exists('AKSRT\\Content\\Visibility')
|
||||
? Visibility::get_post_access_state($post, $uid)
|
||||
: [];
|
||||
|
||||
$need_captcha = function_exists('aksrt_is_captcha_enabled_for') && aksrt_is_captcha_enabled_for('download');
|
||||
|
||||
return new \WP_REST_Response([
|
||||
'post_id' => $post_id,
|
||||
'price' => $display_price,
|
||||
'base_price' => is_array($priced) ? ($priced['base'] ?? $display_price) : $display_price,
|
||||
'pay_modo' => $pay_modo,
|
||||
'pay_limit' => (int) ($meta['pay_limit'] ?? 0),
|
||||
'cost' => $cost,
|
||||
'require_login' => !empty($access['need_login']),
|
||||
'require_captcha' => $need_captcha,
|
||||
'logged_in' => $uid > 0,
|
||||
'balance' => $uid > 0 ? \AKSRT\Ledger\LedgerService::get_instance()->balance($uid, \AKSRT\Ledger\AssetType::POINTS) : 0,
|
||||
'has_paid_access' => !empty($access['has_paid_access']),
|
||||
'need_purchase' => !empty($access['need_purchase']),
|
||||
'need_vip' => !empty($access['need_vip']),
|
||||
'need_login' => !empty($access['need_login']) && $uid <= 0,
|
||||
'can_download' => !empty($access['can_download']),
|
||||
'login_url' => wp_login_url(get_permalink($post)),
|
||||
'vip_level' => (int) ($access['user_vip_level'] ?? 0),
|
||||
'free_limit' => $uid > 0 && function_exists('aksrt_get_user_free_download_limit') ? aksrt_get_user_free_download_limit($uid) : 0,
|
||||
'free_used' => $uid > 0 && function_exists('aksrt_get_user_free_downloaded_number') ? aksrt_get_user_free_downloaded_number($uid) : 0,
|
||||
'free_surplus' => $uid > 0 && function_exists('aksrt_get_free_download_surplus') ? aksrt_get_free_download_surplus($uid) : null,
|
||||
'sources' => array_map(function ($row, $idx) {
|
||||
$extract_code = trim((string) ($row['extract_code'] ?? ''));
|
||||
return [
|
||||
'index' => $idx,
|
||||
'label' => $row['label'] ?? '',
|
||||
'type' => $row['type'] ?? 'direct',
|
||||
'has_extract' => $extract_code !== '',
|
||||
];
|
||||
}, $meta['downloads'] ?? [], array_keys($meta['downloads'] ?? [])),
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function rest_request(\WP_REST_Request $request) {
|
||||
$params = $request->get_json_params();
|
||||
if (!is_array($params)) $params = $request->get_params();
|
||||
@@ -303,6 +262,11 @@ class Download {
|
||||
$this->fail_410();
|
||||
}
|
||||
|
||||
// Master switch off: the token system is retired, links are dead ends.
|
||||
if (!$this->is_enabled()) {
|
||||
$this->fail_410();
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table = \AKSRT\Core\DBMigrator::table('dl_token');
|
||||
if (!$table) $this->fail_410();
|
||||
|
||||
Reference in New Issue
Block a user