2

I have been asked to do some work on a site where the old developer has written this function (create a variable that stores the users avatar into an img tag) into the functions.php:

add_filter('get_avatar', 'lb_acf_profile_avatar', 10, 5);
function lb_acf_profile_avatar($avatar, $id_or_email, $size, $default, $alt) {

    $user = '';
// Get user by id or email
    if (is_numeric($id_or_email)) {
        $id = (int) $id_or_email;
        $user = get_user_by('id', $id);
    } elseif (is_object($id_or_email)) {
        if (!empty($id_or_email->user_id)) {
            $id = (int) $id_or_email->user_id;
            $user = get_user_by('id', $id);
        }
    } else {
        $user = get_user_by('email', $id_or_email);
    }
    if (!$user) {
        return $avatar;
    }
// Get the user id
    $user_id = $user->ID;
    //$user_info = get_userdata($user_id)
    // Get the file id
    $avatar_url = $user->get('user_url'); //'https://dojo.nearsoft.com/wp-content/uploads/2017/02/Eric-Wroolie-per-template.jpg';
    if ($avatar_url == '') {
        return $avatar;
    }
    $avatar = '<img alt="' . $alt . '" src="' . $avatar_url . '" class="avatar avatar-' . $size . '" height="' . $size . '" width="' . $size . '"/>';
// Return our new avatar
    return $avatar;
}

I know the function works as the app he built uses the code to generate the avatar for each user. I just don't know how to use it and cannot reach out to him to help me utilise it.

My efforts so far have failed, using code that looks a little like this:

<?php lb_acf_profile_avatar() ?>
<?php if ($avatar != '') : ?>
    <div>Hellow World</div>
<?php endif; ?>

Where I have tried calling the function then assuming the returned variable (the avatar image) would be usable from that point. That doesn't appear to be the case.

The error message is 5 of these one for each argument:

Warning: Missing argument 5 for lb_acf_profile_avatar(), called in /home/materialshub/public_html/development/wp-content/themes/bolt/header.php on line 238 and defined in /home/materialshub/public_html/development/wp-content/themes/bolt/functions.php on line 663 

Is there a way to tailor this so I get the avatar_url without the img tag returned, but I need the original code to function as it should as it is also used in the app and is functioning correctly.

I don't have access to the app. Or the old developer. Any help you can provide is great. If you want further info just let me know.

I think I want a new function that gets the avatar_url like the function above but without any of the img tag. A simple url is all I need.

I need this to be dynamic as well so it works for all users automatically, generating the avatar_url. How can I pass the arguments in this manor?

I cannot just use the inbuilt get_avatar() WordPress function before we try go down that route as the app has made use of an empty field in the database 'user_url'.

I appreciate this is quite an annoying question, but I appreciate the kindness.

EDIT: I have tried reverting back to the get_avatar() function and that then returns this warning:

Warning: Missing argument 1 for get_avatar(), called in /home/materialshub/public_html/development/wp-content/themes/bolt/header.php on line 239 and defined in /home/materialshub/public_html/development/wp-includes/pluggable.php on line 2450

Thanks, Jason.

7
  • 1
    "I cannot just use the inbuilt get_avatar()" - I think you can? get_avatar just fills in missing arguments then calls the get_avatar filter, and your function is hooked into that filter. So if you call the inbuilt one it should call this code.
    – Rup
    Commented Mar 28, 2019 at 10:45
  • How can you tell it links to the basic wordpress function? - I will try to do it now and let you know if it fixes. I originally built it like that but then realised it didnt pull the image through that the user selected in the app. It would always be the basic gravatar avatar. Commented Mar 28, 2019 at 10:48
  • 1
    The add_filter('get_avatar' line at the top. Here's the built-in get_avatar - you can see that both return statements go through apply_filters( 'get_avatar' ...).
    – Rup
    Commented Mar 28, 2019 at 10:49
  • To use this function, you need write something like that: $my_avatar = apply_filter( 'get_avatar', $my_avatar, $user, /* other args */ );. "apply_filters" on Codex
    – nmr
    Commented Mar 28, 2019 at 10:50
  • @Rup - I think youre on to something here - thanks for identifying that. I have tried to call the get_avatar() and now I get the error I posted in my question... Commented Mar 28, 2019 at 10:53

2 Answers 2

3

As discussed in comments you actually just want the URL. Here's your code modified to be a get_avatar_url hook instead:

add_filter('get_avatar_url', 'lb_acf_profile_avatar_url', 10, 5);
function lb_acf_profile_avatar_url($url, $id_or_email, $args) {
    $user = '';
    // Get user by id or email
    if (is_numeric($id_or_email)) {
        $id = (int) $id_or_email;
        $user = get_user_by('id', $id);
    } elseif (is_object($id_or_email)) {
        if (!empty($id_or_email->user_id)) {
            $id = (int) $id_or_email->user_id;
            $user = get_user_by('id', $id);
        }
    } else {
        $user = get_user_by('email', $id_or_email);
    }
    if (!$user) {
        return $url;
    }

    $avatar_url = $user->get('user_url');
    if ($avatar_url == '') {
        return $url;
    }
    return $avatar_url;
}

Untested, sorry. It uses the same logic as the existing code to resolve the $id_or_email parameter into a user object: there's probably some room for improvement here e.g. since the $id_or_email might already be the user object, and I'm a little nervous about the empty string checks but that's what the existing (presumably working) code does.

You can then call WordPress's get_avatar_url with a user ID and it should return user_url where available. I'd expect get_avatar to still work too with just this filter.

1
  • This is brilliant. Thanks so much! Commented Mar 28, 2019 at 14:05
3

You're trying to call this custom function without any parameters:

lb_acf_profile_avatar()

But it's not meant to work like that. It's not a function that you should call. It's a filter callback and it has to get 5 parameters:

  • $avatar,
  • $id_or_email,
  • $size,
  • $default,
  • $alt

So yes - you will get errors if you won't pass them.

But, as I've already said, this custom function is a filter callback. It means, that whenever get_avatar function is called, the custom function will be run and it will modify the default behavior of get_avatar function. (It will change/filter its result)

This means that you should call default get_avatar function in your header.

You still have to pass some arguments to it. At least one of them:

  • $id_or_email

You can use it like so:

echo get_avatar( get_current_user_id() ); 

And you can pass size as second parameter.

5
  • 1
    I think you may have hit the nail on the head here pal! Beautifully worded too. Commented Mar 28, 2019 at 11:03
  • We are super close. You're correct in how it works and how to call it. However, I need to return just the url, I currently if echo'ing it out will get the full img tag. Are we able to cut just the url for the avatar out please? Commented Mar 28, 2019 at 11:09
  • This part won't be so easy... The custom function doesn't change the URL and it doesn't return the URL itself. So you would have to write your custom function that will do that. Commented Mar 28, 2019 at 11:20
  • I can get JS to do this. I would have just liked it to all be handled by php ideally Commented Mar 28, 2019 at 11:29
  • You could modify the existing code to be a get_avatar_data or get_avatar_url filter instead, and call get_avatar_url in PHP. (Just to be clear: this is more work than just changing the add_filter call.) Or just wrap a call to get_avatar_url with a little of your own code: all you're doing is fetching the user object and checking if it has a non-empty user_url property, and if it does using that instead of the default URL.
    – Rup
    Commented Mar 28, 2019 at 12:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.