Как создать собственную страницу профиля пользователя в WP

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

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

Даже на англоязычных сайтах я ничего не нашел (не знаю, может искал плохо), конечно некоторые решения имелись, но все они были плагинами.

Пример произвольной страницы профиля пользователя на одном из созданных мной сайтов.
Пример произвольной страницы профиля пользователя на одном из созданных мной сайтов.

Шаг 1. Шаблон страницы

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

<?php
/*
 * Template name: Шаблон профиля пользователя
 */
global $user_ID;
 
// если пользователь не авторизован, отправляем его на страницу входа
if( !$user_ID ) {
	header('location:' . site_url() . '/wp-login.php');
	exit;
} else {
	$userdata = get_user_by( 'id', $user_ID );
}
?><html>
<body>
<?php
// после сохранения профиля и смены пароля понадобятся уведомления
// если уведомлений больше двух, то оптимальнее их будет вывести через switch
if( isset($_GET['status']) ) :
	switch( $_GET['status'] ) :
		case 'ok':{
			echo '<div class="success">Сохранено.</div>';
			break;
		}
		case 'exist':{
			echo '<div class="error">Пользователь с указанным email уже существует.</div>';
			break;
		}
		case 'short':{
			echo '<div class="error">Пароль слишком короткий.</div>';
			break;
		}
		case 'mismatch':{
			echo '<div class="error">Пароли не совпадают.</div>';
			break;
		}
		case 'wrong':{
			echo '<div class="error">Старый пароль неверен.</div>';
			break;
		}
		case 'required':{
			echo '<div class="error">Пожалуйста, заполните все обязательные поля.</div>';
			break;
		}
	endswitch;
endif;
 
// profile-update.php - это файл, который находится в папке с темой и обрабатывает сохранение, его содержимое будет в следующем шаге
?>
<form action="<?php echo get_stylesheet_directory_uri() ?>/profile-update.php" method="POST">
	<input type="text" name="first_name" placeholder="Имя" value="<?php echo $userdata->first_name ?>" />
	<input type="text" name="last_name" placeholder="Фамилия" value="<?php echo $userdata->last_name ?>" />
	<input type="text" name="city" placeholder="Город" value="<?php echo get_user_meta($user_ID, 'city', true ) ?>" />
	<input type="email" name="email" placeholder="Email" value="<?php echo $userdata->user_email ?>" />
 
	<input type="password" name="pwd1" placeholder="Старый пароль" />
	<input type="password" name="pwd2" placeholder="Новый пароль" />
	<input type="password" name="pwd3" placeholder="Повторите новый пароль" />
 
	<button>Сохранить</button>
</form>
</body>
</html>

Шаг 2. PHP-файл для обработки сохраняемых данных

Это и есть содержимое файла profile-update.php, который в прошлом шаге мы решили разместить прямо в папке с темой.

<?php
// $_SERVER['HTTP_REFERER'] - полный URL страницы, откуда пришел пользователь
// $url[0] - без GET параметров
// это нам понадобится для правильных редиректов
$url = explode("?",$_SERVER['HTTP_REFERER']);
 
// подключаем WordPress
// тут указан правильный путь, если profile-update.php находится непосредственно в папке с темой
require_once( dirname(__FILE__) . '/../../../wp-load.php' );
 
// если не авторизован, просто выходим из файла
if( !is_user_logged_in() ) exit;
 
// получаем объект пользователя с необходимыми данными
$user_ID = get_current_user_id();
$user = get_user_by( 'id', $user_ID );
 
 
// сначала обработаем пароли, ведь если при сохранении пользователь ничего не указал ни в одном поле пароля, то пропускаем эту часть
if( $_POST['pwd1'] || $_POST['pwd2'] || $_POST['pwd3'] ) {
 
	// при этом пользователь должен заполнить все поля
	if( $_POST['pwd1'] && $_POST['pwd2'] && $_POST['pwd3'] ) {
 
		// сначала проверяем соответствие нового пароля и его подтверждения
		if( $_POST['pwd2'] == $_POST['pwd3'] ){
 
			// пароль из двух символов нам не нужен, минимум 8
			if( strlen( $_POST['pwd2'] ) < 8 ) {
				// если слишком короткий - перенаправляем
				header('location:' . $url[0] . '?status=short');
				exit;
			}
 
			// и самое главное - проверяем, правильно ли указан старый пароль
			if( wp_check_password( $_POST['pwd1'], $user->data->user_pass, $user->ID) ) {
				// если да, меняем на новый и заново авторизуем пользователя
				wp_set_password( $_POST['pwd2'], $user_ID );
				$creds['user_login'] = $user->user_login;
				$creds['user_password'] = $_POST['pwd2'];
				$creds['remember'] = true;
				$user = wp_signon( $creds, false );
			} else {
				// если нет, перенаправляем на ошибку
				header('location:' . $url[0] . '?status=wrong');
				exit;
			}
 
		} else {
			// новый пароль и его подтверждение не соответствуют друг другу
			header('location:' . $url[0] . '?status=mismatch');
			exit;
		}
 
	} else {
		// не все поля заполнены - перенеправляем
		header('location:' . $url[0] . '?status=required');
		exit;
	}
}
 
// допустим, что Имя, Фамилия и Емайл - обязательные поля, Город - не обязательное
if( $_POST['first_name'] && $_POST['last_name'] && is_email($_POST['email']) ) {
 
	// если пользователь указал новый емайл, а кто-то уже под ним зареган - отправляем на ошибку
	if( email_exists( $_POST['email'] ) && $_POST['email'] != $user->user_email ) {
		header('location:' . $url[0] . '?status=exist');
		exit;
	}
 
	// обновляем данные пользователя
	wp_update_user( array( 
			'ID' => $user_ID, 
			'user_email' => $_POST['email'],
			'first_name' => $_POST['first_name'],
			'last_name' => $_POST['last_name'],
			'display_name' => $_POST['first_name'] . ' ' . $_POST['last_name'] ));
 
	// ну и город не забываем обновить
	update_user_meta( $user_ID, 'city', $_POST['city']);
} else {
	// не все поля заполнены - перенеправляем
	header('location:' . $url[0] . '?status=required');
	exit;
}
 
 
// если выполнение кода дошло до сюда, то следовательно всё ок
header('location:' . $url[0] . '?status=ok');
exit;

Если у вас есть вопросы по работе кода или предложения по его доработке, прошу вас проследовать в комментарии :)

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

Почти все функции, использованные в коде статьи

Комментарии 10

  • Max11 декабря 2015 в 11:12 #

    Вау как вовремя! :) Спасибо.
    Миша, а может у тебя есть идеи как вывести создание постов? или уже есть готовая статья?

    Например опубликовал запись + также есть возможность отредактировать или удалить его.
    Такой ответ я думаю лучше оформить все в отдельный пост (вот тебе как идея для нового поста). Так как в инете ничего годного нет. А у тебя мануалы самые понятные :)

  • Виталий11 декабря 2015 в 14:12 #

    ВОУ ВОУ МИША!!!
    СУПЕР!!!!
    сейчас читаю мимолетом, приду с учебы более подробно все протестирую, посмотрю; возникнут вопросы и комментария напишу)))) (обязательно возникнут)
    Спасибо Большое еще раз))

  • Виталий19 декабря 2015 в 00:12 #

    Миша спасибо большое еще раз
    К сожалению только сейчас смог сесть и почитать и все сделать...пришлось уехать на некоторое время по делам и никак не мог добраться
    Если я правильно понял мы создаем:
    Шаблон страницы
    А затем создаем второй файл (который подключили ранее в шаблоне (пункт 1) ) для того чтобы когда пользователь меняет информацию оно могла сохранится и обработаться так?
    Это все работает отлично + я добавил плагин и теперь пользователь может менять аватарку опять же только в админке
    как я не пытался понять и правильно сделать ( с помошью кода) не получается организовать замену аватарке так же как у вас отдельно на странице
    Плюс хотел бы сделать чтобы (пример): пользователь А написал комментарий, пользователь Б нажал на его ник и его перекинуло в профиль пользователя А там аватарка его и инфа там город, телефон, может пару фоточек каких ну простой профиль такие отлично реализованы на DLE

    • Миша19 декабря 2015 в 10:12 #

      Так, без аватарки поля хорошо работают, я правильно понял?

      Относительно URL пользователей - там какой-то хук был вроде бы. Но думаю проще прямо в теме сменить и всё.

    • Max19 декабря 2015 в 11:12 #

      Попробуй плагин WP User Avatar там с помощью шорткода [avatar_upload] можешь загружать аватарки на front-end.

      • Виталий19 декабря 2015 в 15:12 #

        Ок сейчас просмотрю, спасибо.

        Михаил, да и с аваторкой и и без поля работают все хорошо.

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • Владимир: и на третьей строке не хватает скобки ) закрывающей if :)

  • Миша: Добрый вечер! Рекомендую получить ID пользователя через функцию get_current_user_id().

  • Дмитрий: Миша, подскажите пожалуйста, я использую такой редирект, но он не срабатывает: add_action( 'template_redirect', funct...

  • Миша: Ну как не определена - это аргумент функции. Или я просто вас не до конца понимаю.

  • Артем: Ага, понял. Вот только почему $args? Она же нигде не определена, по логике должна быть переменная $true_field_params или...