휴면 후크 참조 생성


10

많은 플러그인 개발자가 사용자가 제품 기능을 조정할 수 있도록 필터 / 액션 후크를 추가하는 데 시간이 걸리는 것 같습니다. 어느 것이 좋지만 자주하지 않는 것은 후크 목록과 인수 수를 제공하는 것입니다.

누구나 플러그인 (또는 테마) 디렉토리를 가리키고 사용 가능한 모든 후크 목록을 보는 가장 자동화 된 방법을 찾았습니까?

나는 후크를 스캔하는 플러그인처럼 보였지만, 내가 알 수있는 한, 주어진 페이지를 렌더링하기 위해 실제로 호출되는 플러그인을 보여줍니다. 내가 얻는 것은 편리 할 수 ​​있습니다. 그러나 때로는 특정 플러그인과 상호 작용하고 있다는 것을 안다면 액션이나 필터를 걸 수있는 모든 곳을 알고 싶습니다.

그래서 내가 정말로 찾고있는 것은 플러그인 루트 디렉토리가 주어지면 각 항목에 포함 된 목록을 만들 것입니다.

  • 꼬리표
  • 유형 (조치 또는 필터)
  • 인수 수
  • 소스에서 ( do_action()또는을 통해 apply_filter()) 호출 된 곳

스크립트는 모든 것을 HTML로 멋지게 HTML 화하고 모든 플러그인의 관리자 UI에서 나에게 보여줄 수 있기 때문에 훌륭 할 것입니다. 그러나 유용한 정적 파일을 출력하는 명령 줄 스크립트도 좋습니다.


그래서 질문은 무엇입니까? 플러그인 추천을
찾으신다면

죄송합니다. WordPress Development Meta 잡초에 너무 가까이 가지 않고 싶지는 않습니다. a) 플러그인을 추천하는 것이 OT라는 것을 몰랐습니다. 나는 그것에 대해… 약간의 의견…을 가지고 있을지 모르지만, 여전히, 나는 그것을 먼저 깨달아야했습니다. b) OTOH, 나는 기존 플러그인이나 쉘 스크립트 또는 처음부터 무언가에 대한 나의 해결책을 찾으려고 노력하고있다. 인 질문은 그래서 엄격하게 플러그인 추천 요청!
yonatron

글쎄, 다른 사람들이 재미있어서 해를 끼치 지 않는 것 같습니다. 이 질문에 대한 나의 "이의 제기"는 실제로 컴파일러 구문 소프트웨어를 작성하지만 실제 워드 프레스 코딩과 관련이 거의없는 사람들에게는 모욕적 인 텍스트 파싱 질문에 관한 것이 었습니다. 플러그인을 제출하는 방법과 같은 wordpress.org에 관한 질문조차도 일반적으로 주제를 벗어난 것으로 투표됩니다.
Mark Kaplun

답변:


6

내가 원하는 것을 할 수있는 스크립트 나 플러그인이 없습니다. 언급했듯이 현재 사용중인 필터 및 작업을 인쇄하는 데 사용할 수있는 스크립트 ( 전역 변수 )가 있습니다.

휴면 필터와 행동에 관해서는, 나는 (이 개 매우 기본적인 기능을 작성했습니다 여기에 몇 가지 도움을 거기에 ) 모든 발견되는 apply_filtersdo_action파일에 인스턴스를하고 그것을 밖으로 인쇄

기초

  • RecursiveDirectoryIterator, RecursiveIteratorIteratorRegexIteratorPHP 클래스를 사용하여 디렉토리 내의 모든 PHP 파일을 가져옵니다. 예를 들어, 로컬 호스트에서E:\xammp\htdocs\wordpress\wp-includes

  • 우리는 다음 파일을 반복하고, 검색 및 리턴 (것 preg_match_all)의 모든 인스턴스를 apply_filters하고 do_action. 중첩 된 괄호 인스턴스와 일치 시키고 apply_filters/ do_action와 첫 번째 괄호 사이의 공백을 일치 시키도록 설정했습니다.

그런 다음 모든 필터와 동작으로 배열을 만든 다음 배열을 반복하여 파일 이름과 필터 및 동작을 출력합니다. 필터 / 액션이없는 파일은 건너 뜁니다

중요 사항

  • 이 기능은 매우 비쌉니다. 로컬 테스트 설치에서만 실행하십시오.

  • 필요에 따라 기능을 수정하십시오. 출력을 파일에 쓰거나 특별한 백엔드 페이지를 만들 수 있습니다. 옵션은 무제한입니다.

옵션 1

첫 번째 옵션 기능은 매우 간단합니다.을 사용하여 파일의 내용을 문자열로 반환 file_get_contents하고 apply_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

1
@ MarkKaplun 이것은 내가 빨리 일한 것입니다 :-). 위의 함수는 적어도 특정 플러그인 / 테마 / 코어 디렉토리에서 필터와 액션이 어디에 있는지 알려줍니다. 소스로 돌아가서 특정 필터가 구체적으로 무엇을 수행하는지 이해하는 것이 여전히 중요합니다. 당신은 여전히 알거나 ;-) 특정 필터는 특정 기능에 무엇을 알아 내기 위해 지식과 배경의 어떤 종류의 필요 때문에 일부 플러그인과 테마를 제대로 문서화되어있다
피터 구센

@PieterGoosen 그래, 나는 보통 소스를보기 위해 뒤로 뛰어 들어도 괜찮습니다. 처음 에이 작업을 수행하는 경우 플러그인에 후크가 있지만 반드시 doc 블록이 아닌 것은 아닙니다. 그러나 그들이 실제로 사용되는 곳을 살펴보면 그들이 가치가 있는지 여부를 이해하는 데 도움이됩니다. 어쨌든 이들은 훌륭 할 것 같습니다. HTML 파일에 쓰도록 2 번째를 수정할 수도 있습니다. 왜냐하면 로컬 서버의 MU 플러그인에 함수 선언을 붙이고 WP CLI에서 실행할 수 있기 때문입니다.
yonatron

@yonatron 내 두 센트가 어떤 식 으로든 도움이되어 다행입니다. 만약 당신이 내 코드에서 자신의 수정을 작성하는 올 경우, 당신은 항상 (응답으로 코드 및 설명을 추가 할 수 있습니다 좋을 것이다 ) ;-). 즐기십시오
Pieter Goosen

1
@PieterGoosen이 스크립트를 작성하고 문서화하는 데 걸린 시간이 얼마나 ***** :)
Webloper

6

WP Parser 가 원하는 것을 수행하는 것처럼 들립니다 . 공식 개발자 참조 를 생성하는 데 사용됩니다 . 매개 변수, @since 태그 및 소스 참조를 나열합니다. 모든 WordPress 플러그인과 함께 작동하며 명령 줄을 통해 액세스 할 수 있습니다.

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

1
필자는이 스크립트에 익숙하지 않지만 잘 문서화하려면 필터 나 작업이 필요한 것 같습니다. ;-) @Rarst에서 이에 대한 피드백을 부탁드립니다
피터 구센

아직 시도하지는 않았지만 설명에 따르면 Pieter의 관심사는 목표에 있다고 생각합니다. 형식이 지정된 doc 블록이 앞에 오는 것뿐만 아니라 모든 후크를 찾고 싶습니다. WordPress 규칙을 사용하여 후크 / 기능에 대해 의견을 말하는 사람들은 이미 지원 사이트에서 이러한 종류의 스크립트 및 게시 API 참조를 실행하고 있다고 생각합니다. 개발자가 공개적으로 필터를 문서화하지 않으면 경고없이 변경 / 더 이상 사용되지 않을 수 있지만 사용하는 일부 플러그인의 경우 문서가 온라인으로 표시 될 때까지 기다릴 수 없기 때문에 이것에 내재 된 위험이 있음을 알고 있습니다.
yonatron

또한 문서화되지 않은 후크를 구문 분석합니다. 예 : developer.wordpress.org/reference/hooks/graceful_fail
Jan Beck

4

분노의 질주

좋은 ol ' *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

여기서이 트릭 을 사용 하여 모든 선행 공백을 제거 하고이 필드를 사용하여 첫 번째 필드를 제외한 모든 필드를 인쇄했습니다.

sed여기에 :공백이없는 경우를 대비 하여 두 번째 콜론 ( ) 뒤에 여분의 공간을 추가하기 위해 여기를 사용 합니다 .

스크립트

이것을 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 NUMBERof grep을 사용할 수 있습니다 .

다양한 방법으로 HTML 출력을 수정할 수 있지만 원하는대로 더 조정할 수 있기를 바랍니다.


감사! 나는 꼬집음에 grep을 사용하지만 나는 파이프에 OR을 사용하는 데 결코 익숙하지 않은 쉘 재료의 초보자입니다. 내가 추가하고 싶은 다른 것은 조금 인쇄하는 옵션입니다. 위의 grep 라인의 출력은 여전히 ​​탈피하기가 매우 어려울 것입니다.
yonatron

2
나는 꽤 인쇄 @yonatron의 예와 답을 갱신
birgire
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.