Richiesta del form $_POST con admin-post
Ho provato a utilizzare un form con il seguente markup usando l'action admin-post.php
<form method='post' action='admin-post.php'>
Sto utilizzando l'hook action suggerito da WordPress per elaborare i parametri $_POST e funziona correttamente. Tuttavia dopo l'esecuzione ottengo una pagina vuota e nessun redirect alla pagina dei plugin. Naturalmente potrei impostare un redirect personalizzato con il referer, ma è questo il comportamento normale?
Un workaround è usare action=""
e gestire la richiesta nel codice normale del plugin.

Forse un po' in ritardo, ma mi sono imbattuto in questo mentre avevo problemi a capirlo, quindi ho pensato di condividere ciò che ho scoperto per aiutare altre persone in futuro.
Ho scoperto che i principi di base consistono nell'avere un input nascosto chiamato action
con un valore personalizzato come identificatore. Ad esempio:
<input name='action' type="hidden" value='custom_form_submit'>
Con questo input e il tuo form che punta a admin-post.php
, puoi impostare un'azione. Definiamo questa azione usando admin_post_custom_form_submit
.
Per complicare le cose, possiamo usare un wp_nonce_field
, che penso sia una misura di sicurezza di base. Fondamentalmente aggiunge un valore casuale in $_POST. Giusto così.
Poi vogliamo impostare la nostra azione in questo modo:
add_action('admin_post_custom_form_submit','our_custom_form_function');
Quindi, quando un form viene inviato a admin-post.php
e c'è un valore action
uguale a custom_form_submit
, la funzione our_custom_form_function
verrà chiamata! :D
function our_custom_form_function(){
//print_r($_POST);
//qui puoi accedere ai valori $_POST, $_GET e $_REQUEST.
wp_redirect(admin_url('admin.php?page=your_custom_page_where_form_is'));
//a quanto pare, quando finisci, è richiesto die();
}
Ora dici che ottieni una pagina bianca. Questo perché dobbiamo reindirizzare di nuovo al nostro form. Ho usato un semplice wp_redirect()
.
Spero che questo sia stato utile :) Proverò a capire come posso fare qualche validazione e restituire errori al nostro form di reindirizzamento. Penso che l'idea più semplice sia creare un valore $_GET
e cercarlo nella nostra pagina, ma non è il massimo, vero?
Ho anche scoperto che una volta inviato, $_POST
viene cancellato!! DX Probabilmente è dovuto al reindirizzamento. Farò una ricerca e vedrò cosa posso trovare :d
Spero che questo sia stato utile :)
AGGIORNAMENTO
Ho fatto ulteriori ricerche e ho capito che l'unico modo per restituire valori è usare la variabile $_GET. In questo modo puoi reinserire i valori del post. Basta non dimenticare di usare urlencode()
per assicurarti che caratteri speciali come '@' e simili vengano inclusi.
Avevo più di una pagina nel mio lavoro, quindi ho usato due reindirizzamenti diversi verso pagine diverse e ho incluso gli errori. Poi li ho verificati sopra il mio form.
Un'altra funzione utile: http_build_query()
può trasformare array in stringhe 'url-safe' in modo da poterle inviare tramite richieste $_GET, ecc.

Ciao fratello, grazie, questa soluzione funziona per me..!
ma c'è un problema, come posso impostare l'errore su admin.php?page=your_custom_page_where_form_is
ho usato add_settings_error()
per visualizzare l'errore ma non mostra alcun errore perché la pagina viene reindirizzata..!
puoi aiutarmi per favore..?
grazie

Ciao @BhavikHirani, non uso più molto WordPress, ma credo che tu debba fare la tua validazione prima della chiamata alla funzione wp_redirect e avere un'istruzione if per verificare che la validazione sia passata prima di reindirizzare. Spero che questo ti aiuti?

dopo l'invio del modulo voglio mostrare un messaggio di successo in 'admin.php?page=your_custom_page_where_form_is' come è possibile?

Ogni metodo ha i suoi casi d'uso specifici. Questo metodo passa i dati nell'URL tramite $_GET
. Potrebbe andare bene per alcune informazioni di base, come mostrare il nome o l'email, o per passare un flag ?success=true
che attiva il messaggio di successo. Tuttavia, non funzionerà per restituire grandi quantità di dati dall'invio del form, ad esempio se l'utente invia il form e questo restituisce dati da un'API.

Prima di reindirizzare, puoi salvare eventuali errori di validazione e i valori del post in un transient. Questi valori persisteranno dopo il reindirizzamento dell'URL.
Questo è esattamente come il core di WordPress lo gestisce per la Settings API quando restituisce errori.
Quindi:
- convalida i dati del form
- memorizza i dati del post in un transient con set_transient()
- memorizza eventuali errori in un transient
- reindirizza all'output del form
- controlla gli errori nel transient
- carica i valori del post nei campi del form dal transient
Potresti usare una sessione o l'Options API invece di un transient.
Ora, ho sperimentato vari modi per gestire l'invio di form sia nel frontend che nell'admin. Non sono sicuro che admin_post_{action} sia così conveniente a causa della necessità di mantenere i dati e gli errori durante il reindirizzamento. Usare l'hook init o admin_init per verificare un invio di form potrebbe essere più semplice. Potresti anche semplicemente inviare il form alla stessa pagina ed elaborare l'invio prima che il form venga visualizzato.

Nota: set_transient()
ha una lunghezza massima di 172 caratteri. Questa è un'opzione plausibile se non puoi o non vuoi usare variabili GET e non si tratta di molti dati. Per quanto ne so, WordPress non utilizza sessioni (di default) quindi per un plugin, potrebbe non essere appropriato. L'API delle opzioni sarebbe una scelta terribile. -- L'opzione finale, se hai bisogno di accedere a un'API e restituire una grande quantità di dati, è effettuare una POST direttamente al sito/pagina stessa. -- Il file admin-post.php
è limitato e probabilmente non è la scelta giusta se devi restituire una grande quantità di dati.

La risposta breve è che devi fare tutto il lavoro: salvare l'input dell'utente nel database, verificare eventuali errori o successi e reindirizzare dove vuoi una volta terminato.
Se vuoi reindirizzare nuovamente al modulo puoi utilizzare un campo generato da wp_nonce()
incluso nell'array $_POST
inviato dal tuo modulo: $_POST['_wp_http_referer']
Infine puoi reindirizzare e inviare un messaggio di successo o errore utilizzando wp_safe_redirect()
, esc_url_raw()
e 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'
)
) {
// Salva i dati del tuo modulo...
// Tutto funziona correttamente?
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();
}
}
