Страница профиля — на подобии KAMA

Плагины не предлагать - много чего нужно додумывать а ковырять под свои нужды плагины то же не есть хорошо

Хочу создать подобную страницу пользователя как у KAMA
в интернете в основном натыкаюсь на две статьи ENGLISH И RUSSIAN - одна статтья та что на русском - рабочая, но мне не нравятся обработка в URL - у КАМА в URL ничего не происходит

От безопасности далек и могу лишака насовать

Может ли кто поделится своими наработками ?

Заметки к вопросу:
kolshix 6.1 год назад

1 создал отдельный шаблон страницы
2 создал страницу profile
3 добавил в страницу profile свой шаблон
4 добавил отдельный файл php с обработкой
(все файлы в корне темы)

page-profile.php

<?php
/*
 * Template name: Page Profile
 */

get_header(); 

global $user_ID;

// если пользователь не авторизован, отправляем его на страницу входа
if( !$user_ID ) {
	header('location:' . site_url() . '/wp-login.php');
	exit;
} else {
	$userdata = get_user_by( 'id', $user_ID );
}
?>

<style>
.text blockquote, .text dl, .text hr, .text iframe, .text img, .text p, .text pre, .text table {
	margin-bottom: 1.2em;
}
.c_box_green {
	background: #f1ffe0;
	border-color: #dbffaf;
	color: #56a200;
}
._c_box, .c_box_green, .c_box_grey, .c_box_red {
	display: block;
	position: relative;
	padding: .7em 1em;
	margin-bottom: 0.5em;
	border-radius: 2px;
	border: 1px solid #ccc;
}
.success {
	padding: 21px 21px 0px 21px;
}

.error {
	margin: 21px;
	display: block;
	position: relative;
	padding: .7em 1em;
	margin-bottom: 0.5em;
	border-radius: 2px;
	border: 1px solid #ccc;
	background: rgba(255, 233, 224, 0.81);
	border-color: #ffd5af;
	color: rgba(162, 76, 0, 0.87);
}
</style>

<?php
// после сохранения профиля и смены пароля понадобятся уведомления
// если уведомлений больше двух, то оптимальнее их будет вывести через switch
if( isset($_GET['status']) ) :
	switch( $_GET['status'] ) :
		case 'ok':{
			echo '<div class="success"><span class="c_box_green">Save.</span></div>';
			break;
		}
		case 'exist':{
			echo '<div class="error">The user with this email already exists.</div>';
			break;
		}
		case 'short':{
			echo '<div class="error">The password is too short OR too long. (min 8 - max 15)</div>';
			break;
		}
		case 'mismatch':{
			echo '<div class="error">Passwords do not match.</div>';
			break;
		}
		case 'wrong':{
			echo '<div class="error">The old password is incorrect.</div>';
			break;
		}
		case 'required':{
			echo '<div class="error">Please, fill in all required fields.</div>';
			break;
		}
		case 'mailchange':{
			echo '<div class="error">To change the email, you need to enter a password.</div>';
			break;
		}       
		case 'fcharacters':{
			echo '<div class="error">Forbidden characters.</div>';
			break;
		}
	endswitch;
endif;

// profile-update.php - это файл, который находится в папке с темой и обрабатывает сохранение, его содержимое будет в следующем шаге
?>
<div id="page" style="    padding: 21px;    display: block;    min-height: 600px;">
			<style> 
			h2 {

			}
			.form-table th {
				vertical-align: top;
				text-align: left;
				padding: 15px 10px 10px 0;
				width: 200px;
				line-height: 1.3;
				font-weight: 600;
			}
			tr {
				display: table-row;
				vertical-align: inherit;
				border-color: inherit;
			}
			.form-table td {
				margin-bottom: 9px;
				padding: 10px 10px 5px 10px;
				line-height: 1.3;
				vertical-align: middle;
				width: 250px;
			}
			#your-profile {
				width: 100%;
				float: left;
			}
			</style> 
			<form id="your-profile"  action="<?php echo get_stylesheet_directory_uri() ?>/profile-update.php" method="POST">
				<h2 style="background: #caf7aa; padding: 0 0px 0 4px; line-height: 28px;">Personal Options</h2>

				<table class="form-table">
					<tbody>
						<tr class="user-first-name-wrap">
							<th><label for="first_name">First Name</label></th>
							<td><input type="text" name="first_name" placeholder="First Name" value="<?php echo $userdata->first_name ?>" /></td>
							<td>Only the Latin alphabet and numbers</td>
						</tr>

						<tr class="user-last-name-wrap">
							<th><label for="last_name">Last Name</label></th>
							<td><input type="text" name="last_name" placeholder="Last Name" value="<?php echo $userdata->last_name ?>" /></td>
							<td>Only the Latin alphabet and numbers</td>
						</tr>

					</tbody>
				</table>

				<h2 style="background: #caf7aa; padding: 0 0px 0 4px; line-height: 28px;">Contact Info</h2>

				<table class="form-table">
					<tbody>

						<tr class="user-nickname-wrap">
							<th><label for="nickname">Nickname <span class="description">(required)</span></label></th>
							<td><input type="text" name="nickname" placeholder="Nickname" value="<?php echo $userdata->nickname ?>" /></td>
							<td>Only the Latin alphabet and numbers</td>

						</tr>

						<tr class="user-email-wrap">
							<th><label for="email">Email <span class="description">(required)</span></label></th>
							<td><input type="email" name="email" placeholder="Email" value="<?php echo $userdata->user_email ?>" /></td>
							<td>If change - You must fill out a Password</td>                           
						</tr>

					</tbody>
				</table>

				<h2 style="background: #caf7aa; padding: 0 0px 0 4px; line-height: 28px;">Account Management</h2>

				<table class="form-table">
					<tbody>
						<tr class="user-first-name-wrap">
							<th><label for="first_name">Old Password</label></th>
							<td><input type="password" name="pwd1" placeholder="Old Password" /></td> 
							<td><a href="/wp-login.php?action=lostpassword">Lost your password?</a></td>
						</tr>

						<tr class="user-nickname-wrap">
							<th><label for="nickname">New Password <span class="description">(required) </span></label></th>
							<td><input type="password" name="pwd2" placeholder="New Password" /></td>
							<td>min 8 - max 15</td>
						</tr>

						<tr class="user-last-name-wrap">
							<th><label for="last_name">Repeat password</label></th>
							<td><input type="password" name="pwd3" placeholder="Repeat new password" /></td>
						</tr> 
					</tbody>
				</table>
				<style>   
					.myButton {
						-moz-box-shadow: inset 0px -3px 7px 0px #29bbff;
						-webkit-box-shadow: inset 0px -3px 7px 0px #5b89b8;
						box-shadow: inset 0px -3px 7px 0px #5b89b8;
						background: -webkit-gradient(linear, left top, left bottom, color-stop(0.05, #2dabf9), color-stop(1, #0688fa));
						background: -moz-linear-gradient(top, #2dabf9 5%, #0688fa 100%);
						background: -webkit-linear-gradient(top, #2dabf9 5%, #0688fa 100%);
						background: -o-linear-gradient(top, #2dabf9 5%, #0688fa 100%);
						background: -ms-linear-gradient(top, #2dabf9 5%, #0688fa 100%);
						background: linear-gradient(to bottom, #5b89b8 5%, #5b89b8 100%);
						filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2dabf9', endColorstr='#0688fa',GradientType=0);
						background-color: #2dabf9;
						-moz-border-radius: 3px;
						-webkit-border-radius: 3px;
						border-radius: 3px;
						border: 1px solid #0b0e07;
						display: inline-block;
						cursor: pointer;
						color: #ffffff;
						font-family: Arial;
						font-size: 15px;
						padding: 9px 23px;
						text-decoration: none;
						text-shadow: 0px 1px 0px #263666;
					}
					.myButton:hover {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0.05, #4c7ea9), color-stop(1, #235c96));
	background: -moz-linear-gradient(top, #0688fa 5%, #2dabf9 100%);
	background: -webkit-linear-gradient(top, #4985b9 5%, #8ca052 100%);
	background: -o-linear-gradient(top, #0688fa 5%, #2dabf9 100%);
	background: -ms-linear-gradient(top, #0688fa 5%, #2dabf9 100%);
	background: linear-gradient(to bottom, #5b89b8 5%, #5b98b8 100%);
	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0688fa', endColorstr='#2dabf9',GradientType=0);
	background-color: #1489ff;
					}
					.myButton:active {
						position:relative;
						top:1px;
					}

				</style> 
				<p class="submit"><input type="submit" name="submit" id="submit" class="myButton" value="Update User"></p>            
			</form>   
				<?php 
					// get_sidebar(); 
					// locate_template('sidebar_static.php');
					get_template_part( 'sidebar_static' ); 
				?>           
</div>
</div>

<?php get_footer(); ?>

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'] ){

			// пароль из двух символов нам не нужен, минимум 7 b меньше 15 включительно
			if( strlen( $_POST['pwd2'] ) < 7 || strlen( $_POST['pwd2'] ) > 15 ) {
				// если слишком короткий - перенаправляем
				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;
		}
	// Проверка - был ли изменен ЕМЕЙЛ, но пароль не заполнен 
	} elseif ( $user->user_email !== $_POST['email']){
		if( $_POST['pwd1']){
			// проверка правельности пароля, если все впорядке идем дальше
			if( wp_check_password( $_POST['pwd1'], $user->data->user_pass, $user->ID) ) {

			} else {
				// если нет, перенаправляем на ошибку
				header('location:' . $url[0] . '?status=wrong');
				exit;
			}
		} else {
			// Емейл изменен но пароль не заполнен
			header('location:' . $url[0] . '?status=mailchange');
			exit;
		}   
	} else {
		// не все поля заполнены - перенеправляем
		header('location:' . $url[0] . '?status=required');
		exit;
	}

// Проверка - был ли изменен логин, но пароль не заполнен 
} elseif ( $user->user_email !== $_POST['email']){
	// и самое главное - проверяем, правильно ли указан старый пароль
	if( wp_check_password( $_POST['pwd1'], $user->data->user_pass, $user->ID) ) {

	} else {
		// если нет, перенаправляем на ошибку
		header('location:' . $url[0] . '?status=mailchange');
		exit;
	}   
}

// проверка на  спецсимволы 
//     || 

if ( ! preg_match('/^[_a-zA-Z0-9-]+$/', $_POST['nickname'] ) || ! preg_match('/^[_a-zA-Z0-9-]+$/', $_POST['first_name']) ||  ! preg_match('/^[_a-zA-Z0-9-]+$/', $_POST['last_name']) ){ 
	header('location:' . $url[0] . '?status=fcharacters');
	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'],
			'nickname'      => $_POST['nickname'],
			'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;