Использование Ajax с файлом класса

13 июл. 2013 г., 23:36:29
Просмотры: 28.9K
Голосов: 7

На данный момент у меня есть ajax, который работает (я получаю успешный ответ [200]), но возникает проблема с хуками действий при ответе. JSON-объект не возвращается, вместо этого я получаю 0.

У меня есть die(); после return, поэтому я думаю, что проблема в том, что хук не работает.

Я пробовал несколько методов в конструкторе класса, но я не уверен, правильный ли это подход. Я делал это раньше с плагином, но сейчас это внутри темы.

Form.php

(включено в functions.php с помощью add_action('after_setup_theme')

public function __construct(){
 // Тест #1
 add_action( 'wp_ajax_nopriv_process_reservation', array( &$this, 'process_reservation' ) );

 // Тест #2 
 add_action( 'wp_ajax_process_reservation', &$this->process_reservation ); //с и без '&' перед $this

 // Тест #3 (это неправильно)
 add_action( 'wp_ajax_nopriv_process_reservation', $this->process_reservation );


//Если обернуть это в **add_action('init',function(){... *** тогда не загружается
 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' ), //не изменяйте это
      'itemNonce'             => wp_create_nonce("ajax_nonce"), //не изменяйте это
  ));
}

На всякий случай, вот также моя тестовая функция обратного вызова на данный момент

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

}

Данные формы в консоли XHR показывают, что передаются и action, и nonce

action:process_reservation
ajax_nonce:6f155a1e17

Я достаточно работал с Ajax, чтобы знать, чего ожидать, поэтому я почти уверен, что проблема здесь с хуками, возможно, что-то со scope темы, чего я не понимаю. В любом случае, любые предложения или помощь от сообщества будут очень полезны! Заранее спасибо

3
Комментарии

Смотрите отладку AJAX. Уже пробовали это?

fuxia fuxia
13 июл. 2013 г. 23:46:49

Только что проверил, спасибо. Получил ожидаемый ответ:

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

Не думаю, что это проблема с AJAX, скорее всего просто хук действия не срабатывает.

Xtremefaith Xtremefaith
14 июл. 2013 г. 00:01:37

Возможно, потому что callback метод объявлен как private? Есть ли разница, если сделать process_reservation() public? Просто предположение.

helgatheviking helgatheviking
14 июл. 2013 г. 00:52:20
Все ответы на вопрос 3
3
24

Ошибки, которые я обнаружил в вашем коде:

Одна была указана @helgatheviking в комментарии: Ajax-колбэк должен быть public методом, а не private.

Не знаю, как вы инициализируете этот класс, но wp_enqueue_script&_style (в единственном числе) должны быть обёрнуты в хук wp_enqueue_scripts (WP_DEBUG выводит уведомление).

Вы можете убрать <b>&</b> из $this, это остаток от PHP 4. Вот рабочий пример:

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 здесь!' );
        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 июл. 2013 г. 02:55:15
Комментарии

Используя ваш пример, я заставил это работать, но когда я начал преобразовывать его по частям, снова возникли проблемы с хуками. Например, обертка add_action( 'init', function() { вокруг wp_enqueue() ломает код; скрипт добавляется в очередь только когда я убираю эту обертку. Единственное отличие, которое я вижу в вашем примере - ваш код находится в файле functions.php, а мой - в отдельном файле, подключаемом через add_action('after_setup_theme', 'load_class_file'); внутри functions.php

Xtremefaith Xtremefaith
16 июл. 2013 г. 04:33:02

Например, в данный момент в моем __contructor() даже такой простой код, как ваш add_action( 'wp_head', function() { echo '<h4><a href="#" id="wpse">TEST AJAX</a></h4>'; }); не работает, если я не убираю обертку add_action

Xtremefaith Xtremefaith
16 июл. 2013 г. 05:01:38

@Xtremefaith, я переписал код для совместимости с PHP 5.2.

brasofilo brasofilo
16 июл. 2013 г. 05:31:59
3

Проблема заключалась в том, что в моем functions.php я подключал файл (reservations.php) с использованием хука after_setup_theme

add_action('after_setup_theme', 'init_cpts');

А затем внутри подключаемого файла я загружал файлы классов с использованием хука init. Я думал, что это нормально, так как init выполняется после after_setup_theme, это выглядело так:

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

Проблема, как упоминалось в ветке @brasofilo, заключалась в том, что любые хуки, которые я пытался использовать внутри файла класса, переставали работать, потому что на этот момент хук init уже был выполнен.

Чтобы исправить это, я просто удалил функцию load_classes(), как показано выше, и вместо этого использовал require_once непосредственно в самом файле (который подключается через after_setup_theme). Тогда решение @brasofilo сработало идеально, так что не забудьте +1 его ответ.

16 июл. 2013 г. 10:57:32
Комментарии

Как насчет того, чтобы самому проголосовать за его ответ? ;)

Johannes Pille Johannes Pille
16 июл. 2013 г. 11:28:03

Я пробовал, но моей репутации недостаточно (11), нужно 15. Как только наберу еще немного очков репутации, обязательно сделаю. Спасибо @JohannesPille

Xtremefaith Xtremefaith
16 июл. 2013 г. 20:17:50

Логично. :)

Johannes Pille Johannes Pille
17 июл. 2013 г. 04:56:36
1

Пожалуйста, проверьте ваш AJAX-запрос

Если вы используете $.ajax(), убедитесь, что указали dataType: "json"


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

или используйте функцию $.getJSON()...

Надеюсь, это решит проблему.

14 июл. 2013 г. 01:12:01
Комментарии

Это не проблема, ajax вызывается и получает ответ 200, как и ожидалось. Но никакое действие не вызывается, поэтому возвращается 0 из die(0) в admin-ajax.php

Xtremefaith Xtremefaith
16 июл. 2013 г. 04:36:09