Делать запросы со стороннего сайта о наличии товара и внесение этих данных в соответствующий элемент каталога.
Идентификатором (полем соответствия) служит артикул.
Первый скрипт для выполения через браузер заставил решить задачу таймаута, вышло примерно следующее:[spoiler]
set_time_limit(0); $urlBegin = "http://www.ххх.хх/?partId="; $getReqEnd = "¶m..."; $count = ($_REQUEST['count']) ? $_REQUEST['count']: 0; ?> <html> <head> </head> <body> <? echo ' Start - '.$count.'<br>'; $flag=true; $elemHave = "Ключевое слово"; // create array ID + Articles and load in SESSION if ($count==0) { CModule::IncludeModule('iblock'); $arSelect = Array("ID", "IBLOCK_ID", "PROPERTY_CML2_ARTICLE"; $res = CIBlockElement::GetList(array(), array("IBLOCK_ID" => ХХ, "SECTION_ID"=> ХХХ), false, false, $arSelect); while ($ob = $res->GetNextElement()){ $arrFields = $ob->GetFields(); $arIdArticles[] = array('ID'=>$arrFields['ID'],'ARTICLE'=>$arrFields['PROPERTY_CML2_ARTICLE_VALUE'] } } else{ $arIdArticles = $_SESSION['arIdArticles']; } $_SESSION['arIdArticles'] = $arIdArticles; $elemCount = count($arIdArticles); Cmodule::IncludeModule('catalog'); while ($count<=$elemCount){ $getReq = strval($arIdArticles[$count]['ARTICLE'] $url = $urlBegin.$getReq.$getReqEnd; $result = iconv('CP1251', 'UTF-8', file_get_contents($url)); $findRes = strstr($result, $elemHave); $quant = ($findRes)? 1: 0; CCatalogProduct::Update($arIdArticles[$count]['ID'], array('QUANTITY'=>$quant)); $arFieldStore = Array( "PRODUCT_ID" => $arIdArticles[$count]['ID'], "STORE_ID" => Х, "AMOUNT" => $quant ); CCatalogStoreProduct::UpdateFromForm($arFieldStore); unset ($result); if ((getmicrotime() - START_EXEC_TIME) > 90){ $flag=false; file_put_contents("data.txt", 'Обработано - '.$count.' из '.$elemCount.' time start session - '.START_EXEC_TIME); echo 'Обработано - '.$count.' из '.$elemCount.' time start session - '.START_EXEC_TIME; break; } // file_put_contents("data.txt", 'Обработано - '.$count); $count++; } ?> </body> </html> <? if (!$flag){ //LocalRedirect('/test/index.php?count='.$count); ?> <script type="text/javascript"> setTimeout(function(){window.location='/test/index.php?count=<?=$count?>'},1500); </script> <? } else die(); |
убедившись, что цель достигнута, занялся переносом кода в init.php
в КМБ Битрикса сказано, что нельзя использовать в агентах $_SESSION т..е. логика перевызова скрипта, через определенное время не сработает.
Оказалось, что агент выполняющийся на кроне вовсе не обязан перезагружаться для корректной работы. Однако вылезли другие ограничения, которые заставили поплясать с бубном и понять, что же в конечнои итоге нужно сделать. Ограничения следующие: агент битрикса очень хочет выполниться в течении какого-то времени (интервал не определил), если он не завершил свое функционирование, то запускается его копия и тоже пытается выполнится, в результате чего можно получить 7-10 копий функции, которые делают одно и тоже, причем раннии копии теряются где-то в недрах сервера и есть подозрение, что не очищают память, конечно если вы об этом не позаботились. Таким образом агент мог выполнить максимум 28 000 циклов, после чего "терялся". Ну собственно КМБ Битрикса и об этом предупреждает: "не рекомендуется вешать на агенты ресурсоёмкие операции, для них существует фоновый запуск по cron'у." Поскольку доступа к крону у меня не было, принял решение "победить" агента. Итог:
function GetCSPresence(){ if (!file_exists($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt")){ $ptime = time()+432000; $headers= "MIME-Version: 1.0\r\n"; $headers .= "Content-type: text/html; charset=UTF-8\r\n"; $headers .= "From: SYSTEM"; mail("info@site.ru", "Агент проверки стартовал", "Произведен запуск агента проверки наличия адрес - http://www.xxx.xx/", $headers); set_time_limit(0); $random_chars = array("0123456789"); $randomNum = randString(8, $random_chars); file_put_contents($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt", 'Сессия - '.$randomNum); $urlBegin = "http://www.xxx.xx?partId="; $getReqEnd = "¶m..."; $count = 0; $elemHave = "Ключевое слово"; |
CModule::IncludeModule('iblock'); $arSelect = Array("ID", "IBLOCK_ID", "PROPERTY_CML2_ARTICLE"); $res = CIBlockElement::GetList(array(), array("IBLOCK_ID" => X, "SECTION_ID"=> XX), false, false, $arSelect); while ($ob = $res->GetNextElement()){ $arrFields = $ob->GetFields(); $arIdArticles[] = array('ID'=>$arrFields['ID'],'ARTICLE'=>$arrFields['PROPERTY_CML2_ARTICLE_VALUE']); } $elemCount = count($arIdArticles); $inAvailable = 0; Cmodule::IncludeModule('catalog'); foreach ($arIdArticles as $arVal){ // while ($count<=$elemCount){ $getReq = strval($arVal['ARTICLE']); $url = $urlBegin.$getReq.$getReqEnd; $result = iconv('CP1251', 'UTF-8', file_get_contents($url)); $findRes = strstr($result, $elemHave); $quant = ($findRes)? 1: 0; if($quant==1)$inAvailable++; CCatalogProduct::Update($arVal['ID'], array('QUANTITY'=>$quant)); $arFieldStore = Array( "PRODUCT_ID" => $arVal['ID'], "STORE_ID" => 6, "AMOUNT" => $quant ); CCatalogStoreProduct::UpdateFromForm($arFieldStore); unset ($result); if ($count%1000==0){ file_put_contents($_SERVER['DOCUMENT_ROOT']."/logcs.txt", 'Сессия - '.$randomNum.' Обработано - '.$count.' в наличии - '.$inAvailable.PHP_EOL, FILE_APPEND); if (!file_exists($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt")) break; } $count++; // if ($randomNum) break; } file_put_contents($_SERVER['DOCUMENT_ROOT']."/logcs.txt", 'Сессия - '.$randomNum.' Обработано - '.$count.' из '.$elemCount.PHP_EOL, FILE_APPEND); unlink($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt"); mail("info@site.ru", "Агент проверки ЦС закончил", "Агент проверки наличия на ЦС адрес - http://www.xxx.xx/ закончил работу. Результат: обработано - ".$count.' из - '.$elemCount.' в наличии - '.$inAvailable.' следующй запуск - '.ConvertTimeStamp($ptime, "FULL"), $headers); |
unset ($arIdArticles); // return "GetCSPresence();"; } if ($ptime) CAgent::AddAgent( "GetCSPresence();", "", // идентификатор модуля "N", // агент критичен к кол-ву запусков 0, // интервал запуска "", // когда проверить первый запуск? (сейчас) "Y", // агент активен ConvertTimeStamp($ptime, "FULL") // начиная с какой даты проверять? ); } |