Blog

How to store billing address information from the s2member plugin

s2member logos2member, the membership plugin we use on Smart Insights, doesn’t store the billing address entered when people purchase memberships or products. I needed a way to be able to get access to that information, and here’s the solution I figured out.

Why doesn’t s2member store billing address information?

Storing cardholder data such as billing address and credit card number is not secure, and puts you in a tricky situation in terms of your site’s PCI Compliance. To avoid this, s2member just passes this information straight onto your payment gateway of choice (in our case this is PayPal) and does not store it locally. It goes without saying that you should NEVER store any credit card details in the WordPress database.

Why would you need to store billing address information from the s2member plugin?

For us, there are two reasons to have access to this information;

1) We want to be able to send billing address (not credit card details) to our CRM/marketing automation platform

We have a marketing automation platform called Office Auto Pilot which runs our email and other marketing activities. It also acts as our customer relationship management (CRM) platform. Not having a member’s address and country details in this is a pain – we’re unable to segment our communications on geographical area, which is lousy when we have members in 50 different countries paying different prices in different currencies.

2) We want our members to be able to see what they’ve purchased previously, and print invoices

s2member doesn’t currently provide any functionality for generating invoices from within WordPress, or allowing members to see what they’ve paid in the past. Relying on PayPal to send receipts to our members isn’t sufficient – many require tax invoices with a letterhead, and at present that means we have to manually create an invoice. As we grow and the volumes increase, this is taking too much time.

How do we store billing address information in the s2member plugin?

s2member comes complete with hundreds of hooks and filters which allow you to attach your custom code to its functionality. Unfortunately (and sorry for saying this s2 guys as the plugin is otherwise exceptional) the documentation is practically non-existent. So you’re left with visiting the API reference and trying to figure out what does what, where and when by trial and error.

After a lot of messing around, I discovered that the action ws_plugin__s2member_during_configure_user_registration_front_side_paid is fired just after someone submits the PayPal payment form, which of course contains the billing address fields.

In order to access this information, you must first create a MU (must-use) plugin in your WordPress installation. These are plugins that WordPress will load automatically. There’s good documentation on creating an s2member MU plugin on the s2member site, so I’ll assume you’ve gone and done that and are now ready to continue.

In order to grab the billing information from the payment form, use the following function and action:


// This function will grab the user street, city, state, country and zip billing address fields and save them as user meta.

add_action('ws_plugin__s2member_during_configure_user_registration_front_side_paid', 's2_grab_fields_from_form');
function s2_grab_fields_from_form($vars = array()) {

update_user_meta( $vars['user_id'], 'billing_street', $_POST['s2member_pro_paypal_checkout']['street'] );
update_user_meta( $vars['user_id'], 'billing_city', $_POST['s2member_pro_paypal_checkout']['city'] );
update_user_meta( $vars['user_id'], 'billing_state', $_POST['s2member_pro_paypal_checkout']['state'] );
update_user_meta( $vars['user_id'], 'billing_country', $_POST['s2member_pro_paypal_checkout']['country'] );
update_user_meta( $vars['user_id'], 'billing_zip', $_POST['s2member_pro_paypal_checkout']['zip'] );

}

Now, I put the example above to show you how the $vars parameter also contains the WordPress user_id of the person who just purchased a membership, which allows you to store this (and indeed any other information in either the $vars or $_POST arrays) as user_meta. But I stress here that just because you can, doesn’t mean you should. In my case I send the billing address information straight off to our CRM system via an API call, and do not store them locally at all. I would strongly recommend you do the same.

Hope that helps someone else save some time instead of trawling the internet for hours looking for a way of storing billing address information from s2member.

Fixing PHPStorm after an OSX Mavericks update

OSX MavericksI use PHPStorm for all my development – it’s a robust and very featured IDE that has got even better recently since version 7 was released. As such it’s the application I spend a large percentage of my working day in, and therefore typical that it’s the source of another issue with OSX Mavericks after my previous issue with Vagrant. PHPStorm simply refuses to start after a OSX Mavericks update.

So how do we go about fixing PHPStorm after an OSX Mavericks update?

The issue is that OSX Mavericks doesn’t come with Java 6 installed, which is what PHPStorm requires to run. To fix it, go here and install the official Java package for OSX. After install, PHP Storm will work again.

Hooray. Maybe now I can actually get some work done today…

Fixing Vagrant after an OSX Mavericks update

OSX MavericksBeing too eager, as I generally am, I went straight ahead and updated to OSX Mavericks when it launched yesterday, and it broke my development environment.

So how do you go about fixing Vagrant after an OSX Mavericks update?

 

Updated: 30th October – issues with starting VM on computer restart 

Updated: 5th November – changes to VirtualBox in version 4.3 

After updating to OSX Mavericks, I was getting the following error message:

There was an error while executing `VBoxManage`, a CLI used by Vagrant for controlling VirtualBox. The command and stderr is shown below.
Command: ["hostonlyif", "create"]Stderr: 0%...Progress state: NS_ERROR_FAILURE
VBoxManage: error: Failed to create the host-only adapter
VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component HostNetworkInterface, interface IHostNetworkInterface
VBoxManage: error: Context: "int handleCreate(HandlerArg*, int, int*)" at line 68 of file VBoxManageHostonly.cpp

After trying to update VirtualBox (didn’t work), refresh Vagrant (didn’t work), review permissions on the Vagrant folders (didn’t work), I stumbled across the following command, which seemed to do the trick in fixing Vagrant after the OSX Mavericks update.

sudo /Library/StartupItems/VirtualBox/VirtualBox restart

Update: If you’re running the latest 4.3 version of Virtual box the restart command has changed – it’s now;

sudo launchctl load /Library/LaunchDaemons/org.virtualbox.startup.plist

The next ‘vagrant up’ command I ran worked, and my dev environment is back in action.

Update: If you’re still having problems with virtual machine being broken on computer restart..

I know a lot of people are having a similar problem – even if you perform a graceful shutdown of your VM before turning off your mac, on restart your VM is broken again.

Last night I uninstalled and updated VirtualBox to 4.3, did the same to Vagrant, and made sure I had the latest version of Varying Vagrant Vagrants. I then killed my existing virtual machine with ‘vagrant destroy’ which has the effect of downloading a new VM on next ‘vagrant up’. After downloading and installing everything my VM was back up and running.

I then shut down my mac, and restarted. This time a ‘vagrant up’ worked. Or at least it seemed to until I discovered that no sites on the VM responded when I tried to visit them in my brower. I logged into the VM on SSH and checked NGINX – it hadn’t started for some reason, so I restarted the service with ‘service nginx reload’, which worked.

Problem is, still no sites respond.

At present the only way I can get my VM working again after a reboot is to run:

vagrant up --provision

Adding this extra parameter forces vagrant to re-run provisioning of the box which in turn forces all services to start up from scratch. This takes longer than a normal ‘vagrant up’ but it works, so for now it seems to be the best solution!

Update: People are saying that upgrading VirtualBox to the very latest 4.3.2 version has fixed the problem

It hasn’t for me, sadly. I can now start the VM with no issues, but I can’t access any sites on it as NGINX refuses to start properly. Not a VBox problem, more an issue with something in my Varying Vagrant Vagrants config, I suspect. I’m still having to run a ‘vagrant up –provision’ to get going again after a restart.

Let me know in the comments if you’ve found a better way.

Implementing Google Universal Analytics Measurement Protocol in PHP and WordPress

Google Universal AnalyticsI’ve had some historic difficulty in being able to track ecommerce transactions in Google Analytics that happen ‘behind the scenes’ of the Smart Insights site – typically when PayPal sends an IPN message, server to server, for a subscription renewal in our case. Since those messages don’t touch the browser, you can’t use the Google Analytics javascript to track them. So I started looking to see how/if I could send data directly to Google Analytics from a backend script running on our WordPress install.

I found several custom PHP classes that seemed, initially, to do the trick;

Problem is, they’re both pretty old and seem to be no longer developed, so I figured there must be something better. My colleague Dave Chaffey then pointed me in the direction of the Google Measurement Protocol, which I hadn’t heard of before.

What is the Google Measurement Protocol and why should I care?

The Measurement Protocol is an addition to the latest version of , which is called ‘Universal Analytics’. From the explainer documentation;

The Google Analytics Measurement Protocol allows developers to make HTTP requests to send raw user interaction data directly to Google Analytics servers. This allows developers to measure how users interact with their business from almost any environment.

More at ‘‘

Google allows you to form and send any of the following types of Analytics request via this API;

  • Page Tracking
  • Event Tracking
  • Ecommerce Tracking
  • Social Interactions
  • Exception Tracking
  • User Timing Tracking
  • App tracking

Using the Google Measurement Protocol in PHP and WordPress

NOTE:  You can only use the Measurement Protocol if you have the Universal Analytics tracking code set up on your site. It will not work with the standard tracking code. If you need help with this, there’s a fantastic introduction at the KissMetrics site: Universal Analytics: Switching to the Next Version of Google Analytics

As is typical with Google and ‘beta’ products (as the Universal Analytics code is still in beta) they give pretty sparse examples and no specific code, so it’s up to you to work things out yourself.

In my case I wanted to be able to fire two types of requests to Google – an ecommerce transaction when a membership renewal occurs, and a custom pageview which is used as a ‘‘ on Analytics.

As I wanted the code to be reusable throughout the WordPress install, I came up with a set of functions (mine lives in a function file of its own, yours could live in your standard theme functions.php file if you wish).

There are two steps needed to make a request to the Measurement Protocol.

1. Obtain the current user’s unique identifier (CID) from the Google Analytics cookie (if it exists!)

Very vital, this, and something I ended up banging my head on the desk about. When a user lands on your site, the Google Analytics code assigns them a unique identifer. This lives in a cookie, and follows them across all requests they make on your site. If you fire a server side request and make up your own unique identifier, the Analytics service has no way of matching the two up.

Obviously this isn’t a problem in my original use case – a behind the scenes ecommerce renewal won’t have a browser cookie to get anything from, and it doesn’t matter that you assign it a unique identifier all of its own. But – if you decide to use the Measurement Protocol for other things, front of site (and I did within 10 minutes of finishing my first code), then you do need to check for the existence of that cookie first. If you don’t, a user that has logged page history will suddenly become anonymous when you fire your Measurement Protocol request. This means that things like conversion funnels won’t work, which is not good.

So, here’s how we parse the GA cookie;

// Handle the parsing of the _ga cookie or setting it to a unique identifier
function gaParseCookie() {
  if (isset($_COOKIE['_ga'])) {
    list($version,$domainDepth, $cid1, $cid2) = split('[\.]', $_COOKIE["_ga"],4);
    $contents = array('version' => $version, 'domainDepth' => $domainDepth, 'cid' => $cid1.'.'.$cid2);
    $cid = $contents['cid'];
  }
  else $cid = gaGenUUID();
  return $cid;
}

This code will pluck the CID value from the cookie if it exists. If not, it runs another function to generate one – gaGenUUID(). The Measurement Protocol documents say that the CID must “be a random UUID (version 4) as described in http://www.ietf.org/rfc/rfc4122.txt“. Ah, okay. So let’s create one of those, then;

// Generate UUID v4 function - needed to generate a CID when one isn't available
function gaGenUUID() {
  return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
    // 32 bits for "time_low"
    mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),

    // 16 bits for "time_mid"
    mt_rand( 0, 0xffff ),

    // 16 bits for "time_hi_and_version",
    // four most significant bits holds version number 4
    mt_rand( 0, 0x0fff ) | 0x4000,

    // 16 bits, 8 bits for "clk_seq_hi_res",
    // 8 bits for "clk_seq_low",
    // two most significant bits holds zero and one for variant DCE1.1
    mt_rand( 0, 0x3fff ) | 0x8000,

    // 48 bits for "node"
    mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
  );
}

So, we now have a CID that we can use.

2. Build and send our Measurement Protocol request

There are two functions used here – one to build the request, the other to send it. In both cases you call gaBuildHit() with two parameters – the method (which in my example is either ‘pageview’ or ‘ecommerce’) and an array of data that is needed by the Measurement Protocol. This differs depending on the method you’re using, so let’s jump into the code and I’ll explain more afterward.

function gaBuildHit( $method = null, $info = null ) {
  if ( $method && $info) {

  // Standard params
  $v = 1;
  $tid = "UA-XXXXXXX"; // Put your own Analytics ID in here
  $cid = gaParseCookie();

  // Register a PAGEVIEW
  if ($method === 'pageview') {

    // Send PageView hit
    $data = array(
      'v' => $v,
      'tid' => $tid,
      'cid' => $cid,
      't' => 'pageview',
      'dt' => $info['title'],
      'dp' => $info['slug']
    );

    gaFireHit($data);

  } // end pageview method

  // Register an ECOMMERCE TRANSACTION (and an associated ITEM)
  else if ($method === 'ecommerce') {

    // Set up Transaction params
    $ti = uniqid(); // Transaction ID
    $ta = 'SI';
    $tr = $info['price']; // transaction value (native currency)
    $cu = $info['cc']; // currency code

    // Send Transaction hit
    $data = array(
      'v' => $v,
      'tid' => $tid,
      'cid' => $cid,
      't' => 'transaction',
      'ti' => $ti,
      'ta' => $ta,
      'tr' => $tr,
      'cu' => $cu
    );
    gaFireHit($data);

    // Set up Item params
    $in = urlencode($info['info']->product_name); // item name;
    $ip = $tr;
    $iq = 1;
    $ic = urlencode($info['info']->product_id); // item SKU
    $iv = urlencode('SI'); // Product Category - we use 'SI' in all cases, you may not want to

    // Send Item hit
    $data = array(
      'v' => $v,
      'tid' => $tid,
      'cid' => $cid,
      't' => 'item',
      'ti' => $ti,
      'in' => $in,
      'ip' => $ip,
      'iq' => $iq,
      'ic' => $ic,
      'iv' => $iv,
      'cu' => $cu
    );
    gaFireHit($data);

  } // end ecommerce method
 }
}

// See https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
function gaFireHit( $data = null ) {
  if ( $data ) {
    $getString = 'https://ssl.google-analytics.com/collect';
    $getString .= '?payload_data&';
    $getString .= http_build_query($data);
    $result = wp_remote_get( $getString );

    #$sendlog = error_log($getString, 1, ""); // comment this in and change your email to get an log sent to your email

    return $result;
  }
  return false;
}

Registering a pageview

Details on the parameters needed .

You need to send the code in the following way:

$data = array(
  'title' => 'Any page title you want to send',
  'slug' => '/please/change/me/to-whatever-you-want/'
);
gaBuildHit( 'pageview', $data);

Registering an ecommerce transaction

You have to send a minimum of two requests here – the first is the initial transaction, and the second is for the specific item, They’re bound together on the same ‘transaction ID’ so Analytics can match them up. Details on the parameters needed .

Please note – if you have multiple line items, my code doesn’t accommodate that as we only ever have one. You’ll need to amend the code to loop over the items and send them all.

You need to send the code in the following way:

$data = array(
  'info' => array ('product_id' => 102, 'product_name' => 'Smart Insights membership' ), // we already have these details in an array so send that, you may want to amend
  'cc' => 'GBP', // the currency code
  'price' => 209.00, // the price
  'country' => GB // the country ISO code
);
gaBuildHit( 'ecommerce', $data);

Some things to be aware of

  1. If you choose to take a peek at what is returned from the API after a request, you’ll be surprised to learn that you only ever get a 200 response, regardless whether your request has succeeded or failed. So it’s a bit pointless, really, you can’t debug it that way
  2. If you use the Real Time view on Analytics, you will be able to see your ‘pageview’ requests appear within seconds, so you know it works!
  3. If you use the ‘ecommerce’ method, you’ll probably have to wait for 2-3 hours (like I did) before data appears, or not. Not helpful, but the code should work – at least you don’t have to start from scratch like I did! 🙂
  4. The code above is written for our site – you will more than likely have to tweak and change it to make it work for yours.

And that’s that – though it could do with some tidying (which I’ll do when I extend it further), it should be easy to add any of the other methods available on the Measurement Protocol API to these functions. Running within your WordPress install it should give a good starting point to using the server side Google Analytics Measurement Protocol in PHP and WordPress.

I’d love to hear how other WordPress developers are using the new Google Universal Analytics Measurement Protocol within their WordPress sites – let me know in the comments!

Installing Git version control on a shared hosting provider

Due to a server upgrade, my ‘staging environment’ hosting provider, Aspiration Hosting broke the self compiled version of Git I had running on the server, which meant I had to go digging once more to remember how I installed it without root access in the first place. Here it is so I (and potentially others) don’t have to do it again.

Essentially, what you’re going to be doing is compiling and installing Git from source. Sounds scary? Not really – just make sure you follow the commands below and all should be well.

Before you start

In order to install Git on a shared hosting you must have the following. If you don’t, you could ask your hosting provider to give you this access. They may surprise you and allow it – most (good ones) should.

  1. SSH access into your hosting provider
  2. Compiler access – test this by running the command gcc –version. If it returns a version number, you’re good to go.

All sorted? Let’s begin

Logged into your hosting and in your home folder, run the following commands;

(NB: You can find the latest Git source from here, so replace the link below with the most recent stable release)

curl -O http://github.com/git/git/archive/v1.8.3.3.tar.gz
tar zxvf git-1.8.3.3.tar.gz
cd git-1.8.3.3
./configure --prefix=/home/$USER --with-curl --with-expat
make -i
make -i install
echo 'PATH=$PATH:$HOME/bin' >> $HOME/.bashrc
source $HOME/.bashrc

That’s it – providing all worked okay, you should now be able to run git version and be rewarded with ‘git version 1.8.3’.

Some notes on the above

Just in case anyone is interested.

Originally when I set Git up prior to the server upgrade, I used Joe Mailer’s article – ‘How to install Git on a shared host‘. This didn’t work for me since the server upgrade, because the hosting company did not have certain software packages I kept getting http/https helper errors during the make process.

I found another guide by Randall Kent here, but again – same problem.

Finally I found a Stack Overflow question that contributed the –with-curl –with-expat parameter in the configure and the -i flag in make which cured the problem.

How to monitor and reduce WordPress memory usage by plugins

WordPress memory

One of the best things about WordPress is that it’s so easy to extend your site’s functionality with the many (mostly) free plugins available on the plugin repository. But loading your site with too many plugins can cause your site to consume too many resources on your server, slowing your site down. So how do you find out what resources your plugins are consuming to help you reduce WordPress memory usage and speed up your site?

Reduce WordPress memory usage by plugins

In a WordPress page request, the point at which plugins are loaded depends on how they’ve been coded. WordPress runs through a series of typical actions on every request. You can see these actions here, including the order in which they are run. A plugin developer decided where in this their plugin is needed, depending on the functionality the plugin offers, and ‘hooks’ into one of these actions, overiding or extending the default WordPress functionality with their custom code. More general information on the basics of plugin writing is available at the WordPress Codex.

So, as an example you’ve got a site that has 10 (or more!) plugins. These are firing at different times during a page request, hooking into different actions, all over the place. So how do you go about monitoring which plugins are most intensive?

As standard, there isn’t an easy way to monitor what WordPress memory usage is as it loads all of the plugins you’ve got installed on your site. But there are three plugins that in tandem, can really help you to find out what’s causing your site to slow down. Let’s look at them.

1) P3 (Plugin Performance Profiler)

Created by the in-house team at GoDaddy, the P3 (Plugin Performance Profiler) plugin allows you to run a scan over your site to determine what resources your plugins are using, and when, during a standard page request. This allows you to see the worst offenders and reduce WordPress memory usage by removing them or finding alternatives.

Once you’ve installed the plugin running a scan is easy and quick, even on a large site. Once the scan is complete you’ll see a comprehensive results report such as this;

P3 (Plugin Performance Profiler) Report
P3 (Plugin Performance Profiler) Report

The Runtime by Plugin report shows you a simple pie breakdown of which plugins are causing the most load on your site during a page request. Very useful, and a very quick way for you to identify and reduce WordPress memory usage by removing plugins that you don’t need.

Even more useful is the Detailed Timeline, which shows when the plugins are being loaded during the page request, so you can see if any particular one is causing a problem at a particular point.

Detailed Timeline of plugin load
Detailed Timeline of plugin load

Using the P3 (Plugin Performance Profiler) is a great start, but how do we get more information about what’s causing our site to slow down?

2) Memory Viewer

As the developer of the Memory Viewer plugin says;

Memory Viewer is a WordPress plugin that allows you to view WordPress’ memory utilization at several hooks during WordPress’ execution. It also shows a summary of MySQL Queries that have ran as well as CPU time.

Once installed, administrative users will see a new panel at the bottom of every page;

Memory Monitor output
Memory Monitor output

The report shows the memory usage at every major action hook, along with statistics on time and MySQL usage. You can also choose to show the queries that are happening at each hook, and output allows gives you an idea as to what code is responsible, which allows you to pinpoint exactly which ones are causing excessive load.

Generally a good indicator is when you see the ‘Current Memory Usage’ column leap up significantly from one action to the next. Any large jumps are worthy of investigation, as there could be plugins running that are the cause, or custom scripts in your theme that need optimisation. By removing or optimising these blockages, you can reduce WordPress memory usage significantly and then retest to see the effect of your changes on page load speed.

3) Debug Bar

Finally, the Debug Bar plugin offers similar functionality to Memory Monitor, but installs a panel into the WordPress admin bar. It is also extendable via other plugins to track and monitor other data such as the errors and warnings that PHP may record when you have the WordPress debug, WP_DEBUG, switched on.

Personally I prefere the ease and simplicity of Memory Monitor, but there’s no doubt that Debug Bar is extremely powerful.

Debug Bar output
Debug Bar output

So that’s three different, easy ways to monitor your WordPress site and find out which plugins and scripts you need to consider removing or tweaking to reduce WordPress memory usage and speed up your site.

I’d be really interested to hear what other WordPress developers use to monitor and optimise their sites.

Increasing the PHP timeout on NGINX for WordPress

wordpress-nginxI’ve been using a Vagrant development set up for a while now, which has introduced me to NGINX after always using Apache in the past. The transition has been fine in the main, though I had an issue yesterday with PHP scripts timing out on me, so needed to figure out how to extend the script execution time.

I’ve started using the excellent WP Migrate DB plugin to synch my local development environment database with the live staging server. It’s well worth spending $19 on the Pro version, by the way – it offers a lot of extra features for the small outlay.

The plugin works by you installing it on both your local and staging sites, and then authorising them to ‘see’ each other using private API keys – it’ll then push (or pull) and overwrite the database from whichever site you choose.

The problem I experienced was that the Smart Insights database is pretty large by WordPress standards – a good couple of hundred MB, and when attempting to pull this down to my local development environment I kept getting “504 Gateway Time-out” errors. Guessing it was more than likely a local timeout issue, I looked around on increasing the PHP timeout on NGINX for WordPress.

Depending on how you’re using NGINX, the answer is that you may have to change a few different things.

NB: I’m using Jeremy Felt’s ‘Varying Vagrant Vagrants’ setup here, so the instructions are specific to that, though I’ll include the default locations too.

Increasing the PHP timeout in the php.ini file

If using ‘Varying Vagrant Vagrants’;

  1. Open your vagrant-local folder root
  2. Open config/php5-fpm-config/php.ini
  3. Change the following line to the length of time you want (in seconds)
max_execution_time = 500

If using a standard server setup the instructions are the same, but the path will generally be /etc/php5/fpm/php.ini.

Increasing the PHP timeout in PHP-FPM

If using ‘Varying Vagrant Vagrants’ without changes, you don’t need this step, but best to check;

  1. Open your vagrant-local folder root
  2. Open config/php5-fpm-config/www.conf
  3. Change/add the following line to the length of time you want (in seconds)
request_terminate_timeout = 500

If using a standard server setup the instructions are the same, but the path will generally be /etc/php5/fpm/pool.d/www.conf.

Increasing the PHP timeout on NGINX config

If using ‘Varying Vagrant Vagrants’ without changes, you shouldn’t need this step either;

  1. Open your vagrant-local folder root
  2. Open config/nginx-config/nginx.conf
  3. Change/add the following line inside the existing http{} section, to the length of time you want (in seconds)
http {
#...
fastcgi_read_timeout 500;
#...
}

If using a standard server setup the instructions are the same, but the path will generally be /etc/nginx/nginx.conf.

Restarting PHP and NGINX

Don’t forget to restart both PHP and NGINX so your changes take affect! You can do this on the command line with the following;

service php5-fpm reload
service nginx reload

After restarting, WP Migrate DB successfully migrated the database from the live staging server to my local copy – way easier than manually exporting/tranferring/importing databases manually!

Hope that helps someone save a bit of time – I’d be interested in knowing what other people think of NGINX in comparison to Apache – let me know!

Sending your own output to the WordPress debug log

Every WordPress developer knows how to use WP_DEBUG in the wp-config.php file to enable the WordPress debug log. But how do you go about sending output to the WordPress debug log, so you can debug your own code while developing a theme or plugin?

Every developer is familiar with using the old print_r($my_stuff); die; trick to print the contents of an array (or object) to the screen so you can make sure that your code is doing what you expect. A better way to do this is write to your own custom log file, of course, and until this week I’ve maintained a separate PHP log file and using the PHP error log function to write to this;


error_log($my_stuff, 3, "/var/tmp/my-errors.log");

I then use Console on my mac to watch this log:

Mac Console
Mac Console

While this is completely fine, in the background WordPress is busy sending output to the WordPress debug log file, which (providing you’ve enabled WP_DEBUG) lives in wp-content/debug.log. I got fed up with having two separate Console windows open to monitor these, and looked into how I could write my own output directly to the WordPress debug log. And it turns out it’s pretty easy.

Add the following code to your theme’s functions.php file;


if (!function_exists('write_log')) {
    function write_log ( $log )  {
        if ( true === WP_DEBUG ) {
            if ( is_array( $log ) || is_object( $log ) ) {
                error_log( print_r( $log, true ) );
            } else {
                error_log( $log );
            }
        }
    }
}

What this does is create a custom logging function that you can call within your code – this first checks to see if WP_DEBUG is set to true (notice the yoda condition here, you will – it’s part of the WordPress coding standards). If WP_DEBUG is switched on, the function prints the contents of $log to the WordPress error log. It doesn’t matter if you’ve populated $log with a variable, array or object – the function checks and handles those.

Whenever you need to be sending output to the WordPress debug log file in your code, simply call the new function as follows;


write_log('THIS IS THE START OF MY CUSTOM DEBUG');

write_log($whatever_you_want_to_log);

Note that I always use two lines here – the first so I can search for my custom output in Console, and the second the actual data I want to log.

Now you can simply monitor the wp-content/debug.log file  for both WordPress errors and your custom ones. Hope someone else finds that useful!

Getting the WordPress current template name in posts and pages

ManHoldingQuestionMarkYesterday I needed to selectively hide breadcrumbs for particular WordPress templates, but had some issues with getting the WordPress current template name when needed, so I thought I’d share how I went about it.

First things first – the way you go about it depends on whether you’re working with pages or posts – these are not seen as the same thing by WordPress, and it can cause some confusion. Posts include any custom post types that you may have created, by the way.

Getting the WordPress current template name for PAGES

Ordinarily when targeting a specific page, you can use is_page();

if ( is_page(*put_your_id_here*) ) {
  // Returns true when the current page is *put_your_id_here* }
else {
  // Returns false when the current page is *put_your_id_here*
}

The problem is, this requires you to put in a specific page_id. What happens if you use the same page template for multiple pages, though? You don’t want to be adding to a never ending list of IDs when you add a new page with that template, so it’s necessary to find a solution that applies to all.

A quick browse through some other code I remembered working with before brought me to the is_page_template() function;

if ( is_page_template('about.php') ) {
  // Returns true when 'about.php' is being used.
} else {
  // Returns false when 'about.php' is not being used.
}

Perfect – simply put your page template file name (including the .php) into the above, and if the function returns true, I don’t output the breadcrumbs.

Getting the WordPress current template name for POSTS

As mentioned above  – don’t forget that this includes custom post types you create – they’re all classed as posts by WordPress.

The post version of is_page() is is_single();

if ( is_single(*put_your_id_here*) ) {
  // Returns true when the current post is *put_your_id_here*
} else {
  // Returns false when the current post is *put_your_id_here*
}

Update: you can also use is_singular() to target a specific custom post type single post.

Again, though, this relies on you targeting a specific post_id. Fine if you only want to target a single post, but useless if you want to target all posts that use the same WordPress template.

In my case, I had a custom post type – Guides, and didn’t want to show the breadcrumbs on any single posts for this post type. As a result, I knew that I needed to target every post that was using the PHP template file single-guide.php – this being the template file I’ve created to override the standard WordPress single post template single.php. If you’re not sure on this – have a read of the WordPress template hierarchy – it explains how you can easily override templates depending on a range of criteria – post types, categories, taxonomies and more.

As it turns out, there’s no easy in-built function to get WordPress to know what template it’s using for posts. The solution I found on StackExchange is to put the following in your theme’s functions.php file:

// Grabbing current page template
add_filter( 'template_include', 'var_template_include', 1000 );
function var_template_include( $t ){
  $GLOBALS['current_theme_template'] = basename($t);
  return $t;
}
function get_current_template( $echo = false ) {
  if( !isset( $GLOBALS['current_theme_template'] ) ) return false;
  if( $echo ) echo $GLOBALS['current_theme_template']; else  return $GLOBALS['current_theme_template'];
}

What this does is;

  • grab the WordPress current template name when WordPress pre-processes it before outputting to the screen
  • drops this template into a global variable so you can use it throughout the site

All you need to do now is call your new get_current_template() function to  your check to see if the current template matches the one you’re looking for, in my case to exclude the breadcrumbs in my theme’s header.php file;

if ( !get_current_template() === 'single-guide.php' ) {
output_breadcrumbs(); // don't show crumbs here on guide pages
}

Hope that helps someone – if anyone knows of a better way, let me know!

Simple A/B testing in WordPress with Google Analytics site experiments

As we’re about to make some significant tweaks and changes to the main product pages on the Smart Insights site, I’ve looked at a lightweight way to do simple A/B testing in WordPress.

What is A/B testing?

You’ll probably be aware of the concept, I’m sure!

A/B testing, also called split testing or multivariate testing, involves your site randomly selecting one of several versions of a page to show to a site visitor. The aim is to find out which one is most successful at converting your visitors.

AB-Testing
What is A/B Testing?

Why do you need it?

Put simply, how do you know if the changes you made to a page are working better than the earlier version unless you can compare them side by side?

A/B testing allows you to make changes from a position of intelligence – knowing the impact of the changes you make allows you to learn what works and what doesn’t, and make sure that you repeat the successes and not the failures.

A/B testing in WordPress

After doing the usual Google searches, I discovered several A/B testing WordPress plugins, the best of which seemed to be MaxA/B. It’s a comprehensive plugin, and as a result pretty complicated.

The problem – MaxA/B seemed to me to duplicate a lot of the metrics and data capture that is really the job of an analytics tool and the fact is, mostly all of us already have a system installed on our sites that is specifically geared around telling us how our site performs – Google Analytics.

It just didn’t seem to make much sense to install something else that duplicates something I already have – so I wanted to see if there was a simpler method to allow us to use Google Analytics and without installing a plugin. I discovered that there is – and it’s provided directly within Google Analytics.

Introducing Google Site Experiments

I use Google Analytics a lot, but this particular feature has completely passed me by. Apparently it used to be a separate system called Google Content Experiments but has been merged into Google Analytics back in August 2012.

Content Experiments is a somewhat different approach from either standard A/B or multivariate testing. Content Experiments is more A/B/N. You’re not testing just two versions of a page as in A/B testing, and you’re not testing various combinations of components on a single page as in multivariate testing. Instead, you are testing up to five full versions of a single page, each delivered to visitors from a separate URL.

More at the

Great – perfect for what we wanted to do, and easy enough to make it work with WordPress on the surface. It recognises that a user is on the page that you’re wanted to experiment with, and then randomly sends them off to one of the other pages you’ve got in the experiment. As a result we can set each version of the page up as a separate page within WordPress, and add each URL to the experiment within Google Analytics.

When you set up your experiment (full instructions ) you get some javascript code that you have to add to the <head> tag of the original page of your experiment;

Create a new experiment Google Analytics
Creating a new experiment in Google Analytics

The problem is that the <head> section of every page in WordPress is served from a single PHP file – header.php. Adding the Google experiments javascript code to this means it will fire on every page, and break your site as a result. So how do we use experiments with WordPress pages? There’s an easy solution.

Outputting the experiments code on your original page only

Firstly, log in to your WordPress site as an administrator and browse to the edit screen for the original page. Once there, look in your browser’s URL bar to get the page ID from the URL.

Getting the WordPress page ID
Getting the WordPress page ID

Now fire up your favourite code editor and open the header.php file in your active theme directory. Below the first <head> line add the following code, substituting your page ID instead of ***PAGEID***, and the experiment javascript code provided by Google Analytics in place of ***GOOGLECODE***;


<?php if (is_page(***PAGE ID***) ):?>

***GOOGLECODE***

<?php endif; ?>

Simple as that! Using the is_page function allows us to surround the output of our experiment code in a conditional statement – if the current page ID matches the ID of your original experiment page, the javascript will fire and the Google experiment will work.

Once installed on your site, Google will automatically randomise which of your test pages your users see and start to measure the success of each, and depending on the length and configuration of the experiment will eventually declare a ‘winner’.

I’m keen to hear what other WordPress developers are using for doing simple A/B testing in WordPress – are you using a plugin such as MaxA/B or have you had any experience of Google content experiments?