休止フック参照を生成する


10

多くのプラグイン開発者は、フィルター/アクションフックを追加して、ユーザーが製品の機能を微調整できるように時間をかけているようです。これはすばらしいことですが、フックのリストと引数の数を提供することはあまりありません。

誰かがプラグイン(またはテーマ)のディレクトリを指し、利用可能なすべてのフックのリストを表示する最適な自動化された方法を見つけましたか?

フックをスキャンするプラグインはいくつかあるようですが、私の知る限り、特定のページをレンダリングするために実際に呼び出されているプラ​​グインが表示されます。私が手に入れるものは便利です。しかし、特定のプラグインを操作していることがわかっている場合は、アクションまたはフィルターをフックできるすべての場所を知りたいことがあります。

だから私が本当に探しているのは、プラグインのルートディレクトリが与えられれば、各アイテムが含まれているリストを作成するものです:

  • 鬼ごっこ
  • タイプ(アクションまたはフィルター)
  • 引数の数
  • ソースで(do_action()またはを介してapply_filter())呼び出される場所

これはおそらくすべてをうまくHTML化し、すべてのプラグインの管理UIに表示できるので、スクリプトは素晴らしいでしょう。しかし、有用な静的ファイルを出力するコマンドラインスクリプトでさえすばらしいでしょう。


だから質問は何ですか?プラグインの推奨事項を探す場合は、ここではトピック外です
Mark Kaplun

申し訳ありませんが、WordPress開発メタ雑草にあまり深く入り込みたくありませんが、a)私はここに初めて来たので、プラグインの推奨事項を求めることがOTであることに気づきませんでした。私は…それについていくつかの意見…を持っているかもしれませんが、それでも、私はそれを最初に認識すべきでした。b)OTOH、既存のプラグインかシェルスクリプトか、何か最初からかどうか、私の質問に対する解決策を見つけようとしています。したがって、質問は厳密にプラグイン推奨リクエストです!
yonatron

まあ、誰もが楽しんでいるように害はありません。質問に対する私の「異論」は、実際にはそれがテキスト解析の質問であることについてでした。これは、コンパイラスタイルのソフトウェアを書きたいが、実際のワードプレスコーディングとはほとんど関係がない人々にとって興味をそそるものです。記録のために、プラグインを提出する方法のようなwordpress.orgに関する質問でさえ、通常はトピック外として投票されます。
Mark Kaplun、2015年

回答:


6

あなたが望むことをするために私が知っているスクリプトやプラグインはありません。既に述べたように、現在使用されているフィルターやアクションを出力するために使用できるスクリプト(グローバル変数も)があります。

休止中のフィルターとアクションについては、ファイル内のすべてとインスタンスを検索して出力する2つの非常に基本的な関数(いくつかのヘルプがあちこちにあります)を作成しましたapply_filtersdo_action

基本

  • とPHPクラスを使用してRecursiveDirectoryIterator、ディレクトリ内のすべてのPHPファイルを取得します。例として、私のローカルホストでは、RecursiveIteratorIteratorRegexIteratorE:\xammp\htdocs\wordpress\wp-includes

  • 私たちは、その後、ファイルをループし、検索とリターン(うpreg_match_all)のすべてのインスタンスをapply_filtersしてdo_action。括弧のネストされたインスタンスに一致し、apply_filters/ do_actionと最初の括弧の間の可能な空白に一致するように設定しました

次に、すべてのフィルターとアクションを含む配列を作成し、その配列をループしてファイル名とフィルターとアクションを出力します。フィルター/アクションのないファイルをスキップします

重要な注意事項

  • この機能は非常に高価です。ローカルテストインストールでのみ実行します。

  • 必要に応じて機能を変更します。出力をファイルに書き込み、そのための特別なバックエンドページを作成することができます。オプションは無制限です

オプション1

最初のオプション関数は非常に単純です。を使用してファイルの内容を文字列として返しfile_get_contentsapply_filters/ do_actionインスタンスを検索して、ファイル名とフィルター/アクション名を出力します

簡単にフォローできるようにコードにコメントしました

function get_all_filters_and_actions( $path = '' )
{
    //Check if we have a path, if not, return false
    if ( !$path ) 
        return false;

    // Validate and sanitize path
    $path = filter_var( $path, FILTER_SANITIZE_URL );
    /**
     * If valiadtion fails, return false
     *
     * You can add an error message of something here to tell
     * the user that the URL validation failed
     */
    if ( !$path ) 
        return false;

    // Get each php file from the directory or URL  
    $dir   = new RecursiveDirectoryIterator( $path );
    $flat  = new RecursiveIteratorIterator( $dir );
    $files = new RegexIterator( $flat, '/\.php$/i' );

    if ( $files ) {

        $output = '';
        foreach($files as $name=>$file) {
            /**
             * Match and return all instances of apply_filters(**) or do_action(**)
             * The regex will match the following
             * - Any depth of nesting of parentheses, so apply_filters( 'filter_name', parameter( 1,2 ) ) will be matched
             * - Whitespaces that might exist between apply_filters or do_action and the first parentheses
             */
            // Use file_get_contents to get contents of the php file
            $get_file_content =  file_get_contents( $file );
            // Use htmlspecialchars() to avoid HTML in filters from rendering in page
            $save_content = htmlspecialchars( $get_file_content );
            preg_match_all( '/(apply_filters|do_action)\s*(\([^()]*(?:(?-1)[^()]*)*+\))/', $save_content, $matches );

            // Build an array to hold the file name as key and apply_filters/do_action values as value
            if ( $matches[0] )
                $array[$name] = $matches[0];
        }
        foreach ( $array as $file_name=>$value ) {

            $output .= '<ul>';
                $output .= '<strong>File Path: ' . $file_name .'</strong></br>';
                $output .= 'The following filters and/or actions are available';
                foreach ( $value as $k=>$v ) {
                    $output .= '<li>' . $v . '</li>';
                }
            $output .= '</ul>';
        }
        return $output;
    }

    return false;
}

テンプレート、フロントエンドまたはバックエンドでフォローで使用できます

echo get_all_filters_and_actions( 'E:\xammp\htdocs\wordpress\wp-includes' );

これは印刷されます

ここに画像の説明を入力してください

オプション2

このオプションは、実行に少しコストがかかります。この関数は、フィルター/アクションが見つかる行番号を返します。

ここではfile、ファイルを配列に分解するために使用し、フィルター/アクションと行番号を検索して返します

function get_all_filters_and_actions2( $path = '' )
{
    //Check if we have a path, if not, return false
    if ( !$path ) 
        return false;

    // Validate and sanitize path
    $path = filter_var( $path, FILTER_SANITIZE_URL );
    /**
     * If valiadtion fails, return false
     *
     * You can add an error message of something here to tell
     * the user that the URL validation failed
     */
    if ( !$path ) 
        return false;

    // Get each php file from the directory or URL  
    $dir   = new RecursiveDirectoryIterator( $path );
    $flat  = new RecursiveIteratorIterator( $dir );
    $files = new RegexIterator( $flat, '/\.php$/i' );

    if ( $files ) {

        $output = '';
        $array  = [];
        foreach($files as $name=>$file) {
            /**
             * Match and return all instances of apply_filters(**) or do_action(**)
             * The regex will match the following
             * - Any depth of nesting of parentheses, so apply_filters( 'filter_name', parameter( 1,2 ) ) will be matched
             * - Whitespaces that might exist between apply_filters or do_action and the first parentheses
             */
            // Use file_get_contents to get contents of the php file
            $get_file_contents =  file( $file );
            foreach ( $get_file_contents as  $key=>$get_file_content ) {
                preg_match_all( '/(apply_filters|do_action)\s*(\([^()]*(?:(?-1)[^()]*)*+\))/', $get_file_content, $matches );

                if ( $matches[0] )
                    $array[$name][$key+1] = $matches[0];
            }
        }

        if ( $array ) {
            foreach ( $array as $file_name=>$values ) {
                $output .= '<ul>';
                    $output .= '<strong>File Path: ' . $file_name .'</strong></br>';
                    $output .= 'The following filters and/or actions are available';

                    foreach ( $values as $line_number=>$string ) {
                        $whitespaces = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
                        $output .= '<li>Line reference ' . $line_number . $whitespaces . $string[0] . '</li>';
                    }
                $output .= '</ul>';
            }
        }
        return $output;

    }

    return false;
}

テンプレート、フロントエンドまたはバックエンドでフォローで使用できます

echo get_all_filters_and_actions2( 'E:\xammp\htdocs\wordpress\wp-includes' );

これは印刷されます

ここに画像の説明を入力してください

編集

これは基本的に、スクリプトがタイムアウトしたり、メモリが不足したりすることなくできることです。オプション2のコードを使用すると、ソースファイルの上記のファイルと上記の行に移動し、フィルター/アクションのすべての有効なパラメーター値を取得するだけでなく、重要なのは、関数と次のコンテキストを取得することと同じくらい簡単です。フィルター/アクションが使用されます


1
空き時間が多すぎます;)しかし、結局のところ、フィルターとは何か、また予想されるパラメーター値と結果は何であるかを知るだけでは十分ではありません。コアファイルの数であり、おそらく非コアプラグインとテーマではまったく利用できません。
Mark Kaplun、2015年

1
@MarkKaplunこれは私がすぐに取り組んだものです:-)。上記の関数は、フィルターとアクションが特定のプラグイン/テーマ/コアディレクトリのどこにあるかを少なくとも伝えます。ソースに戻って、特定のフィルターが具体的に何をするかを理解することは、依然として非常に重要です。一部のプラグインとテーマは十分に文書化されていないため、特定の関数で特定のフィルターが何を行うかを理解または理解するには、何らかの知識と背景が必要です;-)
Pieter Goosen

@PieterGoosenええ、私は通常、ソースに戻ってジャンプすることで大丈夫です。私が最初にこれを行っている場合、それはプラグインにフックがあることを意味しますが、必ずしもそれらのためのdocブロックではありません。しかし、それらが実際に使用されている場所を見てみると、それらが価値があるかどうかを理解するのに役立ちます。とにかく、これらは素晴らしいかもしれないように見えます。ローカルサーバーのMUプラグインに関数宣言を貼り付けてWP CLIから実行できるので、HTMLファイルに書き込むように変更することもできます。
yonatron

@yonatron私の2セントが何らかの形で助けてくれてうれしい。私のコードから独自の変更を書きに来る場合は、いつでもコードと説明を回答として追加できます(これはすばらしいでしょう);-)。楽しむ
Pieter Goosen

1
@PieterGoosenこのスクリプトの作成と文書化にどれだけの時間を費やしたか、すごい***** :)
Webloper

6

WPパーサーがあなたが探していることをするように聞こえます。公式開発者リファレンスを生成するために使用されます。パラメータ、@ sinceタグ、およびソースへの参照がリストされます。すべてのWordPressプラグインで動作し、コマンドラインからアクセスできます:

wp parser create /path/to/source/code --user=<id|login>

1
私はそのスクリプトにはあまり詳しくありませんが、十分に文書化するにはフィルターまたはアクションが必要なようです。@Rarstからこれについてフィードバックをいただければ幸いです;-)
Pieter Goosen

私はまだ試していませんが、説明に基づいて、Pieterの関心は目標にあると思います。適切にフォーマットされたdocブロックが前にあるフックだけでなく、すべてのフックを見つけたいと思います。時間をかけてWordPressの規則を使用してフック/関数にコメントを付けている人は、すでにこの種のスクリプトを実行していて、サポートサイトでAPIリファレンスを公開していると思います。開発者がフィルターを公に文書化しない場合、警告なしに変更/廃止される可能性があるため、これには固有のリスクがあることに気付きますが、使用するプラグインによっては、ドキュメントがオンラインで表示されるのを待つことができません。
yonatron、2015年

ドキュメント化されていないフックも解析します。例:developer.wordpress.org/reference/hooks/graceful_fail
Jan Beck

4

ファストアンドフューリアス

古き良き*nixコマンドラインは常に便利です:

# grep  --line-number                                         \
        --exclude-dir=/path/to/some/directory                 \
        --include=*.php                                       \ 
        --recursive                                           \
        "add_filter\|do_action\|apply_filters"                \
        /path/to/wp-content/plugins/some-plugin               \ 
 | less

より多くのオプション#man grep

次に、単純なbashスクリプトを作成することもできますwp-search.sh

#!/bash/bin
grep --line-number                            \
    --exclude-dir=/path/to/some/directory     \
    --include=*.$1                            \
    --recursive $2 $3

と実行します。

 # bash wp-search.sh php "add_filter\|do_action\|apply_filters" /path/to/some-plugin

かなり出力

--color属性を使用しての出力を色分けできますがgrep、では機能しないことに注意してくださいless

別のオプションは、検索結果のHTMLテーブルを生成することです。

以下awkは、検索結果をHTMLテーブルとしてresults.htmlファイルに出力するために作成した例です。

  | sed 's/:/: /2' \
  | awk ' \
        BEGIN { \
            print "<table><tr><th>Results</th><th>Location</th></tr>"  \
        } \
        { \
            $1=$1; location=$1; $1=""; print "<tr><td>" $0 "</td><td>" location "</td><tr>" \
        } \
        END {  \
           print "</table>" \
       }' \
 > results.html

私が使用したところ、このトリックをすべての主要な空白を削除すると、この1は、すべてのフィールドが、最初のものを印刷します。

sedここでは:、スペースがない場合に備えて、2番目のコロン()の後にスペースを追加するためにのみ使用しています。

脚本

これをwp-search.shスクリプトに追加できます。

#!/bash/bin
grep   --with-filename \
       --line-number \
       --exclude-dir=/path/to/some/directory \
       --include=*.$1 \
       --recursive $2 $3 \
| sed 's/:/: /2' \
| awk ' BEGIN { \
        print "<table><tr><th>Results</th><th>Location</th></tr>"  \
    } \
    { \
        $1=$1; location=$1; $1=""; print "<tr><td>" $0 "</td><td>" location "</td><tr>" \
    } \
    END {  \
        print "</table>" \
    }' \
> /path/to/results.html

あなたは調整する必要がどこ/path/to/some/directory/path/to/results.htmlニーズに。

例-プラグインの検索

wordpress-importerプラグインでこれを試してみると:

bash wp-search.sh php "add_filter\|do_action" /path/to/wp-content/plugins/wordpress-importer/

その後、results.htmlファイルは次のように表示されます。

結果

例-コアの検索

私はそれをコアに対して時間テストしました:

time bash wp-search.sh php "add_filter\|do_action" /path/to/wordpress/core/

real    0m0.083s
user    0m0.067s
sys     0m0.017s

そしてそれは速いです!

ノート

追加のコンテキストを取得するには-C NUMBER、grep のofを使用します。

HTML出力をさまざまな方法で変更できますが、必要に応じてこれをさらに調整できれば幸いです。


ありがとう!私はピンチでgrepを使用しますが、私はシェル関連の初心者なので、パイプをORに使用することに慣れていません。もう1つ追加したいのは、少しきれいに印刷するためのオプションです。上記のgrep行の出力は、まだ簡単に読み飛ばすことができません。
yonatron

2
私はプリティプリント@yonatronの例で回答を更新しました
バージレ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.