Ejemplo n.º 1
0
 function GetRandom($TYPE_SID)
 {
     $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_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"]) > 0 && 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) > 0 || count($arrRequiredPageKeywords_all) > 0 || count($arrDesiredPageKeywords) > 0 || 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) > 0 || 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) > 0 || 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) <= 0 ? 1 : 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 = "\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tB.*,\n\t\t\t\t\t\t\t" . $DB->DateToCharFunction("B.DATE_SHOW_FIRST", "FULL") . " DATE_SHOW_FIRST,\n\t\t\t\t\t\t\t" . $DB->DateToCharFunction("B.DATE_SHOW_FROM", "FULL") . " DATE_SHOW_FROM,\n\t\t\t\t\t\t\t" . $DB->DateToCharFunction("B.DATE_SHOW_TO", "FULL") . " DATE_SHOW_TO,\n\t\t\t\t\t\t\tC.MAX_VISITOR_COUNT\t\tCONTRACT_MAX_VISITOR_COUNT\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tb_adv_banner B,\n\t\t\t\t\t\t\tb_adv_contract C\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tB.CONTRACT_ID = {$CONTRACT_ID}\n\t\t\t\t\t\tand\tB.TYPE_SID = '" . $DB->ForSql($TYPE_SID, 255) . "'\n\t\t\t\t\t\tand B.ID in (" . $strBanners . ")\n\t\t\t\t\t\tand C.ID = B.CONTRACT_ID\n\t\t\t\t\t\tORDER BY\n\t\t\t\t\t\t\tFLYUNIFORM DESC\n\t\t\t\t\t\t";
             } else {
                 $strSql = "\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tB.*,\n\t\t\t\t\t\t\t" . $DB->DateToCharFunction("B.DATE_SHOW_FIRST", "FULL") . " DATE_SHOW_FIRST,\n\t\t\t\t\t\t\t" . $DB->DateToCharFunction("B.DATE_SHOW_FROM", "FULL") . " DATE_SHOW_FROM,\n\t\t\t\t\t\t\t" . $DB->DateToCharFunction("B.DATE_SHOW_TO", "FULL") . " DATE_SHOW_TO\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tb_adv_banner B\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\tB.TYPE_SID = '" . $DB->ForSql($TYPE_SID, 255) . "'\n\t\t\t\t\t\tAND B.ID in (" . $strBanners . ")\n\t\t\t\t\t\tORDER BY\n\t\t\t\t\t\t\tFLYUNIFORM DESC\n\t\t\t\t\t\t";
             }
             $intSum = 0;
             $infVal = 0;
             $infUniform = null;
             $stubs = array();
             $rsBanners = $DB->Query($strSql, false, $err_mess . __LINE__);
             while ($arBanner = $rsBanners->Fetch()) {
                 if (isset($arBanner["FLYUNIFORM"]) and $arBanner["FLYUNIFORM"] == "Y") {
                     // Select most last (weak) rotated banner (x<<1)
                     $unitest = CAdvBanner_all::GetUniformityCoef($arBanner);
                     if ($unitest < $infVal or !$infUniform) {
                         $infVal = $unitest;
                         $infUniform = $arBanner;
                     }
                 } else {
                     $intSum += intval($arBanner["WEIGHT"]);
                     array_push($stubs, $arBanner);
                     // Save stubs
                 }
             }
             // Check out selected uniformed banner
             if ($infUniform == null or $infVal >= 1.0 + BANNER_UNIFORMITY_DIVERGENCE_COEF) {
                 // If this, we have to stop alittle this banner, and show stub one.
                 $infUniform = array();
                 if (count($stubs) > 0) {
                     $intStep = 0;
                     $rndWeight = $intSum * (mt_rand() / mt_getrandmax());
                     reset($stubs);
                     $infUniform = current($stubs);
                     if ($rndWeight < $intStep or $rndWeight > $intStep + $infUniform["WEIGHT"]) {
                         $intStep += $infUniform["WEIGHT"];
                         while ($infUniform = next($stubs)) {
                             if ($rndWeight >= $intStep && $rndWeight <= $intStep + $infUniform["WEIGHT"]) {
                                 break;
                             }
                             $intStep += $infUniform["WEIGHT"];
                         }
                     }
                 }
             }
             $arBanner = $infUniform;
             $BANNER_ID = intval($arBanner["ID"]);
             if ($BANNER_ID > 0) {
                 unset($arrWeightSum[$TYPE_SID][$CONTRACT_ID]["BANNERS"][$arBanner["ID"]]);
                 if (count($arrWeightSum[$TYPE_SID][$CONTRACT_ID]["BANNERS"]) <= 0) {
                     unset($arrWeightSum[$TYPE_SID][$CONTRACT_ID]);
                 }
                 $arrViewedBanners[] = $arBanner["ID"];
             }
             return $arBanner;
         }
     }
     return null;
 }