这个只有部分能用,更新版本在下面
/**
* Local custom avatar system with SVG initials generator
* - Uses user's custom avatar if exists
* - Otherwise generates SVG avatar with random color + initials
*/
add_filter('pre_get_avatar', 'custom_svg_initials_avatar', 10, 3);
function custom_svg_initials_avatar($avatar, $id_or_email, $args) {
$user = false;
// Detect registered user
if (is_numeric($id_or_email)) {
$user = get_user_by('id', (int) $id_or_email);
} elseif (is_object($id_or_email) && !empty($id_or_email->user_id)) {
$user = get_user_by('id', (int) $id_or_email->user_id);
} elseif (is_string($id_or_email)) {
$user = get_user_by('email', $id_or_email);
}
/** --- 1. If user has custom uploaded avatar → use it --- */
if ($user) {
$custom = get_user_meta($user->ID, 'custom_avatar', true);
if (!empty($custom)) {
return build_avatar_img($custom, $args);
}
}
/** --- 2. Otherwise generate initials avatar --- */
$name = '';
if ($user) {
$name = $user->display_name;
} elseif (is_object($id_or_email) && !empty($id_or_email->comment_author)) {
$name = $id_or_email->comment_author;
} elseif (is_string($id_or_email)) {
$name = $id_or_email;
}
$initials = strtoupper(get_initials_from_name($name));
$size = isset($args['size']) ? (int) $args['size'] : 96;
// Deterministic random color based on name/email
$hash = md5($name);
$color = "#" . substr($hash, 0, 6);
// Generate SVG
$svg = create_svg_avatar($initials, $color, $size);
// Output SVG as data URI
$data_uri = 'data:image/svg+xml;base64,' . base64_encode($svg);
return build_avatar_img($data_uri, $args);
}
/**
* Create actual <img> tag for avatars
*/
function build_avatar_img($src, $args) {
$size = isset($args['size']) ? (int) $args['size'] : 96;
$alt = isset($args['alt']) ? esc_attr($args['alt']) : '';
$class = isset($args['class']) ? esc_attr($args['class']) : 'avatar';
return sprintf(
'<img alt="%s" src="%s" class="avatar %s photo" height="%d" width="%d" />',
$alt,
esc_url($src),
$class,
$size,
$size
);
}
/**
* Extract initials from name or email
*/
function get_initials_from_name($name) {
if (empty($name)) return '?';
// If name contains spaces → use first two initials
$parts = preg_split('/\s+/', trim($name));
if (count($parts) >= 2) {
return mb_substr($parts[0], 0, 1) . mb_substr($parts[1], 0, 1);
}
// Single name → use first letter
return mb_substr($name, 0, 1);
}
/**
* Generate the SVG code
*/
function create_svg_avatar($initials, $bg_color, $size) {
$font_size = $size * 0.4;
return '
<svg xmlns="http://www.w3.org/2000/svg" width="'.$size.'" height="'.$size.'">
<rect width="100%" height="100%" fill="'.$bg_color.'" />
<text x="50%" y="50%" font-size="'.$font_size.'"
fill="#ffffff" dy=".35em" text-anchor="middle"
font-family="Arial, sans-serif" font-weight="bold">
'.$initials.'
</text>
</svg>';
}
// Disable Gravatar (safe for custom avatars)
add_filter( 'pre_option_show_avatars', '__return_zero' );
add_filter( 'avatar_defaults', '__return_empty_array' );
// Prevent Gravatar URL generation
add_filter( 'get_avatar_data', function( $args ) {
// If your custom avatar returned a URL, skip blocking
if (strpos($args['url'], 'default-avatar.png') !== false || strpos($args['url'], 'custom_avatar') !== false) {
return $args;
}
// Otherwise block Gravatar fallback
$args['url'] = '';
return $args;
});
add_filter('get_avatar', 'custom_svg_avatar_for_comments', 10, 6);
function custom_svg_avatar_for_comments($avatar, $id_or_email, $size, $default, $alt, $args) {
// Force WordPress to use pre_get_avatar logic
$custom = apply_filters('pre_get_avatar', null, $id_or_email, $args);
// If pre_get_avatar returned our custom avatar → replace the default one
if (!empty($custom)) {
return $custom;
}
return $avatar;
}
更新版本
<?php
/**
* Local custom avatar system with SVG initials generator
* * Logic:
* 1. Hook into pre_get_avatar.
* 2. If we return an <img> tag string, WordPress stops there (disabling Gravatar naturally).
* 3. We detect if it's a registered user with a custom upload.
* 4. If not, we generate an SVG Data URI.
* 5. We bypass esc_url for Data URIs to prevent the src="" bug.
*/
add_filter('pre_get_avatar', 'custom_svg_initials_avatar', 10, 3);
function custom_svg_initials_avatar($avatar, $id_or_email, $args) {
$user = false;
$user_id = 0;
// 1. Normalize User Detection
if (is_numeric($id_or_email)) {
$user_id = (int) $id_or_email;
} elseif (is_string($id_or_email) && ($user = get_user_by('email', $id_or_email))) {
$user_id = $user->ID;
} elseif (is_object($id_or_email) && !empty($id_or_email->user_id)) {
$user_id = (int) $id_or_email->user_id;
}
// 2. Check for Custom Uploaded Image (Meta field: 'custom_avatar')
if ($user_id > 0) {
$custom_url = get_user_meta($user_id, 'custom_avatar', true);
if (!empty($custom_url)) {
return build_avatar_img($custom_url, $args);
}
}
// 3. Fallback: Generate SVG Initials
// Determine the name to display
$name = '';
if ($user_id > 0) {
$user_data = get_userdata($user_id);
$name = $user_data->display_name;
} elseif (is_object($id_or_email) && !empty($id_or_email->comment_author)) {
$name = $id_or_email->comment_author;
} else {
// Fallback for purely email inputs on comments
$name = is_string($id_or_email) ? $id_or_email : 'Visitor';
}
// Generate Initials & Color
$initials = strtoupper(get_initials_from_name($name));
$size = isset($args['size']) ? (int) $args['size'] : 96;
// Create a unique color based on the name string so it's consistent for the user
$hash = md5($name);
$color = '#' . substr($hash, 0, 6);
// Generate SVG HTML
$svg = create_svg_avatar($initials, $color, $size);
// Encode as Data URI
$data_uri = 'data:image/svg+xml;base64,' . base64_encode($svg);
return build_avatar_img($data_uri, $args);
}
/**
* Helper: Build the <img> tag safely
*/
function build_avatar_img($src, $args) {
$size = isset($args['size']) ? (int) $args['size'] : 96;
$alt = isset($args['alt']) ? $args['alt'] : '';
$class = isset($args['class']) ? $args['class'] : 'avatar';
// Sanitize classes
$class_safe = esc_attr($class . ' avatar-' . $size . ' photo');
// CRITICAL FIX:
// If it's a Data URI, esc_url() will strip it. We must use esc_attr() instead.
if (strpos($src, 'data:image') === 0) {
$src_safe = esc_attr($src);
} else {
$src_safe = esc_url($src);
}
return sprintf(
'<img alt="%s" src="%s" class="%s" height="%d" width="%d" loading="lazy" />',
esc_attr($alt),
$src_safe,
$class_safe,
$size,
$size
);
}
/**
* Helper: Extract Initials
*/
function get_initials_from_name($name) {
if (empty($name)) return '?';
// Strip special chars/numbers for cleaner initials
$clean_name = trim(preg_replace('/[0-9@\.]/', '', $name));
if (empty($clean_name)) $clean_name = $name; // Fallback if name was only numbers/emails
$parts = preg_split('/\s+/', $clean_name);
if (count($parts) >= 2) {
return mb_substr($parts[0], 0, 1) . mb_substr($parts[1], 0, 1);
}
return mb_substr($name, 0, 1);
}
/**
* Helper: Generate SVG Code
*/
function create_svg_avatar($initials, $bg_color, $size) {
// Dynamic font size relative to container
$font_size = round($size * 0.45);
return '
<svg xmlns="http://www.w3.org/2000/svg" width="'.$size.'" height="'.$size.'" viewBox="0 0 '.$size.' '.$size.'">
<rect width="100%" height="100%" fill="'.$bg_color.'" />
<text x="50%" y="50%" dy=".35em"
font-size="'.$font_size.'"
fill="#ffffff"
text-anchor="middle"
font-family="sans-serif, Arial"
font-weight="bold">
'.$initials.'
</text>
</svg>';
}
/**
* CLEANUP:
* We do NOT need to hook into 'pre_option_show_avatars' or 'get_avatar_data'.
* By returning a value in 'pre_get_avatar' above, we effectively short-circuit
* WordPress standard Gravatar logic.
*/
更新版本,添加了pre_get_avatar_data的钩子能直接用get_avatar_url获取到头像的url
<?php
/**
* User Avatar
* Version: 2.0
* Local custom avatar system with SVG initials generator
*/
// 1. Hook for the HTML <img> tag (Standard get_avatar calls)
add_filter('pre_get_avatar', 'custom_svg_avatar_html', 10, 3);
// 2. Hook for the raw URL string (get_avatar_url calls)
add_filter('pre_get_avatar_data', 'custom_svg_avatar_url_filter', 10, 2);
/**
* HOOK 1: Handle HTML output
* We keep this to ensure we use esc_attr() for Data URIs instead of esc_url()
*/
function custom_svg_avatar_html($avatar, $id_or_email, $args) {
// 1. Get the URL/Data URI from our central helper
$url = get_custom_avatar_uri($id_or_email, $args);
if (!$url) {
return $avatar; // Fallback to standard if nothing found
}
// 2. Build the tag safely (Your existing logic)
return build_avatar_img($url, $args);
}
/**
* HOOK 2: Handle URL output
* This allows get_avatar_url() to return your SVG Data URI or Custom Image URL
*/
function custom_svg_avatar_url_filter($args, $id_or_email) {
// Avoid infinite loops if needed, though usually safe here
$url = get_custom_avatar_uri($id_or_email, $args);
if ($url) {
$args['url'] = $url;
// Optimization: prevent WordPress from checking Gravatar since we found a local one
$args['found_avatar'] = true;
}
return $args;
}
/**
* CORE LOGIC: Determines the Avatar URI (Image URL or SVG Data URI)
* Returns string or false.
*/
function get_custom_avatar_uri($id_or_email, $args = []) {
$user_id = 0;
$user = false;
// 1. Normalize User Detection
if (is_numeric($id_or_email)) {
$user_id = (int) $id_or_email;
} elseif (is_string($id_or_email) && ($user = get_user_by('email', $id_or_email))) {
$user_id = $user->ID;
} elseif (is_object($id_or_email) && !empty($id_or_email->user_id)) {
$user_id = (int) $id_or_email->user_id;
}
// 2. Check for Custom Uploaded Image (Meta field: 'custom_avatar')
if ($user_id > 0) {
$custom_url = get_user_meta($user_id, 'custom_avatar', true);
if (!empty($custom_url)) {
return $custom_url;
}
}
// 3. Fallback: Generate SVG Initials
$name = '';
if ($user_id > 0) {
$user_data = get_userdata($user_id);
$name = $user_data->display_name;
} elseif (is_object($id_or_email) && !empty($id_or_email->comment_author)) {
$name = $id_or_email->comment_author;
} else {
$name = is_string($id_or_email) ? $id_or_email : 'Visitor';
}
// Generate Initials & Color
$initials = strtoupper(get_initials_from_name($name));
$size = isset($args['size']) ? (int) $args['size'] : 96;
// Consistent Color Hash
$hash = md5($name);
$color = '#' . substr($hash, 0, 6);
// Generate SVG HTML
$svg = create_svg_avatar($initials, $color, $size);
// Return Data URI
return 'data:image/svg+xml;base64,' . base64_encode($svg);
}
/**
* Helper: Build the <img> tag safely
*/
function build_avatar_img($src, $args) {
$size = isset($args['size']) ? (int) $args['size'] : 96;
$alt = isset($args['alt']) ? $args['alt'] : '';
$class = isset($args['class']) ? $args['class'] : 'avatar';
$class_safe = esc_attr($class . ' avatar-' . $size . ' photo');
// CRITICAL: Allow Data URIs by using esc_attr instead of esc_url for them
if (strpos($src, 'data:image') === 0) {
$src_safe = esc_attr($src);
} else {
$src_safe = esc_url($src);
}
return sprintf(
'<img alt="%s" src="%s" class="%s" height="%d" width="%d" loading="lazy" />',
esc_attr($alt),
$src_safe,
$class_safe,
$size,
$size
);
}
/**
* Helper: Extract Initials
*/
function get_initials_from_name($name) {
if (empty($name)) return '?';
$clean_name = trim(preg_replace('/[0-9@\.]/', '', $name));
if (empty($clean_name)) $clean_name = $name;
$parts = preg_split('/\s+/', $clean_name);
if (count($parts) >= 2) {
return mb_substr($parts[0], 0, 1) . mb_substr($parts[1], 0, 1);
}
return mb_substr($name, 0, 1);
}
/**
* Helper: Generate SVG Code
*/
function create_svg_avatar($initials, $bg_color, $size) {
$font_size = round($size * 0.45);
return '
<svg xmlns="http://www.w3.org/2000/svg" width="'.$size.'" height="'.$size.'" viewBox="0 0 '.$size.' '.$size.'">
<rect width="100%" height="100%" fill="'.$bg_color.'" />
<text x="50%" y="50%" dy=".35em"
font-size="'.$font_size.'"
fill="#ffffff"
text-anchor="middle"
font-family="sans-serif, Arial"
font-weight="bold">
'.$initials.'
</text>
</svg>';
}