В WordPress хук wp_ajax_{$action} позволяет создавать обработчики для AJAX-запросов, которые выполняются авторизованными пользователями. Хук формируется динамически, где (action) — это уникальное название действия, указанное в параметре action при запросе к /wp-admin/admin-ajax.php.
do_action( “wp_ajax_{$action}” )
В этой статье мы рассмотрим, как использовать этот хук, его основные особенности и примеры кода для реализации.
Описание
wp_ajax_(action) позволяет регистрировать обработчики для AJAX-запросов, которые выполняются пользователями, находящимися в системе. Если требуется обработка запросов от неавторизованных пользователей, используется аналогичный хук wp_ajax_nopriv_(action). В случае, когда необходимо, чтобы запрос обрабатывался и для авторизованных, и для неавторизованных пользователей, нужно регистрировать оба хука.
1. PHP: Регистрация обработчика AJAX
Для примера создадим AJAX-действие find_best_posts, которое будет возвращать данные на основе ID поста, переданного с фронтенда. Добавим следующий код в файл functions.php темы или в плагин, чтобы зарегистрировать функцию, обрабатывающую AJAX-запросы с действием find_best_posts:
add_action( 'wp_ajax_find_best_posts', 'handle_find_best_posts_ajax' );
add_action( 'wp_ajax_nopriv_find_best_posts', 'handle_find_best_posts_ajax' );
function handle_find_best_posts_ajax() {
// Проверяем nonce для защиты
check_ajax_referer( 'find_best_posts_nonce', 'nonce' );
// Проверка прав пользователя
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error( 'Недостаточно прав' );
}
// Получаем ID поста из запроса
$post_id = intval( $_POST['post_id'] );
if ( $post_id ) {
// Пример получения данных о посте
$post_data = get_post( $post_id );
if ( $post_data ) {
wp_send_json_success( [ 'title' => $post_data->post_title, 'content' => $post_data->post_content ] );
} else {
wp_send_json_error( 'Пост не найден' );
}
} else {
wp_send_json_error( 'ID поста не указан' );
}
wp_die();
}
2. JavaScript: Отправка AJAX-запроса
Создадим AJAX-запрос на фронтенде для отправки данных на сервер и получения ответа. Для этого добавим JavaScript-код, например, в файл скриптов темы:
jQuery(document).ready(function($) {
$('#find-post').on('click', function() {
$.post({
url: my_ajax_object.ajax_url,
data: {
action: 'find_best_posts',
post_id: $('#post-id').val(),
nonce: my_ajax_object.nonce
},
success: function(response) {
if (response.success) {
console.log('Заголовок: ' + response.data.title);
console.log('Содержимое: ' + response.data.content);
} else {
console.error('Ошибка: ' + response.data);
}
}
});
});
});
Здесь my_ajax_object — это объект, передающий URL и nonce AJAX-запроса, создаваемый с помощью wp_localize_script:
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );
function my_enqueue_scripts() {
wp_enqueue_script( 'my-ajax-script', get_template_directory_uri() . '/js/my-ajax-script.js', ['jquery'], null, true );
wp_localize_script( 'my-ajax-script', 'my_ajax_object', [
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'find_best_posts_nonce' )
]);
}
Использование wp_send_json() для ответа в формате JSON
Функции wp_send_json_success() и wp_send_json_error() используются для отправки JSON-ответов. Они автоматически прерывают выполнение PHP-кода, что упрощает код и делает его более читаемым.
Защита с помощью Nonce и проверки прав
Для безопасной обработки AJAX-запросов рекомендуется использовать check_ajax_referer() для валидации nonce. Это защищает AJAX-запросы от подделки. Важно также проверять права пользователей для действий, которые требуют разрешений, например, добавление или удаление данных.
Список занятых action в ядре WordPress
В ядре WordPress PHP-функции для AJAX событий именуются аналогично самому событию, только дефис (-) заменяется на нижнее подчеркивание (_). Например, если в AJAX запросе используется событие get-permalink, то PHP-функция для его обработки будет называться wp_ajax_get_permalink().
Рассмотрим список функций в зависимости от типа запроса (GET или POST) для версии WordPress 5.7.2:
GET-запросы: action → PHP функция
fetch-list→wp_ajax_fetch_list()ajax-tag-search→wp_ajax_ajax_tag_search()wp-compression-test→wp_ajax_wp_compression_test()imgedit-preview→wp_ajax_imgedit_preview()oembed-cache→wp_ajax_oembed_cache()autocomplete-user→wp_ajax_autocomplete_user()dashboard-widgets→wp_ajax_dashboard_widgets()logged-in→wp_ajax_logged_in()rest-nonce→wp_ajax_rest_nonce()
POST-запросы: action → PHP функция
oembed-cache→wp_ajax_oembed_cache()image-editor→wp_ajax_image_editor()delete-comment→wp_ajax_delete_comment()delete-tag→wp_ajax_delete_tag()delete-link→wp_ajax_delete_link()delete-meta→wp_ajax_delete_meta()delete-post→wp_ajax_delete_post()trash-post→wp_ajax_trash_post()untrash-post→wp_ajax_untrash_post()delete-page→wp_ajax_delete_page()dim-comment→wp_ajax_dim_comment()add-link-category→wp_ajax_add_link_category()add-tag→wp_ajax_add_tag()get-tagcloud→wp_ajax_get_tagcloud()get-comments→wp_ajax_get_comments()replyto-comment→wp_ajax_replyto_comment()edit-comment→wp_ajax_edit_comment()add-menu-item→wp_ajax_add_menu_item()add-meta→wp_ajax_add_meta()add-user→wp_ajax_add_user()closed-postboxes→wp_ajax_closed_postboxes()hidden-columns→wp_ajax_hidden_columns()update-welcome-panel→wp_ajax_update_welcome_panel()menu-get-metabox→wp_ajax_menu_get_metabox()wp-link-ajax→wp_ajax_wp_link_ajax()menu-locations-save→wp_ajax_menu_locations_save()menu-quick-search→wp_ajax_menu_quick_search()meta-box-order→wp_ajax_meta_box_order()get-permalink→wp_ajax_get_permalink()sample-permalink→wp_ajax_sample_permalink()inline-save→wp_ajax_inline_save()inline-save-tax→wp_ajax_inline_save_tax()find_posts→wp_ajax_find_posts()widgets-order→wp_ajax_widgets_order()save-widget→wp_ajax_save_widget()delete-inactive-widgets→wp_ajax_delete_inactive_widgets()set-post-thumbnail→wp_ajax_set_post_thumbnail()date_format→wp_ajax_date_format()time_format→wp_ajax_time_format()wp-remove-post-lock→wp_ajax_wp_remove_post_lock()dismiss-wp-pointer→wp_ajax_dismiss_wp_pointer()upload-attachment→wp_ajax_upload_attachment()get-attachment→wp_ajax_get_attachment()query-attachments→wp_ajax_query_attachments()save-attachment→wp_ajax_save_attachment()save-attachment-compat→wp_ajax_save_attachment_compat()send-link-to-editor→wp_ajax_send_link_to_editor()send-attachment-to-editor→wp_ajax_send_attachment_to_editor()save-attachment-order→wp_ajax_save_attachment_order()media-create-image-subsizes→wp_ajax_media_create_image_subsizes()heartbeat→wp_ajax_heartbeat()get-revision-diffs→wp_ajax_get_revision_diffs()save-user-color-scheme→wp_ajax_save_user_color_scheme()update-widget→wp_ajax_update_widget()query-themes→wp_ajax_query_themes()parse-embed→wp_ajax_parse_embed()set-attachment-thumbnail→wp_ajax_set_attachment_thumbnail()parse-media-shortcode→wp_ajax_parse_media_shortcode()destroy-sessions→wp_ajax_destroy_sessions()install-plugin→wp_ajax_install_plugin()update-plugin→wp_ajax_update_plugin()crop-image→wp_ajax_crop_image()generate-password→wp_ajax_generate_password()save-wporg-username→wp_ajax_save_wporg_username()delete-plugin→wp_ajax_delete_plugin()search-plugins→wp_ajax_search_plugins()search-install-plugins→wp_ajax_search_install_plugins()activate-plugin→wp_ajax_activate_plugin()update-theme→wp_ajax_update_theme()delete-theme→wp_ajax_delete_theme()install-theme→wp_ajax_install_theme()get-post-thumbnail-html→wp_ajax_get_post_thumbnail_html()get-community-events→wp_ajax_get_community_events()edit-theme-plugin-file→wp_ajax_edit_theme_plugin_file()wp-privacy-export-personal-data→wp_ajax_wp_privacy_export_personal_data()wp-privacy-erase-personal-data→wp_ajax_wp_privacy_erase_personal_data()health-check-site-status-result→wp_ajax_health_check_site_status_result()health-check-dotorg-communication→wp_ajax_health_check_dotorg_communication()health-check-is-in-debug-mode→wp_ajax_health_check_is_in_debug_mode()health-check-background-updates→wp_ajax_health_check_background_updates()health-check-loopback-requests→wp_ajax_health_check_loopback_requests()health-check-get-sizes→wp_ajax_health_check_get_sizes()toggle-auto-updates→wp_ajax_toggle_auto_updates()send-password-reset→wp_ajax_send_password_reset()
Устаревшие события:
wp-fullscreen-save-post→wp_ajax_wp_fullscreen_save_post()press-this-save-post→wp_ajax_press_this_save_post()press-this-add-category→wp_ajax_press_this_add_category()health-check-dotorg-communication→wp_ajax_health_check_dotorg_communication()health-check-is-in-debug-mode→wp_ajax_health_check_is_in_debug_mode()health-check-background-updates→wp_ajax_health_check_background_updates()health-check-loopback-requests→wp_ajax_health_check_loopback_requests()
Этот список поможет понять, какие функции задействуются в WordPress для обработки AJAX-запросов и каким образом они именуются.
Заключение
Хук wp_ajax_(action) позволяет легко создавать обработчики для AJAX-запросов в WordPress, делая их мощным инструментом для добавления интерактивности в админку или фронтенд.