CAdvBanner :: GetRandomArray: Bitrix method

      
<?php 
//  CAdvBanner :: GetRandomArray()
//  /dist/bitrix/modules/advertising/classes/general/advertising.php:3480

    
public static function GetRandomArray($TYPE_SID$quantity 1)
    {
        
$err_mess = (CAdvBanner_all::err_mess())."<br>Function: GetRandom<br>Line: ";
        global 
$APPLICATION$DB$arrViewedBanners$arrADV_VIEWED_BANNERS;

        static 
$arrWeightSum false;

        
$TYPE_SID trim($TYPE_SID);
        if (
strlen($TYPE_SID)<=0)
        {
            return 
false;
        }

        
$DONT_USE_CONTRACT COption::GetOptionString("advertising""DONT_USE_CONTRACT""N");

        if (
$arrWeightSum === false)
        {
            
// получим массив весов для текущей страницы
            
$arrWeightSum = array();

            
$arrCookie_counter = array();
            
// если мы уже получили на странице значение cookie то
            
if (is_array($arrADV_VIEWED_BANNERS))
            {
                while (list(
$banner_id$arr)=each($arrADV_VIEWED_BANNERS))
                {
                    
$arrCookie_counter[$banner_id] = $arr["COUNTER"];
                }
            }
            else 
// если мы первый раз обращаемся к значению хранимому в cookie
            
{
                
$cookie_name "BANNERS";
                
$arr explode(","$APPLICATION->get_cookie($cookie_name));
                if (
is_array($arr) && count($arr)>0)
                {
                    foreach(
$arr as $str)
                    {
                        
$ar explode("_",$str);
                        
$banner_id intval($ar[1]);
                        
$counter intval($ar[2]);
                        
$arrCookie_counter[$banner_id] = $counter;
                    }
                }
            }

            
$arrWeightSum_RequiredKeywords = array();
            
$arrWeightSum_DesiredKeywords = array();
            
$arrWeightSum_EmptyKeywords = array();
            
$arrWeightSum_all = array();
            
$arKeywordsSet = array(); // заданы ли ключевые слова для того или иного типа

            
$arrRequiredKeywordsBanners = array(); // массив баннеров для которых были найдены все ключевые слова
            
$arrDesiredKeywordsBanners = array(); // массив баннеров для которых было найдено хотя бы одно желательное слово
            
$arrEmptyKeywordsBanners = array(); // массив баннеров у которых поле "ключевые слова" не заполнено
            
$arrPAGE_KEYWORDS CAdvBanner::GetKeywords(); // массив ключевых слов заданных для данной страницы

            
$arrDesiredPageKeywords_all is_array($arrPAGE_KEYWORDS[""]["DESIRED"]) ? $arrPAGE_KEYWORDS[""]["DESIRED"] : array();
            
$arrRequiredPageKeywords_all is_array($arrPAGE_KEYWORDS[""]["REQUIRED"]) ? $arrPAGE_KEYWORDS[""]["REQUIRED"] : array();

            
$rs CAdvBanner::GetPageWeights_RS();
            while(
$ar=$rs->Fetch())
            {
                
// Check for blocked uniformed banners
                
if (isset($ar["FLYUNIFORM"]) and $ar["FLYUNIFORM"] == "Y")
                {
                        
$unitest CAdvBanner_all::GetUniformityCoef($ar);
                        if (
$unitest >= 1.0 BANNER_UNIFORMITY_DIVERGENCE_COEF)
                            continue;
                }

                
$arKeywordsSet[$ar["TYPE_SID"]] = "N";

                if ((
intval($ar["SHOWS_FOR_VISITOR"])>&& intval($arrCookie_counter[$ar["BANNER_ID"]])<intval($ar["SHOWS_FOR_VISITOR"])) || intval($ar["SHOWS_FOR_VISITOR"])<=0)
                {
                    
$arr $arrPAGE_KEYWORDS[$ar["TYPE_SID"]]["DESIRED"];
                    
$arrDesiredPageKeywords is_array($arr) ? $arr : array();

                    
$arr $arrPAGE_KEYWORDS[$ar["TYPE_SID"]]["REQUIRED"];
                    
$arrRequiredPageKeywords is_array($arr) ? $arr : array();

                    if (
count($arrRequiredPageKeywords)>||
                        
count($arrRequiredPageKeywords_all)>||
                        
count($arrDesiredPageKeywords)>||
                        
count($arrDesiredPageKeywords_all)>0
                    
)
                    {
                        
$arKeywordsSet[$ar["TYPE_SID"]] = "Y";
                    }

                    
$arrBannerKeywords preg_split('/[\n\r]+/'$ar["BANNER_KEYWORDS"]);
                    if (
is_array($arrBannerKeywords))
                    {
                        
TrimArr($arrBannerKeywords);
                    }

                    if (
$DONT_USE_CONTRACT <> "Y" && $ar["CONTRACT_KEYWORDS"] <> '')
                    {
                        
$arrContractKeywords preg_split('/[\n\r]+/'$ar["CONTRACT_KEYWORDS"]);
                        if (
is_array($arrContractKeywords))
                        {
                            
TrimArr($arrContractKeywords);
                        }
                        
$arrBannerKeywords array_unique(array_merge($arrBannerKeywords$arrContractKeywords));
                    }

                    if (
$DONT_USE_CONTRACT == "Y" || !array_key_exists("CONTRACT_ID"$ar))
                        
$ar["CONTRACT_ID"] = 0;

                    if (
count($arrBannerKeywords)>0)
                    {
                        
$found_required true;
                        if (
count($arrRequiredPageKeywords)>|| count($arrRequiredPageKeywords_all)>0)
                        {
                            
$arr = array("Y","N"); // совпадение | вхождение
                            
foreach($arr as $exact_match)
                            {
                                
$arr1 is_array($arrRequiredPageKeywords[$exact_match]) ? $arrRequiredPageKeywords[$exact_match] : array();
                                
$arr2 is_array($arrRequiredPageKeywords_all[$exact_match]) ? $arrRequiredPageKeywords_all[$exact_match] : array();
                                
$arrRequiredKeywords array_unique(array_merge($arr1$arr2));
                                if (
count($arrRequiredKeywords)>0)
                                {
                                    
reset($arrRequiredKeywords);
                                    foreach(
$arrRequiredKeywords as $page_word)
                                    {
                                        
$page_word strtoupper($page_word);
                                        
reset($arrBannerKeywords);
                                        
$found false;
                                        foreach(
$arrBannerKeywords as $banner_word)
                                        {
                                            
$banner_word strtoupper($banner_word);
                                            
// совпадение
                                            
if ($exact_match=="Y")
                                            {
                                                if (
$banner_word==$page_word)
                                                {
                                                    
$found true;
                                                    break;
                                                }
                                            }
                                            elseif (
$exact_match=="N")
                                            {
                                                if (
strpos($page_word$banner_word)!==false || strpos($banner_word$page_word)!==false)
                                                {
                                                    
$found true;
                                                    break;
                                                }
                                            }
                                        }
                                        if (!
$found)
                                        {
                                            
$found_required false;
                                            break 
2;
                                        }
                                    }
                                }
                            }
                            
// если все ключевые слова были найдены то
                            
if ($found_required)
                            {
                                
// запоминаем баннер в массиве баннеров для которых были найдены все ключевые слова
                                
$arrRequiredKeywordsBanners[] = $ar["BANNER_ID"];
                            }
                        }

                        
// если по обязательным словам баннер подходит то проверим по желательным словам
                        
if ($found_required && (count($arrDesiredPageKeywords)>|| count($arrDesiredPageKeywords_all)>0))
                        {
                            
$found_desired false;
                            
$arr = array("Y","N"); // совпадение | вхождение
                            
foreach($arr as $exact_match)
                            {
                                
$arr1 is_array($arrDesiredPageKeywords) ? $arrDesiredPageKeywords[$exact_match] : array();
                                
$arr2 is_array($arrDesiredPageKeywords_all) ? $arrDesiredPageKeywords_all[$exact_match] : array();
                                if (!
is_array($arr1)) $arr1 = array();
                                if (!
is_array($arr2)) $arr2 = array();
                                
$arrDesiredKeywords array_unique(array_merge($arr1$arr2));
                                if (
is_array($arrDesiredKeywords) && count($arrDesiredKeywords)>0)
                                {
                                    
reset($arrDesiredKeywords);
                                    foreach(
$arrDesiredKeywords as $page_word)
                                    {
                                        
$page_word strtoupper($page_word);
                                        
reset($arrBannerKeywords);
                                        foreach(
$arrBannerKeywords as $banner_word)
                                        {
                                            
$banner_word strtoupper($banner_word);
                                            
// совпадение
                                            
if ($exact_match=="Y")
                                            {
                                                if (
$banner_word==$page_word)
                                                {
                                                    
$found_desired true;
                                                    break 
3;
                                                }
                                            }
                                            elseif (
$exact_match=="N")
                                            {
                                                if (
strpos($page_word$banner_word)!==false || strpos($banner_word$page_word)!==false)
                                                {
                                                    
$found_desired true;
                                                    break 
3;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            
// если все ключевые слова были найдены то
                            
if ($found_desired)
                            {
                                
// запоминаем баннер в массиве баннеров для которых были найдены все ключевые слова
                                
$arrDesiredKeywordsBanners[] = $ar["BANNER_ID"];
                            }
                        }
                    }
                    else
                    {
                        
// запомнить баннеры у которых вообще не задано ключевых слов
                        
$arrEmptyKeywordsBanners[] = $ar["BANNER_ID"];
                    }

                    if (
in_array($ar["BANNER_ID"], $arrRequiredKeywordsBanners))
                    {
                        
$arrWeightSum_RequiredKeywords[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["WEIGHT"] = intval($ar["CONTRACT_WEIGHT"]);
                        
$arrWeightSum_RequiredKeywords[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["BANNERS"][$ar["BANNER_ID"]] = intval($ar["BANNER_WEIGHT"]);
                    }
                    if (
in_array($ar["BANNER_ID"], $arrDesiredKeywordsBanners))
                    {
                        
$arrWeightSum_DesiredKeywords[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["WEIGHT"] = intval($ar["CONTRACT_WEIGHT"]);
                        
$arrWeightSum_DesiredKeywords[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["BANNERS"][$ar["BANNER_ID"]] = intval($ar["BANNER_WEIGHT"]);
                    }
                    if (
in_array($ar["BANNER_ID"], $arrEmptyKeywordsBanners))
                    {
                        
$arrWeightSum_EmptyKeywords[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["WEIGHT"] = intval($ar["CONTRACT_WEIGHT"]);
                        
$arrWeightSum_EmptyKeywords[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["BANNERS"][$ar["BANNER_ID"]] = intval($ar["BANNER_WEIGHT"]);
                    }
                    
$arrWeightSum_all[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["WEIGHT"] = intval($ar["CONTRACT_WEIGHT"]);
                    
$arrWeightSum_all[$ar["TYPE_SID"]][$ar["CONTRACT_ID"]]["BANNERS"][$ar["BANNER_ID"]] = intval($ar["BANNER_WEIGHT"]);
                }
            }

            
$arrAllTypies array_keys($arrWeightSum_all);
            if (
count($arrAllTypies)>0)
            {
                foreach(
$arrAllTypies as $tsid)
                {
                    
// если для данного типа ключевые слова заданы то
                    
if ($arKeywordsSet[$tsid]=="Y")
                    {
                        
// желательные слова
                        
if (is_array($arrWeightSum_DesiredKeywords[$tsid]) && count($arrWeightSum_DesiredKeywords[$tsid])>0)
                        {
                            
$arrWeightSum[$tsid] = $arrWeightSum_DesiredKeywords[$tsid];
                        }
                        
// обязательные слова
                        
elseif (is_array($arrWeightSum_RequiredKeywords[$tsid]) && count($arrWeightSum_RequiredKeywords[$tsid])>0)
                        {
                            
$arrWeightSum[$tsid] = $arrWeightSum_RequiredKeywords[$tsid];
                        }
                        
// с пустыми словами
                        
elseif ($arKeywordsSet[$tsid]=="Y" && is_array($arrWeightSum_EmptyKeywords[$tsid]))
                        {
                            
$arrWeightSum[$tsid] = $arrWeightSum_EmptyKeywords[$tsid];
                        }
                    }
                    else
                    {
                        
$arrWeightSum[$tsid] = $arrWeightSum_all[$tsid];
                    }
                }
            }
        }

        
$arrWSum $arrWeightSum[$TYPE_SID];

        
// если массив весов подготовлен то
        
if (is_array($arrWSum) && count($arrWSum)>0)
        {
            
$CONTRACT_ID 0;

            if (
$DONT_USE_CONTRACT == "N" || !array_key_exists("0"$arrWSum))
            {
                
// получим сумму весов контрактов
                
$intSum 0;
                
reset($arrWSum);

                while (list(
$cid$arr) = each($arrWSum))
                {
                    
$CONTRACT_ID $cid;
                    
$intSum += intval($arr["WEIGHT"]);
                }

                
// выберем контракт по весу
                
$intStep 0;
                
$rndWeight $intSum * (mt_rand()/mt_getrandmax());
                
reset($arrWSum);
                while (list(
$cid$arr) = each($arrWSum))
                {
                    if(
$rndWeight>=$intStep && $rndWeight<=$intStep+$arr["WEIGHT"])
                    {
                        
$CONTRACT_ID $cid;
                        break;
                    }
                    
$intStep += $arr["WEIGHT"];
                }
                
$CONTRACT_ID intval($CONTRACT_ID)<=intval($CONTRACT_ID);
            }

            
$arrWeightBanners $arrWSum[$CONTRACT_ID]["BANNERS"];

            
// если ID контракта определен то
            
if (is_array($arrWeightBanners) && count($arrWeightBanners)>0)
            {
                
// получим сумму весов баннеров контракта
                
$intSum 0;
                
$strBanners "0";
                
reset($arrWeightBanners);
                while (list(
$bid$weight) = each($arrWeightBanners))
                {
                    if(
in_array($bid$arrViewedBanners))
                        continue;
                    
$intSum += intval($weight);
                    
$strBanners .= ",".intval($bid);
                }

                if (
$CONTRACT_ID>0)
                {
                    
$strSql "
                        SELECT
                            B.*,
                            "
.$DB->DateToCharFunction("B.DATE_SHOW_FIRST""FULL")." DATE_SHOW_FIRST,
                            "
.$DB->DateToCharFunction("B.DATE_SHOW_FROM""FULL")." DATE_SHOW_FROM,
                            "
.$DB->DateToCharFunction("B.DATE_SHOW_TO""FULL")." DATE_SHOW_TO,
                            C.MAX_VISITOR_COUNT        CONTRACT_MAX_VISITOR_COUNT
                        FROM
                            b_adv_banner B,
                            b_adv_contract C
                        WHERE
                            B.CONTRACT_ID = 
$CONTRACT_ID
                        and    B.TYPE_SID = '"
.$DB->ForSql($TYPE_SID,255)."'
                        and B.ID in ("
.$strBanners.")
                        and C.ID = B.CONTRACT_ID
                        ORDER BY
                            FLYUNIFORM DESC
                        "
;
                }
                else
                {
                    
$strSql "
                        SELECT
                            B.*,
                            "
.$DB->DateToCharFunction("B.DATE_SHOW_FIRST""FULL")." DATE_SHOW_FIRST,
                            "
.$DB->DateToCharFunction("B.DATE_SHOW_FROM""FULL")." DATE_SHOW_FROM,
                            "
.$DB->DateToCharFunction("B.DATE_SHOW_TO""FULL")." DATE_SHOW_TO
                        FROM
                            b_adv_banner B
                        WHERE
                        B.TYPE_SID = '"
.$DB->ForSql($TYPE_SID,255)."'
                        AND B.ID in ("
.$strBanners.")
                        ORDER BY
                            FLYUNIFORM DESC
                        "
;

                }

                
$intSum 0;
                
$inf = array();
                
$stubs = array();

                
$rsBanners $DB->Query($strSqlfalse$err_mess.__LINE__);
                while(
$arBanner $rsBanners->Fetch())
                {
                    if (isset(
$arBanner["FLYUNIFORM"]) and $arBanner["FLYUNIFORM"] == "Y")
                    {
                        
$unitest CAdvBanner_all::GetUniformityCoef($arBanner);
                        if (
$unitest 1.0 BANNER_UNIFORMITY_DIVERGENCE_COEF)
                            
$inf[$arBanner['ID']] = $arBanner;
                    }
                    else
                    {
                        
$intSum += intval($arBanner["WEIGHT"]);
                        
$stubs[$arBanner['ID']] = $arBanner// Save stubs
                    
}
                }

                
// Sort array from most last (weak) rotated banner (x<<1) to strongest
                
uasort($inf, array('CAdvBanner_all''arr_comp_uniform'));

                
// Sorting stubs array
                
$infStubs = array();
                while (
count($stubs))
                {
                    
$intStep 0;
                    
$rndWeight $intSum * (mt_rand()/mt_getrandmax());

                    
reset($stubs);
                    
$infCurr current($stubs);
                    if(
$rndWeight $intStep or $rndWeight $intStep $infCurr["WEIGHT"])
                    {
                        
$intStep += $infCurr["WEIGHT"];
                        while (
next($stubs))
                        {
                            
$infCurr current($stubs);
                            if(
$rndWeight>=$intStep && $rndWeight<=$intStep+$infCurr["WEIGHT"])
                                break;
                            
$intStep += $infCurr["WEIGHT"];
                        }
                    }
                    
$infStubs[$infCurr['ID']] = $infCurr;
                    unset(
$stubs[$infCurr['ID']]);
                }

                
$arBanners array_slice(array_merge($inf$infStubs), 0intval($quantity));

                foreach (
$arBanners as $arB)
                {
                    
$BANNER_ID intval($arB["ID"]);
                    if (
$BANNER_ID 0)
                    {
                        unset(
$arrWeightSum[$TYPE_SID][$CONTRACT_ID]["BANNERS"][$arB["ID"]]);
                        if(
count($arrWeightSum[$TYPE_SID][$CONTRACT_ID]["BANNERS"]) <= 0)
                            unset(
$arrWeightSum[$TYPE_SID][$CONTRACT_ID]);
                        
$arrViewedBanners[] = $arB["ID"];
                    }
                }
                return 
$arBanners;
            }
        }
        return 
null;
    }