Intentando usar add_action y do_action con parámetros

15 ene 2015, 12:05:27
Vistas: 28.4K
Votos: 9

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);
0
Todas las respuestas a la pregunta 1
3
13

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ón alter_item al gancho de acción admin_menu. Por lo tanto, cuando ocurre la acción admin_menu, se ejecuta la función alter_item. Según el codex, no se pasan parámetros a las funciones adjuntas a admin_menu. Así que los parámetros que intentas usar en alter_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ón alter_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 tu do_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;
    }
} );
15 ene 2015 13:29:16
Comentarios

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

wxT3APyGfkYJVK wxT3APyGfkYJVK
15 ene 2015 13:48:00

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 :)

Hybrid Web Dev Hybrid Web Dev
12 dic 2015 00:57:45

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

cybmeta cybmeta
12 dic 2015 08:43:54