static function BuildRating($ID)
{
global $DB;
$connection = BitrixMainApplication::getConnection();
$helper = $connection->getSqlHelper();
$ID = intval($ID);
$err_mess = (CRatings::err_mess())."
Function: BuildRating
Line: ";
$resRating = CRatings::GetByID($ID);
$arRating = $resRating->Fetch();
if ($arRating && $arRating['ACTIVE'] == 'Y')
{
$DB->Query("UPDATE b_rating SET CALCULATED = 'C' WHERE id = ".$ID, false, $err_mess.__LINE__);
// Insert new results
$sqlFunc = ($arRating['CALCULATION_METHOD'] == 'SUM') ? 'SUM' : 'AVG';
$strSql = "
INSERT INTO b_rating_results
(RATING_ID, ENTITY_TYPE_ID, ENTITY_ID, CURRENT_VALUE, PREVIOUS_VALUE)
SELECT
".$ID." RATING_ID,
'".$arRating['ENTITY_ID']."' ENTITY_TYPE_ID,
RC.ENTITY_ID,
".$sqlFunc."(RC.CURRENT_VALUE) CURRENT_VALUE,
0 PREVIOUS_VALUE
FROM
b_rating_component_results RC LEFT JOIN b_rating_results RR ON RR.RATING_ID = RC.RATING_ID and RR.ENTITY_ID = RC.ENTITY_ID
WHERE
RC.RATING_ID = ".$ID." and RR.ID IS NULL
GROUP BY RC.ENTITY_ID";
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
// Update current results
$strSql = $helper->prepareCorrelatedUpdate("b_rating_results", "RR", [
'PREVIOUS_VALUE' => 'case when RR.CURRENT_VALUE = RCR.CURRENT_VALUE then RR.PREVIOUS_VALUE else RR.CURRENT_VALUE end',
'CURRENT_VALUE' => 'RCR.CURRENT_VALUE',
], "
(SELECT '".$arRating['ENTITY_ID']."' ENTITY_TYPE_ID, RC.ENTITY_ID, ".$sqlFunc."(RC.CURRENT_VALUE) CURRENT_VALUE
FROM b_rating_component_results RC INNER JOIN b_rating_results RR on RR.RATING_ID = RC.RATING_ID and RR.ENTITY_ID = RC.ENTITY_ID
WHERE RC.RATING_ID = ".$ID."
GROUP BY RC.ENTITY_ID
) as RCR
", "
RR.RATING_ID=".$ID."
and RR.ENTITY_TYPE_ID = RCR.ENTITY_TYPE_ID
and RR.ENTITY_ID = RCR.ENTITY_ID
"
);
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
// Calculation position in rating
if ($arRating['POSITION'] == 'Y')
{
$strSql = $helper->initRowNumber('nPos');
if ($strSql)
{
$DB->Query($strSql);
}
$strSql = $helper->prepareCorrelatedUpdate("b_rating_results", "RR", [
'PREVIOUS_POSITION' => 'case when RR.CURRENT_POSITION = RP.POSITION then RR.PREVIOUS_POSITION else RR.CURRENT_POSITION end',
'CURRENT_POSITION' => 'RP.POSITION',
], "
(SELECT ENTITY_TYPE_ID, ENTITY_ID, CURRENT_VALUE, " . $helper->getRowNumber('nPos') . " as POSITION
FROM b_rating_results
WHERE RATING_ID = ".$ID."
ORDER BY CURRENT_VALUE DESC
) as RP
", "
RR.RATING_ID=".$ID."
and RR.ENTITY_TYPE_ID = RP.ENTITY_TYPE_ID
and RR.ENTITY_ID = RP.ENTITY_ID
"
);
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
}
// Insert new user rating prop
$strSql = "
INSERT INTO b_rating_user
(RATING_ID, ENTITY_ID)
SELECT
".$ID." RATING_ID,
U.ID as ENTITY_ID
FROM
b_user U
LEFT JOIN b_rating_user RU ON RU.RATING_ID = ".$ID." and RU.ENTITY_ID = U.ID
WHERE
U.ACTIVE = 'Y'
AND (CASE WHEN U.EXTERNAL_AUTH_ID IN ('".join("', '", BitrixMainUserTable::getExternalUserTypes())."') THEN 'Y' ELSE 'N' END) = 'N'
AND RU.ID IS NULL ";
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
// authority calc
if ($arRating['AUTHORITY'] == 'Y')
{
$sRatingAssignType = COption::GetOptionString("main", "rating_assign_type", "manual");
if ($sRatingAssignType == 'auto')
{
// auto assign for rating group
$assignRatingGroup = COption::GetOptionString("main", "rating_assign_rating_group", 0);
$assignRatingValueAdd = COption::GetOptionString("main", "rating_assign_rating_group_add", 1);
$assignRatingValueDelete = COption::GetOptionString("main", "rating_assign_rating_group_delete", 1);
CRatings::AutoAssignGroup($assignRatingGroup, $assignRatingValueAdd, $assignRatingValueDelete);
// auto assign for authority group
$assignAuthorityGroup = COption::GetOptionString("main", "rating_assign_authority_group", 0);
$assignAuthorityValueAdd = COption::GetOptionString("main", "rating_assign_authority_group_add", 2);
$assignAuthorityValueDelete = COption::GetOptionString("main", "rating_assign_authority_group_delete", 2);
CRatings::AutoAssignGroup($assignAuthorityGroup, $assignAuthorityValueAdd, $assignAuthorityValueDelete);
}
$sRatingWeightType = COption::GetOptionString("main", "rating_weight_type", "auto");
if ($sRatingWeightType == 'auto')
{
$arCI = CRatings::GetCommunityInfo($ID);
$communitySize = $arCI['COMMUNITY_SIZE'];
$communityAuthority = $arCI['COMMUNITY_AUTHORITY'];
$sRatingNormalizationType = COption::GetOptionString("main", "rating_normalization_type", "auto");
if ($sRatingNormalizationType == 'manual')
{
$ratingNormalization = COption::GetOptionString("main", "rating_normalization", 1000);
}
else
{
if ($communitySize <= 10)
{
$ratingNormalization = 10;
}
elseif ($communitySize <= 1000)
{
$ratingNormalization = 100;
}
else
{
$ratingNormalization = 1000;
}
COption::SetOptionString("main", "rating_normalization", $ratingNormalization);
}
$voteWeight = 1;
if ($communitySize > 0)
$voteWeight = $ratingNormalization/$communitySize;
COption::SetOptionString("main", "rating_community_size", $communitySize);
COption::SetOptionString("main", "rating_community_authority", $communityAuthority);
COption::SetOptionString("main", "rating_vote_weight", $voteWeight);
$ratingCountVote = COption::GetOptionString("main", "rating_count_vote", 10);
$strSql = "UPDATE b_rating_user SET VOTE_COUNT = 0, VOTE_WEIGHT =0 WHERE RATING_ID=".$ID;
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
// default vote count + user authority
$strSql = $helper->prepareCorrelatedUpdate("b_rating_user", "RU", [
'VOTE_COUNT' => intval($ratingCountVote)." + RP.CURRENT_VALUE",
'VOTE_WEIGHT' => "RP.CURRENT_VALUE * " . $voteWeight,
], "
(SELECT ENTITY_ID, CURRENT_VALUE
FROM b_rating_results
WHERE RATING_ID = ".$ID."
) as RP
", "
RU.RATING_ID=".$ID."
and RU.ENTITY_ID = RP.ENTITY_ID
"
);
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
}
else
{
// Depending on current authority set correct weight votes
// Depending on current authority set correct vote count
$strSql = "UPDATE b_rating_user SET VOTE_COUNT = 0, VOTE_WEIGHT =0 WHERE RATING_ID=".$ID;
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
$strSql = $helper->prepareCorrelatedUpdate("b_rating_user", "RU", [
'VOTE_COUNT' => 'RP.COUNT',
'VOTE_WEIGHT' => 'RP.WEIGHT',
], "
(SELECT
RW.RATING_FROM, RW.RATING_TO, RW.WEIGHT, RW.COUNT, RR.ENTITY_ID
FROM
b_rating_weight RW,
b_rating_results RR
WHERE
RR.RATING_ID = ".$ID."
and RR.CURRENT_VALUE BETWEEN RW.RATING_FROM AND RW.RATING_TO
) as RP
", "
RU.RATING_ID=".$ID."
and RU.ENTITY_ID = RP.ENTITY_ID
"
);
$res = $DB->Query($strSql, false, $err_mess.__LINE__);
}
}
global $CACHE_MANAGER;
$CACHE_MANAGER->CleanDir("b_rating_user");
$DB->Query("UPDATE b_rating SET CALCULATED = 'Y', LAST_CALCULATED = ".$DB->GetNowFunction()." WHERE id = ".$ID, false, $err_mess.__LINE__);
}
return true;
}