My first vBulletin project was sometime early last year. The code base was horribly outdated and spammers had littered the board with tens of thousands of posts. I managed to clean out most of those and turn on the built-in CAPTCHA in about three hours. Ultimately we failed to keep the spammers out and vBulletin was replaced with another forum software.
Another customer has recently decided to power their forums with vBulletin. The newest release has a built-in CMS and some other novel features. The problem is that they guard their “trade secrets” jealously and you have to go through a review process in order to gain access to their forums. Since my customer ordered vBulletin himself, I gave up on trying to figure them out.
One of the requirements for this project was a custom theme, complete with several special links and featured articles. If you are not familiar with vBulletin, here is the default layout:

Their template system has the ability to search for specific items. None of the links (mouse over or view source) showed up like I expected them to, except for the “What’s New?” link and that appeared in a number of template elements. That should have been my first clue about this modification.
A grep through the code base turned up an XML file that seemed to contain defaults for the database. includex/xml/product-vbcms.xml holds a reference to “content.php” (the “Home” link):
free
content.php
Sure enough, it was stashed in the database:

Interestingly, they keep a copy of the original value as well. In this case I have not changed anything so it is a duplicate of the current value.
A search for “site_tab_url” in the template returned a hit in the “vbcms_navbar_link” element.

Isn’t that great? No color coding and we have to use their administrative interface to edit the templates because of its complexity. Copy and Paste are friends.
This is where things go from bad to worse. The template is built on true OO principles, so each element of the theme does exactly one thing. The portion above decides whether or not to hilight the “Home” link as selected. There are no other navigation links in this section, which means that another theme section should reference this—right?
Wrong. No other theme elements reference vbcms_navbar_link. Back to searching the codebase. The linux “grep” command found the next step:

That .= operator is a string concatenation for PHP. The code from this XML file is a plugin and gets stored in the database. It will be eval()‘d on page load by vBulletin. Yikes. Anyway, it looks like “vbcms_navbar_link” is tossed into the “navbar_start” variable and that one does appear in the template:

“navbar,” in turn, is directly referenced in a number of other template elements with the directive “{vb:raw navbar}.”
Whew, we have managed to trace a single link. For something as common as creating or modifying a theme, you would think that they could come up with a better way to manage the data. I’ve themed Drupal, Joomla and WordPress. The appearance of a website should not be this difficult.
Any thoughts?
Comments
Submitted by garrettw on
if you can attain a sufficient level of understanding of the system, maybe you could sell your vBulletin-theming services. especially since you enjoy doing it so much! haha.
Submitted by Chris on
I am seriously contemplating whether I should just smash all of this OO work. Other people will have to figure out what I’ve done further on down the road and they are not programmers.
To perpetuate the current state of the theme would be a form of job security.
Submitted by Carrie on
I only wish I understood more of it than I do.
Submitted by Chris on
You should become a programmer. Of kids. =D
Submitted by netwiz on
Did I understand you correctly in that you didn’t gain access to the vBulletin forums? Its hard for me to believe they wanted to make it this hard to change the “theme”...but I’m sure it’s possible.
Submitted by netwiz on
She could start with Scratch…it’s a “privilege” my kids get when they turn 7.
Submitted by Chris on
There is vbulletin.com and then the support community is based at vbulletin.org. I have my customer’s login credentials for vbulletin.com and his serial number. I could probably set up an account for him on the .org domain but something in me dislikes creating accounts for other people. The people who approve accounts on the .org check serial numbers and such before they approve the account.
The last time I tried to do something in a customer’s name, the tech on the phone asked me for the one piece of information that I did not have on the customer. With my luck at social engineering, I would get the account flagged.
I will admit that it is irrational but I don’t like pretending to be something I’m not.
Incidentally, the worst part of this whole process is that they use a plugin to modify variables for the theme. If they didn’t do that then this would be a decent setup. The way that the links are all separated and combined through eval()‘d code in the database is just silly.
Submitted by garrettw on
The fact that they’re using eval() at all seems silly.
Submitted by Chris on
There are a handful of instances where eval() is useful. I ran into one situation ~4 years ago but I forget why that was the best idea at the time.
eval() is a bad idea for two reasons. The first is that it almost always is based around input from an end user, which would be a security risk. At first glance, I do not see that vBulletin is doing this. The other reason is that you are executing code that has not been written with the care and thought that the rest of the code base has seen.
In this situation, I suspect that the code (and the theme) were placed into the database for upgradability. vBulletin does provide copious comments above each function but I have not dug through all of those (as evidenced by the OP). Nevertheless, the way that this is incorporated is almost evil.
Submitted by Chris on
This is how the vBulletin fanboys use eval():
Please pardon me for a few moments as I laugh uncontrollably…
Submitted by garrettw on
That eval() doesn’t seem necessary at all. Wouldn’t this code achieve the same thing?
Submitted by Chris on
No, your code would be safer… unless fetch_template() escapes quote marks.
Suppose that fetch_template(‘navbar’) returned ‘hello “world”!’. That would turn the first eval() into this:
Imagine the havoc…