When developing WordPress sites I generally have three environments: live, staging, and local. Since I like my staging environment to be a very close replica of production, I frequently overwrite the database and files in staging. This is especially true when working with a host like WP Engine that has one-click staging environments.
However, when the database is overwritten in staging, there’s a generally a few settings that still need to be different from production. For instance, with WooCommerce sites, I may need to deactivate SSL and put Stripe into testing mode.
Occasionally I’ll also need to deactivate certain analytics plugins or third-party API integrations like MailChimp.
After making these updates manually for months, I finally moved to a programmatic update routine for many of my sites. The code basically just checks which environment we’re in. If it’s one of the staging environments and the update script hasn’t been run already, it runs it.
Update Routine Code
Here’s example code for the update routine, which I’ll explain in more detail underneath:
https://gist.github.com/devinsays/45958d6ed936aca18079
Check Environment
I used to have the script always run unless it detected it was in production, i.e.:
if ( 'https://example.com' == site_url() )
But I realized this could be dangerous if the site_url ever got updated on production by mistake. Explicitly setting the stage and local environments where the script should run seemed safer.
Use Transient to Check if Settings Updated
We don’t need the update routine to run constantly, just once after the database has been overwritten. We may even want to re-enable some of those plugins or change a setting back in order to test something specific in staging.
This is where the transient comes into play: get_transient( ‘staging-settings-updated’ ). A transient is basically an option that expires after a specific amount of time. In this case, if the transient has already been set, it means the update routine has run and we don’t need to run it again. For this example, I have the transient expire after a day- but you could set this as long as you like.
Nice. I need to be doing something similar with my local set up for EDD’s site.
Funny, I’ve just started thinking this week about how to automate stuff like this and it was great to see in the “Call for features” for WP4.4 on the Make blog lots of people suggest some kind of environment system.
It occurs to me that there’s a number of ways to achieve this:
1) Actual environment variables on the server
2) Constants in wp-config.php
3) The options table
But what I think would be REALLY hand is two things in core. No! Actually, they can be one thing. (I’m thinking on my feet!):
Environment-specific settings.
I don’t know how this would work out. Maybe an extra column in wp_options would be best. But I envisage that there is a default environment, and all settings in this default environment take effect unless they are overridden. And then there are specific environments; so if an options entry has an environment specific option then it takes precedence over the default.
Then you just have a simple constant in wp_config.php that sets the environment.
I’m sure this isn’t thought through and there will be things like serialised data to take into account, and there will be some kind of UI, but something like this seems like a great concept.
I think what you’re envisioning exists! Check out the “Dictator” project by Daniel Bachhuber: https://danielbachhuber.com/2014/03/31/introducing-dictator/
Thanks for sharing your setup, Devin. Automating something like this is a great plan.
I know there are often lots of ways of solving a problem. It seems the WordPress Pre Option Filter might be another choice and might eliminate the need for a transient.
Of course a working solution is better than any theoretical idea :)
Thanks again for sharing.
Hi Sal. Yes, that is a terrific tip! The pre_option filter could definitely be handy for something like this.
In my case, I still want to disable the plugins and maybe occasionally flip one of those settings (even in a sandbox environment) in order to test something specific, so it’s better if I don’t lock the setting using filters.
I cannot overstate how massively helpful this is for me! I have dozens of WooCommerce sites using Subscriptions/Follow Ups on WP Engine. This will save me so much time! Thank you so much!!!