Il semble que beaucoup de développeurs de plugins prennent le temps d’ajouter des points d’accès au filtre/action pour permettre aux utilisateurs d’ajuster les fonctionnalités de leurs produits. Ce qui est excellent, mais ce qu’ils ne font souvent pas, c’est de fournir une liste de points d’accroché et le nombre d’arguments qu’ils prennent.
Quelqu'un a-t-il trouvé le meilleur moyen automatisé de pointer sur un répertoire de plugins (ou de thèmes) et d'afficher une liste de tous les hooks disponibles?
Il semblerait que certains plug-ins analysent les points d’accès, mais pour autant que je sache, ils vous indiquent ceux qui sont en train d’être appelés pour afficher une page donnée. Ce que je reçois peut être pratique. Mais parfois, si je sais que je suis en interaction avec un plugin en particulier, je veux savoir chaque endroit où cela peut me laisser accrocher une action ou un filtre.
Donc, ce que je recherche vraiment, c’est quelque chose qui, étant donné le répertoire racine du plugin, créera une liste où chaque élément comprend:
do_action()
ou apply_filter()
) dans le code sourceUn script serait génial, car cela pourrait vraisemblablement bien HTMLifier le tout et me le montrer directement dans l'interface utilisateur de l'administrateur pour chaque plugin. Mais même un script de ligne de commande qui génère un fichier statique utile serait bien.
Je ne connais aucun script ou plug-in pour faire ce que vous voulez. Comme vous l'avez dit, il existe des scripts (voire des variables globales) que vous pouvez utiliser pour imprimer les filtres et les actions en cours d'utilisation.
En ce qui concerne les filtres et les actions en veille, j’ai écrit deux fonctions très basiques (avec un peu d’aide ici et là), qui trouve toutes les instances apply_filters
et do_action
dans un fichier, puis l’affiche
Nous allons utiliser les classes RecursiveDirectoryIterator
, RecursiveIteratorIterator
et RegexIterator
PHP pour obtenir tous les fichiers PHP d'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, puis rechercher et renvoyer (preg_match_all
) toutes les instances de apply_filters
et do_action
. Je l'ai configuré pour correspondre aux instances imbriquées de parenthèses et aux espaces possibles entre apply_filters
/do_action
et la première parenthèse
Nous allons ensuite simplement créer un tableau avec tous les filtres et actions, puis parcourir le tableau et générer le nom du fichier, les filtres et les actions. Nous allons ignorer les fichiers sans filtres/actions
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 de backend spéciale pour cela, les options sont illimitées.
La première fonction d’options est très simple, nous allons renvoyer le contenu d’un fichier sous forme de chaîne en utilisant file_get_contents
, rechercher les instances apply_filters
/do_action
et sortir simplement le nom du fichier et les noms du filtre/action.
J'ai commenté le code pour faciliter le suivi
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 à suivre sur un modèle, frontend ou backend
echo get_all_filters_and_actions( 'E:\xammp\htdocs\wordpress\wp-includes' );
Cela va imprimer
Cette option est un peu plus chère à exécuter. Cette fonction renvoie le numéro de la ligne où se trouve le filtre/l'action.
Ici, nous utilisons file
pour décomposer le fichier dans un tableau, puis nous recherchons et retournons le filtre/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 = ' ';
$output .= '<li>Line reference ' . $line_number . $whitespaces . $string[0] . '</li>';
}
$output .= '</ul>';
}
}
return $output;
}
return false;
}
Vous pouvez utiliser à suivre sur un modèle, frontend ou backend
echo get_all_filters_and_actions2( 'E:\xammp\htdocs\wordpress\wp-includes' );
Cela va imprimer
C’est essentiellement ce que je peux faire sans que les scripts arrivent à expiration ou manquent de mémoire. Avec le code de l’option 2, il est aussi simple d’aller dans le fichier source et dans ladite code puis d’obtenir toutes les valeurs de paramètre valides du filtre/de l’action, mais aussi et surtout de récupérer la fonction et le contexte dans lequel le filtre/action est utilisé
Cela ressemble à WP Parser fait ce que vous cherchez. Il est utilisé pour générer la référence officielle developer . 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>
La bonne vieille ligne de commande *nix
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 script bash simple wp-search.sh
:
#!/bash/bin
grep --line-number \
--exclude-dir=/path/to/some/directory \
--include=*.$1 \
--recursive $2 $3
et le lancer avec.
# bash wp-search.sh php "add_filter\|do_action\|apply_filters" /path/to/some-plugin
Nous pouvons utiliser l'attribut --color
pour coloriser la sortie de grep
, mais notez que cela 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 exemple awk
que j'ai construit et qui génère les résultats de la recherche sous forme de tableau HTML dans le fichier 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
où j’ai utilisé cette astuce pour supprimer tous les blancs et celui-ci pour imprimer tous les champs sauf le premier.
J'utilise sed
ici juste pour ajouter de l'espace après le deuxième point (:
), juste au cas où il n'y aurait plus d'espace.
Nous pourrions ajouter ceci à notre 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
où vous devez ajuster le /path/to/some/directory
et le /path/to/results.html
à vos besoins.
Si nous essayons ceci sur le plugin wordpress-importer
avec:
bash wp-search.sh php "add_filter\|do_action" /path/to/wp-content/plugins/wordpress-importer/
alors le fichier results.html
s'affichera comme suit:
Je l'ai testé pour le coeur:
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!
Pour obtenir un contexte supplémentaire, nous pourrions utiliser le -C NUMBER
de grep.
Nous pouvons modifier la sortie HTML de différentes manières, mais nous espérons pouvoir l’ajuster davantage à vos besoins.