Мы нажимаем кнопочку на отрытой странице , например test.ru, например vk . Происходит всплытие окна с авторизацией на vk. Во всплывающем окне происходит редирект на test.ru и происходит авторизация в фоновом режиме.
Что мы видим:
1.в табличке b_user появилась новая запись (это можно посмотреть в админ панели).
2. Если хорошо покопаться в табличках битрикса появилась запись в b_socialservices_user
Рассмотрим табличку bitrix b_user и пользователя вошедшего через vk.
Значение в поле EXTERNAL_AUTH_ID=socservices .
Если выставить это значение в Null , запросом, то получим … обычного пользователя.
1 |
UPDATE `test4`.`b_user` SET `EXTERNAL_AUTH_ID` = NULL WHERE `b_user`.`ID` =54; |
Т.е. до выставления этого значения , логин-пароль заменить нельзя было, а если выставить- то можно. Загляните в админку в обычного пользователя и на пользователя зашедшего через vk. В vk- нет логина пароля пользователя.
Теперь посмотрим на табличку bitrix b_socialservices_user.
У нее есть много полей, заполненных из социальной сети, e-mail , имена и другие полезные данные.
в ней есть значение USER_ID=54; Т.е. мы имеем, что табличка привязана к пользователю в табличке b_user с id=54.
Теперь, сделаем такую штуку.Зайдем под пользователем с id=10, через обычного пользователя. И сделаем из под него привязку к пользователю vk чеерз компонент «bitrix:socserv.auth.split» . И… мы увидим что в b_socialservices_user значение USER_ID=10. Просто сменилась привязка к пользователя из социальной сети к другому пользователю.
А теперь фишка!. Если вдруг мы удаляем привязку из пользователя с id=10. Полностью стирается запись в таблице b_socialservices_user.
Теперь, как привязать одного пользователя из vk к любому пользователю обычному. Привязать означает- если человек зашел через vk он попадает в нужного пользователя, по заданной вами логике. У меня логика была в поиске емайла и привязка к пользователю по емайлу.
Вот полезная функция. Привязка обычного пользователя к пользователю из vk. Мы на вход подаем id нужного пользователя и логин vk из таблички b_user. (в b_user- логин заносится автоматически в поле $arUser[‘LOGIN’]).
1 2 3 4 5 6 7 8 |
function SplitUsersBySocloginAndIdUser($id_us_normal, $socset_login){ /*$id_us_normal=53; //обычный пользователь $socset_login='VKuser49...'; */ $connection = Bitrix\Main\Application::getConnection(); $sql = "UPDATE `b_socialservices_user` SET `USER_ID` = '$id_us_normal' WHERE `b_socialservices_user`.`LOGIN` ='$socset_login'"; //echo $sql; $recordset = $connection->queryExecute($sql); } |
Теперь о приколах bitrix для пользователя из социальной сети.
1 при входе черз соцсеть происходит кеширование init.php !после отработки авторизации. Если вы 1 раз изменили файл, то то надо логиниться еще раз. Иначе код не применится. Т.е die() команда с первого раза не сработает! Вы не сможете сразу увидеть результат тестирования.
2 заполнение привязки из соцсети в табличку b_socialservices_user происходит ПОСЛЕ события OnAfterUserAdd. Т.е не мы можем отследить заполение этой таблички сразу посkе авторизации. Поэтому для различных привязок пользователей в файл header.php надо вставить хак . (возможно его можно вставить еще куда нибудь, я не нашел) . В хаке проверяем, пользователь у нас из социально сети или нет. Если из социальной сети, то привязываем его к нужному пользователю и авторизуем его
1 2 3 4 5 6 7 8 9 10 |
global $USER; $rsUser = CUser::GetByID($USER->GetID()); $arUser = $rsUser->Fetch(); if($arUser['EXTERNAL_AUTH_ID']=='socservices'){ // тут ваш код по привязкам к социальной сети в котором вы получите $id_new_user - id нужного вам пользователя. ......... //$id_new_user $USER->Authorize($id_new_user); } |
мой вариант кода, комментировать ничего не буду. Тут я решал свои задачи.
1 2 3 4 5 6 7 8 |
global $USER; $rsUser = CUser::GetByID($USER->GetID()); $arUser = $rsUser->Fetch(); if($arUser['EXTERNAL_AUTH_ID']=='socservices'){ //echo 'вход через социальную сеть-перекидываем на обычного пользователя или оставляем тут' ; $id_new_user=StartSplitUsers($USER->GetID()); $USER->Authorize($id_new_user); } |
А далее полный код привязки, оставлю без коментариев и с внутренней кривизной. Если надо- пользуйте. Там привязывают по e-mail. Если пустой е-mail во вставляет заглушку. И еще происходит создание нормального пользователя битрикса. И к нему все привязываются.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
function getIdUserByEmailLogin($LOGIN_SOC){ //echo $LOGIN_SOC; $id_user_search=''; $filter = Array("LOGIN" => $LOGIN_SOC); $rsUser = CUser::GetList(($by="id"), ($order="desc"), $filter); if($arUser = $rsUser->Fetch()) { $id_user_search = $arUser['ID']; //echo $id_user_search; } return $id_user_search; } function createUserByEmail($EMAIL, $NAME, $LAST_NAME ,$new_password ){ // создадим массив описывающий изображение // находящееся в файле на сервере //$new_password = randString(10); $user = new CUser; $arFields = Array( "NAME" => $NAME, "LAST_NAME" => $LAST_NAME, "EMAIL" => $EMAIL, "LOGIN" => $EMAIL, "LID" => "ru", "ACTIVE" => "Y", "GROUP_ID" => array(2,3), "PASSWORD" => $new_password, "CONFIRM_PASSWORD" => $new_password, /* "PASSWORD" => 123456 "CONFIRM_PASSWORD" => '123456', */ ); //echo 'пароль:'.$new_password. ' '; /* echo '<pre>'; print_r($arFields); echo '</pre>'; */ //проверяем, есть такой, и не создаем если есть. $ID=getIdUserByEmailLogin($EMAIL); if(empty($ID)){ $ID = $user->Add($arFields); if (intval($ID) > 0) echo "Пользователь успешно добавлен. id=".$ID; else echo $user->LAST_ERROR; } return $ID; } function StartSplitUsers( $id_user_input){ global $USER; if(!is_object($USER)) $USER = new CUser; //echo '===='.$id_user_input.'======'; $rsUser = CUser::GetByID($id_user_input); //print_r($rsUser ); // error_reporting(E_ALL); //echo '$id_user_input='.$id_user_input.' '; //echo $id_user_input; $arUser = $rsUser->Fetch(); $EMAIL=$arUser['EMAIL']; $NAME=$arUser['NAME']; $LAST_NAME=$arUser['LAST_NAME']; //echo $EMAIL; // echo ' текущий пользователь '.$USER->GetID().' ----'; //print_r($arUser); if($arUser['EXTERNAL_AUTH_ID']=='socservices'){ // echo 'Это соц сеть'; //мы вошли через социальную сеть. и попали в пользователя социальной сети // ищем обычного пользователя, у которого логин будет нужным нам emailom $LOGIN_SOC=$arUser['LOGIN']; /*if(empty($EMAIL)){ $EMAIL=$LOGIN_SOC.'@noreal-grmaster.ru'; }*/ $new_password = randString(10); if(!empty($EMAIL)){ // поиск пользователя по емайл //получаем id пользователя по e-mail, который является и логином $EMAILLogin=$EMAIL; $id_user_search=getIdUserByEmailLogin($EMAILLogin); // echo 'id usera v base'.$id_user_search.' '; //если нет такого пользователя, создаем его! //echo $id_user_search; if(empty($id_user_search)){ $id_user_search=createUserByEmail($EMAIL, $NAME, $LAST_NAME ,$new_password); } }else{ $EMAIL=$LOGIN_SOC.'@noreal.ru'; echo $EMAIL; $id_user_search=createUserByEmail($EMAIL, $NAME, $LAST_NAME ,$new_password); // создаем пользователя // добавляем ему группу //привязываем одноклассники к этому пользователю // заходим под этим пользователем } // для созданного и имеющегося пользователя делаем привязку if(!empty($id_user_search )){ // если найден юзер, то мы выходим из текущего, входим в найденного пользователя // и делаем привязку SplitUsersBySocloginAndIdUser($id_user_search, $LOGIN_SOC); } } return $id_user_search; } |
1. перетащить все данные из vkuser в нормального пользователя;
2. не забыть удалить пользователя с логином VKuser…; Дабы не засирать БД;
Спасибо за статью)
Пожалуйста)) К сожалению в моей версии база засирается еще как))) Для каждого нового пользователя из социальной сети. Если вы что то доработаете- я могу это добавить в этот урок.
А перетаскивание данных можно повесить на обработчики. Но с этим туго- надо в коде смотреть. Описание в api не совпадает с реальностью.
Вылавливаем учётку юзера с email’ом как в соцсети и прикрепляем к ней
AddEventHandler(«socialservices», «OnFindSocialservicesUser», «OnFindSocialservicesUserHandler»);
function OnFindSocialservicesUserHandler(&$socservUserFields) {
$dbUsersOld = CUser::GetList($by = ‘ID’, $ord = ‘ASC’, array(‘EMAIL’ => $socservUserFields[‘EMAIL’], ‘ACTIVE’ => ‘Y’), array(‘NAV_PARAMS’ => array(«nTopCount» => «1»)));
$socservUser = $dbUsersOld->Fetch();
if($socservUser) {
return $socservUser[«ID»];
}
return false;
}
Спасибо) Будет полезно)
кстати даже так, надо проверять на пустой мейл, а то учётки соцсетей без email’ов будут сливаться с админской учёткой — это будет эпичный фейл
AddEventHandler(«socialservices», «OnFindSocialservicesUser», «OnFindSocialservicesUserHandler»);
function OnFindSocialservicesUserHandler(&$socservUserFields) {
if ($socservUserFields[‘EMAIL’] != ») {
$dbUsersOld = CUser::GetList($by = ‘ID’, $ord = ‘ASC’, array(‘EMAIL’ => $socservUserFields[‘EMAIL’], ‘ACTIVE’ => ‘Y’), array(‘NAV_PARAMS’ => array(«nTopCount» => «1»)));
$socservUser = $dbUsersOld->Fetch();
if ($socservUser) {
return $socservUser[«ID»];
}
}
return false;
}
А не подскажете куда это все писать?
Вот это событие вообще не срабатывает
AddEventHandler(«socialservices», «OnFindSocialservicesUser», «OnFindSocialservicesUserHandler»);
function OnFindSocialservicesUserHandler(&$socservUserFields) {
if ($socservUserFields[‘EMAIL’] != ») {
$dbUsersOld = CUser::GetList($by = ‘ID’, $ord = ‘ASC’, array(‘EMAIL’ => $socservUserFields[‘EMAIL’], ‘ACTIVE’ => ‘Y’), array(‘NAV_PARAMS’ => array(«nTopCount» => «1»)));
$socservUser = $dbUsersOld->Fetch();
if ($socservUser) {
return $socservUser[«ID»];
}
}
return false;
}
я в хедер страницы вставил. И при каждой загрузке проверяю.