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:
<?php /** * 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:
- Must Use Plugins (or mu-plugins)
- Network Activated Plugins (if it’s a multisite install)
- 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.