Как редактировать профиль пользователя на фронтенде?
Вы можете сделать это, скопировав файл page.php вашей темы в новый файл с именем, например, user-profile.php, и добавив в самое начало следующий код:
<?php
/**
* Имя шаблона: Профиль пользователя
*
* Позволяет пользователям обновлять свои профили из фронтенда.
*
*/
/* Получаем информацию о пользователе. */
global $current_user, $wp_roles;
//get_currentuserinfo(); //устарело с версии 3.1
/* Загружаем файл регистрации. */
//require_once( ABSPATH . WPINC . '/registration.php' ); //устарело с версии 3.1
$error = array();
/* Если профиль был сохранён, обновляем его. */
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'update-user' ) {
/* Обновляем пароль пользователя. */
if ( !empty($_POST['pass1'] ) && !empty( $_POST['pass2'] ) ) {
if ( $_POST['pass1'] == $_POST['pass2'] )
wp_update_user( array( 'ID' => $current_user->ID, 'user_pass' => esc_attr( $_POST['pass1'] ) ) );
else
$error[] = __('Введённые пароли не совпадают. Ваш пароль не был обновлён.', 'profile');
}
/* Обновляем информацию о пользователе. */
if ( !empty( $_POST['url'] ) )
wp_update_user( array( 'ID' => $current_user->ID, 'user_url' => esc_url( $_POST['url'] ) ) );
if ( !empty( $_POST['email'] ) ){
if (!is_email(esc_attr( $_POST['email'] )))
$error[] = __('Введённый email недействителен. Пожалуйста, попробуйте снова.', 'profile');
elseif(email_exists(esc_attr( $_POST['email'] )) != $current_user->ID )
$error[] = __('Этот email уже используется другим пользователем. Попробуйте другой.', 'profile');
else{
wp_update_user( array ('ID' => $current_user->ID, 'user_email' => esc_attr( $_POST['email'] )));
}
}
if ( !empty( $_POST['first-name'] ) )
update_user_meta( $current_user->ID, 'first_name', esc_attr( $_POST['first-name'] ) );
if ( !empty( $_POST['last-name'] ) )
update_user_meta($current_user->ID, 'last_name', esc_attr( $_POST['last-name'] ) );
if ( !empty( $_POST['description'] ) )
update_user_meta( $current_user->ID, 'description', esc_attr( $_POST['description'] ) );
/* Перенаправляем, чтобы страница отобразила обновлённую информацию. */
/*Я не автор этого кода - не знаю почему, но это сработало для меня после изменения строки ниже на if ( count($error) == 0 ){ */
if ( count($error) == 0 ) {
//хук для плагинов и сохранения дополнительных полей
do_action('edit_user_profile_update', $current_user->ID);
wp_redirect( get_permalink() );
exit;
}
}
?>
затем замените цикл этой страницы на следующий:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div id="post-<?php the_ID(); ?>">
<div class="entry-content entry">
<?php the_content(); ?>
<?php if ( !is_user_logged_in() ) : ?>
<p class="warning">
<?php _e('Вы должны войти в систему, чтобы редактировать свой профиль.', 'profile'); ?>
</p><!-- .warning -->
<?php else : ?>
<?php if ( count($error) > 0 ) echo '<p class="error">' . implode("<br />", $error) . '</p>'; ?>
<form method="post" id="adduser" action="<?php the_permalink(); ?>">
<p class="form-username">
<label for="first-name"><?php _e('Имя', 'profile'); ?></label>
<input class="text-input" name="first-name" type="text" id="first-name" value="<?php the_author_meta( 'first_name', $current_user->ID ); ?>" />
</p><!-- .form-username -->
<p class="form-username">
<label for="last-name"><?php _e('Фамилия', 'profile'); ?></label>
<input class="text-input" name="last-name" type="text" id="last-name" value="<?php the_author_meta( 'last_name', $current_user->ID ); ?>" />
</p><!-- .form-username -->
<p class="form-email">
<label for="email"><?php _e('E-mail *', 'profile'); ?></label>
<input class="text-input" name="email" type="text" id="email" value="<?php the_author_meta( 'user_email', $current_user->ID ); ?>" />
</p><!-- .form-email -->
<p class="form-url">
<label for="url"><?php _e('Веб-сайт', 'profile'); ?></label>
<input class="text-input" name="url" type="text" id="url" value="<?php the_author_meta( 'user_url', $current_user->ID ); ?>" />
</p><!-- .form-url -->
<p class="form-password">
<label for="pass1"><?php _e('Пароль *', 'profile'); ?> </label>
<input class="text-input" name="pass1" type="password" id="pass1" />
</p><!-- .form-password -->
<p class="form-password">
<label for="pass2"><?php _e('Повторите пароль *', 'profile'); ?></label>
<input class="text-input" name="pass2" type="password" id="pass2" />
</p><!-- .form-password -->
<p class="form-textarea">
<label for="description"><?php _e('Биографическая информация', 'profile') ?></label>
<textarea name="description" id="description" rows="3" cols="50"><?php the_author_meta( 'description', $current_user->ID ); ?></textarea>
</p><!-- .form-textarea -->
<?php
//хук для плагинов и дополнительных полей
do_action('edit_user_profile',$current_user);
?>
<p class="form-submit">
<?php //echo $referer; ?>
<input name="updateuser" type="submit" id="updateuser" class="submit button" value="<?php _e('Обновить', 'profile'); ?>" />
<?php wp_nonce_field( 'update-user' ) ?>
<input name="action" type="hidden" id="action" value="update-user" />
</p><!-- .form-submit -->
</form><!-- #adduser -->
<?php endif; ?>
</div><!-- .entry-content -->
</div><!-- .hentry .post -->
<?php endwhile; ?>
<?php else: ?>
<p class="no-data">
<?php _e('Извините, ни одна страница не соответствует вашим критериям.', 'profile'); ?>
</p><!-- .no-data -->
<?php endif; ?>
и всё, что вам остаётся сделать — это создать новую страницу и выбрать шаблон "Профиль пользователя".
Если всё это кажется вам слишком сложным, вы можете использовать плагины, которые сделают всю работу за вас:

Ваш ответ отлично сработал для меня! Могу ли я использовать похожий метод для редактирования существующей записи? Смотрите мой вопрос здесь: http://wordpress.stackexchange.com/questions/9912/front-end-post-editing-using-a-form

работает ли этот метод с произвольными полями в форме регистрации тоже?

Спасибо, работает отлично. Как я могу добавить сообщение, которое появляется после успешного обновления профиля? Сейчас ничего не происходит.

На самом деле, кажется, у меня получилось, это приемлемо? Я изменил ваш код на:
if ( !$error ) {
wp_redirect( get_permalink() .'?updated=true' );
exit;
}
и затем добавил <?php if ( $_GET['updated'] == 'true' ) : ?> <p>Ваш профиль был обновлен</p> <?php endif; ?>

Спасибо за это, однако email и сайт не обновляются. Другие поля обновляются нормально. Можете предположить, в чем может быть причина? Спасибо.

@Nicola, у меня была такая же проблема. Дело в том, что email и URL сайта не являются метаданными пользователя; они хранятся в таблице wp_users
(в отличие от таблицы wp_usermeta
). Чтобы обновить email и URL, нужно использовать wp_update_user()
, а не update_usermeta()
.

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

Это пример, который вы можете редактировать и добавлять свои проверки

@BandonRandon Я обновил код, добавив простую валидацию email, проверку на дубликаты и несколько хуков действий, которые использует WordPress, чтобы позволить интеграцию с плагинами. Спасибо

Отлично, я уже начал это модифицировать, и всё работает довольно хорошо. Просто отмечу, что другие указали - email использует wp_update_user
, а не update_usermeta
, но это легко исправить

Пожалуйста, прочитайте это @Bainternet. Не был удивлён, когда дочитал до конца и увидел ваш аватар

Ошибка: registration.php устарел начиная с версии 3.1 без доступной альтернативы. Этот файл больше не нужно включать.

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

@Bainternet спасибо за отличный кусок кода. Внес некоторые исправления и закомментировал устаревшие строки.

Мы используем PRO-версию ProfilePress (https://profilepress.net) для редактирования профиля на фронтенде и не могли бы быть более довольны.

эта переменная $referer вечно одинока в коде. Думаю, поэтому меня не перенаправляет после обновления.

Я использовал этот код для гостевых пользователей, чтобы они могли изменять только свое Отображаемое имя. Удается получить необходимые поля, однако не получается сохранить изменения. Прикрепленный PHP файл доступен на pastebin: https://pastebin.com/4sXXu8MU
