Genera riferimenti hook dormienti


10

Sembra che molti sviluppatori di plug-in impieghino il tempo per aggiungere hook di filtro / azione per consentire agli utenti di modificare la funzionalità dei loro prodotti. Il che è fantastico, ma ciò che spesso non fanno è fornire un elenco di hook e quanti argomenti prendono.

Qualcuno ha trovato il modo automatizzato migliore per puntare a una directory di plugin (o tema) e vedere un elenco di tutti gli hook disponibili?

Mi sembrano alcuni plugin che cercano gli hook, ma per quanto ne so, ti mostrano quali vengono effettivamente chiamati per il rendering di una determinata pagina. Che ottengo può essere utile. Ma a volte se so che sto interagendo con un particolare plug-in, voglio sapere ogni posto in cui potrebbe lasciarmi agganciare un'azione o un filtro.

Quindi quello che sto veramente cercando è qualcosa che, data una directory root del plugin, creerà un elenco in cui ogni elemento include:

  • etichetta
  • tipo (azione o filtro)
  • numero di argomenti
  • dove viene chiamato (tramite do_action()o apply_filter()) nella sorgente

Uno script sarebbe fantastico dal momento che questo potrebbe presumibilmente HTMLify il tutto e mostrarmelo direttamente nell'interfaccia utente di amministrazione per ogni plugin. Ma anche uno script da riga di comando che genera un utile file statico sarebbe fantastico.


quindi qual è la domanda? se cerchi una raccomandazione per il plugin, è fuori tema qui
Mark Kaplun,

Siamo spiacenti, non voglio approfondire troppo le erbacce Meta di sviluppo di WordPress , ma a) Sono nuovo qui, quindi non mi ero reso conto che chiedere consigli sui plugin fosse OT. Avrei potuto ... alcune opinioni ... a riguardo, ma avrei dovuto prima rendermene conto. b) OTOH, sto solo cercando di trovare una soluzione alla mia domanda, sia che si tratti di un plug-in esistente o di uno script shell o di qualcosa da zero. Quindi la domanda è strettamente una richiesta di raccomandazione di plugin!
yonatron,

beh, sembra che tutti gli altri si stiano divertendo, quindi nessun danno fatto. La mia "obiezione" alla domanda riguardava in realtà il fatto che si trattava di una domanda di analisi del testo che è interessante per le persone a cui piace scrivere software in stile compilatore ma ha ben poco a che fare con la vera codifica wordpress. Per la cronaca, anche le domande su wordpress.org come come inviare un plugin di solito vengono votate come fuori tema.
Mark Kaplun,

Risposte:


6

Non ci sono script o plugin che conosco per fare quello che vuoi. Come hai affermato, esistono script ( anche variabili globali ) che è possibile utilizzare per stampare i filtri e le azioni attualmente in uso.

Per quanto riguarda i filtri e le azioni dormienti, ho scritto due funzioni molto semplici ( con qualche aiuto qua e là ) che trova tutto apply_filterse do_actionle istanze in un file e poi lo stampa fuori

BASE

  • Useremo il RecursiveDirectoryIterator, RecursiveIteratorIteratore RegexIteratorclassi PHP per ottenere tutti i file PHP all'interno di una directory. Ad esempio, sul mio localhost, ho usatoE:\xammp\htdocs\wordpress\wp-includes

  • Quindi eseguiremo il ciclo tra i file e cercheremo e restituiremo ( preg_match_all) tutte le istanze di apply_filterse do_action. L'ho impostato per abbinare istanze nidificate di parentesi e anche per abbinare possibili spazi bianchi tra apply_filters/ do_actione la prima parentesi

Semplicemente creeremo quindi un array con tutti i filtri e le azioni, quindi eseguiremo un ciclo attraverso l'array e genereremo il nome del file, i filtri e le azioni. Salteremo i file senza filtri / azioni

NOTE IMPORTANTI

  • Queste funzioni sono molto costose. Eseguili solo su un'installazione di prova locale.

  • Modificare le funzioni secondo necessità. Puoi decidere di scrivere l'output in un file, creare una pagina di backend speciale per questo, le opzioni sono illimitate

OPZIONE 1

La prima funzione delle opzioni è molto semplice, restituiremo il contenuto di un file come stringa usando file_get_contents, cercheremo le apply_filters/ do_actionistanze e semplicemente invieremo il nome del file e i nomi di filtro / azione

Ho commentato il codice per un facile seguito

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

È possibile utilizzare a seguire su un modello, frontend o backend

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

Questo stamperà

inserisci qui la descrizione dell'immagine

OPZIONE 2

Questa opzione è un po 'più costosa da eseguire. Questa funzione restituisce il numero di riga in cui è possibile trovare il filtro / l'azione.

Qui usiamo fileper esplodere il file in un array, quindi cerchiamo e restituiamo il filtro / azione e il numero di riga

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

È possibile utilizzare a seguire su un modello, frontend o backend

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

Questo stamperà

inserisci qui la descrizione dell'immagine

MODIFICARE

Questo è fondamentalmente tutto ciò che posso fare senza che gli script scadano o esauriscano la memoria. Con il codice nell'opzione 2, è facile come andare a detto file e detta linea nel codice sorgente e quindi ottenere tutti i valori dei parametri validi del filtro / azione, inoltre, soprattutto, ottenere la funzione e l'ulteriore contesto in cui viene utilizzato il filtro / azione


1
hai troppo tempo libero;) ma alla fine non è mai abbastanza sapere quali sono i filtri ma anche quali sono i valori e i risultati dei parametri previsti e questo non può essere ottenuto dalla sorgente senza bactracking per ottenere il blocco doc nel caso di file core e probabilmente non disponibili in plugin e temi non core.
Mark Kaplun,

1
@MarkKaplun è solo qualcosa su cui ho lavorato rapidamente :-). Le funzioni di cui sopra ti dicono almeno dove sono i filtri e le azioni in specifiche directory plugin / temi / core. Resta ancora molto importante tornare alla fonte e assicurarsi di capire cosa fa specificamente un filtro specifico. Alcuni plugin e temi sono scarsamente documentati, quindi avresti ancora bisogno di qualche tipo di conoscenza e background per sapere o capire cosa fa un filtro specifico in una funzione specifica ;-)
Pieter Goosen

@PieterGoosen Sì, di solito sto bene con un salto indietro per vedere la fonte. Se lo sto facendo in primo luogo, significa che il plugin ha hook ma non necessariamente blocchi doc per loro. Ma se guardo dove sono effettivamente utilizzati, mi aiuta a capire se sono preziosi. Ad ogni modo, sembra che potrebbero essere fantastici. Potrei anche modificarli 2 ° per scrivere solo su un file HTML perché poi potrei semplicemente incollare la dichiarazione di funzione in un plugin MU sul server locale ed eseguirlo dalla CLI di WP.
yonatron,

@yonatron Sono contento che i miei due centesimi mi aiutino in qualche modo. Se mai verrai a scrivere la tua modifica dal mio codice, puoi sempre aggiungere il tuo codice e la tua spiegazione come risposta ( che sarà grandiosa ) ;-). Divertiti
Pieter Goosen il

1
Hai scelto quanto tempo hai impiegato per scrivere questa sceneggiatura e per documentare, accidenti è fantastico ***** :)
Webloper

6

Sembra che WP Parser faccia quello che stai cercando. Viene utilizzato per generare il riferimento ufficiale dello sviluppatore . Elenca i parametri, i tag @since e i riferimenti alla fonte. Funziona con tutti i plugin di WordPress ed è accessibile dalla riga di comando:

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

1
Non ho molta familiarità con quello script, ma sembra che abbia bisogno di un filtro o di un'azione per essere ben documentato. Gradirei feedback su questo da @Rarst ;-)
Pieter Goosen

Non l'ho ancora provato, ma in base alla descrizione, penso che la preoccupazione di Pieter sia rivolta al bersaglio. Voglio trovare tutti gli hook, non solo quelli preceduti da blocchi doc ben formattati. Penso che le persone che si prendono il tempo di commentare i loro hook / funzioni usando le convenzioni di WordPress stanno già eseguendo questo tipo di script e pubblicando riferimenti API sui loro siti di supporto. Mi rendo conto che c'è qualche rischio inerente a questo, dal momento che se uno sviluppatore non documenta pubblicamente un filtro, potrebbe essere modificato / deprecato senza preavviso, ma per alcuni plugin che uso, non vedo l'ora che i documenti vengano visualizzati online.
yonatron,

Analizza anche hook non documentati. Esempio: developer.wordpress.org/reference/hooks/graceful_fail
Jan Beck,

4

Il veloce e il furioso

La buona vecchia *nixriga di comando è sempre utile:

# 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

Molte altre opzioni tramite #man grep.

Quindi possiamo persino creare un semplice script bash wp-search.sh:

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

ed eseguirlo con.

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

Uscita piuttosto

Possiamo usare l' --colorattributo per colorare l'output di grep, ma nota che non funzionerà less.

Un'altra opzione sarebbe quella di generare una tabella HTML per i risultati della ricerca.

Ecco un awkesempio che ho creato che genera i risultati della ricerca come tabella HTML nel results.htmlfile:

  | 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

dove ho usato questo trucco per rimuovere tutto lo spazio bianco iniziale e questo per stampare tutti i campi tranne il primo.

Uso sedqui solo per aggiungere spazio extra dopo il secondo punto ( :), nel caso in cui non ci sia spazio lì.

copione

Potremmo aggiungere questo al nostro wp-search.shscript:

#!/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

dove devi adattare /path/to/some/directorye /path/to/results.htmlalle tue esigenze.

Esempio: ricerca di un plug-in

Se proviamo questo sul wordpress-importerplugin con:

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

quindi il results.htmlfile verrà visualizzato come:

risultati

Esempio: ricerca nel core

L'ho testato per il core:

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

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

ed è veloce!

Appunti

Per ottenere un contesto extra, potremmo usare -C NUMBERgrep.

Potremmo modificare l'output HTML in vari modi, ma speriamo che sia possibile adattarlo ulteriormente alle proprie esigenze.


Grazie! Uso grep in un pizzico, ma sono così alle prime armi con roba da guscio che non mi sono nemmeno mai abituato a usare le pipe per OR. L'altra cosa che vorrei aggiungere sono le opzioni per stamparlo un po '. L'output della suddetta linea grep sarà ancora piuttosto difficile da sfogliare.
yonatron,

2
Ho aggiornato la risposta con un esempio di bella stampa @yonatron
birgire
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.