Раздельная регистрация и вход для разных ролей
Я создал 2 новые роли для моего сайта, используя плагин "Members" - "продавцы" и "покупатели".
Каждая роль должна иметь свою собственную страницу регистрации и входа. Посетитель может зарегистрироваться как покупатель и как продавец, но он может быть авторизован только в одной из этих ролей. Таким образом, если посетитель вошел как продавец и затем переходит на страницу покупателя, он сможет войти как покупатель, и при этом автоматически выйдет из системы как продавец.
Я часами искал плагин, который предоставил бы мне возможность сделать это, но не смог найти. Звучит как довольно распространенная конфигурация для сайтов с регистрацией разных ролей.
Существует ли вообще такой плагин? И если нет, как это можно реализовать?
Создание отдельных форм регистрации для разных ролей довольно просто:
//создаем скрытое поле для роли
add_action('register_form','add_hidden_role_field');
function add_hidden_role_field(){
if (isset($_GET['role'])){
echo '<input id="user_email" type="hidden" tabindex="20" size="25" value="'.$_GET['role'].'" name="role"/>';
}
}
add_action('user_register', 'update_role');
//сохраняем роль
function update_role($user_id, $password="", $meta=array()) {
if (isset($_POST['role'])){
$userdata = array();
$userdata['ID'] = $user_id;
$userdata['role'] = $_POST['role'];
//разрешаем только для ролей seller и buyer, чтобы избежать появления новых админов
if (($userdata['role'] == "seller") or ($userdata['role'] == "buyer")){
wp_update_user($userdata);
}
}
}
Теперь можно привязать каждую роль к своей форме регистрации:
seller: http://example.com/wp-login.php?action=register&role=seller
buyer: http://example.com/wp-login.php?action=register&role=buyer
Но, как заметил Milo:
"если кто-то зарегистрировался как buyer, он не сможет войти под другими ролями с теми же учетными данными"
Это означает, что для регистрации другой роли потребуется другой email.
Обновление
Вот пример, показывающий как использовать одну форму, но с разными полями для каждой роли.
Нужно немного изменить функции:
//создаем скрытое поле для роли и дополнительные поля
add_action('register_form','add_hidden_role_field');
function add_hidden_role_field(){
if (isset($_GET['role'])){
$user_type = $_GET['role'];
echo '<input id="user_email" type="hidden" tabindex="20" size="25" value="'.$_GET['role'].'" name="role"/>';
}
if (isset($user_type) && $user_type == "seller"){
//добавляем дополнительные поля для продавца, например:
?>
Название компании:
<input id="user_email" type="text" tabindex="20" size="25" value="" name="business_name"/>
Адрес компании:
<input id="user_email" type="text" tabindex="20" size="25" value="" name="business_address"/>
<?php
}
if (isset($user_type) && $user_type == "buyer"){
//добавляем дополнительные поля для покупателя, например:
?>
Имя покупателя:
<input id="user_email" type="text" tabindex="20" size="25" value="" name="buyer_name"/>
<?php
}
}
Теперь будут отображаться только поля, нужные для конкретной роли.
Если нужно добавить валидацию для этих полей, можно использовать хук register_post
:
add_action('register_post','my_user_fields_validation',10,3);
function my_user_fields_validation($login, $email, $errors) {
global $firstname, $lastname;
//получаем роль для проверки
if (isset($_POST['role'])){
$user_type = $_POST['role'];
}
//проверяем поля в зависимости от роли
if (isset($user_type) && $user_type == "seller"){
//проверяем поля продавца
if ($_POST['business_name'] == '') {
$errors->add('empty_business_name', "<strong>ОШИБКА</strong>: Пожалуйста, укажите название компании");
}
if ($_POST['business_address'] == '') {
$errors->add('empty_business_address', "<strong>ОШИБКА</strong>: Пожалуйста, укажите адрес компании");
}
}
if (isset($user_type) && $user_type == "buyer"){
//проверяем поля покупателя
if ($_POST['buyer_name'] == '') {
$errors->add('empty_buyer_name', "<strong>ОШИБКА</strong>: Пожалуйста, укажите имя покупателя");
}
}
}
Если все в порядке, сохраняем поля в метаданных пользователя в зависимости от роли:
add_action('user_register', 'update_role');
//сохраняем роль
function update_role($user_id, $password="", $meta=array()) {
if (isset($_POST['role'])){
$userdata = array();
$userdata['ID'] = $user_id;
$userdata['role'] = $_POST['role'];
$user_type = $_POST['role'];
//разрешаем только для ролей seller и buyer
if (($userdata['role'] == "seller") or ($userdata['role'] == "buyer")){
wp_update_user($userdata);
}
if (isset($user_type) && $user_type == "seller"){
//сохраняем поля продавца
update_user_meta($user_id, 'business_name', $_POST['business_name']);
update_user_meta($user_id, 'business_address', $_POST['business_address']);
}
if (isset($user_type) && $user_type == "buyer"){
//сохраняем поля покупателя
update_user_meta($user_id, 'buyer_name', $_POST['buyer_name']);
}
}
}

Спасибо, Bainternet и Milo!
Да, я имею в виду, что посетитель будет регистрироваться дважды — один раз как продавец, а другой как покупатель, с разными email.
Но мне действительно нужны две отдельные формы регистрации, поскольку каждая из них будет содержать разные поля. Например: форма регистрации продавца будет включать поля — "название компании" и "адрес компании", а форма регистрации покупателя будет содержать поле "имя покупателя".
Так что, Bainternet, я не уверен, что могу использовать ваш код в текущем виде (но большое спасибо за усилия), так как он ссылается на одну и ту же страницу, только с разными параметрами.
Как я могу сделать это с двумя отдельными формами?

@Ash: вам всё ещё не нужны две отдельные формы, просто добавьте поля в зависимости от роли. Я обновил свой ответ с примером.

@Bainternet: Извините за новичковый вопрос, но я только учусь :-) - этот код можно использовать только в плагине или также в php-файле, который является шаблоном страницы?

Либо в плагине, либо в functions.php темы. Для других вариантов потребуется подключение дополнительных файлов.

@Bainternet: Хорошо. Проблема с регистрацией понятна. Очень благодарен!
Не могли бы вы также помочь с вопросом входа в систему? Я знаю, что это не стандартное поведение WordPress, но именно так должен работать мой сайт.
Чтобы было понятнее, вот необходимое поведение - если посетитель вошел как покупатель, а затем переходит на страницу входа для продавцов, он должен видеть себя как не вошедшего в систему как продавец. Затем, если он войдет как продавец, он автоматически выйдет из системы как покупатель. В противном случае, если он вернется на страницу покупателя, он увидит себя все еще вошедшим как покупатель.
Еще раз спасибо.

@bainternet, при ошибках функция my_user_fields_validation
перезагружает/использует ссылку http://example.com/wp-login.php?action=register
, а не роль-специфичную ссылку, например http://example.com/wp-login.php?action=register&role=seller
. Можете улучшить эту функцию?

@lurie вы можете установить и читать cookie роли. Задайте новый вопрос, и я помогу вам.

@Bainternet, я задал новый вопрос. Спасибо!

Вместо использования хука register_post для валидации вам следует использовать фильтр registration_errors. Смотрите http://codex.wordpress.org/Plugin_API/Action_Reference/register_post
