Endpoint PHP personalizzato per chiamate AJAX in un plugin
Sto scrivendo un plugin per la prima volta e ho un problema.
Sto utilizzando AJAX nel mio plugin. Il mio file JavaScript si trova nella cartella ../wp-content/plugins/myplugin/js/
, e in esso sto cercando di chiamare un file PHP che si trova nella cartella ../wp-content/plugins/myplugin/
jQuery.ajax({
url: "/wp-content/plugins/myplugin/myfile.php?myparam=" + myparam,
context: document.body
});
La mia domanda è: Come posso far funzionare questo riferimento URL indipendentemente da dove l'utente ha installato il plugin?
Perché quando ad esempio un utente installa questo plugin in http://localhost/subdir/
, il riferimento non è corretto.
Posso in qualche modo creare un link relativo?

Innanzitutto, non dovresti chiamare il tuo file PHP direttamente. Dovresti utilizzare l'endpoint admin-ajax
. Documentazione
Sul lato admin, puoi usare ajaxurl per ottenere l'URL per le chiamate AJAX. Sul frontend devi dichiarare tu stesso la variabile con l'URL. Questo è scritto nella documentazione:
Nota: A differenza del lato admin, la variabile globale javascript ajaxurl non viene definita automaticamente, a meno che tu non abbia BuddyPress o un altro plugin che fa affidamento su Ajax installato. Quindi invece di affidarti a una variabile globale javascript, dichiara un oggetto namespace javascript con la sua proprietà ajaxurl. Puoi anche usare wp_localize_script() per rendere l'URL disponibile al tuo script, e generarlo usando questa espressione: admin_url( 'admin-ajax.php' )
Questo dovrebbe risolvere il problema:
add_action( 'wp_head', 'front_ajaxurl' );
function front_ajaxurl() {
wp_register_script( 'admin_ajax_front', plugin_dir_url(__FILE__) . 'script.js' );
$translation_array = array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
);
wp_localize_script( 'admin_ajax_front', 'front', $translation_array );
wp_enqueue_script( 'admin_ajax_font', false, array(), false, true ); // l'ultimo parametro impostato a true caricherà lo script nel footer
}
E poi nel tuo file JS:
$.ajax({
url: front.ajaxurl,
...
})

Mescolare codice JavaScript e PHP non è una buona pratica. Come dice la citazione della documentazione, opterei per wp_localize_script()
. Questo garantisce che la variabile sarà definita prima che venga caricato lo script che ne dipende.

Ancora meglio di wp_localize_script()
, puoi usare wp_add_inline_script()
da WordPress 4.5 in poi. Questa funzione permette di stampare script inline all'interno dell'ottimo sistema di gestione delle dipendenze di WordPress, e non è limitata solo a un oggetto JavaScript come wp_add_inline_script()
.

ancora non capisco... non so ancora come devo riferirmi a myfile.php e dove? devo trasformarlo in una funzione o come? per favore dammi un indizio, sono perso

Se hai davvero bisogno di chiamare un file dal tuo plugin puoi farlo con plugin_dir_url(__FILE__)

Sono un principiante, ma questo ha funzionato per me
Aggiungi il seguente codice in functions.php. Nota che 'wp_ajax' è un prefisso per convenzione e 'do_something' è il nome dell'azione che ho scelto arbitrariamente:
add_action( 'wp_ajax_do_something', 'do_something' );
function do_something() {
//davvero, vai avanti, fai qualcosa
die("restituisci qualcosa");
}
Per effettuare la chiamata ajax dal browser (lato client), sono riuscito a trovare il mio endpoint usando wp.ajax.settings.url
. La variabile globale wp
è definita nell'oggetto window.
//do_something qui deve corrispondere a quanto sopra, puoi aggiungere altri parametri a questo oggetto
var data = { action: 'do_something' };
jQuery.post(wp.ajax.settings.url, data, function(response) {
console.log('Risultato: ' + response);
});
Ho WordPress 4.6.1 (l'ultima versione al momento della scrittura) e alcuni plugin installati. Mi sono riferito a questa documentazione che dice erroneamente che ajaxurl è definito, ma nel mio caso non lo è: https://codex.wordpress.org/AJAX_in_Plugins

Ho affrontato lo stesso problema.
Volevo utilizzare il mio endpoint personalizzato invece dell'endpoint admin-ajax perché ho delle regole di rewrite che popolano tutte le variabili necessarie per eseguire le azioni AJAX.
Quindi, utilizzare (come detto nel codex)
jQuery(document).ready(function($) {
var data = {
'action': 'my_action',
'whatever': ajax_object.we_value // Passiamo i valori PHP in modo diverso!
};
jQuery.post(ajax_object.ajax_url, data, function(response) {
alert('Got this from the server: ' + response);
});
});
e
add_action( 'wp_ajax_my_action', 'my_action' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action' );
rende solo il mio codice più complicato.
Alla fine ho fatto così e sembra funzionare:
jQuery.ajax({
type: "post",
url: MYCUSTOMENDPOINT?ajax_action,
dataType: 'json',
...
combinato con:
add_action( 'init', 'rewrite_rules');
add_filter( 'template_include','handle_ajax_action');
function rewrite_rules(){
add_rewrite_tag(
'%ajax_action%',
'([^&]+)'
);
}
function handle_ajax_action($template){
$success = null;
// poiché la variabile di query "ajax" non richiede un valore, dobbiamo verificare la sua esistenza
if ( !$action = get_query_var( 'ajax_action' ) ) return $template; //l'azione ajax non esiste
$result = array(
'input' => $_REQUEST,
'message'=> null,
'success'=> null,
);
$success = ...
if ( is_wp_error($success) ){
$result['success'] = false;
$result['message'] = $success->get_error_message();
}else{
$result['success'] = $success;
}
header('Content-type: application/json');
send_nosniff_header();
header('Cache-Control: no-cache');
header('Pragma: no-cache');
wp_send_json( $result );
}
