Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Facebook Sign In with Google Sign In with OpenID Sign In with Twitter

In this Discussion

Show a display name instead of username

jspautschjspautsch Themester ✭✭
I'd like for users and their posts to be labeled with a display name (e.g. "Jon Smith") that's separate from the username they use to login (which is how our SSO works). I've searched around a bit, as I could've sworn I saw someone else ask as similar question, but I couldn't find anything, so I was wondering if anyone else had any ideas as to how best to go about doing this.

I'll be delving into myself in a couple days, but first I wanted to see what the community had to say. Also I'd really like to keep it confined to a plugin and thereby avoid modifying any of the core files, but I'm new to Vanilla development and am not sure if that will be possible for this particular feature.

Answers

  • LincolnLincoln Snapperhead vanilla
    This is very doable as a plugin. Let us know if you get stuck!

    Developer at Vanilla Forums, Inc. [GitHub, Twitter]

  • jspautschjspautsch Themester ✭✭
    Done! Definitely easier than I thought, although I did have to add an event trigger into the ActivityQuery() function in ActivityModel.

    For the rest, I made a plugin that did the following:
    1) Added another column to the User table called DisplayName
    2) Overrode the UserBuilder and UserAnchor functions to include DisplayName.
    3) Setup event handlers for AfterDiscussionSummaryQuery, BeforeGetID (discussion model), AfterCommentQuery, and AfterActivityQuery (which I had to add into the core code myself) to add select statements that mirrored the Name statements in each function, except replaced with DisplayName instead.

    This setup allowed me to change the link text to use display names, but left most of the links themselves intact (linking to usernames not display names). Mind you, even if the links to point to display names it doesn't seem to affect anything, seeing as the links really use User IDs.
  • jspautsch - are you going to make the plugin code available? I also need this feature for my users.
  • jspautschjspautsch Themester ✭✭
    Sure thing, I'll see if I can get that done tomorrow. It will require some manual changes in the core code, and I've only tested it with 2.0.18b4.

    I also don't have a way to set the display name, that's done separately in the code for my SSO login.
  • That would be fantastic. We're running on the release version but if it's reasonably stable I'm willing to upgrade to the beta if need be.

    We're using SSO too, so that's not a problem.
  • jspautschjspautsch Themester ✭✭
    Alright follow these steps and it SHOULD work. Let me know if it doesn't and what kind of errors you get. First, you need to make some modifications to the core code...

    Step 1: Make the following modifications...
    /applications/dashboard/models/class.usermodel.php

    FIND: $Join = GetValue('Join', $Options, array('Name', 'Email', 'Photo'));
    REPLACE WITH: $Join = GetValue('Join', $Options, array('Name', 'Email', 'Photo', 'DisplayName'));

    /applications/vanilla/models/class.commentmodel.php

    IN public function GetID
    FIND $this->CommentQuery(FALSE);
    REPLACE WITH $this->CommentQuery();

    IN public function GetIDData
    FIND $this->CommentQuery(FALSE);
    REPLACE WITH $this->CommentQuery();

    /applications/dashboard/models/class.activitymodel.php

    IN: public function ActivityQuery
    FIND: ->Join('User ru', 'a.RegardingUserID = ru.UserID', 'left');
    ADD AFTER: $this->FireEvent('AfterActivityQuery');

    /applications/conversations/models/class.conversationmodel.php

    IN: public function GetRecipients
    FIND: ->Select('uc.UserID, u.Name, uc.Deleted')
    REPLACE WITH: ->Select('uc.UserID, u.Name, u.DisplayName, uc.Deleted')
    See next comment for the plugin code...
  • jspautschjspautsch Themester ✭✭
    Step 3: Create a plugin, in this example it's called "DisplayNameplugin". I separated this code out from another plugin of mine, so I'm not sure if it works on its own, I think I pulled over every relevant modification.

    Note that this plugin overrides two methods: UserAnchor and UserBuilder. If you're using another plugin that also overrides these methods (like Gravatar), I'm pretty sure you'll need to modify them to include DisplayName as well.
    <?php if (!defined('APPLICATION')) exit();<br />// Define the plugin:
    $PluginInfo['DisplayNameplugin'] = array(
    'Description' => 'Plugin to implement support for display names',
    'Version' => '1.0',
    'Author' => "Jonathan Pautsch",
    'AuthorEmail' => 'jspautsch@gmail.com',
    'AuthorUrl' => 'http://vanillaforums.org/profile/32921/jspautsch'
    );

    class DisplayNameplugin extends Gdn_Plugin
    {
    public function Setup()
    {
    Gdn::Structure()
    ->Table('User')
    ->Column('DisplayName', 'text', NULL)
    ->Set();
    }

    public function CommentModel_AfterCommentQuery_Handler(&$Sender, $Args)
    {
    $Join = GetValue('Join', $Args);
    if ( $Join )
    {
    $Sender->SQL->Select('iu.DisplayName', '', 'InsertDisplayName')
    ->Select('uu.DisplayName', '', 'UpdateDisplayName');
    }
    }

    public function ActivityModel_AfterActivityQuery_Handler(&$Sender)
    {
    $Sender->SQL->Select('au.DisplayName', '', 'ActivityName')
    ->Select('ru.DisplayName', '', 'RegardingName')
    ->Select('au.DisplayName', '', 'ActivityDisplayName')
    ->Select('ru.DisplayName', '', 'RegardingDisplayName');
    }

    public function ConversationMessageModel_BeforeGet_Handler(&$Sender)
    {
    $Sender->SQL->Select('iu.DisplayName', '', 'InsertDisplayName');
    }
    }

    if (!function_exists('UserBuilder'))
    {
    //Override the default UserBuilder function
    function UserBuilder($Object, $UserPrefix = '')
    {
    $Object = (object)$Object;
    $User = new stdClass();
    $UserID = $UserPrefix.'UserID';
    $Name = $UserPrefix.'Name';
    $DisplayName = $UserPrefix.'DisplayName';
    $Photo = $UserPrefix.'Photo';
    $Gender = $UserPrefix.'Gender';
    $User->UserID = $Object->$UserID;
    $User->Name = $Object->$Name;
    $User->DisplayName = $Object->$DisplayName;
    $User->Photo = property_exists($Object, $Photo) ? $Object->$Photo : '';
    $User->Email = GetValue($UserPrefix.'Email', $Object, NULL);
    $User->Gender = property_exists($Object, $Gender) ? $Object->$Gender : NULL;
    return $User;
    }
    }

    if (!function_exists('UserAnchor'))
    {
    //Override the default UserAnchor function
    function UserAnchor($User, $CssClass = '', $Options = NULL)
    {
    static $NameUnique = NULL;
    if ($NameUnique === NULL)
    $NameUnique = C('Garden.Registration.NameUnique');

    $Px = $Options;
    $Name = GetValue($Px.'Name', $User, T('Unknown'));
    $DisplayName = GetValue($Px.'DisplayName', $User, T('Unknown'));
    $UserID = GetValue($Px.'UserID', $User, 0);

    if ($CssClass != '')
    $CssClass = ' class="'.$CssClass.'"';

    return ''.htmlspecialchars($DisplayName).'';
    }
    }

    ?>
  • jspautschjspautsch Themester ✭✭
    So once that's done you just need to modify the code you're using to sync your SSO users to update each user's display name. Mine, for example, uses SOAP requests to authenticate each user and the user's display name is included in the response, so I just have to load that into a variable and issue a simple database update.
    Gdn::SQL()->Update('User')
    ->Set('DisplayName', $newdisplayname)
    ->Where('UserID', $userid)
    ->Put();
  • jspautschjspautsch Themester ✭✭
    Hmmm looks like some of these functions have changed a lot in 2.0.18b4. I'll work on updating them, in the meantime it should work with b2.
  • Thanks heaps. I'm not likely to get to this today due to other commitments, but hopefully this week sometime I can suck down 2.0.18b4 and test your code changes. I'll let you know how it goes.
  • jspautschjspautsch Themester ✭✭
    Updated the instructions for 2.0.18b4.
Sign In or Register to comment.