WordPress POST запросы: обработка

WordPress POST запросы: обработка

От автора: хорошему интерактивному сайту необходимо взаимодействовать с данными, которые вводит пользователь. Данные вводятся в специальных формах, которые являются частью вида. И WordPress в этом случае не исключение. За один день на сайте происходит масса различных форм взаимодействия пользователей с сервером. К примеру, подписка на рассылку новостей, сообщение владельцу сайта из формы обратной связи или заполнение формы заказа. Все это выполняется через POST запросы. И в данной статье мы рассмотри обработку WordPress POST запросов

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

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

Предыстория

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

Мы хотим добиться примерно того же. Нам всего лишь нужно знать правильные хуки для POST запросов и изменить код. Сделать это можно, разместив все формы в отдельном файле admin-post.php в директории wp-admin. Если вы уже работали с WordPress internal AJAX API, то должны заметить, что структура 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 запроса, если адрес примерно такой: http://www.example.com/wp-admin/admin-post.php?action=foobar&data=test

Зная это, можно работать с данными из POST запроса напрямую, избегая шаблонов формы представления.

Испытание концепции

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

<?php
/*
 * Template Name: Contact Page
 */

get_header();

if ( ! empty( $_POST ) ) {
    // Сканируем POST
    // генерируем текст для письма
    // Отсылаем письмо
}

?>

<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, и сделать это довольно просто. Сперва, замените эту строку:

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

На:

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

Для генерации правильной ссылки, которая будет вести на файл admin-post.php мы используем встроенную функцию admin_url. Таким образом, мы обеспечим надежный редирект на наш сайт. Также нам необходимо добавить скрытый action к форме, а для этого нам понадобится еще один хук. Укажем name=»action», value=»contact_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 запроса

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

admin_post_nopriv

admin_post_nopriv_contact_form

admin_post

admin_post_contact_form

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

function prefix_send_email_to_admin() {
    /**
     * Отсюда уже можно использовать $_GET/$_POST
     *
     * Можно начать обработку
     */ 

    // Проверяем POST 
    // Генерируем текст письма
    // Отсылаем по 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. С его помощью можно четко разделить файлы представления от кода, который занимается обработкой запросов.

Автор: Firdaus Zahari

Источник: http://www.sitepoint.com/

Редакция: Команда webformyself.

Хотите быстро научиться создавать сайты и блоги на WordPress с уникальным дизайном?

Получите самую полную в Рунете бесплатную систему обучения создания сайтов на WordPress “Уникальный сайт с нуля”

Получить

Метки: ,

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (1)

  1. Макс

    Спасибо, полезная инфа.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree