Intentando usar add_action y do_action con parámetros
En el archivo functions.php de mi tema estoy intentando agregar una función con parámetros (como prueba para ver si funciona, no por la funcionalidad) y simplemente no funciona.
Los parámetros siempre llegan vacíos incluso si llamo a do_action con los parámetros en cola como se sugiere en esta página del codex.
function alter_item ($user, $items, $action) {
global $current_user, $menu;
get_currentuserinfo();
switch ($action) {
case false:
if ($current_user->user_login == $user) {
remove_menu_page ($items);
}
break;
case true:
if ($current_user->user_login == $user) {
remove_menu_page ($items);
}
break;
}
}
add_action( 'admin_menu', 'alter_item', 10, 3 );
do_action('alter_item', 'my-user', 'plugins.php', false);
Lo estás usando incorrectamente.
add_action
: adjunta una función a un gancho de acción. En tu código, estás adjuntando la funciónalter_item
al gancho de acciónadmin_menu
. Por lo tanto, cuando ocurre la acciónadmin_menu
, se ejecuta la funciónalter_item
. Según el codex, no se pasan parámetros a las funciones adjuntas aadmin_menu
. Así que los parámetros que intentas usar enalter_item
no son válidos.do_action
: invoca todas las funciones adjuntas a un gancho de acción. En tu código, estás invocando todas las funciones adjuntas al gancho de acciónalter_item
.alter_item
sería un gancho de acción personalizado, ya que no está en el núcleo de WP, pero actualmente en tu código no hay ninguna función adjunta a esta acción, por lo que no pasará nada con tudo_action('alter_item'...
.
La forma correcta de adjuntar una función a admin_menu
es:
function alter_item() {
//Haz lo que necesites
}
//El argumento de prioridad (10 en el código de abajo) es opcional.
add_action( 'admin_menu', 'alter_item', 10 );
La forma correcta de definir acciones personalizadas:
do_action('alter_item', 'mi-usuario', 'plugins.php', false);
Luego puedes adjuntar funciones a la acción alter_item
así:
add_action( 'alter_item', 'funcion_adjunta_alter_item', 10, 3 );
function funcion_adjunta_alter_item( $usuario, $items, $accion ) {
//Ahora $usuario, $items y $accion serán 'mi-usuario', 'plugins.php' y false
}
Si deseas pasar información a acciones del núcleo, puedes:
- usar los parámetros válidos para cada acción. Consulta la documentación oficial de cada acción.
- definir variables globales, usar opciones, transitorios o propiedades/métodos de objetos personalizados, para usar esa información en diferentes partes de tu código. Ejemplo.
- Usar funciones anónimas de PHP con la palabra clave
use
.
Ejemplo usando la palabra clave use
:
$usuario = 'mi-usuario';
$items = 'plugins.php';
$accion = false;
add_action( 'admin_menu', function() use ($usuario, $items, $accion) {
global $current_user, $menu;
get_currentuserinfo();
switch ($accion) {
case false:
if ($current_user->user_login == $usuario) {
remove_menu_page ($items);
}
break;
case true:
if ($current_user->user_login == $usuario) {
remove_menu_page ($items);
}
break;
}
} );

¡VAYA! Eso es mucho más complicado de lo que imaginaba, pero tiene un 100% de sentido, ¡gracias cybmeta!

Voto negativo, porque las llamadas a funciones anónimas mediante action_hooks no se pueden desenganchar. Esto es una muy mala práctica, ya que significa que otros no pueden eliminar/anular la llamada. Los action hooks SIEMPRE deberían hacerse correctamente.
Ejemplo:
add_action('some_action_hook', 'some_function'); // Esto es correcto y puede eliminarse mediante remove_action().
add_action('admin_menu', function() { // cosas }); // esto es incorrecto, porque ahora no hay forma de usar remove_action para eliminar este comportamiento.
En realidad, este método es simplemente vago y descuidado, y no hay una razón válida real para necesitar usarlo, aparte de ser perezoso :)

No estoy de acuerdo contigo. Puede haber situaciones en las que el uso de funciones anónimas enganchadas a acciones y filtros esté totalmente justificado. Además, debes saber que las funciones anónimas SÍ se pueden desenganchar (de una manera muy sucia, lo admito). De todos modos, era solo un ejemplo de las muchas posibilidades que mencioné (variables globales, opciones, transients, propiedades de objetos, ...). Lee de nuevo la respuesta con más atención, no seas vago al leer ;)
