Usando Ajax con un archivo de Clase
En este momento tengo un ajax que funciona (recibo una respuesta exitosa [200]), pero estoy teniendo un problema con los hooks de acción en la respuesta. El objeto JSON no está regresando, en su lugar estoy recibiendo un 0.
Tengo el die(); después de mi return así que creo que el problema está en que el hook no está funcionando.
He intentado múltiples métodos dentro del constructor de la Clase pero no estoy seguro si este enfoque es correcto, lo he hecho antes con un plugin que creé, pero esto está dentro del tema.
Form.php
(incluido en functions.php con add_action('after_setup_theme')
public function __construct(){
// Prueba #1
add_action( 'wp_ajax_nopriv_process_reservation', array( &$this, 'process_reservation' ) );
// Prueba #2
add_action( 'wp_ajax_process_reservation', &$this->process_reservation ); //con y sin '&' antes de $this
// Prueba #3 (esto es incorrecto)
add_action( 'wp_ajax_nopriv_process_reservation', $this->process_reservation );
//Si envuelvo esto con **add_action('init',function(){... *** entonces no carga
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' ), //no cambiar esto
'itemNonce' => wp_create_nonce("ajax_nonce"), //no cambiar esto
));
}
Por si acaso es necesario, aquí está también la prueba de mi función callback en este 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 ) );
}
Los datos del formulario en la consola XHR muestran que tanto la acción como el nonce son pasados
action:process_reservation
ajax_nonce:6f155a1e17
He trabajado lo suficiente con Ajax para saber qué esperar, así que estoy bastante seguro de que es un problema con los hooks aquí, tal vez algo con el alcance del tema que no entiendo, de cualquier manera ¡cualquier sugerencia o ayuda de la comunidad sería genial! Gracias de antemano
Los errores que he detectado en tu código:
Uno fue señalado por @helgatheviking en un comentario: el callback de Ajax debe ser un método public
, no private
.
No estoy seguro de cómo estás inicializando esta clase, pero wp_enqueue_script
&_style
(en singular) debe estar encapsulado dentro de un hook wp_enqueue_scripts
(WP_DEBUG muestra un aviso).
Puedes eliminar el <b>&</b>
de $this
, eso es de PHP 4. A continuación un ejemplo funcional:
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">PRUEBA 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 funcionando!' );
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 );
});
});
});

Así que usando tu ejemplo aquí logré que funcione, pero cuando empecé a convertirlo parte por parte me encontré con problemas, otra vez con los hooks. Por ejemplo, el envoltorio add_action( 'init', function() {
alrededor del wp_enqueue()
falla; solo cuando lo quito es que el script se encola. La única diferencia que veo en tu ejemplo es que el tuyo está dentro del archivo functions.php, pero mi ejemplo está en un archivo separado incluido en un add_action('after_setup_theme', 'load_class_file');
dentro de functions.php

Por ejemplo, actualmente en mi __contructor()
incluso algo simple como tu add_action( 'wp_head', function() {
echo '<h4><a href="#" id="wpse">TEST AJAX</a></h4>';
});
no funciona a menos que quite el envoltorio add_action

El problema era que en mi archivo functions.php estaba cargando un archivo (reservations.php) usando el hook after_setup_theme
add_action('after_setup_theme', 'init_cpts');
Y luego, desde dentro del archivo que se cargaba, estaba incluyendo mis archivos de clase con el hook init
. Pensé que esto estaría bien ya que init
se carga después de after_setup_theme
, se veía así:
function load_classes(){
require_once( PATH_TO_FILE .'/Class.php');
}
add_action('init','load_classes');
El problema, como se mencionó en el hilo de @brasofilo, era que cualquier acción que intentara desde el archivo de clase ya no funcionaría, porque en ese momento el hook init
ya se había ejecutado.
Para solucionarlo, simplemente eliminé la función load_classes() como se muestra arriba, y en su lugar usé require_once
directamente dentro del archivo (que se carga con after_setup_theme
). Entonces la respuesta de @brasofilo funcionó perfectamente, así que asegúrate de darle +1 a su respuesta.

Lo intenté, pero mi reputación es demasiado baja (11), necesita ser al menos 15. Así que una vez que gane algunos puntos más de reputación lo haré. Gracias @JohannesPille
