Endpoint PHP personalizzato per chiamate AJAX in un plugin

27 lug 2016, 11:57:39
Visualizzazioni: 13.6K
Voti: 4

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?

0
Tutte le risposte alla domanda 3
5

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,
    ...
})
27 lug 2016 12:03:51
Commenti

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.

David David
27 lug 2016 12:16:36

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().

cybmeta cybmeta
27 lug 2016 12:25:37

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

user3199063 user3199063
27 lug 2016 14:02:41

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

Krzysztof Grabania Krzysztof Grabania
27 lug 2016 14:28:44

ho bisogno di chiamare myfile.php nel mio js come ho mostrato nella domanda, ovviamente, è per questo che mi serve ajax. Non mi è chiaro neanche se dovrei mettere admin-ajax.php in ajaxurl, oppure se è myfile.php che dovrei mettere lì invece?

user3199063 user3199063
27 lug 2016 15:03:02
0

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

4 dic 2016 17:38:55
0

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

}
10 dic 2018 11:48:09