Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?php
/**
* This is an (arguably messy) setup to test what might be a hook issue.
*
* Jchristopher_Hook_ID_Test_Alpha stores an array of strings to prepend to the_content.
* It has a hook jchristopher_test allowing for other code to modify the array of strings.
* It has its own string 'alpha'.
*
* Jchristopher_Hook_ID_Test_Beta has its own string 'beta' and uses the hook from the
* first class to append 'beta' to the list of strings to prepend to the_content.
*
* Jchristopher_Hook_ID_Test_Gamma also has its own string 'gamma' which it also
* adds to the array of strings using the jchristopher_test filter.
*
* Lastly there is a closure that also aims to append it's own string 'closure' to the
* array of strings that is prepended to the_content.
*
* Problem: The remove_filter call in Jchristopher_Hook_ID_Test_Beta->add_string()
* removes the closure which has a higher priority, and it's never executed.
*
* Expected output: 'alpha beta gamma closure' prepended to the_content
* Actual output: 'alpha beta gamma' prepended to the_content
*/
class Jchristopher_Hook_ID_Test_Alpha {
private $strings = [ 'alpha' ];
function __construct() {
$this->run();
add_filter( 'the_content', function( $content ) {
return implode( ' ', $this->strings ) . ' ' . $content;
} );
}
function run() {
$this->strings = array_merge( $this->strings, array_filter(
apply_filters( 'jchristopher_test', [], $this ),
function( $string ) {
return is_string( $string );
}
) );
}
}
class Jchristopher_Hook_ID_Test_Beta {
private $strings = [ 'beta' ];
function __construct() {
add_action( 'init', [ $this, 'run' ] );
}
function run() {
add_filter( 'jchristopher_test', [ $this, 'strings' ], 20 );
new Jchristopher_Hook_ID_Test_Alpha();
}
function strings( $strings ) {
remove_filter( 'jchristopher_test', [ $this, 'strings' ], 20 );
return array_merge( $this->strings, $strings );
}
}
new Jchristopher_Hook_ID_Test_Beta();
class Jchristopher_Hook_ID_Test_Gamma {
function __construct() {
add_filter( 'jchristopher_test', [ $this, 'strings' ] );
}
function strings( $strings ) {
return array_merge( ['gamma'], $strings );
}
}
new Jchristopher_Hook_ID_Test_Gamma();
// This closure is not executed unless the priority is reduced below 20
// which is the priority of the hook removed in Jchristopher_Hook_ID_Test_Beta->strings()
add_filter( 'jchristopher_test', function( $strings ) {
$strings[] = 'closure';
return $strings;
}, 21 );
@jchristopher

This comment has been minimized.

Copy link
Owner Author

@jchristopher jchristopher commented Jul 7, 2020

Here are the IDs during the call to remove_filter:

xdebug

@jchristopher

This comment has been minimized.

Copy link
Owner Author

@jchristopher jchristopher commented Jul 7, 2020

Turns out it's a logged issue https://core.trac.wordpress.org/ticket/40393

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.