Folosirea Ajax cu un fișier Class

13 iul. 2013, 23:36:29
Vizualizări: 28.9K
Voturi: 7

În prezent am un ajax care funcționează (primesc un răspuns de succes [200]), dar am o problemă cu action hooks la răspuns. Obiectul JSON nu se întoarce, în schimb primesc 0.

Am die(); după return-ul meu așa că mă gândesc că problema este că hook-ul nu funcționează.

Am încercat mai multe metode în constructorul Clasei dar nu sunt sigur dacă această abordare este corectă, am făcut-o înainte într-un plugin pe care l-am creat, dar acesta este în temă.

Form.php

(inclus în functions.php cu 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 ); //cu și fără '&' înainte de $this

 // Test #3 (acest mod este incorect)
 add_action( 'wp_ajax_nopriv_process_reservation', $this->process_reservation );


//Dacă învelesc asta cu **add_action('init',function(){... *** atunci nu se încarcă
 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' ), //nu schimba asta
      'itemNonce'             => wp_create_nonce("ajax_nonce"), //nu schimba asta
  ));
}

Pentru orice eventualitate, aici este și testul funcției mele callback în acest moment

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

}

Datele formularului în consola XHR arată că atât action cât și nonce sunt transmise

action:process_reservation
ajax_nonce:6f155a1e17

Am făcut destul de mult Ajax pentru a ști la ce să mă aștept, așa că sunt destul de sigur că este o problemă de hooking aici, poate ceva legat de scopul temei pe care nu-l înțeleg, oricum orice sugestii sau ajutor din partea comunității ar fi grozave! Mulțumesc anticipat

3
Comentarii

Vezi depanarea AJAX. Ai încercat asta?

fuxia fuxia
13 iul. 2013 23:46:49

Tocmai am făcut-o, mulțumesc. Am primit răspunsul așteptat:

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

Nu cred că e o problemă de AJAX, cred că e doar că hook-ul de acțiune nu se declanșează.

Xtremefaith Xtremefaith
14 iul. 2013 00:01:37

Poate pentru că metoda callback este setată ca privată? Există vreo diferență dacă process_reservation() este publică? Doar presupun aici.

helgatheviking helgatheviking
14 iul. 2013 00:52:20
Toate răspunsurile la întrebare 3
3
24

Erorile pe care le-am identificat în codul tău:

Una a fost menționată de @helgatheviking într-un comentariu: callback-ul Ajax trebuie să fie o metodă public, nu private.

Nu sunt sigur cum inițializezi această clasă, dar wp_enqueue_script&_style (la singular) trebuie să fie încapsulate într-un hook wp_enqueue_scripts (WP_DEBUG afișează o notificare).

Poți renunța la <b>&</b> din fața lui $this, asta era valabil în PHP 4. Iată un exemplu funcțional:

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 aici!' );
        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 iul. 2013 02:55:15
Comentarii

Deci folosind exemplul tău de aici am reușit să fac asta să funcționeze, dar când am început să-l convertesc bucată cu bucată am dat din nou de probleme, tot cu hook-uri. De exemplu, învelișul add_action( 'init', function() { în jurul lui wp_enqueue() se strică; doar când îl elimin scriptul este încărcat. Singura diferență pe care o văd în exemplul tău este că al tău este în fișierul functions.php, dar exemplul meu este într-un fișier separat inclus printr-un add_action('after_setup_theme', 'load_class_file'); în functions.php

Xtremefaith Xtremefaith
16 iul. 2013 04:33:02

De exemplu, în momentul de față în __contructor()-ul meu chiar și ceva simplu ca add_action( 'wp_head', function() { echo '<h4><a href="#" id="wpse">TEST AJAX</a></h4>'; }); nu funcționează decât dacă elimin învelișul add_action

Xtremefaith Xtremefaith
16 iul. 2013 05:01:38

@Xtremefaith, am rescris codul să fie compatibil cu PHP 5.2.

brasofilo brasofilo
16 iul. 2013 05:31:59
3

Problema era că în functions.php încărcam un fișier (reservations.php) folosind hook-ul after_setup_theme

add_action('after_setup_theme', 'init_cpts');

Și apoi din interiorul fișierului care era încărcat, includeam fișierele de clasă cu hook-ul init. Am crezut că este ok deoarece init se încarcă după after_setup_theme, arăta astfel:

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

Problema, așa cum s-a menționat în thread-ul lui @brasofilo, era că orice action hook pe care încercam să-l folosesc în fișierul de clasă nu mai funcționa, deoarece în acel moment init fusese deja declanșat.

Pentru a rezolva, am eliminat simplu funcția load_classes() așa cum este arătat mai sus și am folosit direct require_once în interiorul fișierului în sine (care este încărcat prin after_setup_theme). Apoi răspunsul lui @brasofilo a funcționat perfect, așa că asigurați-vă să-i dați +1 răspunsului său.

16 iul. 2013 10:57:32
Comentarii

Cum ar fi să îi votezi tu răspunsul? ;)

Johannes Pille Johannes Pille
16 iul. 2013 11:28:03

Am încercat, reputația mea este prea mică (11) trebuie să fie la 15. Așa că odată ce mai câștig câteva puncte de reputație, o voi face. Mulțumesc @JohannesPille

Xtremefaith Xtremefaith
16 iul. 2013 20:17:50

Are sens. :)

Johannes Pille Johannes Pille
17 iul. 2013 04:56:36
1

Te rog să verifici apelul tău AJAX

Dacă folosești $.ajax(), asigură-te că ai adăugat dataType: "json"


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

sau folosește funcția $.getJSON() ...

Sper că această soluție rezolvă problema.

14 iul. 2013 01:12:01
Comentarii

Nu asta este problema, apelul ajax este efectuat și primește un răspuns 200 așa cum era de așteptat. Dar nici o acțiune nu este apelată, de aceea returnează 0 din die(0) în admin-ajax.php

Xtremefaith Xtremefaith
16 iul. 2013 04:36:09