Как создать сайт для членства в WordPress: часть 3

23 января 2018

Ранее в этой серии мы рассмотрели, как настроить регистрационные формы WordPress. Затем мы добавили некоторые пользовательские поля в нашу регистрационную форму. Сегодня в третьей и заключительной части этой серии мы расскажем о том, как создать раздел «Моя учетная запись» для пользователей вашего сайта, посредством которого пользователи могут редактировать свою информацию о профиле.

Установка страницы

Первое, что мы хотим сделать, это создать шаблон страницы для размещения нашего контента. Мне нравится префикс шаблонов страниц со словом «шаблон». Таким образом, мой файл называется template-user-profile.php, и открытие PHP выглядит так:

<?php
/**
 * Template Name: User Profile
 */

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

Теперь перейдем к концу WordPress и создадим страницу с именем «профиль», а в метатеге «Атрибуты страницы» присвойте ей наш новый шаблон страницы. После того, как вы опубликовали эту страницу, у вас должна быть пустая страница в интерфейсе: http: yourdomain profile.

Теперь добавьте некоторый контент на нашу страницу. Мы хотим, чтобы структура была содержимым страницы (то есть все, что написано в WordPress WYSIWYG), а затем форму нашего профиля.

Часто бывает полезно получить код с page.php и использовать его в качестве отправной точки для ваших шаблонов страниц. Этот код немного отличается в зависимости от вашей темы, но скорее всего он будет содержать цикл, который выплевывает содержимое страницы. Часть контента обычно извлекается с помощью функции WordPress get_template_part (). Прямо под тем, где содержимое было восстановлено, давайте вставим нашу форму HTML. Итак, вернемся:

    Copy и вставьте код из page.php в наш шаблон страницы. NЗарегистрируйтесь, где будет выводиться содержимое. NУбедитесь в этом, вставьте следующий код, а затем мы пройдем через него:
<form role="form" action="" id="user_profile" method="POST">
    <?php wp_nonce_field( 'user_profile_nonce', 'user_profile_nonce_field' ); ?>
    <div class="form-group">
        <label for="first_name"><?php _e( 'First name', 'sage' ); ?></label>
        <input type="text" class="form-control" id="first_name" name="first_name" placeholder="<?php _e( 'First name', 'sage' ); ?>" value="<?php echo $user_info->first_name; ?>">
    </div>
    <div class="form-group">
        <label for="last_name"><?php _e( 'Last name', 'sage' ); ?></label>
        <input type="text" class="form-control" id="last_name" name="last_name" placeholder="<?php _e( 'Last name', 'sage' ); ?>" value="<?php echo $user_info->last_name; ?>">
    </div>
    <div class="form-group">
        <label for="twitter_name"><?php _e( 'Twitter name', 'sage' ); ?></label>
        <input type="text" class="form-control" id="twitter_name" name="twitter_name" placeholder="<?php _e( 'Twitter name', 'sage' ); ?>" value="<?php echo $user_info->twitter_name; ?>">
    </div>
    <div class="form-group">
        <label for="email"><?php _e( 'Email address', 'sage' ); ?></label>
        <input type="email" class="form-control" id="email" name="email" placeholder="<?php _e( 'Email address', 'sage' ); ?>" value="<?php echo $user_info->user_email; ?>">
    </div>
    <div class="form-group">
        <label for="pass1"><?php _e( 'Password', 'sage' ); ?></label>
        <input type="password" class="form-control" id="pass1" name="pass1" placeholder="<?php _e( 'Password', 'sage' ); ?>">
    </div>
    <div class="form-group">
        <label for="pass2"><?php _e( 'Repeat password', 'sage' ); ?></label>
        <input type="password" class="form-control" id="pass2" name="pass2" placeholder="<?php _e( 'Repeat password', 'sage' ); ?>">
    </div>
    <button type="submit" class="btn btn-default"><?php _e( 'Submit', 'sage' ); ?></button>
</form>

Здесь нет ничего сумасшедшего: форма использует разметку Bootstrap, поскольку наша тема построена на Bootstrap. Следует отметить, что форма отправляется с использованием метода POST, и мы включили wp_nonce_field - это маркер безопасности, который помогает предотвратить вредоносные атаки. Если вы не знакомы с WordPress's Nonces, я предлагаю прочитать эту статью.

Извлечение данных

С учетом этого у вас должна быть форма на передней панели сайта, но она не делает много. Мы хотим, чтобы он отображал данные, которые мы имеем для зарегистрированного пользователя. Возможно, вы заметили, что атрибуты value в нашей форме повторяют некоторые PHP.

value = "first_name;?> "

Прямо сейчас, когда объект $ user_info не существует, так как мы еще не написали код, так что давайте начнем там. Вставьте следующий код перед нашей формой в template-user-profile.php.

<?php
/**
 * Gets the user info.
 * Returned in an object.
 *
 * http://codex.wordpress.org/Function_Reference/get_userdata
 */
$user_id = get_current_user_id();
$user_info = get_userdata( $user_id );

Используя некоторые собственные функции WordPress, он получает идентификатор текущего пользователя, и с этим мы можем получить данные пользователя. Это сохраняется в объекте с именем $ user_info, и, как показано выше, мы можем легко получить пользовательские данные. Чтобы просмотреть все данные, хранящиеся в этом объекте, вы можете запустить var_dump следующим образом:. Это может быть полезно для отладки или просто для просмотра того, что вы можете получить.

Обработка данных

В головоломке есть одна заключительная часть, и это необходимо для обработки данных, что позволяет пользователям редактировать свои профили. Чтобы все было организовано, я ввел код членства в файл, точно названный member.php. Это находится в каталоге lib и входит в наш файл functions.php. Как только вы это сделаете, откройте свой новый файл membership.php в редакторе кода и позвольте нам сделать функцию, которая будет обрабатывать данные пользователей.

Во-первых, давайте быстро перейдем к логике. Когда нажата кнопка отправки, мы хотим проверить, что наше поле nonce было отправлено - это проверяет, что данные поступают с нужного места.

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

И код для всего, что выглядит примерно так:

<?php
/**
 * Process the profile editor form
 */
function tutsplus_process_user_profile_data() {
    if ( isset( $_POST['user_profile_nonce_field'] ) && wp_verify_nonce( $_POST['user_profile_nonce_field'], 'user_profile_nonce' ) ) {
        // Get the current user id.
        $user_id = get_current_user_id();
        // Put our data into a better looking array and sanitize it.
        $user_data = array(
            'first_name' => sanitize_text_field( $_POST['first_name'] ),
            'last_name' => sanitize_text_field( $_POST['last_name'] ),
            'user_email' => sanitize_email( $_POST['email'] ),
            'twitter_name' => sanitize_text_field( $_POST['twitter_name'] ),
            'user_pass' => $_POST['pass1'],
        );
        if ( ! empty( $user_data['user_pass'] ) ) {
            // Validate the passwords to check they are the same.
            if ( strcmp( $user_data['user_pass'], $_POST['pass2'] ) !== 0 ) {
                wp_redirect( '?password-error=true' );
                exit;
            }
        } else {
            // If the password fields are not set don't save.
            unset( $user_data['user_pass'] );
        }
        // Save the values to the post.
        foreach ( $user_data as $key => $value ) {
            $results = '';
            // http://codex.wordpress.org/Function_Reference/wp_update_user
            if ( $key == 'twitter_name' ) {
                $results = update_user_meta( $user_id, $key, $value );
                unset( $user_data['twitter_name'] );
            } elseif ( $key == 'user_pass' ) {
                wp_set_password( $user_data['user_pass'], $user_id );
                unset( $user_data['user_pass'] );
            } else {
                // Save the remaining values.
                $results = wp_update_user( array( 'ID' => $user_id, $key => $value ) );
            }
            if ( ! is_wp_error( $results ) ) {
                wp_redirect( '?profile-updated=true' );
            }
        }
        wp_redirect( '?profile-updated=false' );
        exit;
    }
}
add_action( 'tutsplus_process_user_profile', 'tutsplus_process_user_profile_data' );

Теперь вы можете заметить, что данные сохраняются с использованием трех разных функций WordPress:

update_user_meta () для имени твита wp_set_password () для пароля wp_update_user () для остальных данных

И вы правы, чтобы задать вопрос. В принципе, пользовательские метаданные (имя Твиттера) необходимо обрабатывать с использованием относительной функции, а не общей пользовательской функции обновления. Что касается пароля, в то время как он может работать с wp_update_user (), у меня были проблемы с ним и я предпочитаю использовать этот метод. Помните, что это всего лишь руководство, и часто код предназначен для демонстрации различных методов для достижения ваших требований.

Итак, теперь у нас есть наша функция обработки данных, но она нигде не называется. В конце нашей функции вы видите, что есть действие, связанное с ним. Поэтому для вызова этой функции нам просто нужно использовать WordPress: do_action ();. Поэтому вставьте эту строку над своей формой в шаблон страницы профиля пользователя, который мы создали ранее:

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

Сообщения об ошибках и успехах

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

В нашей функции tutsplus_process_user_profile () вы, возможно, заметили, что она добавляет разные строки запроса к URL-адресу в зависимости от результата обработки. Поэтому, если все будет сохранено и успешно, то наш URL будет добавлен с помощью: profile-updated = true, и они будут меняться в зависимости от результатов. Нам нужно вызвать сообщение, основанное на этих ответах.

Ниже я использовал фильтр для захвата содержимого, а через магию $ _GET мы можем проверить параметры и выплюнуть то, что нам нужно.

<?php
/**
 * Display the correct message based on the query string.
 *
 * @param string $content Post content.
 *
 * @return string Message and content.
 */
function tutsplus_display_messages( $content ) {
    if ( 'true' == $_GET['profile-updated'] ) {
        $message = __( 'Your information was successfully updated', 'sage' );
        $message_markup = tutsplus_get_message_markup( $message, 'success' );
    } elseif ( 'false' == $_GET['profile-updated'] ) {
        $message = __( 'There was an error processing your request', 'sage' );
        $message_markup = tutsplus_get_message_markup( $message, 'danger' );
    } elseif ( 'true' == $_GET['password-error'] ) {
        $message = __( 'The passwords you provided did not match', 'sage' );
        $message_markup = tutsplus_get_message_markup( $message, 'danger' );
    }
    return $message_markup . $content;
}
add_filter( 'the_content', 'tutsplus_display_messages', 1 );

Хорошо, не совсем там, мы используем функцию tutsplus_get_message_markup () выше, но мы еще не определили ее. Он принимает два параметра:

a строка: сообщение для отображения строки a: серьезность предупреждения для отображения на основе Bootstrap

Итак, давайте определим нашу функцию tutsplus_get_message_markup ():

<?php
/**
 * A little helper function to generate the Bootstrap alerts markup.
 *
 * @param string $message Message to display.
 * @param string $severity Severity of message to display.
 *
 * @return string Message markup.
 */
function tutsplus_get_message_markup( $message, $severity ) {
    $output = '<div class="alert alert-' . $severity . ' alert-dismissable">';
        $output .= '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">';
            $output .= '<i class="fa fa-times-circle"></i>';
        $output .= '</button>';
        $output .= '<p class="text-center">' . $message . '</p>';
    $output .= '</div>';
    return $output;
}

Отлично. Теперь наши участники могут видеть, сохранены ли их данные или нет.

Дополнительный кредит

Итак, теперь у нас есть рабочий прототип для сайта членства. Большая часть этой функциональности поставляется с WordPress, но мы разработали и изменили ее, чтобы сделать ее лучшим опытом для наших пользователей. Итак, теперь давайте просто расстанем наши «я» и перекрестим наши «Т», чтобы улучшить этот опыт чуть больше.

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

Вот функция, которая помещается в member.php:

<?php
/**
 * Makes pages where this function is called only
 * accessible if you are logged in.
 */
function tutsplus_private_page() {
    if ( ! is_user_logged_in() ) {
        wp_redirect( home_url() );
        exit();
    }
}

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

Затем мы хотим сохранить пользователей - ну, подписчиков - из области администратора. И вдобавок к этому, позвольте нам удалить панель администратора для зарегистрированных пользователей. Опять же, пусть это в нашем членстве.php.

<?php
/**
 * Stop subscribers from accessing the backed
 * Also turn off the admin bar for anyone but administrators.
 */
function tutsplus_lock_it_down() {
    if ( ! current_user_can('administrator') && ! is_admin() ) {
        show_admin_bar( false );
    }
    if ( current_user_can( 'subscriber' ) && is_admin() ) {
        wp_safe_redirect( 'profile' );
    }
}
add_action( 'after_setup_theme', 'tutsplus_lock_it_down' );

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

<?php
/**
 * Outputs some user specific navigation.
 */
function tutsplus_user_nav() {
    $user_id = get_current_user_id();
    $user_name = get_user_meta( $user_id, 'first_name', true );
    $welcome_message = __( 'Welcome', 'sage' ) . ' ' . $user_name;
    echo '<ul class="nav navbar-nav navbar-right">';
        if ( is_user_logged_in() ) {
            echo '<li>';
                echo '<a href="' . home_url( 'profile' ) . '">' . $welcome_message . '</a>';
            echo '</li>';
            echo '<li>';
                echo '<a href="' . wp_logout_url( home_url() ) . '">' . __( 'Log out', 'sage' ) . '</a>';
            echo '</li>';
        } else {
            echo '<li>';
                echo '<a href="' . wp_login_url() . '">' . __( 'Log in', 'sage' ) . '</a>';
            echo '</li>';
        }
    echo '</ul>';
}

Резюме

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

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

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

Замечания

Обратите внимание: если вы загружаете код из репозитория GitHub, он включает в себя все файлы для запуска и запуска вашей темы. Идея состоит в том, что вы можете захватить репо и просто запустить необходимые команды Gulp and Bower, и вам не будет! Если вам просто нужны файлы, содержащие код, специфичный для этой серии, файлы перечислены ниже:

all файлы в каталоге admin lib admin.php lib membership.php template-user-profile.php