• Модуль: ldap
  • Путь к файлу: ~/bitrix/modules/ldap/classes/general/ldap_server.php
  • Класс: CLdapServer
  • Вызов: CLdapServer::Sync
static function Sync($ldap_server_id)
{
	global $DB, $USER, $APPLICATION;
	$bUSERGen = false;
	self::$syncErrors = array();

	if(!is_object($USER))
	{
		$USER = new CUser();
		$bUSERGen = true;
	}

	$dbLdapServers = CLdapServer::GetByID($ldap_server_id);
	if(!($oLdapServer = $dbLdapServers->GetNextServer()))
		return false;

	if(!$oLdapServer->Connect())
		return false;

	if(!$oLdapServer->BindAdmin())
	{
		$oLdapServer->Disconnect();
		return false;
	}

	$APPLICATION->ResetException();
	$db_events = GetModuleEvents("ldap", "OnLdapBeforeSync");

	while($arEvent = $db_events->Fetch())
	{
		$arParams['oLdapServer'] = $oLdapServer;

		if(ExecuteModuleEventEx($arEvent, array(&$arParams))===false)
		{
			if(!($err = $APPLICATION->GetException()))
				$APPLICATION->ThrowException("Unknown error");

			return false;
		}
	}

	// select all users from LDAP
	$arLdapUsers = array();
	$ldapLoginAttr = mb_strtolower($oLdapServer->arFields["~USER_ID_ATTR"]);

	$APPLICATION->ResetException();
	$dbLdapUsers = $oLdapServer->GetUserList();
	$ldpEx = $APPLICATION->GetException();

	while($arLdapUser = $dbLdapUsers->Fetch())
		$arLdapUsers[mb_strtolower($arLdapUser[$ldapLoginAttr])] = $arLdapUser;

	unset($dbLdapUsers);

	// select all Bitrix CMS users for this LDAP
	$arUsers = Array();

	CTimeZone::Disable();
	$dbUsers = CUser::GetList('', '', Array("EXTERNAL_AUTH_ID"=>"LDAP#".$ldap_server_id));
	CTimeZone::Enable();

	while($arUser = $dbUsers->Fetch())
		$arUsers[mb_strtolower($arUser["LOGIN"])] = $arUser;
		
	unset($dbUsers);

	$arDelLdapUsers = array();

	if(!$ldpEx || $ldpEx->msg != 'LDAP_SEARCH_ERROR')
		$arDelLdapUsers = array_diff(array_keys($arUsers), array_keys($arLdapUsers));

	if($oLdapServer->arFields["SYNC_LAST"] <> '')
		$syncTime = MakeTimeStamp($oLdapServer->arFields["SYNC_LAST"]);
	else
		$syncTime = 0;

	$cnt = 0;
	$departmentCache = array();
	// have to update $oLdapServer->arFields["FIELD_MAP"] for user fields
	// for each one of them looking for similar in user list
	foreach($arLdapUsers as $userLogin => $arLdapUserFields)
	{
		if(!is_array($arUsers[$userLogin]))
		{
			//For manual users import - always add
			if($oLdapServer->arFields["SYNC_USER_ADD"] != "Y")
				continue;

			// if user is not found among already existing ones, then import him
			// $arLdapUserFields - user fields from ldap
			$userActive = $oLdapServer->getLdapValueByBitrixFieldName("ACTIVE", $arLdapUserFields);

			if($userActive != "Y")
				continue;

			$arUserFields = $oLdapServer->GetUserFields($arLdapUserFields, $departmentCache);

			if(self::isUserInBannedGroups($ldap_server_id, $arUserFields))
				continue;

			if($oLdapServer->SetUser($arUserFields))
			{
				$cnt++;
			}
			else if(BitrixLdapLimit::isUserLimitExceeded())
			{
				self::$syncErrors[] = BitrixLdapLimit::getUserLimitNotifyMessage();
				break;
			}
		}
		else
		{
			// if date of update is set, then compare it
			$ldapTime = time();

			if($syncTime > 0
				&& $oLdapServer->arFields["SYNC_ATTR"] <> ''
				&& preg_match("'([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2}).0Z'", $arLdapUserFields[mb_strtolower($oLdapServer->arFields["SYNC_ATTR"])], $arTimeMatch)
				)
			{
				$ldapTime = gmmktime($arTimeMatch[4], $arTimeMatch[5], $arTimeMatch[6], $arTimeMatch[2], $arTimeMatch[3], $arTimeMatch[1]);
				$userTime = MakeTimeStamp($arUsers[$userLogin]["TIMESTAMP_X"]);
			}

			if($syncTime < $ldapTime || $syncTime < $userTime)
			{
				$arUserFields = $oLdapServer->GetUserFields($arLdapUserFields, $departmentCache);

				if(self::isUserInBannedGroups($ldap_server_id, $arUserFields))
					continue;

				$arUserFields["ID"] = $arUsers[$userLogin]["ID"];

				if($oLdapServer->SetUser($arUserFields))
				{
					$cnt++;
				}
				else if(BitrixLdapLimit::isUserLimitExceeded())
				{
					self::$syncErrors[] = BitrixLdapLimit::getUserLimitNotifyMessage();
					break;
				}
			}
		}

		if($USER->LAST_ERROR != '')
		{
			self::$syncErrors[] = $userLogin.': '.$USER->LAST_ERROR;
			$USER->LAST_ERROR = '';
		}
	}

	foreach ($arDelLdapUsers as $userLogin)
	{
		$USER = new CUser();
		if (isset($arUsers[$userLogin]) && $arUsers[$userLogin]['ACTIVE'] == 'Y')
		{
			$ID = intval($arUsers[$userLogin]["ID"]);
			$USER->Update($ID, array('ACTIVE' => 'N'));
		}
	}

	$oLdapServer->Disconnect();
	CLdapServer::Update($ldap_server_id, Array("~SYNC_LAST"=>$DB->CurrentTimeFunction()));

	if($bUSERGen)
		unset($USER);

	return $cnt;
}