'array', 'sanitize_callback' => [$this, 'sanitize_settings'], 'default' => leexport_default_settings(), ]); } public function sanitize_settings($raw): array { $out = leexport_get_settings(); $defaults = leexport_default_settings(); if (!is_array($raw)) { return $out; } // Post types. if (isset($raw['post_types']) && is_array($raw['post_types'])) { $post_types = []; foreach ($raw['post_types'] as $pt) { $pt = sanitize_key((string)$pt); if ($pt !== '') { $post_types[] = $pt; } } $out['post_types'] = $post_types ?: $defaults['post_types']; } // Fields. if (isset($raw['fields']) && is_array($raw['fields'])) { $merged = array_merge($defaults['fields'], is_array($out['fields'] ?? null) ? $out['fields'] : []); foreach ($merged as $k => $_) { $merged[$k] = leexport_bool_int($raw['fields'][$k] ?? 0); } $out['fields'] = $merged; } // Date format. // Removed: custom date format. We use the WordPress date format setting. // Export options. if (isset($raw['export']) && is_array($raw['export'])) { $export = array_merge($defaults['export'], is_array($out['export'] ?? null) ? $out['export'] : []); $export['split_rows'] = leexport_sanitize_int($raw['export']['split_rows'] ?? $export['split_rows'], 0, 100000); $out['export'] = $export; } if (isset($raw['filters']) && is_array($raw['filters'])) { $out['filters'] = leexport_sanitize_filters($raw['filters']); } // Link check options. if (isset($raw['link_check']) && is_array($raw['link_check'])) { $link = array_merge($defaults['link_check'], is_array($out['link_check'] ?? null) ? $out['link_check'] : []); $ua = isset($raw['link_check']['user_agent']) ? (string)$raw['link_check']['user_agent'] : $defaults['link_check']['user_agent']; $ua = trim($ua); $link['enabled'] = leexport_bool_int($raw['link_check']['enabled'] ?? $link['enabled']); $link['max_items'] = leexport_sanitize_int($raw['link_check']['max_items'] ?? $link['max_items'], 1, 500); $link['batch_posts'] = leexport_sanitize_int($raw['link_check']['batch_posts'] ?? $link['batch_posts'], 1, 50); $link['batch_urls'] = leexport_sanitize_int($raw['link_check']['batch_urls'] ?? $link['batch_urls'], 1, 100); $link['include_internal'] = leexport_bool_int($raw['link_check']['include_internal'] ?? $link['include_internal']); $link['include_external'] = leexport_bool_int($raw['link_check']['include_external'] ?? $link['include_external']); $link['max_links'] = leexport_sanitize_int($raw['link_check']['max_links'] ?? $link['max_links'], 50, 5000); $link['allow_private_targets'] = leexport_bool_int($raw['link_check']['allow_private_targets'] ?? $link['allow_private_targets']); $link['timeout'] = leexport_sanitize_int($raw['link_check']['timeout'] ?? $link['timeout'], 2, 30); $link['user_agent'] = $ua !== '' ? $ua : $link['user_agent']; $out['link_check'] = $link; } return $out; } public function enqueue_assets(string $hook): void { if ($hook !== 'settings_page_leexport') { return; } wp_enqueue_style('leexport-admin', LEEXPORT_URL . 'assets/admin.css', [], LEEXPORT_VERSION); wp_enqueue_script('leexport-admin', LEEXPORT_URL . 'assets/admin.js', ['jquery'], LEEXPORT_VERSION, true); wp_localize_script('leexport-admin', 'LeExportAdmin', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'exportTabUrl' => admin_url('options-general.php?page=leexport&tab=export'), 'linkCheckTabUrl' => admin_url('options-general.php?page=leexport&tab=linkcheck'), 'nonce' => wp_create_nonce('leexport_ajax'), 'i18n' => [ 'idle' => __('Idle.', 'leexport'), 'mode_content_links' => __('Content links', 'leexport'), 'mode_site_urls' => __('Site URLs', 'leexport'), 'posts' => __('Posts', 'leexport'), 'urls_checked' => __('URLs checked', 'leexport'), 'status' => __('Status', 'leexport'), ], ]); } public function render_settings_page(): void { if (!current_user_can('manage_options')) { return; } $settings = leexport_get_settings(); $post_types = get_post_types(['public' => true], 'objects'); $categories = get_categories([ 'taxonomy' => 'category', 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC', ]); $filter_match_count = LeExport_Exporter::count_published_posts($settings); $topic_taxonomy_options = leexport_get_topic_taxonomy_options(); $active_topic_taxonomy = leexport_resolve_topic_taxonomy($settings); $topic_terms = []; if ($active_topic_taxonomy !== '') { $topic_terms = get_terms([ 'taxonomy' => $active_topic_taxonomy, 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC', ]); if (is_wp_error($topic_terms)) { $topic_terms = []; } } $link_scan = get_transient('leexport_link_scan_latest'); if (!is_array($link_scan)) { $link_scan = null; } // Read-only tab selector (GET); no state change, nonce not required. $leexport_tab = isset($_GET['tab']) ? sanitize_key(wp_unslash((string)$_GET['tab'])) : 'export'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $active_tab = $leexport_tab === 'linkcheck' ? 'linkcheck' : 'export'; $opt = leexport_settings_key(); ?>

>

$obj) : ?>

1) : ?>

__('ID', 'leexport'), 'title' => __('Title', 'leexport'), 'url' => __('URL', 'leexport'), 'categories' => __('Categories (names)', 'leexport'), 'category_urls' => __('Category URLs', 'leexport'), 'tags' => __('Tags (names)', 'leexport'), 'tag_urls' => __('Tag URLs', 'leexport'), 'published_date' => __('Published Date', 'leexport'), ]; if ($active_topic_taxonomy !== '') { $topic_label = $topic_taxonomy_options[$active_topic_taxonomy] ?? __('Topics', 'leexport'); /* translators: %s: topic taxonomy label, e.g. Topics */ $fields['topics'] = sprintf(__('%s (names)', 'leexport'), $topic_label); /* translators: %s: topic taxonomy label, e.g. Topics */ $fields['topic_urls'] = sprintf(__('%s URLs', 'leexport'), $topic_label); } foreach ($fields as $k => $label) : ?>



>



<?php echo esc_attr__('WeChat QR code', 'leexport'); ?>

· By

'forbidden'], 403); } check_ajax_referer('leexport_ajax', 'nonce'); } public function ajax_scan_start(): void { $this->ajax_require_permissions(); $settings = leexport_get_settings(); if (empty($settings['link_check']['enabled'])) { wp_send_json_error(['message' => 'disabled'], 400); } $mode = isset($_POST['mode']) ? sanitize_key(wp_unslash((string)$_POST['mode'])) : 'site_urls'; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified in ajax_require_permissions(). $user_id = get_current_user_id(); $job = LeExport_Scan_Jobs::start_job($user_id, $settings, $mode); wp_send_json_success(['job' => $job]); } public function ajax_scan_poll(): void { $this->ajax_require_permissions(); $settings = leexport_get_settings(); $user_id = get_current_user_id(); $batch_posts = (int)($settings['link_check']['batch_posts'] ?? 10); $batch_urls = (int)($settings['link_check']['batch_urls'] ?? 25); $job = LeExport_Scan_Jobs::run_batch($user_id, $settings, $batch_posts, $batch_urls); wp_send_json_success(['job' => $job]); } public function ajax_scan_cancel(): void { $this->ajax_require_permissions(); $user_id = get_current_user_id(); LeExport_Scan_Jobs::clear_job($user_id); wp_send_json_success(['ok' => true]); } }