Статьи

Обработка POST-запросов WordPress Way

Получите нужные права доступа к файлам на вашем сайте WordPress с помощью нашего учебника.

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

WordPress Transient API

В этой статье мы рассмотрим простой пример обработки запроса POST от пользователя, который отправляется через контактную форму. Мы собираемся использовать внутренний хук WordPress для правильного получения данных, их соответствующей обработки и перенаправления пользователя обратно на определенную страницу.

В этой статье предполагается, что у вас есть базовые знания API плагинов WordPress . Если вы не знакомы, настоятельно рекомендуется сначала просмотреть страницу Кодекса.

Фон

WordPress основан на архитектуре, управляемой событиями . Это означает, что внутренне ядро ​​WordPress заполнено различными действиями и фильтрами, чтобы изменить выполнение программы или изменить содержимое во время выполнения. Примерами действий, выполняемых во время выполнения программы, являются init , wp , template_redirect и wp_head . Многие плагины используют эти действия и фильтры для изменения работы WordPress.

Это не отличается от того, что мы собираемся достичь. Все, что нам нужно знать, — это правильные хуки, необходимые для запроса POST и соответственно изменить наш код. Это возможно, указав все admin-post.php нами формы в определенный файл в каталоге wp-admin именем admin-post.php . Если вы сталкивались с интеграцией вашего приложения с внутренним AJAX API WordPress , то вы заметите, что базовая структура admin-post.php не сильно отличается от аналога admin-ajax.php .

Анатомия admin-post.php

На самом базовом уровне admin-post.php содержит только 71 строку кода . Он начинается с определения константы WP_ADMIN и последующей загрузки WordPress, требуя wp-load.php . После этого он отправляет соответствующий заголовок и запускает действие admin_init .

Текущее действие определяется этой строкой кода:

 $action = empty( $_REQUEST['action'] ) ? '' : $_REQUEST['action']; 

Несмотря на название, admin-post.php может обрабатывать запросы POST и GET . Однако то, что нам интересно пройти в контексте этой статьи, будет связано только с запросом POST . Следующий,

 if ( ! wp_validate_auth_cookie() ) { if ( empty( $action ) ) { /** * Fires on a non-authenticated admin post request where no action was supplied. * * @since 2.6.0 */ do_action( 'admin_post_nopriv' ); } else { /** * Fires on a non-authenticated admin post request for the given action. * * The dynamic portion of the hook name, `$action`, refers to the given * request action. * * @since 2.6.0 */ do_action( "admin_post_nopriv_{$action}" ); } } else { if ( empty( $action ) ) { /** * Fires on an authenticated admin post request where no action was supplied. * * @since 2.6.0 */ do_action( 'admin_post' ); } else { /** * Fires on an authenticated admin post request for the given action. * * The dynamic portion of the hook name, `$action`, refers to the given * request action. * * @since 2.6.0 */ do_action( "admin_post_{$action}" ); } } 

Мы можем видеть, что два разных хука действий будут вызваны в зависимости от пользователя, вошедшего в систему, который является admin_post для зарегистрированного пользователя и admin_post_nopriv для не авторизованного пользователя. Если вам нужен более точный элемент управления только для обработки данных, относящихся к вашему запросу, также будет инициировано более конкретное действие, а именно admin_post_nopriv_{$action} и admin_post_{$action} , опять же на основе состояния пользователя, вошедшего в систему.

Допустим, у нашего POST запроса есть action со значением foobar . Эти два действия будут запущены, если текущий пользователь не вошел в систему:

  • admin_post_nopriv
  • admin_post_nopriv_foobar

Если вы вошли в систему, будут запущены два разных действия:

  • admin_post
  • admin_post_foobar

Для запроса GET , когда вы получаете доступ к URL-адресу, как это:

 http://www.example.com/wp-admin/admin-post.php?action=foobar&data=test 

Все вышеперечисленные четыре крючка все еще доступны для использования.

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

Доказательство концепции

Давайте возьмем контактную форму в качестве примера. Самый простой способ сделать это (не рекомендуется) — возможно, создать пользовательский шаблон страницы на основе базового page.php , жестко закодировать форму и выполнить обработку в этом файле. Примерно так это выглядит:

 <?php /* * Template Name: Contact Page */ get_header(); if ( ! empty( $_POST ) ) { // Sanitize the POST field // Generate email content // Send to appropriate email } ?> <div id="content"> <form action="" method="post"> <label for="fullname">Full Name</label> <input type="text" name="fullname" id="fullname" required> <label for="email">Email Address</label> <input type="email" name="email" id="email" required> <label for="message">Your Message</label> <textarea name="message" id="message"></textarea> <input type="submit" value="Send My Message"> </form> </div> <?php get_footer(); 

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

Чтобы полностью использовать управляемую событиями природу WordPress, а также обеспечить разделение admin-post.php , мы можем использовать предоставленный admin-post.php . Преобразование существующей формы, чтобы сделать ее совместимой с admin-post.php , также довольно просто.

Сначала мы изменим эту строку с:

 <form action="" method="post"> 

чтобы:

 <form action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" method="post"> 

Чтобы создать правильный URL-адрес, указывающий на admin-post.php , мы используем встроенную функцию admin_url . Это обеспечит правильность нашего URL-адреса в отношении текущего сайта, который работает.

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

Мы добавляем эту строку где-то между <form> .

 <input type="hidden" name="action" value="contact_form"> 

Вот так выглядит шаблон страницы после модификации:

 <?php /* * Template Name: Contact Page */ get_header(); ?> <div id="content"> <form action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" method="post"> <label for="fullname">Full Name</label> <input type="text" name="fullname" id="fullname" required> <label for="email">Email Address</label> <input type="email" name="email" id="email" required> <label for="message">Your Message</label> <textarea name="message" id="message"></textarea> <input type="hidden" name="action" value="contact_form"> <input type="submit" value="Send My Message"> </form> </div> <?php get_footer(); 

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

Фактическая обработка запроса POST

Для этой части у нас есть два варианта, и выбор любого из них — это нормально. Мы можем либо подключиться к admin_post_* через functions.php нашей темы, либо мы можем создать простой плагин для обработки контактной формы. Давайте просто закодируем это в functions.php для простоты.

Помните, что у нас есть настраиваемое действие contact_form в форме, поэтому по праву нам будут доступны следующие четыре хука:

  • admin_post_nopriv
  • admin_post_nopriv_contact_form
  • admin_post
  • admin_post_contact_form

Откройте файл functions.php вашей текущей темы и добавьте эти строки в:

 function prefix_send_email_to_admin() { /** * At this point, $_GET/$_POST variable are available * * We can do our normal processing here */ // Sanitize the POST field // Generate email content // Send to appropriate email } add_action( 'admin_post_nopriv_contact_form', 'prefix_send_email_to_admin` ); add_action( 'admin_post_contact_form', 'prefix_send_email_to_admin` ); 

Поскольку мы хотим обрабатывать отправку формы одинаково, независимо от того, вошел ли пользователь в данный момент в системе или нет, мы указываем на одну и ту же функцию обратного вызова для admin_post_nopriv_contact_form и admin_post_contact_form . Фактическая функция обратного вызова prefix_send_email_to_admin будет вашим основным пунктом для обработки данных.

Вывод

admin-post.php — полезный скрытый драгоценный камень, содержащийся в ядре WordPress. Используя его, мы можем сохранить разделение проблем между фактическим шаблоном и несвязанным кодом, который не нужен для отображения, разделенным путем подключения к соответствующим обработчикам.

Получите нужные права доступа к файлам на вашем сайте WordPress с помощью нашего учебника.