php / wordpress · 2024 年 6 月 7 日

WordPress自定义用户头像

主题根目录新建 function_1.php(名字自己定),

然后在 functions.php 文件引入

functions.php内容

...
include( get_template_directory() . '/function_1.php' );
...

function_1.php内容

<?php
class Simple_Local_Avatars {
    private $user_id_being_edited;

    public function __construct() {
        add_filter( &#039;get_avatar&#039;, array( $this, &#039;get_avatar&#039; ), 10, 5 );

        add_action( &#039;admin_init&#039;, array( $this, &#039;admin_init&#039; ) );

        add_action( &#039;show_user_profile&#039;, array( $this, &#039;edit_user_profile&#039; ) );
        add_action( &#039;edit_user_profile&#039;, array( $this, &#039;edit_user_profile&#039; ) );

        add_action( &#039;personal_options_update&#039;, array( $this, &#039;edit_user_profile_update&#039; ) );
        add_action( &#039;edit_user_profile_update&#039;, array( $this, &#039;edit_user_profile_update&#039; ) );

        add_filter( &#039;avatar_defaults&#039;, array( $this, &#039;avatar_defaults&#039; ) );
    }

    public function get_avatar( $avatar = &#039;&#039;, $id_or_email, $size = 96, $default = &#039;&#039;, $alt = false ) {

        if ( is_numeric($id_or_email) )
            $user_id = (int) $id_or_email;
        elseif ( is_string( $id_or_email ) && ( $user = get_user_by( &#039;email&#039;, $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;

        if ( empty( $user_id ) )
            return $avatar;

        $local_avatars = get_user_meta( $user_id, &#039;simple_local_avatar&#039;, true );

        if ( empty( $local_avatars ) || empty( $local_avatars[&#039;full&#039;] ) )
            return $avatar;

        $size = (int) $size;

        if ( empty( $alt ) )
            $alt = get_the_author_meta( &#039;display_name&#039;, $user_id );

        // generate a new size
        if ( empty( $local_avatars[$size] ) ) {
            $upload_path = wp_upload_dir();
            $avatar_full_path = str_replace( $upload_path[&#039;baseurl&#039;], $upload_path[&#039;basedir&#039;], $local_avatars[&#039;full&#039;] );
            $image_sized = image_resize( $avatar_full_path, $size, $size, true );
            // deal with original being >= to original image (or lack of sizing ability)
            $local_avatars[$size] = is_wp_error($image_sized) ? $local_avatars[$size] = $local_avatars[&#039;full&#039;] : str_replace( $upload_path[&#039;basedir&#039;], $upload_path[&#039;baseurl&#039;], $image_sized );
            // save updated avatar sizes
            update_user_meta( $user_id, &#039;simple_local_avatar&#039;, $local_avatars );
        } elseif ( substr( $local_avatars[$size], 0, 4 ) != &#039;http&#039; ) {
            $local_avatars[$size] = home_url( $local_avatars[$size] );
        }

        $author_class = is_author( $user_id ) ? &#039; current-author&#039; : &#039;&#039; ;
        $avatar = "<img alt=&#039;" . esc_attr( $alt ) . "&#039; src=&#039;" . $local_avatars[$size] . "&#039; class=&#039;avatar avatar-{$size}{$author_class} photo&#039; height=&#039;{$size}&#039; width=&#039;{$size}&#039; />";

        return apply_filters( &#039;simple_local_avatar&#039;, $avatar );
    }

    public function admin_init() {
        //load_plugin_textdomain( &#039;simple-local-avatars&#039;, false, dirname( plugin_basename( __FILE__ ) ) . &#039;/localization/&#039; );

        register_setting( &#039;discussion&#039;, &#039;simple_local_avatars_caps&#039;, array( $this, &#039;sanitize_options&#039; ) );
        add_settings_field( &#039;simple-local-avatars-caps&#039;, __(&#039;上传头像权限&#039;,&#039;simple-local-avatars&#039;), array( $this, &#039;avatar_settings_field&#039; ), &#039;discussion&#039;, &#039;avatars&#039; );
    }

    public function sanitize_options( $input ) {
        $new_input[&#039;simple_local_avatars_caps&#039;] = empty( $input[&#039;simple_local_avatars_caps&#039;] ) ? 0 : 1;
        return $new_input;
    }

    public function avatar_settings_field( $args ) {
        $options = get_option(&#039;simple_local_avatars_caps&#039;);

        echo &#039;
            <label for="simple_local_avatars_caps">
                <input type="checkbox" name="simple_local_avatars_caps" id="simple_local_avatars_caps" value="1" &#039; . @checked( $options[&#039;simple_local_avatars_caps&#039;], 1, false ) . &#039; />
                &#039; . __(&#039;仅具有头像上传权限的用户具有设置本地头像权限(作者及更高等级角色)。&#039;,&#039;simple-local-avatars&#039;) . &#039;
            </label>
        &#039;;
    }

    public function edit_user_profile( $profileuser ) {
    ?>
    <h3><?php _e( &#039;头像&#039;,&#039;simple-local-avatars&#039; ); ?></h3>

    <table class="form-table">
        <tr>
            <th><label for="simple-local-avatar"><?php _e(&#039;上传头像&#039;,&#039;simple-local-avatars&#039;); ?></label></th>
            <td style="width: 50px;" valign="top">
                <?php echo get_avatar( $profileuser->ID ); ?>
            </td>
            <td>
            <?php
                $options = get_option(&#039;simple_local_avatars_caps&#039;);

                if ( empty($options[&#039;simple_local_avatars_caps&#039;]) || current_user_can(&#039;upload_files&#039;) ) {
                    do_action( &#039;simple_local_avatar_notices&#039; );
                    wp_nonce_field( &#039;simple_local_avatar_nonce&#039;, &#039;_simple_local_avatar_nonce&#039;, false );
            ?>
                    <input type="file" name="simple-local-avatar" id="simple-local-avatar" /><br />
            <?php
                    if ( empty( $profileuser->simple_local_avatar ) )
                        echo &#039;<span class="description">&#039; . __(&#039;尚未设置本地头像,请点击“浏览”按钮上传本地头像。&#039;,&#039;simple-local-avatars&#039;) . &#039;</span>&#039;;
                    else
                        echo &#039;
                            <input type="checkbox" name="simple-local-avatar-erase" value="1" /> &#039; . __(&#039;移除本地头像&#039;,&#039;simple-local-avatars&#039;) . &#039;<br />
                            <span class="description">&#039; . __(&#039;如需要修改本地头像,请重新上传新头像。如需要移除本地头像,请选中上方的“移除本地头像”复选框并更新个人资料即可。<br/>移除本地头像后,将恢复使用 Gravatar 头像。&#039;,&#039;simple-local-avatars&#039;) . &#039;</span>
                        &#039;;
                } else {
                    if ( empty( $profileuser->simple_local_avatar ) )
                        echo &#039;<span class="description">&#039; . __(&#039;尚未设置本地头像,请在 Gravatar.com 网站设置头像。&#039;,&#039;simple-local-avatars&#039;) . &#039;</span>&#039;;
                    else
                        echo &#039;<span class="description">&#039; . __(&#039;你没有头像上传权限,如需要修改本地头像,请联系站点管理员。&#039;,&#039;simple-local-avatars&#039;) . &#039;</span>&#039;;
                }
            ?>
            </td>
        </tr>
    </table>
    <script type="text/javascript">var form = document.getElementById(&#039;your-profile&#039;);form.encoding = &#039;multipart/form-data&#039;;form.setAttribute(&#039;enctype&#039;, &#039;multipart/form-data&#039;);</script>
    <?php
    }

    public function edit_user_profile_update( $user_id ) {
        if ( ! isset( $_POST[&#039;_simple_local_avatar_nonce&#039;] ) || ! wp_verify_nonce( $_POST[&#039;_simple_local_avatar_nonce&#039;], &#039;simple_local_avatar_nonce&#039; ) )            //security
            return;

        if ( ! empty( $_FILES[&#039;simple-local-avatar&#039;][&#039;name&#039;] ) ) {
            $mimes = array(
                &#039;jpg|jpeg|jpe&#039; => &#039;image/jpeg&#039;,
                &#039;gif&#039; => &#039;image/gif&#039;,
                &#039;png&#039; => &#039;image/png&#039;,
                &#039;bmp&#039; => &#039;image/bmp&#039;,
                &#039;tif|tiff&#039; => &#039;image/tiff&#039;
            );

            // front end (theme my profile etc) support
            if ( ! function_exists( &#039;wp_handle_upload&#039; ) )
                require_once( ABSPATH . &#039;wp-admin/includes/file.php&#039; );

            $this->avatar_delete( $user_id );   // delete old images if successful

            // need to be more secure since low privelege users can upload
            if ( strstr( $_FILES[&#039;simple-local-avatar&#039;][&#039;name&#039;], &#039;.php&#039; ) )
                wp_die(&#039;For security reasons, the extension ".php" cannot be in your file name.&#039;);

            $this->user_id_being_edited = $user_id; // make user_id known to unique_filename_callback function
            $avatar = wp_handle_upload( $_FILES[&#039;simple-local-avatar&#039;], array( &#039;mimes&#039; => $mimes, &#039;test_form&#039; => false, &#039;unique_filename_callback&#039; => array( $this, &#039;unique_filename_callback&#039; ) ) );

            if ( empty($avatar[&#039;file&#039;]) ) {     // handle failures
                switch ( $avatar[&#039;error&#039;] ) {
                    case &#039;File type does not meet security guidelines. Try another.&#039; :
                        add_action( &#039;user_profile_update_errors&#039;, create_function(&#039;$a&#039;,&#039;$a->add("avatar_error",__("请上传有效的图片文件。","simple-local-avatars"));&#039;) );
                        break;
                    default :
                        add_action( &#039;user_profile_update_errors&#039;, create_function(&#039;$a&#039;,&#039;$a->add("avatar_error","<strong>".__("上传头像过程中出现以下错误:","simple-local-avatars")."</strong> &#039; . esc_attr( $avatar[&#039;error&#039;] ) . &#039;");&#039;) );
                }

                return;
            }

            update_user_meta( $user_id, &#039;simple_local_avatar&#039;, array( &#039;full&#039; => $avatar[&#039;url&#039;] ) );     // save user information (overwriting old)
        } elseif ( ! empty( $_POST[&#039;simple-local-avatar-erase&#039;] ) ) {
            $this->avatar_delete( $user_id );
        }
    }

    /**
     * remove the custom get_avatar hook for the default avatar list output on options-discussion.php
     */
    public function avatar_defaults( $avatar_defaults ) {
        remove_action( &#039;get_avatar&#039;, array( $this, &#039;get_avatar&#039; ) );
        return $avatar_defaults;
    }

    /**
     * delete avatars based on user_id
     */
    public function avatar_delete( $user_id ) {
        $old_avatars = get_user_meta( $user_id, &#039;simple_local_avatar&#039;, true );
        $upload_path = wp_upload_dir();

        if ( is_array($old_avatars) ) {
            foreach ($old_avatars as $old_avatar ) {
                $old_avatar_path = str_replace( $upload_path[&#039;baseurl&#039;], $upload_path[&#039;basedir&#039;], $old_avatar );
                @unlink( $old_avatar_path );
            }
        }

        delete_user_meta( $user_id, &#039;simple_local_avatar&#039; );
    }

    public function unique_filename_callback( $dir, $name, $ext ) {
        $user = get_user_by( &#039;id&#039;, (int) $this->user_id_being_edited );
        $name = $base_name = sanitize_file_name( $user->user_login . &#039;_avatar&#039; );
        $number = 1;

        while ( file_exists( $dir . "/$name$ext" ) ) {
            $name = $base_name . &#039;_&#039; . $number;
            $number++;
        }

        return $name . $ext;
    }
}

$simple_local_avatars = new Simple_Local_Avatars;

/**
 * more efficient to call simple local avatar directly in theme and avoid gravatar setup
 *
 * @param int|string|object $id_or_email A user ID,  email address, or comment object
 * @param int $size Size of the avatar image
 * @param string $default URL to a default image to use if no avatar is available
 * @param string $alt Alternate text to use in image tag. Defaults to blank
 * @return string <img> tag for the user&#039;s avatar
 */
function get_simple_local_avatar( $id_or_email, $size = &#039;96&#039;, $default = &#039;&#039;, $alt = false ) {
    global $simple_local_avatars;
    $avatar = $simple_local_avatars->get_avatar( &#039;&#039;, $id_or_email, $size, $default, $alt );

    if ( empty ( $avatar ) )
        $avatar = get_avatar( $id_or_email, $size, $default, $alt );

    return $avatar;
}

[1]WordPress自定义用户头像