• Модуль: socialnetwork
  • Путь к файлу: ~/bitrix/modules/socialnetwork/classes/general/log_counter.php
  • Класс: CAllSocNetLogCounter
  • Вызов: CAllSocNetLogCounter::GetSubSelect
static function GetSubSelect(
	$counterEntityId,
	$counterEntityType = '',
	$logEntityId = false,
	$logEventId = '',
	$createdById = 0,
	$entitiesList = null,
	$adminList = false,
	$transport = false,
	$visible = "Y",
	$type = CSocNetLogCounter::TYPE_LOG_ENTRY,
	$params = array(),
	$decrement = false,
	$forAllAccess = false
)
{
	global $DB;

	if (
		is_array($counterEntityId)
		&& isset($counterEntityId["LOG_ID"])
	)
	{
		$arFields = $counterEntityId;

		$counterEntityId = (int)$arFields["LOG_ID"];
		$counterEntityType = (string)($arFields["ENTITY_TYPE"] ?? '');
		$logEventId = (string)($arFields["EVENT_ID"] ?? '');
		$createdById = (int)($arFields["CREATED_BY_ID"] ?? 0);
		$type = ($arFields["TYPE"] ?? CSocNetLogCounter::TYPE_LOG_ENTRY);
		$code = ($arFields["CODE"] ?? false);
		$params = ($arFields["PARAMS"] ?? []);
		$decrement = ($arFields["DECREMENT"] ?? false);
		$multiple = (isset($arFields['MULTIPLE']) && $arFields['MULTIPLE'] === 'Y');
		$setTimestamp = (isset($arFields['SET_TIMESTAMP']) && $arFields['SET_TIMESTAMP'] === 'Y');

		$forAllAccessOnly = false;
		if (isset($arFields["FOR_ALL_ACCESS_ONLY"]))
		{
			$forAllAccessOnly = ($arFields["FOR_ALL_ACCESS_ONLY"] ? "Y" : "N");
		}

		$forAllAccess = (
			$forAllAccessOnly === 'Y'
				? true
				: ($arFields["FOR_ALL_ACCESS"] ?? false)
		);
		$tagSet = ($arFields["TAG_SET"] ?? false);

		$sendToAuthor = (
			isset($arFields['SEND_TO_AUTHOR'])
			&& $arFields['SEND_TO_AUTHOR'] === 'Y'
		);
		$userIdListToIncrement = (
			isset($arFields["USER_ID"])
			&& is_array($arFields["USER_ID"])
				? $arFields["USER_ID"]
				: []
		);
		$workgroupMode = (bool)($arFields["WORKGROUP_MODE"] ?? false);
	}
	else
	{
		$sendToAuthor = false;
		$forAllAccessOnly = false;
		$multiple = false;
		$tagSet = false;
		$code = false;
		$setTimestamp = false;
		$userIdListToIncrement = [];
		$workgroupMode = false;
	}

	$intranetInstalled = static::$moduleManagerClass::isModuleInstalled('intranet');
	if ((int)$counterEntityId <= 0)
	{
		return '';
	}

	$arSocNetAllowedSubscribeEntityTypesDesc = static::$allowedClass::GetAllowedEntityTypesDesc();

	if (!$code)
	{
		$code = CUserCounter::LIVEFEED_CODE . ($multiple ? $type.$counterEntityId : "");

		if ($workgroupMode)
		{
			$code .= 'SG';
		}

		$code = "'" . $code . "'";
	}

	$params = (
		is_array($params)
			? $params
			: []
	);

	$params['CODE'] = (
		!empty($params['CODE'])
			? $params['CODE']
			: $code
	);

	if (
		$type === CSocNetLogCounter::TYPE_LOG_ENTRY
		&& ($arLog = static::$logClass::GetByID($counterEntityId))
	)
	{
		$logId = $counterEntityId;
		$counterEntityType = (string)$arLog["ENTITY_TYPE"];
		$logEventId = (string)$arLog["EVENT_ID"];
		$createdById = (int)$arLog["USER_ID"];
	}
	elseif (
		$type === CSocNetLogCounter::TYPE_LOG_COMMENT
		&& ($arLogComment = static::$logCommentClass::GetByID($counterEntityId))
	)
	{
		$counterEntityType = (string)$arLogComment["ENTITY_TYPE"];
		$logEventId = (string)$arLogComment["EVENT_ID"];
		$createdById = (int)$arLogComment["USER_ID"];
		$logId = $arLogComment["LOG_ID"]; // recalculate log_id
	}
	else
	{
		$logId = $counterEntityId;
	}

	if (
		$logEventId === ''
		|| !in_array($counterEntityType, static::$allowedClass::GetAllowedEntityTypes(), true)
	)
	{
		return '';
	}

	$logRightCodes = [];
	$res = static::$logRightTableClass::getList([
		'filter' => [
			'=LOG_ID' => $logId,
		],
		'select' => [ 'GROUP_CODE' ],
	]);
	while ($logRightFields = $res->fetch())
	{
		$logRightCodes[] = $logRightFields['GROUP_CODE'];
	}

	$useUASubSelect = false;

	$useFollow = (
		!$workgroupMode
		&& $type === CSocNetLogCounter::TYPE_LOG_COMMENT
		&& (
			!defined('DisableSonetLogFollow')
			|| DisableSonetLogFollow !== true
		)
	);

	$defaultFollowValue = static::$optionClass::get('socialnetwork', 'follow_default_type', 'Y');

	$followJoin = '';
	$followWhere = '';

	if ($useFollow)
	{
		if ($defaultFollowValue === 'Y')
		{
			$followWhere = "
				AND (
					NOT EXISTS (
						SELECT USER_ID 
						FROM b_sonet_log_follow 
						WHERE 
							USER_ID = U.ID 
							AND TYPE = 'N' 
							AND (CODE = 'L" . $logId . "' OR CODE = '**')
					)
					OR EXISTS (
						SELECT USER_ID 
						FROM b_sonet_log_follow 
						WHERE 
							USER_ID = U.ID 
							AND TYPE = 'Y' AND CODE = 'L" . $logId . "'
					)
				)
			";
		}
		else
		{
			$followJoin = '';

			[ $join, $condition ] = static::getFollowJoin($logId, 'U.ID', 'positive');
			$followJoin .= $join . ' AND ' . $condition . ' ';

			[ $join, $condition ] = static::getFollowJoin($logId, 'U.ID', 'negative');
			$followJoin .= $join . ' AND ' . $condition . ' ';

			$wherePositive = static::getFollowWhere('positive');
			$whereNegative = static::getFollowWhere('negative');

			$followWhere = "
				AND (LFW.USER_ID IS NOT NULL AND " . $wherePositive .")
				AND " . $whereNegative . "
			";
		}
	}

	$viewJoin = " 
		LEFT JOIN b_sonet_log_view LFV 
		ON 
			LFV.USER_ID = U.ID 
			AND LFV.EVENT_ID = '" . $DB->ForSql($logEventId) . "'";

	$viewWhere = "AND (LFV.USER_ID IS NULL OR LFV.TYPE = 'Y')";

	$logRightFilterValue = [];

	if (!empty($userIdListToIncrement))
	{
		$userWhere = " AND U.ID IN (".implode(",", $userIdListToIncrement).")";
	}
	elseif ($workgroupMode)
	{
		$workgroupIdList = [];
		foreach ($logRightCodes as $rightCode)
		{
			if (
				!preg_match('/^SG(d+)/i', $rightCode, $matches)
				|| (int)$matches[1] <= 0
			)
			{
				continue;
			}
			$workgroupIdList[] = (int)$matches[1];
		}

		$workgroupIdList = array_unique($workgroupIdList);
		if (empty($workgroupIdList))
		{
			return '';
		}

		$userWhere = "
			AND SU2G.GROUP_ID IN (" . static::implodeArrayOfIntegers($workgroupIdList) . ")
			AND SU2G.ROLE IN (" . static::implodeArrayOfStrings(UserToGroupTable::getRolesMember()) . ")
		";
	}
	elseif (!$intranetInstalled)
	{
		if (static::$optionClass::get('socialnetwork', 'sonet_log_smart_filter', 'N') === 'Y')
		{
			$userWhere = "
				AND (
					0=1
					OR (
						(
							SLSF.USER_ID IS NULL
							OR SLSF.TYPE = 'Y'
						)
						" . (!$forAllAccess ? ' AND (UA.ACCESS_CODE = SLR.GROUP_CODE)' : '') . "
						AND (
							SLR.GROUP_CODE LIKE 'SG%'
							OR SLR.GROUP_CODE = " . $DB->Concat("'U'", 'U.ID') . "
						)
					)
					OR (
						SLSF.TYPE <> 'Y'
						AND (
							SLR.GROUP_CODE IN ('AU', 'G2')
							" . (!$forAllAccess ? ' OR (UA.ACCESS_CODE = SLR.GROUP_CODE)' : '') . "
						)
					)
				)
			";
		}
		else
		{
			$userWhere = "
				AND (
					0=1
					OR (
						(
							SLSF.USER_ID IS NULL
							OR SLSF.TYPE <> 'Y'
						)
						AND (
							SLR.GROUP_CODE IN ('AU', 'G2')
							" . ($forAllAccess ? '' : ' OR (UA.ACCESS_CODE = SLR.GROUP_CODE)') . "
						)
					)
					OR (
						SLSF.TYPE = 'Y'
						" . ($forAllAccess ? '' : ' AND (UA.ACCESS_CODE = SLR.GROUP_CODE)') . "
						AND (
							SLR.GROUP_CODE LIKE 'SG%'
							OR SLR.GROUP_CODE = " . $DB->Concat("'U'", 'U.ID') . "
						)
					)
				)
			";
		}
	}
	else
	{
		$userLogRightsIntersectCondition = '';
		if (!$forAllAccess && $forAllAccessOnly !== 'Y')
		{
			foreach ($logRightCodes as $rightCode)
			{
				if (in_array($rightCode, [ 'AU', 'G2' ], true))
				{
					continue;
				}

				$logRightFilterValue[] = $rightCode;
			}

			$userLogRightsIntersectCondition = (
				!empty($logRightFilterValue)
					? ' OR UA.ACCESS_CODE IN (' . static::implodeArrayOfStrings($logRightFilterValue) . ') '
					: ' OR UA.ACCESS_CODE = SLR.GROUP_CODE '
				);
		}

		if (
			$useFollow
			&& $defaultFollowValue !== 'Y'
			&& !$forAllAccess
			&& $forAllAccessOnly !== 'Y'
			&& !empty($logRightFilterValue)
		)
		{
			$useUASubSelect = true;

			[ $join, $condition ] = static::getFollowJoin($logId, 'UA.USER_ID', 'positive');
			$where = static::getFollowWhere('positive');

			$userWhere = "
				AND U.ID IN (
					SELECT DISTINCT UA.USER_ID
					FROM b_user_access UA
					" . $join . "
					WHERE
						UA.ACCESS_CODE IN (" . static::implodeArrayOfStrings($logRightFilterValue) . ")
						AND " . $where . "
						AND " . $condition . "
				)
			";

			[ $join, $condition ] = static::getFollowJoin($logId, 'U.ID', 'negative');
			$where = static::getFollowWhere('negative');

			$followJoin = $join . ' AND ' . $condition . ' ';
			$followWhere = " AND " . $where . " ";
		}
		else
		{
			$userWhere = "
				AND (
					0=1
					" . (
						$forAllAccessOnly !== 'N' || $forAllAccess
							? "OR (SLR.GROUP_CODE IN ('AU', 'G2'))"
							: ''
					) . "
					" . $userLogRightsIntersectCondition . "
				)
			";
		}
	}

	$userWhere = (
		(
			$type === CSocNetLogCounter::TYPE_LOG_COMMENT
			|| (
				array_key_exists("USE_CB_FILTER", $arSocNetAllowedSubscribeEntityTypesDesc[$counterEntityType])
				&& $arSocNetAllowedSubscribeEntityTypesDesc[$counterEntityType]["USE_CB_FILTER"] === "Y"
			)
		)
		&& $createdById > 0
		&& !$sendToAuthor
			? " AND U.ID <> " . $createdById
			: ""
		) .
		$userWhere;

	if ($workgroupMode)
	{
		$strSQL = "
			SELECT DISTINCT
				U.ID as ID
				," . ($decrement ? "-1" : "1") . " as CNT
				, '**' as SITE_ID
				," . $DB->Concat($params['CODE'], 'SU2G.GROUP_ID') . " as CODE,
				0 as SENT
				" . ($tagSet ? ", '" . $DB->ForSQL($tagSet) . "' as TAG" : "") . "
				" . ($setTimestamp ? ', ' . CDatabase::currentTimeFunction() . ' as TIMESTAMP_X' : '') . "
			FROM
				b_user U
			INNER JOIN b_sonet_user2group SU2G ON SU2G.USER_ID = U.ID" .
			$viewJoin . "
			WHERE
				U.ACTIVE = 'Y'
				AND U.LAST_ACTIVITY_DATE IS NOT NULL
				AND U.LAST_ACTIVITY_DATE > " . CSocNetLogCounter::dbWeeksAgo(2) . "
				AND CASE WHEN U.EXTERNAL_AUTH_ID IN ('".implode("','", static::$userTableClass::getExternalUserTypes())."') THEN 'N' ELSE 'Y' END = 'Y'
				" .
				$userWhere . " " .
				$viewWhere . "
		";
	}
	else
	{
		$strSQL = "
			SELECT DISTINCT
				U.ID as ID
				," . ($decrement ? "-1" : "1")." as CNT
				, " .$DB->IsNull("SLS.SITE_ID", "'**'")." as SITE_ID
				," . $params['CODE']." as CODE,
				0 as SENT
				" . ($tagSet ? ", '".$DB->ForSQL($tagSet)."' as TAG" : "") . "
				" . ($setTimestamp ? ', ' . CDatabase::currentTimeFunction() . ' as TIMESTAMP_X' : '') . "
			FROM
				b_user U
			INNER JOIN b_sonet_log_right SLR ON SLR.LOG_ID = ".$logId."
				" . (
					!$forAllAccess && !$useUASubSelect
						? 'INNER JOIN b_user_access UA 
							ON UA.USER_ID = U.ID' .
							(!empty($logRightFilterValue) ? ' AND (UA.ACCESS_CODE = SLR.GROUP_CODE)' : '')
						: ''
				)."
				LEFT JOIN b_sonet_log_site SLS ON SLS.LOG_ID = SLR.LOG_ID
				" . ($followJoin !== '' ? $followJoin : "") . "
				" . $viewJoin . "
				".(!$intranetInstalled ? "LEFT JOIN b_sonet_log_smartfilter SLSF ON SLSF.USER_ID = U.ID " : "")."

			WHERE
				U.ACTIVE = 'Y'
				AND U.LAST_ACTIVITY_DATE IS NOT NULL
				AND U.LAST_ACTIVITY_DATE > " . CSocNetLogCounter::dbWeeksAgo(2) . "
				AND CASE WHEN U.EXTERNAL_AUTH_ID IN ('".implode("','", static::$userTableClass::getExternalUserTypes())."') THEN 'N' ELSE 'Y' END = 'Y'
				" .
				$userWhere."
				".
				$followWhere .
				$viewWhere . "
		";
	}

	return $strSQL;
}