Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
WordPress 2.5 Bridge: How to change Vanilla's username to display WordPress's display_name
This is helpful when creating users with WordPress and sharing the user table as discussion called WordPress 2.5 Bridge discusses.
The Problem
By Default, Vanilla displays the username of the user in all posts, as well as in the text at the top of the page that says "Signed in As X" (where X is your user name). This didn't work for us because our username convention consists of nothing but numbers (big company using LDAP, etc). When we want to see who made the post, numbers don't represent anything meaningful to tell us who posted the comment. So we had to figure out a way to get the full-name of the user to show up instead. I'm going to outline what I did here in hopes that the community will provide helpful suggestions on how I can turn this into an extension rather than a core code change. Because of the nature of the fields involved, I'm not sure if the Vanilla framework provides a way to write an extension that would accomplish this. I'm also researching the documentation as I go, so I'll post what I learn here if no one else does.
What you need to know to read this discussion
If you're not familiar with the WordPress 2.5 Bridge, or what is involved in getting that to work, then you'll be lost in this discussion. Please read that first. The document on how to integrate WordPress 2.5 with Vanilla 1.1.4 goes with it. Issues related to how to accomplish that integration are outside the scope of this discussion.
So, here we go:
How to change vanilla's FullName to display WordPress's display_name
I noted during my installation of WordPress/Vanilla/2.5 Bridge that Vanilla uses a virtual field called FullName repeatedly throughout the code. It seems that the Vanilla developers intend this field to be used in any case where the user's first and last name fields are intended for display. In some contexts, these two fields are not present because they are not selected when building the SQL query in library/People/People.Class.UserManager.php. I'll take that up with the Vanilla developers. But in the mean-time, you'll also need to know that if you're going to change the display name. This field is dynamically filled in by Vanilla by concatenating the FirstName and LastName fields with a space separator. This concatenation occurrs in library/People/People.Class.User.php on line 186.
However, if you're creating your account with WordPress, WordPress will likely use the display_name field, and completely disregard the FirstName and LastName fields. This is especially a problem, because from Vanilla's perspective, the display_name field doesn't exist either, so without modification we have zero access to any full-name type field with the Bridge setup in Vanilla.
The first thing I did, was find out where data is coming from, and how I can get Vanilla to at least be aware of the display_name field used by WordPress. I know, the Bridge integration document has an entry in the conf/database.php file for it, but that's a dead-end because the SQLBuilder queries used by Vanilla still need to explicitly ask for the field. The queries don't just get all fields. So I found out that there are 2 methods of the library/People/People.UserManager.php class that call information from the users table separately. The first is GetUserBuilder(), and the second is GetSessionDataById(). There is a call to the AddSelect() method in both functions where display_name needs to be added to the list of fields to select from the database. It doesn't matter where you add them in the list. I added mine as the first field. For example, here's the line I changed for GetSessionDataById():
You may also notice that I added FirstName and LastName to this field. Believe it or not, it wasn't there. I guess session data doesn't need them by default.
Next I changed GetUserBuilder() in a similar fashion, making sure display_name was included in the list.
Next, I found out where FullName is concatenated. As mentioned above, this happens inside library/People/People.User.php on line 186. So I commented out that line and added the necessary line above it like this:
Next, the templates need to know to use FullName instead of the default Name field, which contains the user login name. Fortunately, Vanilla makes theme extensions very easy. All we do is simply drop a folder with an arbitrary name inside the themes folder, and then copy the which ever theme files we want to modify into it directly from the themes folder itself. So, for example, if I want to change the place where it says "Signed In As X" where X is my username, I simply copy menu.php into my folder with an arbitrary name, and make modifications. The arbitrary name will show up as a new theme in your settings menu under Themes & Styles, and as soon as you turn the theme on, your modified theme pages will be used.
All in all, I had to modify menu.php, discussion.php and comments.php to change references to where the username rears its ugly head.
Then we're done.
I hope some of you might have some idea of how to turn this into an extension as opposed to a core code modification. I don't recommend this upgrade because it involves changing the core code. I would be much more comfortable with an extension.
Anyway, I look forward to reading your responses.
The Problem
By Default, Vanilla displays the username of the user in all posts, as well as in the text at the top of the page that says "Signed in As X" (where X is your user name). This didn't work for us because our username convention consists of nothing but numbers (big company using LDAP, etc). When we want to see who made the post, numbers don't represent anything meaningful to tell us who posted the comment. So we had to figure out a way to get the full-name of the user to show up instead. I'm going to outline what I did here in hopes that the community will provide helpful suggestions on how I can turn this into an extension rather than a core code change. Because of the nature of the fields involved, I'm not sure if the Vanilla framework provides a way to write an extension that would accomplish this. I'm also researching the documentation as I go, so I'll post what I learn here if no one else does.
What you need to know to read this discussion
If you're not familiar with the WordPress 2.5 Bridge, or what is involved in getting that to work, then you'll be lost in this discussion. Please read that first. The document on how to integrate WordPress 2.5 with Vanilla 1.1.4 goes with it. Issues related to how to accomplish that integration are outside the scope of this discussion.
So, here we go:
How to change vanilla's FullName to display WordPress's display_name
I noted during my installation of WordPress/Vanilla/2.5 Bridge that Vanilla uses a virtual field called FullName repeatedly throughout the code. It seems that the Vanilla developers intend this field to be used in any case where the user's first and last name fields are intended for display. In some contexts, these two fields are not present because they are not selected when building the SQL query in library/People/People.Class.UserManager.php. I'll take that up with the Vanilla developers. But in the mean-time, you'll also need to know that if you're going to change the display name. This field is dynamically filled in by Vanilla by concatenating the FirstName and LastName fields with a space separator. This concatenation occurrs in library/People/People.Class.User.php on line 186.
However, if you're creating your account with WordPress, WordPress will likely use the display_name field, and completely disregard the FirstName and LastName fields. This is especially a problem, because from Vanilla's perspective, the display_name field doesn't exist either, so without modification we have zero access to any full-name type field with the Bridge setup in Vanilla.
The first thing I did, was find out where data is coming from, and how I can get Vanilla to at least be aware of the display_name field used by WordPress. I know, the Bridge integration document has an entry in the conf/database.php file for it, but that's a dead-end because the SQLBuilder queries used by Vanilla still need to explicitly ask for the field. The queries don't just get all fields. So I found out that there are 2 methods of the library/People/People.UserManager.php class that call information from the users table separately. The first is GetUserBuilder(), and the second is GetSessionDataById(). There is a call to the AddSelect() method in both functions where display_name needs to be added to the list of fields to select from the database. It doesn't matter where you add them in the list. I added mine as the first field. For example, here's the line I changed for GetSessionDataById():
$s->AddSelect(array('display_name', 'Name', 'UserID', 'RoleID', 'StyleID', 'CustomStyle', 'UserBlocksCategories', 'DefaultFormatType', 'Preferences', 'SendNewApplicantNotifications', 'FirstName', 'LastName'), 'u');
You may also notice that I added FirstName and LastName to this field. Believe it or not, it wasn't there. I guess session data doesn't need them by default.
Next I changed GetUserBuilder() in a similar fashion, making sure display_name was included in the list.
Next, I found out where FullName is concatenated. As mentioned above, this happens inside library/People/People.User.php on line 186. So I commented out that line and added the necessary line above it like this:
$this->FullName = ForceString(@$DataSet['display_name'], '');
// $this->FullName = trim($this->FirstName . ' ' . $this->LastName);
// $this->FullName = trim($this->FirstName . ' ' . $this->LastName);
Next, the templates need to know to use FullName instead of the default Name field, which contains the user login name. Fortunately, Vanilla makes theme extensions very easy. All we do is simply drop a folder with an arbitrary name inside the themes folder, and then copy the which ever theme files we want to modify into it directly from the themes folder itself. So, for example, if I want to change the place where it says "Signed In As X" where X is my username, I simply copy menu.php into my folder with an arbitrary name, and make modifications. The arbitrary name will show up as a new theme in your settings menu under Themes & Styles, and as soon as you turn the theme on, your modified theme pages will be used.
All in all, I had to modify menu.php, discussion.php and comments.php to change references to where the username rears its ugly head.
Then we're done.
I hope some of you might have some idea of how to turn this into an extension as opposed to a core code modification. I don't recommend this upgrade because it involves changing the core code. I would be much more comfortable with an extension.
Anyway, I look forward to reading your responses.
1
Comments
What I'm really looking forward to is someone creating a combined WP/V package that people can just fire and forget - now that would be superb If only I had the knowledge (and more importantly, time)...
Thanks for the encouragement. In my studying the Vanilla Framework, it appears that what you want is quite possible. The Vanilla framework is surprisingly extensible and easy to understand. Today I learned how to extend objects using Vanilla's ObjectFactory->SetReference() method. This is important in this case because the 2 functions inside library/People/People.Class.UserManager.php, and the function in library/People/People.Class.User.php don't implement any calls to CallDelegate(), which is the preferred way to extend functions according to the Vanilla developer docs. If you're interested, the document can be found here.
Hopefully an extension that accomplishes this full-name feature will be forthcoming sooner than I thought. The trouble I'm running into currently is how to get my new extension to show up in the list of available extensions in my settings panel. I have created a new directory called WordPressFullName under the extensions directory, and created a new page called default.php. But it doesn't show up in the control panel under Extensions (If you have any ideas on this, please don't keep it a secret.)
If I create a comprehensive Extension that allows users to plug-and-play with WordPress later, I'll create a new discussion thread and try to post it as a formal extension.
<?php /* Extension Name: Your Extension Name Here Extension Url: The url to where this extension can be downloaded Description: A description of your extension Version: The current version of your extension Author: Your Name Author Url: Your personal url */ // replace your info up there // Insert code here ?>
Thank you. I eventually found this out on my own. All the information was there, but for some reason the extension I as copying from had a single space preceeding each meta parameter. Once I deleted the spaces, it all worked.
Today I get to continue working on this extension, so I'll probably be posting again later today with further news.
It turns out that Vanilla has 2 ways of allowing an extension access to override features within the existing framework:
1. Create a Delegate - Works on the basis of events being fired from hooks placed throughout the framework.
2. ObjectFactory::SetReference - Is the way Vanilla allows developers to override objects to add or redefine methods and properties.
As I stated early on in the code, there are no pre-existing delegate hooks in the places they need to be to make this extension work on the basis of calling delegates. There would need to be one inside each of the two UserManager functions mentioned in the first comment, and one inside the User function mentioned. So option 1 is out.
Further, option 2 has serious limitations, starting with this known limitation copied from the ObjectFactory document:
The biggest shortcoming of the ObjectFactory is that once a new reference has been set, it may break an extension if the reference is changed again.
It is also worthy of note that the ObjectFactory is instantiated in the constructor for the Context object. As a result of this, neither the context class, nor any of the classes instantiated in it’s constructor can be overridden by the ObjectFactory.
So after reading that the first time I thought, "No problem! People.Class.User and People.Class.UserManager aren't instantiated inside the Context class. I looked at the code myself! And for some applications, I was right. But what isn't stated there is that any object instantiated as a result of some other object being instantiated is also not extendable as far as the session object is concerned.
In this case, we are trying to change the line at the top of Vanilla to say, "Signed in as X", where X is your FullName, mapped from WordPress' display_name field. And for any object outside the session object, my new extension that uses ObjectFactory to override these methods will work. But ObjectFactory doesn't override anything until after Context is initiated. And the session data is acquired from within the Context init. So the User and UserManager objects aren't changed until after the session is started. In other words, when the session is starting, the User and UserManager objects haven't been overridden yet. So the framework provides no way to map FullName directly to display_name without changing core code.
It is also interesting to note that even creating a delegate hook inside functions in User and UserManager would not work, because the delegate listeners are not applied until after the session is started.
The Vanilla developers have 3 options in this case.
1. Change FullName into an actual database field that gets updated whenever the user's information is updated. This would allow me to place a field mapping inside $vanilla/conf/database.php that mapped the field directly to FullName. This would solve this particular problem, but would not be nearly as good as option number 2.
2. They could change the Context object to override objects with extension overrides before the session is started. This would be the best option. And theorhetically, it should be feasible to move the extension evaluation events to occur before Session->Start occurs. Further, this would probably not have any negative affects on any extension that has been written up to this point. It would not require a major version increment, and would not cause any headaches for developers who wrote extensions for the current version.
3. They could change the Delegate model by adding delegates to the end of each method in the framework. In conjunction with number 2, this would probably eliminate 99% of the limitations that extension writers are running into with needing to add Delegate hooks, or not having access to change the objects stored in the session.
In any case, there is always more than 1 way to skin a cat. So I'll be looking at how to access data from within the menu.php template file next. Perhaps I can simply get a direct data pull going there instead of depending on data acquired at session start.
Jon
I finally found a way to write the extension, and I didn't need to do anything with the session. Anyway, needless to say, I'm happy. I found that the menu control actually does have a PreRender delegate that allows me to overwrite the $Menu->Context->Session->User->FullName variable. After that, I updated the menu.php template in my own custom template subfolder to reference $this->Context->Session->User->FullName instead of $this->Context->Session->User->Name.
So in retrospect, I was getting stuck because I didn't have enough knowledge of which delegate I needed to use to get access to the variables that run the menu.php control. I can chalk that up to learning with little or no embarrassment, especially since this is my first Vanilla extension. I also hope others can use this thread to get better acquainted with how to write an extension in general. Do examine the code (links below) to get familiar with what I did.
The full code has been published as a combination of an Extension and a Theme. Please note that credit is due to JasonP for his NamedVanilla2 theme, which I modified to make these changes possible. Namely, he was manually concatenating FirstName and LastName. So I changed his references to use FullName. I also added menu.php to the theme, so I could get the username at the top to change and show FullName instead. I have called this new version of JasonP's theme NamedVanilla2_WordPress. The complete version of the WordPressFullName extension is also available. You can either get to them by clicking those links, or searching the community Add-ons for those names.