¿Dónde puedo encontrar una lista de hooks de WordPress?
¿Dónde puedo encontrar una lista de todos los hooks de WordPress y funciones anulables (pluggable, scriptable, etc)?
Edición: El plugin está listado aquí.
@Arlen: Como señala Keith S, La Lista de Hooks de Adam Brown es el recurso de facto para los hooks de WordPress. Sin embargo, no es perfecta:
- No muestra los hooks en el orden en que son llamados,
- No proporciona el nombre del archivo ni el número de línea donde se invocan,
- No indica la cantidad de argumentos pasados,
- No es una lista completa porque algunos hooks pueden llamarse dinámicamente,
- Y no muestra hooks de plugins.
Así que, aunque la lista de Adam es un gran recurso, especialmente para entender cuándo se añadieron históricamente los hooks, no es tan útil como si pudieras instrumentar los hooks en cualquier página de tu propio sitio.
He estado jugando con esta idea por un tiempo, así que tu pregunta me motivó a escribir un plugin llamado "Instrument Hooks for WordPress". Puedes encontrar el código fuente completo debajo de la captura de pantalla y también puedes descargarlo desde gist aquí.
Aquí tienes una captura de pantalla de cómo se ve la instrumentación:
Puedes activar la instrumentación usando el parámetro de URL instrument=hooks
, es decir:
Y como prometí, aquí está el código fuente (o descárgalo aquí):
<?php
/*
Plugin Name: Instrument Hooks for WordPress
Description: Instrumenta Hooks para una Página. Muestra la salida durante el Hook de Shutdown.
Version: 0.1
Author: Mike Schinkel
Author URI: http://mikeschinkel.com
*/
if ($_GET['instrument']=='hooks') {
add_action('shutdown','instrument_hooks');
function instrument_hooks() {
global $wpdb;
$hooks = $wpdb->get_results("SELECT * FROM wp_hook_list ORDER BY first_call");
$html = array();
$html[] = '<style>#instrumented-hook-list table,#instrumented-hook-list th,#instrumented-hook-list td {border:1px solid gray;padding:2px 5px;}</style>
<div align="center" id="instrumented-hook-list">
<table>
<tr>
<th>Primera Llamada</th>
<th>Nombre del Hook</th>
<th>Tipo de Hook</th>
<th>Núm. Args</th>
<th>Llamado Por</th>
<th>Línea #</th>
<th>Nombre Archivo</th>
</tr>';
foreach($hooks as $hook) {
$html[] = "<tr>
<td>{$hook->first_call}</td>
<td>{$hook->hook_name}</td>
<td>{$hook->hook_type}</td>
<td>{$hook->arg_count}</td>
<td>{$hook->called_by}</td>
<td>{$hook->line_num}</td>
<td>{$hook->file_name}</td>
</tr>";
}
$html[] = '</table></div>';
echo implode("\n",$html);
}
add_action('all','record_hook_usage');
function record_hook_usage($hook){
global $wpdb;
static $in_hook = false;
static $first_call = 1;
static $doc_root;
$callstack = debug_backtrace();
if (!$in_hook) {
$in_hook = true;
if ($first_call==1) {
$doc_root = $_SERVER['DOCUMENT_ROOT'];
$results = $wpdb->get_results("SHOW TABLE STATUS LIKE 'wp_hook_list'");
if (count($results)==1) {
$wpdb->query("TRUNCATE TABLE wp_hook_list");
} else {
$wpdb->query("CREATE TABLE wp_hook_list (
called_by varchar(96) NOT NULL,
hook_name varchar(96) NOT NULL,
hook_type varchar(15) NOT NULL,
first_call int(11) NOT NULL,
arg_count tinyint(4) NOT NULL,
file_name varchar(128) NOT NULL,
line_num smallint NOT NULL,
PRIMARY KEY (first_call,hook_name))"
);
}
}
$args = func_get_args();
$arg_count = count($args)-1;
$hook_type = str_replace('do_','',
str_replace('apply_filters','filter',
str_replace('_ref_array','[]',
$callstack[3]['function'])));
$file_name = str_replace($doc_root,'',$callstack[3]['file']);
$line_num = $callstack[3]['line'];
$called_by = $callstack[4]['function'];
$wpdb->query("INSERT wp_hook_list
(first_call,called_by,hook_name,hook_type,arg_count,file_name,line_num)
VALUES ($first_call,'$called_by()','$hook','$hook_type',$arg_count,'$file_name',$line_num)");
$first_call++;
$in_hook = false;
}
}
}

Yo... es una de esas cosas que quizás solo uses una o dos veces, pero cuando la usas, le das las gracias a las estrellas por ello :)

¡Mike, eso es genial! Pero, ¿qué recomendarías para entender realmente lo que hace cada filtro/acción? ¿Hay algún archivo donde estén listados todos junto con su 'actividad'? ¡Gracias!

@Amit - Sí, esa es la pregunta difícil. :) Gracias por preguntar. Desafortunadamente, no veo ninguna forma de automatizar eso como hice para listar los hooks anteriormente, así que no tengo una respuesta perfecta para ti. Idealmente, para cada hook alguien escribiría una gran publicación de blog (o haría una pregunta aquí que obtuviera una gran respuesta) y entonces "Googlearlo" sería tu respuesta. Tal como está, yo uso un IDE de depuración (PhpStorm+XDEBUG, US$49 hasta septiembre de 2010) y establezco puntos de interrupción y solo sigo el rastro del código en ejecución. ¡Puede que haya una mejor manera, y si alguien más ha pensado en ella, por favor háznoslo saber!

@Mike: Una pregunta rápida, ¿por qué lo almacenas en la base de datos en lugar de en memoria o en un flujo temporal?

@hakre - ¡Buena pregunta! Cuando comencé a escribir el plugin, imaginé que recopilaría información sobre hooks a través de múltiples cargas de página. Después de terminar la implementación, me di cuenta de que sería más útil hacerlo solo para cada carga de página, pero ya lo tenía escribiendo en una tabla de la base de datos. Consideré cambiarlo, pero me preocupaba que pudiera consumir demasiada memoria (probablemente no era una preocupación válida, pero de todos modos...). Así que sí, usar memoria sería una alternativa y probablemente una forma preferida de hacerlo. ¿Quieres hacer la actualización por mí? ¡WA se trata de participación positiva! :-)

@drtanz - No tiene relación con el front end vs. administrador. Debería funcionar en cualquier carga de página.

Como pequeña sugerencia. El plugin Debug Objects tiene la lista de todos los hooks y los hooks de la página actual como característica.

Muestra una lista de acciones ejecutadas para la solicitud actual. Requiere el plugin debug bar.

También está el Complemento Debug Bar Actions and Filters y el Debug Bar Hook Log.

El Codex tiene una Referencia de Acciones y una Referencia de Filtros. Adam Brown creó una base de datos de hooks que contiene todos los hooks en el código fuente, y añade la documentación de las páginas wiki, información de versión y enlaces al código fuente. Puedes mejorarla escribiendo documentación en el Codex.
Por supuesto, algunos hooks son dinámicos, dependiendo de otros datos. Tomemos la función wp_transition_post_status
:
function wp_transition_post_status($new_status, $old_status, $post) {
do_action('transition_post_status', $new_status, $old_status, $post);
do_action("${old_status}_to_$new_status", $post);
do_action("${new_status}_$post->post_type", $post->ID, $post);
}
Si registras un tipo de entrada personalizado event
y un estado de publicación personalizado cancelled
, tendrás un hook de acción cancelled_event
.

Aunque primitivo, quizás este código de plugin pueda ayudar? Cambia "add_action" por "add_filter" si prefieres examinar filtros en lugar de acciones. Activa el plugin y luego actualiza la página principal del sitio. Una vez cargado, es muy difícil desactivarlo, así que simplemente renombra el archivo del plugin en la carpeta de plugins y actualiza el sitio nuevamente — se desactivará automáticamente. He usado este truco muchas veces para resolver problemas o encontrar un lugar donde insertar algo.
<?php
/*
Plugin Name: Hooks
Plugin URI: http://example.com/
Description: Hooks
Version: 1.00
Author: Hooks
Author URI: http://example.com/
*/
add_action('all','hook_catchall');
function hook_catchall(&$s1 = '', &$s2 = '', &$s3 = '', &$s4 = '') {
echo "<h1>1</h1>\n";
print_r($s1);
echo "<br />\n";
echo "<h1>2</h1>\n";
print_r($s2);
echo "<br />\n";
echo "<h1>3</h1>\n";
print_r($s3);
echo "<br />\n";
echo "<h1>4</h1>\n";
print_r($s4);
echo "<br />\n";
return $s1;
}

Utilizo esto para encontrar el orden de los hooks. Para obtener los filters
simplemente cambia add_action
por add_filter
.
function echo_all_hooks() {
$not_arr = array('gettext','sanitize_key','gettext_with_context','attribute_escape');
if(!in_array(current_filter(),$not_arr)) echo current_filter()."<br/>";
}
add_action('all','echo_all_hooks');

Como sugiere @kaiser, no publiques solo enlaces, lo estoy mejorando. Pero no es posible usar todo el código aquí, así que estoy usando algunas imágenes para explicar cómo tener una lista completa de los hooks de WordPress con una descripción de cada uno. Puedes encontrarlo aquí para hooks, clases, funciones, plugins,
para describir cada uno

Puedes utilizar un plugin de monitor de consultas: https://wordpress.org/plugins/query-monitor/
