Добавление Ajax к вашим плагинам WordPress

Использовать Ajax на вашем WordPress сайте легче, чем вы думаете. С помощью JQuery вы можете представлять и получать данные. Взаимодействие с WordPress осуществляется с помощью специальных, предназначенных для WordPress действий Ajax, которые могут обрабатываться на стороне сервера:

Ajax-действия происходят, как правило, после отправки формы, или после нажатия кнопки, что позволяет вам отправить биты данных на сервер для обработки. В качестве примера рассмотрим следующий фрагмент кода:

var data {
    action: 'spyr_plugin_do_ajax_request',
    var1: 'value 1',
    var2: 'value 2'
}

С помощью нашего друга JQuery, мы собираемся отправить эти данные на сервер и получим ответ. В WordPress, все запросы Ajax отсылаются для обработки к admin-ajax.php. Этот файл находится в папке /wp-admin вашего WordPress сайта. Даже при том, что файл находится в админ-панели вашего сайта, вы можете использовать его для обработки взаимодействий, как на стороне клиента, так и на стороне сервера.

Параметры действия

В предыдущем примере, параметр действия spyr_plugin_do_ajax_request отвечает за связь между файлом JavaScript и кодом PHP. Рекомендуется все действия, включая и это, использовать с префиксами; таким образом, оно становится уникально и легко может быть идентифицировано. Сделать так, чтобы было видно, что оно принадлежит плагину WordPress.

Отдельные действия Ajax для WordPress

Существует два отдельных действия Ajax для WordPress, которые мы можем использовать.
Во-первых, wp_ajax_$action, которое обрабатывает запрос Ajax, если пользователь вошел в систему.
Во-вторых, wp_ajax_nopriv_$action, которое обрабатывает запрос Ajax, если пользователь не вошел в систему, и не имеет никаких привилегий.

Исходя из наших предыдущих примеров, нам нужно добавить эти обращения действий в наш плагин следующим образом:

add_action( 'wp_ajax_spyr_plugin_do_ajax_request', 'spyr_plugin_do_ajax_request' );
add_action( 'wp_ajax_nopriv_spyr_plugin_do_ajax_request', 'spyr_plugin_do_ajax_request' );

Теперь, когда мы знакомы с основными принципами того, как события Ajax взаимодействуют с WordPress, давайте рассмотрим реальный пример. Давайте создадим простой плагин, который позволит администраторам удалять определенные записи на стороне клиента.

Плагин Ajax для удаления записей

Теперь мы можем начать создавать демонстрационный плагин, который будет удалять записи через Ajax. Так как целью этой статьи является дать вам представление о внутренней работе по обработке запроса Ajax, я думаю, что это плагин позволит вам получить достаточно информации, при этом, не нагружая ненужными подробностями. Наш плагин будет состоять из:

  • Добавления файла JavaScript со скриптом Ajax;
  • Добавления в каждую запись ссылки, которая при нажатии будет удалять запись;
  • Обработки Ajax-запроса к PHP;
  • Обработки клика кнопки с помощью JQuery;
  • Добавления скрипта в очередь обработки.
// Добавляем скрипт только на одну страницу, если пользователь имеет права администратора
add_action( 'template_redirect', 'spyr_add_js_single_posts' );
function spyr_add_js_single_posts() {
    // Мы хотим добавить скрипт только, если is_single()
    // и можем управлять опциями (администраторов)
    if( is_single() && current_user_can( 'manage_options' ) ) {

        // Получаем путь к паке плагина
        $path = plugin_dir_url( __FILE__ );

        // Добавляем наш скрипт в очередь обработки
        wp_enqueue_script( 'spyr_ajax_delete_posts', 
                            $path. 'js/ajax-delete-posts.js',
                            array( 'jquery' ),
                            '1.0.0', true );

        // Получаем протокол текущей страницы

       $protocol = isset( $_SERVER['HTTPS'] ) ? 'https://' : 'http://';

        // Устанавливаем параметр ajaxurl, который будет выводиться непосредственно пwhich 
        // перед файлом ajax-delete-posts.js, чтобы могли использовать ajaxurl
        $params = array(
            // Получаем url-адрес файла admin-ajax.php с помощью admin_url()
            'ajaxurl' => admin_url( 'admin-ajax.php', $protocol ),
        );
        // Выводим скрипт на странице
        wp_localize_script( 'spyr_ajax_delete_posts', 'spyr_params', $params );
    }
}

Обеспечение безопасности всегда стоит на первом месте. Поэтому мы должны проверить, имеет ли текущий пользователь достаточные права, чтобы видеть ссылку "Удалить". Мы также должны убедиться, что мы имеем дело с одиночной записью, в противном случае нет никакого смысла добавлять ссылку "Удалить".

Если оба условия выполняются, мы переходим к обработке скрипта, который содержит код JavaScript для обработки того, что происходит после нажатия ссылку. Обратите особое внимание на то, как протокол используется на клиентской стороне сайта.

Мы должны соответствовать политике Ajax, согласно которой запросы и ответы должны иметь то же происхождение. Все запросы и ответы Ajax должны обрабатываться с того же домена; и протоколы также должны соответствовать.

В WordPress можно установить протокол https в панели администрирования вашего сайта, задав для параметра "FORCESSLADMIN" значение ‘true’ в конфигурационном файле WordPress. Отправка запроса с адреса http://example.com/sample-post/ на адрес https://example.com/wp-admin/admin-ajax.php не будет работать. Даже если мы установили https:// на стороне сервера, мы можем выполнить вызов admin-ajax.php без https://.

Наконец, последняя значимая строка кода выводит динамические переменные, которые будут использоваться в ajax-delete-posts.js:

<script>
/* <![CDATA[ */
var spyr_params = {"ajaxurl":"http://example.com/wp-admin/admin-ajax.php"};
/* ]]> */
</script>

Добавление ссылки "Удалить" к содержимому страницы

// Добавление ссылки администрирования к каждой записи 
add_filter( 'the_content', 'spyr_add_content_delete_link' );
function spyr_add_content_delete_link( $content ) {
    if( is_single() && current_user_can( 'manage_options' ) ) {
        // Получение текущей записи
        global $post;

        // Создание nonce для этого действия
        $nonce = wp_create_nonce( 'spyr_adp-delete-' . $post->ID );
        // Добавление ссылки к странице администрирования для удаления записи в корзину и добавления  для нее
        $link = '<a href="'. admin_url( 'post.php?post='. $post->ID .'&action=trash&nonce=' .$nonce ) .'" 
                class="spyr_adp_link" data-nonce="'. $nonce .'" data-id="'. $post->ID .'">Delete Post</a>';

        // Выведение ссылки на странице
        return $content . '<p>'. $link .'</p>';
    }
}

Коротко и ясно. Cнова проверяем права доступа и убеждаемся, что мы просматриваем одиночную запись. Такие меры безопасности необходимы, и к этому вы должны привыкнуть. Далее создаем nonce и привязываем его к действию; обратите внимание на специальный формат.

Он использует следующую структуру, префикс_плагин-действие-идентификатор, где префикс - это spyr, adp = Ajax Delete Post, действие - это наше действие удаления, а идентификатор - ID удаляемого поста. Это не обязательно, но такой формат рекомендуется при составлении плагинов.

Обратите внимание, что мы также добавляем к ссылке ID записи и nonce, используя при этом атрибуты данных HTML5. Последний шаг - это прикрепить сформированную ссылку к содержимому страницы.

Обработка запросов Ajax с помощью PHP и WordPress

Мы уже дошли до половины статьи. Далее мы рассмотрим код, который на самом деле управляет представлением вашего Ajax запроса. Изучите его внимательно, поскольку он опирается на то, как вы называете данные, представленные запросом JQuery для получения идентификатора записи (pid) и значения nonce:

// Обработчик Ajax
add_action( 'wp_ajax_spyr_adp_ajax_delete_post', 'spyr_adp_ajax_delete_post' );
function spyr_adp_ajax_delete_post() {
    // Получаем ID поста из URL
    $pid = $_REQUEST['pid'];

    // Подтверждение WP_Ajax_Response
    $response = new WP_Ajax_Response;

    // Обработка, мы снова проверяем права доступа
    if( current_user_can( 'manage_options' ) && 
        // Верификация Nonces
        wp_verify_nonce( $_REQUEST['nonce'], 'spyr_adp-delete-' . $pid ) &&
        // Удаление записи
        wp_delete_post( $pid ) ) {
        // Формирование ответа, если все прошло без ошибок
        $response->add( array(
            'data'  => 'success',
            'supplemental' => array(
                'pid' => $pid,
                'message' => 'This post has been deleted',
            ),
        ) );
    } else {
        // Формирование ответа, если возникли ошибки
        $response->add( array(
            'data'  => 'error',
            'supplemental' => array(
                'pid' => $pid,
                'message' => 'Error deleting this post ('. $pid .')',
            ),
        ) );
    }
    // В любом случае отправляем ответ
    $response->send();

    // Всегда выходим, когда Ajax выполнен
    exit();
}

spyr_adp_ajax_delete_post - это имя действия передается в ответ на запрос файла JavaScript. Это подразумевает, что полное имя для вашего действия будет wp_ajax_spyr_adp_ajax_delete_post. Значения ID и nonce записи также передаются с помощью файла JavaScript, и мы можем получить их от $_REQUEST.

Мы собираемся установить экземпляр объекта WP_Ajax_Response, который позволит нам вернуть необходимый XML-ответ. После этого вы можете считать этот результат и действовать в соответствии с ним через JQuery.

Опять же, перед удалением записи вы должны убедиться, что пользователь является администратором, и значения nonce совпадают. Вы должны создать различные ответы для каждого сценария, так чтобы вы точно знали, была ли запись удалена или нет.

Вы можете приложить краткое сообщение, описывающее результат обработки, чтобы обеспечить дополнительную обратную связь с пользователем. Наконец, мы отправляем ответ обратно в браузер и выходим. Всегда помните, что вы должны выйти после выполнения запроса Ajax.

На сервер для обработки запрос отправляется очень просто:

action=spyr_adp_ajax_delete_post&pid=403&nonce=878727e18a

В качестве примера сформированного XML-файла, полученного в ответе, можно рассмотреть следующее:

<wp_ajax>
    <response action="spyr_adp_ajax_delete_post_0">
        <object id="0" position="1">
            <response_data>success</response_data>
            <supplemental>
                <pid>403</pid>
                <message>This post has been deleted</message>
            </supplemental>
        </object>
    </response>
</wp_ajax>

Обработка нажатия на кнопку с помощью JQuery

Единственное, что нам осталось рассмотреть, это создание кода JavaScript, который будет отправлять запрос и обработать ответ. Сам код довольно понятен, но я все же добавил в него комментарии, чтобы он стал еще проще для понимания:

jQuery( document ).ready( function() {
    jQuery( '.spyr_adp_link' ).click( function( e ) {
        var link = this;
        var id   = jQuery( link ).attr( 'data-id' );
        var nonce = jQuery( link ).attr( 'data-nonce' );

        // Это то, что мы отправляем на сервер
        var data = {
            action: 'spyr_adp_ajax_delete_post',
            pid: id,
            nonce: nonce
        }
        // Изменяем текст анкора ссылки
        // Чтобы предоставить пользователю некоторую немедленную информацию
        jQuery( link ).text( 'Trying to delete post' );

        // Отправляем на сервер
        jQuery.post( spyr_params.ajaxurl, data, function( data ) {
            // Разбираем XML-ответ с помощью jQuery
            // Получаем статус
            var status = jQuery( data ).find( 'response_data' ).text();
            // Получаем сообщение
            var message = jQuery( data ).find( 'supplemental message' ).text();
            // Если все прошло без сбоев, выводим сообщение об этом и удаляем ссылку
            if( status == 'success' ) {
                jQuery( link ).parent().after( '<p><strong>' + message + '</strong></p>').remove();
            } else {
                // Если возникла ошибка, выводим сообщение об ошибке
                alert( message );
            }
        });
        // Блокируем поведение ссылки по умолчанию
        e.preventDefault();
    });
});

Разбирается XML через JQuery очень просто, мы просматриваем XML на наличие элементов с помощью jQuery.find();, как если бы мы пытались найти элемент в HTML-документе.

Заключение

Как видите, выполнение запросов Ajax в ваших плагинах и темах WordPress является довольно простым процессом. В частности, это делается еще проще, благодаря двум специальным действиям: wp_ wp_ajax_$action и wp_ajax_nopriv_$action.

Это только начало удивительного пути, на котором вы сможете писать код, позволяющий обойтись без повторных загрузок страницы и делающий ваши темы и плагины WordPress более интерактивными. Что вы дальше хотите с этим сделать?

Если вы хотите получить дополнительную информацию по этой теме, ознакомьтесь с разделом Кодекса WordPress по Ajax и Ajax в плагинах.

РедакцияПеревод статьи «Adding Ajax to Your WordPress Plugin»