The Problem

Recently, I was working on a support thread where the user was attempting to override the default functionality of Easy Digital Downloads by using the remove_action() function. This was being done in a custom plugin. This function allows you to negate any add_action() created by another plugin, theme, or WordPress core. Their code, at a basic level, looked like this:

 * Plugin Name: Some Custom Plugin
 * Plugin URI:  ...
 * Description: Another custom plugin
 * Author:      ...
 * Author URI:  ...
 * Version:     ...
 * Text Domain: ...

remove_action( 'edd_purchase_form_after_user_info', 'edd_user_info_fields' );
remove_action( 'edd_register_fields_before', 'edd_user_info_fields' );

function new_edd_user_info_fields() {
 // Replace the checkout form user fields
add_action( 'edd_purchase_form_after_user_info', 'new_edd_user_info_fields' );
add_action( 'edd_register_fields_before', 'new_edd_user_info_fields' );

In short, they were trying to write a custom set of customer info fields on the checkout screen, by overriding the defaults using remove_action. This wasn’t working for them however…I’ll give you a second to think about why. Go ahead, get your thoughts in order.

The Explanation

The issue at hand, is plugin load order. WordPress loads the code for plugins in the following order:

  1. Must Use Plugins (or mu-plugins)
  2. Network Activated Plugins (if it’s a multisite install)
  3. Plugins in the ‘plugins_activated’ option in alphabetical order

What was basically happening, is this custom plugin was loading before Easy Digital Downloads, resulting in the remove_action() was being called before the add_action() that EDD was using.

The Solution

So how did we solve it? Pretty easily actually…

add_action( 'plugins_loaded', 'ck_edd_remove_personal_info', 99 );
function ck_edd_remove_personal_info() {
	remove_action( 'edd_purchase_form_after_user_info', 'edd_user_info_fields' );
	remove_action( 'edd_register_fields_before', 'edd_user_info_fields' );

What this allowed us to do is wait until the last possible moment of the plugins_loaded hook using the ’99’ parameter for order, and then tell WordPress to remove the hooks run by EDD. Then we were free to add our own hooks to make a personalized checkout screen.

Any gotchas?

As with all software development, there’s probably a few edge cases where this won’t work. If the hooks and filters are determining anything before the end of plugins loaded, you might have an issue, but for most general use cases, this should do the trick.

Posted by Chris Klosowski

Chris Klosowski is the President of Easy Digital Downloads, the easiest way to sell your digital products with WordPress. Trusted by over 50,000 smart store owners.