Gerar referências de gancho inativo

10

Parece que muitos desenvolvedores de plugins reservam um tempo para adicionar ganchos de filtro / ação para permitir que os usuários ajustem a funcionalidade de seus produtos. O que é ótimo, mas o que eles geralmente não fazem é fornecer uma lista de ganchos e quantos argumentos eles recebem.

Alguém encontrou a melhor maneira automatizada de apontar para um diretório de plug-in (ou tema) e ver uma lista de todos os ganchos disponíveis?

Eu pareço alguns plug-ins que procuram por ganchos, mas, até onde sei, eles mostram quais deles estão sendo realmente chamados para renderizar uma determinada página. O que eu recebo pode ser útil. Mas, às vezes, se eu sei que estou interagindo com um plug-in específico, quero saber em todos os lugares que ele pode permitir que eu crie uma ação ou um filtro.

Então, o que realmente estou procurando é algo que, dado um diretório raiz de plug-in, criará uma lista em que cada item inclui:

  • tag
  • tipo (ação ou filtro)
  • número de argumentos
  • onde é chamado (via do_action() ou apply_filter() ) na origem

Um script seria ótimo, pois isso poderia HTMLify a coisa toda e mostrá-lo para mim na interface do administrador para cada plug-in. Mas mesmo um script de linha de comando que produza um arquivo estático útil seria ótimo.

    
por yonatron 04.10.2015 / 20:42

3 respostas

6

Não há script ou plug-in que eu saiba para fazer o que você quer. Como você afirmou, existem scripts ( mesmo variáveis globais ) que você pode usar para imprimir filtros e ações que estão sendo usadas atualmente.

Quanto a filtros e ações dormentes, escrevi duas funções muito básicas ( com alguma ajuda aqui e ali ) que encontra todas as instâncias de apply_filters e do_action em um arquivo e depois imprime fora

BASICS

  • Usaremos as classes RecursiveDirectoryIterator , RecursiveIteratorIterator e RegexIterator PHP para obter todos os arquivos PHP em um diretório. Como exemplo, no meu localhost, usei E:\xammp\htdocs\wordpress\wp-includes

  • Em seguida, percorremos os arquivos, pesquisamos e retornamos ( preg_match_all ) todas as instâncias de apply_filters e do_action . Eu configurei-o para coincidir com instâncias aninhadas de parênteses e também para combinar possíveis espaços em branco entre apply_filters / do_action e o primeiro parênteses

Vamos simplificar, em seguida, criar um array com todos os filtros e ações e, em seguida, percorrer o array e gerar o nome do arquivo, filtros e ações. Vamos pular arquivos sem filtros / ações

NOTAS IMPORTANTES

  • Essas funções são muito caras. Execute-os apenas em uma instalação de teste local.

  • Modifique as funções conforme necessário. Você pode decidir gravar a saída em um arquivo, criar uma página especial de back-end para isso, as opções são ilimitadas

OPÇÃO 1

A primeira função de opções é muito simples, retornamos o conteúdo de um arquivo como uma string usando file_get_contents , procuramos as apply_filters / do_action instances e simplesmente geramos o nome do arquivo e os nomes de filtro / ação

Comentei o código para facilitar o acompanhamento

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

Você pode usar a seguir em um modelo, frontend ou backend

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

Isso imprimirá

OPÇÃO2

Estaopçãoéumpoucomaiscaraparaserexecutada.Estafunçãoretornaonúmerodalinhaondeofiltro/açãopodeserencontrado.

Aquiusamosfileparaexplodiroarquivoemumamatriz,entãoprocuramoseretornamosofiltro/açãoeonúmerodalinha

functionget_all_filters_and_actions2($path=''){//Checkifwehaveapath,ifnot,returnfalseif(!$path)returnfalse;//Validateandsanitizepath$path=filter_var($path,FILTER_SANITIZE_URL);/***Ifvaliadtionfails,returnfalse**Youcanaddanerrormessageofsomethingheretotell*theuserthattheURLvalidationfailed*/if(!$path)returnfalse;//GeteachphpfilefromthedirectoryorURL$dir=newRecursiveDirectoryIterator($path);$flat=newRecursiveIteratorIterator($dir);$files=newRegexIterator($flat,'/\.php$/i');if($files){$output='';$array=[];foreach($filesas$name=>$file){/***Matchandreturnallinstancesofapply_filters(**)ordo_action(**)*Theregexwillmatchthefollowing*-Anydepthofnestingofparentheses,soapply_filters('filter_name',parameter(1,2))willbematched*-Whitespacesthatmightexistbetweenapply_filtersordo_actionandthefirstparentheses*///Usefile_get_contentstogetcontentsofthephpfile$get_file_contents=file($file);foreach($get_file_contentsas$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($arrayas$file_name=>$values){$output.='<ul>';$output.='<strong>FilePath:'.$file_name.'</strong></br>';$output.='Thefollowingfiltersand/oractionsareavailable';foreach($valuesas$line_number=>$string){$whitespaces='&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';$output.='<li>Linereference'.$line_number.$whitespaces.$string[0].'</li>';}$output.='</ul>';}}return$output;}returnfalse;}

Vocêpodeusaraseguiremummodelo,frontendoubackend

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

Issoimprimirá

EDITAR

Isso é basicamente o que eu posso fazer sem os scripts expirarem ou ficarem sem memória. Com o código na opção 2, é tão fácil quanto ir ao dito arquivo e a dita linha no código fonte e então obter todos os valores de parâmetros válidos do filtro / ação, também, importante, obter a função e o contexto em que o filtro / ação é usado

    
por Pieter Goosen 07.10.2015 / 10:04
6

Parece que o WP Parser faz o que você está procurando. É usado para gerar a referência de desenvolvedor oficial. Ele lista parâmetros, tags @since e referências à fonte. Ele funciona com todos os plugins do WordPress e pode ser acessado via linha de comando:

wp parser create /path/to/source/code --user=<id|login>
    
por Jan Beck 07.10.2015 / 12:20
3

O Veloz e Furioso

A boa linha de comando *nix é sempre útil:

# 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

Muitas mais opções via #man grep .

Em seguida, podemos até criar um script bash simples wp-search.sh :

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

e execute-o com.

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

Saída bonita

Podemos usar o atributo --color para colorir a saída de grep , mas observe que não funcionará com less .

Outra opção seria gerar uma tabela HTML para os resultados da pesquisa.

Aqui está um exemplo de awk que construímos que gera os resultados da pesquisa como uma tabela HTML, no arquivo 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

onde usei esse truque para remover todos os espaços em branco iniciais e esta para imprimir todos os campos, exceto o primeiro.

Eu uso sed aqui apenas para adicionar espaço extra após o segundo cólon ( : ), caso não haja espaço.

Script

Poderíamos adicionar isso ao nosso script 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

onde você precisa ajustar o /path/to/some/directory e o /path/to/results.html de acordo com suas necessidades.

Exemplo - Procurando por um plugin

Se tentarmos isso no plug-in wordpress-importer com:

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

o arquivo results.html será exibido como:

Exemplo-Pesquisandoonúcleo

Eutesteiotempoparaonúcleo:

timebashwp-search.shphp"add_filter\|do_action" /path/to/wordpress/core/

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

e é rápido!

Notas

Para obter um contexto extra, podemos usar o -C NUMBER do grep.

Poderíamos modificar a saída HTML de várias maneiras, mas esperamos que você possa ajustá-la às suas necessidades.

    
por birgire 07.10.2015 / 12:56

Tags