web-dev-qa-db-ja.com

WordPress:「the_content」フィルターのすべての登録済み関数を取得する方法

WordPress、特にバージョン3.0以降に関して質問があります。

The_contentフィルターに適用または「登録」されるすべての関数の配列またはリストを取得する方法を知っている人はいますか?

アイデアは、wpautopなど、フィルターから削除する可能性のある関数のチェックボックスリストを生成することです。ハードコーディングされたラベルを使用してフィルターから関数を削除する方法は知っていますが、より動的なソリューションを作成したいと思っています。

これが可能かどうか、そしてそれをどのように行うことができるかについて誰かがアイデアを持っているなら、私は非常に興味があるでしょう。ありがとう。

55
macguru2000

フィルター配列から印刷する単純な関数?

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

必要な場所で呼び出します。

print_filters_for( 'the_content' );
115
t31os

これはもう少し高度な例で、_$wp_filter_配列のデータに加えて、フックがアタッチされているファイルのパスと、関数が定義されているコード内の行を表示します。

特定のアクション(またはfilter)にフックされた関数の基本リストを取得するには、フィルター配列からアイテムをフェッチするだけで十分ですが、関数はさまざまな方法(クラスメソッドまたはクロージャー)でアタッチできるため、リストには文字列として表示されるオブジェクトを含む大量の無関係なデータ。この例では、関連データのみを優先度順に表示します。

  • 関数名(コールバック構文に応じて):
    • 関数コールバック:_'function_name'_
    • オブジェクトメソッド:array( $object, 'function_name' )
    • 静的クラスメソッド:array( 'class_name', 'function_name' )および_'class_name::function_name'_
    • クロージャ:function() {}
    • 相対静的クラスメソッド:array( 'class_name', 'parent::function_name' )
  • 受け入れられた引数
  • ファイル名
  • スタートライン
  • id
  • 優先度

_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;
}
_

ランタイム全体でフックを追加および削除できるため、出力は関数が呼び出されるポイントに依存します(_wp_footer_アクションは完全なリストを取得するのに適した場所です)

_print_r_フィルターの_the_content_の例:

_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
        )

    .....
_

編集:2017-05-05

  • _WP_Hook_クラスに適合
  • 優先度を追加
  • 修正済み:コールバックが存在しない場合にエラーが発生しましたが、WordPressも警告を発します
  • 修正:同じidで異なる優先度のフックが前のものを上書きする
25
Danijel