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

WordpressFilter

Wordpress Problem Overview


I have a question regarding WordPress, specifically version 3.0 and newer.

Does anyone know how to get an array or list of all the functions that will be applied or are 'registered' to the_content filter?

The idea is to generate a checkbox list of possible functions to remove from the filter, such as wpautop. I know how to remove functions from the filter with hard coded labels, but I am hoping to create a more dynamic solution.

If anyone has any ideas if this is possible and how it could be done I would be very interested. Thanks.

Wordpress Solutions


Solution 1 - Wordpress

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' );

Solution 2 - Wordpress

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

Solution 3 - Wordpress

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;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmacguru2000View Question on Stackoverflow
Solution 1 - Wordpresst31osView Answer on Stackoverflow
Solution 2 - WordpressDanijelView Answer on Stackoverflow
Solution 3 - WordpressDenis FedorovView Answer on Stackoverflow