Просмотров: 2341
Задача, на конкретном сайте: раньше все пользователи регистрировались по стандартному режиму, через логин(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’], и измениили параметры пользователя.
Получить номер телефона из последнего заказа пользователя
Если, вы ни когда не справшивали номер телефона пользователя, можно попоробовать скопировать его из заказа, если пользователь хотя бы раз делал заказ в интернет магазине.
Для начала, получим самый свежий заказ каждого пользователя, скорее всего в нем актуальный номер телефона в свойстве «Номер телефона». Делать будем старым методом, так как на 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']),
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'];
}
break;
}
$fields = Array(
"PHONE_NUMBER" => $userOrderPhone,
);
$user->Update($arUser['ID'], $fields);
}
Пояснения:
- Все также с CUser::GetList прошлись по пользователям. Теперь нам нужны только их ID.
- Внутри цикла пользователя воспользовались CSaleOrder::GetList получили заказы пользователя, при этом отфильтровали по дате создания (от новых к старым) ‘DATE_INSERT’ => ‘DESC’. В отборе использовали только ID заказа array(‘ID’) — другие данные нам не нужны и весь скрипт отработает быстрее.
- В конце цикла, перебора заказов пользователя, оборвали его с помощью break, что бы получить только один заказ, а не все заказы пользователя. )
- Внутри заказа, зная его ID «ORDER_ID» => $ar_sales[‘ID’] получили (методом CSaleOrderPropsValue::GetList) значение свойства с телефоном, в моем случае это поле с кодом «CODE»=>array(«PHONE»)
- Передали VALUE с номером телефона в переменную $userOrderPhone
- Дальше, все также, как и в статье выше, обновили номер для регистрации методом CUser::Update
На этом все, вопросы прошу задавать в комментариях. Для работы с заказом специально не использовал D7 — так как возможностей там больше, по работе с заказами- но они работают медленнее, для конкретно этой, описанной в статье ситуации (нужно получать коллекции свойств и грузить классы заказа BitrixSaleOrder)
Но, можете попробовать перевести все это на D7 и написать в комментарии и не плохая практика и возможно, кому-то будет полезно.
Поблагодарить и поддержать!
Поддержать выпуски видео уроков, поблагодарить за полезную инструкцию или заметку можно через:
Юманей
Мои каналы:
Каналы на которые я выкладываю видео. Контент дублируется, смотрите где удобнее.
Получение номера пользователя и отправка сообшения
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// получаем id пользователя по номеру телефона | |
$phone = BitrixMainUserPhoneAuthTable::normalizePhoneNumber($_POST[‘ONE_CLICK_BUY’][‘PHONE’]); | |
$PhoneAuthTable = BitrixMainUserPhoneAuthTable::getList($parameters = array( | |
‘filter’=>array(‘PHONE_NUMBER’ => $phone) | |
)); | |
if($item = $PhoneAuthTable->fetch()){ | |
$userId = $item[«USER_ID»]; | |
} | |
// генерируем код | |
list($code, $phoneNumber) = CUser::GeneratePhoneCode($userId); | |
// отправляем код сообшением пользователю | |
$sms = new BitrixMainSmsEvent( | |
‘SMS_USER_CONFIRM_NUMBER’, // SMS_USER_RESTORE_PASSWORD — для восстановления | |
[ | |
‘USER_PHONE’ => $phoneNumber, | |
‘CODE’ => $code, | |
] | |
); | |
$sms->send(true); | |
Отправка сообщения | |
Для того, чтобы отправить сообщение с СМС кодом подтверждения регистрации, выполним следующий код: | |
<?php | |
$userId = 1; | |
$phone = BitrixMainUserPhoneAuthTable::normalizePhoneNumber(‘+79999999999’); | |
BitrixMainUserPhoneAuthTable::add([ | |
‘USER_ID’ => $userId, | |
‘PHONE_NUMBER’ => $phone, | |
]); | |
list($code, $phoneNumber) = CUser::GeneratePhoneCode($userId); | |
$sms = new BitrixMainSmsEvent( | |
‘SMS_USER_CONFIRM_NUMBER’, // SMS_USER_RESTORE_PASSWORD — для восстановления | |
[ | |
‘USER_PHONE’ => $phoneNumber, | |
‘CODE’ => $code, | |
] | |
); | |
$sms->send(true); | |
?> | |
Подтверждение номера телефона | |
Для того, чтобы проверить введенный код: | |
<?php | |
$phoneRecord = BitrixMainUserPhoneAuthTable::getList([ | |
‘filter’ => [ | |
‘=USER_ID’ => 1 | |
], | |
‘select’ => [‘USER_ID’, ‘PHONE_NUMBER’, ‘USER.ID’, ‘USER.ACTIVE’], | |
])->fetchObject(); | |
if(!$phoneRecord) { | |
// Ошибка. Пользователь не найден | |
} | |
$smsCode = 1111; | |
if(CUser::VerifyPhoneCode($phoneRecord->getPhoneNumber(), $smsCode)) { | |
if($phoneRecord->getUser()->getActive() && !$USER->IsAuthorized()) { | |
$USER->Authorize($userId); | |
} | |
return true; | |
} | |
?> |
Всем привет. У меня новый квест) За долгое время работы с битриксом приходилось реализовывать много чего, но вот с подключением MessageService по смс работать не приходилось.
На просторах интернета не много информации по этому вопросу, и та, что есть не работает как нужно, а часто вообще не работает.
Итак начнем!
Для подключения провайдера смс вам конечно же необходимо сначала протестировать api отправки смс на чистом php без битрикса, так я и сделал. Обычно это soap/curl или работа через сокеты и если ваш провайдер предоставляет библиотеку с которой нужно работать — это отлично. В основном предлагается библиотека QTSMS.class.php, при чем в разных источниках она совершенно разная, начиная от названий класса и методов и заканчивая самой логикой работы. Я скачал библиотеку которая по заверениям совместима с новым api для версий php 7.4, но я использовал старую версию api. Сама работа по отправке смс находится в файле Src/SmsClient.class.php (вся библиотека будет прикреплена к статье), и как мы видим на 222 строчке отправка выполняется через curl.
<?php
private function connectSettings()
{
$protocol = !empty($this->protocol) ? $this->protocol.’://’ : »;
$path = !empty($this->path) ? $this->path : »;
$url = $protocol . $this->hostname . $path;
curl_setopt_array($this->ch, [
CURLOPT_URL => $url,
CURLOPT_HEADER => FALSE,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_HTTPHEADER => $this->buildHeaders(),
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => FALSE,
CURLOPT_USERAGENT => ‘AISMS PHP class’,
]);
}
?>
Хотелось бы пояснить, что целью данной статьи не является разбор именно создания скрипта отправки смс под определенный сервис, а только подключение своего MessageService по отправке смс.
Итак, скачиваем архив с библиотекой и распаковываем в директорию /bitrix/php_interface/sms/ или /local/php_interface/sms/, я специально не стал называть директорию lib или vendor и т.д.,как принято в битриксе или для загрузки из composer, чтобы по названию было сразу понятно, что там лежит. Если же у вас уже существуют данные директории и в них много библиотек, то конечно же размещайте файлы архива так /bitrix/php_interface/lib/sms/ или /local/php_interface/lib/sms/
Далее в этой же директории sms создаем файл, например index.php и заполняем его кодом класса, который и будет нашим sms MessageService.
На данный момент это рабочий класс для работы с BitrixMainSmsEvent, в будущем конечно же возможны изменения в названиях методов да и в принципе построения логики sms MessageService.
<?php
namespace MyProviderMessageService;
use BitrixMainApplication;
use BitrixMainError;
use BitrixMainResult;
use BitrixMainWebHttpClient;
use BitrixMainWebJson;
use BitrixMainLoader;
use BitrixMessageServiceSenderResultMessageStatus;
use BitrixMessageServiceSenderResultSendMessage;
use BitrixMessageService;
// название класса может быть любым, только именно этот класс вам нужно будет подключить в обработчике собятия отправки в файле init.php
class Smska extends BitrixMessageServiceSenderBase
{
public $user=’*****’;
public $pass=’*****’;
public $host=’*****’;
public $servesename = ‘*****’;
public static function isSupported()
{
return true;
}
public function getId()
{
return ‘я писал здесь просто латинское слово без пробелов’;
}
public function getName()
{
return «полное название смс провайдера»;
}
public function getShortName()
{
return ‘краткое название или адрес домена сервиса’;
}
public function isDemo()
{
return false; //есть ли демо период, оставляем так
}
public function canUse()
{
return true; //включен или выключен ваш сервис, ниже будет проверка (*)
}
//этот метод для парсинга атридутов xml объектов, так как мне на выход приходил именно xml объект, если вам он не нужен, можете смело удалять
public function xmlAttribute($object, $attribute){
if(isset($object[$attribute]))
return (string) $object[$attribute];
else
return null;
}
//основной метод работы провайдера, отправляет смс
public function sendMessage(array $messageFields)
{
//здесь проверяем свой же метод выше (*), если получаем false, то выводим сообщение о том, что сервис отключен
if (!$this->canUse()) {
$result = new SendMessage(); //это основной класс с методами проверки ответов и параметрами сохранения результатов
$result->addError(new Error(‘Ошибка отправки. СМС-сервис отключен’)); //передаем именно объект new Error, строковые значения этот метод не признает
return $result;
}
//выполняем подключение нашего класса библиотеки и передаем в него наши свойства (логин,пароль и хост (хост обычно полный вместе с https:// с полным адресом для http запросов))
$sms = new QTSMS($this->user, $this->pass, $this->host);
$return = new SendMessage(); //подключаем здесь основной класс с методами проверки ответов и параметрами сохранения результатов
$result = $sms->post_message($messageFields[‘MESSAGE_BODY’], $messageFields[‘MESSAGE_TO’], $this->servesename); //отправляем нашу смс
//дальше что-то делаем с результатом для понимания дошла смс или нет, к этому этапу вы уже должны протестировать на «чистом php» обработку результата, что он вам дает при ошибке и при отправке
##### это все логика работы именно вашего сервиса, пишите свою или используйте эту, если она вам подойдет
/* $xml = new SimpleXMLElement($result);//у меня приходит xml поэтому я перевожу его в объект
$status = $this->xmlAttribute($xml->result,’*****’); //здесь получаю атрибут
$result_status = $sms->status_sms_group_id($status); //проверяю статус отправилось или нет
$r_xml = new SimpleXMLElement($result_status);//у меня приходит xml поэтому я опять перевожу его в объект
$id = $this->xmlAttribute($r_xml->*****,’*****’); //получаю id записи
*/
//проверяем вашу переменную , которая скажет отправлено смс или нет, у меня это id записи при успешной отправке
if(isset($id) && (int)$id>0){
$return->setExternalId($id); //пишем уникальный номер отправления, если у вас его нет можете писать любое большое рандомное число
$return->setAccepted(); //говорим, что все ok sms отправлена
}
else{
$return->addError(new Error(‘Ошибка отправки’)); //если что-то пошло не так записываем ошибку, она будет выведена пользователю
}
return $return;
}
//через этот метод мы работаем с нашим классом как с объектом (используется в init.php)
public static function onGetSmsSenders()
{
$class = __CLASS__;
return [new $class()];
}
//имя отправителя, обязательно, если их будет несколько в административной панели вы сможете выбрать
public function getFromList()
{
return [$this->servesename];
}
}
?>
Далее открываем или создаем, если еще не создан файл /bitrix/php_interface/init.php или /local/php_interface/init.php
Добавляем в него обработчик события отправки смс и подключаем к нему наш класс
У меня после подключения вывалилась ошибка «класс BitrixMessageServiceSenderBase не найден», возможно это связано с конфигурацией моего проекта и у вас все заработает, но если нет подключайте файл с двумя звездочками (**)
<?
include_once($_SERVER[‘DOCUMENT_ROOT’].’/bitrix/modules/messageservice/lib/sender/base.php’); // файл с двумя звездочками (**) без него может ничего не заработать, видимо у битрикса проблема с автоподгрузкой классов в этом пространстве имен
include_once($_SERVER[‘DOCUMENT_ROOT’] . ‘/bitrix/php_interface/sms/QTSMS.class.php’); //подключаем нашу библиотеку
include_once($_SERVER[‘DOCUMENT_ROOT’] . ‘/bitrix/php_interface/sms/test_config.php’); // он понадобится нам в файле ajax авторизации (необходимо заполнить вашими доступами (логин, пароль, адрес))
include_once($_SERVER[‘DOCUMENT_ROOT’].’/bitrix/php_interface/sms/index.php’); // подключаем наш обработчик
// вызов обработсика нашего события
$eventManager = BitrixMainEventManager::getInstance();
$eventManager->addEventHandler(
«messageservice»,
«onGetSmsSenders»,
array(
MyProviderMessageServiceSmska::class,
«onGetSmsSenders»,
)
);
?>
Все сохраняем и переходим по ссылке вашсайт/bitrix/admin/settings.php?lang=ru&mid=main&mid_menu=1#authorize
Переходим на вкладку «Почта и СМС» и ставим нашу службу как «Служба отправки СМС по умолчанию», а также выбираем номер отправителя по умолчанию
Теперь переходим к самому главному: в битриксе нет авторизации по смс в стандартном виде, например в компоненте регистрации по адресу вашсайт/bitrix/admin/fileman_file_edit.php?path=%2Fbitrix%2Fcomponents%2Fbitrix%2Fmain.register%2Fcomponent.php&full_src=Y&site=s1&lang=ru&&filter=Y&set_filter=Y
на 220 строчке вы найдете подключение провайдера смс.
<?
$sms = new BitrixMainSmsEvent(
«SMS_USER_CONFIRM_NUMBER»,
[
«USER_PHONE» => $phoneNumber,
«CODE» => $code,
]
);
?>
А в компонентах вашсайт/bitrix/admin/fileman_file_edit.php?path=%2Fbitrix%2Fcomponents%2Fbitrix%2Fsystem.auth.form%2Fcomponent.php&full_src=Y&site=s1&lang=ru&&filter=Y&set_filter=Y или вашсайт/bitrix/admin/fileman_admin.php?PAGEN_1=1&SIZEN_1=20&lang=ru&site=s1&path=%2Fbitrix%2Fcomponents%2Fbitrix%2Fmain.auth.form%2F&del_filter=Y&find_name=auth нет, возможно в битриксе есть какие-то специальные компоненты для этого, но я их не нашел, да и выводить в публичной части необходимо в рамках шаблона компонента формы авторизации, так что в любом случае придется переписывать.
Нам понадобится файл кастомного шаблона авторизации вашсайт/bitrix/admin/fileman_file_edit.php?path=%2Fbitrix%2Ftemplates%2F(ваш_шаблон_сайта)%2Fcomponents%2Fbitrix%2Fsystem.auth.form%2Fmain%2Ftemplate.php&full_src=Y&site=s1&lang=ru&&filter=Y&set_filter=Y у вас может быть другой.
У меня на строчке 110 после
<div class=»form_footer»>
<div class=»filter block»>
Добавляю
<div class=»auth_sms»>
<label for=»auth_sms» title=»Войти по номеру телефона» tabindex=»5″>Войти по номеру телефона</label>
</div>
Также на строчке 39 после
<input type=»hidden» name=»AUTH_FORM» value=»Y» />
<input type=»hidden» name=»TYPE» value=»AUTH» />
<input type=»hidden» name=»POPUP_AUTH» value=»<?=$arParams[‘POPUP_AUTH’]?>» />
Добавляю
<div class=»form_sms»>
<label>Введите номер телефона</label>
<input type=»tel» class=»phone_sms» name=»sms_phone» autocomplete=»tel»>
<input type=»button» class=»send_sms» value=»Получить СМС»>
</div>
<div class=»form_sms2″>
<label>Введите код из смс</label>
<input type=»tel» class=»sms_code» name=»sms_code» autocomplete=»tel»>
<input type=»button» class=»auth_sms» value=»Войти»>
</div>
Открываем кастомный файл js скриптов вашсайт/bitrix/admin/fileman_file_edit.php?path=%2Fbitrix%2Ftemplates%2F(ваш_шаблон_сайта)%2Fjs%2Fcustom.js&site=s1&lang=ru&&filter=Y&set_filter=Y#authorize
и добавляем jquery код
$(document).on(‘click’,'[for=»auth_sms»]’,function(){
$(‘.form_sms’).show(500);
$(‘.form_body’).hide(300);
$(«.phone_sms»).inputmask({«mask»: «+7 (999) 999-99-99″});
$(this).html(‘Войти с помощью логина’);
$(this).attr(‘for’,»auth_login»);
$(‘.form_footer .buttons.clearfix’).hide();
});
$(document).on(‘click’,'[for=»auth_login»]’,function(){
$(‘.form_sms’).hide(300);
$(‘.form_sms2’).hide(300);
$(‘.form_body’).show(500);
$(this).html(‘Войти по номеру телефона’);
$(this).attr(‘for’,»auth_sms»);
$(‘.form_footer .buttons.clearfix’).show();
});
$(document).on(‘click’,’.send_sms’,function(){
$(‘.form_footer .buttons.clearfix’).hide();
var tel_auth = $(‘.phone_sms’).val();
if(tel_auth!=»){
$.ajax({
type: «POST»,
url: «/ajax/script/sms.php»,
data: {number_login:tel_auth},
success: function(data){
if(data==’yes’){
$(‘.form_sms’).hide(300);
$(‘.form_sms2′).show(500);
}
else if(data==’no-user’){
$(‘.form_sms label’).html(‘Введите номер телефона <span class=»red-not»>Пользователь с таким номером не найден</span>’);
}
else{
$(‘.form_sms label’).html(‘Введите номер телефона <span class=»red-not»>Ошибка отправки СМС</span>’);
}
}
});
}
else{
$(‘.form_sms label’).html(‘Введите номер телефона <span class=»red-not»>Пустое поле телефона</span>’);
}
$(this).html(‘Войти по номеру телефона’);
$(this).attr(‘for’,»auth_sms»);
});
$(document).on(‘click’,’.auth_sms’,function(){
$(‘.form_footer .buttons.clearfix’).hide();
var code = $(‘.sms_code’).val();
if(code!=»){
$.ajax({
type: «POST»,
url: «/ajax/script/auth_sms.php»,
data: {code:code},
success: function(data){
if(data==’yes’){
document.location.href = ‘/personal/’;
}
else if(data==’no-code’){
$(‘.form_sms2 label’).html(‘Введите код из смс <span class=»red-not»>Пустое поле</span>’);
}
else{
$(‘.form_sms2 label’).html(‘Введите код из смс <span class=»red-not»>Неверный код</span>’);
}
}
});
}
else{
$(‘.form_sms2 label’).html(‘Введите код из смс <span class=»red-not»>Пустое поле</span>’);
}
});
не забудьте подключить библиотеку для маски телефона и указать в ready
$(document).ready(function(){
$(«.phone_sms»).inputmask({«mask»: «+7 (999) 999-99-99»});
});
Открываем кастомный файл стилей вашсайт/bitrix/admin/fileman_file_edit.php?path=%2Fbitrix%2Ftemplates%2F(ваш_шаблон_сайта)%2Fcss%2Fcustom.css&site=s1&lang=ru&&filter=Y&set_filter=Y
И добавляем наши стили, у вас могут быть свои
/*auth form sms*/
.auth_sms label {
color: #198ac8 !important;
cursor: pointer;
}
.form_sms label,.form_sms2 label{
color: #888888;
display: block;
}
.form_sms,.form_sms2 {
margin: 0;
padding: 29px 60px 8px;
display:none;
}
input.phone_sms,input.sms_code {
padding: 8px 13px 7px;
width: 100%;
height: 48px;
}
input.send_sms,input.auth_sms {
background-color: #1d9de3;
border-color: #1d9de3;font-size: 0.7333em;
font-weight: normal;
text-transform: uppercase;
text-decoration: none;
margin: 0px;
border: 0px solid;
letter-spacing: 0.8px;
border-radius: 3px;
padding: 12px 21px 11px;
overflow: hidden;
transition: background-color 0.3s ease;
-moz-transition: background-color 0.3s ease;
-ms-transition: background-color 0.3s ease;
-o-transition: background-color 0.3s ease;
-webkit-transition: background-color 0.3s ease;color: #fff;margin-top: 20px;
}
span.red-not {
color: red;
display: block;
border-bottom: 1px dashed;
width: max-content;
margin-top: -5px;
margin-bottom: 5px;
}
/*—*/
Теперь создаем наши php файлы для авторизации в директории /ajax/script/ (у вас может быть своя, для установки своей директории внесите изменения в кастомный файл js):
Файл sms.php:
<?php session_start();
ini_set(‘max_execution_time’, 20000);
require_once($_SERVER[«DOCUMENT_ROOT»] . «/bitrix/modules/main/include/prolog_before.php»);
/*ini_set(‘error_reporting’, E_ALL); //можете раскомментировать для тестирования ошибок в консоли браузера на вкладке network->Fetch/XHR
ini_set(‘display_errors’, 1);
ini_set(‘display_startup_errors’, 1);*/
function xmlAttribute($object, $attribute){
if(isset($object[$attribute]))
return (string) $object[$attribute];
else
return null;
}
$sms = new QTSMS($cfg[‘login’], $cfg[‘password’], $cfg[‘host’]);
$rand = mt_rand(0,9).mt_rand(0,9).mt_rand(0,9).mt_rand(0,9).mt_rand(0,9); //создаем рандомный код для смс
$_SESSION[‘rand_sms’] = $rand; //сохраняем его в сессию
$sender_name = ‘имя отправителя’;
//проверяем передали ли нам номер телефона (меняется в кастомном файле js)
if(isset($_POST[‘number_login’])){
$phoneNumber = $_POST[‘number_login’];
// проверяем есть ли пользователь с таким телефоном
$filter = Array(«PERSONAL_PHONE»=>$phoneNumber);
$rsUsers = CUser::GetList(($by=»personal_country»), ($order=»desc»), $filter);
while($arUser = $rsUsers->Fetch()){
$user_id = $arUser[‘ID’];
}
if(isset($user_id)){
// если найден записываем его id в сессию по коду из смс
$_SESSION[‘USER_ID_AUTH’][$_SESSION[‘rand_sms’]] = $user_id;
//чистим номер от лишних символов, чтобы отправить смс
$phoneNumber = str_replace(‘+7′,’8’,$phoneNumber);
$phoneNumber = preg_replace(‘#([^0-9]+)#’,»,$phoneNumber);
// отправляем смс
$result = $sms->post_message($rand, $phoneNumber, $sender_name);
/* $xml = new SimpleXMLElement($result);//у меня приходит xml поэтому я перевожу его в объект
$status = $this->xmlAttribute($xml->result,’*****’); //здесь получаю атрибут
$result_status = $sms->status_sms_group_id($status); //проверяю статус отправилось или нет
$r_xml = new SimpleXMLElement($result_status);//у меня приходит xml поэтому я опять перевожу его в объект
$id = $this->xmlAttribute($r_xml->*****,’*****’); //получаю id записи
*/
if((int)$id>0){
echo ‘yes’;
}
else{
echo ‘no’;
}
}
else{
echo ‘no-user’;
}
}
else{
echo ‘no’;
}
Файл auth_sms.php:
<?php session_start();
ini_set(‘max_execution_time’, 20000);
require_once($_SERVER[«DOCUMENT_ROOT»] . «/bitrix/modules/main/include/prolog_before.php»);
if(isset($_POST[‘code’])){
if(isset($_SESSION[‘USER_ID_AUTH’][$_POST[‘code’]])){
global $USER;
$USER->Authorize($_SESSION[‘USER_ID_AUTH’][$_POST[‘code’]]);
echo ‘yes’;
}
else{
echo ‘no’;
}
}
else{
echo ‘no-code’;
}
Вот и все!!! Желаю вам успехов в разработке)
ANTO, печально, я сам не делал, но думал что раз есть регистрация то есть и авторизация.
Тогда руками пилить (компонент system.auth.authorize)
1. В классе CUser есть 2 метода
public static function SendPhoneCode($phoneNumber, $smsTemplate, $siteId = null)
public static function VerifyPhoneCode($phoneNumber, $code)
2. В шаблоне добавляешь input для телефона в стандартную форму авторизации и оборачиваешь в if
<?if(!isset($arResult["SHOW_SMS_FIELD"]) || $arResult["SHOW_SMS_FIELD"] !== true):?>
<form //..............
<input type="text" required name="PHONE_NUMBER">
</form>
<?endif;?>
3. Добавляешь в шаблон блок для ввода кода из смс
<?if($arResult["SHOW_SMS_FIELD"] == true):?>
<?CJSCore::Init('phone_auth');?>
<form method="post" action="<?=$arResult["AUTH_URL"]?>" name="regform">
<input type="hidden" name="SIGNED_DATA" value="<?=htmlspecialcharsbx($arResult["SIGNED_DATA"])?>" />
<div class="bx-authform-formgroup-container">
<div class="bx-authform-label-container"><span class="bx-authform-starrequired">*</span><?echo GetMessage("main_register_sms_code")?></div>
<div class="bx-authform-input-container">
<input type="text" name="SMS_CODE" maxlength="255" value="<?=htmlspecialcharsbx($arResult["SMS_CODE"])?>" autocomplete="off" />
</div>
</div>
<div class="bx-authform-formgroup-container">
<input type="submit" class="btn btn-primary" name="code_submit_button" value="<?echo GetMessage("main_register_sms_send")?>" />
</div>
</form>
<div id="bx_auth_error" style="display:none" class="alert alert-danger"></div>
<div id="bx_auth_resend"></div>
<script>
new BX.PhoneAuth({
containerId: 'bx_auth_resend',
errorContainerId: 'bx_auth_error',
interval: <?=$arResult["PHONE_CODE_RESEND_INTERVAL"]?>,
data:
<?=CUtil::PhpToJSObject([
'signedData' => $arResult["SIGNED_DATA"],
])?>,
onError:
function(response)
{
var errorNode = BX('bx_auth_error');
errorNode.innerHTML = '';
for(var i = 0; i < response.errors.length; i++)
{
errorNode.innerHTML = errorNode.innerHTML + BX.util.htmlspecialchars(response.errors[i].message) + '<br />';
}
errorNode.style.display = '';
}
});
</script>
<?endif;?>
4. Добавляешь обработчик, например в result_modifier (обработчик писал без проверки):
$arResult["PHONE_CODE_RESEND_INTERVAL"] = CUser::PHONE_CODE_RESEND_INTERVAL;
$phoneNumber = $_REQUEST['PHONE_NUMBER'] ?? null;
$signedData = $_REQUEST['SIGNED_DATA'] ?? null;
if(!empty($phoneNumber))
{
$smsTemplate = 'SMS_USER_RESTORE_PASSWORD'; // только указываешь свой шаблон (создаешь сначала в админке)
$result = CUser::SendPhoneCode($phoneNumber, $smsTemplate, SITE_ID);
if($result->isSuccess()) {
$arResult['SIGNED_DATA'] = BitrixMainControllerPhoneAuth::signData([
'phoneNumber' => $phoneNumber,
'smsTemplate' => $smsTemplate
]);
$arResult["SHOW_SMS_FIELD"] = true;
}
else {
$arResult['ERROR_MESSAGE'] = $result->getErrorMessages();
}
if(!empty($signedData)) {
$arResult["SIGNED_DATA"] = $signedData;
$arResult["SHOW_SMS_FIELD"] = true;
}
// verify phone code
$isNeedVerifySmsCode = $_SERVER["REQUEST_METHOD"] == "POST" && $_REQUEST["code_submit_button"] <> '' && !$USER->IsAuthorized() && !empty($signedData);
if($isNeedVerifySmsCode)
{
$smsCode = $_REQUEST['SMS_CODE'];
if(($params = BitrixMainControllerPhoneAuth::extractData($signedData)) !== false)
{
if(($userId = CUser::VerifyPhoneCode($params['phoneNumber'], $smsCode)))
{
$USER->Authorize($userId);
}
else
{
$arResult['ERROR_MESSAGE'] = 'Error verify code'; // здесь сам ошибку придумай
$arResult["SHOW_SMS_FIELD"] = true;
$arResult["SMS_CODE"] = $smsCode;
$arResult["SIGNED_DATA"] = $signedData;
}
}
}
}
Вроде так, но могут быть ошибки, если что пиши))
В init.php напишем обработчик на событие OnBeforeUserLoginHandler (перед попыткой авторизации пользователя), который будет определять введен логин или телефон и подменять поля отправленные пользователем.
AddEventHandler("main", "OnBeforeUserLogin", Array("MaxyssClass", "OnBeforeUserLoginHandler")); class MaxyssClass { // авторизация по номеру телефона function OnBeforeUserLoginHandler(&$arFields) { $rsUser = CUser::GetByLogin($arFields['LOGIN']); if($arUser = $rsUser->Fetch()){ // ничего не делаем так как введен логин }else{ // ищем юзера по телефону $phone = BitrixMainUserPhoneAuthTable::normalizePhoneNumber($arFields['LOGIN']); // нормализуем номер телефона $user = BitrixMainUserPhoneAuthTable::getList($parameters = array( 'filter'=>array('PHONE_NUMBER' =>$phone, 'CONFIRMED'=>'Y') // выборка пользователя с подтвержденным номером )); if($row = $user->fetch()) { $rsUser = CUser::GetByID($row['USER_ID']); // найдем пользователя по ID $arUser = $rsUser->Fetch(); $arFields['LOGIN'] = $arUser['LOGIN']; // заменим на логин пользователя } } } }
Подготовка профилей существующих пользователей
В процессе работы модуль использует специальное поле в котором хранится номер телефона, в форме редактирования пользователей в административном разделе оно выводится как поле — Номер телефона для регистрации
(Код — PHONE_NUMBER
).
Если это поле не заполнено, войти на сайт под этим профилем возможно будет только по логину + пароль или email + пароль.
Это же поле используется стандартной авторизацией по номеру телефона Битркиса.
Для новых пользователей номер телефона сохраняется в профиле автоматически при авторизации / регистрации через компоненты модуля
Поэтому в модуле добавлен инструмент для автоматического заполнение профилей пользователей номерами телефонов из других полей и/или свойств оформленных заказов.
Для этого нужно перейти на страницу —
Администрирование / BXmaker /Авторизация по номеру телефона / Заполнить поля
Поле для заполнения выбираем с кодом PHONE_NUMBER
И обязательно выбираем поля в которых нужно искать номер телефона
Автоматическая регистрация пользователя по номеру телефона в Битриксе
2016-08-12
Как сделать автоматическое создание заказа при покупке в один клик.
init.php
/** * регистрирует пользователя по номеру телефона * на входе номер, на выходе id пользователя в любом случае */ function registerUserByPhone($phone) { if(checkUserByPhone($phone) == false){ // если пользователь не зарегистрирован $password = rand(0, 9).rand(14, 99).rand().rand().rand().rand().rand().rand().rand().rand(); $user = new CUser; $fields = Array( "NAME" => "", "LAST_NAME" => "", "EMAIL" => "autoreg-".date('ymdhis')."@".$_SERVER['HTTP_HOST'], "LOGIN" => $phone, // логин - номер телефона без + "LID" => "ru", "ACTIVE" => "Y", "GROUP_ID" => array(3), "PASSWORD" => $password, "CONFIRM_PASSWORD" => $password, "PERSONAL_PHONE" => $phone, ); $user->Add($fields); if (intval($ID) > 0): // echo "string"; $USER->Authorize($ID);// сразу же авторизуем return $ID; else: // echo $user->LAST_ERROR; endif; } else { // если пользователь зарегистрирован return checkUserByPhone($phone); } } /** * id пользователя по номеру телефона * возвращает false если не существует * возвращает id если существует */ function checkUserByPhone($phone) { $by = "ID"; $order = "ASC"; $rsUser = CUser::GetList(($by="ID"), ($order="desc"), array("PERSONAL_PHONE"=>$phone),array()); $arUser = $rsUser->Fetch(); if(!empty($arUser['ID'])) { return $arUser['ID']; // пользователь существует } else { return false; // пользователь не существует } }
Вызов и авторизация. Поместить на странцу вызываемую через ajax, передавать массив с id товара и телефоном.
global $USER; // преобразуем url в массив $fields_arr = urldecode($_POST['quickordr']); parse_str($fields_arr, $get_array); // регистрируем если не зарегистрирован, получаем id пользователя $res = registerUserByPhone((int)$get_array['phone']); // бывает что с первого раза не авторизует $res = registerUserByPhone((int)$get_array['phone']); // чтобы точно авторизовало if($res !== false) { $USER->Authorize($res); } // добавлять в корзину Add2BasketByProductID($get_array['pid'], 1, false, false); // создавать заказ с этим товаром $arFields = array( "LID" => SITE_ID, "PERSON_TYPE_ID" => 1, "PAYED" => "N", "CANCELED" => "N", "STATUS_ID" => "N", "PRICE" => 0, "CURRENCY" => CSaleLang::GetLangCurrency(SITE_ID), "USER_ID" => IntVal($USER->GetID()), "PAY_SYSTEM_ID" => 1, "PRICE_DELIVERY" => 0, "DELIVERY_ID" => 1, "TAX_VALUE" => 0.0, "USER_DESCRIPTION" => "Покупка в один клик" ); $ORDER_ID = CSaleOrder::Add($arFields); CSaleBasket::OrderBasket($ORDER_ID, CSaleBasket::GetBasketUserID(), SITE_ID, false); if (!$ORDER_ID) die("Заказ не добавили".var_dump($arFields)); else echo $ORDER_ID; $ORDER_ID = IntVal($ORDER_ID);
- bitrix
- php
- битрикс
Возможности системного компонента регистрации довольно скромные: нет возможности добавить свои поля, сделать их обязательными для заполнения. Для реализации таких возможностей есть компонент «Настраиваемая регистрация», который позволяет настроить и разместить на сайте свою форму регистрации. В визуальном редакторе компонент расположен по пути: «Служебные • Пользователь • Настраиваемая регистрация».
Пример вызова компонента
<?php $APPLICATION->IncludeComponent( // Настраиваемая регистрация "bitrix:main.register", "", array( "AUTH" => "Y", // Автоматически авторизовать пользователей "REQUIRED_FIELDS" => array( // Поля, обязательные для заполнения 0 => "EMAIL", 1 => "NAME", 2 => "LAST_NAME", ), "SET_TITLE" => "Y", // Устанавливать заголовок страницы "SHOW_FIELDS" => array( // Поля, которые показывать в форме 0 => "EMAIL", 1 => "NAME", 2 => "LAST_NAME", ), "SUCCESS_PAGE" => "", // Страница окончания регистрации "USER_PROPERTY" => "", // Показывать дополнительные свойства "USER_PROPERTY_NAME" => "", // Название блока пользовательских свойств "USE_BACKURL" => "N", // Отправлять пользователя по обратной ссылке ), false ); ?>
Создадим страницу /auth/register.php
, разместим на ней вызов компонента «Настраиваемая регистрация». В настройках компонента выберем поля, которые надо показывать:
[EMAIL] E-mail
[NAME] Имя
[LAST_NAME] Фамилия
[PERSONAL_PHONE] Телефон
[WORK_COMPANY] Наименование компании
[WORK_PHONE] Телефон (рабочий)
И укажем поля, обязательные для заполнения:
[EMAIL] E-mail
[NAME] Имя
[LAST_NAME] Фамилия
[PERSONAL_PHONE] Телефон
После этого страница /auth/register.php
содержит следующий код:
<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Регистрация"); ?> <?php $APPLICATION->IncludeComponent( "bitrix:main.register", ".default", array( "AUTH" => "N", "COMPONENT_TEMPLATE" => ".default", "REQUIRED_FIELDS" => array( 0=>"EMAIL", 1=>"NAME", 2=>"LAST_NAME", 3=>"PERSONAL_PHONE", ), "SET_TITLE" => "Y", "SHOW_FIELDS" => array( 0=>"EMAIL", 1=>"NAME", 2=>"LAST_NAME", 3=>"PERSONAL_PHONE", 4=>"WORK_COMPANY", 5=>"WORK_PHONE", ), "SUCCESS_PAGE" => "/auth/", "USER_PROPERTY" => array(), "USER_PROPERTY_NAME" => "", "USE_BACKURL" => "N" ) ); ?> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
И имеет такой вид:
Теперь нам надо кастомизировать форму регистрации под наш дизайн. Для этого копируем шаблон компонента:
- откуда:
bitrix/components/bitrix/main.register/templates/.default
- куда:
local/templates/.default/components/bitrix/main.register/.default
После внесения изменений получилось так:
<? /* * Файл local/templates/.default/components/bitrix/main.register/.default/template.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); ?> <?php if ($USER->IsAuthorized()): /* если пользователь уже авторизован */ ?> <p><?= GetMessage('MAIN_REGISTER_REG_AUTH'); /* Вы зарегистрированы и авторизованы */ ?></p> <?php return ?> <?php endif; ?> <div class="bitrix-main-register"> <h2><?= GetMessage('MAIN_REGISTER_FORM_TITLE'); /* заголовок формы */ ?></h2> <?php if (count($arResult["ERRORS"]) > 0): /* сообщения об ошибках при заполнении формы */ ?> <?php foreach ($arResult["ERRORS"] as $key => $error) { if (intval($key) == 0 && $key !== 0) { $arResult["ERRORS"][$key] = str_replace( "#FIELD_NAME#", '«'.GetMessage('MAIN_REGISTER_'.$key).'»', $error ); } } ShowError(implode("<br />", $arResult["ERRORS"])); ?> <?php elseif ($arResult["USE_EMAIL_CONFIRMATION"] === "Y"): ?> <p><?= GetMessage('MAIN_REGISTER_EMAIL_HELP'); /* будет отправлено письмо для подтверждения */ ?></p> <?php endif; ?> <form method="post" action="<?= POST_FORM_ACTION_URI; ?>" name="regform" enctype="multipart/form-data"> <?php if ($arResult["BACKURL"] <> ''): ?> <input type="hidden" name="backurl" value="<?= $arResult["BACKURL"]; ?>" /> <?php endif; ?> <?php foreach ($arResult["SHOW_FIELDS"] as $FIELD): ?> <?php if ($FIELD == "AUTO_TIME_ZONE" && $arResult["TIME_ZONE_ENABLED"]): /* часовой пояс */ ?> <!-- код удален --> <?php continue; ?> <?php endif; ?> <div> <span> <?= GetMessage('MAIN_REGISTER_'.$FIELD); /* очередное поле */ ?> <?php if ($arResult["REQUIRED_FIELDS_FLAGS"][$FIELD] == "Y"): ?> <i>*</i> <!-- поле обязательно для заполнения --> <?php endif; ?> </span> <span> <?php if ($FIELD == "PASSWORD"): /* пароль */ ?> <input type="password" name="REGISTER[<?= $FIELD; ?>]" value="<?= $arResult["VALUES"][$FIELD]; ?>" autocomplete="off" /> <?php if ($arResult["SECURE_AUTH"]): /* безопасная авторизация */ ?> <!-- код удален --> <?php endif; ?> <?php elseif ($FIELD == "CONFIRM_PASSWORD"): /* подтверждение пароля */ ?> <input type="password" name="REGISTER[<?= $FIELD; ?>]" value="<?= $arResult["VALUES"][$FIELD]; ?>" autocomplete="off" /> <?php elseif ($FIELD == "PERSONAL_GENDER"): /* пол: мужской, женский */ ?> <select name="REGISTER[<?= $FIELD; ?>]"> <option value=""> <?= GetMessage('MAIN_REGISTER_USER_UNKNOWN'); ?> </option> <option value="M"<?= $arResult["VALUES"][$FIELD] == 'M' ? ' selected="selected"' : ''; ?>> <?= GetMessage('MAIN_REGISTER_USER_MALE'); ?> </option> <option value="F"<?= $arResult["VALUES"][$FIELD] == 'F' ? ' selected="selected"' : ''; ?>> <?= GetMessage('MAIN_REGISTER_USER_FEMALE'); ?> </option> </select> <?php elseif (in_array($FIELD, array("PERSONAL_COUNTRY", "WORK_COUNTRY"))): /* страна проживания или работы */ ?> <select name="REGISTER[<?= $FIELD; ?>]"> <?php foreach ($arResult["COUNTRIES"]["reference_id"] as $key => $value): ?> <?php $selected = ($value == $arResult["VALUES"][$FIELD]) ? ' selected="selected"' : ''; ?> <option value="<?= $value; ?>"<?= $selected; ?>> <?= $arResult["COUNTRIES"]["reference"][$key]; ?> </option> <?php endforeach; ?> </select> <?php elseif (in_array($FIELD, array("PERSONAL_PHOTO", "WORK_LOGO"))): /* личное фото */ ?> <input type="file" name="REGISTER_FILES_<?= $FIELD; ?>" /> <?php elseif (in_array($FIELD, array("PERSONAL_NOTES", "WORK_NOTES"))): ?> <textarea name="REGISTER[<?= $FIELD; ?>]"> <?= $arResult["VALUES"][$FIELD]; ?> </textarea> <?php elseif ($FIELD == "PERSONAL_BIRTHDAY"): /* дата рождения */ ?> <small><?= $arResult["DATE_FORMAT"]; ?></small><br /> <input size="30" type="text" name="REGISTER[<?= $FIELD; ?>]" value="<?= $arResult["VALUES"][$FIELD]; ?>" /> <?php $APPLICATION->IncludeComponent( 'bitrix:main.calendar', '', array( 'SHOW_INPUT' => 'N', 'FORM_NAME' => 'regform', 'INPUT_NAME' => 'REGISTER[PERSONAL_BIRTHDAY]', 'SHOW_TIME' => 'N' ), null, array("HIDE_ICONS"=>"Y") ); ?> <?php else: ?> <input type="text" name="REGISTER[<?= $FIELD; ?>]" value="<?= $arResult["VALUES"][$FIELD]; ?>" /> <?php endif; ?> </span> </div> <?php endforeach; ?> <?php /***** User properties *****/ ?> <?php if($arResult["USER_PROPERTIES"]["SHOW"] == "Y"): ?> <h3> <?= empty($arParams["USER_PROPERTY_NAME"]) ? GetMessage("USER_TYPE_EDIT_TAB") : $arParams["USER_PROPERTY_NAME"]; ?> </h3> <?php foreach ($arResult["USER_PROPERTIES"]["DATA"] as $FIELD_NAME => $arUserField): ?> <div> <span> <?= $arUserField["EDIT_FORM_LABEL"]; ?> <?php if ($arUserField["MANDATORY"]=="Y"): ?> <i>*</i> <!-- поле обязательно для заполнения --> <?php endif; ?> </span> <span> <?php $APPLICATION->IncludeComponent( "bitrix:system.field.edit", $arUserField["USER_TYPE"]["USER_TYPE_ID"], array( "bVarsFromForm" => $arResult["bVarsFromForm"], "arUserField" => $arUserField, "form_name" => "regform" ), null, array("HIDE_ICONS"=>"Y") ); ?> </span> </div> <?php endforeach; ?> <?php endif; ?> <?php /***** User properties *****/ ?> <?php if ($arResult["USE_CAPTCHA"] == "Y"): /* использовать CAPTCHA? */ ?> <div class="captcha"> <h3><?= GetMessage('MAIN_REGISTER_CAPTCHA_TITLE'); ?></h3> <input type="hidden" name="captcha_sid" value="<?= $arResult["CAPTCHA_CODE"]; ?>" /> <img src="/bitrix/tools/captcha.php?captcha_sid=<?= $arResult["CAPTCHA_CODE"]; ?>" width="180" height="40" alt="CAPTCHA" /> <span> <?= GetMessage('MAIN_REGISTER_CAPTCHA_HELP'); ?> <i>*</i> </span> <span> <input type="text" name="captcha_word" maxlength="50" value="" /> </span> </div> <?php endif; ?> <div class="submit"> <input type="submit" name="register_submit_button" value="<?= GetMessage('MAIN_REGISTER_FORM_SUBMIT'); /* кнопка отправки формы */ ?>" /> </div> </form> <p> <?= $arResult["GROUP_POLICY"]["PASSWORD_REQUIREMENTS"]; /* предупреждение о min длине пароля */?> </p> <p> <i>*</i> <?= GetMessage('MAIN_REGISTER_REQUIRED'); /* Эти поля обязательны для заполнения */ ?> </p> </div>
<?php /* * Файл local/templates/.default/components/bitrix/main.register/.default/lang/ru/template.php */ $MESS['MAIN_REGISTER_FORM_TITLE'] = 'Регистрация'; $MESS['MAIN_REGISTER_REG_AUTH'] = 'Вы зарегистрированы и успешно авторизованы.'; $MESS['MAIN_REGISTER_EMAIL_HELP'] = 'На указанный в форме e-mail придет запрос на подтверждение регистрации.'; $MESS['MAIN_REGISTER_LOGIN'] = 'Логин'; $MESS['MAIN_REGISTER_EMAIL'] = 'E-mail'; $MESS['MAIN_REGISTER_PASSWORD'] = 'Пароль'; $MESS['MAIN_REGISTER_CONFIRM_PASSWORD'] = 'Подтверждение пароля'; $MESS['MAIN_REGISTER_NAME'] = 'Имя'; $MESS['MAIN_REGISTER_SECOND_NAME'] = 'Отчество'; $MESS['MAIN_REGISTER_LAST_NAME'] = 'Фамилия'; $MESS['MAIN_REGISTER_TITLE'] = 'Обращение'; $MESS['MAIN_REGISTER_USER_UNKNOWN'] = 'Нет данных'; $MESS['MAIN_REGISTER_USER_MALE'] = 'Мужской'; $MESS['MAIN_REGISTER_USER_FEMALE'] = 'Женский'; $MESS['MAIN_REGISTER_PERSONAL_PROFESSION'] = 'Профессия'; $MESS['MAIN_REGISTER_PERSONAL_WWW'] = 'WWW-страница'; $MESS['MAIN_REGISTER_PERSONAL_ICQ'] = 'ICQ'; $MESS['MAIN_REGISTER_PERSONAL_GENDER'] = 'Пол'; $MESS['MAIN_REGISTER_PERSONAL_BIRTHDAY'] = 'Дата рождения'; $MESS['MAIN_REGISTER_PERSONAL_PHOTO'] = 'Фотография'; $MESS['MAIN_REGISTER_PERSONAL_PHONE'] = 'Телефон'; $MESS['MAIN_REGISTER_PERSONAL_FAX'] = 'Факс'; $MESS['MAIN_REGISTER_PERSONAL_MOBILE'] = 'Мобильный'; $MESS['MAIN_REGISTER_PERSONAL_PAGER'] = 'Пейджер'; $MESS['MAIN_REGISTER_PERSONAL_STREET'] = 'Улица, дом'; $MESS['MAIN_REGISTER_PERSONAL_MAILBOX'] = 'Почтовый ящик'; $MESS['MAIN_REGISTER_PERSONAL_CITY'] = 'Город'; $MESS['MAIN_REGISTER_PERSONAL_STATE'] = 'Область / край'; $MESS['MAIN_REGISTER_PERSONAL_ZIP'] = 'Почтовый индекс'; $MESS['MAIN_REGISTER_PERSONAL_COUNTRY'] = 'Страна'; $MESS['MAIN_REGISTER_PERSONAL_NOTES'] = 'Дополнительные заметки'; $MESS['MAIN_REGISTER_WORK_COMPANY'] = 'Наименование компании'; $MESS['MAIN_REGISTER_WORK_DEPARTMENT'] = 'Департамент / Отдел'; $MESS['MAIN_REGISTER_WORK_POSITION'] = 'Должность'; $MESS['MAIN_REGISTER_WORK_WWW'] = 'WWW-страница (работа)'; $MESS['MAIN_REGISTER_WORK_PHONE'] = 'Телефон (работа)'; $MESS['MAIN_REGISTER_WORK_FAX'] = 'Факс (работа)'; $MESS['MAIN_REGISTER_WORK_PAGER'] = 'Пейджер (работа)'; $MESS['MAIN_REGISTER_WORK_STREET'] = 'Улица, дом (работа)'; $MESS['MAIN_REGISTER_WORK_MAILBOX'] = 'Почтовый ящик (работа)'; $MESS['MAIN_REGISTER_WORK_CITY'] = 'Город (работа)'; $MESS['MAIN_REGISTER_WORK_STATE'] = 'Область / край (работа)'; $MESS['MAIN_REGISTER_WORK_ZIP'] = 'Почтовый индекс (работа)'; $MESS['MAIN_REGISTER_WORK_COUNTRY'] = 'Страна (работа)'; $MESS['MAIN_REGISTER_WORK_PROFILE'] = 'Направления деятельности'; $MESS['MAIN_REGISTER_WORK_LOGO'] = 'Логотип компании'; $MESS['MAIN_REGISTER_WORK_NOTES'] = 'Дополнительные заметки (работа)'; $MESS['MAIN_REGISTER_FORM_SUBMIT'] = 'Зарегистрироваться'; $MESS['MAIN_REGISTER_CAPTCHA_TITLE'] = 'Защита от автоматической регистрации'; $MESS['MAIN_REGISTER_CAPTCHA_HELP'] = 'Введите символы с картинки'; $MESS['MAIN_REGISTER_REQUIRED'] = 'Эти поля обязательны для заполнения';
<?php /* * Файл local/templates/.default/components/bitrix/main.register/.default/lang/ru/component.php */ $MESS['REGISTER_WRONG_CAPTCHA'] = 'Неверно введено слово с картинки'; $MESS['REGISTER_FIELD_REQUIRED'] = 'Поле #FIELD_NAME# обязательно для заполнения'; $MESS['REGISTER_DEFAULT_TITLE'] = 'Регистрация нового пользователя'; $MESS['REGISTER_USER_WITH_EMAIL_EXIST'] = 'Пользователь с таким e-mail (#EMAIL#) уже существует'; $MESS['main_register_sess_expired'] = 'Ваша сессия истекла, повторите попытку регистрации'; $MESS['main_register_decode_err'] = 'Ошибка при дешифровании пароля (#ERRCODE#)';
/* * Файл local/templates/.default/components/bitrix/main.register/.default/style.css */ .bitrix-main-register { } .bitrix-main-register > p { margin: 1em 0; } .bitrix-main-register > p > a { text-decoration: underline; } .bitrix-main-register > form { overflow: hidden; } .bitrix-main-register > form > div { width: 50%; margin-bottom: 15px; float: left; box-sizing: border-box; } .bitrix-main-register > form > div.captcha { border: 1px solid #ccc; padding: 20px 15px 15px 15px; position: relative; margin-top: 15px; width: 49%; clear: both; } .bitrix-main-register > form > div.captcha > h3 { position: absolute; top: -10px; font-weight: normal; font-size: 16px; background: #eee; padding: 0 10px; color: #999; } .bitrix-main-register > form > div.captcha > span:first-of-type { margin-top: 10px; } .bitrix-main-register > form > div:nth-of-type(even) { padding-left: 1%; } .bitrix-main-register > form > div:nth-of-type(odd) { padding-right: 1%; } .bitrix-main-register > form > div > span { display: block; } .bitrix-main-register > form > div > span:first-child { margin-bottom: 5px; } .bitrix-main-register > form > div > span > input[type="text"], .bitrix-main-register > form > div > span > input[type="password"], .bitrix-main-register > form > div > span > select, .bitrix-main-register > form > div > span > textarea { width: 100%; padding: 5px; border:1px solid #ccc; } .bitrix-main-register > form > div.submit { float: none; padding-left: 0; } .bitrix-main-register > form > div.submit > input[type="submit"] { width: 30%; padding: 5px; background: #333; color: #fff; border: none; margin-top: 10px; } .bitrix-main-register i { font-style: normal; font-weight: bold; color: #f00; }
И вот что получилось в итоге:
Тут есть еще один важный момент. Что будет, если на эту страницу попадает авторизованный пользователь? Ему показывается малоинформативное сообщение, что он зарегистрирован и авторизован.
<?php if ($USER->IsAuthorized()): /* если пользователь уже авторизован */ ?> <p><?= GetMessage('MAIN_REGISTER_REG_AUTH'); /* Вы зарегистрированы и авторизованы */ ?></p> <?php return ?> <?php endif; ?>
Есть смысл перенаправить его на страницу личного кабинета или на страницу профиля:
<?php if ($USER->IsAuthorized()): /* если пользователь уже авторизован, ему здесь делать нечего */ ?> <?php LocalRedirect('/auth/profile.php'); ?> <?php endif; ?>
Пользовательские поля
Хотя Битрикс предлагает большой набор предопределенных полей, их все-таки может не хватить. Тогда остается только создавать свои поля. Это можно сделать в панели управления: «Настройки • Настройки продукта • Пользовательские поля»:
Я добавил поле «Мое поле», тип «Строка», в настройках компонента указал, что это поле надо показывать:
Теперь форма регистрации имеет вид:
Порядок полей
Для настройки порядка следования полей в форме, создадим файл local/templates/.default/components/bitrix/main.register/.default/result_modifier.php
:
<?php /* * Файл local/templates/.default/components/bitrix/main.register/.default/result_modifier.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); // меняем порядок следования полей $arResult['SHOW_FIELDS'] = array( 'NAME', 'LAST_NAME', 'LOGIN', 'EMAIL', 'PASSWORD', 'CONFIRM_PASSWORD', 'WORK_COMPANY', 'WORK_PHONE', 'PERSONAL_PHONE', ); ?>
В результате чего форма примет вид:
Авторизация по E-mail
Давайте уберем поле LOGIN
, как отживший свое пережиток прошлого. Без этого поля регистрацию пользователь не пройдет, поэтому будем создавать LOGIN
из EMAIL
. Добавляем в init.php
следующий код:
AddEventHandler("main", "OnBeforeUserRegister", "OnBeforeUserUpdateHandler"); AddEventHandler("main", "OnBeforeUserUpdate", "OnBeforeUserUpdateHandler"); function OnBeforeUserUpdateHandler(&$arFields) { $arFields["LOGIN"] = $arFields["EMAIL"]; return $arFields; }
Чтобы форма регистрации не выдавала ошибок «Не заполнено обязательное поле логин», внесем изменение в шаблон компонента:
<?php if ($FIELD == 'LOGIN'): /* логин */ ?> <input type="text" name="REGISTER[<?= $FIELD; ?>]" value="<?= uniqid('user_'); ?>" /> <?php elseif ($FIELD == "PASSWORD"): /* пароль */ ?> <!-- код пропущен --> <?php elseif ($FIELD == "CONFIRM_PASSWORD"): /* подтверждение пароля */ ?> <!-- код пропущен --> <?php endif; ?>
Еще раз изменим порядок следования полей в форме и сделаем поле LOGIN
первым, чтобы можно было его скрыть, обратившись с помощью :first-of-type
:
<?php /* * Файл local/templates/.default/components/bitrix/main.register/.default/result_modifier.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); // меняем порядок следования полей $arResult['SHOW_FIELDS'] = array( 'LOGIN', 'NAME', 'LAST_NAME', 'EMAIL', 'PERSONAL_PHONE', 'PASSWORD', 'CONFIRM_PASSWORD', 'WORK_COMPANY', 'WORK_PHONE', ); ?>
Теперь скроем поле LOGIN
:
/* * Файл local/templates/.default/components/bitrix/main.register/.default/style.css */ .bitrix-main-register { } /* код пропущен */ .bitrix-main-register > form > div:first-of-type { display: none; } /* код пропущен */ .bitrix-main-register > form > div:nth-of-type(even) { padding-right: 1%; } .bitrix-main-register > form > div:nth-of-type(odd) { padding-left: 1%; } /* код пропущен */
Но есть еще одна проблема — у нас теперь две формы регистрации с разным составом полей:
- первая формируется системным компонентом
system.auth.registration
и доступна по адресу/auth/?register=yes
- вторая формируется компонентом
bitrix:main.register
и доступна по адресу/auth/register.php
Давайте это исправим. Удалим весь код из шаблона компонента system.auth.registration
, и поместим в него вызов компонента bitrix:main.register
из файла /auth/register.php
:
<?php /* * Файл local/templates/.default/components/bitrix/system.auth.registration/.default/template.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); $APPLICATION->IncludeComponent( "bitrix:main.register", ".default", array( "AUTH" => "N", "REQUIRED_FIELDS" => array( 0 => "EMAIL", 1 => "NAME", 2 => "LAST_NAME", 3 => "PERSONAL_PHONE", ), "SET_TITLE" => "Y", "SHOW_FIELDS" => array( 0 => "EMAIL", 1 => "NAME", 2 => "LAST_NAME", 3 => "PERSONAL_PHONE", 4 => "WORK_COMPANY", 5 => "WORK_PHONE", ), "SUCCESS_PAGE" => "/auth/", "USER_PROPERTY" => array( ), "USER_PROPERTY_NAME" => "", "USE_BACKURL" => "N", "COMPONENT_TEMPLATE" => ".default" ), false );
А файл /auth/register.php
просто удалим. Можно еще удалить лишний код из шаблона компонента bitrix:main.register
, который никогда не будет выполнен. Системный компонент system.auth.registration
вызывается где-то глубоко в недрах Битрикс только в том случае, если пользователь не авторизован. И еще одна проверка в шаблоне «Пользователь авторизован?» просто не нужна.
<?php /* * Файл local/templates/.default/components/bitrix/main.register/.default/template.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); ?> <!-- следующие три строчки можно удалить --> <?php if ($USER->IsAuthorized()): /* если пользователь уже авторизован, ему здесь делать нечего */ ?> <?php LocalRedirect('/auth/profile.php'); ?> <?php endif; ?>
Не забываем изменить другие системные компоненты:
<?php /* * Файл local/templates/.default/components/bitrix/system.auth.authorize/.default/lang/ru/template.php */ $MESS['SYS_AUTH_AUTHORIZE_TITLE'] = 'Авторизация'; // теперь e-mail используется как логин $MESS['SYS_AUTH_AUTHORIZE_LOGIN'] = 'E-mail'; $MESS['SYS_AUTH_AUTHORIZE_PASSWORD'] = 'Пароль'; $MESS['SYS_AUTH_AUTHORIZE_REMEMBER'] = 'Запомнить меня'; $MESS['SYS_AUTH_AUTHORIZE_CAPTCHA_TITLE'] = 'Защита от автоматической регистрации'; $MESS['SYS_AUTH_AUTHORIZE_CAPTCHA_TEXT'] = 'Введите символы с картинки'; $MESS['SYS_AUTH_AUTHORIZE_SUBMIT'] = 'Войти'; $MESS['SYS_AUTH_AUTHORIZE_REG_USER'] = 'Зарегистрироваться'; $MESS['SYS_AUTH_AUTHORIZE_FORGOT'] = 'Забыли пароль?';
<?php /* * Файл local/templates/.default/components/bitrix/system.auth.forgotpasswd/.default/lang/ru/template.php */ $MESS['SYS_AUTH_FORGOT_TITLE'] = 'Восстановление пароля'; // теперь восстановление пароля только по e-mail $MESS['SYS_AUTH_FORGOT_HELP'] = 'Введите Ваш E-mail: инструкция по смене пароля будет отправлена на этот почтовый адрес.'; $MESS['SYS_AUTH_FORGOT_LOGIN'] = 'Логин'; $MESS['SYS_AUTH_FORGOT_EMAIL'] = 'E-mail'; $MESS['SYS_AUTH_FORGOT_CAPTHA_TITLE'] = 'Защита от автоматической регистрации'; $MESS['SYS_AUTH_FORGOT_CAPTHA_TEXT'] = 'Введите символы с картинки'; $MESS['SYS_AUTH_FORGOT_SUBMIT'] = 'Отправить'; $MESS['SYS_AUTH_FORGOT_AUTH'] = 'Авторизация';
<?php /* * Файл local/templates/.default/components/bitrix/system.auth.forgotpasswd/.default/template.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); ?> <!-- логин больше не нужен, удаляем или комментируем код ниже --> <!-- <div> <span> <?= GetMessage('SYS_AUTH_FORGOT_LOGIN'); /* логин пользователя */ ?> </span> <span> <input type="text" name="USER_LOGIN" maxlength="50" value="<?= $arResult["LAST_LOGIN"]; ?>" /> </span> </div> -->
<?php /* * Файл local/templates/.default/components/bitrix/system.auth.changepasswd/.default/lang/ru/template.php */ $MESS['SYS_AUTH_CHANGE_TITLE'] = 'Смена пароля'; // теперь e-mail используется как логин $MESS['SYS_AUTH_CHANGE_LOGIN'] = 'E-mail'; $MESS['SYS_AUTH_CHANGE_CHECK'] = 'Контрольная строка'; $MESS['SYS_AUTH_CHANGE_PASSWORD'] = 'Новый пароль'; $MESS['SYS_AUTH_CHANGE_CONFIRM'] = 'Подтверждение пароля'; $MESS['SYS_AUTH_CHANGE_CAPTCHA_TITLE'] = 'Защита от автоматической регистрации'; $MESS['SYS_AUTH_CHANGE_CAPTCHA_TEXT'] = 'Введите символы с картинки'; $MESS['SYS_AUTH_CHANGE_SUBMIT'] = 'Изменить пароль'; $MESS['SYS_AUTH_CHANGE_AUTH'] = 'Авторизация'; $MESS['SYS_AUTH_CHANGE_REQUIRED'] = 'Эти поля обязательны для заполнения';
Есть еще один момент, о котором есть смысл упомянуть. Если при изменении пароля не заполнить поле «E-mail», появляется сообщение об ошибке «Логин должен быть не менее 3 символов». Где это изменить, я не нашел, видимо где-то в недрах ядра Битрикс. Поэтому небольшой хак:
<?php /* * Файл local/templates/.default/components/bitrix/system.auth.changepasswd/.default/template.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); ?> <div class="system-auth-changepasswd"> <h2><?= GetMessage('SYS_AUTH_CHANGE_TITLE'); /* заголовок формы */ ?></h2> <?php // небольшй хак, который убирает сообщение о длине логина if (isset($arParams['AUTH_RESULT']['TYPE']) && $arParams['AUTH_RESULT']['TYPE'] == 'ERROR' && false !== iconv_strpos($arParams['AUTH_RESULT']['MESSAGE'], 'Логин должен быть')) { $arParams['~AUTH_RESULT']['MESSAGE'] = 'Недопустимое значение поля «E-mail»'; } ?> <p><?php ShowMessage($arParams["~AUTH_RESULT"]); /* сообщение о результате смены пароля */ ?></p>
Поиск:
CMS • Web-разработка • Авторизация • Битрикс • Компонент • Регистрация • Форма • Шаблон компонента
Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
В интернете описано достаточно большое кол-во статей на данную тему, но так как у нас Bitrix, каждый решает данную задачу по-своему. На просторах сети нашел достаточно простое решение реализации данной задачи.
Итак, первое что нам нужно сделать, чтобы добавить поле телефон при регистрации пользователя в CMS Bitrix – это зайти в админку. Далее идем в Настройки->Пользователи->Список пользователей. Скриншот:
После того, как мы зашли в список пользователей нам необходимо перейти на любого пользователя и открыть вкладку “Доп. Поля”
Далее нажимаем “Добавить пользовательское поле” и заполняем его характеристики:
В моем случае с полем “Телефон” я заполнил следующим образом:
Тип данных (можно задать только для нового поля): | Строка |
Объект: | USER |
Код поля (можно задать только для нового поля): | UF_PHONE |
Обязательное: (отмечаю чекбокс)
И далее остается заполнить остальные характеристики с переводом. Сохраняем – смотрим форму регистрации и ВУАЛЯ – мы с вами добавили кастомное поле при регистрации пользователя в CMS BItrix!