Use country flag as user avatar based on comments IP address?

You need to hook into get_avatar() somewhere. There are plenty of options:

  • get_avatar() itself is pluggable, so you can just replace the function wholesale
  • but it assembles the <img> tag from, so it might be simpler to hook into get_avatar_url(), which itself is just a wrapper around get_avatar_data(), and leave get_avatar() to still build the HTML for you
  • and the obvious point to hook get_avatar_data is the pre_get_avatar_data hook:

    /**
     * Filters whether to retrieve the avatar URL early.
     *
     * Passing a non-null value in the 'url' member of the return array will
     * effectively short circuit get_avatar_data(), passing the value through
     * the {@see 'get_avatar_data'} filter and returning early.
     *
     * @since 4.2.0
     *
     * @param array $args        Arguments passed to get_avatar_data(), after processing.
     * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user ID, Gravatar MD5 hash,
     *                           user email, WP_User object, WP_Post object, or WP_Comment object.
     */
    $args = apply_filters( 'pre_get_avatar_data', $args, $id_or_email );
    

which is slightly complicated in that you need to process many different types of input, but you can borrow the code from just below that call to do that. In your filter handler you’ll need to work out which country the user, email or comment is from and then set $args['url'] to be the flag image you want to use.

However that’s not that simple in itself:

  • comments are probably the easy case, since you have the commenter’s IP address in the WP_Comment object; you can then look that up once and store it as comment meta, or use some other IP address lookup caching scheme; you don’t want to call your geolocation service for every comment on every page load
  • users, by ID or WP_User, are probably fine too: you’ll just need to store an IP address and country against the user at some point, and again you can store that in user meta
  • posts are fine, as you can look up the author user then proceed as above
  • but what to do with email addresses? You can try looking up a user and using that, and maybe try comments too if that doesn’t match, but you’ll want to do this once only if possible and cache the results, success or failure. Maybe a serialised dictionary in a transient? But that doesn’t feel a great solution.