Utilizzare Ajax con un file di Classe

13 lug 2013, 23:36:29
Visualizzazioni: 28.9K
Voti: 7

Al momento ho un ajax che funziona (ottengo una risposta di successo [200]), ma ho un problema con gli action hook nella risposta. L'oggetto JSON non viene restituito, invece sto ottenendo uno 0.

Ho il die(); dopo il mio return quindi penso che il problema sia che l'hook non funziona.

Ho provato diversi metodi all'interno del costruttore della Classe ma non sono sicuro che questo approccio sia corretto, l'ho fatto prima con un plugin che ho creato, ma questo è all'interno del tema.

Form.php

(incluso in functions.php con add_action('after_setup_theme')

public function __construct(){
 // Test #1
 add_action( 'wp_ajax_nopriv_process_reservation', array( &$this, 'process_reservation' ) );

 // Test #2 
 add_action( 'wp_ajax_process_reservation', &$this->process_reservation ); //con e senza '&' prima di $this

 // Test #3 (questo è scorretto)
 add_action( 'wp_ajax_nopriv_process_reservation', $this->process_reservation );


//Se avvolgo questo con **add_action('init',function(){... *** allora non carica
 wp_enqueue_script('ajax_script',THEME_MODULES_URL.'/Reservations/form.js',array('jquery'),TRUE);
 wp_localize_script( 'ajax_script', 'myAjax', array(
      'ajaxurl'               => admin_url( 'admin-ajax.php' ), //non modificare questo
      'itemNonce'             => wp_create_nonce("ajax_nonce"), //non modificare questo
  ));
}

Nel caso fosse necessario ecco anche il test della mia funzione di callback al momento

private function process_reservation(){
    check_ajax_referer( 'process_reservation_nonce', 'nonce' );

    if( true )
        wp_send_json_success( 'ok' );
    else
        wp_send_json_error( array( 'error' => $custom_error ) );

}

I dati del form nella console XHR mostrano sia l'action che il nonce passati

action:process_reservation
ajax_nonce:6f155a1e17

Ho fatto abbastanza Ajax da sapere cosa aspettarmi quindi sono abbastanza sicuro che sia un problema di hook qui, forse qualcosa con lo scope del tema che non capisco, in ogni caso qualsiasi suggerimento o aiuto dalla community sarebbe fantastico! Grazie in anticipo

3
Commenti

Vedi debugging AJAX. L'hai già provato?

fuxia fuxia
13 lug 2013 23:46:49

L'ho appena fatto, grazie. Ho ricevuto una risposta come previsto:

X-Debug-Ajax-1:File "C:\...\wp-content\themes\bp\functions.php" was called on an AJAX request. X-Debug-Ajax-2:Function "t5_debug_test" was called and the user is not logged in. X-Frame-Options:SAMEORIGIN X-Powered-By:PHP/5.4.7 X-Robots-Tag:noindex

Non credo sia un problema di AJAX, penso piuttosto che l'hook dell'azione non si stia attivando.

Xtremefaith Xtremefaith
14 lug 2013 00:01:37

Forse perché il metodo di callback è impostato come privato? Cambia qualcosa se process_reservation() è pubblico? Sto solo ipotizzando.

helgatheviking helgatheviking
14 lug 2013 00:52:20
Tutte le risposte alla domanda 3
3
24

Gli errori che ho individuato nel tuo codice:

Uno è stato segnalato da @helgatheviking in un commento: il callback Ajax deve essere un metodo public, non private.

Non sono sicuro di come stai inizializzando questa classe, ma wp_enqueue_script&_style (al singolare) deve essere racchiuso all'interno di un hook wp_enqueue_scripts (WP_DEBUG mostra un notice).

Puoi rimuovere il <b>&</b> da $this, è una sintassi di PHP 4. Ecco un esempio funzionante:

class MyTheme
{
    public function __construct()
    {
        add_action( 'wp_footer', array( $this, 'aux_function' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'init_plugin' ) );
        add_action( 'wp_ajax_process_reservation', array( $this, 'process_reservation' ) ); 
        add_action( 'wp_ajax_nopriv_process_reservation', array( $this, 'process_reservation' ) );
    }

    public function aux_function()
    {
        echo '<h4><a href="#" id="wpse">TEST AJAX</a></h4>';
    }

    public function init_plugin()
    {
        wp_enqueue_script( 
            'ajax_script', 
            plugins_url( '/test.js',__FILE__ ), 
            array('jquery'), 
            TRUE 
        );
        wp_localize_script( 
            'ajax_script', 
            'myAjax', 
            array(
                'url'   => admin_url( 'admin-ajax.php' ),
                'nonce' => wp_create_nonce( "process_reservation_nonce" ),
            )
        );
    }

    public function process_reservation()
    {
        check_ajax_referer( 'process_reservation_nonce', 'nonce' );

        if( true )
            wp_send_json_success( 'Ajax qui!' );
        else
            wp_send_json_error( array( 'error' => $custom_error ) );
    }
}
new MyTheme();

test.js

jQuery(document).ready(function($) 
{
    $('#wpse').click(function(e) 
    {
        e.preventDefault();
        var data = {
            action: 'process_reservation',
            nonce: myAjax.nonce
        };

        $.post( myAjax.url, data, function( response ) 
        {
            $('#wpse').html( response.data );
        });
    });
});
14 lug 2013 02:55:15
Commenti

Quindi usando il tuo esempio qui sono riuscito a farlo funzionare, ma quando ho iniziato a convertirlo un pezzo alla volta mi sono imbattuto in problemi, ancora una volta con gli hook. Ad esempio, il wrapper add_action( 'init', function() { attorno a wp_enqueue() non funziona; solo quando lo rimuovo lo script viene accodato. L'unica differenza che vedo nel tuo esempio è che il tuo è dentro il file functions.php, mentre il mio esempio è in un file separato incluso tramite add_action('after_setup_theme', 'load_class_file'); dentro functions.php

Xtremefaith Xtremefaith
16 lug 2013 04:33:02

Ad esempio, al momento nel mio __contructor() anche qualcosa di semplice come il tuo add_action( 'wp_head', function() { echo '<h4><a href="#" id="wpse">TEST AJAX</a></h4>'; }); non funziona a meno che non rimuova il wrapper add_action

Xtremefaith Xtremefaith
16 lug 2013 05:01:38

@Xtremefaith, ho riscritto il codice per renderlo compatibile con PHP 5.2.

brasofilo brasofilo
16 lug 2013 05:31:59
3

Il problema era che nel mio functions.php stavo caricando un file (reservations.php) utilizzando l'hook after_setup_theme

add_action('after_setup_theme', 'init_cpts');

E poi all'interno del file che veniva caricato, richiamavo i miei file delle classi con l'hook init. Pensavo che fosse ok dato che init viene caricato dopo after_setup_theme, e appariva così:

function load_classes(){
    require_once( PATH_TO_FILE .'/Class.php');
}
add_action('init','load_classes');

Il problema, come menzionato nel thread di @brasofilo, era che qualsiasi action hook che tentavo di utilizzare nel file della classe non funzionava più, perché a quel punto l'init era già stato attivato.

Per risolvere ho semplicemente rimosso la funzione load_classes() mostrata sopra, e invece ho utilizzato direttamente require_once all'interno del file stesso (che viene caricato con after_setup_theme). Poi la risposta di @brasofilo ha funzionato perfettamente, quindi assicuratevi di +1 la sua risposta.

16 lug 2013 10:57:32
Commenti

Che ne dici di votare positivamente tu stesso la sua risposta? ;)

Johannes Pille Johannes Pille
16 lug 2013 11:28:03

Ho provato, la mia reputazione è troppo bassa (11) deve essere almeno 15. Quindi una volta ottenuti qualche altro punto di reputazione lo farò. Grazie @JohannesPille

Xtremefaith Xtremefaith
16 lug 2013 20:17:50

Ha senso. :)

Johannes Pille Johannes Pille
17 lug 2013 04:56:36
1

Per favore controlla la tua chiamata ajax

Se la usi assicurati di inserire dataType: "json"


$.ajax({
  dataType: "json",
  url: url,
  data: data,
  success: success
});

oppure usa la funzione $.getJSON()...

Spero che questo risolva il problema.

14 lug 2013 01:12:01
Commenti

Non è questo il problema, la chiamata ajax viene effettuata e riceve una risposta 200 come previsto. Ma nessuna azione viene chiamata, quindi restituisce 0 dal die(0) nel file admin-ajax.php

Xtremefaith Xtremefaith
16 lug 2013 04:36:09