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
));
}
}