mirror of
https://github.com/WenPai-org/wpavatar.git
synced 2025-08-07 10:08:28 +08:00
v1.8.1 添加多站点支持
This commit is contained in:
parent
31a0254299
commit
88d798a5a5
6 changed files with 2449 additions and 404 deletions
|
@ -9,6 +9,7 @@ jQuery(document).ready(function($) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Tab navigation
|
||||
$('.wpavatar-tab').on('click', function() {
|
||||
var tab = $(this).data('tab');
|
||||
if (!tab) return;
|
||||
|
@ -21,7 +22,11 @@ jQuery(document).ready(function($) {
|
|||
|
||||
if (tab === 'cache' && $('#cache-stats').is(':empty')) {
|
||||
setTimeout(function() {
|
||||
if (wpavatar.is_network_admin === '1') {
|
||||
$('#check-all-cache').trigger('click');
|
||||
} else {
|
||||
$('#check-cache').trigger('click');
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
|
@ -32,6 +37,7 @@ jQuery(document).ready(function($) {
|
|||
}
|
||||
});
|
||||
|
||||
// CDN options management
|
||||
function updateCdnOptions() {
|
||||
var selectedType = $('input[name="wpavatar_cdn_type"]:checked').val();
|
||||
|
||||
|
@ -53,23 +59,32 @@ jQuery(document).ready(function($) {
|
|||
if (value && value.toLowerCase().indexOf('cravatar') !== -1) {
|
||||
forceMd5HashMethod(true);
|
||||
} else {
|
||||
// 非Cravatar服务默认选择SHA256,但不强制
|
||||
var currentHashMethod = $('input[name="wpavatar_hash_method"]:checked').val();
|
||||
if (!currentHashMethod) {
|
||||
$('input[name="wpavatar_hash_method"][value="sha256"]').prop('checked', true);
|
||||
}
|
||||
forceMd5HashMethod(false);
|
||||
}
|
||||
}
|
||||
|
||||
function forceMd5HashMethod(force) {
|
||||
if (force) {
|
||||
// Save the current user-selected hash method to restore later if needed
|
||||
var currentMethod = $('input[name="wpavatar_hash_method"]:checked').val();
|
||||
if (currentMethod) {
|
||||
$(this).data('previous-hash-method', currentMethod);
|
||||
}
|
||||
|
||||
// Force MD5 and disable SHA256 option
|
||||
$('input[name="wpavatar_hash_method"][value="md5"]').prop('checked', true);
|
||||
$('input[name="wpavatar_hash_method"][value="sha256"]').prop('disabled', true);
|
||||
$('.hash-method-notice').show();
|
||||
} else {
|
||||
// Restore disabled state, but don't change selection
|
||||
$('input[name="wpavatar_hash_method"][value="sha256"]').prop('disabled', false);
|
||||
$('.hash-method-notice').hide();
|
||||
|
||||
// Restore previous selection (if any)
|
||||
var previousMethod = $(this).data('previous-hash-method');
|
||||
if (previousMethod && previousMethod === 'sha256') {
|
||||
$('input[name="wpavatar_hash_method"][value="sha256"]').prop('checked', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,6 +100,7 @@ jQuery(document).ready(function($) {
|
|||
checkIfCravatarRelated($(this).val());
|
||||
});
|
||||
|
||||
// Cache management for single site
|
||||
$('#check-cache').on('click', function() {
|
||||
var $button = $(this);
|
||||
var $stats = $('#cache-stats');
|
||||
|
@ -165,6 +181,111 @@ jQuery(document).ready(function($) {
|
|||
});
|
||||
});
|
||||
|
||||
// Cache management for network admin
|
||||
if (wpavatar.is_network_admin === '1') {
|
||||
$('#check-all-cache').on('click', function() {
|
||||
var $button = $(this);
|
||||
var $stats = $('#cache-stats');
|
||||
|
||||
$button.prop('disabled', true).text(wpavatar_l10n.checking);
|
||||
$stats.html('<p>' + wpavatar_l10n.checking_status + '</p>');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: wpavatar.ajaxurl,
|
||||
data: {
|
||||
action: 'wpavatar_check_all_cache',
|
||||
nonce: wpavatar.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$stats.html(response.data);
|
||||
} else {
|
||||
$stats.html('<div class="error"><p>' + (response.data || wpavatar_l10n.check_failed) + '</p></div>');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$stats.html('<div class="error"><p>' + wpavatar_l10n.request_failed + '</p></div>');
|
||||
},
|
||||
complete: function() {
|
||||
$button.prop('disabled', false).text('查看所有站点缓存');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#purge-all-cache').on('click', function() {
|
||||
var $button = $(this);
|
||||
var $stats = $('#cache-stats');
|
||||
var $status = $('#wpavatar-status');
|
||||
|
||||
if (!confirm(wpavatar_l10n.confirm_purge)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$button.prop('disabled', true).text(wpavatar_l10n.purging);
|
||||
$stats.html('<p>' + wpavatar_l10n.purging_cache + '</p>');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: wpavatar.ajaxurl,
|
||||
data: {
|
||||
action: 'wpavatar_purge_all_cache',
|
||||
nonce: wpavatar.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$status.removeClass('notice-error')
|
||||
.addClass('notice-success')
|
||||
.text(response.data)
|
||||
.show()
|
||||
.delay(3000)
|
||||
.fadeOut();
|
||||
|
||||
setTimeout(function() {
|
||||
$('#check-all-cache').trigger('click');
|
||||
}, 1000);
|
||||
} else {
|
||||
$status.removeClass('notice-success')
|
||||
.addClass('notice-error')
|
||||
.text(response.data || wpavatar_l10n.purge_failed)
|
||||
.show();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$status.removeClass('notice-success')
|
||||
.addClass('notice-error')
|
||||
.text(wpavatar_l10n.request_failed)
|
||||
.show();
|
||||
},
|
||||
complete: function() {
|
||||
$button.prop('disabled', false).text('清空所有站点缓存');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Network management controls
|
||||
if ($('#select-all-options').length) {
|
||||
$('#select-all-options').on('click', function() {
|
||||
$('input[name="wpavatar_network_controlled_options[]"]').prop('checked', true);
|
||||
});
|
||||
|
||||
$('#deselect-all-options').on('click', function() {
|
||||
$('input[name="wpavatar_network_controlled_options[]"]').prop('checked', false);
|
||||
});
|
||||
|
||||
$('#reset-default-options').on('click', function() {
|
||||
if (confirm(wpavatar_l10n.confirm_reset)) {
|
||||
var defaultOptions = ['wpavatar_enable_cravatar', 'wpavatar_cdn_type', 'wpavatar_cravatar_route', 'wpavatar_third_party_mirror', 'wpavatar_custom_cdn'];
|
||||
|
||||
$('input[name="wpavatar_network_controlled_options[]"]').each(function() {
|
||||
$(this).prop('checked', defaultOptions.indexOf($(this).val()) !== -1);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Form validation
|
||||
$('#wpavatar-basic-form, #wpavatar-cache-form, #wpavatar-advanced-form, #wpavatar-shortcodes-form').on('submit', function(e) {
|
||||
var formId = $(this).attr('id');
|
||||
var $status = $('#wpavatar-status');
|
||||
|
@ -202,6 +323,28 @@ jQuery(document).ready(function($) {
|
|||
return true;
|
||||
});
|
||||
|
||||
// For network import and bulk operations
|
||||
if ($('#import-site-settings').length) {
|
||||
$('#import-site-settings').on('click', function(e) {
|
||||
if (!confirm(wpavatar_l10n.confirm_import)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if ($('#apply-to-all-sites').length) {
|
||||
$('#apply-to-all-sites').on('click', function(e) {
|
||||
if (!confirm('确定要将网络设置应用到所有站点吗?此操作将覆盖每个站点的现有设置。')) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Settings saved notification
|
||||
if (window.location.search.indexOf('settings-updated=true') > -1) {
|
||||
$('#wpavatar-status')
|
||||
.removeClass('notice-error')
|
||||
|
@ -212,6 +355,29 @@ jQuery(document).ready(function($) {
|
|||
.fadeOut();
|
||||
}
|
||||
|
||||
// Import settings notification
|
||||
if (window.location.search.indexOf('imported=true') > -1) {
|
||||
$('#wpavatar-status')
|
||||
.removeClass('notice-error')
|
||||
.addClass('notice-success')
|
||||
.text('站点设置已成功导入到网络设置。')
|
||||
.show()
|
||||
.delay(3000)
|
||||
.fadeOut();
|
||||
}
|
||||
|
||||
// Applied to all sites notification
|
||||
if (window.location.search.indexOf('applied=true') > -1) {
|
||||
$('#wpavatar-status')
|
||||
.removeClass('notice-error')
|
||||
.addClass('notice-success')
|
||||
.text('网络设置已成功应用到所有站点。')
|
||||
.show()
|
||||
.delay(3000)
|
||||
.fadeOut();
|
||||
}
|
||||
|
||||
// Set active tab
|
||||
var currentTab = '';
|
||||
|
||||
if (window.location.search.indexOf('tab=') > -1) {
|
||||
|
|
|
@ -81,10 +81,33 @@ class Settings {
|
|||
return get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
}
|
||||
|
||||
// If multisite, ensure the site-specific cache directory exists
|
||||
if (is_multisite()) {
|
||||
$blog_id = get_current_blog_id();
|
||||
$site_cache_dir = trailingslashit($value) . 'site-' . $blog_id;
|
||||
|
||||
if (!file_exists($site_cache_dir)) {
|
||||
if (!wp_mkdir_p($site_cache_dir)) {
|
||||
add_settings_error(
|
||||
'wpavatar_cache',
|
||||
'cache_path_invalid',
|
||||
__('无法创建站点缓存目录,请检查权限', 'wpavatar'),
|
||||
'error'
|
||||
);
|
||||
return get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
}
|
||||
}
|
||||
|
||||
$index_file = $site_cache_dir . '/index.php';
|
||||
if (!file_exists($index_file)) {
|
||||
@file_put_contents($index_file, '<?php // Silence is golden.');
|
||||
}
|
||||
} else {
|
||||
$index_file = $value . 'index.php';
|
||||
if (!file_exists($index_file)) {
|
||||
@file_put_contents($index_file, '<?php // Silence is golden.');
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
@ -112,9 +135,11 @@ class Settings {
|
|||
wp_localize_script('wpavatar-admin', 'wpavatar', [
|
||||
'nonce' => wp_create_nonce('wpavatar_admin_nonce'),
|
||||
'ajaxurl' => admin_url('admin-ajax.php'),
|
||||
'cache_path' => get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR),
|
||||
'cache_path' => wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR),
|
||||
'plugin_url' => WPAVATAR_PLUGIN_URL,
|
||||
'assets_url' => WPAVATAR_PLUGIN_URL . 'assets/',
|
||||
'is_network_admin' => '0',
|
||||
'is_multisite' => is_multisite() ? '1' : '0',
|
||||
]);
|
||||
|
||||
wp_localize_script('wpavatar-admin', 'wpavatar_l10n', [
|
||||
|
@ -142,6 +167,17 @@ class Settings {
|
|||
}
|
||||
|
||||
public static function render_settings_page() {
|
||||
// Check for network control in multisite
|
||||
if (is_multisite()) {
|
||||
$network_enabled = get_site_option('wpavatar_network_enabled', 1);
|
||||
$network_enforce = get_site_option('wpavatar_network_enforce', 0);
|
||||
$network_controlled_options = get_site_option('wpavatar_network_controlled_options', array());
|
||||
|
||||
if (!is_array($network_controlled_options)) {
|
||||
$network_controlled_options = explode(',', $network_controlled_options);
|
||||
}
|
||||
}
|
||||
|
||||
$active_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'basic';
|
||||
?>
|
||||
<div class="wrap wpavatar-settings">
|
||||
|
@ -174,24 +210,66 @@ class Settings {
|
|||
<h2><?php _e('基础设置', 'wpavatar'); ?></h2>
|
||||
<p class="wpavatar-section-desc"><?php _e('配置头像服务和CDN设置。', 'wpavatar'); ?></p>
|
||||
|
||||
<?php if (is_multisite() && $network_enabled): ?>
|
||||
<div class="wpavatar-network-notice">
|
||||
<p>
|
||||
<?php if (in_array('wpavatar_enable_cravatar', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('启用初认头像', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_cdn_type', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('线路选择', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_cravatar_route', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('Cravatar官方源', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_third_party_mirror', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('第三方镜像', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_custom_cdn', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('自定义CDN', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_hash_method', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('头像哈希方法', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_timeout', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('超时设置', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (array_intersect(['wpavatar_enable_cravatar', 'wpavatar_cdn_type', 'wpavatar_cravatar_route', 'wpavatar_third_party_mirror', 'wpavatar_custom_cdn', 'wpavatar_hash_method', 'wpavatar_timeout'], $network_controlled_options)): ?>
|
||||
<em><?php _e('以上选项由网络管理员控制,您的更改将不会生效。', 'wpavatar'); ?></em>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="options.php" id="wpavatar-basic-form">
|
||||
<?php
|
||||
settings_fields('wpavatar_basic');
|
||||
|
||||
$enable_cravatar = get_option('wpavatar_enable_cravatar', 1);
|
||||
$cdn_type = get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$cravatar_route = get_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
$third_party_mirror = get_option('wpavatar_third_party_mirror', 'weavatar.com');
|
||||
$custom_cdn = get_option('wpavatar_custom_cdn', '');
|
||||
$hash_method = get_option('wpavatar_hash_method', 'md5');
|
||||
$timeout = get_option('wpavatar_timeout', 5);
|
||||
// Get option values using wpavatar_get_option instead of get_option
|
||||
$enable_cravatar = wpavatar_get_option('wpavatar_enable_cravatar', 1);
|
||||
$cdn_type = wpavatar_get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$cravatar_route = wpavatar_get_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
$third_party_mirror = wpavatar_get_option('wpavatar_third_party_mirror', 'weavatar.com');
|
||||
$custom_cdn = wpavatar_get_option('wpavatar_custom_cdn', '');
|
||||
$hash_method = wpavatar_get_option('wpavatar_hash_method', 'md5');
|
||||
$timeout = wpavatar_get_option('wpavatar_timeout', 5);
|
||||
|
||||
// Determine if fields should be disabled in multisite
|
||||
$disabled_enable_cravatar = (is_multisite() && $network_enabled && in_array('wpavatar_enable_cravatar', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_cdn_type = (is_multisite() && $network_enabled && in_array('wpavatar_cdn_type', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_cravatar_route = (is_multisite() && $network_enabled && in_array('wpavatar_cravatar_route', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_third_party_mirror = (is_multisite() && $network_enabled && in_array('wpavatar_third_party_mirror', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_custom_cdn = (is_multisite() && $network_enabled && in_array('wpavatar_custom_cdn', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_hash_method = (is_multisite() && $network_enabled && in_array('wpavatar_hash_method', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_timeout = (is_multisite() && $network_enabled && in_array('wpavatar_timeout', $network_controlled_options)) ? 'disabled' : '';
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><?php _e('启用初认头像', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<label class="wpavatar-switch">
|
||||
<input type="checkbox" name="wpavatar_enable_cravatar" value="1" <?php checked($enable_cravatar); ?>>
|
||||
<input type="checkbox" name="wpavatar_enable_cravatar" value="1" <?php checked($enable_cravatar); ?> <?php echo $disabled_enable_cravatar; ?>>
|
||||
<span class="wpavatar-slider"></span>
|
||||
<span class="wpavatar-switch-label"><?php _e('替换WordPress默认头像为Cravatar', 'wpavatar'); ?></span>
|
||||
</label>
|
||||
|
@ -202,15 +280,15 @@ class Settings {
|
|||
<th><?php _e('线路选择', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<label class="wpavatar-radio">
|
||||
<input type="radio" name="wpavatar_cdn_type" value="cravatar_route" <?php checked($cdn_type, 'cravatar_route'); ?>>
|
||||
<input type="radio" name="wpavatar_cdn_type" value="cravatar_route" <?php checked($cdn_type, 'cravatar_route'); ?> <?php echo $disabled_cdn_type; ?>>
|
||||
<span class="wpavatar-radio-label"><?php _e('Cravatar自选线路', 'wpavatar'); ?></span>
|
||||
</label><br>
|
||||
<label class="wpavatar-radio">
|
||||
<input type="radio" name="wpavatar_cdn_type" value="third_party" <?php checked($cdn_type, 'third_party'); ?>>
|
||||
<input type="radio" name="wpavatar_cdn_type" value="third_party" <?php checked($cdn_type, 'third_party'); ?> <?php echo $disabled_cdn_type; ?>>
|
||||
<span class="wpavatar-radio-label"><?php _e('第三方镜像', 'wpavatar'); ?></span>
|
||||
</label><br>
|
||||
<label class="wpavatar-radio">
|
||||
<input type="radio" name="wpavatar_cdn_type" value="custom" <?php checked($cdn_type, 'custom'); ?>>
|
||||
<input type="radio" name="wpavatar_cdn_type" value="custom" <?php checked($cdn_type, 'custom'); ?> <?php echo $disabled_cdn_type; ?>>
|
||||
<span class="wpavatar-radio-label"><?php _e('自定义CDN', 'wpavatar'); ?></span>
|
||||
</label>
|
||||
</td>
|
||||
|
@ -218,7 +296,7 @@ class Settings {
|
|||
<tr class="cdn-option cravatar-route-option" <?php echo $cdn_type !== 'cravatar_route' ? 'style="display:none;"' : ''; ?>>
|
||||
<th><?php _e('Cravatar官方源', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<select name="wpavatar_cravatar_route" class="wpavatar-select">
|
||||
<select name="wpavatar_cravatar_route" class="wpavatar-select" <?php echo $disabled_cravatar_route; ?>>
|
||||
<option value="cravatar.cn" <?php selected($cravatar_route, 'cravatar.cn'); ?>><?php _e('默认线路 (cravatar.com)', 'wpavatar'); ?></option>
|
||||
<option value="cn.cravatar.com" <?php selected($cravatar_route, 'cn.cravatar.com'); ?>><?php _e('中国 (cn.cravatar.com)', 'wpavatar'); ?></option>
|
||||
<option value="hk.cravatar.com" <?php selected($cravatar_route, 'hk.cravatar.com'); ?>><?php _e('香港 (hk.cravatar.com)', 'wpavatar'); ?></option>
|
||||
|
@ -230,7 +308,7 @@ class Settings {
|
|||
<tr class="cdn-option third-party-option" <?php echo $cdn_type !== 'third_party' ? 'style="display:none;"' : ''; ?>>
|
||||
<th><?php _e('第三方镜像', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<select name="wpavatar_third_party_mirror" class="wpavatar-select">
|
||||
<select name="wpavatar_third_party_mirror" class="wpavatar-select" <?php echo $disabled_third_party_mirror; ?>>
|
||||
<option value="weavatar.com" <?php selected($third_party_mirror, 'weavatar.com'); ?>><?php _e('WeAvatar (weavatar.com)', 'wpavatar'); ?></option>
|
||||
<option value="libravatar.org" <?php selected($third_party_mirror, 'libravatar.org'); ?>><?php _e('Libravatar (libravatar.org)', 'wpavatar'); ?></option>
|
||||
<option value="gravatar.loli.net" <?php selected($third_party_mirror, 'gravatar.loli.net'); ?>><?php _e('Loli镜像 (gravatar.loli.net)', 'wpavatar'); ?></option>
|
||||
|
@ -244,7 +322,7 @@ class Settings {
|
|||
<tr class="cdn-option custom-cdn-option" <?php echo $cdn_type !== 'custom' ? 'style="display:none;"' : ''; ?>>
|
||||
<th><?php _e('自定义CDN', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<input type="text" name="wpavatar_custom_cdn" value="<?php echo esc_attr($custom_cdn); ?>" class="regular-text wpavatar-input">
|
||||
<input type="text" name="wpavatar_custom_cdn" value="<?php echo esc_attr($custom_cdn); ?>" class="regular-text wpavatar-input" <?php echo $disabled_custom_cdn; ?>>
|
||||
<p class="description"><?php _e('输入自定义CDN域名,例如:cdn.example.com', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -252,21 +330,21 @@ class Settings {
|
|||
<th><?php _e('头像哈希方法', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<label class="wpavatar-radio">
|
||||
<input type="radio" name="wpavatar_hash_method" value="md5" <?php checked($hash_method, 'md5'); ?>>
|
||||
<input type="radio" name="wpavatar_hash_method" value="md5" <?php checked($hash_method, 'md5'); ?> <?php echo $disabled_hash_method; ?>>
|
||||
<span class="wpavatar-radio-label"><?php _e('MD5 (Cravatar默认)', 'wpavatar'); ?></span>
|
||||
</label><br>
|
||||
<label class="wpavatar-radio">
|
||||
<input type="radio" name="wpavatar_hash_method" value="sha256" <?php checked($hash_method, 'sha256'); ?>>
|
||||
<input type="radio" name="wpavatar_hash_method" value="sha256" <?php checked($hash_method, 'sha256'); ?> <?php echo $disabled_hash_method; ?>>
|
||||
<span class="wpavatar-radio-label"><?php _e('SHA256 (Gravatar默认)', 'wpavatar'); ?></span>
|
||||
</label>
|
||||
<p class="description"><?php _e('选择头像邮箱的哈希方法,Cravatar目前使用MD5,一般Gravatar镜像均为SHA256', 'wpavatar'); ?></p>
|
||||
<p class="description hash-method-notice" style="color: #d63638; <?php echo $cdn_type !== 'cravatar_route' ? 'display:none;' : ''; ?>"><?php _e('注意:使用Cravatar服务时,哈希方法将仅使用MD5', 'wpavatar'); ?></p>
|
||||
<p class="description hash-method-notice" style="color: #d63638; <?php echo $cdn_type !== 'cravatar_route' ? 'display:none;' : ''; ?>"><?php _e('注意:使用Cravatar服务时,哈希方法将仅使用MD5。', 'wpavatar'); ?> <a href="https://cravatar.com/docs" target="_blank" rel="noopener noreferrer"><?php _e('进一步了解↗', 'wpavatar'); ?></a></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php _e('超时设置', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wpavatar_timeout" value="<?php echo esc_attr($timeout); ?>" min="1" max="30" class="small-text wpavatar-input">
|
||||
<input type="number" name="wpavatar_timeout" value="<?php echo esc_attr($timeout); ?>" min="1" max="30" class="small-text wpavatar-input" <?php echo $disabled_timeout; ?>>
|
||||
<?php _e('秒', 'wpavatar'); ?>
|
||||
<p class="description"><?php _e('头像请求的最大等待时间,超过后将使用备用头像', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
|
@ -283,6 +361,26 @@ class Settings {
|
|||
<h2><?php _e('缓存控制', 'wpavatar'); ?></h2>
|
||||
<p class="wpavatar-section-desc"><?php _e('管理头像缓存设置和操作。', 'wpavatar'); ?></p>
|
||||
|
||||
<?php if (is_multisite() && $network_enabled): ?>
|
||||
<div class="wpavatar-network-notice">
|
||||
<p>
|
||||
<?php if (in_array('wpavatar_enable_cache', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('启用本地缓存', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_cache_path', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('缓存目录', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_cache_expire', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('缓存过期时间', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (array_intersect(['wpavatar_enable_cache', 'wpavatar_cache_path', 'wpavatar_cache_expire'], $network_controlled_options)): ?>
|
||||
<em><?php _e('以上选项由网络管理员控制,您的更改将不会生效。', 'wpavatar'); ?></em>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="wpavatar-stats-card">
|
||||
<h3><?php _e('缓存统计', 'wpavatar'); ?></h3>
|
||||
<div id="cache-stats" class="cache-stats-wrapper"></div>
|
||||
|
@ -296,16 +394,22 @@ class Settings {
|
|||
<?php
|
||||
settings_fields('wpavatar_cache');
|
||||
|
||||
$enable_cache = get_option('wpavatar_enable_cache', 1);
|
||||
$cache_path = get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$cache_expire = get_option('wpavatar_cache_expire', 7);
|
||||
// Get option values using wpavatar_get_option instead of get_option
|
||||
$enable_cache = wpavatar_get_option('wpavatar_enable_cache', 1);
|
||||
$cache_path = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$cache_expire = wpavatar_get_option('wpavatar_cache_expire', 7);
|
||||
|
||||
// Determine if fields should be disabled in multisite
|
||||
$disabled_enable_cache = (is_multisite() && $network_enabled && in_array('wpavatar_enable_cache', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_cache_path = (is_multisite() && $network_enabled && in_array('wpavatar_cache_path', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_cache_expire = (is_multisite() && $network_enabled && in_array('wpavatar_cache_expire', $network_controlled_options)) ? 'disabled' : '';
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><?php _e('启用本地缓存', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<label class="wpavatar-switch">
|
||||
<input type="checkbox" name="wpavatar_enable_cache" value="1" <?php checked($enable_cache); ?>>
|
||||
<input type="checkbox" name="wpavatar_enable_cache" value="1" <?php checked($enable_cache); ?> <?php echo $disabled_enable_cache; ?>>
|
||||
<span class="wpavatar-slider"></span>
|
||||
<span class="wpavatar-switch-label"><?php _e('缓存头像到本地服务器', 'wpavatar'); ?></span>
|
||||
</label>
|
||||
|
@ -315,14 +419,18 @@ class Settings {
|
|||
<tr>
|
||||
<th><?php _e('缓存目录', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<input type="text" name="wpavatar_cache_path" value="<?php echo esc_attr($cache_path); ?>" class="regular-text wpavatar-input">
|
||||
<input type="text" name="wpavatar_cache_path" value="<?php echo esc_attr($cache_path); ?>" class="regular-text wpavatar-input" <?php echo $disabled_cache_path; ?>>
|
||||
<?php if (is_multisite()): ?>
|
||||
<p class="description"><?php printf(__('确保目录可写,当前站点将创建子目录:%s', 'wpavatar'), trailingslashit($cache_path) . 'site-' . get_current_blog_id()); ?></p>
|
||||
<?php else: ?>
|
||||
<p class="description"><?php _e('确保目录可写,建议路径:/wp-content/uploads/cravatar', 'wpavatar'); ?></p>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php _e('缓存过期时间', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wpavatar_cache_expire" value="<?php echo esc_attr($cache_expire); ?>" min="1" max="30" class="small-text wpavatar-input">
|
||||
<input type="number" name="wpavatar_cache_expire" value="<?php echo esc_attr($cache_expire); ?>" min="1" max="30" class="small-text wpavatar-input" <?php echo $disabled_cache_expire; ?>>
|
||||
<?php _e('天', 'wpavatar'); ?>
|
||||
<p class="description"><?php _e('头像缓存的有效期,过期后将重新获取', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
|
@ -339,21 +447,47 @@ class Settings {
|
|||
<h2><?php _e('高级设置', 'wpavatar'); ?></h2>
|
||||
<p class="wpavatar-section-desc"><?php _e('配置头像的SEO和备用方案。', 'wpavatar'); ?></p>
|
||||
|
||||
<?php if (is_multisite() && $network_enabled): ?>
|
||||
<div class="wpavatar-network-notice">
|
||||
<p>
|
||||
<?php if (in_array('wpavatar_seo_alt', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('SEO替代文本', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_fallback_mode', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('头像加载失败处理', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_fallback_avatar', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('备用头像选择', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (array_intersect(['wpavatar_seo_alt', 'wpavatar_fallback_mode', 'wpavatar_fallback_avatar'], $network_controlled_options)): ?>
|
||||
<em><?php _e('以上选项由网络管理员控制,您的更改将不会生效。', 'wpavatar'); ?></em>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="options.php" id="wpavatar-advanced-form">
|
||||
<?php
|
||||
settings_fields('wpavatar_advanced');
|
||||
|
||||
$seo_alt = get_option('wpavatar_seo_alt', '%s的头像');
|
||||
$fallback_mode = get_option('wpavatar_fallback_mode', 1);
|
||||
$fallback_avatar = get_option('wpavatar_fallback_avatar', 'default');
|
||||
// Get option values using wpavatar_get_option instead of get_option
|
||||
$seo_alt = wpavatar_get_option('wpavatar_seo_alt', '%s的头像');
|
||||
$fallback_mode = wpavatar_get_option('wpavatar_fallback_mode', 1);
|
||||
$fallback_avatar = wpavatar_get_option('wpavatar_fallback_avatar', 'default');
|
||||
|
||||
$local_avatars = \WPAvatar\Cravatar::get_local_avatars();
|
||||
|
||||
// Determine if fields should be disabled in multisite
|
||||
$disabled_seo_alt = (is_multisite() && $network_enabled && in_array('wpavatar_seo_alt', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_fallback_mode = (is_multisite() && $network_enabled && in_array('wpavatar_fallback_mode', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_fallback_avatar = (is_multisite() && $network_enabled && in_array('wpavatar_fallback_avatar', $network_controlled_options)) ? 'disabled' : '';
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><?php _e('SEO替代文本', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<input type="text" name="wpavatar_seo_alt" value="<?php echo esc_attr($seo_alt); ?>" class="regular-text wpavatar-input">
|
||||
<input type="text" name="wpavatar_seo_alt" value="<?php echo esc_attr($seo_alt); ?>" class="regular-text wpavatar-input" <?php echo $disabled_seo_alt; ?>>
|
||||
<p class="description"><?php _e('头像的ALT文本,%s将被替换为用户名', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -361,7 +495,7 @@ class Settings {
|
|||
<th><?php _e('头像加载失败处理', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<label class="wpavatar-switch">
|
||||
<input type="checkbox" name="wpavatar_fallback_mode" value="1" <?php checked($fallback_mode); ?>>
|
||||
<input type="checkbox" name="wpavatar_fallback_mode" value="1" <?php checked($fallback_mode); ?> <?php echo $disabled_fallback_mode; ?>>
|
||||
<span class="wpavatar-slider"></span>
|
||||
<span class="wpavatar-switch-label"><?php _e('启用备用头像', 'wpavatar'); ?></span>
|
||||
</label>
|
||||
|
@ -374,7 +508,7 @@ class Settings {
|
|||
<div class="default-avatar-options">
|
||||
<?php foreach ($local_avatars as $key => $avatar) : ?>
|
||||
<label>
|
||||
<input type="radio" name="wpavatar_fallback_avatar" value="<?php echo esc_attr($key); ?>" <?php checked($fallback_avatar, $key); ?>>
|
||||
<input type="radio" name="wpavatar_fallback_avatar" value="<?php echo esc_attr($key); ?>" <?php checked($fallback_avatar, $key); ?> <?php echo $disabled_fallback_avatar; ?>>
|
||||
<img src="<?php echo esc_url($avatar['url']); ?>" alt="<?php echo esc_attr($avatar['name']); ?>" width="48" height="48">
|
||||
<span class="avatar-option-name"><?php echo esc_html($avatar['name']); ?></span>
|
||||
</label>
|
||||
|
@ -388,7 +522,7 @@ class Settings {
|
|||
: 'https://wpcy.com';
|
||||
|
||||
printf(
|
||||
__('选择您喜欢的故障备用头像,如需智能线路切换,请使用%s。', 'wpavatar'),
|
||||
__('选择您的故障备用头像,如需智能线路切换,请使用%s。', 'wpavatar'),
|
||||
sprintf(
|
||||
'<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
|
||||
esc_url($wpcy_link),
|
||||
|
@ -407,11 +541,30 @@ class Settings {
|
|||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="wpavatar-section" id="wpavatar-section-shortcodes" style="<?php echo $active_tab !== 'shortcodes' ? 'display: none;' : ''; ?>">
|
||||
<h2><?php _e('简码设置', 'wpavatar'); ?></h2>
|
||||
<p class="wpavatar-section-desc"><?php _e('配置头像简码的默认参数和预览效果。', 'wpavatar'); ?></p>
|
||||
|
||||
<?php if (is_multisite() && $network_enabled): ?>
|
||||
<div class="wpavatar-network-notice">
|
||||
<p>
|
||||
<?php if (in_array('wpavatar_shortcode_size', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('默认头像大小', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_shortcode_class', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('默认CSS类名', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array('wpavatar_shortcode_shape', $network_controlled_options)): ?>
|
||||
<span class="dashicons dashicons-lock"></span> <?php _e('默认头像形状', 'wpavatar'); ?><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (array_intersect(['wpavatar_shortcode_size', 'wpavatar_shortcode_class', 'wpavatar_shortcode_shape'], $network_controlled_options)): ?>
|
||||
<em><?php _e('以上选项由网络管理员控制,您的更改将不会生效。', 'wpavatar'); ?></em>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="wpavatar-preview-container">
|
||||
<h3><?php _e('头像预览', 'wpavatar'); ?></h3>
|
||||
<div class="wpavatar-preview-wrapper">
|
||||
|
@ -447,29 +600,35 @@ class Settings {
|
|||
<?php
|
||||
settings_fields('wpavatar_shortcodes');
|
||||
|
||||
$shortcode_size = get_option('wpavatar_shortcode_size', 96);
|
||||
$shortcode_class = get_option('wpavatar_shortcode_class', 'wpavatar');
|
||||
$shortcode_shape = get_option('wpavatar_shortcode_shape', 'square');
|
||||
// Get option values using wpavatar_get_option instead of get_option
|
||||
$shortcode_size = wpavatar_get_option('wpavatar_shortcode_size', 96);
|
||||
$shortcode_class = wpavatar_get_option('wpavatar_shortcode_class', 'wpavatar');
|
||||
$shortcode_shape = wpavatar_get_option('wpavatar_shortcode_shape', 'square');
|
||||
|
||||
// Determine if fields should be disabled in multisite
|
||||
$disabled_shortcode_size = (is_multisite() && $network_enabled && in_array('wpavatar_shortcode_size', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_shortcode_class = (is_multisite() && $network_enabled && in_array('wpavatar_shortcode_class', $network_controlled_options)) ? 'disabled' : '';
|
||||
$disabled_shortcode_shape = (is_multisite() && $network_enabled && in_array('wpavatar_shortcode_shape', $network_controlled_options)) ? 'disabled' : '';
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><?php _e('默认头像大小', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wpavatar_shortcode_size" value="<?php echo esc_attr($shortcode_size); ?>" min="16" max="512" class="small-text wpavatar-input">
|
||||
<input type="number" name="wpavatar_shortcode_size" value="<?php echo esc_attr($shortcode_size); ?>" min="16" max="512" class="small-text wpavatar-input" <?php echo $disabled_shortcode_size; ?>>
|
||||
<p class="description"><?php _e('简码默认头像大小(像素)', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php _e('默认CSS类名', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<input type="text" name="wpavatar_shortcode_class" value="<?php echo esc_attr($shortcode_class); ?>" class="regular-text wpavatar-input">
|
||||
<input type="text" name="wpavatar_shortcode_class" value="<?php echo esc_attr($shortcode_class); ?>" class="regular-text wpavatar-input" <?php echo $disabled_shortcode_class; ?>>
|
||||
<p class="description"><?php _e('简码生成的头像默认CSS类', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php _e('默认头像形状', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<select name="wpavatar_shortcode_shape" class="wpavatar-select">
|
||||
<select name="wpavatar_shortcode_shape" class="wpavatar-select" <?php echo $disabled_shortcode_shape; ?>>
|
||||
<option value="square" <?php selected($shortcode_shape, 'square'); ?>><?php _e('方形', 'wpavatar'); ?></option>
|
||||
<option value="rounded" <?php selected($shortcode_shape, 'rounded'); ?>><?php _e('圆角方形', 'wpavatar'); ?></option>
|
||||
<option value="circle" <?php selected($shortcode_shape, 'circle'); ?>><?php _e('圆形', 'wpavatar'); ?></option>
|
||||
|
@ -603,106 +762,23 @@ class Settings {
|
|||
font-size: 12px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.wpavatar-network-notice {
|
||||
margin: 0 0 20px;
|
||||
padding: 10px 12px;
|
||||
background: #f0f6fc;
|
||||
border-left: 4px solid #72aee6;
|
||||
}
|
||||
.wpavatar-network-notice .dashicons-lock {
|
||||
color: #72aee6;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.wpavatar-network-notice em {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
class Network {
|
||||
public static function init() {
|
||||
if (is_network_admin()) {
|
||||
add_action('network_admin_menu', [__CLASS__, 'add_network_menu']);
|
||||
add_action('network_admin_edit_wpavatar_network', [__CLASS__, 'save_network_settings']);
|
||||
}
|
||||
}
|
||||
|
||||
public static function add_network_menu() {
|
||||
add_submenu_page(
|
||||
'settings.php',
|
||||
__('WPAvatar网络设置', 'wpavatar'),
|
||||
__('WPAvatar', 'wpavatar'),
|
||||
'manage_network_options',
|
||||
'wpavatar-network',
|
||||
[__CLASS__, 'render_network_page']
|
||||
);
|
||||
}
|
||||
|
||||
public static function render_network_page() {
|
||||
?>
|
||||
<div class="wrap wpavatar-settings">
|
||||
<h1><?php esc_html_e('WPAvatar网络设置', 'wpavatar'); ?></h1>
|
||||
|
||||
<div id="wpavatar-network-status" class="notice" style="display:none; margin-top: 10px;"></div>
|
||||
|
||||
<div class="wpavatar-card">
|
||||
<h2><?php _e('网络范围设置', 'wpavatar'); ?></h2>
|
||||
<p class="wpavatar-section-desc"><?php _e('配置多站点网络的WPAvatar设置。', 'wpavatar'); ?></p>
|
||||
|
||||
<form method="post" action="edit.php?action=wpavatar_network" id="wpavatar-network-form">
|
||||
<?php wp_nonce_field('wpavatar_network_settings'); ?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><?php _e('启用网络范围设置', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<label class="wpavatar-switch">
|
||||
<input type="checkbox" name="wpavatar_network_enabled" value="1" <?php checked(get_site_option('wpavatar_network_enabled', 1)); ?>>
|
||||
<span class="wpavatar-slider"></span>
|
||||
<span class="wpavatar-switch-label"><?php _e('在所有站点启用WPAvatar', 'wpavatar'); ?></span>
|
||||
</label>
|
||||
<p class="description"><?php _e('启用后,WPAvatar将在网络中的所有站点上生效', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php _e('默认CDN类型', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<select name="wpavatar_network_cdn_type" class="wpavatar-select">
|
||||
<option value="cravatar_route" <?php selected(get_site_option('wpavatar_network_cdn_type', 'cravatar_route'), 'cravatar_route'); ?>><?php _e('Cravatar线路', 'wpavatar'); ?></option>
|
||||
<option value="third_party" <?php selected(get_site_option('wpavatar_network_cdn_type', 'cravatar_route'), 'third_party'); ?>><?php _e('第三方镜像', 'wpavatar'); ?></option>
|
||||
<option value="custom" <?php selected(get_site_option('wpavatar_network_cdn_type', 'cravatar_route'), 'custom'); ?>><?php _e('自定义CDN', 'wpavatar'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php _e('默认Cravatar线路', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<select name="wpavatar_network_cravatar_route" class="wpavatar-select">
|
||||
<option value="cravatar.com" <?php selected(get_site_option('wpavatar_network_cravatar_route', 'cravatar.com'), 'cravatar.com'); ?>><?php _e('默认线路 (cravatar.com)', 'wpavatar'); ?></option>
|
||||
<option value="cn.cravatar.com" <?php selected(get_site_option('wpavatar_network_cravatar_route', 'cravatar.com'), 'cn.cravatar.com'); ?>><?php _e('中国大陆 (cn.cravatar.com)', 'wpavatar'); ?></option>
|
||||
<option value="hk.cravatar.com" <?php selected(get_site_option('wpavatar_network_cravatar_route', 'cravatar.com'), 'hk.cravatar.com'); ?>><?php _e('香港 (hk.cravatar.com)', 'wpavatar'); ?></option>
|
||||
<option value="en.cravatar.com" <?php selected(get_site_option('wpavatar_network_cravatar_route', 'cravatar.com'), 'en.cravatar.com'); ?>><?php _e('国际 (en.cravatar.com)', 'wpavatar'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php _e('哈希方法', 'wpavatar'); ?></th>
|
||||
<td>
|
||||
<p class="description" style="color: #d63638;"><?php _e('注意:使用Cravatar服务时,哈希方法将强制使用MD5', 'wpavatar'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="wpavatar-submit-wrapper">
|
||||
<button type="submit" class="button button-primary"><?php _e('保存设置', 'wpavatar'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function save_network_settings() {
|
||||
check_admin_referer('wpavatar_network_settings');
|
||||
|
||||
update_site_option('wpavatar_network_enabled', isset($_POST['wpavatar_network_enabled']) ? 1 : 0);
|
||||
|
||||
if (isset($_POST['wpavatar_network_cdn_type'])) {
|
||||
update_site_option('wpavatar_network_cdn_type', sanitize_text_field($_POST['wpavatar_network_cdn_type']));
|
||||
}
|
||||
|
||||
if (isset($_POST['wpavatar_network_cravatar_route'])) {
|
||||
update_site_option('wpavatar_network_cravatar_route', sanitize_text_field($_POST['wpavatar_network_cravatar_route']));
|
||||
}
|
||||
|
||||
wp_redirect(add_query_arg(['page' => 'wpavatar-network', 'updated' => 'true'], network_admin_url('settings.php')));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
|
106
includes/compatibility.php
Normal file
106
includes/compatibility.php
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
/**
|
||||
* WPAvatar 兼容性修复
|
||||
*
|
||||
* 用于处理与 WP-China-Yes 插件的兼容性问题
|
||||
*/
|
||||
|
||||
namespace WPAvatar;
|
||||
|
||||
class Compatibility {
|
||||
/**
|
||||
* 初始化兼容性修复
|
||||
*/
|
||||
public static function init() {
|
||||
// 在所有插件加载后、主题初始化前运行
|
||||
add_action('after_setup_theme', [__CLASS__, 'handle_wp_china_yes_compatibility'], 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理与 WP-China-Yes 插件的兼容性
|
||||
*/
|
||||
public static function handle_wp_china_yes_compatibility() {
|
||||
// 检查 WP-China-Yes 插件是否激活
|
||||
if (self::is_wp_china_yes_active()) {
|
||||
// 移除 WP-China-Yes 的头像替换过滤器
|
||||
self::remove_wp_china_yes_filters();
|
||||
|
||||
// 重新初始化 WPAvatar 的 Cravatar 功能,使用更高的优先级
|
||||
self::reinitialize_wpavatar_filters();
|
||||
|
||||
// 可选:添加管理界面通知
|
||||
if (is_admin()) {
|
||||
add_action('admin_notices', [__CLASS__, 'admin_compatibility_notice']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 WP-China-Yes 插件是否激活
|
||||
*/
|
||||
private static function is_wp_china_yes_active() {
|
||||
return class_exists('WenPai\\ChinaYes\\Service\\Super') ||
|
||||
defined('CHINA_YES_VERSION') ||
|
||||
function_exists('WenPai\\ChinaYes\\get_settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除 WP-China-Yes 的头像替换过滤器
|
||||
*/
|
||||
private static function remove_wp_china_yes_filters() {
|
||||
// 找到可能的 Super 类实例
|
||||
global $wp_filter;
|
||||
|
||||
$filters_to_check = [
|
||||
'get_avatar_url',
|
||||
'um_user_avatar_url_filter',
|
||||
'bp_gravatar_url',
|
||||
'user_profile_picture_description',
|
||||
'avatar_defaults'
|
||||
];
|
||||
|
||||
foreach ($filters_to_check as $filter_name) {
|
||||
if (isset($wp_filter[$filter_name])) {
|
||||
foreach ($wp_filter[$filter_name]->callbacks as $priority => $callbacks) {
|
||||
foreach ($callbacks as $callback_key => $callback_data) {
|
||||
if (is_array($callback_data['function']) &&
|
||||
is_object($callback_data['function'][0]) &&
|
||||
get_class($callback_data['function'][0]) === 'WenPai\\ChinaYes\\Service\\Super') {
|
||||
|
||||
$method_name = $callback_data['function'][1];
|
||||
remove_filter($filter_name, [$callback_data['function'][0], $method_name], $priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新初始化 WPAvatar 的 Cravatar 过滤器,使用更高的优先级
|
||||
*/
|
||||
private static function reinitialize_wpavatar_filters() {
|
||||
if (wpavatar_get_option('wpavatar_enable_cravatar', true)) {
|
||||
// 使用高优先级再次添加过滤器
|
||||
add_filter('um_user_avatar_url_filter', ['\WPAvatar\Cravatar', 'replace_avatar_url'], 9999);
|
||||
add_filter('bp_gravatar_url', ['\WPAvatar\Cravatar', 'replace_avatar_url'], 9999);
|
||||
add_filter('user_profile_picture_description', ['\WPAvatar\Cravatar', 'modify_profile_picture_description'], 9999);
|
||||
|
||||
// 确保 get_avatar_url 过滤器的优先级高于其他插件
|
||||
remove_filter('get_avatar_url', ['\WPAvatar\Cravatar', 'get_avatar_url'], 999);
|
||||
add_filter('get_avatar_url', ['\WPAvatar\Cravatar', 'get_avatar_url'], 9999, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理界面兼容性通知
|
||||
*/
|
||||
public static function admin_compatibility_notice() {
|
||||
$screen = get_current_screen();
|
||||
if ($screen && $screen->id === 'settings_page_wpavatar-settings') {
|
||||
echo '<div class="notice notice-info is-dismissible">';
|
||||
echo '<p>检测到文派叶子(WPCY.COM)插件,WPAvatar 生态组件兼容性补丁已生效,确保文派头像设置优先。</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,12 +19,17 @@ class Cravatar {
|
|||
];
|
||||
|
||||
public static function init() {
|
||||
if (get_option('wpavatar_enable_cravatar', true)) {
|
||||
add_filter('get_avatar_url', [__CLASS__, 'replace_avatar_url'], 1);
|
||||
if (wpavatar_get_option('wpavatar_enable_cravatar', true)) {
|
||||
// 使用高优先级过滤器来预处理头像数据
|
||||
add_filter('pre_get_avatar_data', [__CLASS__, 'pre_get_avatar_data'], 1, 2);
|
||||
|
||||
// 直接过滤avatar_url,无论是否已经通过pre_get_avatar_data处理
|
||||
add_filter('get_avatar_url', [__CLASS__, 'get_avatar_url'], 999, 2);
|
||||
|
||||
// 其他过滤器
|
||||
add_filter('um_user_avatar_url_filter', [__CLASS__, 'replace_avatar_url'], 1);
|
||||
add_filter('bp_gravatar_url', [__CLASS__, 'replace_avatar_url'], 1);
|
||||
add_filter('user_profile_picture_description', [__CLASS__, 'modify_profile_picture_description'], 1);
|
||||
add_filter('pre_get_avatar_data', [__CLASS__, 'pre_get_avatar_data'], 9, 2);
|
||||
add_filter('get_avatar', [__CLASS__, 'add_seo_alt'], 10, 5);
|
||||
}
|
||||
}
|
||||
|
@ -74,12 +79,144 @@ class Cravatar {
|
|||
return '<a href="https://cravatar.com" target="_blank" rel="noopener">' . __('您可以在初认头像修改您的资料图片', 'wpavatar') . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* 预处理头像数据,根据配置决定是否强制使用MD5
|
||||
*/
|
||||
public static function pre_get_avatar_data($args, $id_or_email) {
|
||||
if (is_null($args)) {
|
||||
$args = [];
|
||||
}
|
||||
|
||||
$email = self::get_email_from_id_or_email($id_or_email);
|
||||
|
||||
if (empty($email)) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
// 检查是否为 Cravatar 线路,只有 Cravatar 线路才强制使用 MD5
|
||||
$cdn_type = wpavatar_get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
if ($cdn_type === 'cravatar_route') {
|
||||
// Cravatar 线路强制使用 MD5
|
||||
$args['hash_method'] = 'md5';
|
||||
|
||||
// 移除SHA256散列标记(如果存在)
|
||||
if (isset($args['hash']) && $args['hash'] === 'sha256') {
|
||||
unset($args['hash']);
|
||||
}
|
||||
} else {
|
||||
// 尊重用户选择的哈希方法
|
||||
$hash_method = wpavatar_get_option('wpavatar_hash_method', 'md5');
|
||||
$args['hash_method'] = $hash_method;
|
||||
}
|
||||
|
||||
// 确保我们有email_hash供后续使用,根据选择的哈希方法计算
|
||||
if ($args['hash_method'] === 'sha256' && function_exists('hash')) {
|
||||
$args['wpavatar_email_hash'] = hash('sha256', strtolower(trim($email)));
|
||||
} else {
|
||||
$args['wpavatar_email_hash'] = md5(strtolower(trim($email)));
|
||||
}
|
||||
|
||||
// 添加超时属性
|
||||
$timeout = wpavatar_get_option('wpavatar_timeout', 5);
|
||||
$args['extra_attr'] = isset($args['extra_attr']) ? $args['extra_attr'] : '';
|
||||
$args['extra_attr'] .= ' data-timeout="' . esc_attr($timeout) . '"';
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接替换头像URL,根据配置决定是否强制使用Cravatar和MD5哈希
|
||||
*/
|
||||
public static function get_avatar_url($url, $id_or_email) {
|
||||
// 如果地址已经是我们支持的域名,则直接返回
|
||||
$cdn_type = wpavatar_get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$cdn_domain = '';
|
||||
|
||||
if ($cdn_type === 'cravatar_route') {
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
} elseif ($cdn_type === 'third_party') {
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_third_party_mirror', 'weavatar.com');
|
||||
} elseif ($cdn_type === 'custom') {
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_custom_cdn', '');
|
||||
if (empty($cdn_domain)) {
|
||||
$cdn_domain = 'cravatar.com';
|
||||
}
|
||||
}
|
||||
|
||||
// 检查URL是否已经使用了支持的域名
|
||||
if (strpos($url, $cdn_domain) !== false) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// 获取用户设置的哈希方法
|
||||
$hash_method = wpavatar_get_option('wpavatar_hash_method', 'md5');
|
||||
|
||||
// 仅当使用Cravatar线路或者自定义CDN包含"cravatar"时,强制使用MD5
|
||||
$force_md5 = ($cdn_type === 'cravatar_route' ||
|
||||
($cdn_type === 'custom' && strpos(strtolower($cdn_domain), 'cravatar') !== false));
|
||||
|
||||
if ($force_md5) {
|
||||
// 对于Cravatar,删除hash=sha256参数
|
||||
$url = str_replace(['?hash=sha256', '&hash=sha256'], ['', ''], $url);
|
||||
}
|
||||
|
||||
// 从URL提取邮箱哈希
|
||||
$hash = '';
|
||||
|
||||
// 根据URL中是否包含SHA256或MD5哈希进行处理
|
||||
if (preg_match('/\/avatar\/([a-f0-9]{64})/', $url, $matches)) {
|
||||
// SHA256哈希
|
||||
if ($force_md5) {
|
||||
// 如果强制使用MD5,需要重新计算哈希
|
||||
$email = self::get_email_from_id_or_email($id_or_email);
|
||||
if (!empty($email)) {
|
||||
$hash = md5(strtolower(trim($email)));
|
||||
} else {
|
||||
// 如果无法获取邮箱,则使用默认头像
|
||||
return self::replace_avatar_url($url);
|
||||
}
|
||||
} else {
|
||||
// 尊重SHA256
|
||||
$hash = $matches[1];
|
||||
}
|
||||
} elseif (preg_match('/\/avatar\/([a-f0-9]{32})/', $url, $matches)) {
|
||||
// MD5哈希
|
||||
$hash = $matches[1];
|
||||
}
|
||||
|
||||
if (empty($hash)) {
|
||||
return self::replace_avatar_url($url);
|
||||
}
|
||||
|
||||
// 构建新的头像URL
|
||||
$new_url = 'https://' . $cdn_domain . '/avatar/' . $hash;
|
||||
|
||||
// 保留原始URL中的参数
|
||||
$query_params = [];
|
||||
$parsed_url = parse_url($url);
|
||||
if (isset($parsed_url['query'])) {
|
||||
parse_str($parsed_url['query'], $query_params);
|
||||
}
|
||||
|
||||
// 如果使用SHA256并且不是强制使用MD5的情况,添加哈希参数
|
||||
if ($hash_method === 'sha256' && !$force_md5 && strlen($hash) === 64) {
|
||||
$query_params['hash'] = 'sha256';
|
||||
}
|
||||
|
||||
// 构建完整URL
|
||||
if (!empty($query_params)) {
|
||||
$new_url .= '?' . http_build_query($query_params);
|
||||
}
|
||||
|
||||
return $new_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ID或邮箱获取邮箱地址
|
||||
*/
|
||||
public static function get_email_from_id_or_email($id_or_email) {
|
||||
$email = '';
|
||||
|
||||
if (is_numeric($id_or_email)) {
|
||||
$user = get_user_by('id', (int)$id_or_email);
|
||||
if ($user) {
|
||||
|
@ -90,89 +227,58 @@ class Cravatar {
|
|||
$email = $id_or_email;
|
||||
}
|
||||
} elseif (is_object($id_or_email)) {
|
||||
if (isset($id_or_email->user_id) && $id_or_email->user_id) {
|
||||
$user = get_user_by('id', $id_or_email->user_id);
|
||||
if ($id_or_email instanceof \WP_User) {
|
||||
$email = $id_or_email->user_email;
|
||||
} elseif ($id_or_email instanceof \WP_Post) {
|
||||
$user = get_user_by('id', (int)$id_or_email->post_author);
|
||||
if ($user) {
|
||||
$email = $user->user_email;
|
||||
}
|
||||
} elseif (isset($id_or_email->comment_author_email)) {
|
||||
} elseif ($id_or_email instanceof \WP_Comment) {
|
||||
if (!empty($id_or_email->user_id)) {
|
||||
$user = get_user_by('id', (int)$id_or_email->user_id);
|
||||
if ($user) {
|
||||
$email = $user->user_email;
|
||||
}
|
||||
} elseif (!empty($id_or_email->comment_author_email)) {
|
||||
$email = $id_or_email->comment_author_email;
|
||||
} elseif (isset($id_or_email->user_email)) {
|
||||
$email = $id_or_email->user_email;
|
||||
}
|
||||
} elseif (isset($id_or_email->comment_ID)) {
|
||||
$comment = get_comment($id_or_email->comment_ID);
|
||||
if ($comment) {
|
||||
if ($comment->user_id) {
|
||||
$user = get_user_by('id', (int)$comment->user_id);
|
||||
if ($user) {
|
||||
$email = $user->user_email;
|
||||
}
|
||||
|
||||
if (empty($email)) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
// 确定使用的哈希方法
|
||||
$cdn_type = get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$use_md5 = true;
|
||||
|
||||
// Cravatar只支持MD5,如果使用Cravatar相关服务,强制使用MD5
|
||||
if ($cdn_type !== 'cravatar_route') {
|
||||
// 检查第三方镜像或自定义CDN是否与Cravatar相关
|
||||
$third_party_mirror = get_option('wpavatar_third_party_mirror', '');
|
||||
$custom_cdn = get_option('wpavatar_custom_cdn', '');
|
||||
$is_cravatar_related = (
|
||||
strpos(strtolower($third_party_mirror), 'cravatar') !== false ||
|
||||
strpos(strtolower($custom_cdn), 'cravatar') !== false
|
||||
);
|
||||
|
||||
if (!$is_cravatar_related) {
|
||||
// 非Cravatar服务使用用户设置的哈希方法
|
||||
$hash_method = get_option('wpavatar_hash_method', 'sha256');
|
||||
$use_md5 = ($hash_method === 'md5');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查WordPress版本,决定是否支持SHA256
|
||||
$wp_version = get_bloginfo('version');
|
||||
$use_sha256_support = version_compare($wp_version, '6.8', '>=');
|
||||
|
||||
// 设置哈希方法
|
||||
if (!$use_md5 && $use_sha256_support) {
|
||||
$args['hash_method'] = 'sha256';
|
||||
$args['hash'] = 'sha256';
|
||||
} else {
|
||||
$args['hash_method'] = 'md5';
|
||||
|
||||
if (isset($args['hash']) && $args['hash'] === 'sha256') {
|
||||
unset($args['hash']);
|
||||
$email = $comment->comment_author_email;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算邮箱地址的哈希值
|
||||
if (!isset($args['wpavatar_email_hash'])) {
|
||||
if (!$use_md5) {
|
||||
$args['wpavatar_email_hash'] = hash('sha256', strtolower(trim($email)));
|
||||
} else {
|
||||
$args['wpavatar_email_hash'] = md5(strtolower(trim($email)));
|
||||
}
|
||||
}
|
||||
|
||||
// 设置超时属性
|
||||
$timeout = get_option('wpavatar_timeout', 5);
|
||||
$args['extra_attr'] = isset($args['extra_attr']) ? $args['extra_attr'] : '';
|
||||
$args['extra_attr'] .= ' data-timeout="' . esc_attr($timeout) . '"';
|
||||
|
||||
return $args;
|
||||
return $email;
|
||||
}
|
||||
|
||||
public static function replace_avatar_url($url) {
|
||||
// 遍历所有Gravatar域名,替换为Cravatar相关域名
|
||||
// 移除hash=sha256参数,因为Cravatar不支持
|
||||
if (strpos($url, 'hash=sha256') !== false) {
|
||||
$url = str_replace(['?hash=sha256', '&hash=sha256'], ['', ''], $url);
|
||||
}
|
||||
|
||||
// 更换Gravatar域名为Cravatar域名
|
||||
foreach (self::$gravatar_domains as $domain) {
|
||||
if (strpos($url, $domain) !== false) {
|
||||
$cdn_type = get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$cdn_type = wpavatar_get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$cdn_domain = '';
|
||||
|
||||
if ($cdn_type === 'cravatar_route') {
|
||||
$cdn_domain = get_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
} elseif ($cdn_type === 'third_party') {
|
||||
$cdn_domain = get_option('wpavatar_third_party_mirror', 'weavatar.com');
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_third_party_mirror', 'weavatar.com');
|
||||
} elseif ($cdn_type === 'custom') {
|
||||
$custom_cdn = get_option('wpavatar_custom_cdn', '');
|
||||
$custom_cdn = wpavatar_get_option('wpavatar_custom_cdn', '');
|
||||
if (!empty($custom_cdn)) {
|
||||
$cdn_domain = $custom_cdn;
|
||||
} else {
|
||||
|
@ -189,7 +295,7 @@ class Cravatar {
|
|||
|
||||
public static function add_seo_alt($avatar, $id_or_email, $size, $default, $alt) {
|
||||
// 添加SEO友好的alt属性
|
||||
$seo_alt = get_option('wpavatar_seo_alt');
|
||||
$seo_alt = wpavatar_get_option('wpavatar_seo_alt');
|
||||
if (!empty($seo_alt)) {
|
||||
$user = false;
|
||||
if (is_numeric($id_or_email)) {
|
||||
|
@ -211,8 +317,8 @@ class Cravatar {
|
|||
}
|
||||
|
||||
// 添加头像加载失败的备用显示
|
||||
if (get_option('wpavatar_fallback_mode', 1)) {
|
||||
$fallback_type = get_option('wpavatar_fallback_avatar', 'default');
|
||||
if (wpavatar_get_option('wpavatar_fallback_mode', 1)) {
|
||||
$fallback_type = wpavatar_get_option('wpavatar_fallback_avatar', 'default');
|
||||
$local_avatars = self::get_local_avatars();
|
||||
|
||||
if (isset($local_avatars[$fallback_type])) {
|
||||
|
@ -233,7 +339,7 @@ class Cache {
|
|||
add_action('init', [__CLASS__, 'setup_cache_dir']);
|
||||
add_action('init', [__CLASS__, 'schedule_purge']);
|
||||
|
||||
if (get_option('wpavatar_enable_cache', true)) {
|
||||
if (wpavatar_get_option('wpavatar_enable_cache', true)) {
|
||||
add_filter('get_avatar_url', [__CLASS__, 'prepare_cache_url'], 99, 2);
|
||||
add_filter('get_avatar', [__CLASS__, 'serve_cached_avatar'], 20, 5);
|
||||
}
|
||||
|
@ -245,12 +351,11 @@ class Cache {
|
|||
}
|
||||
|
||||
public static function setup_cache_dir() {
|
||||
$dir = get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$base_dir = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$base_dir = rtrim($base_dir, '/\\') . '/';
|
||||
|
||||
$dir = rtrim($dir, '/\\') . '/';
|
||||
|
||||
if (!file_exists($dir)) {
|
||||
if (!wp_mkdir_p($dir)) {
|
||||
if (!file_exists($base_dir)) {
|
||||
if (!wp_mkdir_p($base_dir)) {
|
||||
add_settings_error(
|
||||
'wpavatar_cache',
|
||||
'cache_dir_error',
|
||||
|
@ -261,7 +366,7 @@ class Cache {
|
|||
}
|
||||
}
|
||||
|
||||
if (!is_writable($dir)) {
|
||||
if (!is_writable($base_dir)) {
|
||||
add_settings_error(
|
||||
'wpavatar_cache',
|
||||
'cache_dir_writable',
|
||||
|
@ -271,12 +376,14 @@ class Cache {
|
|||
return false;
|
||||
}
|
||||
|
||||
$index_file = $dir . 'index.php';
|
||||
// Create index.php in base dir
|
||||
$index_file = $base_dir . 'index.php';
|
||||
if (!file_exists($index_file)) {
|
||||
@file_put_contents($index_file, '<?php // Silence is golden.');
|
||||
}
|
||||
|
||||
$htaccess_file = $dir . '.htaccess';
|
||||
// Create .htaccess in base dir
|
||||
$htaccess_file = $base_dir . '.htaccess';
|
||||
if (!file_exists($htaccess_file)) {
|
||||
$htaccess_content = "# Prevent directory listing\n";
|
||||
$htaccess_content .= "Options -Indexes\n";
|
||||
|
@ -288,11 +395,45 @@ class Cache {
|
|||
@file_put_contents($htaccess_file, $htaccess_content);
|
||||
}
|
||||
|
||||
// If multisite, create site-specific directory
|
||||
if (is_multisite()) {
|
||||
$blog_id = get_current_blog_id();
|
||||
$site_dir = $base_dir . 'site-' . $blog_id . '/';
|
||||
|
||||
if (!file_exists($site_dir)) {
|
||||
if (!wp_mkdir_p($site_dir)) {
|
||||
add_settings_error(
|
||||
'wpavatar_cache',
|
||||
'cache_dir_error',
|
||||
__('无法创建站点缓存目录,请检查权限', 'wpavatar'),
|
||||
'error'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_writable($site_dir)) {
|
||||
add_settings_error(
|
||||
'wpavatar_cache',
|
||||
'cache_dir_writable',
|
||||
__('站点缓存目录不可写,请检查权限', 'wpavatar'),
|
||||
'error'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create index.php in site dir
|
||||
$site_index_file = $site_dir . 'index.php';
|
||||
if (!file_exists($site_index_file)) {
|
||||
@file_put_contents($site_index_file, '<?php // Silence is golden.');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function prepare_cache_url($url, $id_or_email) {
|
||||
if (!get_option('wpavatar_enable_cache', true)) {
|
||||
if (!wpavatar_get_option('wpavatar_enable_cache', true)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
@ -307,7 +448,7 @@ class Cache {
|
|||
}
|
||||
|
||||
public static function serve_cached_avatar($avatar, $id_or_email, $size, $default, $alt) {
|
||||
if (!get_option('wpavatar_enable_cache', true)) {
|
||||
if (!wpavatar_get_option('wpavatar_enable_cache', true)) {
|
||||
return $avatar;
|
||||
}
|
||||
|
||||
|
@ -320,25 +461,24 @@ class Cache {
|
|||
|
||||
$is_avatar_url = false;
|
||||
|
||||
$cdn_type = get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$cdn_type = wpavatar_get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
if ($cdn_type === 'cravatar_route') {
|
||||
$cdn_domain = get_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
if (strpos($url, $cdn_domain) !== false) {
|
||||
$is_avatar_url = true;
|
||||
}
|
||||
} elseif ($cdn_type === 'third_party') {
|
||||
$cdn_domain = get_option('wpavatar_third_party_mirror', 'weavatar.com');
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_third_party_mirror', 'weavatar.com');
|
||||
if (strpos($url, $cdn_domain) !== false) {
|
||||
$is_avatar_url = true;
|
||||
}
|
||||
} elseif ($cdn_type === 'custom') {
|
||||
$cdn_domain = get_option('wpavatar_custom_cdn', '');
|
||||
$cdn_domain = wpavatar_get_option('wpavatar_custom_cdn', '');
|
||||
if (!empty($cdn_domain) && strpos($url, $cdn_domain) !== false) {
|
||||
$is_avatar_url = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否为Gravatar URL
|
||||
if (!$is_avatar_url) {
|
||||
foreach (Cravatar::$gravatar_domains as $domain) {
|
||||
if (strpos($url, $domain) !== false) {
|
||||
|
@ -355,7 +495,7 @@ class Cache {
|
|||
$hash = self::get_avatar_hash($id_or_email);
|
||||
$cache_file = self::get_cache_path($hash, $size);
|
||||
|
||||
$cache_expire = get_option('wpavatar_cache_expire', 7) * DAY_IN_SECONDS;
|
||||
$cache_expire = wpavatar_get_option('wpavatar_cache_expire', 7) * DAY_IN_SECONDS;
|
||||
if (file_exists($cache_file) && filemtime($cache_file) > (time() - $cache_expire)) {
|
||||
$cached_url = content_url(str_replace(WP_CONTENT_DIR, '', $cache_file));
|
||||
return str_replace($url, esc_url($cached_url), $avatar);
|
||||
|
@ -370,46 +510,51 @@ class Cache {
|
|||
}
|
||||
|
||||
public static function get_avatar_hash($id_or_email) {
|
||||
$email = '';
|
||||
|
||||
if (is_object($id_or_email)) {
|
||||
if (isset($id_or_email->comment_author_email)) {
|
||||
$email = $id_or_email->comment_author_email;
|
||||
} elseif (isset($id_or_email->user_email)) {
|
||||
$email = $id_or_email->user_email;
|
||||
}
|
||||
} elseif (is_numeric($id_or_email)) {
|
||||
$user = get_user_by('id', $id_or_email);
|
||||
$email = $user ? $user->user_email : '';
|
||||
} elseif (is_string($id_or_email) && is_email($id_or_email)) {
|
||||
$email = $id_or_email;
|
||||
}
|
||||
$email = Cravatar::get_email_from_id_or_email($id_or_email);
|
||||
|
||||
if (empty($email)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$cdn_type = get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$use_md5 = true;
|
||||
// 获取用户设置的哈希方法
|
||||
$cdn_type = wpavatar_get_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
$hash_method = wpavatar_get_option('wpavatar_hash_method', 'md5');
|
||||
|
||||
// 确定使用的哈希方法
|
||||
if ($cdn_type !== 'cravatar_route' &&
|
||||
strpos(get_option('wpavatar_third_party_mirror', ''), 'cravatar') === false &&
|
||||
strpos(get_option('wpavatar_custom_cdn', ''), 'cravatar') === false) {
|
||||
$hash_method = get_option('wpavatar_hash_method', 'md5');
|
||||
$use_md5 = ($hash_method === 'md5');
|
||||
// 检查是否需要强制使用MD5(针对Cravatar服务)
|
||||
$force_md5 = false;
|
||||
if ($cdn_type === 'cravatar_route') {
|
||||
$force_md5 = true;
|
||||
} elseif ($cdn_type === 'custom') {
|
||||
$custom_cdn = wpavatar_get_option('wpavatar_custom_cdn', '');
|
||||
if (strpos(strtolower($custom_cdn), 'cravatar') !== false) {
|
||||
$force_md5 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$use_md5) {
|
||||
// 根据设置和条件选择哈希方法
|
||||
if ($force_md5 || $hash_method === 'md5') {
|
||||
return md5(strtolower(trim($email)));
|
||||
} else {
|
||||
// 使用SHA256
|
||||
if (function_exists('hash')) {
|
||||
return hash('sha256', strtolower(trim($email)));
|
||||
} else {
|
||||
// 如果不支持hash函数,回退到MD5
|
||||
return md5(strtolower(trim($email)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_cache_path($hash, $size) {
|
||||
$dir = get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$dir = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$dir = trailingslashit($dir);
|
||||
|
||||
// Add site-specific directory if multisite
|
||||
if (is_multisite()) {
|
||||
$blog_id = get_current_blog_id();
|
||||
$dir = $dir . 'site-' . $blog_id . '/';
|
||||
}
|
||||
|
||||
wp_mkdir_p($dir);
|
||||
return $dir . "{$hash}-{$size}.jpg";
|
||||
}
|
||||
|
@ -428,7 +573,7 @@ class Cache {
|
|||
return false;
|
||||
}
|
||||
|
||||
$timeout = get_option('wpavatar_timeout', 5);
|
||||
$timeout = wpavatar_get_option('wpavatar_timeout', 5);
|
||||
|
||||
$response = wp_remote_get($url, [
|
||||
'timeout' => $timeout,
|
||||
|
@ -470,7 +615,7 @@ class Cache {
|
|||
}
|
||||
|
||||
public static function cache_comment_avatar($comment_id, $comment_approved) {
|
||||
if ($comment_approved !== 1 || !get_option('wpavatar_enable_cache', true)) {
|
||||
if ($comment_approved !== 1 || !wpavatar_get_option('wpavatar_enable_cache', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -480,7 +625,7 @@ class Cache {
|
|||
}
|
||||
|
||||
$email = $comment->comment_author_email;
|
||||
$size = get_option('wpavatar_shortcode_size', 96);
|
||||
$size = wpavatar_get_option('wpavatar_shortcode_size', 96);
|
||||
|
||||
$avatar_url = get_avatar_url($email, ['size' => $size]);
|
||||
|
||||
|
@ -493,14 +638,13 @@ class Cache {
|
|||
|
||||
self::cache_remote_avatar($avatar_url, $cache_file);
|
||||
|
||||
// 缓存2x尺寸的头像,用于高分辨率显示器
|
||||
$retina_url = get_avatar_url($email, ['size' => $size * 2]);
|
||||
$retina_cache_file = self::get_cache_path($hash, $size * 2);
|
||||
self::cache_remote_avatar($retina_url, $retina_cache_file);
|
||||
}
|
||||
|
||||
public static function cache_user_avatar($user_id) {
|
||||
if (!get_option('wpavatar_enable_cache', true)) {
|
||||
if (!wpavatar_get_option('wpavatar_enable_cache', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -510,7 +654,7 @@ class Cache {
|
|||
}
|
||||
|
||||
$email = $user->user_email;
|
||||
$size = get_option('wpavatar_shortcode_size', 96);
|
||||
$size = wpavatar_get_option('wpavatar_shortcode_size', 96);
|
||||
|
||||
$avatar_url = get_avatar_url($email, ['size' => $size]);
|
||||
|
||||
|
@ -523,32 +667,47 @@ class Cache {
|
|||
|
||||
self::cache_remote_avatar($avatar_url, $cache_file);
|
||||
|
||||
// 缓存2x尺寸的头像,用于高分辨率显示器
|
||||
$retina_url = get_avatar_url($email, ['size' => $size * 2]);
|
||||
$retina_cache_file = self::get_cache_path($hash, $size * 2);
|
||||
self::cache_remote_avatar($retina_url, $retina_cache_file);
|
||||
}
|
||||
|
||||
public static function purge_expired() {
|
||||
$dir = get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
if (!file_exists($dir) || !is_dir($dir)) {
|
||||
$base_dir = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
if (!file_exists($base_dir) || !is_dir($base_dir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$files = glob(trailingslashit($dir) . '*.jpg');
|
||||
if (!$files) {
|
||||
return;
|
||||
}
|
||||
|
||||
$expire_days = get_option('wpavatar_cache_expire', 7);
|
||||
$expire_days = wpavatar_get_option('wpavatar_cache_expire', 7);
|
||||
$expire_time = time() - ($expire_days * DAY_IN_SECONDS);
|
||||
|
||||
// If multisite, purge site-specific directory
|
||||
if (is_multisite()) {
|
||||
$blog_id = get_current_blog_id();
|
||||
$site_dir = trailingslashit($base_dir) . 'site-' . $blog_id . '/';
|
||||
|
||||
if (file_exists($site_dir) && is_dir($site_dir)) {
|
||||
$files = glob($site_dir . '*.jpg');
|
||||
if ($files) {
|
||||
foreach ($files as $file) {
|
||||
if (filemtime($file) < $expire_time) {
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For non-multisite, purge all files in the base directory
|
||||
$files = glob(trailingslashit($base_dir) . '*.jpg');
|
||||
if ($files) {
|
||||
foreach ($files as $file) {
|
||||
if (filemtime($file) < $expire_time) {
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function schedule_purge() {
|
||||
if (!wp_next_scheduled('wpavatar_purge_cache')) {
|
||||
|
@ -557,23 +716,48 @@ class Cache {
|
|||
}
|
||||
|
||||
public static function check_cache_status() {
|
||||
$dir = get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$base_dir = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
|
||||
// For multisite, check site-specific directory
|
||||
if (is_multisite()) {
|
||||
$blog_id = get_current_blog_id();
|
||||
$site_dir = trailingslashit($base_dir) . 'site-' . $blog_id;
|
||||
|
||||
$stats = [
|
||||
'path' => $dir,
|
||||
'exists' => file_exists($dir) && is_dir($dir),
|
||||
'writable' => is_writable($dir),
|
||||
'path' => $site_dir,
|
||||
'exists' => file_exists($site_dir) && is_dir($site_dir),
|
||||
'writable' => is_writable($site_dir),
|
||||
'file_count' => 0,
|
||||
'size' => 0
|
||||
];
|
||||
|
||||
if ($stats['exists']) {
|
||||
$files = glob(trailingslashit($dir) . '*.jpg');
|
||||
$files = glob(trailingslashit($site_dir) . '*.jpg');
|
||||
$stats['file_count'] = count($files ?: []);
|
||||
foreach ($files ?: [] as $file) {
|
||||
$stats['size'] += filesize($file);
|
||||
}
|
||||
$stats['size'] = size_format($stats['size']);
|
||||
}
|
||||
} else {
|
||||
// For single site
|
||||
$stats = [
|
||||
'path' => $base_dir,
|
||||
'exists' => file_exists($base_dir) && is_dir($base_dir),
|
||||
'writable' => is_writable($base_dir),
|
||||
'file_count' => 0,
|
||||
'size' => 0
|
||||
];
|
||||
|
||||
if ($stats['exists']) {
|
||||
$files = glob(trailingslashit($base_dir) . '*.jpg');
|
||||
$stats['file_count'] = count($files ?: []);
|
||||
foreach ($files ?: [] as $file) {
|
||||
$stats['size'] += filesize($file);
|
||||
}
|
||||
$stats['size'] = size_format($stats['size']);
|
||||
}
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
@ -587,6 +771,120 @@ class Cache {
|
|||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
public static function check_all_cache_status() {
|
||||
$base_dir = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
|
||||
$global_stats = [
|
||||
'path' => $base_dir,
|
||||
'exists' => file_exists($base_dir) && is_dir($base_dir),
|
||||
'writable' => is_writable($base_dir),
|
||||
'site_count' => 0,
|
||||
'total_files' => 0,
|
||||
'total_size' => 0
|
||||
];
|
||||
|
||||
$site_stats = [];
|
||||
|
||||
if ($global_stats['exists']) {
|
||||
// Find all site directories
|
||||
$site_dirs = glob(trailingslashit($base_dir) . 'site-*', GLOB_ONLYDIR);
|
||||
$global_stats['site_count'] = count($site_dirs ?: []);
|
||||
|
||||
// Check each site directory
|
||||
foreach ($site_dirs ?: [] as $site_dir) {
|
||||
$blog_id = intval(str_replace(trailingslashit($base_dir) . 'site-', '', $site_dir));
|
||||
if ($blog_id > 0) {
|
||||
$files = glob($site_dir . '/*.jpg');
|
||||
$file_count = count($files ?: []);
|
||||
$global_stats['total_files'] += $file_count;
|
||||
|
||||
$size = 0;
|
||||
foreach ($files ?: [] as $file) {
|
||||
$size += filesize($file);
|
||||
$global_stats['total_size'] += filesize($file);
|
||||
}
|
||||
|
||||
// Try to get blog name
|
||||
$blog_name = '';
|
||||
if (function_exists('get_blog_details')) {
|
||||
$blog_details = get_blog_details($blog_id);
|
||||
if ($blog_details) {
|
||||
$blog_name = $blog_details->blogname;
|
||||
}
|
||||
}
|
||||
|
||||
$site_stats[] = [
|
||||
'id' => $blog_id,
|
||||
'name' => $blog_name ?: sprintf(__('站点 #%d', 'wpavatar'), $blog_id),
|
||||
'files' => $file_count,
|
||||
'size' => size_format($size)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Also check for legacy non-site specific files
|
||||
$legacy_files = glob(trailingslashit($base_dir) . '*.jpg');
|
||||
$legacy_count = count($legacy_files ?: []);
|
||||
if ($legacy_count > 0) {
|
||||
$global_stats['total_files'] += $legacy_count;
|
||||
|
||||
$legacy_size = 0;
|
||||
foreach ($legacy_files ?: [] as $file) {
|
||||
$legacy_size += filesize($file);
|
||||
$global_stats['total_size'] += filesize($file);
|
||||
}
|
||||
|
||||
$site_stats[] = [
|
||||
'id' => 0,
|
||||
'name' => __('旧版缓存文件(非站点特定)', 'wpavatar'),
|
||||
'files' => $legacy_count,
|
||||
'size' => size_format($legacy_size)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Sort sites by file count (descending)
|
||||
usort($site_stats, function($a, $b) {
|
||||
return $b['files'] - $a['files'];
|
||||
});
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="network-cache-stats">
|
||||
<h4><?php _e('全局缓存统计', 'wpavatar'); ?></h4>
|
||||
<p><?php printf(__('缓存根目录: %s', 'wpavatar'), esc_html($global_stats['path'])); ?></p>
|
||||
<p><?php printf(__('目录存在: %s', 'wpavatar'), $global_stats['exists'] ? __('是', 'wpavatar') : __('否', 'wpavatar')); ?></p>
|
||||
<p><?php printf(__('目录可写: %s', 'wpavatar'), $global_stats['writable'] ? __('是', 'wpavatar') : __('否', 'wpavatar')); ?></p>
|
||||
<p><?php printf(__('站点缓存目录数: %d', 'wpavatar'), $global_stats['site_count']); ?></p>
|
||||
<p><?php printf(__('总缓存文件数: %d', 'wpavatar'), $global_stats['total_files']); ?></p>
|
||||
<p><?php printf(__('总缓存大小: %s', 'wpavatar'), size_format($global_stats['total_size'])); ?></p>
|
||||
|
||||
<?php if (!empty($site_stats)): ?>
|
||||
<h4><?php _e('站点缓存详情', 'wpavatar'); ?></h4>
|
||||
<table class="widefat striped" style="margin-top: 10px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('站点', 'wpavatar'); ?></th>
|
||||
<th><?php _e('文件数', 'wpavatar'); ?></th>
|
||||
<th><?php _e('大小', 'wpavatar'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($site_stats as $stat): ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($stat['name']); ?></td>
|
||||
<td><?php echo esc_html($stat['files']); ?></td>
|
||||
<td><?php echo esc_html($stat['size']); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
|
||||
class Shortcode {
|
||||
|
@ -597,9 +895,9 @@ class Shortcode {
|
|||
}
|
||||
|
||||
public static function render_avatar($atts) {
|
||||
$default_size = get_option('wpavatar_shortcode_size', 96);
|
||||
$default_class = get_option('wpavatar_shortcode_class', 'wpavatar');
|
||||
$default_shape = get_option('wpavatar_shortcode_shape', 'square');
|
||||
$default_size = wpavatar_get_option('wpavatar_shortcode_size', 96);
|
||||
$default_class = wpavatar_get_option('wpavatar_shortcode_class', 'wpavatar');
|
||||
$default_shape = wpavatar_get_option('wpavatar_shortcode_shape', 'square');
|
||||
|
||||
$atts = shortcode_atts([
|
||||
'size' => $default_size,
|
||||
|
|
1134
includes/multisite.php
Normal file
1134
includes/multisite.php
Normal file
File diff suppressed because it is too large
Load diff
281
wpavatar.php
281
wpavatar.php
|
@ -1,22 +1,24 @@
|
|||
<?php
|
||||
/**
|
||||
* Plugin Name: WPAvatar
|
||||
* Version: 1.6.3
|
||||
* Version: 1.8.1
|
||||
* Plugin URI: https://wpavatar.com/download
|
||||
* Description: Replace Gravatar with Cravatar, a perfect replacement of Gravatar in China.
|
||||
* Author: WPfanyi
|
||||
* Author URI: https://wpfanyi.com/
|
||||
* Text Domain: wpavatar
|
||||
* Domain Path: /languages
|
||||
* Network: true
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
define('WPAVATAR_VERSION', '1.6.3');
|
||||
define('WPAVATAR_VERSION', '1.8.0');
|
||||
define('WPAVATAR_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('WPAVATAR_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
define('WPAVATAR_CACHE_DIR', WP_CONTENT_DIR . '/uploads/cravatar');
|
||||
|
||||
// Create necessary plugin directories if they don't exist
|
||||
if (!file_exists(WPAVATAR_PLUGIN_DIR . 'assets')) {
|
||||
wp_mkdir_p(WPAVATAR_PLUGIN_DIR . 'assets');
|
||||
}
|
||||
|
@ -55,19 +57,31 @@ if (!file_exists(WPAVATAR_PLUGIN_DIR . 'includes')) {
|
|||
}
|
||||
}
|
||||
|
||||
// Include core files
|
||||
require_once WPAVATAR_PLUGIN_DIR . 'includes/core.php';
|
||||
require_once WPAVATAR_PLUGIN_DIR . 'includes/admin.php';
|
||||
require_once WPAVATAR_PLUGIN_DIR . 'includes/multisite.php';
|
||||
|
||||
// Register AJAX actions
|
||||
add_action('wp_ajax_wpavatar_purge_cache', 'wpavatar_purge_cache_ajax');
|
||||
function wpavatar_purge_cache_ajax() {
|
||||
check_ajax_referer('wpavatar_admin_nonce', 'nonce');
|
||||
|
||||
// Check user capability
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(__('权限不足', 'wpavatar'));
|
||||
return;
|
||||
}
|
||||
|
||||
$dir = get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
// Get cache directory path
|
||||
$dir = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
|
||||
// Add blog-specific directory if multisite
|
||||
if (is_multisite()) {
|
||||
$blog_id = get_current_blog_id();
|
||||
$dir = trailingslashit($dir) . 'site-' . $blog_id . '/';
|
||||
}
|
||||
|
||||
$dir = rtrim($dir, '/\\') . '/';
|
||||
|
||||
if (!file_exists($dir) || !is_dir($dir)) {
|
||||
|
@ -91,6 +105,60 @@ function wpavatar_purge_cache_ajax() {
|
|||
wp_send_json_success(sprintf(__('已清空 %d 个缓存文件', 'wpavatar'), $count));
|
||||
}
|
||||
|
||||
add_action('wp_ajax_wpavatar_purge_all_cache', 'wpavatar_purge_all_cache_ajax');
|
||||
function wpavatar_purge_all_cache_ajax() {
|
||||
check_ajax_referer('wpavatar_admin_nonce', 'nonce');
|
||||
|
||||
// Check user capability for network admin
|
||||
if (!current_user_can('manage_network_options')) {
|
||||
wp_send_json_error(__('权限不足', 'wpavatar'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get base cache directory path
|
||||
$base_dir = wpavatar_get_option('wpavatar_cache_path', WPAVATAR_CACHE_DIR);
|
||||
$base_dir = rtrim($base_dir, '/\\') . '/';
|
||||
|
||||
if (!file_exists($base_dir) || !is_dir($base_dir)) {
|
||||
wp_send_json_error(__('缓存目录不存在', 'wpavatar'));
|
||||
return;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
// Get all site cache directories
|
||||
$site_dirs = glob($base_dir . 'site-*', GLOB_ONLYDIR);
|
||||
|
||||
if ($site_dirs) {
|
||||
foreach ($site_dirs as $site_dir) {
|
||||
$files = glob($site_dir . '/*.jpg');
|
||||
if ($files) {
|
||||
foreach ($files as $file) {
|
||||
if (file_exists($file)) {
|
||||
if (@unlink($file)) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also check legacy non-site specific files
|
||||
$legacy_files = glob($base_dir . '*.jpg');
|
||||
if ($legacy_files) {
|
||||
foreach ($legacy_files as $file) {
|
||||
if (file_exists($file)) {
|
||||
if (@unlink($file)) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success(sprintf(__('已清空所有站点的 %d 个缓存文件', 'wpavatar'), $count));
|
||||
}
|
||||
|
||||
add_action('wp_ajax_wpavatar_check_cache', 'wpavatar_check_cache_ajax');
|
||||
function wpavatar_check_cache_ajax() {
|
||||
check_ajax_referer('wpavatar_admin_nonce', 'nonce');
|
||||
|
@ -104,9 +172,24 @@ function wpavatar_check_cache_ajax() {
|
|||
wp_send_json_success($result);
|
||||
}
|
||||
|
||||
add_action('wp_ajax_wpavatar_check_all_cache', 'wpavatar_check_all_cache_ajax');
|
||||
function wpavatar_check_all_cache_ajax() {
|
||||
check_ajax_referer('wpavatar_admin_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('manage_network_options')) {
|
||||
wp_send_json_error(__('权限不足', 'wpavatar'));
|
||||
return;
|
||||
}
|
||||
|
||||
$result = \WPAvatar\Cache::check_all_cache_status();
|
||||
wp_send_json_success($result);
|
||||
}
|
||||
|
||||
add_action('plugins_loaded', function () {
|
||||
// Load text domain for translations
|
||||
load_plugin_textdomain('wpavatar', false, dirname(plugin_basename(__FILE__)) . '/languages');
|
||||
|
||||
// Create default avatar if it doesn't exist
|
||||
$default_avatar = WPAVATAR_PLUGIN_DIR . 'assets/images/default-avatar.png';
|
||||
if (!file_exists($default_avatar)) {
|
||||
$placeholder = WPAVATAR_PLUGIN_DIR . 'assets/images/placeholder-avatar.png';
|
||||
|
@ -127,6 +210,7 @@ add_action('plugins_loaded', function () {
|
|||
}
|
||||
}
|
||||
|
||||
// Fetch Cravatar logo if it doesn't exist
|
||||
$cravatar_logo = WPAVATAR_PLUGIN_DIR . 'assets/images/cravatar-logo.png';
|
||||
if (!file_exists($cravatar_logo) && function_exists('file_get_contents')) {
|
||||
$logo_url = 'https://cn.cravatar.com/avatar/00000000000000000000000000000000?d=cravatar_logo';
|
||||
|
@ -137,25 +221,49 @@ add_action('plugins_loaded', function () {
|
|||
}
|
||||
}
|
||||
|
||||
// Initialize multisite network support first
|
||||
if (is_multisite()) {
|
||||
\WPAvatar\Network::init();
|
||||
}
|
||||
|
||||
// Initialize core components
|
||||
\WPAvatar\Core::init();
|
||||
\WPAvatar\Cravatar::init();
|
||||
\WPAvatar\Cache::init();
|
||||
\WPAvatar\Shortcode::init();
|
||||
|
||||
// Initialize admin settings (will be conditionally disabled in multisite if network managed)
|
||||
if (is_admin()) {
|
||||
\WPAvatar\Settings::init();
|
||||
// Check if we should initialize settings in site admin
|
||||
$should_init_settings = true;
|
||||
|
||||
if (is_multisite() && get_site_option('wpavatar_network_enforce', 0) && !is_network_admin()) {
|
||||
$should_init_settings = false;
|
||||
}
|
||||
|
||||
if ($should_init_settings) {
|
||||
\WPAvatar\Settings::init();
|
||||
}
|
||||
}
|
||||
|
||||
// Filter text to replace Gravatar references with Cravatar
|
||||
add_filter('gettext', 'wpavatar_replace_gravatar_text', 20, 3);
|
||||
add_filter('ngettext', 'wpavatar_replace_gravatar_text_plural', 20, 4);
|
||||
});
|
||||
|
||||
/**
|
||||
* Replace Gravatar text with Cravatar in translations
|
||||
*
|
||||
* @param string $translated_text Translated text
|
||||
* @param string $text Original text
|
||||
* @param string $domain Text domain
|
||||
* @return string Modified translated text
|
||||
*/
|
||||
function wpavatar_replace_gravatar_text($translated_text, $text, $domain) {
|
||||
if (!get_option('wpavatar_enable_cravatar', 1)) {
|
||||
// Get enable_cravatar setting
|
||||
$enable_cravatar = wpavatar_get_option('wpavatar_enable_cravatar', 1);
|
||||
|
||||
if (!$enable_cravatar) {
|
||||
return $translated_text;
|
||||
}
|
||||
|
||||
|
@ -179,8 +287,20 @@ function wpavatar_replace_gravatar_text($translated_text, $text, $domain) {
|
|||
return $translated_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace Gravatar text with Cravatar in plural translations
|
||||
*
|
||||
* @param string $translated_text Translated text
|
||||
* @param string $single Singular text
|
||||
* @param string $plural Plural text
|
||||
* @param int $number Number for plural form
|
||||
* @return string Modified translated text
|
||||
*/
|
||||
function wpavatar_replace_gravatar_text_plural($translated_text, $single, $plural, $number) {
|
||||
if (!get_option('wpavatar_enable_cravatar', 1)) {
|
||||
// Get enable_cravatar setting
|
||||
$enable_cravatar = wpavatar_get_option('wpavatar_enable_cravatar', 1);
|
||||
|
||||
if (!$enable_cravatar) {
|
||||
return $translated_text;
|
||||
}
|
||||
|
||||
|
@ -202,7 +322,39 @@ function wpavatar_replace_gravatar_text_plural($translated_text, $single, $plura
|
|||
return $translated_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the correct option based on multisite status
|
||||
*
|
||||
* @param string $option_name Option name
|
||||
* @param mixed $default Default value
|
||||
* @return mixed Option value
|
||||
*/
|
||||
function wpavatar_get_option($option_name, $default = false) {
|
||||
if (is_multisite()) {
|
||||
// Check if network settings are enabled
|
||||
if (get_site_option('wpavatar_network_enabled', 1)) {
|
||||
// Check if this option is controlled by network
|
||||
$network_controlled_options = get_site_option('wpavatar_network_controlled_options', array());
|
||||
|
||||
// Convert to array if it's a string (for backward compatibility)
|
||||
if (!is_array($network_controlled_options)) {
|
||||
$network_controlled_options = explode(',', $network_controlled_options);
|
||||
}
|
||||
|
||||
// If this option is controlled by network or network enforces all settings
|
||||
if (in_array($option_name, $network_controlled_options) || get_site_option('wpavatar_network_enforce', 0)) {
|
||||
return get_site_option($option_name, $default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default to site option
|
||||
return get_option($option_name, $default);
|
||||
}
|
||||
|
||||
// Register activation hook
|
||||
register_activation_hook(__FILE__, function() {
|
||||
// Set default options for single site
|
||||
add_option('wpavatar_enable_cravatar', 1);
|
||||
add_option('wpavatar_cdn_type', 'cravatar_route');
|
||||
add_option('wpavatar_cravatar_route', 'cravatar.com');
|
||||
|
@ -223,13 +375,16 @@ register_activation_hook(__FILE__, function() {
|
|||
add_option('wpavatar_shortcode_class', 'wpavatar');
|
||||
add_option('wpavatar_shortcode_shape', 'square');
|
||||
|
||||
// Create cache directory
|
||||
wp_mkdir_p(WPAVATAR_CACHE_DIR);
|
||||
|
||||
// Create index.php to prevent directory listing
|
||||
$index_file = rtrim(WPAVATAR_CACHE_DIR, '/\\') . '/index.php';
|
||||
if (!file_exists($index_file)) {
|
||||
@file_put_contents($index_file, '<?php // Silence is golden.');
|
||||
}
|
||||
|
||||
// Create .htaccess to configure cache
|
||||
$htaccess_file = rtrim(WPAVATAR_CACHE_DIR, '/\\') . '/.htaccess';
|
||||
if (!file_exists($htaccess_file)) {
|
||||
$htaccess_content = "# Prevent directory listing\n";
|
||||
|
@ -242,17 +397,127 @@ register_activation_hook(__FILE__, function() {
|
|||
@file_put_contents($htaccess_file, $htaccess_content);
|
||||
}
|
||||
|
||||
// Set default options for multisite
|
||||
if (is_multisite()) {
|
||||
// Network settings
|
||||
add_site_option('wpavatar_network_enabled', 1);
|
||||
add_site_option('wpavatar_network_cdn_type', 'cravatar_route');
|
||||
add_site_option('wpavatar_network_cravatar_route', 'cravatar.com');
|
||||
add_site_option('wpavatar_network_enforce', 0);
|
||||
|
||||
// Define default network controlled options
|
||||
$default_controlled = array(
|
||||
'wpavatar_enable_cravatar',
|
||||
'wpavatar_cdn_type',
|
||||
'wpavatar_cravatar_route',
|
||||
'wpavatar_third_party_mirror',
|
||||
'wpavatar_custom_cdn'
|
||||
);
|
||||
add_site_option('wpavatar_network_controlled_options', $default_controlled);
|
||||
|
||||
// Copy regular options to network options
|
||||
foreach ([
|
||||
'wpavatar_enable_cravatar',
|
||||
'wpavatar_cdn_type',
|
||||
'wpavatar_cravatar_route',
|
||||
'wpavatar_third_party_mirror',
|
||||
'wpavatar_custom_cdn',
|
||||
'wpavatar_hash_method',
|
||||
'wpavatar_timeout',
|
||||
'wpavatar_enable_cache',
|
||||
'wpavatar_cache_path',
|
||||
'wpavatar_cache_expire',
|
||||
'wpavatar_seo_alt',
|
||||
'wpavatar_fallback_mode',
|
||||
'wpavatar_fallback_avatar',
|
||||
'wpavatar_shortcode_size',
|
||||
'wpavatar_shortcode_class',
|
||||
'wpavatar_shortcode_shape'
|
||||
] as $option_name) {
|
||||
add_site_option($option_name, get_option($option_name));
|
||||
}
|
||||
|
||||
// If current site is not the main site, create site-specific cache dir
|
||||
if (!is_main_site()) {
|
||||
$blog_id = get_current_blog_id();
|
||||
$cache_dir = trailingslashit(WPAVATAR_CACHE_DIR) . 'site-' . $blog_id;
|
||||
wp_mkdir_p($cache_dir);
|
||||
|
||||
$index_file = $cache_dir . '/index.php';
|
||||
if (!file_exists($index_file)) {
|
||||
@file_put_contents($index_file, '<?php // Silence is golden.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule daily cache purge
|
||||
if (!wp_next_scheduled('wpavatar_purge_cache')) {
|
||||
wp_schedule_event(time(), 'daily', 'wpavatar_purge_cache');
|
||||
}
|
||||
});
|
||||
|
||||
// Register deactivation hook
|
||||
register_deactivation_hook(__FILE__, function() {
|
||||
// Clear scheduled events
|
||||
wp_clear_scheduled_hook('wpavatar_purge_cache');
|
||||
});
|
||||
|
||||
// 确保 WPAvatar 插件已激活
|
||||
add_action('plugins_loaded', function() {
|
||||
if (class_exists('WPAvatar\\Cravatar')) {
|
||||
// 添加兼容性过滤器,确保 WPAvatar 的优先级高于 WP-China-Yes
|
||||
add_action('after_setup_theme', function() {
|
||||
// 检查 WP-China-Yes 插件是否激活
|
||||
if (class_exists('WenPai\\ChinaYes\\Service\\Super') || defined('CHINA_YES_VERSION')) {
|
||||
// 移除 WP-China-Yes 的头像相关过滤器
|
||||
global $wp_filter;
|
||||
|
||||
$filters_to_check = [
|
||||
'get_avatar_url',
|
||||
'um_user_avatar_url_filter',
|
||||
'bp_gravatar_url',
|
||||
'user_profile_picture_description',
|
||||
'avatar_defaults'
|
||||
];
|
||||
|
||||
foreach ($filters_to_check as $filter_name) {
|
||||
if (isset($wp_filter[$filter_name])) {
|
||||
foreach ($wp_filter[$filter_name]->callbacks as $priority => $callbacks) {
|
||||
foreach ($callbacks as $callback_key => $callback_data) {
|
||||
if (is_array($callback_data['function']) &&
|
||||
is_object($callback_data['function'][0]) &&
|
||||
get_class($callback_data['function'][0]) === 'WenPai\\ChinaYes\\Service\\Super') {
|
||||
|
||||
$method_name = $callback_data['function'][1];
|
||||
remove_filter($filter_name, [$callback_data['function'][0], $method_name], $priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重新添加 WPAvatar 的过滤器,使用更高的优先级
|
||||
if (wpavatar_get_option('wpavatar_enable_cravatar', true)) {
|
||||
// 移除原有优先级的过滤器
|
||||
remove_filter('get_avatar_url', ['WPAvatar\\Cravatar', 'get_avatar_url'], 999);
|
||||
remove_filter('um_user_avatar_url_filter', ['WPAvatar\\Cravatar', 'replace_avatar_url'], 1);
|
||||
remove_filter('bp_gravatar_url', ['WPAvatar\\Cravatar', 'replace_avatar_url'], 1);
|
||||
|
||||
// 使用更高优先级重新添加
|
||||
add_filter('get_avatar_url', ['WPAvatar\\Cravatar', 'get_avatar_url'], 9999, 2);
|
||||
add_filter('um_user_avatar_url_filter', ['WPAvatar\\Cravatar', 'replace_avatar_url'], 9999);
|
||||
add_filter('bp_gravatar_url', ['WPAvatar\\Cravatar', 'replace_avatar_url'], 9999);
|
||||
add_filter('user_profile_picture_description', ['WPAvatar\\Cravatar', 'modify_profile_picture_description'], 9999);
|
||||
}
|
||||
|
||||
// 添加管理界面通知
|
||||
add_action('admin_notices', function() {
|
||||
$screen = get_current_screen();
|
||||
if ($screen && $screen->id === 'settings_page_wpavatar-settings') {
|
||||
echo '<div class="notice notice-info is-dismissible">';
|
||||
echo '<p>检测到文派叶子(WPCY.COM)插件,WPAvatar 生态组件兼容性补丁已生效,确保文派头像设置优先。</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue