WordPress: How do I get all the registered functions for 'the_content' filter

Based on the same idea of print_filters_for, an extended function for those who need not only print but return as well:

function filters_for( $hook = '', $return = FALSE ) {
    global $wp_filter;
    if( empty( $hook ) || !isset( $wp_filter[$hook] ) )
        return;

    if( $return ) {
        ob_start();
    }

    print '<pre>';
    print_r( $wp_filter[$hook] );
    print '</pre>';

    if( $return ) {
        return ob_get_flush();
    }
}

Output:

filters_for( 'the_content' );

Get and output:

$output = filters_for( 'the_content', true );
echo $output;

Simple function to print from the filter array?

function print_filters_for( $hook = '' ) {
    global $wp_filter;
    if( empty( $hook ) || !isset( $wp_filter[$hook] ) )
        return;

    print '<pre>';
    print_r( $wp_filter[$hook] );
    print '</pre>';
}

Call it where you need it.

print_filters_for( 'the_content' );

This is a bit more advanced example, that will, in addition to data from $wp_filter array, show the path of the file where the hook is attached, as well as the line in code where the function is defined.

To get a basic list of functions hooked on a specific action ( or filter ) it is enough to fetch the items from the filter array, but since the functions can be attached in various ways ( as a class method or closure ) that list will contain a ton of irelevant data that includes objects presented as string. This example will display only the relevant data, in order of priority:

  • function name ( depending on callbacks syntax ):
    • function callback: 'function_name'
    • object method: array( $object, 'function_name' )
    • static class method: array( 'class_name', 'function_name' ) and 'class_name::function_name'
    • closure: function() {}
    • relative static class method: array( 'class_name', 'parent::function_name' )
  • accepted args
  • file name
  • start line
  • id
  • priority

function list_hooks( $hook = '' ) {
    global $wp_filter;

    if ( isset( $wp_filter[$hook]->callbacks ) ) {      
        array_walk( $wp_filter[$hook]->callbacks, function( $callbacks, $priority ) use ( &$hooks ) {           
            foreach ( $callbacks as $id => $callback )
                $hooks[] = array_merge( [ 'id' => $id, 'priority' => $priority ], $callback );
        });         
    } else {
        return [];
    }

    foreach( $hooks as &$item ) {
        // skip if callback does not exist
        if ( !is_callable( $item['function'] ) ) continue;

        // function name as string or static class method eg. 'Foo::Bar'
        if ( is_string( $item['function'] ) ) {
            $ref = strpos( $item['function'], '::' ) ? new ReflectionClass( strstr( $item['function'], '::', true ) ) : new ReflectionFunction( $item['function'] );
            $item['file'] = $ref->getFileName();
            $item['line'] = get_class( $ref ) == 'ReflectionFunction' 
                ? $ref->getStartLine() 
                : $ref->getMethod( substr( $item['function'], strpos( $item['function'], '::' ) + 2 ) )->getStartLine();

        // array( object, method ), array( string object, method ), array( string object, string 'parent::method' )
        } elseif ( is_array( $item['function'] ) ) {

            $ref = new ReflectionClass( $item['function'][0] );

            // $item['function'][0] is a reference to existing object
            $item['function'] = array(
                is_object( $item['function'][0] ) ? get_class( $item['function'][0] ) : $item['function'][0],
                $item['function'][1]
            );
            $item['file'] = $ref->getFileName();
            $item['line'] = strpos( $item['function'][1], '::' )
                ? $ref->getParentClass()->getMethod( substr( $item['function'][1], strpos( $item['function'][1], '::' ) + 2 ) )->getStartLine()
                : $ref->getMethod( $item['function'][1] )->getStartLine();

        // closures
        } elseif ( is_callable( $item['function'] ) ) {     
            $ref = new ReflectionFunction( $item['function'] );         
            $item['function'] = get_class( $item['function'] );
            $item['file'] = $ref->getFileName();
            $item['line'] = $ref->getStartLine();

        }       
    }

    return $hooks;
}

Since hooks can be added and removed throughout the entire runtime, the output depends on at what point the function is called ( wp_footer action is a good place to get the complete list )

print_r example for the_content filter:

Array
(
    [0] => Array
        (
            [id] => 000000004c8a4a660000000011808a14run_shortcode
            [priority] => 8
            [function] => Array
                (
                    [0] => WP_Embed
                    [1] => run_shortcode
                )

            [accepted_args] => 1
            [file] => C:\xampp\htdocs\wordpress\wp-includes\class-wp-embed.php
            [line] => 58
        )

    [1] => Array
        (
            [id] => wptexturize
            [priority] => 10
            [function] => wptexturize
            [accepted_args] => 1
            [file] => C:\xampp\htdocs\wordpress\wp-includes\formatting.php
            [line] => 41
        )

    [2] => Array
        (
            [id] => 0000000006c5dc6d0000000064b1bc8e
            [priority] => 10
            [function] => Closure
            [accepted_args] => 1
            [file] => C:\xampp\htdocs\wordpress\wp-content\plugins\plugin\plugin.php
            [line] => 16
        )

    .....

Edit: 2017-05-05

  • adapted for WP_Hook class
  • added priority
  • fixed: error raised if callback does not exists, although WordPress also raises a warning for that
  • fixed: hook with the same id but different priority overwrites the previous one