<?php

/**
 * Replace default WordPress avatars URL with BP avatars URL, if available.
 *
 * See 'get_avatar_url' filter description in wp-includes/pluggable.php.
 *
 * @param string            $url            The avatar path passed to 'get_avatar'.
 * @param int|string|object $id_or_email    A user ID, email address, or comment object.
 * @param array             $args           Arguments passed to get_avatar_data(), after processing.
 * @return string BP avatar URL, if found; else the original avatar URL.
 */
function bp_fetch_avatar_url_filter( $url, $id_or_email, $args ) {
    /**
      * Remove this filter to prevent infinite loop as
      * get_avatar itself calls get_avatar_url
      */
    remove_filter('get_avatar_url', __FUNCTION__, 11, 3);

    // get avatar HTML
    $avatar_html = call_user_func_array('get_avatar', array(
        $id_or_email,
        isset($args['size']) ? esc_attr($args['size']) : null,
        isset($args['default']) ? esc_attr($args['default']) : null,
        null,
        $args
    ));

    /**
      * Restore back the filter now that we got the avatar HTML
      */
    add_filter('get_avatar_url', __FUNCTION__, 11, 3);

    /** Search for image src attribute // regex might need improvement **/
    preg_match('/<img\s*(.*?) src=["\']?(.*?)["\']? (.*?)>/si', $avatar_html, $src);
    
    /** assign the image src as the avatar URL **/
    if ( !empty( $src[2] ) ) {
        $url = esc_url( $src[2] );
    }

    /** the new avatar URL, bp filtered **/
    return $url;
}
add_filter( 'get_avatar_url', 'bp_fetch_avatar_url_filter', 11, 3 );