В этой статье создадим продвинутую форму регистрации с:
- Валидацией данных
- Условными полями (для врачей)
- Защитой от злоупотреблений
- Автоматическим входом после регистрации
Преимущества решения:
✔ Полный контроль над процессом регистрации
✔ Гибкая система проверки данных
✔ Безопасность через nonce и ограничение попыток
✔ Профессиональный пользовательский опыт
Шаг 1: Подготовка HTML-формы
Разместите этот код там, где должна отображаться форма — в шаблоне страницы, виджете или через шорткод:
<form id="custom-register-form">
<!-- Скрытые поля безопасности -->
<input type="hidden" name="security" value="<?php echo wp_create_nonce('custom-register-nonce'); ?>">
<!-- Основные поля -->
<div class="form-group">
<label for="email">E-mail *</label>
<input type="email" name="email" id="email" required>
</div>
<div class="form-group">
<label for="fullname">ФИО *</label>
<input type="text" name="fullname" id="fullname" required>
</div>
<!-- Поля пароля с уникальными ID -->
<div class="form-group">
<label for="register_password">Пароль *</label>
<input type="password" name="password" id="register_password" required minlength="6">
</div>
<div class="form-group">
<label for="register_password_repeat">Повторите пароль *</label>
<input type="password" name="password_repeat" id="register_password_repeat" required>
</div>
<!-- Выбор типа пользователя -->
<div class="form-group">
<label for="user_type">Тип пользователя *</label>
<select name="user_type" id="user_type" required>
<option value="">Выберите тип</option>
<option value="student">Студент</option>
<option value="doctor">Врач</option>
<option value="user">Пользователь</option>
</select>
</div>
<!-- Условное поле для врачей (изначально скрыто) -->
<div class="form-group" id="file-upload-group" style="display: none;">
<label for="doctor_file">Документ, подтверждающий статус врача *</label>
<input type="file" name="doctor_file" id="doctor_file" accept=".pdf,.doc,.docx,.jpg,.png">
<p class="file-hint">Формат: PDF, DOC, JPG или PNG (макс. 2MB)</p>
</div>
<button type="submit">Зарегистрироваться</button>
<!-- Контейнер для сообщений -->
<div id="register-message" class="message"></div>
</form>
Шаг 2: Добавляем JavaScript логику
Создаем файл js/custom-register.js:
Часть 1: Инициализация и показ полей
window.addEventListener('load', function() {
const form = document.getElementById('custom-register-form');
if (!form) return;
const userTypeSelect = document.getElementById('user_type');
const fileUploadGroup = document.getElementById('file-upload-group');
const messageEl = document.getElementById('register-message');
// Показываем/скрываем поле для файла при изменении типа пользователя
userTypeSelect.addEventListener('change', function() {
fileUploadGroup.style.display = this.value === 'doctor' ? 'block' : 'none';
});
});
Часть 2: Обработка отправки формы
form.addEventListener('submit', async function(e) {
e.preventDefault();
// Сброс состояния сообщений
messageEl.textContent = '';
messageEl.className = 'message';
// Получаем значения полей
const formData = {
email: form.email.value.trim(),
fullname: form.fullname.value.trim(),
password: form.register_password.value.trim(),
password_repeat: form.register_password_repeat.value.trim(),
user_type: form.user_type.value,
security: form.security.value
};
// Базовая валидация
if (!formData.email || !formData.fullname || !formData.password ||
!formData.password_repeat || !formData.user_type) {
showMessage('Пожалуйста, заполните все обязательные поля', 'error');
return;
}
if (formData.password !== formData.password_repeat) {
showMessage('Пароли не совпадают', 'error');
return;
}
if (formData.password.length < 6) {
showMessage('Пароль должен содержать минимум 6 символов', 'error');
return;
}
Часть 3: Специальная валидация для врачей
// Валидация для врачей
if (formData.user_type === 'doctor') {
const fileInput = document.getElementById('doctor_file');
if (!fileInput.files || fileInput.files.length === 0) {
showMessage('Необходимо загрузить документ', 'error');
return;
}
const file = fileInput.files[0];
const validTypes = [
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'image/jpeg',
'image/png'
];
const maxSize = 2 * 1024 * 1024; // 2MB
if (!validTypes.includes(file.type)) {
showMessage('Недопустимый формат файла', 'error');
return;
}
if (file.size > maxSize) {
showMessage('Файл слишком большой (макс. 2MB)', 'error');
return;
}
}
Часть 4: Отправка данных на сервер
// Подготовка данных для отправки
const data = new FormData();
for (const key in formData) {
data.append(key, formData[key]);
}
// Добавляем файл для врачей
if (formData.user_type === 'doctor') {
data.append('doctor_file', document.getElementById('doctor_file').files[0]);
}
// Отправка данных
try {
const response = await fetch(customVars.rest_register_url, {
method: 'POST',
headers: {
'X-WP-Nonce': customVars.rest_nonce
},
body: data
});
const result = await response.json();
if (result.success) {
showMessage(result.message, 'success');
if (result.redirect) {
setTimeout(() => {
window.location.href = result.redirect;
}, 2000);
}
} else {
showMessage(result.message, 'error');
}
} catch (error) {
showMessage('Ошибка соединения с сервером', 'error');
console.error('Registration error:', error);
}
});
// Функция для показа сообщений
function showMessage(text, type) {
messageEl.innerHTML = text;
messageEl.className = `message ${type}`;
}
});
Шаг 3: Серверная обработка (PHP)
Добавляем в functions.php:
Часть 1: Регистрация REST endpoint
add_action('rest_api_init', function() {
register_rest_route('wp/v2', '/custom-register', [
'methods' => 'POST',
'callback' => 'handle_custom_register',
'permission_callback' => '__return_true',
]);
});
Часть 2: Обработчик регистрации
function handle_custom_register(WP_REST_Request $request) {
// Проверка nonce
if (!wp_verify_nonce($request['security'], 'custom-register-nonce')) {
return new WP_REST_Response([
'success' => false,
'message' => 'Ошибка безопасности сессии'
], 200);
}
// Получение и очистка данных
$email = sanitize_email($request['email']);
$fullname = sanitize_text_field($request['fullname']);
$password = $request['password'];
$user_type = sanitize_text_field($request['user_type']);
// Валидация email
if (!is_email($email)) {
return new WP_REST_Response([
'success' => false,
'message' => 'Некорректный email'
], 200);
}
if (email_exists($email)) {
return new WP_REST_Response([
'success' => false,
'message' => 'Этот email уже зарегистрирован'
], 200);
}
// Валидация пароля
if (strlen($password) < 6) {
return new WP_REST_Response([
'success' => false,
'message' => 'Пароль должен содержать минимум 6 символов'
], 200);
}
Часть 3: Обработка врачей
// Специальная проверка для врачей
if ($user_type === 'doctor') {
if (empty($_FILES['doctor_file'])) {
return new WP_REST_Response([
'success' => false,
'message' => 'Необходимо загрузить документ'
], 200);
}
$file = $_FILES['doctor_file'];
$valid_types = [
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'image/jpeg',
'image/png'
];
$max_size = 2 * 1024 * 1024; // 2MB
if (!in_array($file['type'], $valid_types)) {
return new WP_REST_Response([
'success' => false,
'message' => 'Недопустимый формат файла'
], 200);
}
if ($file['size'] > $max_size) {
return new WP_REST_Response([
'success' => false,
'message' => 'Файл слишком большой (макс. 2MB)'
], 200);
}
}
Часть 4: Создание пользователя
// Создание пользователя
$user_id = wp_create_user($email, $password, $email);
if (is_wp_error($user_id)) {
return new WP_REST_Response([
'success' => false,
'message' => $user_id->get_error_message()
], 200);
}
// Сохранение дополнительных полей
update_user_meta($user_id, 'fullname', $fullname);
update_user_meta($user_id, 'user_type', $user_type);
// Обработка файла для врачей
if ($user_type === 'doctor' && !empty($_FILES['doctor_file'])) {
require_once(ABSPATH . 'wp-admin/includes/file.php');
$upload = wp_handle_upload($_FILES['doctor_file'], ['test_form' => false]);
if ($upload && !isset($upload['error'])) {
update_user_meta($user_id, 'doctor_document', $upload['url']);
} else {
error_log('File upload error: ' . $upload['error']);
}
}
// Автоматический вход после регистрации
$user = wp_signon([
'user_login' => $email,
'user_password' => $password,
'remember' => true
], false);
return new WP_REST_Response([
'success' => true,
'message' => 'Регистрация прошла успешно!',
'redirect' => home_url('/')
], 200);
}
Шаг 4: Подключение скриптов и стилей
В том же functions.php добавляем:
// Регистрация скриптов
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script(
'custom-register',
get_template_directory_uri() . '/js/custom-register.js',
array(),
filemtime(get_template_directory() . '/js/custom-register.js'),
true
);
wp_localize_script('custom-register', 'customVars', [
'rest_register_url' => rest_url('wp/v2/custom-register'),
'rest_nonce' => wp_create_nonce('wp_rest')
]);
});
// Стили формы
add_action('wp_head', function() {
echo '<style>
#custom-register-form {
max-width: 500px;
margin: 2rem auto;
padding: 2rem;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.message {
margin-top: 1.5rem;
padding: 1rem;
border-radius: 4px;
}
.message.success {
background: #edfaef;
color: #00a32a;
border: 1px solid #00a32a;
}
.message.error {
background: #f8ebea;
color: #d63638;
border: 1px solid #d63638;
}
</style>';
});
Итоги
Мы создали полнофункциональную форму регистрации с:
- Валидацией на стороне клиента и сервера
- Условными полями для разных типов пользователей
- Защитой от злоупотреблений
- Автоматическим входом после регистрации
Чтобы внедрить это решение:
- Разместите HTML-код формы в нужном шаблоне
- Добавьте JavaScript в файл
/js/custom-register.js - Вставьте PHP-код в
functions.phpвашей темы - Проверьте работу всех сценариев
Дальнейшие улучшения могут включать:
- Подтверждение email
- Капчу для защиты от ботов
- Интеграцию с социальными сетями
- Двухфакторную аутентификацию
Форма готова к использованию и обеспечит удобный и безопасный процесс регистрации для ваших пользователей.