Скопировать номер телефона из поля пользователя в телефон для регистрации

Просмотров: 5229

Задача, на конкретном сайте: раньше все пользователи регистрировались по стандартному режиму, через логин(e-mail) и пароль. При этом, у всех пользователей запрашивался и номер телефона, который записывался в стандартное поле "Номер телефона", он же PERSONAL_MOBILE.

Необходимо перевести всех пользователей на вход по номеру телефона, с отправкой смс с паролем.

Что бы не напрягать существующих пользователей просто скопируем номера телефонов из PERSONAL_MOBILE в новое поле (которое доступно в свежих редакциях Битрикс, создавать его не надо) Номер телефона для регистрации он же PHONE_NUMBER

Получаем информацию о пользователях через API

Для начала, нам нужно получить информацию о пользователях, с помощью CUser::GetList - Возвращает список пользователей в виде объекта класса CDBResult. Статический метод.

По идее, нам нужно только поле PERSONAL_MOBILE, но покажу как вывести вообще всю информацию о пользователях, отсортированных по ID пользователя.

$data = CUser::GetList(($by="ID"), ($order="ASC"),
    array(
     'ACTIVE' => 'Y', // Выбрали всех активных
    )
);
while($arUser = $data->Fetch()) {
   echo '<pre>';
   print_r($arUser);
   echo '</pre>';
}

В распечатке $arUser увидем вообще всю информацию о каждом пользователе (ФИО, дату регистрации, все персональные данные итд).

Достаточно, с помощью метода CUser::Update обновить поле PHONE_NUMBER из поля PERSONAL_MOBILE

$user = new CUser;
$data = CUser::GetList(($by="ID"), ($order="ASC"),
    array(
     'ACTIVE' => 'Y',
    )
);
while($arUser = $data->Fetch()) {
    $fields = Array(
        "PHONE_NUMBER"  => $arUser['PERSONAL_MOBILE'],
    );
    $user->Update($arUser['ID'], $fields);
}

Здесь мы вписали номер телефона "PHONE_NUMBER" => $arUser['PERSONAL_MOBILE'], и изменили параметры пользователя.

Замена 8 на +7 в номере телефона

Если пользователи указывали свои телефоны с 8-ки, такие номера не скопируются. По этому, в обходе пользователей нужно заменить 8 на +7.

Для замены номера телефона, начинающегося с "8" на номер, начинающийся с "+7", нужно добавить проверку в коде. Используем функцию substr, чтобы проверить первый символ номера телефона и заменить его, если он начинается с "8". Вот пример, как это можно сделать:

$user = new CUser;
$data = CUser::GetList(
    ($by="ID"),
    ($order="ASC"),
    array(
        'ACTIVE' => 'Y',
    )
);

while($arUser = $data->Fetch()) {
   echo '<pre>';
   print_r($arUser['PERSONAL_PHONE']);
   echo '</pre>';

    $phoneNumber = $arUser['PERSONAL_PHONE'];

    // Проверяем, начинается ли номер на "8"
    if(substr($phoneNumber, 0, 1) === '8') {
        // Заменяем "8" на "+7"
        $phoneNumber = '+7' . substr($phoneNumber, 1);
    }

    $fields = Array(
        "PHONE_NUMBER" => $phoneNumber,
    );

    $user->Update($arUser['ID'], $fields);
}

Получить номер телефона из последнего заказа пользователя

Если, вы ни когда не спрашивали номер телефона пользователя, можно попробовать скопировать его из заказа, если пользователь хотя бы раз делал заказ в интернет магазине.

Для начала, получим самый свежий заказ каждого пользователя, скорее всего в нем актуальный номер телефона в свойстве "Номер телефона". Делать будем старым методом, так как на D7 все работает гораздо медленеее.

$user = new CUser;
CModule::IncludeModule("sale");
$data = CUser::GetList(($by = "ID"), ($order = "ASC"),
    array(
        'ACTIVE' => 'Y', // Выбрали всех активных
    )
);
while ($arUser = $data->Fetch()) {
    $db_sales = CSaleOrder::GetList(
        array(
            'DATE_INSERT' => 'DESC'
        ),
        array(
            'USER_ID' => $arUser['ID']
        ),
        false,
        array(
            'nTopCount' => 1 // Получаем один заказ, самый свежий
        ),
        array(
            'ID'
        )
    );
    while ($ar_sales = $db_sales->Fetch()) {
        $dbOrderProps = CSaleOrderPropsValue::GetList(
            array(
                'SORT' => 'ASC'
            ),
            array(
                'ORDER_ID' => $ar_sales['ID'],
                'CODE' => array('PHONE')
            )
        );
        while ($arOrderProps = $dbOrderProps->GetNext()) {
            $userOrderPhone = $arOrderProps['VALUE'];
        }
    }
    $fields = array(
        'PHONE_NUMBER' => $userOrderPhone,
    );
    $user->Update($arUser['ID'], $fields);
}

Пояснения:

  • Все также с CUser::GetList прошлись по пользователям. Теперь нам нужны только их ID.
  • Внутри цикла пользователя воспользовались CSaleOrder::GetList получили заказы пользователя, при этом отфильтровали по дате создания (от новых к старым) 'DATE_INSERT' => 'DESC'. В отборе использовали только ID заказа array('ID') - другие данные нам не нужны и весь скрипт отработает быстрее.
  • Внутри заказа, зная его ID "ORDER_ID" => $ar_sales['ID'] получили (методом CSaleOrderPropsValue::GetList) значение свойства с телефоном, в моем случае это поле с кодом "CODE"=>array("PHONE")
  • Передали VALUE с номером телефона в переменную $userOrderPhone
  • Дальше, все также, как и в статье выше, обновили номер для регистрации методом CUser::Update
На этом все, вопросы прошу задавать в комментариях. Для работы с заказом специально не использовал D7 - так как возможностей там больше, по работе с заказами- но они работают медленнее, для конкретно этой, описанной в статье ситуации (нужно получать коллекции свойств и грузить классы заказа \Bitrix\Sale\Order)

Но, можете попробовать перевести все это на D7 и написать в комментарии и не плохая практика и возможно, кому-то будет полезно.

Александр 07.09.2022
Мы эту процедуру запускаем разово перед переходом на авторизацию по номеру телефона?
Есть пример готового полного файла скрипта?
Михаил Базаров 07.09.2022
Да, один раз. Подразумевается, что новые пользователи уже заведомом регистрируются по телефону.
Код, собственно в заметке - там и нечего добавить. :)
Павел 26.09.2022
Поле PHONE_NUMBER хоть и есть и можно в него записать, но как поучить из этого поля данные простым удобным способом не понятно...

\CUser::GetList не возвращает это поле.
Михаил Базаров 07.03.2024
Вот так можно получить номер телефона
Код
$userPhoneNumber = \Bitrix\Main\UserPhoneAuthTable::getList([
    'filter' => [
        '=USER_ID' => $arResult['CREATED_BY']
    ],
    'select' => [
        'PHONE_NUMBER'
    ],
])->fetch();