Очень частой задачей является перенести пользователей со старой системы 1С-Битрикс на новую. При этом мы конечно же хотим сохранить весь процесс незаметным для клиента что бы не приходилось делать массовую рассылку с временным паролем и так далее.
Очень частой задачей является перенести пользователей со старой системы 1С-Битрикс на новую. При этом мы конечно же хотим сохранить весь процесс незаметным для клиента что бы не приходилось делать массовую рассылку с временным паролем и так далее.
Экспорт пользователей
Мы можем настроить необходимые столбцы и экспортировать данные в формате Excel с помощью стандартного функционала Битрикс, так же можно сделать экспорт через phpMyAdmin, но мы решили написать этот функционал самостоятельно. На исходном сайте создаем файл, например users.php со следующим содержимым:
// Подключаем пролог Bitrix require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); // Проверяем права доступа if (!$USER->IsAdmin()) { die("Access denied"); } // Устанавливаем заголовки для скачивания CSV файла header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=users.csv'); // Открываем поток для записи в файл $output = fopen('php://output', 'w'); // Записываем заголовки столбцов fputcsv($output, array('ID', 'NAME', 'LAST_NAME' ,'LOGIN','PASSWORD', 'EMAIL')); $rsUsers = CUser::GetList(($by="sort"), ($order="desc"), array()); $users = []; while ($arUser = $rsUsers->Fetch()) { if(empty($arUser['NAME'])) $arUser['NAME'] = 'EMPTY'; if(empty($arUser['LAST_NAME'])) $arUser['LAST_NAME'] = 'EMPTY'; $users[] = $arUser; } foreach($users as $user) { fputcsv($output, array( $user['ID'], $user['NAME'], $user['LAST_NAME'], $user['LOGIN'], $user['PASSWORD'], $user['EMAIL'], )); } // Закрываем поток fclose($output); // Завершаем выполнение скрипта require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");
После запуска скрипта будет скачан файл .csv со списком пользователей, мы не будем рассматривать в этой статье ситуацию с большим объемом данных, в таких случаях обмен можно выполнять частями.
Промежуточная таблица
Основная задумка в том, что нам необходимо создать промежуточную таблицу для пользователей перед их загрузкой, а после добавления уже внести данные в эту таблицу, в этом случае мы сможем сравнивать хэш паролей перед авторизацией клиентов и в случае совпадения обновлять незаметно пароль и удалять запись из промежуточной таблицы.
Создаем таблицу (Настройки-> Инструменты -> SQL запрос):
CRE ATE TABLE `old_user` ( `LOGIN` varchar(60) NOT NULL, `HASH` varchar(64) NOT NULL, PRIMARY KEY (`LOGIN`) );
Экспорт пользователей
Перед добавлением пользователей в базу регистрируем обработчик события OnBeforeUserAdd
AddEventHandler("main", "OnBeforeUserAdd", "__beforeUserAdd");
function __beforeUserAdd($arParams)
{
if (defined("USER_IMPORT_EXECUTION_TIME")) {
global $DB;
$from_old = "FROM old_user where LOGIN='".$arParams["LOGIN"]."';";
$rsOLDUser = $DB->Query("SELECT * $from_old");
if (!($rsOLDUser->GetNext())) {
$DB->Insert("old_user", array(
"LOGIN" => "'" . $DB->ForSQL($arParams["LOGIN"]) . "'",
"HASH" => "'" . $DB->ForSQL($arParams["PASSWORD"]) . "'"
));
}
}
}
Как только обработчик готов можно запускать импорт пользователей из CSV файла.
Сравниваем хэш паролей перед авторизацией с помощью события OnBeforeUserLogin
Пишем обработчик события OnBeforeUserLogin в котором после ввода пароля мы сравниваем его хэш со старым хэшем из промежуточной таблицы и если они совпали обновляем хэш пароля пользователя, авторизуем его в системе и удаляем из промежуточной таблицы.
AddEventHandler("main", "OnBeforeUserLogin", "__beforeUserLogin");
function __beforeUserLogin($arParams)
{
global $DB;
$login = $DB->ForSQL($arParams["LOGIN"]);
$password = $arParams["PASSWORD"];
$from_old = "FROM old_user where LOGIN='$login';";
// Ищем пользователя с таким логином в "old_user"
$rsOLDUser = $DB->Query("SELECT * $from_old");
if(!($arOLDUser = $rsOLDUser->GetNext()))
return true;
// Ищем пользователя с таким логином в базе Битрикса
$rsBXUser = CUser::GetByLogin($login);
if(!($arBXUser = $rsBXUser->GetNext()))
return true;
// Проверяем правильность присланного пароля
// алгоритмом старой системы
if(!password_verify($password, $arOLDUser['HASH']))
return true;
// Обновляем пароль пользователя в базе Битрикса
$USER = new CUser;
$bUbdate = $USER->Update($arBXUser["ID"], array("PASSWORD" => $password));
unset($USER);
if(!$bUbdate)
return true;
// А затем удаляем пользователя из "old_user"
$DB->Query("DELETE $from_old");
return true;
}
После экспорта пользователей обработчик __beforeUserAdd можно удалить, и периодически проверять промежуточную таблицу, как только она опустее можно удалять. Всем спасибо за внимание, если возникнут сложности или понадобится профессиональная помощь мы всегда на связи.