db = WP_Domain_Mapping_DB::get_instance(); // 添加菜单页面 add_action('network_admin_menu', array($this, 'add_menu_page'), 20); // 处理表单提交 add_action('admin_init', array($this, 'handle_form_submission')); // AJAX处理程序 add_action('wp_ajax_dm_import_csv', array($this, 'ajax_import_csv')); } /** * 添加导入/导出菜单 */ public function add_menu_page() { add_submenu_page( 'settings.php', __('Import/Export Domains', 'wp-domain-mapping'), __('Import/Export Domains', 'wp-domain-mapping'), 'manage_network', 'domain-mapping-import-export', array($this, 'render_page') ); } /** * 渲染导入/导出页面 */ public function render_page() { // 检查权限 if (!current_user_can('manage_network')) { wp_die(__('You do not have sufficient permissions to access this page.', 'wp-domain-mapping')); } // 输出成功消息(如果有) if (isset($_GET['imported']) && $_GET['imported']) { $count = intval($_GET['imported']); echo '

' . sprintf( _n( '%d domain mapping imported successfully.', '%d domain mappings imported successfully.', $count, 'wp-domain-mapping' ), $count ) . '

'; } if (isset($_GET['export']) && $_GET['export'] == 'success') { echo '

' . __('Domain mappings exported successfully.', 'wp-domain-mapping') . '

'; } // 显示页面 ?>



blog_id domain active
1 example.com 1
2 example.org 0
handle_export(); } } /** * 处理CSV导出 */ private function handle_export() { // 检查权限 if (!current_user_can('manage_network')) { wp_die(__('You do not have sufficient permissions to export data.', 'wp-domain-mapping')); } // 验证nonce if (!isset($_POST['domain_mapping_export_nonce']) || !wp_verify_nonce($_POST['domain_mapping_export_nonce'], 'domain_mapping_export')) { wp_die(__('Invalid security token. Please try again.', 'wp-domain-mapping')); } // 获取选项 $include_header = isset($_POST['include_header']) ? (bool) $_POST['include_header'] : false; $blog_id_filter = isset($_POST['blog_id_filter']) && !empty($_POST['blog_id_filter']) ? intval($_POST['blog_id_filter']) : 0; // 获取域名映射数据 global $wpdb; $table = $wpdb->base_prefix . WP_DOMAIN_MAPPING_TABLE_DOMAINS; $sql = "SELECT blog_id, domain, active FROM {$table}"; if ($blog_id_filter > 0) { $sql .= $wpdb->prepare(" WHERE blog_id = %d", $blog_id_filter); } $domains = $wpdb->get_results($sql, ARRAY_A); if (empty($domains)) { // 没有数据 wp_redirect(add_query_arg(array('page' => 'domain-mapping-import-export', 'export' => 'empty'), network_admin_url('settings.php'))); exit; } // 设置CSV输出 $filename = 'domain-mappings-' . date('Y-m-d') . '.csv'; header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=' . $filename); $output = fopen('php://output', 'w'); // 添加标题行 if ($include_header) { fputcsv($output, array('blog_id', 'domain', 'active')); } // 添加数据行 foreach ($domains as $domain) { fputcsv($output, $domain); } fclose($output); exit; } /** * AJAX处理CSV导入 */ public function ajax_import_csv() { // 检查权限 if (!current_user_can('manage_network')) { wp_send_json_error(__('You do not have sufficient permissions to import data.', 'wp-domain-mapping')); } // 验证nonce if (!isset($_POST['domain_mapping_import_nonce']) || !wp_verify_nonce($_POST['domain_mapping_import_nonce'], 'domain_mapping_import')) { wp_send_json_error(__('Invalid security token. Please try again.', 'wp-domain-mapping')); } // 检查文件 if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] != UPLOAD_ERR_OK) { wp_send_json_error(__('No file uploaded or upload error.', 'wp-domain-mapping')); } // 获取选项 $has_header = isset($_POST['has_header']) ? (bool) $_POST['has_header'] : false; $update_existing = isset($_POST['update_existing']) ? (bool) $_POST['update_existing'] : false; $validate_sites = isset($_POST['validate_sites']) ? (bool) $_POST['validate_sites'] : true; // 打开文件 $file = fopen($_FILES['csv_file']['tmp_name'], 'r'); if (!$file) { wp_send_json_error(__('Could not open the uploaded file.', 'wp-domain-mapping')); } // 初始化计数器和日志 $imported = 0; $skipped = 0; $errors = 0; $log = array(); // 跳过标题行 if ($has_header) { fgetcsv($file); } // 处理每一行 $core = WP_Domain_Mapping_Core::get_instance(); $row_num = $has_header ? 2 : 1; // 考虑标题行 while (($data = fgetcsv($file)) !== false) { // 检查数据格式 if (count($data) < 3) { $log[] = array( 'status' => 'error', 'message' => sprintf(__('Row %d: Invalid format. Expected at least 3 columns.', 'wp-domain-mapping'), $row_num) ); $errors++; $row_num++; continue; } // 解析数据 $blog_id = intval($data[0]); $domain = $core->clean_domain(trim($data[1])); $active = intval($data[2]); // 验证blog_id if ($blog_id <= 0) { $log[] = array( 'status' => 'error', 'message' => sprintf(__('Row %d: Invalid blog ID: %d', 'wp-domain-mapping'), $row_num, $blog_id) ); $errors++; $row_num++; continue; } // 验证站点是否存在 if ($validate_sites && !get_blog_details($blog_id)) { $log[] = array( 'status' => 'error', 'message' => sprintf(__('Row %d: Site ID %d does not exist.', 'wp-domain-mapping'), $row_num, $blog_id) ); $errors++; $row_num++; continue; } // 验证域名格式 if (!$core->validate_domain($domain)) { $log[] = array( 'status' => 'error', 'message' => sprintf(__('Row %d: Invalid domain format: %s', 'wp-domain-mapping'), $row_num, $domain) ); $errors++; $row_num++; continue; } // 检查域名是否已经存在于其他站点 global $wpdb; $table = $wpdb->base_prefix . WP_DOMAIN_MAPPING_TABLE_DOMAINS; $existing = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $table WHERE domain = %s", $domain )); if ($existing) { if ($existing->blog_id != $blog_id) { $log[] = array( 'status' => 'error', 'message' => sprintf(__('Row %d: Domain %s is already mapped to blog ID %d.', 'wp-domain-mapping'), $row_num, $domain, $existing->blog_id) ); $errors++; } elseif (!$update_existing) { $log[] = array( 'status' => 'warning', 'message' => sprintf(__('Row %d: Domain %s already exists for blog ID %d. Skipped.', 'wp-domain-mapping'), $row_num, $domain, $blog_id) ); $skipped++; } else { // 更新现有域名 $result = $wpdb->update( $table, array('active' => $active), array('domain' => $domain), array('%d'), array('%s') ); if ($result !== false) { $log[] = array( 'status' => 'success', 'message' => sprintf(__('Row %d: Updated domain %s for blog ID %d.', 'wp-domain-mapping'), $row_num, $domain, $blog_id) ); $imported++; } else { $log[] = array( 'status' => 'error', 'message' => sprintf(__('Row %d: Failed to update domain %s for blog ID %d.', 'wp-domain-mapping'), $row_num, $domain, $blog_id) ); $errors++; } } } else { // 添加新域名 $result = $wpdb->insert( $table, array( 'blog_id' => $blog_id, 'domain' => $domain, 'active' => $active ), array('%d', '%s', '%d') ); if ($result) { // 记录操作 $this->db->log_action('import', $domain, $blog_id); // 清除缓存 $this->db->invalidate_domain_cache($blog_id); $log[] = array( 'status' => 'success', 'message' => sprintf(__('Row %d: Added domain %s for blog ID %d.', 'wp-domain-mapping'), $row_num, $domain, $blog_id) ); $imported++; } else { $log[] = array( 'status' => 'error', 'message' => sprintf(__('Row %d: Failed to add domain %s for blog ID %d.', 'wp-domain-mapping'), $row_num, $domain, $blog_id) ); $errors++; } } $row_num++; } fclose($file); // 构建响应 $message = sprintf( __('Import completed: %d imported, %d skipped, %d errors.', 'wp-domain-mapping'), $imported, $skipped, $errors ); wp_send_json_success(array( 'message' => $message, 'imported' => $imported, 'skipped' => $skipped, 'errors' => $errors, 'details' => $log )); } }