static function IncrementWithSelect($sub_select, $sendPull = true, $arParams = array())
{
global $CACHE_MANAGER;
$connection = BitrixMainApplication::getConnection();
$helper = $connection->getSqlHelper();
if ($sub_select <> '')
{
$pullInclude = (
$sendPull
&& self::CheckLiveMode()
);
if (
is_array($arParams)
&& isset($arParams["TAG_SET"])
)
{
$insertFields = ['USER_ID', 'CNT', 'SITE_ID', 'CODE', 'SENT', 'TAG'];
if (is_array($arParams) && isset($arParams["SET_TIMESTAMP"]))
{
$insertFields[] = 'TIMESTAMP_X';
}
$strSQL = $helper->prepareMergeSelect(
'b_user_counter',
['USER_ID', 'SITE_ID', 'CODE'],
$insertFields,
'(' . $sub_select . ')',
[
'CNT' => new BitrixMainDBSqlExpression('b_user_counter.CNT + ?v', 'CNT'),
'SENT' => new BitrixMainDBSqlExpression('?v', 'SENT'),
'TAG' => $arParams["TAG_SET"],
]
);
}
elseif (
is_array($arParams)
&& isset($arParams["TAG_CHECK"])
)
{
$insertFields = ['USER_ID', 'CNT', 'SITE_ID', 'CODE', 'SENT'];
if (is_array($arParams) && isset($arParams["SET_TIMESTAMP"]))
{
$insertFields[] = 'TIMESTAMP_X';
}
$strSQL = $helper->prepareMergeSelect(
'b_user_counter',
['USER_ID', 'SITE_ID', 'CODE'],
$insertFields,
'(' . $sub_select . ')',
[
'CNT' => new BitrixMainDBSqlExpression("CASE WHEN b_user_counter.TAG = '" . $helper->forSQL($arParams["TAG_CHECK"]) . "' THEN b_user_counter.CNT ELSE b_user_counter.CNT + ?v END", 'CNT'),
'SENT' => new BitrixMainDBSqlExpression("CASE WHEN b_user_counter.TAG = '" . $helper->forSQL($arParams["TAG_CHECK"]) . "' THEN b_user_counter.SENT ELSE ?v END", 'SENT'),
]
);
}
else
{
$insertFields = ['USER_ID', 'CNT', 'SITE_ID', 'CODE', 'SENT'];
if (is_array($arParams) && isset($arParams["SET_TIMESTAMP"]))
{
$insertFields[] = 'TIMESTAMP_X';
}
$strSQL = $helper->prepareMergeSelect(
'b_user_counter',
['USER_ID', 'SITE_ID', 'CODE'],
$insertFields,
'(' . $sub_select . ')',
[
'CNT' => new BitrixMainDBSqlExpression("b_user_counter.CNT + ?v", 'CNT'),
'SENT' => new BitrixMainDBSqlExpression("?v", 'SENT'),
]
);
}
$connection->query($strSQL);
if (
!is_array($arParams)
|| (
!isset($arParams["TAG_SET"])
&& (
!isset($arParams["CLEAN_CACHE"])
|| $arParams["CLEAN_CACHE"] != "N"
)
)
)
{
self::$counters = [];
$CACHE_MANAGER->CleanDir("user_counter");
}
if ($pullInclude)
{
$arSites = Array();
$by = '';
$order = '';
$res = CSite::GetList($by, $order, Array("ACTIVE" => "Y"));
while($row = $res->Fetch())
{
$arSites[] = $row['ID'];
}
if (
!empty($arParams["USERS_TO_PUSH"])
&& is_array($arParams["USERS_TO_PUSH"])
)
{
if($connection->lock('pull'))
{
$helper = $connection->getSqlHelper();
$strSQL = "
SELECT uc.USER_ID as CHANNEL_ID, uc.USER_ID, uc.SITE_ID, uc.CODE, uc.CNT
FROM b_user_counter uc
INNER JOIN b_user u ON u.ID = uc.USER_ID AND (CASE WHEN u.EXTERNAL_AUTH_ID IN ('" . implode("', '", BitrixMainUserTable::getExternalUserTypes())."') THEN 'Y' ELSE 'N' END) = 'N' AND u.LAST_ACTIVITY_DATE > " . $helper->addSecondsToDateTime('(-3600)')."
WHERE uc.SENT = '0' AND uc.USER_ID IN (" . implode(", ", $arParams["USERS_TO_PUSH"]) . ")
";
$res = $connection->Query($strSQL, false, "FILE: ".__FILE__."
LINE: ".__LINE__);
$pullMessage = Array();
while($row = $res->fetch())
{
self::addValueToPullMessage($row, $arSites, $pullMessage);
}
$connection->Query("UPDATE b_user_counter SET SENT = '1' WHERE SENT = '0' AND CODE NOT LIKE '". self::LIVEFEED_CODE . "L%'");
$connection->unlock('pull');
if (self::CheckLiveMode())
{
foreach ($pullMessage as $channelId => $arMessage)
{
BitrixPullEvent::add($channelId, Array(
'module_id' => 'main',
'command' => 'user_counter',
'expiry' => 3600,
'params' => $arMessage,
));
}
}
}
}
else
{
CUserCounterPage::setNewEvent();
}
}
}
}