Petición de formulario $_POST con admin-post

4 feb 2015, 16:14:38
Vistas: 40.5K
Votos: 18

Intenté usar un formulario con el siguiente markup usando la acción admin-post.php

<form method='post' action='admin-post.php'>

Estoy usando el hook de acción sugerido por WordPress para procesar los parámetros $_POST y funciona bien. Sin embargo, después de la ejecución obtengo una página en blanco y no hay redirección de vuelta a la página de plugins. Por supuesto, podría establecer una redirección personalizada con el referer, pero ¿es ese el comportamiento normal?

Una solución alternativa es usar action="" y obtener la petición en mi código normal del plugin.

4
Comentarios

Si usas admin-post.php y la acción admin_post necesitas redirigir de vuelta a la página de tu plugin.

cybmeta cybmeta
4 feb 2015 20:15:04

Esa información debería añadirse al codex. No estaba seguro de esto.

Rubberducker Rubberducker
5 feb 2015 10:46:53

Si envías el formulario a admin-post.php, admin-post.php es donde va el usuario. Solo revisa el contenido de ese archivo para ver que no imprime nada, solo verifica la cookie de autenticación y ejecuta las funciones enganchadas a admin_init primero y a admin_post después.

cybmeta cybmeta
5 feb 2015 10:59:36

wp_redirect no funciona al enviar formularios con admin-post. Generará un error indicando que las cabeceras ya fueron enviadas, por lo que parece ser un método inútil para enviar un formulario e intentar redirigir a algún lugar después.

Solomon Closson Solomon Closson
2 dic 2016 09:26:22
Todas las respuestas a la pregunta 3
5
27

Tal vez un poco tarde, pero me encontré con esto cuando tenía problemas para entenderlo, así que pensé en compartir lo que descubrí para futuras personas.

He descubierto que los principios básicos son tener un input oculto llamado action y que su valor sea un identificador personalizado. Por ejemplo:

<input name='action' type="hidden" value='custom_form_submit'>

Con este input, y con el action de tu formulario apuntando a admin-post.php, se puede configurar una acción. Configuramos esta acción usando admin_post_custom_form_submit.

Para hacer las cosas más complicadas, podemos usar un wp_nonce_field, que creo que es una medida de seguridad básica. Básicamente, añade un valor aleatorio en $_POST. Justo.

Luego queremos configurar nuestra acción así:

add_action('admin_post_custom_form_submit','our_custom_form_function');

Así que cuando se envíe un formulario a admin-post.php y haya un valor de acción llamado custom_form_submit, ¡se llamará a la función our_custom_form_function! :D

function our_custom_form_function(){
    //print_r($_POST);
    //aquí puedes acceder a los valores de $_POST, $GET y $_REQUEST.
    wp_redirect(admin_url('admin.php?page=your_custom_page_where_form_is'));
   //aparentemente, al terminar, se requiere die();.
}

Ahora dices que obtienes una página en blanco. Esto es porque necesitamos redirigir de vuelta a nuestro formulario. He usado un simple wp_redirect().

Espero que esto haya ayudado :) Voy a intentar averiguar cómo puedo hacer alguna validación y devolver errores a nuestro formulario de redirección. Creo que la idea más simple sería crear un valor $_GET y buscarlo en nuestra página, pero no es genial, ¿verdad?

También he descubierto que una vez enviado, ¡$_POST se borra! DX Esto probablemente tenga que ver con la redirección. Voy a buscar en Google a ver qué encuentro :d

Espero que esto haya ayudado :)

ACTUALIZACIÓN

Hice un poco más de trabajo y me di cuenta de que la única forma real de devolver valores es usar la variable $_GET. De esta manera, puedes volver a ingresar cualquier valor de post. Solo no olvides usar urlencode() para asegurarte de que los caracteres especiales como '@' y demás se incluyan.

Tenía más de una página con lo que estaba trabajando, así que hice 2 redirecciones diferentes a las diferentes páginas e incluí los errores, etc. Luego los verifiqué encima de mi formulario.

Otra función útil: http_build_query() puede convertir arrays en arrays 'seguros para URL' para que puedas enviarlos a través de solicitudes $_GET, etc.

7 sept 2015 13:44:07
Comentarios

Hola hermano, gracias, ¡esto funciona para mí..! pero hay un problema, ¿cómo puedo establecer el error en admin.php?page=your_custom_page_where_form_is? Usé add_settings_error() para mostrar el error, pero no muestra ningún error porque la página se redirige..! ¿Puedes ayudarme con eso..?

Gracias

Bhavik Hirani Bhavik Hirani
2 sept 2017 09:23:06

Hola @BhavikHirani, ya no uso WordPress realmente, pero supongo que necesitas hacer tu validación antes de la llamada a la función wp_redirect y tener una declaración if para indicar que tu validación pasó antes de redirigir. ¿Espero que esto ayude?

bashleigh bashleigh
4 sept 2017 11:12:02

Después del envío del formulario, quiero mostrar un mensaje de éxito en 'admin.php?page=your_custom_page_where_form_is'. ¿Cómo es posible?

Rijo Rijo
24 mar 2018 04:48:41

@Rijo ¿probaste con echo?

bashleigh bashleigh
26 mar 2018 11:54:43

Cada método tiene sus propios casos de uso. Este método pasa datos en la URL a través de $_GET. Esto estaría bien para información básica, como mostrar su nombre o correo electrónico, o para pasar una bandera ?success=true que active tu mensaje de éxito. Sin embargo, no funcionará para devolver grandes cantidades de datos del envío del formulario, por ejemplo, si envían el formulario y este devuelve datos de una API.

CyberPunkCodes CyberPunkCodes
24 ene 2020 22:06:03
1

Antes de redirigir, puedes guardar cualquier error de validación y los valores del formulario en un transitorio. Estos valores persistirán después de la redirección de la URL.

Esto es exactamente cómo lo hace el núcleo de WordPress para la API de Configuración cuando devuelve errores.

Entonces:

- Validar los datos del formulario

- Almacenar los datos del formulario en un transitorio con set_transient()

- Almacenar cualquier error en un transitorio

- Redirigir a la salida del formulario

- Verificar si hay errores en el transitorio

- Cargar los valores del formulario desde el transitorio

Podrías usar una sesión o la API de Opciones en lugar de un transitorio.

Ahora, he estado experimentando con varias formas de manejar los envíos de formularios tanto en el frontend como en el administrador. No estoy seguro de que admin_post_{action} sea tan conveniente debido a la necesidad de persistir datos y errores a través de la redirección. Usar el hook init o admin_init para verificar un envío de formulario podría ser más fácil. También podrías simplemente enviar tu formulario de vuelta a la misma página y procesar el envío antes de que se muestre el formulario.

22 sept 2015 07:14:54
Comentarios

Nota: set_transient() tiene una longitud máxima de 172 caracteres. Esta es una opción plausible si no puedes o no quieres usar variables GET y no es mucha data. Hasta donde sé, WordPress no usa sesiones (por defecto) así que para un plugin, esto puede ser inapropiado. La API de Opciones sería una terrible elección. -- La opción final si necesitas acceder a una API y devolver una gran cantidad de datos, es hacer un POST al sitio/página misma. -- El admin-post.php es limitado y probablemente no sea la elección correcta si necesitas devolver una gran cantidad de datos.

CyberPunkCodes CyberPunkCodes
24 ene 2020 22:14:46
1

La respuesta corta es que tienes que hacer todo el trabajo: guardar la entrada del usuario en la base de datos, verificar si hay errores o éxito, y redirigir a donde quieras cuando hayas terminado.

Si deseas redirigir al formulario nuevamente, puedes usar un campo generado por wp_nonce() incluido en el arreglo $_POST enviado por tu formulario: $_POST['_wp_http_referer']

Finalmente puedes redirigir y enviar un mensaje de éxito o error usando wp_safe_redirect(), esc_url_raw() y add_query_arg().

add_action( 'admin_post_my-action', 'my_save_form_function' );
add_action( 'admin_post_nopriv_my-action', 'my_save_form_function' );
function my_save_form_function() {
    if ( ! empty( $_POST['_wp_http_referer'] ) ) {
        $form_url = esc_url_raw( wp_unslash( $_POST['_wp_http_referer'] ) );
    } else {
        $form_url = home_url( '/' );
    }
    if ( isset( $_POST['name'] )
        && isset( $_POST['description'] )
        && isset( $_POST['my-nonce'] )
        && wp_verify_nonce(
            sanitize_text_field( wp_unslash( $_POST['my-nonce'] ) ),
            'my-action'
        )
        ) {

        // Guarda los datos de tu formulario...

        // ¿Todo funcionó correctamente?
        wp_safe_redirect(
            esc_url_raw(
                add_query_arg( 'my_status', 'success', $form_url )
            )
        );
        exit();
    } else {
        wp_safe_redirect(
            esc_url_raw(
                add_query_arg( 'my_status', 'error', $form_url )
            )
        );
        exit();
    }
}
10 dic 2019 10:28:25
Comentarios

redirigiéndome a wp-admin/admin-post.php?my_status=success en lugar de a la página del formulario de origen. No funciona correctamente

Himanshu Bansal Himanshu Bansal
2 jun 2021 15:19:08