Статьи

Как разработать сайт членства с помощью WordPress: Часть 3

Конечный продукт
Что вы будете создавать

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

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

1
2
3
4
5
<?php
 
/**
 * Template Name: User Profile
 */

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

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

Профиль пользователя

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

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

  1. Скопируйте и вставьте код из page.php в наш шаблон страницы.
  2. Найти, где контент выводится.
  3. Прямо под этим вставьте следующий код, а затем мы пройдемся по нему:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<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’ );
        <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’ );
        <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’ );
        <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’ );
        <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’ );
        <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’ );
        <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’ );
</form>

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

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

value="<?php echo $user_info->first_name; ?>"

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

01
02
03
04
05
06
07
08
09
10
11
<?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 следующим образом: <?php var_dump($user_info); ?> <?php var_dump($user_info); ?> . Это может быть полезно для отладки или просто для просмотра того, к чему вы можете получить доступ.

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

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

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?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() для имени Twitter
  • wp_set_password() для пароля
  • wp_update_user() для оставшихся данных

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

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

<?php do_action( 'tutsplus_process_user_profile' ); ?>

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

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

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

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?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 .
}
 
add_filter( ‘the_content’, ‘tutsplus_display_messages’, 1 );

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

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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»>’ .
    $output .= ‘</div>’;
 
    return $output;
     
}

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

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

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?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();
         
    }
     
}

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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, где отображается основная навигация.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?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’ ) .
 
    echo ‘<ul class=»nav navbar-nav navbar-right»>’;
 
        if ( is_user_logged_in() ) {
 
            echo ‘<li>’;
                echo ‘<a href=»‘ . home_url( ‘profile’ ) . ‘»>’ .
            echo ‘</li>’;
            echo ‘<li>’;
                echo ‘<a href=»‘ . wp_logout_url( home_url() ) . ‘»>’ .
            echo ‘</li>’;
 
        } else {
 
            echo ‘<li>’;
                echo ‘<a href=»‘ . wp_login_url() . ‘»>’ .
            echo ‘</li>’;
 
        }
 
    echo ‘</ul>’;
     
}

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

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

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

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