Resolve post list mode from global list_type + surface card overrides so homepage/archives/AJAX honor admin list and card style settings.
625 lines
28 KiB
PHP
625 lines
28 KiB
PHP
<?php
|
|
/**
|
|
* AKSRT Admin — Global & Functions Controller
|
|
*
|
|
* Handles REST routes for the "全局&功能" domain:
|
|
* SEO, email/SMTP, footer, floating buttons, footer tabbar,
|
|
* friend links, CMS features, homepage settings, category recommend.
|
|
*
|
|
* @package AKSRT
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
class AKSRT_Admin_Global_Controller extends AKSRT_Admin_Controller_Base {
|
|
use AKSRT_Admin_Global_Controller_Part_1;
|
|
use AKSRT_Admin_Global_Controller_Part_2;
|
|
use AKSRT_Admin_Homepage_Settings_Rest;
|
|
|
|
|
|
private static $instance = null;
|
|
|
|
public static function get_instance(): self {
|
|
if (null === self::$instance) self::$instance = new self();
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Register all routes for the global domain.
|
|
*/
|
|
public function register_routes(): void {
|
|
// Email / SMTP
|
|
register_rest_route(self::API_NAMESPACE, '/settings/mail', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_mail'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
register_rest_route(self::API_NAMESPACE, '/mail/test', [
|
|
'methods' => 'POST',
|
|
'callback' => [$this, 'rest_test_mail'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Footer
|
|
register_rest_route(self::API_NAMESPACE, '/settings/footer', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_footer_settings'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Footer Tabbar
|
|
register_rest_route(self::API_NAMESPACE, '/settings/footer-tabbar', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_footer_tabbar'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
register_rest_route(self::API_NAMESPACE, '/settings/footer-tabbar/reorder', [
|
|
'methods' => 'POST',
|
|
'callback' => [$this, 'rest_reorder_footer_tabbar'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Floating Buttons
|
|
register_rest_route(self::API_NAMESPACE, '/settings/floating-buttons', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_floating_buttons'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
register_rest_route(self::API_NAMESPACE, '/settings/floating-buttons/reorder', [
|
|
'methods' => 'POST',
|
|
'callback' => [$this, 'rest_reorder_floating_buttons'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Friend Links
|
|
register_rest_route(self::API_NAMESPACE, '/friend-links', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_friend_links'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
register_rest_route(self::API_NAMESPACE, '/friend-links/(?P<id>\d+)', [
|
|
'methods' => 'DELETE',
|
|
'callback' => [$this, 'rest_delete_friend_link'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
register_rest_route(self::API_NAMESPACE, '/friend-links/reorder', [
|
|
'methods' => 'POST',
|
|
'callback' => [$this, 'rest_reorder_friend_links'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// CMS Features
|
|
register_rest_route(self::API_NAMESPACE, '/settings/cms-features', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_cms_features'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Homepage settings
|
|
register_rest_route(self::API_NAMESPACE, '/settings/homepage', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_homepage_settings'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Category recommend
|
|
register_rest_route(self::API_NAMESPACE, '/settings/category-recommend', [
|
|
'methods' => ['GET', 'POST'],
|
|
'callback' => [$this, 'rest_handle_category_recommend'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Categories list (for admin selectors)
|
|
register_rest_route(self::API_NAMESPACE, '/categories', [
|
|
'methods' => 'GET',
|
|
'callback' => [$this, 'rest_get_categories'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Category term meta
|
|
register_rest_route(self::API_NAMESPACE, '/categories/(?P<id>\d+)/meta', [
|
|
'methods' => 'POST',
|
|
'callback' => [$this, 'rest_update_category_meta'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// Homepage tab posts (public)
|
|
register_rest_route(self::API_NAMESPACE, '/homepage/tab-posts', [
|
|
'methods' => 'GET',
|
|
'callback' => [$this, 'rest_homepage_tab_posts'],
|
|
'permission_callback' => '__return_true',
|
|
'args' => [
|
|
'term_id' => ['type' => 'integer', 'required' => true, 'sanitize_callback' => 'absint'],
|
|
'page' => ['type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint'],
|
|
'per_page' => ['type' => 'integer', 'default' => 10, 'sanitize_callback' => 'absint'],
|
|
'sort' => ['type' => 'string', 'default' => 'modified', 'sanitize_callback' => 'sanitize_text_field'],
|
|
'view_mode' => ['type' => 'string', 'default' => 'list', 'sanitize_callback' => 'sanitize_text_field'],
|
|
'page_url' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'esc_url_raw'],
|
|
'panel' => ['type' => 'string', 'default' => 'latest', 'sanitize_callback' => 'sanitize_key'],
|
|
'source' => ['type' => 'string', 'default' => 'home', 'sanitize_callback' => 'sanitize_key'],
|
|
'tab_orderby' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_key'],
|
|
],
|
|
]);
|
|
|
|
// Archive AJAX filter (public) — §2.5/§2.6/§2.7
|
|
register_rest_route(self::API_NAMESPACE, '/archive/posts', [
|
|
'methods' => 'GET',
|
|
'callback' => [$this, 'rest_archive_posts'],
|
|
'permission_callback' => '__return_true',
|
|
'args' => [
|
|
'archive_type' => ['type' => 'string', 'default' => 'category', 'sanitize_callback' => 'sanitize_key'],
|
|
'term_id' => ['type' => 'integer', 'default' => 0, 'sanitize_callback' => 'absint'],
|
|
'filter_cat' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
|
|
'filter_tag' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
|
|
'sort' => ['type' => 'string', 'default' => 'date', 'sanitize_callback' => 'sanitize_key'],
|
|
'order' => ['type' => 'string', 'default' => 'DESC', 'sanitize_callback' => 'sanitize_key'],
|
|
'page' => ['type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint'],
|
|
'per_page' => ['type' => 'integer', 'default' => 10, 'sanitize_callback' => 'absint'],
|
|
'custom_filters' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
|
|
],
|
|
]);
|
|
|
|
// Homepage categories (for admin tab editor)
|
|
register_rest_route(self::API_NAMESPACE, '/homepage/categories', [
|
|
'methods' => 'GET',
|
|
'callback' => [$this, 'rest_homepage_categories'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
]);
|
|
|
|
// User search (for admin user selectors)
|
|
register_rest_route(self::API_NAMESPACE, '/users/search', [
|
|
'methods' => 'GET',
|
|
'callback' => [$this, 'rest_search_users'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
'args' => [
|
|
'search' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
|
|
'number' => ['type' => 'integer', 'default' => 20, 'sanitize_callback' => 'absint'],
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function rest_handle_cms_features(WP_REST_Request $request): WP_REST_Response {
|
|
if ($request->get_method() === 'GET') {
|
|
return $this->success(['cms_features' => AKSRT_Settings::get_cms_features()]);
|
|
}
|
|
|
|
$params = $this->get_json_params($request);
|
|
$allowed = [
|
|
'resource_cpt_enabled' => 'bool',
|
|
'download_login' => 'bool',
|
|
'download_credit' => 'bool',
|
|
'download_captcha' => 'bool',
|
|
'search_include_resource' => 'bool',
|
|
];
|
|
$sanitized = $this->sanitize_fields($params, $allowed);
|
|
$settings = AKSRT_Settings::get_all();
|
|
$settings['cms_features'] = array_merge(
|
|
is_array($settings['cms_features'] ?? null) ? $settings['cms_features'] : [],
|
|
$sanitized
|
|
);
|
|
update_option('aksrt_settings', $settings);
|
|
AKSRT_Settings::flush_settings_cache();
|
|
|
|
return $this->success(['message' => 'CMS 功能已保存', 'cms_features' => AKSRT_Settings::get_cms_features()]);
|
|
}
|
|
|
|
public function rest_handle_mail(WP_REST_Request $request): WP_REST_Response {
|
|
$option_key = 'aksrt_mail_config';
|
|
|
|
if ($request->get_method() === 'GET') {
|
|
$config = get_option($option_key, [
|
|
'smtp_host' => '',
|
|
'smtp_port' => 465,
|
|
'smtp_user' => '',
|
|
'smtp_pass' => '',
|
|
'smtp_secure' => 'ssl',
|
|
'from_email' => '',
|
|
'from_name' => '',
|
|
]);
|
|
return $this->success(['data' => $config, 'code' => 'success']);
|
|
}
|
|
|
|
$params = $this->get_json_params($request);
|
|
$current = get_option($option_key, []);
|
|
$merged = array_merge(is_array($current) ? $current : [], $params);
|
|
update_option($option_key, $merged);
|
|
|
|
return $this->success(['message' => '邮件配置已保存', 'code' => 'success']);
|
|
}
|
|
|
|
public function rest_test_mail(WP_REST_Request $request): WP_REST_Response {
|
|
$params = $this->get_json_params($request);
|
|
$to = sanitize_email($params['to'] ?? '');
|
|
if (!is_email($to)) {
|
|
return $this->error(__('请输入有效的邮箱地址', 'aksrt'));
|
|
}
|
|
|
|
$sent = wp_mail($to, __('AKSRT 邮件测试', 'aksrt'), __('如果你收到这封邮件,说明 SMTP 配置正确。', 'aksrt'));
|
|
if ($sent) {
|
|
return $this->success(['message' => '测试邮件已发送']);
|
|
}
|
|
return $this->error(__('邮件发送失败,请检查 SMTP 配置', 'aksrt'));
|
|
}
|
|
|
|
public function rest_homepage_tab_posts(WP_REST_Request $request): WP_REST_Response {
|
|
$term_id = (int) $request->get_param('term_id');
|
|
$page = max(1, (int) $request->get_param('page'));
|
|
$per_page = min(50, max(1, (int) $request->get_param('per_page')));
|
|
$sort = sanitize_key($request->get_param('sort') ?: 'modified');
|
|
$view_mode = sanitize_key($request->get_param('view_mode') ?: 'list');
|
|
$tab_orderby = sanitize_key($request->get_param('tab_orderby') ?: '');
|
|
$panel = sanitize_key($request->get_param('panel') ?: 'latest');
|
|
|
|
$post_types = function_exists('aksrt_homepage_get_post_types')
|
|
? aksrt_homepage_get_post_types()
|
|
: ['post'];
|
|
|
|
$args = [
|
|
'post_type' => $post_types,
|
|
'post_status' => 'publish',
|
|
'posts_per_page' => $per_page,
|
|
'paged' => $page,
|
|
'ignore_sticky_posts' => $term_id > 0,
|
|
];
|
|
|
|
if ($term_id > 0) {
|
|
$term = get_term($term_id);
|
|
$taxonomy = ($term && !is_wp_error($term)) ? (string) $term->taxonomy : 'category';
|
|
if (!in_array($taxonomy, ['category', 'topics'], true)) {
|
|
$taxonomy = 'category';
|
|
}
|
|
$args['tax_query'] = [[
|
|
'taxonomy' => $taxonomy,
|
|
'field' => 'term_id',
|
|
'terms' => [$term_id],
|
|
]];
|
|
}
|
|
|
|
$exclude_ids = class_exists('AKSRT_Settings')
|
|
? AKSRT_Settings::home_exclude_post_ids()
|
|
: [];
|
|
if (!empty($exclude_ids)) {
|
|
$args['post__not_in'] = $exclude_ids;
|
|
}
|
|
|
|
if ($panel === 'latest' || $term_id <= 0) {
|
|
$exclude_cat_ids = class_exists('AKSRT_Settings')
|
|
? AKSRT_Settings::home_exclude_category_ids()
|
|
: [];
|
|
if (!empty($exclude_cat_ids)) {
|
|
$args['category__not_in'] = $exclude_cat_ids;
|
|
}
|
|
}
|
|
|
|
$effective_sort = $tab_orderby !== '' ? $tab_orderby : $sort;
|
|
if (function_exists('aksrt_homepage_apply_named_sort_args')) {
|
|
$args = aksrt_homepage_apply_named_sort_args($args, $effective_sort);
|
|
} else {
|
|
$args['orderby'] = 'date';
|
|
$args['order'] = 'DESC';
|
|
}
|
|
|
|
$query = new WP_Query($args);
|
|
|
|
$mode = in_array($view_mode, ['card', 'list'], true) ? $view_mode : '';
|
|
$html = '';
|
|
if (function_exists('aksrt_render_post_list')) {
|
|
$overrides = ['context' => 'home'];
|
|
if ($mode !== '') {
|
|
$overrides['mode'] = $mode;
|
|
}
|
|
$render_config = function_exists('aksrt_resolve_post_list_render_config')
|
|
? aksrt_resolve_post_list_render_config([
|
|
'context' => 'home',
|
|
'overrides' => $overrides,
|
|
])
|
|
: array_merge(['mode' => ($mode !== '' ? $mode : 'list'), 'context' => 'home'], $overrides);
|
|
$html = aksrt_render_post_list($query, $render_config, false);
|
|
} elseif ($query->have_posts()) {
|
|
$html = '<div class="posts-row aksrt-homepage__posts" data-view="' . esc_attr($mode) . '">';
|
|
while ($query->have_posts()) {
|
|
$query->the_post();
|
|
if (function_exists('aksrt_homepage_render_post_card')) {
|
|
ob_start();
|
|
aksrt_homepage_render_post_card();
|
|
$html .= ob_get_clean();
|
|
}
|
|
}
|
|
$html .= '</div>';
|
|
wp_reset_postdata();
|
|
}
|
|
|
|
$has_more = $page < (int) $query->max_num_pages;
|
|
|
|
return $this->success([
|
|
'html' => $html,
|
|
'total' => (int) $query->found_posts,
|
|
'has_more' => $has_more,
|
|
]);
|
|
}
|
|
|
|
public function rest_archive_posts(WP_REST_Request $request): WP_REST_Response {
|
|
return $this->rest_homepage_tab_posts($request);
|
|
}
|
|
|
|
public function rest_homepage_categories(): WP_REST_Response {
|
|
$data = [];
|
|
|
|
$cats = get_categories(['hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC']);
|
|
foreach ($cats as $cat) {
|
|
$data[] = [
|
|
'id' => (int) $cat->term_id,
|
|
'term_id' => (int) $cat->term_id,
|
|
'name' => $cat->name,
|
|
'slug' => $cat->slug,
|
|
'count' => (int) $cat->count,
|
|
'parent' => (int) $cat->parent,
|
|
'taxonomy' => 'category',
|
|
];
|
|
}
|
|
|
|
if (taxonomy_exists('topics')) {
|
|
$topics = get_terms([
|
|
'taxonomy' => 'topics',
|
|
'hide_empty' => false,
|
|
'orderby' => 'name',
|
|
'order' => 'ASC',
|
|
]);
|
|
if (!is_wp_error($topics)) {
|
|
foreach ($topics as $term) {
|
|
$data[] = [
|
|
'id' => (int) $term->term_id,
|
|
'term_id' => (int) $term->term_id,
|
|
'name' => $term->name,
|
|
'slug' => $term->slug,
|
|
'count' => (int) $term->count,
|
|
'parent' => (int) $term->parent,
|
|
'taxonomy' => 'topics',
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->success(['data' => $data]);
|
|
}
|
|
|
|
public function rest_handle_friend_links(WP_REST_Request $request): WP_REST_Response {
|
|
if ($request->get_method() === 'GET') {
|
|
$links = aksrt_get_friend_links();
|
|
return rest_ensure_response(['code' => 'success', 'data' => $links]);
|
|
}
|
|
|
|
$params = $this->get_json_params($request);
|
|
$links = get_option('aksrt_friend_links', []);
|
|
$new_link = [
|
|
'id' => uniqid('fl_'),
|
|
'name' => sanitize_text_field($params['name'] ?? ''),
|
|
'url' => esc_url_raw($params['url'] ?? ''),
|
|
'logo' => esc_url_raw($params['logo'] ?? ''),
|
|
'description' => sanitize_textarea_field($params['description'] ?? ''),
|
|
'sort_order' => (int) ($params['sort_order'] ?? 0),
|
|
'active' => 1,
|
|
];
|
|
$links[] = $new_link;
|
|
usort($links, function ($a, $b) {
|
|
return ($a['sort_order'] ?? 0) <=> ($b['sort_order'] ?? 0);
|
|
});
|
|
update_option('aksrt_friend_links', $links);
|
|
|
|
return rest_ensure_response(['code' => 'success', 'data' => $new_link, 'message' => __('Friend link added.', 'aksrt')]);
|
|
}
|
|
|
|
public function rest_delete_friend_link(WP_REST_Request $request): WP_REST_Response {
|
|
$id = $request->get_param('id');
|
|
$links = get_option('aksrt_friend_links', []);
|
|
$links = array_filter($links, function ($link) use ($id) {
|
|
return ($link['id'] ?? '') !== $id;
|
|
});
|
|
$links = array_values($links);
|
|
update_option('aksrt_friend_links', $links);
|
|
return rest_ensure_response(['code' => 'success', 'message' => __('Friend link deleted.', 'aksrt')]);
|
|
}
|
|
|
|
public function rest_reorder_friend_links(WP_REST_Request $request): WP_REST_Response {
|
|
$ordered_ids = $request->get_param('ids');
|
|
if (!is_array($ordered_ids)) {
|
|
return new WP_REST_Response(['code' => 'error', 'message' => __('参数错误', 'aksrt')], 400);
|
|
}
|
|
$links = get_option('aksrt_friend_links', []);
|
|
$order_map = array_flip($ordered_ids);
|
|
usort($links, function ($a, $b) use ($order_map) {
|
|
$idx_a = $order_map[($a['id'] ?? '')] ?? 999;
|
|
$idx_b = $order_map[($b['id'] ?? '')] ?? 999;
|
|
return $idx_a <=> $idx_b;
|
|
});
|
|
foreach ($links as $index => &$link) {
|
|
$link['sort_order'] = $index;
|
|
}
|
|
update_option('aksrt_friend_links', $links);
|
|
return rest_ensure_response(['code' => 'success', 'message' => __('Order saved.', 'aksrt')]);
|
|
}
|
|
|
|
public function rest_handle_footer_settings(WP_REST_Request $request): WP_REST_Response {
|
|
if ($request->get_method() === 'GET') {
|
|
$footer = get_option('aksrt_footer_settings', []);
|
|
$defaults = [
|
|
'contacts' => [],
|
|
'quick_links' => [],
|
|
'more_links' => [],
|
|
'hot_categories' => 5,
|
|
'copyright_text' => '',
|
|
'layout_template' => 'default',
|
|
'footer_t1_m_s' => ['pc', 'mobile'],
|
|
'footer_t1_img' => '',
|
|
'footer_t1_img_dark' => '',
|
|
'footer_t1_t' => '',
|
|
'fcode_t1_code' => '',
|
|
'footer_contact_m_s' => ['pc', 'mobile'],
|
|
'footer_contact_wechat_img' => '',
|
|
'footer_contact_qq' => '',
|
|
'footer_contact_weibo' => '',
|
|
'footer_contact_email' => '',
|
|
'footer_contact_more' => '',
|
|
'fcode_t2_code_1' => '',
|
|
'fcode_t2_code_2' => '',
|
|
'footer_mini_img_m_s' => ['pc', 'mobile'],
|
|
'footer_mini_img' => [],
|
|
'fcode_customize_code' => '',
|
|
];
|
|
$data = array_merge($defaults, $footer);
|
|
return rest_ensure_response(['code' => 'success', 'data' => $data]);
|
|
}
|
|
|
|
$params = $this->get_json_params($request);
|
|
$footer = [
|
|
'contacts' => isset($params['contacts']) ? $this->sanitize_contacts($params['contacts']) : [],
|
|
'quick_links' => isset($params['quick_links']) ? $this->sanitize_link_list($params['quick_links']) : [],
|
|
'more_links' => isset($params['more_links']) ? $this->sanitize_link_list($params['more_links']) : [],
|
|
'hot_categories' => (int) ($params['hot_categories'] ?? 5),
|
|
'copyright_text' => sanitize_textarea_field($params['copyright_text'] ?? ''),
|
|
'layout_template' => in_array($params['layout_template'] ?? '', ['default', 'compact', 'centered'], true)
|
|
? $params['layout_template'] : 'default',
|
|
'footer_t1_m_s' => $this->sanitize_device_visibility($params['footer_t1_m_s'] ?? ['pc', 'mobile']),
|
|
'footer_t1_img' => esc_url_raw($params['footer_t1_img'] ?? ''),
|
|
'footer_t1_img_dark' => esc_url_raw($params['footer_t1_img_dark'] ?? ''),
|
|
'footer_t1_t' => sanitize_text_field($params['footer_t1_t'] ?? ''),
|
|
'fcode_t1_code' => wp_kses_post($params['fcode_t1_code'] ?? ''),
|
|
'footer_contact_m_s' => $this->sanitize_device_visibility($params['footer_contact_m_s'] ?? ['pc', 'mobile']),
|
|
'footer_contact_wechat_img' => esc_url_raw($params['footer_contact_wechat_img'] ?? ''),
|
|
'footer_contact_qq' => sanitize_text_field($params['footer_contact_qq'] ?? ''),
|
|
'footer_contact_weibo' => sanitize_text_field($params['footer_contact_weibo'] ?? ''),
|
|
'footer_contact_email' => sanitize_email($params['footer_contact_email'] ?? ''),
|
|
'footer_contact_more' => isset($params['footer_contact_more']) && is_array($params['footer_contact_more'])
|
|
? $this->sanitize_contact_more($params['footer_contact_more']) : [],
|
|
'fcode_t2_code_1' => wp_kses_post($params['fcode_t2_code_1'] ?? ''),
|
|
'fcode_t2_code_2' => wp_kses_post($params['fcode_t2_code_2'] ?? ''),
|
|
'footer_mini_img_m_s' => $this->sanitize_device_visibility($params['footer_mini_img_m_s'] ?? ['pc', 'mobile']),
|
|
'footer_mini_img' => isset($params['footer_mini_img']) && is_array($params['footer_mini_img'])
|
|
? $this->sanitize_mini_img_group($params['footer_mini_img']) : [],
|
|
'fcode_customize_code' => wp_kses_post($params['fcode_customize_code'] ?? ''),
|
|
];
|
|
update_option('aksrt_footer_settings', $footer);
|
|
return rest_ensure_response(['code' => 'success', 'message' => __('Footer settings saved.', 'aksrt')]);
|
|
}
|
|
|
|
private function sanitize_contacts(array $contacts): array {
|
|
$allowed_icons = ['github', 'x', 'twitter', 'email', 'wechat', 'qq', 'weibo',
|
|
'telegram', 'discord', 'bilibili', 'linkedin', 'facebook',
|
|
'youtube', 'instagram', 'rss', 'web', 'globe'];
|
|
$clean = [];
|
|
foreach ($contacts as $item) {
|
|
$icon = sanitize_text_field($item['icon'] ?? '');
|
|
if (!in_array($icon, $allowed_icons)) {
|
|
continue;
|
|
}
|
|
$clean[] = [
|
|
'icon' => $icon,
|
|
'url' => esc_url_raw($item['url'] ?? ''),
|
|
'title' => sanitize_text_field($item['title'] ?? ''),
|
|
'enabled' => !empty($item['enabled']),
|
|
];
|
|
}
|
|
return $clean;
|
|
}
|
|
|
|
private function sanitize_link_list(array $links): array {
|
|
$clean = [];
|
|
foreach ($links as $item) {
|
|
$clean[] = [
|
|
'id' => isset($item['id']) ? sanitize_text_field($item['id']) : uniqid('link_'),
|
|
'name' => sanitize_text_field($item['name'] ?? ''),
|
|
'url' => esc_url_raw($item['url'] ?? '#'),
|
|
'enabled' => !empty($item['enabled']),
|
|
'sort_order' => (int) ($item['sort_order'] ?? 0),
|
|
];
|
|
}
|
|
return $clean;
|
|
}
|
|
|
|
private function sanitize_device_visibility($value): array {
|
|
$arr = is_array($value) ? $value : [$value];
|
|
$allowed = ['pc', 'mobile'];
|
|
$clean = array_values(array_intersect(array_map('sanitize_key', $arr), $allowed));
|
|
return $clean ?: ['pc', 'mobile'];
|
|
}
|
|
|
|
private function sanitize_contact_more(array $items): array {
|
|
$clean = [];
|
|
foreach ($items as $item) {
|
|
if (!is_array($item)) {
|
|
continue;
|
|
}
|
|
$clean[] = [
|
|
'desc' => sanitize_text_field($item['desc'] ?? ''),
|
|
'icon' => sanitize_text_field($item['icon'] ?? ''),
|
|
'link' => esc_url_raw($item['link'] ?? ''),
|
|
'img' => esc_url_raw($item['img'] ?? ''),
|
|
];
|
|
}
|
|
return $clean;
|
|
}
|
|
|
|
private function sanitize_mini_img_group(array $items): array {
|
|
$clean = [];
|
|
foreach ($items as $item) {
|
|
if (!is_array($item)) {
|
|
continue;
|
|
}
|
|
if (count($clean) >= 4) {
|
|
break;
|
|
}
|
|
$clean[] = [
|
|
'text' => sanitize_text_field($item['text'] ?? ''),
|
|
'img' => esc_url_raw($item['img'] ?? ''),
|
|
];
|
|
}
|
|
return $clean;
|
|
}
|
|
|
|
public function rest_handle_footer_tabbar(WP_REST_Request $request): WP_REST_Response {
|
|
if ($request->get_method() === 'GET') {
|
|
$settings = class_exists('AKSRT_Settings')
|
|
? AKSRT_Settings::get_footer_tabbar_settings()
|
|
: ['enabled' => true, 'scroll_hide' => false, 'scroll_down_hide' => true, 'items' => []];
|
|
return rest_ensure_response(['code' => 'success', 'data' => $settings]);
|
|
}
|
|
|
|
$params = $this->get_json_params($request);
|
|
$items = isset($params['items']) ? array_map([$this, 'sanitize_tabbar_item'], (array) $params['items']) : [];
|
|
|
|
$max_items = max(3, min(7, (int) ($params['max_items'] ?? 5)));
|
|
if (count($items) > $max_items) {
|
|
return new WP_REST_Response([
|
|
'code' => 'error',
|
|
'message' => sprintf(__('Footer tabbar supports at most %d items.', 'aksrt'), $max_items),
|
|
], 400);
|
|
}
|
|
|
|
$tabbar = [
|
|
'enabled' => !empty($params['enabled']),
|
|
'scroll_hide' => !empty($params['scroll_hide']),
|
|
'scroll_down_hide' => !empty($params['scroll_down_hide']),
|
|
'max_items' => $max_items,
|
|
'icon_size' => max(16, min(32, (int) ($params['icon_size'] ?? 22))),
|
|
'text_size' => max(8, min(14, (int) ($params['text_size'] ?? 10))),
|
|
'show_text' => !empty($params['show_text']),
|
|
'active_color' => sanitize_hex_color($params['active_color'] ?? '') ?: '#f04494',
|
|
'bg_color' => sanitize_hex_color($params['bg_color'] ?? '') ?: '',
|
|
'border' => !empty($params['border']),
|
|
'shadow' => !empty($params['shadow']),
|
|
'animation' => !empty($params['animation']),
|
|
'double_click_home' => !empty($params['double_click_home']),
|
|
'badge_dot' => !empty($params['badge_dot']),
|
|
'items' => $items,
|
|
];
|
|
update_option('aksrt_footer_tabbar', $tabbar);
|
|
|
|
if (class_exists('AKSRT_Settings')) {
|
|
AKSRT_Settings::flush_settings_cache();
|
|
}
|
|
|
|
return rest_ensure_response(['code' => 'success', 'message' => __('Footer tabbar settings saved.', 'aksrt')]);
|
|
}
|
|
|
|
}
|