Selectively disable WordPress plugins in your development environment

I recently installed the Add Link to Facebook WordPress plugin on the Colette blog so that our articles would automatically post to our company Facebook page. It works great, and is much more reliable than the Facebook app we used to use to pull content from our RSS feed.

However, shortly after installing this plugin, I was doing some work on the site in my local development environment when I was informed that we suddenly had a handful of duplicate posts on Facebook, all with invalid .dev URLs. Oops.

It didn’t take long to figure out what happened: I periodically sync my development database with a copy of the production database, and scheduled posts come along with it. When the publication dates pass, these posts will switch to “Published” in my local copy of the site. That’s fine, of course, but then the aforementioned Facebook plugin dutifully saw these new posts and pushed them all to our Facebook page, resulting in the duplicate posts and the invalid development site links.

The solution seemed simple: Figure out a way to disable this plugin in develoment. I was already setting a WP_ENV environment variable in my Apache config, setting it to “development” on my laptop and “production” on the server. It seemed a simple thing to check this variable and disable the plugin as needed. All I had to to was figure out just how to do that last step.

Naturally, this turned out to be quite a bit more complicated than I expected, due to the order in which WordPress loads. I initially thought I could simply use deactivate_plugins() in my wp-config.php file but that didn’t seem to be working. Rather, it worked on the second page load but not the first, suggesting that the deactivation code wasn’t loaded early enough.

It took a bit of digging but I finally discovered an answer on StackExchange that clarified things for me. WordPress loads plugins before most anything else, and does not leave room for modifying this beforehand in any of the usual places. Calling deactivate_plugins() in your theme or config file will have no effect because your plugins have already been loaded.

Looking over the diagram in the post, I found my answer: “Must Use” plugins. A holdover from WPMU, must-use plugins are plugins that are installed in a different directory from regular plugins, are automatically activated, and cannot be disabled via WP admin. They also load before regular plugins. The default location for these special plugins is in WP_CONTENT_DIR/mu-plugins but this can be overridded by setting the WPMU_PLUGIN_URL and WPMU_PLUGIN_DIR constants in wp-config.php.

Once I figured that out, the rest was easy. Create your mu-plugins (or whatever you choose to call it) directory, add a file called disable-plugins-in-development.php (or something), and place this code in it:


<?php
/**
 * Disable specified plugins in your development environment.
 * 
 * This is a "Must-Use" plugin. Code here is loaded automatically before
 * regular plugins load. This is the only place from which regular plugins
 * can be disabled programatically.
 * 
 * Place this code in a file in WP_CONTENT_DIR/mu-plugins or specify a
 * custom location by setting the WPMU_PLUGIN_URL and WPMU_PLUGIN_DIR
 * constants in wp-config.php.
 * 
 * This code depends on a server environment variable of WP_ENV, which I set 
 * to "development" or "production" in each particular server/environment.
 */

if (empty($_SERVER['WP_ENV']) || $_SERVER['WP_ENV'] != 'production') {
    $plugins = array(
        'add-link-to-facebook/add-link-to-facebook.php',
        'varnish-http-purge/varnish-http-purge.php',
    );
    require_once(ABSPATH . 'wp-admin/includes/plugin.php');
    deactivate_plugins($plugins);
}

Code also available on GitHub.

You can set up that environment variable for Apache like this (requires mod_env):
SetEnv WP_ENV 'development'

And like this for Nginx:

env WP_ENV=development

What would Seth Godin do? (revisited)

There exists a popular WordPress plugin called What Would Seth Godin Do? (WWSGD), which can be used to display a message to new visitors to your WordPress blog or site. The idea is that new visitors can be shown a welcome message, and be encouraged to take certain actions, such as subscribe to an RSS feed or follow the author on Twitter (or whatever).

To quote Mr. Godin,

“One opportunity that’s underused is the idea of using cookies to treat returning visitors differently than newbies. It’s more work at first, but it can offer two experiences to two different sorts of people.” — Seth Godin, …in the middle, Starting

Admittedly, this technique is not as underused in 2013 as it was in 2006 when this was written, but it’s still useful.

I’m a big fan of this plugin, and have been using it pretty much since it was released, but last year I began using Varnish, which works best when you eliminate unnecessary server-side cookies. Varnish is a great high-performance caching layer and it removes the need to deal with WordPress caching plugins, but by default it does not served cached pages for requests with cookies, working under the assumption that something dynamic is happening on the page and the reader should get fresh data. While this technically is the case with WWSGD, there’s really no reason it has to be.

The functionality provided by the What Would Seth Godin Do? plugin is extremely simple. It checks for a pageview counter stored in a cookie and if the count is lower than the configured threshold, it inserts a customizable message into the page. The greatest value here is the ease of changing the counter threshold and modifying the message, which can both be done via the WordPress admin UI. This is convenient, but not necessary for me.

Realizing that setting and reading the cookie entirely on the client side would get me around the caching issue, I’ve removed the plugin and implemented the core functionality in a few lines of JavaScript (plus jQuery Cookie).


function wwsgd()
{
    var show = 5;
    var cookie_name = 'wwsgd';
    if ($.cookie(cookie_name)) {
        var count = parseInt($.cookie(cookie_name), 10) + 1;
    } else {
        var count = 1;
    }
    $.cookie(cookie_name, count, { expires: 365, path: '/' });
    if (count > show) {
        $('#wwsgd').hide();
    }
}

Code also available on Github

The second step is to instruct Varnish to strip this cookie. Instructions for this can be found in the Varnish documentation.

All that’s left at this point is to add the welcome message to your site with an id of #wwsgd and you’re ready to go. And unlike a WordPress plugin, this technique can be used on any site.

Replacing a plugin with this simple alternative also satisfies my desire for minimal dependencies.

Amazon SNS and StartSSL certificates

I’m considering setting up Sendy so we can move a few of our smaller mailing lists away from MailChimp, which gets fairly expensive as accumulate more lists. Sendy uses Amazon Simple Email Service (SES) to send mail at a fraction of the price and, being a self-hosted application, there are no ongoing fees for use.

In addition to SES, Sendy also uses Amazon’s Simple Notification Service (SNS) to keep track of bounced messages and emails reported as spam. SNS notifies us by sending messages via HTTP to endpoints in the Sendy application that record the data.

I just spent a week working with Amazon support on a problem where my SNS endpoints were stuck in “PendingConfirmation” state. After a handful of days and a fair bit of back-and-forth email, we discovered that the problem had to do with the SSL certificate I’m using for my Sendy installation.

I’m using a wildcard certificate from StartSSL which works great in every browser I’ve tested, back to IE6, but is apparently not trusted by the Java SSL library that Amazon is using for their SNS service. The result of this is that SNS will not be able to talk to your endpoints if you’re using one of these certificates.

Options at this point are a) get a different certificate, or b) not require SSL for your bounces/complaints endpoints. Either of these will fix the problem easily, but it was a real headache figuring this out.

Amazon has a list of certificate authorities supported by SNS, so if you’re not using one of the big ones, you should check there if you see similar problems.

Hopefully this will help anyone else who runs into this problem.

Update: In the end I decided that we’re better served sticking with Mailchimp.

Basil & Co. Retired

Basil & Co. was a cocktail and spirits writing and events project based in Portland, Oregon. We were active from 2010 until 2012, but are no longer maintaining the blog or running events. All content will continue to be available online indefinitely, however.

Cocktailia

For those who love reading about drinking

Cocktailia features high-quality cocktail recipes, reviews of can’t-miss cocktail bars in Portland and beyond, and events of interest to the cocktail aficionado, whether professional or enthusiast. Join us in our travels or just take a look at what we’re mixing up at home. You’re sure to find something you love.

Cocktail Camp

Cocktail education and inspiration

Cocktail Camp is an annual event that’s part social gathering and part learning experience. If you enjoy finely crafted cocktails, or just want to learn more about what goes into them, this full day of cocktail education and socializing has something for you.

If you have questions about these or other projects we were involved in, please get in touch. Please note that I am no longer accepting products for review or hosting events.

Minimal dependencies in WordPress projects

From a post on the Fingertips blog, advice to keep external dependencies in a web application to a minimum:

Minimal dependency is not just about the number of libraries you use, but also about the total amount of code you pull into your project. Less code means less bugs.

It will also give you less trouble with interdependencies when you try to upgrade.

Finally, less dependencies makes long-term maintenance easier because there is less that can go wrong when it’s time to upgrade …

Good advice, especially in light of the serious parameter parsing vulnerability that surfaced in Rails this week. As well as being present in ActionPack, part of Rails core, it was also found in the multi_xml library, which is a used by many popular gems. And I’m sure more vulnerable libraries will be found now that so many eyes are looking for this class of problems.

So while we’re seeing a lot of this right now in the Rails world, it’s important to remember that this issue affects any web sites you’re creating, whether you’re using a third-party framework or not. WordPress is a perfect example — the availability of so many great open source plugins means it’s easy to just grab one for whatever functionality you need and not think about it. It’s almost too easy, really — I’ve seen WordPress sites with literally dozens of plugins installed, for every conceivable purpose.

Case in point: the TimThumb WordPress exploit in 2011. A remote code execution vulnerability was found in a very popular image manipulation library. Few people knowingly used TimThumb on their sites, but it turns out it’s present in many, many open source plugins and themes, meaning that lots of people were open to the attack without being aware of it.

So how do you prevent this? Well, unless you’re writing every bit of code on your site from scratch, there’s no 100% foolproof way. But you can mitigate the issue by being aware of what you’re using, and avoiding external code that isn’t absolutely essential to your particular site or application. Avoid building on third-party WordPress themes. Avoid plugins that don’t provide some essential functionality.

My own habit is to first consider whatever it is I need to do:

  • Can WordPress already do this without a plugin?
  • Can I do it myself without using a plugin or CMS feature?
  • Do I need this feature at all?

For example, I’m a big fan of What Would Seth Godin Do? but it doesn’t require a plugin or even any PHP at all. When looking for ways to minimize cookie use by WordPress (for easier Varnish caching), I replaced this plugin with a few lines of JavaScript that accomplish the exact same thing.

As well, many plugins do nothing but make built-in WP features easier to use. That’s definitely helpful, but it isn’t always necessary. Take the time to do it yourself — it will be easier to customize and you’ll have one less plugin to keep up-to-date.

Finally, if a plugin isn’t providing something that’s essential to your site, you might reconsider whether you need it at all. Are you using it because it’s really adding something useful, or just because you can?

Take the time to audit your WordPress sites to see what you can eliminate. Your life will be easier and your readers will thank you too. Keeping the size of your codebase small not only helps prevent security issues, but also makes your site faster and more responsive.

(For this site, I eliminated WordPress itself. These are static HTML pages generated by Middleman.)