1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Custom Field not available for all callback instances (PHP)

Discussion in 'XenForo Development Discussions' started by TylerHanavan, Sep 6, 2016.

  1. TylerHanavan

    TylerHanavan New Member

    I am developing an add-on for my Xenforo-enabled website that changes the user's avatar based on a custom field they input in the Preferences section of their profile.

    The custom field is "mcusername". If the user has inputted something in this field, their avatar image will be linked to "https://minotar.net/avatar/$mcusername" (with $mcusername replaced with the custom field) and if they do not have the custom field inputted, the avatar image will be linked to "https://minotar.net/avatar/Steve".

    User's without the custom field "mcusername" should display this image
    [​IMG]

    I was able to find some code on Xenforo and modify it to fit my needs

    I have a callback for init_dependencies with that calls the following function

    PHP:
        public static function init(XenForo_Dependencies_Abstract $dependencies, array $data)
        {
           
            
    XenForo_Template_Helper_Core::$helperCallbacks ['avatar'] = array('minecraftUsername_helpers''helperAvatarUrl');
            
    XenForo_Template_Helper_Core::$helperCallbacks ['avatarhtml'] = array('minecraftUsername_helpers''helperAvatarHtml');
           
        }
    The above method then uses the following two helper methods:

    PHP:
    public static function helperAvatarHtml(array $user$img, array $attributes = array(), $content '')
        {
          
            
    $size strtolower($attributes['size']);
          
            if(
    $size == 's') {
              
                
    $urlSize '/48';
              
            }
          
            if(
    $size == 'm') {
              
                
    $urlSize '/96';
              
            }
          
            
    $mcusername $user['customFields']['mcusername'];
          
            if(isset(
    $mcusername) && !empty($mcusername)) {
              
                
    $src "https://minotar.net/avatar/$mcusername";
              
            } else {
              
                
    $src "https://minotar.net/avatar/Steve";
          
            }

            
    $href XenForo_Template_Helper_Core::getUserHref($user$attributes);

            if (
    $img)
            {
                
    $username htmlspecialchars($user['username']);
                
    $dimension XenForo_Model_Avatar::getSizeFromCode($size);
              
                
    $image "<img src=\"{$src}$urlSize\" width=\"{$dimension}\" height=\"{$dimension}\" alt=\"{$username}\" />";
            }
            else
            {
                
    $text = (empty($attributes['text']) ? '' htmlspecialchars($attributes['text']));

                
    $image "<span class=\"img {$size}\" style=\"background-image: url('{$src}$urlSize')\">{$text}</span>";
            }

            
    $class = (empty($attributes['class']) ? '' ' ' htmlspecialchars($attributes['class']));

            unset(
    $attributes['user'], $attributes['size'], $attributes['img'], $attributes['text'], $attributes['class']);

            
    $attribs XenForo_Template_Helper_Core::getAttributes($attributes);

            if (
    $content !== '')
            {
                
    $content {$content}";
            }

            return 
    "<a{$href} class=\"avatar Av{$user['user_id']}{$size}{$class}\"{$attribs} data-avatarhtml=\"true\">{$image}{$content}</a>";
        }
      
      
        public static function 
    helperAvatarUrl($user$size$forceType null$canonical false)
        {
            if (!
    is_array($user))
            {
                
    $user = array();
            }

            if (
    $forceType)
            {
                switch (
    $forceType)
                {
                    case 
    'default':
                    case 
    'custom':
                        break;

                    default:
                        
    $forceType null;
                        break;
                }
            }
          
            
    $size strtolower($attributes['size']);
          
            if(
    $size == 's') {
              
                
    $urlSize '/48';
              
            }
          
            if(
    $size == 'm') {
              
                
    $urlSize '/96';
              
            }
          
            
    $mcusername $user['customFields']['mcusername'];
          
            if(isset(
    $mcusername) && !empty($mcusername)) {
              
                
    $src "https://minotar.net/avatar/$mcusername$urlSize";
              
            } else {
              
                
    $src "https://minotar.net/avatar/Steve$urlSize";
          
            }

            return 
    htmlspecialchars($src);
        }
    The above code does work for some parts of the site, but other parts don't appear to work.

    Working:
    [​IMG]
    [​IMG]
    [​IMG]
    Not Working:
    [​IMG]
    [​IMG]
    More things I will note, it seems to be that $user['customFields'] is not defined for the sections of images in the "Not Working" spoiler. Another pattern I've noticed is that all the images displaying my "default avatar" seem to be the small versions of the images. I'm not sure why.
     
  2. Liam W

    Liam W Well-Known Member

    The user array passed to the avatar helper is occasionally not the full array, and may not contain certain extra data such as custom fields.

    Liam
     
    TylerHanavan likes this.
  3. TylerHanavan

    TylerHanavan New Member

    Then given my situation, is there anything I can do?
     
  4. Liam W

    Liam W Well-Known Member

    In reality your only option is to fetch the custom fields in the avatar method.

    That will of course add queries to page views, however.

    Liam
     
  5. James

    James Well-Known Member

    I feel like the way to do this will be to actually request this information at registration then actually download and save the image as their avatar. This will drastically reduce queries as the info will be loaded as an avatar.

    The only caveat is you'll need to have it coded for you or code it yourself.
     
  6. TylerHanavan

    TylerHanavan New Member

    I've decided to opt for just querying the database. This is producing a new error issue.

    Here's my code:

    Code:
        if(!isset($mcusername) && empty($mcusername)) { //Custom field data was not passed
       
            $db = XenForo_Application::get('db');
            $mcusername = $db->fetchRow("SELECT field_value FROM xf_user_field_value WHERE (user_id=\"$id\" AND field_id=\"mcusername\")");
       
        }
    
    Whenever I do this, ALL avatars that the custom field data was not passed to end up being the same image regardless of the user_id.

    Nevermind. The issue was $mcusername was an Array instead of a string.

    Thanks for the help everyone.
     
    Last edited: Sep 6, 2016

Share This Page