Générer des références de crochets dormants

10

Il semble que de nombreux développeurs de plugins prennent le temps d'ajouter des filtres / actions pour permettre aux utilisateurs de modifier les fonctionnalités de leurs produits. Ce qui est génial, mais ce qu'ils ne font souvent pas, c'est de fournir une liste de crochets et le nombre d'arguments qu'ils prennent.

Quelqu'un a-t-il trouvé la meilleure façon automatisée de pointer vers un répertoire de plugins (ou de thèmes) et de voir une liste de tous les hooks disponibles?

J'ai l'impression que certains plugins recherchent des crochets, mais pour autant que je sache, ils vous montrent lesquels sont réellement appelés pour rendre une page donnée. Ce que je reçois peut être pratique. Mais parfois, si je sais que j'interagis avec un plugin particulier, je veux savoir à quel endroit il peut me permettre d'accrocher une action ou un filtre.

Donc ce que je recherche vraiment, c'est que, étant donné un répertoire racine de plugin, il créera une liste où chaque élément comprend:

  • étiquette
  • type (action ou filtre)
  • nombre d'arguments
  • où il est appelé (via do_action()ou apply_filter()) dans la source

Un script serait génial car cela pourrait vraisemblablement joliment HTMLifier le tout et me le montrer directement dans l'interface d'administration pour chaque plugin. Mais même un script de ligne de commande qui génère un fichier statique utile serait génial.

yonatron
la source
Donc quelle est la question? si vous recherchez une recommandation de plugin, c'est hors sujet ici
Mark Kaplun
Désolé, je ne veux pas aller trop loin dans les mauvaises herbes de développement WordPress , mais a) je suis nouveau ici, donc je ne savais pas que demander des recommandations de plugin était OT. J'aurais peut-être… quelques opinions… là-dessus, mais j'aurais quand même dû m'en rendre compte d'abord. b) OTOH, j'essaie juste de trouver une solution à ma question, que ce soit un plugin existant ou un script shell, ou quelque chose à partir de zéro. La question est donc strictement une demande de recommandation de plugin!
yonatron
Eh bien, il semble que tout le monde s'amuse donc pas de mal. Mon "objection" à la question était en fait plus d'être une question d'analyse de texte qui est intéressante pour les gens qui aiment écrire un logiciel de style compilateur mais qui a très peu à voir avec le codage wordpress réel. Pour mémoire, même les questions concernant wordpress.org comme la façon de soumettre un plugin seront généralement votées hors sujet.
Mark Kaplun

Réponses:

6

Il n'y a aucun script ou plugin à ma connaissance pour faire ce que vous voulez. Comme vous l'avez indiqué, il existe des scripts ( même des variables globales ) que vous pouvez utiliser pour imprimer des filtres et des actions actuellement utilisés.

En ce qui concerne les filtres et les actions dormants, j'ai écrit deux fonctions très basiques ( avec une aide ici et là ) qui trouvent tout apply_filterset les do_actioninstances dans un fichier puis l'imprime

LES BASES

  • Nous utiliserons les RecursiveDirectoryIterator, RecursiveIteratorIteratoret les RegexIteratorclasses PHP pour obtenir tous les fichiers PHP dans un répertoire. Par exemple, sur mon hôte local, j'ai utiliséE:\xammp\htdocs\wordpress\wp-includes

  • Nous allons ensuite parcourir les fichiers et rechercher et retourner ( preg_match_all) toutes les instances de apply_filterset do_action. Je l'ai configuré pour correspondre aux instances imbriquées de parenthèses et également pour faire correspondre les espaces blancs possibles entre apply_filters/ do_actionet la première parenthèse

Nous allons simplement créer un tableau avec tous les filtres et actions, puis parcourir le tableau et afficher le nom de fichier et les filtres et actions. Nous ignorerons les fichiers sans filtres / actions

NOTES IMPORTANTES

  • Ces fonctions sont très chères. Exécutez-les uniquement sur une installation de test locale.

  • Modifiez les fonctions selon vos besoins. Vous pouvez décider d'écrire la sortie dans un fichier, créer une page spéciale pour cela, les options sont illimitées

OPTION 1

La première fonction d'options est très simple, nous retournerons le contenu d'un fichier sous forme de chaîne en utilisant file_get_contents, rechercherons les instances apply_filters/ do_actionet sortirons simplement le nom de fichier et les noms de filtre / action

J'ai commenté le code pour un suivi facile

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

Vous pouvez utiliser au suivi sur un modèle, frontend ou backend

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

Cela imprimera

entrez la description de l'image ici

OPTION 2

Cette option est un peu plus coûteuse à exécuter. Cette fonction renvoie le numéro de ligne où le filtre / l'action peut être trouvé.

Ici, nous utilisons filepour exploser le fichier dans un tableau, puis nous recherchons et renvoyons le filtre / l'action et le numéro de ligne

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

Vous pouvez utiliser au suivi sur un modèle, frontend ou backend

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

Cela imprimera

entrez la description de l'image ici

ÉDITER

C'est essentiellement autant que je peux le faire sans que les scripts expirent ou manquent de mémoire. Avec le code de l'option 2, c'est aussi simple que d'aller dans ledit fichier et ladite ligne dans le code source, puis d'obtenir toutes les valeurs de paramètres valides du filtre / de l'action, et aussi, ce qui est important, d'obtenir la fonction et le contexte dans lequel le filtre / action est utilisé

Pieter Goosen
la source
1
vous avez trop de temps libre;) mais au final il ne suffit jamais de savoir quels sont les filtres mais aussi quelles sont les valeurs et résultats attendus des paramètres et cela ne peut pas être obtenu depuis la source sans bactracking pour obtenir le bloc doc au cas où des fichiers core et probablement pas du tout disponible dans les plugins et thèmes non core.
Mark Kaplun
1
@MarkKaplun c'est juste quelque chose sur lequel j'ai rapidement travaillé :-). Les fonctions ci-dessus vous indiquent au moins où se trouvent les filtres et les actions dans des répertoires spécifiques de plugin / thème / noyau. Il est toujours très important de revenir à la source et de vous assurer de bien comprendre en quoi consiste un filtre spécifique. Certains plugins et thèmes sont mal documentés, vous aurez donc besoin de connaissances et de connaissances pour savoir ou comprendre ce que fait un filtre spécifique dans une fonction spécifique ;-)
Pieter Goosen
@PieterGoosen Oui, je suis généralement d'accord pour revenir en arrière pour regarder la source. Si je fais cela en premier lieu, cela signifie que le plugin a des crochets mais pas nécessairement des blocs doc pour eux. Mais si je regarde où ils sont réellement utilisés, cela m'aide à déterminer s'ils ont une valeur. Quoi qu'il en soit, ils semblent pouvoir être formidables. Je pourrais même les modifier 2e pour simplement écrire dans un fichier HTML parce que je pourrais simplement coller la déclaration de fonction dans un plugin MU sur le serveur local et l'exécuter à partir de WP CLI.
yonatron
@yonatron Heureux que mes deux cents m'aident d'une manière ou d'une autre. Si jamais vous venez écrire votre propre modification à partir de mon code, vous pouvez toujours ajouter votre code et votre explication comme réponse ( ce qui sera génial ) ;-). Profitez
Pieter Goosen
1
@PieterGoosen combien de temps vous avez pris pour écrire ce script ainsi que pour documenter, ça alors c'est génial ***** :)
Webloper
6

On dirait que WP Parser fait ce que vous cherchez. Il est utilisé pour générer la référence officielle du développeur . Il répertorie les paramètres, les balises @since et les références à la source. Il fonctionne avec tous les plugins WordPress et est accessible via la ligne de commande:

wp parser create /path/to/source/code --user=<id|login>
Jan Beck
la source
1
Je ne connais pas très bien ce script, mais il semble qu'il ait besoin d'un filtre ou d'une action pour être bien documenté. J'apprécierais les commentaires à ce sujet de @Rarst ;-)
Pieter Goosen
Je ne l'ai pas encore essayé, mais sur la base de la description, je pense que la préoccupation de Pieter est à la hauteur. Je veux trouver tous les crochets, pas seulement ceux précédés de blocs doc bien formatés. Je pense que les gens qui prennent le temps de commenter leurs crochets / fonctions en utilisant les conventions WordPress exécutent déjà ce type de script et publient des références d'API sur leurs sites de support. Je me rends compte qu'il y a un risque inhérent à cela, car si un développeur ne documente pas publiquement un filtre, il pourrait être modifié / obsolète sans avertissement, mais pour certains plugins que j'utilise, je ne peux pas attendre que les documents apparaissent en ligne.
yonatron
Il analyse également les crochets non documentés. Exemple: developer.wordpress.org/reference/hooks/graceful_fail
Jan Beck
4

Le rapide et le furieux

La bonne *nixligne de commande est toujours pratique:

# 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

Beaucoup plus d'options via #man grep.

Ensuite, nous pouvons même créer un simple script bash wp-search.sh:

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

et exécutez-le avec.

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

Jolie sortie

Nous pouvons utiliser l' --colorattribut pour coloriser la sortie de grep, mais notez qu'il ne fonctionnera pas avec less.

Une autre option serait de générer un tableau HTML pour les résultats de la recherche.

Voici un awkexemple que j'ai construit qui produit les résultats de la recherche sous forme de tableau HTML, dans le results.htmlfichier:

  | 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

où j'ai utilisé cette astuce pour supprimer tous les espaces blancs de tête et celle-ci pour imprimer tous les champs sauf le premier.

J'utilise sedici juste pour ajouter de l'espace supplémentaire après le deuxième deux-points ( :), juste au cas où il n'y aurait pas d'espace là-bas.

Scénario

Nous pourrions ajouter ceci à notre 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

où vous devez ajuster le /path/to/some/directoryet /path/to/results.htmlà vos besoins.

Exemple - Recherche d'un plugin

Si nous essayons ceci sur le wordpress-importerplugin avec:

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

alors le results.htmlfichier s'affichera comme:

résultats

Exemple - Recherche dans le noyau

Je l'ai testé pour le noyau:

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

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

et c'est rapide!

Remarques

Pour obtenir un contexte supplémentaire, nous pourrions utiliser le -C NUMBERgrep.

Nous pourrions modifier la sortie HTML de diverses manières, mais j'espère que vous pourrez l'ajuster davantage à vos besoins.

Birgire
la source
Merci! J'utilise grep à la rigueur, mais je suis tellement novice dans les trucs shell que je n'ai même jamais utilisé les tuyaux pour OR. L'autre chose que je voudrais ajouter, ce sont des options pour l'imprimer un peu. La sortie de la ligne grep ci-dessus sera encore assez difficile à parcourir.
yonatron
2
J'ai mis à jour la réponse avec un exemple de jolie impression @yonatron
birgire