Petición de formulario $_POST con admin-post
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.

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.

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

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?

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?

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.

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.

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.

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