Yesterday I had my first ever bad experience with a WordPress plugin auto-upgrade and it was really really bad. I did the auto-upgrade of the Popularity Contest plugin, first upgrade in a very long time. These upgrades have become so routine that I don’t much think twice about executing them any more. I clicked the link and BANG my blog stopped working. Completely. Totally. All pages, including the wp-admin pages, said:
Error: Popularity contest cannot be installed.
I had to move the plugin out of the directory in order to get anything to work again, then I had to clear my SuperCache as the non-functioning pages had been cached for some of them, like the all important front page.
This morning before work I took a few seconds to look at it, and I found some egregious code. The plugin has a get_settings() method which has this code (forgive the white space munging):
// If the DB tables are not in place, lets check to see if we can install
if (!count($settings)) {
// This checks to see if we need to install, then checks if we can install
// For the can install to work in MU the AKPC_MU_AUTOINSTALL variable must be set to 1
if (!$this->check_install() && $this->can_autoinstall()) {
$this->install();
}
$settings = $this->query_settings();
if (!count($settings)) {
// trigger_error('Popularity Contest Cannot Install', E_USER_WARNING);
wp_die('<b>Error:</b> Popularity contest cannot be installed.');
}
}
Now, this appears to have a couple of really bad problems. One, it is doing wp_die for a configuration problem! Seriously, WTF? I think that violates the contract between a plugin and the main WordPress process. If you have some sort of problem, die gracefully rather than just shutting down the whole blog. Second, it seems like my case will always trigger that die. The $settings array comes from:
select * from wp_ak_popularity_options;
I had the plugin previously installed so that it didn’t need to install but I was running all default options so that my wp_ak_popularity_options table was zero rows. At this point, the plugin decided that was such a bad problem that it needed to shut down all of WordPress including the wp-admin pages you would use to create those option records. Oh boy.
What I did to get back running was to comment out the wp_die line. At that point, the plugin actually installed and I was able to get to the settings page for it. I did a “Save” even though I had all default values just to get rows into that table. Now my table has 4 rows in it and presumably even if I do another automatic upgrade this one should keep working. This plugin is now on my watchlist, though. It’s burned me hard once.
I think for people having this problem just commenting out the wp_die line will get most or all of them back up and running. I’m not sure what the thinking was that went into this logic but it was a really terrible bit of thinking with really severe consequences. Not to the WordPress plugin author community: calling wp_die is really fricking serious. Don’t do it unless continuing to run will delete the blog. Otherwise handle your problems yourself.
Update: For bonus points in the version I have installed, the setup page gives you code to cut and paste into your template that doesn’t actually work. It tells you to use:
show_top_ranked_in_last_days($limit, $before, $after, $days = 45)
when in fact the actual function is:
akpc_most_popular_in_last_days()
The former is an internal one not available outside the plugin. The latter is the external API call that is available to your template.
Update 2: I’ve opted to remove the plugin as well as the WordPress Mobile Edition by the same guy. The author takes shutting down my blog too lightly, and defends this whole thing with “hey, it’s a beta so what do you expect?” I was installing via the Plugin GUI on my WP Admin page. If it was risky, I had no way of knowing that unless seeing a “b” in the version number was supposed to communicate that. Over on his plugin page, Alex King defends the use of the wp_die call as being reasonable. I don’t see that rendering the blog unusable is a reasonable way to deal with it, even if the configuration tables were missing. His code wasn’t even checking that, as it treated an empty table as the same as a not-created table. Bad juju.
Alex, thanks for your time in creating this plugin. I appreciate the use I got out of it for the time I did. However, my blog is important to me and I can’t have plugin upgrades shutting it down.