New PayPal/GoDaddy Scam?

As I was getting ready to enjoy a couple relaxing hours this evening on the 8th of July, 2019, a notification popped up via KDE Connect from my phone. Ordinarily, if it’s an email (which this was), I’d ignore it and go about my business. But something caught my eye: It said “invoice” somewhere in the text and also mentioned “GoDaddy.”

Puzzling, I thought, because I have all GoDaddy-related emails go to a separate folder, and they typically say nothing about an “invoice” in the message text. I quickly clicked on my email and, there, at the bottom of the window, sat a new message from PayPal with the title “Invoice from GoDaddy” with one of my domains in parenthesis at the end.

Before I continue, I’ll confide a small secret: I panicked. Oh, yes, I panicked. I don’t know why, because I use a password manager for everything, and 2FA where possible, but there’s always a small seed of doubt lurking in the darkness, desperately trying to convince you of the worst.

Escaping from my brief delirium, shortly after rationality finally kicked back in, I thought to myself “Ah-hah! It’s most likely this is a phishing email! This is the first one I’ve received in quite a while!”

I won’t deny that I felt the pangs of confidence–and a healthy sprinkling of arrogance–as I clicked through to examine the email headers in their entirety. Of course it was going to show up as an email that neither originated from PayPal nor from any reputable email service except, perhaps, from a hacked account being exploited for spam.

As I scrolled through the DKIM signatures and the SPF validation, not to mention the SMTP exchanges that clearly identified this as a legitimate PayPal emailing, reality set in. This wasn’t going to be quite so simple as an email scam. This was, in fact, a legitimate mailing from PayPal themselves.

Now, I’d be lying to you if I said that I was completely free of my panicked state. Nay, it returned, with somewhat more strength, to concern me even more deeply that perhaps my PayPal account was victim of an as-yet unknown attack or exploit. Quickly, or as fast as fumbling and vaguely worried hands could manage, I logged in to my PayPal account. There, at the bottom of the activity list, was an invoice–for $56.00 USD.

First, I’ll point out that this is just an invoice. It doesn’t mean that any money has exchanged hands. Yet. But it was still cause for alarm, because someone had decided it might be cute to exploit trust and the general imposition people feel toward settling outstanding debts for services rendered. To say this is a scummy, disgusting practice would be something of an understatement.

However, here’s where the scammer made a couple of critical mistakes (ignoring the more obvious ones–more on that momentarily). Of these, the most obvious was their account name on the requested transaction: It was written in Russian. Second, the string they used for “GoDaddy” did not match what GoDaddy actually uses for their billing statements. I don’t expect most people would consider the latter until it was too late, but I think the Russian name might’ve been something of a flashing neon sign that really ought to give pause for thought.

There were a couple of other clues that immediately shouted “SCAM!” (in capital letters), but they might not be helpful toward potential victims that have dozens of domains or are otherwise pressed for time and simply cannot consider these alternatives. The first of these was the timing. The domain they were targeting was indeed up for renewal, but they missed the expiration date by one day. I had already received an email from GoDaddy about the pending (automatic) renewal several days before and had it floating around in the back of my head. This invoice was therefore something of a surprise. As such, considering this background provided an immediate indication that something wasn’t quite right. The second was that all of my domains automatically renew. I don’t receive invoices from GoDaddy–only receipts. Oh, and finally, I don’t use PayPal to pay for my domains.

Admittedly, that last one was something of a dead ringer for potential scam (or a cracked account) material.

Before doing anything, I immediately started scouring the Internet for clues. Surprisingly, I couldn’t find anything about fake invoices from GoDaddy. I found some from buyers looking for shoes (of all things), and dozens of examples of phishing emails. This wasn’t a phishing email–this was a legitimate notification from PayPal informing me of an invoice that had been fraudulently sent. So, I did what any self-respecting (lol) person would do in a time of abject puzzlement: Take to Twitter.

It didn’t take me long to find someone else complaining to both the GoDaddy and PayPal Twitter accounts about receiving an invoice for $47 on a renewal that wasn’t up yet. I replied, suggesting that it might’ve been a scam, and that I received something similar.

Of course, I don’t know that the Twitter user in question was complaining about a fraudulent invoice. They didn’t provide enough information to deduce whether or not there was anything off about the invoice they received. But hey, why not offer it up as a possibility?

About 5 minutes later, I had a notification waiting for me on Twitter. It was PayPal’s support account asking for details via DM. I’m still a bit shocked in retrospect, to be completely honest, because I didn’t expect to hear from anyone much less one of the companies in question. I certainly can’t complain, either.

As expected, they asked for account information, location, and the nature of the issue. However, they also asked for screenshots of the offending invoice (couldn’t they see it?). After a brief back-and-forth, they strongly recommended I report it to their abuse department. I was quite pleased with the immediacy of their interest, but it remains to be seen what happens with the abuse report. (I’ll have to wait until later in the week for a reply, if any; I’m not holding out much hope.)

But the saga doesn’t end there.

I’ve heard mixed things about GoDaddy’s customer support. I’ve had a wide array of experiences myself but limited mostly to their sales department (they’re rabid up until the moment you turn off the whole “I’d like to be contacted for sales purposes,” which was apparently re-enabled at some point in my account’s history). I mused for a while about whether GoDaddy should know their name was being exploited for the gains of less savory individuals. I strongly considered against it, I won’t lie, but my conscience got the better of me.

I loaded up their web chat and almost immediately got in touch with one of their support representatives. She (I’ll assume it was a she, based on the feminine accents on the name; if not, for privacy, we’ll just roll with it) asked for my name and a description of the problem.

Well, this was awkward. I hadn’t really thought that far ahead, because the problem wasn’t really a problem with GoDaddy. It wasn’t a problem with my account. It wasn’t a problem with my domains, customer service, or any particular product offering. I told her as much. The problem was weird, I can’t deny that, but I felt someone needed to know. Even if it didn’t matter, at least I could sleep better at night knowing that I tried to do something about it. After all, I can’t be the only one targeted in this scam. What if someone else were to fall for it?

I explained the issue, and she quickly escalated the ticket through the account verification process, and then asked for some additional information. I explained a couple of times that the problem wasn’t with an account or domain per se so much as it appeared to be a new-ish scam, and that I mostly wanted to report it for my own satisfaction.

We went back and forth with a couple of relevant questions, and then she asked for a copy of the scam email. I was somewhat surprised, because I hadn’t exactly received a scam email from anyone. I asked if she meant the PayPal message; she said yes. So, off went the PayPal message (as an attachment to preserve headers), and I asked if she would like screenshots of the PayPal account pages with the invoice. Much to my surprise, she also wanted copies of those.

At this point, I’ll be honest. I don’t know what good any of this is going to do. I do know that the GoDaddy support representative was incredibly helpful, and she seemed genuinely interested in my concern (even going so far as to say “You are such a responsible person” to sate my worries). I was a bit taken back by her kindness, to say the least.

What surprised me with this whole ordeal was GoDaddy’s interest in the problem. They weren’t the ones who were dealing with invoices to third parties masquerading as someone else. They were merely the third party whose name was being exploited to commit fraud. It remains to be seen if PayPal expresses concern outside social media. I hope they do, but for now, it’s been awfully surprising to me that I received far more customer care from a company who couldn’t do anything about the problem. (I say “couldn’t,” even though technically they could, as the scammer was using their name and logos–i.e. trademarks–without permission.) Nevertheless, PayPal’s social team responded to me very quickly, so they at least get a few points for expediency.

All things considered, I feel the night ended on mostly positive terms. The initial shock of receiving a fraudulent invoice that wasn’t via a phishing attempt certainly took me by surprise, but in the end, the positive experiences with a random customer service representative probably half-way across the world expressing concern and compassion for others who could become victims of this scam more than made up for it. It’s a reminder that no matter how big a company is or how variable its reputation is viewed by customers on the receiving end, there are still humans who work for them. Sure, there are humans who typically see it as just another job. That’s normal.

However, no matter how rare it may be, it’s worth noting that there are those who see it as their duty to help. It may be woefully uncommon in our society today, but there are genuinely people who want to do the Right Thing™.

I don’t expect I’ll ever know if the representative who helped me managed to escalate the ticket and share the information about this scam to others who might be able to do something. Even if they could, there isn’t anything GoDaddy could do about this scam in the first place. This is clearly in PayPal’s sphere of influence, but perhaps if they know about it they can inform their customers when they inevitably receive the calls asking “Why am I receiving this invoice?”

No comments.

New Build: Problems and Solutions

This weekend, I put together a new mixed purpose desktop. This is my first AMD build, and so far I’m quite pleased with it. Sure, Intel offers greater performance in general, but truth be told, their processors are above and beyond what I was willing to spend. I built this desktop with a few things in mind: 1) Be reasonably future-proof, 2) have reasonable performance for the few games that I do actually play, 3) support hobbies that I delve into infrequently (I’m looking at you, Blender), and 4) handle the abuse I toss at it, including when I’m working. I really abuse my systems with work and with play, so whatever extra power I can get within a reasonable price range is going to improve my productivity immensely.

Of course, no build is without its teething problems. There’s always an adaptation period where new hardware simply doesn’t “feel right” for whatever reason. Maybe it’s not broken in, maybe there’s a tiny little issue that’s driving you absolutely insane, or maybe you simply haven’t gotten everything configured precisely to your specifications. Whatever the problem, if you’ve ever built your own computer for yourself, it’s to be expected. Sure, it’s one thing building systems for other people–you select components you know work well with each other and are unlikely to cause issues in the future. But that’s because the more problems they have, the more problems they’re going to give you when they ask for support.

But for yourself? Hah. That’s no fun. You’ve got to live sometime, man. Be adventurous. Buy enthusiast hardware. Select something without checking reviews, first. Be reckless.

Actually, I’m kidding. Never do any of these things unless you want to be sorely disappointed. Always, always, always research and review your hardware purchases before making them. But be mindful that no matter how careful you are in selecting your parts, you’re going to run into issues. It’s just the nature of the beast. There will always be some little issue that, once it hits, you’ll be thinking to yourself “Man, I wish I had Googled for X, then I would have known this was going to be a problem.”

Don’t fret. It happens. Just persevere, and you’ll fix it sooner or later. Take my most recent experience to heart, and keep in mind that I’ve built my fair share of systems over the years, although I’ve never made a switch between major component providers (e.g. Intel to AMD) before.

Here are the problems I ran into:

  • My hard disks would click between 5-6 times during shutdown before finally powering off. Furthermore, my hard disks would power down (shut off) every single time I restarted or rebooted the system. Obnoxious.
  • The Windows 7 SP1 installation failed every single attempt with the erro 0x800f0a12. The solution was about as inane as could be expected with a Microsoft product.
  • Google Chrome exhibited some inexplicable weirdness that I’ve never encountered before. Every time I searched something on Google, the links wouldn’t switch to their visited style and were a different shade of blue than normal.
  • Finally, hibernate/sleep/suspend (whichever you prefer) simply wouldn’t work.

TL;DR version of the solutions (spoilers, if you want to read the background stories!):

  • Disable AHCI support in your BIOS to resolve unexpected HDD power downs and clicking during shutdown.
  • When installing Windows 7 SP1, unplug all other hard disks in your system if you have multiple, bootable disks. If you have multiple bootable partitions, set the Windows partition as active using a tool such as fdisk.
  • Weirdness in Google Chrome can often be resolved by deleting cookies.
  • Gigabyte boards have problems with sleep mode. If fiddling with the power management mode of individual devices doesn’t work and you’re at your wit’s end, try changing the setting for hybrid sleep under advanced power management settings from Windows’ power management. It might just fix the problem.

Note: These problems aren’t specific to my board, but it is the first time I’ve encountered anything of the sort.

If you have the attention span of a fly, you’re finished. You won’t find anything else of any use in this post. For the rest of you who enjoy reading and appreciate a good story, you may continue. Hopefully this will be of some entertainment to you.

The System

The source of two of these problems is the motherboard I purchased. Rather, I should say that the source of two of these problems was operator error and how I had configured the motherboard. I purchased a Gigabyte GA-870A-UD3 for my build and promptly discovered that I was not alone–particularly with regards to the sleep problem. There’s an assortment of other hardware in this build, both new and old, that I brought over from my previous desktop–my keyboard, mouse, and a soundcard (I like the HT|Omega’s environments better than those that ship with the Realtek chip). The other items aren’t relevant. I know, because I swapped and removed just about every component I could in pursuit of my solutions.

Let’s start with the hard disks.

Hard Disks: Mysterious Clicking

The mysterious clicking of my hard disks on the Gigabyte board was mostly more of a nuisance than a concern. I’ve had enough drives die from the Click of Death to know from experience that this was different. More importantly, booting to Ubuntu cleared the problem. Whenever I’d shut the system down from Ubuntu, the drives would emit the same single click they normally would when parking and powering off on my old system. Rebooting wouldn’t power the disks down, either, except when I would restart the system from Windows. Clearly, Windows was the problem, but why?

After a few hours of fruitlessly searching for an answer, I finally stumbled upon this post. Someone else with a similar problem was experiencing unusual clicks on shut down with AHCI enabled. Incidentally, I had enabled AHCI support prior to testing this system out. What had I to lose by disabling it other than a few minutes?

Thus, I restarted the system (and cringed when the disks powered down again), entered BIOS, disabled AHCI support by setting everything back to IDE, and then tried it again. I shut the system down. No clicks. After another restart, I applied a few updates, rebooted the system from Windows–the lo and behold! The drives miraculously remained powered up through a restart!

As it turns out, the generic AHCI support in Windows must be somewhat flaky. Gigabyte recommends installing their AHCI drivers during the OS’ install, presumably for some of the features offered by the various SATA chipsets that ship with the GA-870A-UD3, but I can’t help wondering if installing their drivers would resolve the clicking as well. That is a test reserved for another day–and another drive.

Of course, the drives’ behavior was normal under Linux regardless of the state of AHCI in BIOS. But hey, Linux generally Just Works. Windows… well, not so much. Whatever. If there’s one thing Windows excels at, it is its ability to consistently lower my expectations. (Although I absolutely love the Windows 7 taskbar. It’s fantastic.)

As a side note, my last desktop always had AHCI support disabled. It used an Intel reference board (DP965LT) back when they still called them reference boards and not some flashy name to catch enthusiasts’ eyes. Yet that Intel board would do weird things on a reboot. Sometimes it would behave normally and restart the system. Sometimes it would turn itself off for 5 seconds before powering back up and restarting. Sometimes it would power the disks down, reboot, and then power them back up. It’s nice to have a system again where I don’t have to worry about placing additional wear and tear on my drives from something as innocuous as a reboot.

Windows SP1 Installation Failure: 0x800f0a12

I love Microsoft’s cryptic hex error messages. Rather than outright explaining what the problem is, it seems so much easier for companies whose management still lives in the 1980s to barf up numerical responses that require a lookup table. I’d even be willing to bet that same lookup table only exists in a printed copy rotting away in some dusty storage room. If you’ve ever diagnosed problems (quickly, I might add) from /var/log/messages (or kin, though I hate other loggers), you’ll understand the burning disdain I hold for numerical errors. Storage is cheap. Memory is cheap. Processing power is cheap. An extra 16-18 bytes isn’t going to kill anyone.

Then again, I guess 640K is enough for everyone, right? (Misattributed, see link.)

So, to the failure. 0x800f0a12 was beyond me. Worse, it was apparent that the error was also beyond some of the Microsoft MVPs who suggested fixes like this one. I encountered this issue on both my previous desktop and my current one–both clean installs–and couldn’t for the life of me figure out a solution.

That is, until I read another post that gave me an epiphany. Specifically, the pertinent part responsible for my eureka-moment was this snippet written by D. Charles Pyle:

You don’t need to run fixmbr, bootsect, bootfix, run repair from the DVD,etc., in instances like that I mentioned above, for this problem if you have a hybrid, single disk, or a single disk with multiple operating systems.

Just marking the Windows partition as ‘active’ made it work flawlessly because the Service Pack 1 installer looks to the active partition for some of the files that need to be updated. When it does not find them on the expected active partition it throws the exception and generates error 0x800f0a12.

Emphasis mine.

I mentioned before that I use Ubuntu. What I didn’t mention was that I dual boot Ubuntu and Windows 7 on the same system. However, both operating systems reside on separate drives. My Ubuntu disk is set as the first boot device, and because it’s more powerful than the Windows’ boot loader, I use Grub to switch between operating systems.

If Windows 7’s Service Pack 1 requires the Windows partition to be marked active before it’ll install, would it be possible that having BIOS initially boot to a completely separate disk be a problem for SP1? To test it, I powered my system down and unplugged the Ubuntu drive. With some animosity, I restarted the SP1 install.

Presto. It worked.

Two completely different systems, two operating systems, and precisely the same problem. All of it related to SP1’s requirement that it be the only OS in control of the system’s boot order. Very funny, Microsoft.

As an addendum to the words of Mr. Pyle, not only does Windows require its partition to be marked active (bootable), but it may also require being configured as the first (or only) disk from BIOS. In some cases, unplugging any other bootable disk in the system may be the only resort. If your attempts to install SP1 failed and your setup is somewhat analogous to mine, this may be your only choice. If you have multiple partitions on the same disk, you may need to set the Windows partition as bootable from fdisk. Although, I would recommend giving each OS its own separate disk. They’re easier to control and isolate that way.

Google Chrome: Let’s make Google Search Powder Blue

…and also hide what links the user has previously clicked on such that everything looks the same.

I admit. Whenever I reinstall Windows, I always backup my user directory. This way, I never have to reconfigure software. I simply reinstall and copy my user directory back over (typically in parts), thus maintaining most of my previous configurations. Whether it’s Chrome, VirtualBox, GiMP, or any number of other software packages, I would much rather take the time to backup and restore my settings than configure everything from scratch. Plus, I like my browser tabs (see above).

The habit was one that I inherited from Linux. In particular, the home directory on my Ubuntu install has lived through 2 Gentoo 32-bit installs, 1 Gentoo 64-bit install, 1 Gentoo 32-bit revert, and 2 Ubuntu upgrades (x64). In one particular case, I even copied my entire Gentoo install to an external drive on the offhand chance I’d have to revert it (I did), and it worked. Unlike Windows, Linux requires little magic to work, and almost any backup method involving copying files (with permissions!) will invariably work–or work well enough that the system can be restored to a usable state.

Unfortunately, I’m not sure what happens half the time when copying completely unchanged configurations between two Windows installs. Sometimes, it may work without a hitch. Other times, you’re left with inexplicable problems. Like my issue with Chrome displaying all Google search pages with the same powder blue link color, no visited link coloration, and no indication of my history, the problem appeared only after copying my Chrome configurations over from my previous Windows install.

I couldn’t find anyone with a similar problem. Those who had problems with Google search appearing weird were suggested to clear their cache (did that), change their Google history settings (not about to do that), or reinstall Windows (haha, really?). So, I did what any other enterprising individual might do. I moved my Chrome directory to another location and re-ran the browser. Crossing my fingers, I ran another search in the hopes I hadn’t somehow corrupted my Chrome install–or something more sinister.

Google search promptly appeared normal as if nothing happened. Strange.

So, I removed the new Chrome directory, replaced it with the old one, restarted the browser, and bam! Same thing–Google search was totally borked.

I hadn’t any idea where to start, really, so I figured that the next best option was to simply start deleting parts of the Chrome user directory to see what got restored and what was affected. My first step was to obliterate everything but the folders under %APPDATA%/Local/google/Chrome/User Data/Default. It’s just user data, right? The only moderately important things I could see were files that clearly stored my browsing history, cookies, bookmarks, and so forth. I had a backup anyway, so who would care if I deleted any of this? I then pressed delete, restarted the browser, and…

…it worked perfectly fine.

Really? Okay, this isn’t funny anymore. I restored the Chrome user data from backup again, launched the browser, checked search, and noticed it was broken. Again. Yes, Google. Blue is a lovely color, but powder blue was something I wore when I was still in diapers. I want something that’s going to show me where I have been. Colorizing every visited link the same as every unvisited link was driving me nuts.

Then it occurred to me: What if it were a cookie problem? Hah. Right. Sure. May as well give it a try, right? I’ve got all Saturday evening…

I opened up Chrome’s cookie list, searched for Google, deleted everything Google-related I find, and then pulled up Google search. Taking a deep breath, I typed out something clever, and pressed enter.

Sweet, beautiful a:visited tags, how I love thee! My problems had been solved by banishing the demons plaguing some cookie in the deep, dark depths of my user directory.

Really, Chrome, you could’ve just told me. Sheesh.

It’s time to Sleep… or Not

The last problem I had with this Gigabyte GA-870A-UD3 board is that I couldn’t get sleep, hibernate, or suspend working on it no matter what I tried. Various forums I stumbled upon where others were having similar problems with identical (or mostly identical) boards suggested disabling “Allow this device to wake up the computer” and enabling “Allow Windows to power off this device” along with various other things like unplugging every device from the computer, turning your keyboard upside-down over your eyes (don’t do this), and even reinstalling Windows (I’m starting to see a pattern). Not a single one of these suggestions worked.

Let me repeat that just to be on the safe side:

Not a single damn suggestion I ever came across solved the Windows 7 sleep issue with this Gigabyte board. Not even a thread on the Seven Forums, ironically marked SOLVED!, offered any helpful advice.

In fact, it wasn’t until I was browsing Microsoft’s Technet forums when I ran across a poster complaining about his system sleeping–but not coming out of sleep–that it dawned on me that the problem might have multiple facets. I don’t have a link to the article anymore, but the poster resolved his wake-up-and-smell-the-roses resume problems by disabling hybrid sleep from the Windows advanced power options. Hey, it couldn’t hurt, could it?

I dug around for a while and couldn’t find it in my power profile under “sleep.” Then I realized I had changed some of the settings in BIOS related to sleep in a futile attempt to cure my system’s malady. Another reboot later, and I had changed ACPI suspend from S1 (power on sleep) to S3 (suspend to RAM), then checked the Windows advanced power options. There it was–under “Sleep”–“allow hybrid sleep: enabled.”

The original poster had hybrid sleep disabled, and claimed that enabling it had fixed the problems with his system waking up. But what if my problem was just different enough that I hybrid sleep wasn’t working at all? It’s possible.

I disabled hybrid sleep, closed my few remaining applications, and clicked sleep. A few moments later, the LED-lit fans in my case shut off and the disks spun down. It was fast asleep.

There’s no real moral to this story in particular other than the fairly obvious realization that suspend, hibernate, or sleep is something like black magic. It works when it works, and when it doesn’t, there’s no telling why. My previous desktop, an Intel board and CPU, entered sleep mode perfectly fine most times (although it would wake up about 1 out of every 10 times for no real reason), but that was hardware from 2006. This Gigabyte board is fairly new, and judging by the number of similar problems out there, I can only surmise that sleep mode problems are pretty common among Gigabyte boards. Yet the weird thing is that out of the three systems I’ve built using Gigabyte boards, mine was the only one that exhibited this issue.

A Penny Saved…

However you have come across this post doesn’t matter much, but I certainly hope that some of the stories I have shared will help you in your particular adventure. Building your own systems is rewarding, and it can also expose software problems and configuration-related issues you never knew existed. The trick is patience. There is a solution, somewhere, if you know where to look. Sometimes, you may need to spend a few nights searching the Interwebs for similar problems, and reading those links that you do come across no matter how unrelated they seem. In some cases, one man’s solution may not work for you, but his suggestions may offer insight that you wouldn’t have come across any other way. Oddly, there are a lot of answers found by no other method than by accident, often using unrelated suggestions as a guide.

If you have also purchased a Gigabyte GA-870A-UD3 board and are experiencing similar issues with sleep mode and mysterious power-down clicks from your hard disks, I hope that the solutions I found will help you. I wasted many hours before I finally resolved my problems, and I would be delighted if this post helps you find a solution much faster. If it does, then I know that time wasn’t wasted at all.

No comments.

Annoyances: vBulletin 4 Template Hooks

I’ve been doing commercial software development for vBulletin 3.x (and, by extension, 4.x) off and on now for a couple of years. While there are some things that irritate the crap out of me about both of these products, vBulletin (both versions) have features that just aren’t found in other bulletin board packages. Admittedly, many of these exclusive features are provided by an extensive library of 3rd party software, but the point still stands–as much as I hate to admit it. Few other message boards have a plugin system that’s easy to develop for, and fewer still have the vast library of plugins available. phpBB doesn’t even come close. vBulletin still has its shortcomings for developers, but I’ll save my complaints for a later installment.

What I’m going to write about tonight is something that bit me, and I know it’s going to bite someone else out there: Template hooks have been the bane of my existence in vB4 for the majority of this weekend, and once you start adding a few yourself, you’ll grow to appreciate the manic schizophrenia that is the vBulletin 4.x template system in all its unadulterated glory. I hope to save you from the onset of severe insanity, so keep reading for my story and my solution.

Side note: You might also want to make this a summer project, because you’ll be bald by the time you’re finished, and I understand that bald heads get cold quite quickly. If you’re already bald, accept my apologies and tear something else out–like the upholstery stuffing in your desk chair. Don’t have a chair? Reach for the carpet. Don’t have carpet? Well, you’re on your own.

Template Hooks: They Work–But not When You Want Them To

I’ve written a couple of plugins that rely on the various forumhome_wgo_pos* template hooks for both vBulletin 3.x and 4.x. These hooks work perfectly for most use cases, regardless of when your plugin fires, and are almost foolproof. Don’t be lulled into a false sense of security, though. The moment you do anything unusual with template hooks in vBulletin 4.x, you’ll be bitten by the what-the-heck-happened-to-my-output surprise.

To reproduce the ailment that has been afflicting my sanity for the better part of this last Sunday, I direct you to a simple test:

  1. Create a new product, complete with its very own plugin.
  2. Set the plugin to fire on the global_start plugin hook.
  3. Add the following code to the plugin:
    $template_hook['footer_test_hook'] = '<b>Hi!</b>';
  4. Add the following code to your footer template:
    {vb:raw template_hook.footer_test_hook}
  5. Run it!

You should notice that you now have a nice, shiny string containing Hi! at the bottom of your page in the footer code. Now, let’s break it:

  1. Add a template, such as break_my_footer to your product XML (optional; you could use any other template if you like)
  2. Call this template from your plugin using something like:
    $tpl = vB_Template::create('mytemplate');

    Or, if you decided to use an existing (small) template:

    $tpl = vB_Template::create('option');
  3. Then modify your template hook code appropriately:
    $template_hook['footer_test_hook'] = htmlentities($tpl->render());
  4. Watch in horror as nothing appears in your footer.

Try as I might, I spent a good hour or two trawling various vBulletin support sites for answers. Rather than make a post somewhere and risk having one of their ill-tempered devs explain “Well, this is how it’s supposed to work, didn’t you use the search?” when the built in search generally sucks and Google doesn’t always pick up their help threads, I decided that this issue became personal. That is to say, this code insulted my mother, my father, my nonexistent siblings, and each of my ancestors going back 1,500 years.

After performing various blind tests I concluded that somehow the call to the vB_Template::create() factory method was effectively wiping the contents of $template_hook–or ignoring it, or purging it, or performing an exorcism on it with tremendous glee while I steamed with fury in front of my monitor. I then decided that I’d had enough, and so I searched for the footer template to determine where it was being called, prepared, and possibly rendered in the code. My hunch was that the footer was being generated separately from the forumhome cruft that so happily seemed to work no matter where I used it or what I did with it (and indeed it is generated separately). Yet my own template hook refused to work.

Then I came across this code in includes/class_bootstrap.php:

 $templater = vB_Template::create('footer');
                        $templater->register('admincpdir', $admincpdir);
                        $templater->register('ad_location', $ad_location);
                        $templater->register('cronimage', $cronimage);
                        $templater->register('languagechooserbits', $languagechooserbits);
                        $templater->register('modcpdir', $modcpdir);
                        $templater->register('quickchooserbits', $quickchooserbits);
                        $templater->register('template_hook', $template_hook);
                        $templater->register('facebook_footer', $facebook_footer);
                $footer = $templater->render();

Pay careful attention to the line $template->register('template_hook', $template_hook);. Clearly, the footer is processing the template hook here–so I thought to myself, perhaps there’s a nearby hook that I could attach my plugin to so I can guarantee I know that the content of $template_hook won’t be interfered with.

I scrolled up and found a hook that probably should have been fairly obvious to me from the start. But hey, it’s the weekend. What more can you expect?

($hook = vBulletinHook::fetch_hook('parse_templates')) ? eval($hook) : false;

Sheepishly, I changed my plugin to use the parse_templates plugin hook instead of global_start, and it worked! So the upshot is: If you’re going to try using custom template hooks and you discover that they won’t work the moment you load a template, try changing the plugin hook to parse_templates. It might just fix the problem.

Now, this was admittedly all my fault for not realizing that parse_templates may be the correct solution; I really should have examined the vBulletin sources more closely. Shame on me. In my defense, though, the vBulletin documentation is pretty poor, much of it is outdated, and even less of it focuses on issues specific to 4.x. However, I have one particular bone to pick: It’s puzzling to me that whatever is in $template_hook will work fine up until the moment you decide to call vB_Template::create(). There’s a comment under the create() method that indicates something to do with $template_hook and treating it as a special case for the purpose of various globals or some such, along with a reference to a bug tracker ID. I think that’s more coincidental than anything else, and certainly if I wanted to find out what was happening, I could run a trace with XDebug, but I’m not that desperate–or bored (yet). My guess is that, somehow, subsequent calls to vB_Template::create() clobber the contents of $template_hook by the time vBulletin gets around to rendering the footer; I may be wrong–I probably am–but this is an example of bizarre code suffering from manic schizophrenia.

Frankly, the vBulletin sources are so stupidly convoluted it’s a miracle the software works as well as it does. I’ll save that for another rant much later this week or next. In short, remember: If you’re toying with custom template hooks, you might just break your code. If you do, try changing the plugin you’re writing for template rendering purposes to hook into parse_templates. You’re almost guaranteed to have little to no interference with the contents of $template_hook and the parse_templates hook is nearest to the templates that are most likely to be affected.

Toodles for now. Expect to see a whiny rant soon!