开发者

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

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.


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


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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜