Generar referencias de gancho inactivas

10

Parece que muchos desarrolladores de complementos se toman el tiempo de agregar enlaces de acción / filtro para permitir a los usuarios modificar la funcionalidad de sus productos. Lo que es genial, pero lo que a menudo no hacen es proporcionar una lista de ganchos y la cantidad de argumentos que toman.

¿Alguien ha encontrado la mejor forma automatizada de apuntar a un directorio de plugin (o tema) y ver una lista de todos los ganchos disponibles?

Parezco algunos complementos que buscan enganches, pero por lo que puedo decir, te muestran cuáles están siendo llamados para procesar una página determinada. Lo que recibo puede ser útil. Pero a veces, si sé que estoy interactuando con un complemento en particular, quiero saber en qué lugar me permite conectar una acción o un filtro.

Entonces, lo que realmente estoy buscando es algo que, dado el directorio raíz de un complemento, creará una lista donde cada elemento incluye:

  • etiqueta
  • tipo (acción o filtro)
  • número de argumentos
  • donde se llama (a través de do_action() o apply_filter() ) en la fuente

Una secuencia de comandos sería genial, ya que esto podría presumiblemente muy bien HTML y mostrarlo directamente en la interfaz de usuario de administración para cada complemento. Pero incluso una secuencia de comandos de línea de comandos que genere un archivo estático útil sería excelente.

    
pregunta yonatron 04.10.2015 - 20:42

3 respuestas

6

No hay ningún script o complemento que yo sepa para hacer lo que quieres. Como ha indicado, hay scripts ( incluso variables globales ) que puede usar para imprimir filtros y acciones que se están utilizando actualmente.

En cuanto a los filtros y acciones latentes, escribí dos funciones muy básicas ( con algo de ayuda aquí y allá ) que encuentran todas las instancias apply_filters y do_action en un archivo y luego las imprimen fuera

BÁSICOS

  • Usaremos las clases PHP RecursiveDirectoryIterator , RecursiveIteratorIterator y RegexIterator para obtener todos los archivos PHP dentro de un directorio. Como ejemplo, en mi host local, he usado E:\xammp\htdocs\wordpress\wp-includes

  • Luego recorreremos los archivos y buscaremos y devolveremos ( preg_match_all ) todas las instancias de apply_filters y do_action . Lo he configurado para que coincida con las instancias anidadas de paréntesis y también para que coincida con espacios en blanco posibles entre apply_filters / do_action y el primer paréntesis

Simplemente crearemos una matriz con todos los filtros y acciones y luego recorreremos la matriz y emitiremos el nombre del archivo, los filtros y las acciones. Vamos a saltar archivos sin filtros / acciones

NOTAS IMPORTANTES

  • Estas funciones son muy caras. Ejecutarlos solo en una instalación de prueba local.

  • Modifique las funciones según sea necesario. Puede decidir escribir la salida en un archivo, crear una página especial para eso, las opciones son ilimitadas

OPCIÓN 1

La primera función de opciones es muy simple, devolveremos el contenido de un archivo como una cadena usando file_get_contents , buscaremos las instancias apply_filters / do_action y simplemente mostraremos el nombre de archivo y los nombres de filtro / acción

He comentado el código para un fácil seguimiento

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

Puede utilizar en follow en una plantilla, frontend o backend

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

Esto se imprimirá

OPCIÓN2

Estaopciónesunpocomáscaradeejecutar.Estafuncióndevuelveelnúmerodelíneadondesepuedeencontrarelfiltro/acción.

Aquíusamosfileparaexplotarelarchivoenunamatriz,luegobuscamosydevolvemoselfiltro/acciónyelnúmerodelínea

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

Puedeutilizarenfollowenunaplantilla,frontendobackend

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

Estoseimprimirá

EDITAR

Esto es básicamente todo lo que puedo hacer sin que los scripts se agoten o se queden sin memoria. Con el código en la opción 2, es tan fácil como ir a dicho archivo y dicha línea en el código fuente y luego obtener todos los valores de los parámetros válidos del filtro / acción, además de obtener la función y el contexto adicional en el que Se utiliza el filtro / acción

    
respondido por el Pieter Goosen 07.10.2015 - 10:04
6

Suena como WP Parser hace lo que está buscando. Se utiliza para generar la referencia del desarrollador oficial. Enumera los parámetros, etiquetas @since y referencias a la fuente. Funciona con todos los complementos de WordPress y se puede acceder a través de la línea de comandos:

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

El rápido y el furioso

La línea de comandos good ol ' *nix siempre es ú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

Muchas más opciones a través de #man grep .

Entonces podemos incluso crear un simple script de bash wp-search.sh :

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

y ejecútalo con.

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

Salida bonita

Podemos usar el atributo --color para colorear la salida de grep , pero ten en cuenta que no funcionará con less .

Otra opción sería generar una tabla HTML para los resultados de búsqueda.

Aquí hay un ejemplo de awk que construí que genera los resultados de la búsqueda como una tabla HTML, en el archivo 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

donde utilicé este truco para eliminar todos los espacios en blanco iniciales y this para imprimir todos los campos excepto el primero.

Utilizo sed aquí solo para agregar espacio adicional después de la segunda coma ( : ), en caso de que no haya espacio allí.

Script

Podríamos agregar esto a nuestro 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

donde tiene que ajustar el /path/to/some/directory y /path/to/results.html a sus necesidades.

Ejemplo: búsqueda de un complemento

Si intentamos esto en el complemento wordpress-importer con:

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

entonces el archivo results.html se mostrará como:

Ejemplo-Buscandoelnúcleo

Loprobéporeltiempoparaelnúcleo:

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

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

y es rápido!

Notas

Para obtener un contexto adicional, podemos usar el -C NUMBER de grep.

Podríamos modificar la salida HTML de varias maneras, pero esperamos que puedas ajustar esto más a tus necesidades.

    
respondido por el birgire 07.10.2015 - 12:56

Lea otras preguntas en las etiquetas