Utilizzare Ajax con un file di Classe
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
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 );
});
});
});

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

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

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.

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

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
