Кастомный PHP эндпоинт для AJAX вызова в WordPress плагине

27 июл. 2016 г., 11:57:39
Просмотры: 13.6K
Голосов: 4

Я впервые пишу плагин и столкнулся с проблемой.

Я использую AJAX в своем плагине. Мой JavaScript файл находится в папке ../wp-content/plugins/myplugin/js/, и в нем я пытаюсь вызвать PHP файл, который расположен в ../wp-content/plugins/myplugin/

jQuery.ajax({
    url: "/wp-content/plugins/myplugin/myfile.php?myparam=" + myparam,
    context: document.body
});

Мой вопрос: Как сделать эту ссылку рабочей независимо от того, где пользователь установил плагин. Потому что если, например, пользователь установит плагин в http://localhost/subdir/, ссылка будет некорректной. Можно ли как-то создать относительную ссылку?

0
Все ответы на вопрос 3
5

Прежде всего, не следует вызывать собственный PHP файл напрямую. Вместо этого следует использовать конечную точку admin-ajax. Документация

В административной части сайта можно использовать переменную ajaxurl для получения URL для AJAX запросов. На фронтенде вам необходимо самостоятельно объявить переменную с URL. Это описано в документации:

Примечание: В отличие от административной части, глобальная переменная ajaxurl не определяется автоматически на фронтенде, если у вас не установлен BuddyPress или другой плагин, использующий AJAX. Вместо того чтобы полагаться на глобальную переменную, объявите пространство имен JavaScript с собственным свойством ajaxurl. Также можно использовать wp_localize_script() для предоставления URL вашему скрипту, сгенерировав его с помощью выражения: admin_url( 'admin-ajax.php' )

Данное решение должно устранить проблему:

add_action( 'wp_head', 'front_ajaxurl' );
function front_ajaxurl() {
    wp_register_script( 'admin_ajax_front', plugin_dir_url(__FILE__) . 'script.js' );
    $translation_array = array(
        'ajaxurl' => admin_url( 'admin-ajax.php' )
    );
    wp_localize_script( 'admin_ajax_front', 'front', $translation_array );
    wp_enqueue_script( 'admin_ajax_font', false, array(), false, true ); // последний параметр true добавит скрипт в подвал
}

Затем в вашем JS файле:

$.ajax({
    url: front.ajaxurl,
    ...
})
27 июл. 2016 г. 12:03:51
Комментарии

Смешивание JavaScript и PHP кода — не лучшая практика. Как указано в цитате из документации, я бы рекомендовал использовать wp_localize_script(). Это гарантирует, что переменная будет определена до загрузки скрипта, который от нее зависит.

David David
27 июл. 2016 г. 12:16:36

Еще лучше, чем wp_localize_script(), вы можете использовать wp_add_inline_script(), начиная с WordPress 4.5. Эта функция позволяет выводить встроенные скрипты в рамках мощной системы управления зависимостями WordPress, и не ограничивается только JavaScript объектом, как wp_add_inline_script().

cybmeta cybmeta
27 июл. 2016 г. 12:25:37

Я все еще не понимаю... Я до сих пор не знаю, как мне ссылаться на myfile.php и где? Нужно ли превращать его в функцию или как? Пожалуйста, дайте подсказку, я запутался.

user3199063 user3199063
27 июл. 2016 г. 14:02:41

Если вам действительно нужно вызвать файл из вашего плагина, вы можете сделать это с помощью plugin_dir_url(__FILE__)

Krzysztof Grabania Krzysztof Grabania
27 июл. 2016 г. 14:28:44

мне нужно вызвать myfile.php в моем js, как я показал в вопросе, конечно, для этого мне и нужен ajax. Также мне не совсем понятно, должен ли я указывать admin-ajax.php в ajaxurl, или вместо этого нужно указать там myfile.php?

user3199063 user3199063
27 июл. 2016 г. 15:03:02
0

Я новичок, но у меня сработало

Добавьте следующее в functions.php. Обратите внимание, что 'wp_ajax' — это префикс по соглашению, а 'do_something' — произвольно выбранное мной имя действия:

add_action( 'wp_ajax_do_something', 'do_something' );

function do_something() {
    //действительно, вперед, сделайте что-нибудь
    die("верните что-нибудь");
}

Чтобы сделать AJAX-запрос из браузера (на стороне клиента), я смог найти конечную точку, используя wp.ajax.settings.url. Глобальная переменная wp определена в объекте window.

//do_something здесь должно соответствовать указанному выше, вы можете добавить другие параметры в этот объект
var data = { action: 'do_something' };
jQuery.post(wp.ajax.settings.url, data, function(response) {
    console.log('Результат: ' + response);
});

У меня установлен WordPress 4.6.1 (последняя версия на момент написания) и несколько плагинов. Я ссылался на эту документацию, где ошибочно указано, что ajaxurl определен, но в моем случае это не так: https://codex.wordpress.org/AJAX_in_Plugins

4 дек. 2016 г. 17:38:55
0

Я столкнулся с такой же проблемой.

Я хотел использовать свой собственный endpoint вместо admin-ajax, потому что у меня есть правила перезаписи, которые заполняют все переменные, необходимые для выполнения ajax-действий.

Таким образом, использование (как указано в codex)

jQuery(document).ready(function($) {
    var data = {
        'action': 'my_action',
        'whatever': ajax_object.we_value      // Передаем PHP-значения по-другому!
    };
    jQuery.post(ajax_object.ajax_url, data, function(response) {
        alert('Получено от сервера: ' + response);
    });
});

и

add_action( 'wp_ajax_my_action', 'my_action' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action' );

только усложняет мой код.

В итоге я сделал так, и это работает:

    jQuery.ajax({
        type: "post",
        url: MYCUSTOMENDPOINT?ajax_action,
        dataType: 'json',
        ...

в сочетании с:

    add_action( 'init', 'rewrite_rules');
    add_filter( 'template_include','handle_ajax_action');

function rewrite_rules(){
    add_rewrite_tag(
        '%ajax_action%',
        '([^&]+)'
    );
}

function handle_ajax_action($template){

    $success = null;

    // Поскольку переменная запроса "ajax" не требует значения, нужно проверить ее наличие
    if ( !$action = get_query_var( 'ajax_action' ) ) return $template; // ajax-действие отсутствует

    $result = array(
        'input' =>  $_REQUEST,
        'message'=> null,
        'success'=> null,
    );

    $success = ...

    if ( is_wp_error($success) ){
        $result['success'] = false;
        $result['message'] = $success->get_error_message();

    }else{
        $result['success'] = $success;
    }

    header('Content-type: application/json');
    send_nosniff_header();
    header('Cache-Control: no-cache');
    header('Pragma: no-cache');

    wp_send_json( $result );  

}
10 дек. 2018 г. 11:48:09