A few years ago I read an article about short-circuiting functions with apply_filters()
rather than using pluggable functions via function_exists()
. I love the idea because of how flexible it is- I'm not limited by when a function can be overridden (plugins, child theme, parent theme), how often, or by naming convention. With this mindset, I've written my theme to allow many functions to be short-circuited this way.
For comparison:
Pluggable Function Override
if ( !function_exists('xyz_print_name') ){
function xyz_print_name($name){
//Do stuff here
}
}
Short-circuited Function Override
function xyz_print_name($name){
$override = apply_filters('xyz_pre_print_name', null, $name); //Notice $name is a single parameter, so this works no problem. See below for issues with multiple parameters when I split it into first and last name.
if ( isset($override) ){return;}
//Do stuff here
}
I could override it like this:
add_filter('xyz_pre_print_name', '__return_empty_string');
Or I could rewrite it like this:
add_filter('xyz_pre_print_name', 'abc_print_name');
function abc_print_name($name){
//Do my own stuff here
return true;
}
This has been absolutely great until I ran into the issue that has been plaguing my for the last few months on and off...
I can easily override functions with no parameters or even a single one, but two or more parameters will through a monkey wrench into everything.
I can't quite figure out why, either. I think it has something to do with the second parameter of apply_filters()
itself: $value
Since I'm not passing a value, I assign it false
, and use the actual $arg1
, $arg2
, etc. parameters. However, when I write the actual override function, I need to include a null value in the declaration to accommodate it. I feel like this is sloppy code:
add_filter('xyz_pre_print_name', 'abc_print_name', 10, 3); //I must pass 3 parameters here (instead of the 2 I need to account for the extra $null parameter)
function abc_print_name($null, $first_name, $last_name){ //Notice here I need to pass $null as the first parameter
//Do stuff here
}
Instead, I could do it like this, but I've noticed it breaks some of my functions (and technically is incorrect according to the WordPress Codex since I'm misusing the $value
parameter):
//...
$override = apply_filters('xyz_pre_print_name', $first_name, $last_name);
//...
add_filter('xyz_pre_print_name', 'abc_print_name', 10, 2);
function abc_print_name($first_name, $last_name){ //Notice $first_name is being passed as the $value parameter of the filter- which is wrong
//Do my own stuff here
}
One last quick note, if I switch my override to use do_action()
instead of apply_filter()
which does not have the extra parameter before the arguments, everything works great again except that I can not detect if the override hook was used, so both the override function and then my original function run.
Phew, that's a long question. TL;DR Is anyone else short-circuiting functions in WordPress? I thought I saw some discussion about it even in WordPress core. If so, how are you doing it? Have you run into similar issues?
I struggle so much to find others trying this method, so I'd appreciate any insight at all. I just don't want to give up on this method...
Edit: To specify my question:
Is there a better way to allow for short-circuiting a function so that an extra $null
parameter does not need to be used when utilizing it? I've also added comments in my above snippets for what I'm specifying in each.