Скрипт для чистки дубликатов пользователей с перепривязкой заказов в 1С-Битрикс
У одного из наших клиентов возникла проблема с дубликатами пользователей (покупателей) на сайте. Возникла она из-за того, что изначально в интернет-магазине не стояла настройка «Проверять email на уникальность при регистрации». Из-за этого покупатели, когда без авторизации в интернет-магазине, совершали заказ, то вводили свои данные и Битрикс создавал нового пользователя (логин равен адресу электронной почты) и привязывал заказ к этому новому пользователю. И все было замечательно до тех пор, пока в интернет-магазине не ввели скидочную систему, благодаря которой покупатели стали уже внимательнее относиться к своим аккаунтам (регистрироваться с одинаковыми email тоже запретили, чтобы новых дубликатов пользователей не появлялось).
Но возникли проблемы со старыми пользователями:
- Покупатели само собою не могли вспомнить свой пароль и восстановить доступ у них не получалось, т.к. с таким email было несколько пользователей.
- Удалить лишних пользователей нельзя, т.к. к ним привязаны заказы.
- Необходимо собрать все заказы с дублей пользователей, чтобы покупатель видел все свои заказы и могла рассчитаться правильно скидка.
Чтобы решить все, перечисленные проблемы дублей пользователей, решено было оставить только самого первого пользователя с одинаковым логином (все заказы одинаковых логинов перепривязать к нему), остальных пользователей удалить.
Конечно, все это можно делать ручками для каждого покупателя, но это не наш метод. Наш метод - написать скрипт для обработки всех пользователей и их заказов. Этот скрипт надо выполнить внутри админки сайта на странице адрес_сайта/bitrix/admin/php_command_line.php
//title: Чистка дублей пользователей с перепривязкой заказов
\Bitrix\Main\Loader::includeModule('sale');
$order = array('sort' => 'asc');
$tmp = 'sort';
$rsUsers = CUser::GetList($order, $tmp);
$arlogin = [];
while($rsUsers->NavNext(true, "f_")) :
$arlogin[mb_strtolower($f_LOGIN)][] = $f_ID;
endwhile;
foreach($arlogin as $login=>$arLoginId):
if(count($arLoginId)>1):
$arOrder = \Bitrix\Sale\Order::loadByFilter([
'filter' => [
"USER_ID" => $arLoginId,
],
'order' => ['ID' => 'ASC'],
]);
foreach($arOrder as $order):
if( (int)$order->getUserId() != (int)$arLoginId[0] ){
echo "{$order->getUserId()} - заказ {$order->getId()} - привязать к {$arLoginId[0]} {$login}\n";
// Привязываем все заказы к самому первому пользователю с таким логином
$order->setFieldNoDemand('USER_ID', $arLoginId[0]);
$order->save();
}
endforeach;
// Удаляем дубли пользователя, оставляем только самого первого
foreach($arLoginId as $k=>$loginId){
if($k>0) {
if (CUser::Delete($loginId)) echo "Пользователь {$loginId} {$login} удален.\n";
} else{
echo "Оставляем пользователя {$loginId} {$login}\n";
}
}
endif;
endforeach;
Перед выполнением этого скрипта обязательно сделайте бэкап базы данных.
Если у вас прям много таких дублей (тысячи и более), а сайт расположен на виртуальном хостинге, то может не хватить времени выполнения php скрипта. Но у таких сайтов обычно есть к кому обратиться за решением проблемы.