mirror of
https://github.com/WenPai-org/wp-domain-mapping.git
synced 2025-08-03 05:33:23 +08:00
升级至 v2.0.1 稳定版
This commit is contained in:
parent
babbc3d05b
commit
8932ec9fa7
14 changed files with 2677 additions and 512 deletions
|
@ -335,7 +335,7 @@ function dm_domain_listing( $rows ) {
|
|||
</td>
|
||||
<td class="column-primary">
|
||||
<?php if ( $row->active == 1 ) : ?>
|
||||
<span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
|
||||
<span class="dashicons dashicons-yes" style="color: #46b450;"></span>
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'Yes', 'wp-domain-mapping' ); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="dashicons dashicons-no-alt" style="color: #dc3232;"></span>
|
||||
|
|
|
@ -80,7 +80,7 @@ function dm_render_admin_page() {
|
|||
'</p></div>';
|
||||
}
|
||||
?>
|
||||
<div class="card domain-mapping-card">
|
||||
|
||||
<!-- Tab Navigation -->
|
||||
<div class="domain-mapping-tabs">
|
||||
<?php foreach ( $tabs as $tab_key => $tab_label ) : ?>
|
||||
|
@ -110,7 +110,7 @@ function dm_render_admin_page() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function switchTab(tab) {
|
||||
// Update URL without reloading
|
||||
|
@ -837,12 +837,61 @@ function dm_render_health_content() {
|
|||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if WP China Yes plugin is active
|
||||
*/
|
||||
function dm_is_wp_china_yes_active() {
|
||||
if ( ! function_exists( 'is_plugin_active' ) ) {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
// Check for common WP China Yes plugin paths
|
||||
$possible_plugins = array(
|
||||
'wp-china-yes/wp-china-yes.php',
|
||||
'wp-china-yes/index.php',
|
||||
'wp-china-yes/main.php'
|
||||
);
|
||||
|
||||
foreach ( $possible_plugins as $plugin ) {
|
||||
if ( is_plugin_active( $plugin ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Also check if the WP_CHINA_YES constant is defined
|
||||
return defined( 'WP_CHINA_YES' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render import/export tab content
|
||||
*/
|
||||
function dm_render_import_export_content() {
|
||||
$wp_china_yes_active = dm_is_wp_china_yes_active();
|
||||
?>
|
||||
<div class="card domain-mapping-card">
|
||||
|
||||
<?php if ( ! $wp_china_yes_active ) : ?>
|
||||
<div class="notice notice-info inline">
|
||||
<p>
|
||||
<?php
|
||||
$wpcy_installed = class_exists('WP_China_Yes'); // 检查是否安装了文派叶子插件
|
||||
$wpcy_link = $wpcy_installed
|
||||
? admin_url('admin.php?page=wp-china-yes')
|
||||
: 'https://wpcy.com';
|
||||
|
||||
printf(
|
||||
__('Install the %s high-performance component to use batch domain import/export.', 'wp-domain-mapping'),
|
||||
sprintf(
|
||||
'<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
|
||||
esc_url($wpcy_link),
|
||||
__('文派叶子 🍃(WPCY.COM)', 'wp-domain-mapping')
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card domain-mapping-card" <?php echo ! $wp_china_yes_active ? 'style="opacity: 0.5; pointer-events: none;"' : ''; ?>>
|
||||
<h2><?php _e( 'Export Domain Mappings', 'wp-domain-mapping' ); ?></h2>
|
||||
<p><?php _e( 'Export all domain mappings to a CSV file.', 'wp-domain-mapping' ); ?></p>
|
||||
|
||||
|
@ -852,24 +901,24 @@ function dm_render_import_export_content() {
|
|||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label>
|
||||
<input type="checkbox" name="include_header" value="1" checked>
|
||||
<input type="checkbox" name="include_header" value="1" checked <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
<?php _e( 'Include column headers', 'wp-domain-mapping' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label for="blog_id_filter"><?php _e( 'Export for specific site ID (optional):', 'wp-domain-mapping' ); ?></label>
|
||||
<input type="number" id="blog_id_filter" name="blog_id_filter" min="1" class="regular-text">
|
||||
<input type="number" id="blog_id_filter" name="blog_id_filter" min="1" class="regular-text" <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
<p class="description"><?php _e( 'Leave empty to export all domains.', 'wp-domain-mapping' ); ?></p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Export to CSV', 'wp-domain-mapping' ); ?>">
|
||||
<input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Export to CSV', 'wp-domain-mapping' ); ?>" <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card domain-mapping-card">
|
||||
<div class="card domain-mapping-card" <?php echo ! $wp_china_yes_active ? 'style="opacity: 0.5; pointer-events: none;"' : ''; ?>>
|
||||
<h2><?php _e( 'Import Domain Mappings', 'wp-domain-mapping' ); ?></h2>
|
||||
<p><?php _e( 'Import domain mappings from a CSV file.', 'wp-domain-mapping' ); ?></p>
|
||||
|
||||
|
@ -879,7 +928,7 @@ function dm_render_import_export_content() {
|
|||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label for="csv_file"><?php _e( 'CSV File:', 'wp-domain-mapping' ); ?></label><br>
|
||||
<input type="file" id="csv_file" name="csv_file" accept=".csv" required>
|
||||
<input type="file" id="csv_file" name="csv_file" accept=".csv" required <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
<p class="description">
|
||||
<?php _e( 'The CSV file should have the columns: blog_id, domain, active (1 or 0).', 'wp-domain-mapping' ); ?><br>
|
||||
<?php _e( 'Example: 1,example.com,1', 'wp-domain-mapping' ); ?>
|
||||
|
@ -888,14 +937,14 @@ function dm_render_import_export_content() {
|
|||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label>
|
||||
<input type="checkbox" name="has_header" value="1" checked>
|
||||
<input type="checkbox" name="has_header" value="1" checked <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
<?php _e( 'First row contains column headers', 'wp-domain-mapping' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label>
|
||||
<input type="checkbox" name="update_existing" value="1" checked>
|
||||
<input type="checkbox" name="update_existing" value="1" checked <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
<?php _e( 'Update existing mappings', 'wp-domain-mapping' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php _e( 'If unchecked, will skip domains that already exist.', 'wp-domain-mapping' ); ?></p>
|
||||
|
@ -903,14 +952,14 @@ function dm_render_import_export_content() {
|
|||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label>
|
||||
<input type="checkbox" name="validate_sites" value="1" checked>
|
||||
<input type="checkbox" name="validate_sites" value="1" checked <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
<?php _e( 'Validate site IDs', 'wp-domain-mapping' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php _e( 'If checked, will only import domains for existing sites.', 'wp-domain-mapping' ); ?></p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Import from CSV', 'wp-domain-mapping' ); ?>">
|
||||
<input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Import from CSV', 'wp-domain-mapping' ); ?>" <?php echo ! $wp_china_yes_active ? 'disabled' : ''; ?>>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
|
@ -962,6 +1011,7 @@ function dm_render_import_export_content() {
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<?php if ( $wp_china_yes_active ) : ?>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
$('#domain-mapping-import-form').on('submit', function(e) {
|
||||
|
@ -1047,6 +1097,7 @@ function dm_render_import_export_content() {
|
|||
});
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
|
|
@ -155,3 +155,20 @@ $domains = isset($domains) ? $domains : array();
|
|||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
// Make Primary 按钮 AJAX 处理
|
||||
$('.button[href*="action=primary"]').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var href = $button.attr('href');
|
||||
var domain = new URLSearchParams(href.split('?')[1]).get('domain');
|
||||
|
||||
$button.prop('disabled', true).text('<?php _e('Processing...', 'wp-domain-mapping'); ?>');
|
||||
|
||||
// 直接访问链接
|
||||
window.location.href = href;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -392,3 +392,32 @@
|
|||
display: table-cell;
|
||||
}
|
||||
}
|
||||
|
||||
/* 在文件末尾添加移动端优化 */
|
||||
@media screen and (max-width: 600px) {
|
||||
.wp-list-table {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.column-actions .button {
|
||||
padding: 2px 8px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.domain-mapping-card {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 添加验证消息样式 */
|
||||
#domain-validation-message {
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#domain-validation-message.error {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
|
|
|
@ -586,3 +586,156 @@ jQuery(document).ready(function($) {
|
|||
// Initialize when document is ready
|
||||
initializePage();
|
||||
});
|
||||
// Domain Mapping Dashboard Widget JavaScript
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
// 健康状态刷新按钮
|
||||
$(document).on('click', '.dm-refresh-health', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var $healthContent = $button.closest('.dm-health-status').find('.dm-health-content');
|
||||
var blogId = $button.data('blog-id');
|
||||
|
||||
$button.prop('disabled', true);
|
||||
$healthContent.addClass('dm-loading');
|
||||
|
||||
// 旋转图标
|
||||
$button.find('.dashicons').addClass('dashicons-update-spin');
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'dm_quick_health_check',
|
||||
blog_id: blogId,
|
||||
nonce: wpDomainMapping.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$healthContent.html(response.data.html);
|
||||
|
||||
// 显示成功消息
|
||||
var $notice = $('<div class="notice notice-success is-dismissible"><p>' +
|
||||
response.data.message + '</p></div>');
|
||||
$('#dm_domain_status_widget .inside').prepend($notice);
|
||||
|
||||
setTimeout(function() {
|
||||
$notice.fadeOut(function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}, 3000);
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
$button.prop('disabled', false);
|
||||
$button.find('.dashicons').removeClass('dashicons-update-spin');
|
||||
$healthContent.removeClass('dm-loading');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 检查所有域名健康状态
|
||||
$(document).on('click', '.dm-check-all-health', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var blogId = $button.data('blog-id');
|
||||
var originalText = $button.html();
|
||||
|
||||
$button.prop('disabled', true).html(
|
||||
'<span class="dashicons dashicons-update dashicons-update-spin"></span> ' +
|
||||
wpDomainMapping.messages.processing
|
||||
);
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'dm_quick_health_check',
|
||||
blog_id: blogId,
|
||||
nonce: wpDomainMapping.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
// 刷新健康状态区域
|
||||
if ($('#dm-widget-health-status').length) {
|
||||
$('#dm-widget-health-status .dm-health-content').html(response.data.html);
|
||||
}
|
||||
|
||||
// 显示成功消息
|
||||
var $notice = $('<div class="notice notice-success is-dismissible"><p>' +
|
||||
response.data.message + '</p></div>');
|
||||
$('#dm_domain_status_widget .inside').prepend($notice);
|
||||
|
||||
setTimeout(function() {
|
||||
$notice.fadeOut(function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}, 3000);
|
||||
} else {
|
||||
alert(response.data || wpDomainMapping.messages.error);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert(wpDomainMapping.messages.error);
|
||||
},
|
||||
complete: function() {
|
||||
$button.prop('disabled', false).html(originalText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 自动刷新(可选)
|
||||
if ($('#dm_domain_status_widget').length && $('#dm_domain_status_widget').is(':visible')) {
|
||||
// 每10分钟自动刷新一次
|
||||
var autoRefreshInterval = setInterval(function() {
|
||||
if ($('#dm_domain_status_widget').is(':visible')) {
|
||||
$('.dm-refresh-health').first().trigger('click');
|
||||
}
|
||||
}, 600000); // 10分钟
|
||||
|
||||
// 页面卸载时清除定时器
|
||||
$(window).on('beforeunload', function() {
|
||||
clearInterval(autoRefreshInterval);
|
||||
});
|
||||
}
|
||||
|
||||
// 小工具配置保存
|
||||
$(document).on('submit', '#dm_domain_status_widget form', function(e) {
|
||||
// 配置会自动保存,这里可以添加额外的处理
|
||||
var showHealth = $('#dm_widget_show_health').is(':checked');
|
||||
|
||||
// 如果取消勾选健康状态,隐藏相关区域
|
||||
if (!showHealth) {
|
||||
$('#dm-widget-health-status').fadeOut();
|
||||
} else {
|
||||
$('#dm-widget-health-status').fadeIn();
|
||||
}
|
||||
});
|
||||
|
||||
// 为域名链接添加外部图标
|
||||
$('.dm-domains-list a, .dm-domain-primary a').each(function() {
|
||||
if (!$(this).find('.dashicons-external').length) {
|
||||
$(this).append(' <span class="dashicons dashicons-external" style="font-size: 14px; vertical-align: middle;"></span>');
|
||||
}
|
||||
});
|
||||
|
||||
// 工具提示
|
||||
if ($.fn.tooltip) {
|
||||
$('#dm_domain_status_widget [title]').tooltip({
|
||||
position: {
|
||||
my: 'center bottom-5',
|
||||
at: 'center top',
|
||||
using: function(position, feedback) {
|
||||
$(this).css(position);
|
||||
$('<div>')
|
||||
.addClass('dm-tooltip-arrow')
|
||||
.addClass(feedback.vertical)
|
||||
.addClass(feedback.horizontal)
|
||||
.appendTo(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -79,6 +79,13 @@ class WP_Domain_Mapping_Admin {
|
|||
add_action( 'manage_blogs_custom_column', array( $this, 'display_domain_mapping_column' ), 1, 3 );
|
||||
add_action( 'manage_sites_custom_column', array( $this, 'display_domain_mapping_column' ), 1, 3 );
|
||||
|
||||
// 添加仪表盘小工具
|
||||
add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widget' ) );
|
||||
|
||||
// 添加仪表盘小工具的AJAX处理
|
||||
add_action( 'wp_ajax_dm_refresh_widget_status', array( $this, 'ajax_refresh_widget_status' ) );
|
||||
add_action( 'wp_ajax_dm_quick_health_check', array( $this, 'ajax_quick_health_check' ) );
|
||||
|
||||
// Handle user domain mapping actions
|
||||
if ( isset( $_GET['page'] ) && 'domainmapping' === $_GET['page'] ) {
|
||||
add_action( 'admin_init', array( $this, 'handle_user_domain_actions' ) );
|
||||
|
@ -100,7 +107,7 @@ class WP_Domain_Mapping_Admin {
|
|||
}
|
||||
|
||||
if ( isset($current_site->path) && $current_site->path != "/" ) {
|
||||
wp_die( esc_html__( "The domain mapping plugin only works if the site is installed in /. This is a limitation of how virtual servers work and is very difficult to work around.", 'wp-domain-mapping' ) );
|
||||
wp_die( esc_html__( "The domain mapping plugin only works if WordPress is installed in the root directory of your webserver. It is currently installed in '%s'.", 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
if ( get_site_option( 'dm_user_settings' ) && $current_site->blog_id != $wpdb->blogid && ! $this->sunrise_warning( false ) ) {
|
||||
|
@ -137,6 +144,577 @@ class WP_Domain_Mapping_Admin {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加仪表盘小工具
|
||||
*/
|
||||
public function add_dashboard_widget() {
|
||||
// 只在子站显示,不在主站显示
|
||||
if ( is_main_site() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查用户权限和设置
|
||||
if ( ! current_user_can( 'manage_options' ) || ! get_site_option( 'dm_user_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_add_dashboard_widget(
|
||||
'dm_domain_status_widget',
|
||||
__( 'Domain Mapping Status', 'wp-domain-mapping' ),
|
||||
array( $this, 'render_dashboard_widget' ),
|
||||
array( $this, 'render_dashboard_widget_config' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染仪表盘小工具
|
||||
*/
|
||||
public function render_dashboard_widget() {
|
||||
global $wpdb;
|
||||
$blog_id = get_current_blog_id();
|
||||
$domains = dm_get_domains_by_blog_id( $blog_id );
|
||||
$show_health_status = get_user_meta( get_current_user_id(), 'dm_widget_show_health', true );
|
||||
$show_health_status = ( $show_health_status === '' ) ? '1' : $show_health_status;
|
||||
?>
|
||||
<style>
|
||||
.dm-dashboard-widget{padding:0}
|
||||
.dm-dashboard-widget>div{margin-bottom:15px;padding-bottom:15px;border-bottom:1px solid #eee}
|
||||
.dm-dashboard-widget>div:last-child{margin-bottom:0;padding-bottom:0;border-bottom:none}
|
||||
.dm-dashboard-widget h4{margin:0 0 8px 0;font-size:13px;font-weight:600;color:#1d2327;display:flex;align-items:center;justify-content:space-between}
|
||||
.dm-domain-primary{font-size:14px;display:flex;align-items:center;gap:8px}
|
||||
.dm-domain-primary a{text-decoration:none;color:#2271b1}
|
||||
.dm-domain-primary a:hover{color:#135e96;text-decoration:underline}
|
||||
.dm-no-primary{color:#666;font-style:italic;display:flex;align-items:center;gap:8px}
|
||||
.dm-stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;text-align:center}
|
||||
.dm-stat{background:#f0f0f1;padding:10px;border-radius:4px}
|
||||
.dm-stat-value{display:block;font-size:24px;font-weight:600;color:#2271b1;line-height:1}
|
||||
.dm-stat-label{display:block;font-size:11px;color:#666;margin-top:5px}
|
||||
.dm-domains-list ul{margin:0;padding:0;list-style:none}
|
||||
.dm-domains-list li{padding:5px 0;display:flex;align-items:center;gap:5px}
|
||||
.dm-domains-list a{text-decoration:none;color:#50575e}
|
||||
.dm-domains-list a:hover{color:#2271b1}
|
||||
.dm-badge-primary{background:#2271b1;color:#fff;font-size:11px;padding:2px 6px;border-radius:3px;margin-left:auto}
|
||||
.dm-health-status{position:relative}
|
||||
.dm-refresh-health{padding:2px 4px!important;min-height:24px!important;line-height:1!important}
|
||||
.dm-refresh-health .dashicons{font-size:16px;width:16px;height:16px}
|
||||
.dm-health-good{color:#46b450;display:flex;align-items:center;gap:5px;margin:0}
|
||||
.dm-health-issues{background:#fcf0f1;border:1px solid #f0c4c6;border-radius:4px;padding:10px}
|
||||
.dm-issue-item{margin-bottom:5px}
|
||||
.dm-issue-item:last-child{margin-bottom:0}
|
||||
.dm-issue-list{color:#d63638;font-size:12px}
|
||||
.dm-last-check{margin:8px 0 0;font-size:12px;color:#666;font-style:italic}
|
||||
.dm-dns-info code{background:#f0f0f1;padding:3px 6px;border-radius:3px;font-family:Consolas,Monaco,monospace;font-size:12px}
|
||||
.dm-activity-list{margin:0;padding:0;list-style:none}
|
||||
.dm-activity-list li{padding:6px 0;border-bottom:1px solid #f0f0f1;font-size:12px}
|
||||
.dm-activity-list li:last-child{border-bottom:none;padding-bottom:0}
|
||||
.dm-activity-action{display:inline-block;padding:2px 6px;border-radius:3px;font-size:11px;font-weight:600;margin-right:5px}
|
||||
.dm-action-add{background-color:#dff0d8;color:#3c763d}
|
||||
.dm-action-edit{background-color:#d9edf7;color:#31708f}
|
||||
.dm-action-delete{background-color:#f2dede;color:#a94442}
|
||||
.dm-activity-domain{font-weight:500;color:#1d2327}
|
||||
.dm-activity-meta{display:block;color:#666;margin-top:2px}
|
||||
.dm-quick-actions{display:flex;gap:10px}
|
||||
.dm-quick-actions .button{flex:1;display:flex;align-items:center;justify-content:center;gap:5px}
|
||||
.dm-quick-actions .dashicons{font-size:16px;width:16px;height:16px;line-height:1}
|
||||
.dm-loading{opacity:.6;pointer-events:none}
|
||||
.dm-loading::after{content:'';position:absolute;top:50%;left:50%;width:20px;height:20px;margin:-10px 0 0 -10px;border:2px solid #f0f0f1;border-top-color:#2271b1;border-radius:50%;animation:dm-spin 1s linear infinite}
|
||||
@keyframes dm-spin{to{transform:rotate(360deg)}
|
||||
}
|
||||
@media screen and (max-width:782px){.dm-stats-grid{grid-template-columns:repeat(3,1fr);gap:5px}
|
||||
.dm-stat{padding:8px 5px}
|
||||
.dm-stat-value{font-size:20px}
|
||||
.dm-quick-actions{flex-direction:column}
|
||||
.dm-quick-actions .button{width:100%}
|
||||
}
|
||||
#dm_domain_status_widget .postbox-header{cursor:move}
|
||||
#dm_domain_status_widget.closed .inside{display:none}
|
||||
</style>
|
||||
|
||||
<div class="dm-dashboard-widget">
|
||||
<!-- 1. 主域名状态 -->
|
||||
<div class="dm-primary-domain">
|
||||
<h4><?php _e( 'Primary Domain', 'wp-domain-mapping' ); ?></h4>
|
||||
<?php
|
||||
$primary = wp_list_filter( $domains, array( 'active' => 1 ) );
|
||||
if ( ! empty( $primary ) ) {
|
||||
$primary_domain = reset( $primary );
|
||||
$ssl_status = $this->check_domain_ssl( $primary_domain->domain );
|
||||
?>
|
||||
<p class="dm-domain-primary">
|
||||
<span class="dashicons dashicons-admin-site-alt3"></span>
|
||||
<strong>
|
||||
<a href="<?php echo esc_url( ( $ssl_status ? 'https://' : 'http://' ) . $primary_domain->domain ); ?>" target="_blank">
|
||||
<?php echo esc_html( $primary_domain->domain ); ?>
|
||||
</a>
|
||||
</strong>
|
||||
<?php if ( $ssl_status ): ?>
|
||||
<span class="dashicons dashicons-lock" style="color: #46b450;" title="<?php esc_attr_e( 'SSL Active', 'wp-domain-mapping' ); ?>"></span>
|
||||
<?php else: ?>
|
||||
<span class="dashicons dashicons-unlock" style="color: #d63638;" title="<?php esc_attr_e( 'No SSL', 'wp-domain-mapping' ); ?>"></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php
|
||||
} else {
|
||||
$orig_url = WP_Domain_Mapping_Core::get_instance()->get_original_url( 'siteurl' );
|
||||
$orig_domain = parse_url( $orig_url, PHP_URL_HOST );
|
||||
?>
|
||||
<p class="dm-no-primary">
|
||||
<span class="dashicons dashicons-admin-site"></span>
|
||||
<?php _e( 'Using original domain:', 'wp-domain-mapping' ); ?>
|
||||
<strong><?php echo esc_html( $orig_domain ); ?></strong>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!-- 2. 映射域名统计 -->
|
||||
<div class="dm-domains-stats">
|
||||
<h4><?php _e( 'Domain Statistics', 'wp-domain-mapping' ); ?></h4>
|
||||
<div class="dm-stats-grid">
|
||||
<div class="dm-stat">
|
||||
<span class="dm-stat-value"><?php echo count( $domains ); ?></span>
|
||||
<span class="dm-stat-label"><?php _e( 'Total Domains', 'wp-domain-mapping' ); ?></span>
|
||||
</div>
|
||||
<div class="dm-stat">
|
||||
<span class="dm-stat-value"><?php echo count( wp_list_filter( $domains, array( 'active' => 1 ) ) ); ?></span>
|
||||
<span class="dm-stat-label"><?php _e( 'Primary', 'wp-domain-mapping' ); ?></span>
|
||||
</div>
|
||||
<div class="dm-stat">
|
||||
<span class="dm-stat-value"><?php echo count( wp_list_filter( $domains, array( 'active' => 0 ) ) ); ?></span>
|
||||
<span class="dm-stat-label"><?php _e( 'Secondary', 'wp-domain-mapping' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 映射域名列表 -->
|
||||
<?php if ( ! empty( $domains ) && count( $domains ) > 1 ): ?>
|
||||
<div class="dm-domains-list">
|
||||
<h4><?php _e( 'All Mapped Domains', 'wp-domain-mapping' ); ?></h4>
|
||||
<ul>
|
||||
<?php foreach ( $domains as $domain ): ?>
|
||||
<li>
|
||||
<span class="dashicons dashicons-admin-links"></span>
|
||||
<a href="<?php echo esc_url( 'http://' . $domain->domain ); ?>" target="_blank">
|
||||
<?php echo esc_html( $domain->domain ); ?>
|
||||
</a>
|
||||
<?php if ( $domain->active ): ?>
|
||||
<span class="dm-badge-primary"><?php _e( 'Primary', 'wp-domain-mapping' ); ?></span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 4. 健康状态(可选) -->
|
||||
<?php if ( $show_health_status == '1' ): ?>
|
||||
<div class="dm-health-status" id="dm-widget-health-status">
|
||||
<h4>
|
||||
<?php _e( 'Health Status', 'wp-domain-mapping' ); ?>
|
||||
<button type="button" class="button-link dm-refresh-health" data-blog-id="<?php echo $blog_id; ?>">
|
||||
<span class="dashicons dashicons-update"></span>
|
||||
<span class="screen-reader-text"><?php _e( 'Refresh', 'wp-domain-mapping' ); ?></span>
|
||||
</button>
|
||||
</h4>
|
||||
<div class="dm-health-content">
|
||||
<?php $this->render_widget_health_status( $domains ); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 5. DNS 配置提示 -->
|
||||
<?php
|
||||
$ipaddress = get_site_option( 'dm_ipaddress' );
|
||||
$cname = get_site_option( 'dm_cname' );
|
||||
if ( ( $ipaddress || $cname ) && empty( $domains ) ):
|
||||
?>
|
||||
<div class="dm-dns-info">
|
||||
<h4><?php _e( 'DNS Configuration', 'wp-domain-mapping' ); ?></h4>
|
||||
<p class="description">
|
||||
<?php if ( $cname ): ?>
|
||||
<?php printf( __( 'Point your domain CNAME to: %s', 'wp-domain-mapping' ), '<code>' . esc_html( $cname ) . '</code>' ); ?>
|
||||
<?php elseif ( $ipaddress ): ?>
|
||||
<?php printf( __( 'Point your domain A record to: %s', 'wp-domain-mapping' ), '<code>' . esc_html( $ipaddress ) . '</code>' ); ?>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 6. 最近活动 -->
|
||||
<?php
|
||||
$recent_logs = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT * FROM {$this->tables['logs']} WHERE blog_id = %d ORDER BY timestamp DESC LIMIT 3",
|
||||
$blog_id
|
||||
));
|
||||
if ( ! empty( $recent_logs ) ):
|
||||
?>
|
||||
<div class="dm-recent-activity">
|
||||
<h4><?php _e( 'Recent Activity', 'wp-domain-mapping' ); ?></h4>
|
||||
<ul class="dm-activity-list">
|
||||
<?php foreach ( $recent_logs as $log ):
|
||||
$user = get_userdata( $log->user_id );
|
||||
$username = $user ? $user->display_name : __( 'Unknown', 'wp-domain-mapping' );
|
||||
?>
|
||||
<li>
|
||||
<span class="dm-activity-action dm-action-<?php echo esc_attr( $log->action ); ?>">
|
||||
<?php echo esc_html( dm_format_action_name( $log->action ) ); ?>
|
||||
</span>
|
||||
<span class="dm-activity-domain"><?php echo esc_html( $log->domain ); ?></span>
|
||||
<span class="dm-activity-meta">
|
||||
<?php
|
||||
printf(
|
||||
__( 'by %s %s ago', 'wp-domain-mapping' ),
|
||||
esc_html( $username ),
|
||||
human_time_diff( strtotime( $log->timestamp ), current_time( 'timestamp' ) )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 7. 快速操作 -->
|
||||
<div class="dm-quick-actions">
|
||||
<a href="<?php echo admin_url( 'tools.php?page=domainmapping' ); ?>" class="button button-primary">
|
||||
<?php _e( 'Manage Domains', 'wp-domain-mapping' ); ?>
|
||||
</a>
|
||||
<?php if ( ! empty( $domains ) ): ?>
|
||||
<button type="button" class="button dm-check-all-health" data-blog-id="<?php echo $blog_id; ?>">
|
||||
<?php _e( 'Check Health', 'wp-domain-mapping' ); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
// 等待小工具完全渲染
|
||||
$(document).ready(function() {
|
||||
console.log('DM Widget: Document ready');
|
||||
|
||||
// 初始化变量
|
||||
var ajaxUrl = '<?php echo esc_js( admin_url( 'admin-ajax.php' ) ); ?>';
|
||||
var nonce = '<?php echo esc_js( wp_create_nonce( 'domain_mapping' ) ); ?>';
|
||||
|
||||
// 检查元素是否存在
|
||||
console.log('Refresh button count:', $('.dm-refresh-health').length);
|
||||
console.log('Check all button count:', $('.dm-check-all-health').length);
|
||||
|
||||
// 刷新健康状态
|
||||
$('#dm_domain_status_widget').on('click', '.dm-refresh-health', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
console.log('Refresh health clicked');
|
||||
|
||||
var $button = $(this);
|
||||
var $healthContent = $('.dm-health-content');
|
||||
var blogId = $button.data('blog-id');
|
||||
|
||||
// 禁用按钮
|
||||
$button.prop('disabled', true).blur();
|
||||
$button.find('.dashicons').addClass('dashicons-update-spin');
|
||||
$healthContent.addClass('dm-loading');
|
||||
|
||||
$.ajax({
|
||||
url: ajaxUrl,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
action: 'dm_quick_health_check',
|
||||
blog_id: blogId,
|
||||
nonce: nonce
|
||||
},
|
||||
success: function(response) {
|
||||
console.log('Health check response:', response);
|
||||
|
||||
if (response.success) {
|
||||
$healthContent.html(response.data.html);
|
||||
|
||||
// 显示成功消息
|
||||
var $widget = $('#dm_domain_status_widget');
|
||||
var $notice = $('<div class="notice notice-success is-dismissible"><p>' +
|
||||
response.data.message + '</p></div>');
|
||||
|
||||
$widget.find('.inside').prepend($notice);
|
||||
|
||||
setTimeout(function() {
|
||||
$notice.fadeOut(function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}, 3000);
|
||||
} else {
|
||||
alert(response.data || 'An error occurred');
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('AJAX error:', status, error);
|
||||
alert('An error occurred during the health check');
|
||||
},
|
||||
complete: function() {
|
||||
$button.prop('disabled', false);
|
||||
$button.find('.dashicons').removeClass('dashicons-update-spin');
|
||||
$healthContent.removeClass('dm-loading');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 检查所有域名健康状态
|
||||
$('#dm_domain_status_widget').on('click', '.dm-check-all-health', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
console.log('Check all health clicked');
|
||||
|
||||
var $button = $(this);
|
||||
var blogId = $button.data('blog-id');
|
||||
var originalHtml = $button.html();
|
||||
|
||||
// 禁用按钮
|
||||
$button.prop('disabled', true).blur();
|
||||
$button.html('<span class="dashicons dashicons-update dashicons-update-spin"></span> Processing...');
|
||||
|
||||
$.ajax({
|
||||
url: ajaxUrl,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
action: 'dm_quick_health_check',
|
||||
blog_id: blogId,
|
||||
nonce: nonce
|
||||
},
|
||||
success: function(response) {
|
||||
console.log('Check all response:', response);
|
||||
|
||||
if (response.success) {
|
||||
// 更新健康状态区域
|
||||
var $healthSection = $('#dm-widget-health-status');
|
||||
if ($healthSection.length) {
|
||||
$healthSection.find('.dm-health-content').html(response.data.html);
|
||||
|
||||
if (!$healthSection.is(':visible')) {
|
||||
$healthSection.slideDown();
|
||||
}
|
||||
}
|
||||
|
||||
// 显示成功消息
|
||||
var $widget = $('#dm_domain_status_widget');
|
||||
var $notice = $('<div class="notice notice-success is-dismissible"><p>' +
|
||||
response.data.message + '</p></div>');
|
||||
|
||||
$widget.find('.inside').prepend($notice);
|
||||
|
||||
setTimeout(function() {
|
||||
$notice.fadeOut(function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}, 3000);
|
||||
} else {
|
||||
alert(response.data || wpDomainMapping.messages.error);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('AJAX error:', status, error);
|
||||
alert(wpDomainMapping.messages.error);
|
||||
},
|
||||
complete: function() {
|
||||
$button.prop('disabled', false);
|
||||
$button.html(originalHtml);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染小工具配置
|
||||
*/
|
||||
public function render_dashboard_widget_config() {
|
||||
// 处理表单提交 - WordPress 会在保存前调用这个方法
|
||||
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset( $_POST['widget_id'] ) && $_POST['widget_id'] == 'dm_domain_status_widget' ) {
|
||||
// 重要:checkbox 未勾选时不会在 $_POST 中出现
|
||||
$show_health = isset( $_POST['dm_widget_show_health'] ) ? '1' : '0';
|
||||
update_user_meta( get_current_user_id(), 'dm_widget_show_health', $show_health );
|
||||
}
|
||||
|
||||
// 获取当前设置
|
||||
$show_health = get_user_meta( get_current_user_id(), 'dm_widget_show_health', true );
|
||||
$show_health = ( $show_health === '' ) ? '1' : $show_health; // 默认显示
|
||||
?>
|
||||
<p>
|
||||
<label for="dm_widget_show_health">
|
||||
<input type="checkbox" id="dm_widget_show_health" name="dm_widget_show_health" value="1" <?php checked( $show_health, '1' ); ?> />
|
||||
<?php _e( 'Show health status', 'wp-domain-mapping' ); ?>
|
||||
</label>
|
||||
</p>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
// 提供实时预览
|
||||
$('#dm_widget_show_health').on('change', function() {
|
||||
var $healthSection = $('#dm-widget-health-status');
|
||||
if ($(this).is(':checked')) {
|
||||
$healthSection.slideDown();
|
||||
} else {
|
||||
$healthSection.slideUp();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
/**
|
||||
* 渲染健康状态内容
|
||||
*/
|
||||
private function render_widget_health_status( $domains ) {
|
||||
if ( empty( $domains ) ) {
|
||||
echo '<p class="dm-no-domains">' . __( 'No domains to check.', 'wp-domain-mapping' ) . '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
$all_healthy = true;
|
||||
$issues = array();
|
||||
|
||||
foreach ( $domains as $domain ) {
|
||||
$health = dm_get_health_result( $domain->domain );
|
||||
if ( $health ) {
|
||||
$domain_issues = array();
|
||||
|
||||
if ( isset( $health['accessible'] ) && ! $health['accessible'] ) {
|
||||
$domain_issues[] = __( 'Not accessible', 'wp-domain-mapping' );
|
||||
$all_healthy = false;
|
||||
}
|
||||
|
||||
if ( isset( $health['ssl_valid'] ) && ! $health['ssl_valid'] ) {
|
||||
$domain_issues[] = __( 'SSL issue', 'wp-domain-mapping' );
|
||||
$all_healthy = false;
|
||||
}
|
||||
|
||||
if ( isset( $health['dns_status'] ) && $health['dns_status'] !== 'success' ) {
|
||||
$domain_issues[] = __( 'DNS issue', 'wp-domain-mapping' );
|
||||
$all_healthy = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $domain_issues ) ) {
|
||||
$issues[$domain->domain] = $domain_issues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $all_healthy ) {
|
||||
echo '<p class="dm-health-good"><span class="dashicons dashicons-yes-alt"></span> ' .
|
||||
__( 'All domains are healthy!', 'wp-domain-mapping' ) . '</p>';
|
||||
} else {
|
||||
echo '<div class="dm-health-issues">';
|
||||
foreach ( $issues as $domain => $domain_issues ) {
|
||||
echo '<div class="dm-issue-item">';
|
||||
echo '<strong>' . esc_html( $domain ) . ':</strong> ';
|
||||
echo '<span class="dm-issue-list">' . implode( ', ', $domain_issues ) . '</span>';
|
||||
echo '</div>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// 显示最后检查时间
|
||||
$last_check = get_site_option( 'dm_widget_last_health_check_' . get_current_blog_id() );
|
||||
if ( $last_check ) {
|
||||
echo '<p class="dm-last-check">' .
|
||||
sprintf(
|
||||
__( 'Last checked: %s ago', 'wp-domain-mapping' ),
|
||||
human_time_diff( $last_check, current_time( 'timestamp' ) )
|
||||
) . '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX刷新小工具状态
|
||||
*/
|
||||
public function ajax_refresh_widget_status() {
|
||||
check_ajax_referer( 'domain_mapping', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error( __( 'Permission denied.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
ob_start();
|
||||
$this->render_dashboard_widget();
|
||||
$html = ob_get_clean();
|
||||
|
||||
wp_send_json_success( $html );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX快速健康检查
|
||||
*/
|
||||
public function ajax_quick_health_check() {
|
||||
check_ajax_referer( 'domain_mapping', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error( __( 'Permission denied.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
$blog_id = isset( $_POST['blog_id'] ) ? intval( $_POST['blog_id'] ) : get_current_blog_id();
|
||||
$domains = dm_get_domains_by_blog_id( $blog_id );
|
||||
|
||||
if ( empty( $domains ) ) {
|
||||
wp_send_json_error( __( 'No domains found.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
// 执行健康检查
|
||||
$tools = WP_Domain_Mapping_Tools::get_instance();
|
||||
foreach ( $domains as $domain ) {
|
||||
$result = $tools->check_domain_health( $domain->domain );
|
||||
dm_save_health_result( $domain->domain, $result );
|
||||
}
|
||||
|
||||
// 更新最后检查时间
|
||||
update_site_option( 'dm_widget_last_health_check_' . $blog_id, current_time( 'timestamp' ) );
|
||||
|
||||
// 返回更新后的健康状态HTML
|
||||
ob_start();
|
||||
$this->render_widget_health_status( $domains );
|
||||
$html = ob_get_clean();
|
||||
|
||||
wp_send_json_success( array(
|
||||
'html' => $html,
|
||||
'message' => __( 'Health check completed.', 'wp-domain-mapping' )
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查域名SSL状态
|
||||
*/
|
||||
private function check_domain_ssl( $domain ) {
|
||||
$health_result = dm_get_health_result( $domain );
|
||||
return $health_result && isset( $health_result['ssl_valid'] ) && $health_result['ssl_valid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取域名健康问题
|
||||
*/
|
||||
private function get_domain_health_issues( $blog_id ) {
|
||||
$domains = dm_get_domains_by_blog_id( $blog_id );
|
||||
$issues = array();
|
||||
|
||||
foreach ( $domains as $domain ) {
|
||||
$health_result = dm_get_health_result( $domain->domain );
|
||||
if ( $health_result ) {
|
||||
if ( ! $health_result['accessible'] || ! $health_result['ssl_valid'] || $health_result['dns_status'] !== 'success' ) {
|
||||
$issues[] = $domain->domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin scripts and styles
|
||||
*/
|
||||
|
@ -171,6 +749,8 @@ class WP_Domain_Mapping_Admin {
|
|||
'processing' => __( 'Processing...', 'wp-domain-mapping' ),
|
||||
'error' => __( 'An error occurred.', 'wp-domain-mapping' ),
|
||||
'noSelection' => __( 'Please select at least one domain.', 'wp-domain-mapping' ),
|
||||
'invalidDomain' => __( 'Invalid domain format.', 'wp-domain-mapping' ),
|
||||
'checking' => __( 'Checking...', 'wp-domain-mapping' ), // 新增
|
||||
)
|
||||
));
|
||||
}
|
||||
|
@ -243,6 +823,7 @@ class WP_Domain_Mapping_Admin {
|
|||
|
||||
/**
|
||||
* AJAX handler for domain actions
|
||||
* UPDATED: Support editing domain names and better conflict checking
|
||||
*/
|
||||
public function ajax_handle_actions() {
|
||||
check_ajax_referer( 'domain_mapping', 'nonce' );
|
||||
|
@ -268,69 +849,110 @@ class WP_Domain_Mapping_Admin {
|
|||
wp_send_json_error( __( 'Invalid domain format.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
// Check if domain exists for another blog
|
||||
$exists = $wpdb->get_var( $wpdb->prepare(
|
||||
"SELECT domain FROM {$this->tables['domains']} WHERE blog_id != %d AND domain = %s",
|
||||
$blog_id, $domain
|
||||
));
|
||||
// For editing, check if domain changed
|
||||
$domain_changed = ! empty( $orig_domain ) && $orig_domain !== $domain;
|
||||
|
||||
if ( null == $exists ) {
|
||||
$wpdb->query( 'START TRANSACTION' );
|
||||
if ( $domain_changed || empty( $orig_domain ) ) {
|
||||
// Check if domain exists for another blog
|
||||
$exists = dm_domain_exists_for_another_blog( $domain, $blog_id );
|
||||
|
||||
try {
|
||||
if ( empty( $orig_domain ) ) {
|
||||
// Insert new domain
|
||||
$success = $wpdb->insert(
|
||||
$this->tables['domains'],
|
||||
array(
|
||||
'blog_id' => $blog_id,
|
||||
'domain' => $domain,
|
||||
'active' => $active
|
||||
),
|
||||
array( '%d', '%s', '%d' )
|
||||
);
|
||||
|
||||
if ( $success ) {
|
||||
// Log the action
|
||||
dm_log_action( 'add', $domain, $blog_id, $current_user_id );
|
||||
|
||||
$wpdb->query( 'COMMIT' );
|
||||
wp_send_json_success( __( 'Domain added successfully.', 'wp-domain-mapping' ) );
|
||||
} else {
|
||||
$wpdb->query( 'ROLLBACK' );
|
||||
wp_send_json_error( __( 'Failed to add domain.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
} else {
|
||||
// Update existing domain
|
||||
$success = $wpdb->update(
|
||||
$this->tables['domains'],
|
||||
array(
|
||||
'blog_id' => $blog_id,
|
||||
'domain' => $domain,
|
||||
'active' => $active
|
||||
),
|
||||
array( 'domain' => $orig_domain ),
|
||||
array( '%d', '%s', '%d' ),
|
||||
array( '%s' )
|
||||
);
|
||||
|
||||
if ( $success !== false ) {
|
||||
// Log the action
|
||||
dm_log_action( 'edit', $domain, $blog_id, $current_user_id );
|
||||
|
||||
$wpdb->query( 'COMMIT' );
|
||||
wp_send_json_success( __( 'Domain updated successfully.', 'wp-domain-mapping' ) );
|
||||
} else {
|
||||
$wpdb->query( 'ROLLBACK' );
|
||||
wp_send_json_error( __( 'No changes were made or update failed.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$wpdb->query( 'ROLLBACK' );
|
||||
wp_send_json_error( __( 'An error occurred while saving domain.', 'wp-domain-mapping' ) );
|
||||
if ( $exists ) {
|
||||
wp_send_json_error( sprintf(
|
||||
__( 'Domain %s is already mapped to site ID %d.', 'wp-domain-mapping' ),
|
||||
$domain,
|
||||
$exists->blog_id
|
||||
));
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( __( 'Domain already exists for another site.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
$wpdb->query( 'START TRANSACTION' );
|
||||
|
||||
try {
|
||||
if ( empty( $orig_domain ) ) {
|
||||
// Insert new domain
|
||||
$success = $wpdb->insert(
|
||||
$this->tables['domains'],
|
||||
array(
|
||||
'blog_id' => $blog_id,
|
||||
'domain' => $domain,
|
||||
'active' => $active
|
||||
),
|
||||
array( '%d', '%s', '%d' )
|
||||
);
|
||||
|
||||
if ( $success ) {
|
||||
// If setting as primary, reset other domains
|
||||
if ( $active ) {
|
||||
$wpdb->update(
|
||||
$this->tables['domains'],
|
||||
array( 'active' => 0 ),
|
||||
array(
|
||||
'blog_id' => $blog_id,
|
||||
'domain !=' => $domain
|
||||
),
|
||||
array( '%d' ),
|
||||
array( '%d', '%s' )
|
||||
);
|
||||
}
|
||||
|
||||
// Log the action
|
||||
dm_log_action( 'add', $domain, $blog_id, $current_user_id );
|
||||
|
||||
$wpdb->query( 'COMMIT' );
|
||||
wp_send_json_success( __( 'Domain added successfully.', 'wp-domain-mapping' ) );
|
||||
} else {
|
||||
$wpdb->query( 'ROLLBACK' );
|
||||
wp_send_json_error( __( 'Failed to add domain.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
} else {
|
||||
// Update existing domain
|
||||
|
||||
// Prepare update data
|
||||
$update_data = array(
|
||||
'blog_id' => $blog_id,
|
||||
'active' => $active
|
||||
);
|
||||
$update_format = array( '%d', '%d' );
|
||||
|
||||
// If domain changed, update it
|
||||
if ( $domain_changed ) {
|
||||
$update_data['domain'] = $domain;
|
||||
$update_format[] = '%s';
|
||||
}
|
||||
|
||||
// If setting as primary, reset other domains first
|
||||
if ( $active ) {
|
||||
$wpdb->update(
|
||||
$this->tables['domains'],
|
||||
array( 'active' => 0 ),
|
||||
array( 'blog_id' => $blog_id ),
|
||||
array( '%d' ),
|
||||
array( '%d' )
|
||||
);
|
||||
}
|
||||
|
||||
$success = $wpdb->update(
|
||||
$this->tables['domains'],
|
||||
$update_data,
|
||||
array( 'domain' => $orig_domain ),
|
||||
$update_format,
|
||||
array( '%s' )
|
||||
);
|
||||
|
||||
if ( $success !== false ) {
|
||||
// Log the action
|
||||
dm_log_action( 'edit', $domain, $blog_id, $current_user_id );
|
||||
|
||||
$wpdb->query( 'COMMIT' );
|
||||
wp_send_json_success( __( 'Domain updated successfully.', 'wp-domain-mapping' ) );
|
||||
} else {
|
||||
$wpdb->query( 'ROLLBACK' );
|
||||
wp_send_json_error( __( 'No changes were made or update failed.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$wpdb->query( 'ROLLBACK' );
|
||||
wp_send_json_error( __( 'An error occurred while saving domain.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( __( 'Invalid site ID.', 'wp-domain-mapping' ) );
|
||||
|
@ -399,14 +1021,16 @@ class WP_Domain_Mapping_Admin {
|
|||
|
||||
/**
|
||||
* Handle user domain mapping actions
|
||||
* UPDATED: Support www prefix and better domain validation
|
||||
*/
|
||||
public function handle_user_domain_actions() {
|
||||
global $wpdb, $parent_file;
|
||||
|
||||
$url = add_query_arg( array( 'page' => 'domainmapping' ), admin_url( $parent_file ) );
|
||||
|
||||
// 处理 POST 请求(添加域名)
|
||||
if ( ! empty( $_POST['action'] ) ) {
|
||||
$domain = isset( $_POST['domain'] ) ? sanitize_text_field( $_POST['domain'] ) : '';
|
||||
$domain = isset( $_POST['domain'] ) ? dm_clean_domain( sanitize_text_field( $_POST['domain'] ) ) : '';
|
||||
|
||||
if ( empty( $domain ) ) {
|
||||
wp_die( esc_html__( "You must enter a domain", 'wp-domain-mapping' ) );
|
||||
|
@ -425,46 +1049,82 @@ class WP_Domain_Mapping_Admin {
|
|||
wp_die( esc_html__( "Invalid domain format", 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
// Check if domain already exists
|
||||
$domain_exists = $wpdb->get_row( $wpdb->prepare(
|
||||
"SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s OR (SELECT blog_id FROM {$this->tables['domains']} WHERE domain = %s)",
|
||||
$domain, $domain
|
||||
// Check if domain already exists for any blog
|
||||
$domain_exists = dm_get_domain_by_name( $domain );
|
||||
|
||||
// Also check if it exists in the blogs table
|
||||
$blog_exists = $wpdb->get_row( $wpdb->prepare(
|
||||
"SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s",
|
||||
$domain
|
||||
));
|
||||
|
||||
if ( null == $domain_exists ) {
|
||||
// If primary, reset other domains to not primary
|
||||
if ( isset( $_POST['primary'] ) && $_POST['primary'] ) {
|
||||
$wpdb->update(
|
||||
$this->tables['domains'],
|
||||
array( 'active' => 0 ),
|
||||
array( 'blog_id' => $wpdb->blogid ),
|
||||
array( '%d' ),
|
||||
array( '%d' )
|
||||
);
|
||||
if ( $domain_exists || $blog_exists ) {
|
||||
// Check if it's for the current blog
|
||||
if ( $domain_exists && $domain_exists->blog_id == $wpdb->blogid ) {
|
||||
wp_redirect( add_query_arg( array( 'updated' => 'exists' ), $url ) );
|
||||
exit;
|
||||
} else {
|
||||
wp_die( sprintf(
|
||||
esc_html__( "Domain '%s' is already mapped to another site.", 'wp-domain-mapping' ),
|
||||
esc_html( $domain )
|
||||
));
|
||||
}
|
||||
|
||||
// Insert new domain
|
||||
$wpdb->insert(
|
||||
$this->tables['domains'],
|
||||
array(
|
||||
'blog_id' => $wpdb->blogid,
|
||||
'domain' => $domain,
|
||||
'active' => isset( $_POST['primary'] ) ? 1 : 0
|
||||
),
|
||||
array( '%d', '%s', '%d' )
|
||||
);
|
||||
|
||||
wp_redirect( add_query_arg( array( 'updated' => 'add' ), $url ) );
|
||||
exit;
|
||||
} else {
|
||||
wp_redirect( add_query_arg( array( 'updated' => 'exists' ), $url ) );
|
||||
exit;
|
||||
}
|
||||
break;
|
||||
|
||||
case "primary":
|
||||
// If primary, reset other domains to not primary
|
||||
if ( isset( $_POST['primary'] ) && $_POST['primary'] ) {
|
||||
$wpdb->update(
|
||||
$this->tables['domains'],
|
||||
array( 'active' => 0 ),
|
||||
array( 'blog_id' => $wpdb->blogid ),
|
||||
array( '%d' ),
|
||||
array( '%d' )
|
||||
);
|
||||
}
|
||||
|
||||
// Insert new domain
|
||||
$wpdb->insert(
|
||||
$this->tables['domains'],
|
||||
array(
|
||||
'blog_id' => $wpdb->blogid,
|
||||
'domain' => $domain,
|
||||
'active' => isset( $_POST['primary'] ) ? 1 : 0
|
||||
),
|
||||
array( '%d', '%s', '%d' )
|
||||
);
|
||||
|
||||
// 记录日志
|
||||
dm_log_action( 'add', $domain, $wpdb->blogid );
|
||||
|
||||
// 清除缓存
|
||||
dm_clear_domain_cache( $wpdb->blogid );
|
||||
|
||||
wp_redirect( add_query_arg( array( 'updated' => 'add' ), $url ) );
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 处理 GET 请求(删除和设为主域名)
|
||||
elseif ( isset( $_GET['action'] ) ) {
|
||||
$action = sanitize_text_field( $_GET['action'] );
|
||||
$domain = isset( $_GET['domain'] ) ? sanitize_text_field( $_GET['domain'] ) : '';
|
||||
|
||||
if ( empty( $domain ) ) {
|
||||
wp_die( esc_html__( "You must enter a domain", 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
switch ( $action ) {
|
||||
case 'primary':
|
||||
check_admin_referer( 'domain_mapping' );
|
||||
|
||||
do_action( 'dm_handle_actions_primary', $domain );
|
||||
|
||||
// Verify domain belongs to current blog
|
||||
$domain_info = dm_get_domain_by_name( $domain );
|
||||
if ( ! $domain_info || $domain_info->blog_id != $wpdb->blogid ) {
|
||||
wp_die( esc_html__( "Domain not found or does not belong to this site.", 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
// Reset all domains to not primary
|
||||
$wpdb->update(
|
||||
$this->tables['domains'],
|
||||
|
@ -492,30 +1152,52 @@ class WP_Domain_Mapping_Admin {
|
|||
);
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
dm_log_action( 'edit', $domain, $wpdb->blogid );
|
||||
|
||||
// 清除缓存
|
||||
dm_clear_domain_cache( $wpdb->blogid );
|
||||
|
||||
wp_redirect( add_query_arg( array( 'updated' => 'primary' ), $url ) );
|
||||
exit;
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
check_admin_referer( "delete" . $domain );
|
||||
|
||||
do_action( 'dm_handle_actions_del', $domain );
|
||||
|
||||
// Verify domain belongs to current blog
|
||||
$domain_info = dm_get_domain_by_name( $domain );
|
||||
if ( ! $domain_info || $domain_info->blog_id != $wpdb->blogid ) {
|
||||
wp_die( esc_html__( "Domain not found or does not belong to this site.", 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
// Don't allow deleting primary domain
|
||||
if ( $domain_info->active == 1 ) {
|
||||
wp_die( esc_html__( "Cannot delete the primary domain. Please set another domain as primary first.", 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
// Delete the domain
|
||||
$wpdb->delete(
|
||||
$this->tables['domains'],
|
||||
array(
|
||||
'domain' => $domain,
|
||||
'blog_id' => $wpdb->blogid
|
||||
),
|
||||
array( '%s', '%d' )
|
||||
);
|
||||
|
||||
// 记录日志
|
||||
dm_log_action( 'delete', $domain, $wpdb->blogid );
|
||||
|
||||
// 清除缓存
|
||||
dm_clear_domain_cache( $wpdb->blogid );
|
||||
|
||||
wp_redirect( add_query_arg( array( 'updated' => 'del' ), $url ) );
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
} elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'delete' ) {
|
||||
$domain = sanitize_text_field( $_GET['domain'] );
|
||||
|
||||
if ( empty( $domain ) ) {
|
||||
wp_die( esc_html__( "You must enter a domain", 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( "delete" . $_GET['domain'] );
|
||||
|
||||
do_action( 'dm_handle_actions_del', $domain );
|
||||
|
||||
// Delete the domain
|
||||
$wpdb->delete(
|
||||
$this->tables['domains'],
|
||||
array( 'domain' => $domain ),
|
||||
array( '%s' )
|
||||
);
|
||||
|
||||
wp_redirect( add_query_arg( array( 'updated' => 'del' ), $url ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -710,7 +1392,7 @@ class WP_Domain_Mapping_Admin {
|
|||
/**
|
||||
* Default updated messages
|
||||
*/
|
||||
public function echo_default_updated_msg() {
|
||||
public static function echo_default_updated_msg() {
|
||||
if ( ! isset( $_GET['updated'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -449,7 +449,7 @@ class WP_Domain_Mapping_Core {
|
|||
|
||||
$protocol = is_ssl() ? 'https://' : 'http://';
|
||||
$hash = $this->get_hash();
|
||||
$key = md5( time() );
|
||||
$key = wp_generate_password(32, true, true);
|
||||
|
||||
$wpdb->insert(
|
||||
$this->tables['logins'],
|
||||
|
@ -475,6 +475,10 @@ class WP_Domain_Mapping_Core {
|
|||
public function remote_login_js() {
|
||||
global $current_blog, $current_user, $wpdb;
|
||||
|
||||
if (strtotime($details->t) < (time() - 300)) {
|
||||
wp_die(__('Login key expired', 'wp-domain-mapping'));
|
||||
}
|
||||
|
||||
if ( 0 == get_site_option( 'dm_remote_login' ) ) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -585,7 +585,7 @@ class WP_Domain_Mapping_Tools {
|
|||
* @param string $domain Domain to check
|
||||
* @return array Health check result
|
||||
*/
|
||||
private function check_domain_health( $domain ) {
|
||||
public function check_domain_health( $domain ) {
|
||||
$result = array(
|
||||
'domain' => $domain,
|
||||
'last_check' => current_time( 'mysql' ),
|
||||
|
@ -899,6 +899,12 @@ class WP_Domain_Mapping_Tools {
|
|||
wp_send_json_error( __( 'Invalid security token. Please try again.', 'wp-domain-mapping' ) );
|
||||
}
|
||||
|
||||
// 在处理文件之前添加:
|
||||
if ($_FILES['csv_file']['size'] > 5 * 1024 * 1024) {
|
||||
wp_send_json_error(__('File size exceeds 5MB limit.', 'wp-domain-mapping'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check file
|
||||
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' ) );
|
||||
|
@ -909,6 +915,13 @@ class WP_Domain_Mapping_Tools {
|
|||
$update_existing = isset( $_POST['update_existing'] ) ? (bool) $_POST['update_existing'] : false;
|
||||
$validate_sites = isset( $_POST['validate_sites'] ) ? (bool) $_POST['validate_sites'] : true;
|
||||
|
||||
// 验证文件类型
|
||||
$file_type = wp_check_filetype($_FILES['csv_file']['name']);
|
||||
if (!in_array($file_type['ext'], array('csv', 'txt'))) {
|
||||
wp_send_json_error(__('Only CSV files are allowed.', 'wp-domain-mapping'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Open file
|
||||
$file = fopen( $_FILES['csv_file']['tmp_name'], 'r' );
|
||||
if ( ! $file ) {
|
||||
|
|
|
@ -25,6 +25,7 @@ function dm_ensure_protocol( $domain ) {
|
|||
|
||||
/**
|
||||
* Clean domain name (remove protocol and trailing slash)
|
||||
* UPDATED: Keep www prefix to distinguish www.domain.com from domain.com
|
||||
*
|
||||
* @param string $domain Domain name
|
||||
* @return string Cleaned domain
|
||||
|
@ -36,6 +37,14 @@ function dm_clean_domain( $domain ) {
|
|||
// Remove trailing slash
|
||||
$domain = rtrim( $domain, '/' );
|
||||
|
||||
// Remove path if exists
|
||||
if ( strpos( $domain, '/' ) !== false ) {
|
||||
$domain = substr( $domain, 0, strpos( $domain, '/' ) );
|
||||
}
|
||||
|
||||
// Convert to lowercase for consistency
|
||||
$domain = strtolower( $domain );
|
||||
|
||||
// Convert IDN to ASCII (Punycode)
|
||||
if ( function_exists( 'idn_to_ascii' ) && preg_match( '/[^a-z0-9\-\.]/i', $domain ) ) {
|
||||
if (defined('INTL_IDNA_VARIANT_UTS46')) {
|
||||
|
@ -52,13 +61,29 @@ function dm_clean_domain( $domain ) {
|
|||
|
||||
/**
|
||||
* Validate a domain name
|
||||
* UPDATED: Accept www prefix as valid
|
||||
*
|
||||
* @param string $domain The domain
|
||||
* @return bool True if valid
|
||||
*/
|
||||
function dm_validate_domain( $domain ) {
|
||||
// Basic validation
|
||||
return (bool) preg_match( '/^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}$/i', $domain );
|
||||
// Basic validation - now accepts www prefix
|
||||
return (bool) preg_match( '/^(www\.)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}$/i', $domain );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two domains are the same (ignoring www prefix)
|
||||
*
|
||||
* @param string $domain1 First domain
|
||||
* @param string $domain2 Second domain
|
||||
* @return bool True if domains are essentially the same
|
||||
*/
|
||||
function dm_domains_are_equivalent( $domain1, $domain2 ) {
|
||||
// Remove www. prefix for comparison
|
||||
$clean1 = preg_replace( '/^www\./i', '', $domain1 );
|
||||
$clean2 = preg_replace( '/^www\./i', '', $domain2 );
|
||||
|
||||
return strcasecmp( $clean1, $clean2 ) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,6 +172,30 @@ function dm_get_domain_by_name( $domain ) {
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if domain exists for another blog
|
||||
* UPDATED: More precise checking for domain conflicts
|
||||
*
|
||||
* @param string $domain Domain name
|
||||
* @param int $exclude_blog_id Blog ID to exclude from check (optional)
|
||||
* @return object|null Domain object if exists for another blog, null otherwise
|
||||
*/
|
||||
function dm_domain_exists_for_another_blog( $domain, $exclude_blog_id = 0 ) {
|
||||
global $wpdb;
|
||||
|
||||
$tables = dm_get_table_names();
|
||||
|
||||
$query = "SELECT * FROM {$tables['domains']} WHERE domain = %s";
|
||||
$params = array( $domain );
|
||||
|
||||
if ( $exclude_blog_id > 0 ) {
|
||||
$query .= " AND blog_id != %d";
|
||||
$params[] = $exclude_blog_id;
|
||||
}
|
||||
|
||||
return $wpdb->get_row( $wpdb->prepare( $query, $params ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get domains by blog ID
|
||||
*
|
||||
|
@ -212,6 +261,7 @@ function dm_add_domain( $blog_id, $domain, $active = 0 ) {
|
|||
|
||||
if ( $result ) {
|
||||
dm_log_action( 'add', $domain, $blog_id );
|
||||
dm_clear_domain_cache( $blog_id );
|
||||
return $wpdb->insert_id;
|
||||
}
|
||||
|
||||
|
@ -220,17 +270,35 @@ function dm_add_domain( $blog_id, $domain, $active = 0 ) {
|
|||
|
||||
/**
|
||||
* Update domain mapping
|
||||
* UPDATED: Support changing domain name and blog_id
|
||||
*
|
||||
* @param string $domain Domain name
|
||||
* @param string $domain Domain name (current)
|
||||
* @param int $blog_id Blog ID
|
||||
* @param int $active Whether domain is primary (1) or not (0)
|
||||
* @param string $new_domain New domain name (optional)
|
||||
* @return bool True on success, false on failure
|
||||
*/
|
||||
function dm_update_domain( $domain, $blog_id, $active ) {
|
||||
function dm_update_domain( $domain, $blog_id, $active, $new_domain = null ) {
|
||||
global $wpdb;
|
||||
|
||||
$tables = dm_get_table_names();
|
||||
|
||||
// If changing domain name
|
||||
if ( $new_domain && $new_domain !== $domain ) {
|
||||
$new_domain = dm_clean_domain( $new_domain );
|
||||
|
||||
// Validate new domain
|
||||
if ( ! dm_validate_domain( $new_domain ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if new domain exists for another blog
|
||||
$existing = dm_domain_exists_for_another_blog( $new_domain, $blog_id );
|
||||
if ( $existing ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If setting as primary, reset other domains
|
||||
if ( $active ) {
|
||||
$wpdb->update(
|
||||
|
@ -242,17 +310,30 @@ function dm_update_domain( $domain, $blog_id, $active ) {
|
|||
);
|
||||
}
|
||||
|
||||
// Prepare update data
|
||||
$data = array(
|
||||
'active' => $active,
|
||||
'blog_id' => $blog_id
|
||||
);
|
||||
$data_format = array( '%d', '%d' );
|
||||
|
||||
if ( $new_domain && $new_domain !== $domain ) {
|
||||
$data['domain'] = $new_domain;
|
||||
$data_format[] = '%s';
|
||||
}
|
||||
|
||||
// Update domain
|
||||
$result = $wpdb->update(
|
||||
$tables['domains'],
|
||||
array( 'active' => $active ),
|
||||
$data,
|
||||
array( 'domain' => $domain ),
|
||||
array( '%d' ),
|
||||
$data_format,
|
||||
array( '%s' )
|
||||
);
|
||||
|
||||
if ( $result !== false ) {
|
||||
dm_log_action( 'edit', $domain, $blog_id );
|
||||
dm_log_action( 'edit', $new_domain ?: $domain, $blog_id );
|
||||
dm_clear_domain_cache( $blog_id );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -286,6 +367,7 @@ function dm_delete_domain( $domain ) {
|
|||
|
||||
if ( $result ) {
|
||||
dm_log_action( 'delete', $domain, $domain_info->blog_id );
|
||||
dm_clear_domain_cache( $domain_info->blog_id );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -319,6 +401,27 @@ function dm_get_health_result( $domain ) {
|
|||
return isset( $health_results[$domain_key] ) ? $health_results[$domain_key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if domain has all health checks passing
|
||||
*
|
||||
* @param string $domain Domain name
|
||||
* @return bool True if all health checks pass
|
||||
*/
|
||||
function dm_is_domain_healthy( $domain ) {
|
||||
$health_result = dm_get_health_result( $domain );
|
||||
|
||||
if ( ! $health_result ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check all three criteria: DNS, SSL, and Accessibility
|
||||
$dns_ok = isset( $health_result['dns_status'] ) && $health_result['dns_status'] === 'success';
|
||||
$ssl_ok = isset( $health_result['ssl_valid'] ) && $health_result['ssl_valid'] === true;
|
||||
$accessible_ok = isset( $health_result['accessible'] ) && $health_result['accessible'] === true;
|
||||
|
||||
return $dns_ok && $ssl_ok && $accessible_ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format action name for display
|
||||
*
|
||||
|
@ -339,3 +442,21 @@ function dm_format_action_name( $action ) {
|
|||
return ucfirst( $action );
|
||||
}
|
||||
}
|
||||
|
||||
// Cache functions
|
||||
function dm_get_domains_by_blog_id_cached($blog_id) {
|
||||
$cache_key = 'dm_domains_' . $blog_id;
|
||||
$domains = wp_cache_get($cache_key, 'domain_mapping');
|
||||
|
||||
if (false === $domains) {
|
||||
$domains = dm_get_domains_by_blog_id($blog_id);
|
||||
wp_cache_set($cache_key, $domains, 'domain_mapping', HOUR_IN_SECONDS);
|
||||
}
|
||||
|
||||
return $domains;
|
||||
}
|
||||
|
||||
// Clear cache function
|
||||
function dm_clear_domain_cache($blog_id) {
|
||||
wp_cache_delete('dm_domains_' . $blog_id, 'domain_mapping');
|
||||
}
|
||||
|
|
3
languages/wp-domain-mapping-zh_CN.l10n.php
Normal file
3
languages/wp-domain-mapping-zh_CN.l10n.php
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -29,8 +29,11 @@ global $wpdb, $current_blog, $current_site;
|
|||
$domain_mapping_table = $wpdb->base_prefix . 'domain_mapping';
|
||||
|
||||
// Check for the current domain in the domain mapping table
|
||||
$domain = $wpdb->escape($_SERVER['HTTP_HOST']);
|
||||
$blog_id = $wpdb->get_var("SELECT blog_id FROM {$domain_mapping_table} WHERE domain = '{$domain}' LIMIT 1");
|
||||
$domain = sanitize_text_field($_SERVER['HTTP_HOST']);
|
||||
$blog_id = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT blog_id FROM {$domain_mapping_table} WHERE domain = %s LIMIT 1",
|
||||
$domain
|
||||
));
|
||||
|
||||
// If we found a mapped domain, override current_blog
|
||||
if (!empty($blog_id)) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Plugin Name: WP Domain Mapping
|
||||
* Plugin URI: https://wenpai.org/plugins/wp-domain-mapping/
|
||||
* Description: Map any site on a WordPress website to another domain with enhanced management features.
|
||||
* Version: 2.0.2
|
||||
* Version: 2.1.0
|
||||
* Author: WPDomain.com
|
||||
* Author URI: https://wpdomain.com/
|
||||
* Network: true
|
||||
|
@ -20,7 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
}
|
||||
|
||||
// Define plugin constants
|
||||
define( 'WP_DOMAIN_MAPPING_VERSION', '2.0.2' );
|
||||
define( 'WP_DOMAIN_MAPPING_VERSION', '2.1.0' );
|
||||
define( 'WP_DOMAIN_MAPPING_DIR_URL', plugin_dir_url( __FILE__ ) );
|
||||
define( 'WP_DOMAIN_MAPPING_DIR_PATH', plugin_dir_path( __FILE__ ) );
|
||||
define( 'WP_DOMAIN_MAPPING_BASENAME', plugin_basename( __FILE__ ) );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue