Voldemord

Untitled

Mar 21st, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. class CMigration
  3. {
  4.     private static $_instance;
  5.     private static $dir = "/upload/catalog/";
  6.     private static $paramFile = "param.php";
  7.     private static $catFile = "catalog.php";
  8.     private static $lockFile = "process.lock";
  9.     private static $debugMode = 1;
  10.     //5aaecf6f-0199-11e6-831c-74d43599898f
  11.     public static $xmlRegex = "#[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-#i";
  12.     public static $translit = Array("replace_space" => '-',"replace_other" => '-');
  13.     public static $priceID = 5;
  14.     public static $params = Array();
  15.  
  16.     public static $propsExeption = Array(
  17.         "CML2_BAR_CODE",
  18.         "TIP_TSENY_KOLLEROVKI",
  19.         "CML2_ARTICLE",
  20.         "CML2_LINK",
  21.         "CML2_ATTRIBUTES",
  22.         "CML2_TRAITS",
  23.         "CML2_BASE_UNIT",
  24.         "CML2_TAXES",
  25.         "GROUP_NAME_LIST",
  26.         "FILES",
  27.         "R",
  28.         "G",
  29.         "B",
  30.     );
  31.  
  32.     public static $linkerProperties = Array(
  33.         "CML2_MANUFACTURER", //Производитель
  34.         "BRAND", //Производитель
  35.         "WORK_TYPE", //Тип работ
  36.         "OBJECT_TYPE", //Тип объекта
  37.         "WORK_MATERIAL", //Материал рабочей поверхности
  38.         "LKM_TYPE", //Тип ЛКМ
  39.         "THINNER", //Разбавитель
  40.         "BASE", //База
  41.         "COLOR", //Цвет
  42.         "VOLUME_L", //Объем, л
  43.         "VOLUME_KG", //Объем, кг
  44.         "PLOTNOST", //Плотность
  45.         "KVADRATURA", //Квадратура, кв.м
  46.         "LENGTH", //Длина, мм
  47.         "CHIPS_SIZE", //Размер крошки, мм
  48.         "SEQUIN_COLOR", //Цвет блёсток
  49.         "SEQUIN_SIZE", //Размер блёсток, мм
  50.         "GLOSS", //Степень блеска
  51.  
  52.     );
  53.  
  54.     private static $noUpdateHandler = false;
  55.  
  56.     private static function setNoHandler($bool)
  57.     {
  58.         self::$noUpdateHandler=$bool;
  59.     }
  60.  
  61.     public static function getNoHandler()
  62.     {
  63.         return self::$noUpdateHandler;
  64.     }
  65.  
  66.     public static function exception($s)
  67.     {
  68.         if(self::$debugMode)
  69.         {
  70.             printra(func_get_args());
  71.         }
  72.         else
  73.         {
  74.             throw new Exception(func_get_args());
  75.         }
  76.     }
  77.  
  78.     private static function lock()
  79.     {
  80.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  81.         touch($docRoot.self::$dir.self::$lockFile);
  82.     }
  83.  
  84.     private static function locked()
  85.     {
  86.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  87.         $sFile = $docRoot.self::$dir.self::$lockFile;
  88.         $locktime = 1800;
  89.        
  90.         if (file_exists($sFile) && (time() - filemtime($sFile)) < $locktime) {
  91.             unset($sFile);
  92.         }
  93.        
  94.         return file_exists($sFile);
  95.     }
  96.  
  97.     private static function unlock()
  98.     {
  99.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  100.         @unlink($docRoot.self::$dir.self::$lockFile);
  101.     }
  102.  
  103.     public static function getParams()
  104.     {
  105.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  106.         $arParams = Array();
  107.         require($docRoot.self::$dir.self::$paramFile);
  108.         return $arParams;
  109.     }
  110.  
  111.     public static function setParams($arParams=Array())
  112.     {
  113.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  114.         ArrayToFile($arParams,"arParams",$docRoot.self::$dir.self::$paramFile);
  115.         return $arParams;
  116.     }
  117.  
  118.     public static function logToFile($sStr)
  119.     {
  120.         $sErrorLog = $_SERVER['DOCUMENT_ROOT']."/upload/catalog/log/".date("Y.m.d").".txt";
  121.         $hFile = fopen($sErrorLog,"a+");
  122.         fputs($hFile,date("Y.m.d H:i:s")."\t".$sStr."\n");
  123.         fclose($hFile);
  124.     }
  125.  
  126.     public static function cron()
  127.     {
  128.         try
  129.         {
  130.             if(!self::locked())
  131.             {
  132.                 if(strlen($sAction = self::$params["action"]))
  133.                 {
  134.                     self::lock();
  135.                     self::logToFile("Start: {$sAction}");
  136.                     self::${"sAction"}();
  137.                     self::logToFile("End: {$sAction}");
  138.                     self::unlock();
  139.                 }
  140.             }
  141.         }
  142.         catch(Exception $e)
  143.         {
  144.             ob_start();
  145.             printr($e);
  146.             $sError = ob_get_contents();
  147.             ob_end_clean();
  148.             self::SendError($sError);
  149.             return false;
  150.         }
  151.         return true;
  152.     }
  153.  
  154.     public static function next()
  155.     {
  156.         $arParams = self::getParams();
  157.         if(!$arParams["action"] || $arParams["action"]=="done") return false;
  158.         global $APPLICATION;
  159.         echo '
  160.                 <script>
  161.                     window.setTimeout(function() {
  162.                         window.location.href = "'.$APPLICATION->GetCurPage().'";
  163.                     }, "300");
  164.                 </script>
  165.             ';
  166.     }
  167.  
  168.     public static function SendError($sError)
  169.     {
  170.         $obEvent = new CEvent();
  171.         $obEvent->Send("CRON_ERROR","s1",Array("ERROR"=>$sError));
  172.         printr($sError);
  173.     }
  174.  
  175.     public static function checkStart()
  176.     {
  177.         $sFunctionName = "CMigration::start();";
  178.         $obAgent = new CAgent();
  179.         $obExists = $obAgent->GetList(Array(), Array("NAME" => $sFunctionName));
  180.         if($arExists = $obExists->fetch())
  181.         {
  182.             $obAgent->Delete($arExists["ID"]);
  183.         }
  184.         $arAdd = Array(
  185.             "NAME" => $sFunctionName,
  186.             "AGENT_INTERVAL" => 1,
  187.             "NEXT_EXEC" => date("d.m.Y H:i:s", time() + 60),
  188.             "IS_PERIOD" => "N"
  189.         );
  190.         $obAgent->Add($arAdd);
  191.     }
  192.  
  193.     public static function start()
  194.     {
  195.         self::removeIBlockLink();
  196.         self::syncProperties();
  197.         self::setParams(Array("action"=>"syncSections"));
  198.     }
  199.  
  200.     public static function removeIBlockLink()
  201.     {
  202.         CCatalog::UnLinkSKUIBlock(IB_SKU);
  203.     }
  204.  
  205.     public static function GetLinkerIBlocks()
  206.     {
  207.         if(!isset($GLOBALS["L_IBLOCK"]))
  208.         {
  209.             $GLOBALS["LINKER_IBLOCK"]=Array();
  210.             $obIBlocks = CIBlock::GetList(Array("ID"=>"ASC"),Array("TYPE"=>"links"));
  211.             while($arIBlock = $obIBlocks->Fetch())
  212.             {
  213.                 $GLOBALS["L_IBLOCK"][$arIBlock["CODE"]]=$arIBlock["ID"];
  214.             }
  215.         }
  216.         return $GLOBALS["L_IBLOCK"];
  217.     }
  218.  
  219.     public static function processLinkerIBlock($arProperty)
  220.     {
  221.         $iIBlockID=false;
  222.         if(!empty($arProperty) && $arProperty["CODE"])
  223.         {
  224.             $arIBlocks = self::GetLinkerIBlocks();
  225.             global $APPLICATION;
  226.             $arFields = Array(
  227.                 "SORT"=>$arProperty["SORT"],
  228.                 "CODE" => ToUpper(trim($arProperty["CODE"])),
  229.                 "IBLOCK_TYPE_ID" => "links",
  230.                 "NAME" => self::cleanString($arProperty["NAME"]),
  231.                 "VERSION" => 2,
  232.                 "WORKFLOW" => "N",
  233.                 "SITE_ID" => Array("s1"),
  234.                 "GROUP_ID" => Array("2" => "R")
  235.             );
  236.             $arFields["DETAIL_PAGE_URL"]="/catalog/fil-".ToLower($arFields["CODE"])."-is-#CODE#/";
  237.  
  238.             $obNewIBlock = new CIBlock();
  239.             $arSettings = Array();
  240.             $arSettings["CODE"]["WF_TYPE"] = "N";
  241.             $arSettings["CODE"]["IS_REQUIRED"] = "Y";
  242.             $arSettings["CODE"]["DEFAULT_VALUE"]["UNIQUE"] = "Y";
  243.             $arSettings["CODE"]["DEFAULT_VALUE"]["TRANSLITERATION"] = "Y";
  244.  
  245.             if(!isset($arIBlocks[$arProperty["CODE"]]))
  246.             {
  247.                 if(!($iIBlockID = $obNewIBlock->Add($arFields)))
  248.                 {
  249.                     self::exception("AF: Error creating infoblock - ".$obNewIBlock->LAST_ERROR);
  250.                     $APPLICATION->ThrowException("AF: Error creating infoblock - ".$obNewIBlock->LAST_ERROR);
  251.                 }
  252.             }
  253.             else
  254.             {
  255.                 $iIBlockID = $arIBlocks[$arProperty["CODE"]];
  256.                 /*if(!($obNewIBlock->Update($iIBlockID, $arFields)))
  257.                 {
  258.                     self::exception("AF: Error creating infoblock - ".$obNewIBlock->LAST_ERROR);
  259.                     $APPLICATION->ThrowException("AF: Error creating infoblock - ".$obNewIBlock->LAST_ERROR);
  260.                 }*/
  261.             }
  262.             CIBlock::SetFields($iIBlockID, $arSettings);
  263.         }
  264.         return $iIBlockID;
  265.     }
  266.  
  267.     public static function syncProperties()
  268.     {
  269.         $obSkuProperties = CIBlockProperty::GetList(Array(),Array("IBLOCK_ID"=>IB_CATALOG));
  270.         $arSkuProperties = Array();
  271.         while($arSkuProperty = $obSkuProperties->Fetch())
  272.         {
  273.             $arSkuProperties[$arSkuProperty["CODE"]]=$arSkuProperty;
  274.         }
  275.  
  276.         $obCatProperties = CIBlockProperty::GetList(Array(),Array("IBLOCK_ID"=>IB_SKU));
  277.         $arCatProperties = Array();
  278.         $iPropertySort=0;
  279.         while($arCatProperty = $obCatProperties->Fetch())
  280.         {
  281.             if(in_array($arCatProperty["CODE"],self::$propsExeption)) continue;
  282.             if(preg_match("#^CML2_#",$arCatProperty["XML_ID"]) || preg_match(self::$xmlRegex,$arCatProperty["XML_ID"]))
  283.             {
  284.  
  285.                 switch($arCatProperty["PROPERTY_TYPE"])
  286.                 {
  287.                     case "F":
  288.                         $arPropertyFields = Array(
  289.                             "NAME" => $arCatProperty["NAME"],
  290.                             "ACTIVE" => "Y",
  291.                             "SORT" => $iPropertySort,
  292.                             "CODE" => $arCatProperty["CODE"],
  293.                             "PROPERTY_TYPE" => "F",
  294.                             "IBLOCK_ID" => IB_CATALOG,
  295.                             "WITH_DESCRIPTION" => "Y",
  296.                             "MULTIPLE"=>"Y",
  297.                             "XML_ID"=>""
  298.                         );
  299.                     break;
  300.                     default:
  301.                         $arPropertyFields = Array(
  302.                             "NAME" => $arCatProperty["NAME"],
  303.                             "ACTIVE" => "Y",
  304.                             "SORT" => $iPropertySort,
  305.                             "CODE" => $arCatProperty["CODE"],
  306.                             "PROPERTY_TYPE" => "S",
  307.                             "IBLOCK_ID" => IB_CATALOG,
  308.                             "WITH_DESCRIPTION" => "Y",
  309.                             "MULTIPLE"=>"Y",
  310.                             "MULTIPLE_CNT"=>1,
  311.                             "XML_ID"=>""
  312.                         );
  313.                         if(in_array($arCatProperty["CODE"], self::$linkerProperties) && ($iIBlockID = self::processLinkerIBlock($arPropertyFields)))
  314.                         {
  315.                             $arPropertyFields["PROPERTY_TYPE"]="E";
  316.                             $arPropertyFields["LINK_IBLOCK_ID"]=$iIBlockID;
  317.                         }
  318.                     break;
  319.                 }
  320.                 $obNewProperty = new CIBlockProperty();
  321.                 $iPropertySort++;
  322.                 if(!isset($arSkuProperties[$arCatProperty["CODE"]]))
  323.                 {
  324.                     if(!$obNewProperty->Add($arPropertyFields))
  325.                     {
  326.                         self::exception("AF: Error creating property - ".$obNewProperty->LAST_ERROR,__LINE__);
  327.                     }
  328.                 }
  329.                 else
  330.                 {
  331.                     $iPropertyID = $arSkuProperties[$arCatProperty["CODE"]]["ID"];
  332.                     //printra("upd ",$iPropertyID,$arPropertyFields);
  333.                     if(0)
  334.                     {
  335.                         //&&!$obNewProperty->Update($iPropertyID,$arPropertyFields)
  336.                         self::exception("AF: Error updating property - ".$obNewProperty->LAST_ERROR,__LINE__);
  337.                     }
  338.                 }
  339.                 $arSkuProperties[$arCatProperty["CODE"]]=$arPropertyFields;
  340.                 $arCatProperties[$arCatProperty["CODE"]]=$arCatProperty;
  341.             }
  342.         }
  343.         return true;
  344.     }
  345.  
  346.     public static function syncSections()
  347.     {
  348.         $arResult=Array();
  349.         /**
  350.          * Get SKU + Catalog Sections
  351.          */
  352.         self::setNoHandler(true);
  353.         $arSelect = Array(
  354.             "ID",
  355.             "NAME",
  356.             "IBLOCK_ID",
  357.             "ACTIVE",
  358.             "IBLOCK_SECTION_ID",
  359.             "XML_ID",
  360.             "SORT",
  361.             "UF_*"
  362.         );
  363.         $obSections = CIBlockSection::getList(
  364.             Array("DEPTH_LEVEL"=>"ASC"),
  365.             Array("IBLOCK_ID"=>IB_CATALOG),
  366.             false,
  367.             $arSelect
  368.         );
  369.  
  370.         while($arSection = $obSections->fetch())
  371.         {
  372.             $arResult["CATALOG"][$arSection["XML_ID"]]=$arSection;
  373.         }
  374.  
  375.         $obSections = CIBlockSection::getList(
  376.             Array("DEPTH_LEVEL"=>"ASC"),
  377.             Array("IBLOCK_ID"=>IB_SKU),
  378.             false,
  379.             $arSelect
  380.         );
  381.  
  382.         while($arSection = $obSections->fetch())
  383.         {
  384.             $arResult["SKU"][$arSection["ID"]]=$arSection;
  385.         }
  386.         $sHash = md5(serialize($arResult));
  387.  
  388.  
  389.         /**
  390.          * Cache block
  391.          */
  392.         $iCacheTime=360000000;
  393.         $sCacheDir="/migration/sections";
  394.         $obCache = new CPHPCache();
  395.  
  396.         if(!$obCache->InitCache($iCacheTime, $sHash, $sCacheDir))
  397.         {
  398.  
  399.             $obCache->StartDataCache();
  400.  
  401.             global $CACHE_MANAGER;
  402.             $CACHE_MANAGER->StartTagCache($sCacheDir);
  403.             $obNewSection = new CIBlockSection();
  404.             foreach($arResult["SKU"] as $arSection)
  405.             {
  406.                 $sCRC = md5(serialize($arSection));
  407.                 $arFields = Array(
  408.                     "IBLOCK_ID"=>IB_CATALOG,
  409.                     "ACTIVE"=>$arSection["ACTIVE"],
  410.                     "UF_CRC"=>$sCRC,
  411.                     "SORT"=>$arSection["SORT"],
  412.                     "NAME"=>$arSection["NAME"],
  413.                     "XML_ID"=>"cat_{$arSection["ID"]}",
  414.                     "IBLOCK_SECTION_ID"=>$arResult["CATALOG"]["cat_{$arSection["IBLOCK_SECTION_ID"]}"]["ID"],
  415.                     "CODE"=>CUtil::translit($arSection["NAME"],"ru",self::$translit)
  416.                 );
  417.                 if(isset($arResult["CATALOG"]["cat_{$arSection["ID"]}"]))
  418.                 {
  419.                     $arCatSection = $arResult["CATALOG"]["cat_{$arSection["ID"]}"];
  420.                     if($arCatSection["UF_CRC"]!=$sCRC)
  421.                     {
  422.                         if(!$obNewSection->Update($arCatSection["ID"],$arFields,false))
  423.                         {
  424.                             self::exception($obNewSection->LAST_ERROR,$arFields);
  425.                         }
  426.                     }
  427.                 }
  428.                 else
  429.                 {
  430.                     if($iItemID = $obNewSection->Add($arFields,false))
  431.                     {
  432.                         $arResult["CATALOG"]["cat_{$arSection["ID"]}"]=Array("ID"=>$iItemID)+$arFields;
  433.                     }
  434.                     else
  435.                     {
  436.                         self::exception($obNewSection->LAST_ERROR,$arFields);
  437.                     }
  438.                 }
  439.             }
  440.  
  441.             /**
  442.              * Deactivate sections
  443.              */
  444.             /*foreach($arResult["CATALOG"] as $arCatSection)
  445.             {
  446.                 if(preg_match("#^cat_(\d+)$#",$arCatSection["XML_ID"],$arMatches))
  447.                 {
  448.                     $iSKUSectionID = IntVal($arMatches[1]);
  449.                     if(isset($ar))
  450.                 }
  451.             }*/
  452.  
  453.  
  454.             CIBlockSection::ReSort(IB_CATALOG);
  455.  
  456.             $CACHE_MANAGER->RegisterTag(IB_CATALOG);
  457.             $CACHE_MANAGER->EndTagCache();
  458.  
  459.             $obCache->EndDataCache($arResult);
  460.         }
  461.         else
  462.         {
  463.             $arResult = $obCache->GetVars();
  464.         }
  465.  
  466.         self::setNoHandler(false);
  467.         self::setParams(Array("action"=>"saveFiles"));
  468.         return true;
  469.     }
  470.  
  471.     public static function saveFiles()
  472.     {
  473.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  474.  
  475.         /**
  476.          * Get Linker IBlocks Values
  477.          * $GLOBALS["LINK_IB"][$iIBlockID][$sName]=$iItemID;
  478.          */
  479.  
  480.         $GLOBALS["LINK_IB"]=Array();
  481.         $obItems = \Bitrix\Iblock\ElementTable::getList(
  482.             Array(
  483.                 "filter"=>Array(
  484.                     "IBLOCK.TYPE.ID"=>"links",
  485.                     "WF_PARENT_ELEMENT_ID"=>false
  486.                 ),
  487.                 "select"=>Array("*")
  488.             )
  489.         );
  490.         $GLOBALS["LINK_IB"]=Array();
  491.         while($arItem = $obItems->Fetch())
  492.         {
  493.             $GLOBALS["LINK_IB"][$arItem["IBLOCK_ID"]][$arItem["NAME"]]=$arItem["ID"];
  494.         }
  495.  
  496.         /**
  497.          * Get SKU Section Links
  498.          */
  499.  
  500.         $obItemSections = \Bitrix\Iblock\SectionElementTable::getList(
  501.             Array(
  502.                 "filter" => Array(
  503.                     "IBLOCK_SECTION.IBLOCK_ID" => IB_SKU
  504.                 )
  505.             )
  506.         );
  507.         $arItemToSections = Array();
  508.         while($arItem = $obItemSections->Fetch())
  509.         {
  510.             $arItemToSections[$arItem["IBLOCK_ELEMENT_ID"]][]=$arItem["IBLOCK_SECTION_ID"];
  511.         }
  512.  
  513.         /**
  514.          * Get Section to section Link
  515.          */
  516.  
  517.         $obSections = \Bitrix\Iblock\SectionTable::getList(Array(
  518.             "filter"=>Array(
  519.                 "IBLOCK_ID"=>IB_CATALOG
  520.             ),
  521.             "select"=>Array("ID","XML_ID")
  522.         ));
  523.         $arSKUSectionToCatSection=Array();
  524.         while($arSection = $obSections->fetch())
  525.         {
  526.             if(preg_match("#^cat_(\d+)$#",$arSection["XML_ID"],$arMatches))
  527.             {
  528.                 $arSKUSectionToCatSection[$arMatches[1]]=$arSection["ID"];
  529.             }
  530.         }
  531.  
  532.         /**
  533.          * Get Properties link
  534.          */
  535.         $obSkuProperties = CIBlockProperty::GetList(Array(),Array("IBLOCK_ID"=>IB_SKU));
  536.  
  537.         $arProperties = Array();
  538.         $iGroupNameID = 0;
  539.         $iGroupListNameID = 0;
  540.         while($arSkuProperty = $obSkuProperties->Fetch())
  541.         {
  542.             if($arSkuProperty["CODE"]=="GROUP_NAME") $iGroupNameID=$arSkuProperty["ID"];
  543.             if($arSkuProperty["CODE"]=="GROUP_NAME_LIST") $iGroupListNameID=$arSkuProperty["ID"];
  544.             $arSkuProperties[$arSkuProperty["CODE"]]=$arSkuProperty["ID"];
  545.             $arProperties[$arSkuProperty["ID"]]=$arSkuProperty;
  546.         }
  547.  
  548.  
  549.         $obCatProperties = CIBlockProperty::GetList(Array(),Array("IBLOCK_ID"=>IB_CATALOG));
  550.         $arPropertiesCatalogToSKULink = Array();
  551.         $arCRCProperties = Array();
  552.         while($arCatProperty = $obCatProperties->Fetch())
  553.         {
  554.             if(substr_count($arCatProperty["CODE"],"CRC_"))
  555.             {
  556.                 $arCRCProperties[]=$arCatProperty["CODE"];
  557.                 continue;
  558.             }
  559.             if(isset($arSkuProperties[$arCatProperty["CODE"]]))
  560.             {
  561.                 $arPropertiesCatalogToSKULink[$arSkuProperties[$arCatProperty["CODE"]]]=$arCatProperty["CODE"];
  562.             }
  563.         }
  564.  
  565.         /**
  566.          * Get Properties enum values
  567.          */
  568.         $arPropertyEnumToValue=Array();
  569.         $arPropertyEnumToXMLID=Array();
  570.         foreach($arProperties as $iPropertyID=>$arProperty)
  571.         {
  572.             if($arProperty["PROPERTY_TYPE"]=="L")
  573.             {
  574.                 $obEnum = CIBlockProperty::GetPropertyEnum($iPropertyID);
  575.                 while($arItem = $obEnum->Fetch())
  576.                 {
  577.                     $arPropertyEnumToValue[$arItem["ID"]]=$arItem["VALUE"];
  578.                     $arPropertyEnumToXMLID[$arItem["ID"]]=$arItem["XML_ID"];
  579.                 }
  580.             }
  581.  
  582.         }
  583.  
  584.         /**
  585.          * Get Catalog element links
  586.          */
  587.         $arSSelect = Array("ID","XML_ID");
  588.         foreach($arCRCProperties as $sCode) $arSSelect[]="PROPERTY_{$sCode}";
  589.         $obCatItems = CIBlockElement::GetList(Array(),Array("IBLOCK_ID"=>IB_CATALOG),false,false,$arSSelect);
  590.         $arCatItemsLink = Array();
  591.         while($arCatItem = $obCatItems->fetch())
  592.         {
  593.             $arCatItemsLink[$arCatItem["XML_ID"]]=$arCatItem;
  594.         }
  595.  
  596.  
  597.         /**
  598.          * Get SKU With Properties and Prices
  599.          */
  600.  
  601.         $arLinkerIBlocks = self::GetLinkerIBlocks();
  602.  
  603.         $iTime = microtime(1);
  604.         $arSelect = Array(
  605.             "ID",
  606.             "XML_ID",
  607.             "NAME",
  608.             "ACTIVE",
  609.             "PROPERTY_*",
  610.             "PROPERTY_ENUM_*",
  611.             "PROPERTY_XML_ID_*",
  612.             "CATALOG_QUANTITY"
  613.         );
  614.         $arSelect[]="CATALOG_GROUP_".BASE_PRICE_ID;
  615.  
  616.  
  617.         $obSKUItems = CIBlockElement::GetList(
  618.             Array(),
  619.             Array(
  620.                 "ACTIVE"=>"Y",
  621.                 "IBLOCK_ID" => IB_SKU,
  622.                 Array(
  623.                     "LOGIC"=>"OR",
  624.                     Array("!PROPERTY_GROUP_NAME"=>false),
  625.                     Array("!PROPERTY_GROUP_NAME_LIST"=>false)
  626.                 )
  627.             ),
  628.             false,
  629.             false,
  630.             $arSelect
  631.         );
  632.  
  633.  
  634.         $arResult = Array();
  635.  
  636.         while($arItem = $obSKUItems->Fetch())
  637.         {
  638.             $sGroupName = self::cleanString($arItem["PROPERTY_{$iGroupNameID}"]);
  639.             $sGroupNameList = self::cleanString($arPropertyEnumToValue[$arItem["PROPERTY_{$iGroupListNameID}"]]);//self::cleanString($arItem["PROPERTY_{$iGroupNameID}"]);
  640.  
  641.             $sGroupNameListXML = $arPropertyEnumToXMLID[$arItem["PROPERTY_{$iGroupListNameID}"]];
  642.  
  643.             unset($arItem["PROPERTY_{$iGroupNameID}"]);
  644.             unset($arItem["DESCRIPTION_{$iGroupNameID}"]);
  645.             if(!$sGroupName && !$sGroupNameListXML) continue;
  646.             $sToMD5 = $sGroupNameListXML?:CUtil::translit($sGroupName,"ru",self::$translit);
  647.             $sGroupXMLID = "cat_".md5($sToMD5);
  648.  
  649.             if(!isset($arResult[$sGroupXMLID]))
  650.             {
  651.                 $sElementName = $sGroupNameList?:$sGroupName;
  652.                 $arResult[$sGroupXMLID]=Array(
  653.                     "FIELDS"=>Array(
  654.                         "IBLOCK_ID"=>IB_CATALOG,
  655.                         "ACTIVE"=>"Y",
  656.                         "NAME" => $sElementName,
  657.                         "XML_ID" => $sGroupXMLID,
  658.                         "CODE"=>CUtil::translit($sGroupName,"ru",self::$translit),
  659.                         "CATALOG_AVAILABLE"=>"N",
  660.                         "CATALOG_QUANTITY"=>0
  661.                     ),
  662.                     "PROPERTIES"=>Array("ACTIVE"=>false),
  663.                     "SECTIONS"=>Array(),
  664.                     "PRICES"=>Array(),
  665.                     "SKU_ITEMS"=>Array(),
  666.                     "CRC"=>Array()
  667.                 );
  668.             }
  669.             $arCatItem = &$arResult[$sGroupXMLID];
  670.             $arCatItemFields = &$arCatItem["FIELDS"];
  671.             $arCatItemProperties = &$arCatItem["PROPERTIES"];
  672.             $arCatItemSections = &$arCatItem["SECTIONS"];
  673.             $arCatPrices = &$arCatItem["PRICES"];
  674.             $arCatItemSKU = &$arCatItem["SKU_ITEMS"];
  675.  
  676.  
  677.             /**
  678.              * Заполненные значения в каталоге + CRC
  679.              */
  680.  
  681.             if(isset($arCatItemsLink[$sGroupXMLID]))
  682.             {
  683.                 $arWasCatItem = $arCatItemsLink[$sGroupXMLID];
  684.                 $arCatItemFields["ID"]=$arWasCatItem["ID"];
  685.                 foreach($arWasCatItem as $sCode=>$sValue)
  686.                 {
  687.                     if(preg_match("#^PROPERTY_CRC_(\S+)_VALUE$#",$sCode,$arMatches))
  688.                     {
  689.                         $arCatItem["CRC"][$arMatches[1]]=$sValue;
  690.                     }
  691.                 }
  692.             }
  693.             else
  694.             {
  695.                 //printr($arCatItem["FIELDS"]["NAME"],$sGroupXMLID);
  696.             }
  697.  
  698.             /**
  699.              * Перегон разделов
  700.              */
  701.             if(isset($arItemToSections[$arItem["ID"]]) && $sGroupXMLID)
  702.             {
  703.                 foreach($arItemToSections[$arItem["ID"]] as $iSectionID)
  704.                 {
  705.                     if(isset($arSKUSectionToCatSection[$iSectionID]))
  706.                     {
  707.                         $iCatSectionID = $arSKUSectionToCatSection[$iSectionID];
  708.                         if(!in_array($iCatSectionID,$arCatItemSections))
  709.                         {
  710.                             $arCatItemSections[]=$iCatSectionID;
  711.                         }
  712.                     }
  713.                 }
  714.             }
  715.  
  716.             /**
  717.              * Перегон всех свойств в формат свойств для каталога.
  718.              */
  719.             foreach($arItem as $sCode=>$arValues)
  720.             {
  721.                 if(preg_match("#^PROPERTY_(\d+)$#",$sCode,$arMatches))
  722.                 {
  723.                     $iPropertyID = IntVal($arMatches[1]);
  724.                     if(isset($arPropertiesCatalogToSKULink[$iPropertyID]))
  725.                     {
  726.                         if(!is_array($arValues))
  727.                         {
  728.                             $arValues = Array($arValues);
  729.                             $arItem["DESCRIPTION_{$iPropertyID}"]=Array($arItem["DESCRIPTION_{$iPropertyID}"]);
  730.                         }
  731.                         $iCatPropertyID = $arPropertiesCatalogToSKULink[$iPropertyID];
  732.                         if(!isset($arCatItemProperties[$iCatPropertyID]))
  733.                         {
  734.                             $arCatItemProperties[$iCatPropertyID]=Array();
  735.                         }
  736.                         $sPropertyType = $arProperties[$iPropertyID]["PROPERTY_TYPE"];
  737.                         $sPropertyCode = $arProperties[$iPropertyID]["CODE"];
  738.  
  739.                         foreach($arValues as $iKey=>$value)
  740.                         {
  741.                             switch($sPropertyType)
  742.                             {
  743.                                 case "L":
  744.                                     $enumID = $value;
  745.                                     $value=$arPropertyEnumToValue[$value];
  746.  
  747.                                     if(in_array($sPropertyCode,self::$linkerProperties) && (isset($arLinkerIBlocks[$sPropertyCode])))
  748.                                     {
  749.  
  750.  
  751.                                         if($sPropertyCode=="WORK_TYPE")
  752.                                         {
  753.                                             $arValuesStr = explode("/",$value);
  754.                                             $value = Array();
  755.                                             foreach($arValuesStr as $iKey=>$sValue)
  756.                                             {
  757.                                                 if($sValue = trim($sValue))
  758.                                                 {
  759.                                                     $value[]=CIBlockExt::TouchPropertyElement($sValue,$arLinkerIBlocks[$sPropertyCode]);
  760.                                                 }
  761.                                             }
  762.                                         }
  763.                                         elseif($sPropertyCode=="COLOR")
  764.                                         {
  765.                                             $value=CIBlockExt::TouchPropertyElement($value,$arLinkerIBlocks[$sPropertyCode], $arPropertyEnumToXMLID[$enumID]);
  766.                                         }
  767.                                         else
  768.                                         {
  769.                                             $value=CIBlockExt::TouchPropertyElement($value,$arLinkerIBlocks[$sPropertyCode]);
  770.                                         }
  771.  
  772.  
  773.                                     }
  774.                                 break;
  775.                                 default:
  776.                                 break;
  777.                             }
  778.                             if(!is_array($value))
  779.                             {
  780.                                 $value=self::cleanString($value);
  781.                                 $sDescription = self::cleanString($arItem["DESCRIPTION_{$iPropertyID}"][$iKey]);
  782.                             }
  783.                             else
  784.                             {
  785.                                 if(empty($value))
  786.                                 {
  787.                                     $value=false;
  788.                                 }
  789.                             }
  790.  
  791.                             /*if(!in_array($value,$arCatItemProperties[$iCatPropertyID]["VALUE"]))
  792.                             {
  793.                                 $arCatItemProperties[$iCatPropertyID]["VALUE"][$iKey]=$value;
  794.                                 $arCatItemProperties[$iCatPropertyID]["DESCRIPTION"][$iKey]=$sDescription;
  795.                             }*/
  796.                             /**
  797.                              * Hack with no description. Upper variant doesn't work. Debug yourself.
  798.                              */
  799.                             if(is_array($value))
  800.                             {
  801.                                 foreach($value as $oneValue)
  802.                                 {
  803.                                     if(!in_array($oneValue,$arCatItemProperties[$iCatPropertyID]))
  804.                                     {
  805.                                         $arCatItemProperties[$iCatPropertyID][]=$oneValue;
  806.                                     }
  807.                                 }
  808.                             }
  809.                             elseif(!in_array($value,$arCatItemProperties[$iCatPropertyID]))
  810.                             {
  811.                                 $arCatItemProperties[$iCatPropertyID][]=$value;
  812.                             }
  813.                         }
  814.                         if(empty($arCatItemProperties[$iCatPropertyID])) $arCatItemProperties[$iCatPropertyID]=false;
  815.                     }
  816.  
  817.                 }
  818.             }
  819.  
  820.  
  821.             /**
  822.              * Перегон цен и остатков
  823.              */
  824.             if($iPrice = FloatVal($arItem["CATALOG_PRICE_".BASE_PRICE_ID]))
  825.             {
  826.  
  827.                 if(($sCurrency = $arItem["CATALOG_CURRENCY_".BASE_PRICE_ID])!="RUB")
  828.                 {
  829.                     $iPrice = CCurrencyRates::ConvertCurrency($iPrice,$sCurrency,"RUB");
  830.                 }
  831.                 if(($arItem["CATALOG_QUANTITY"]>0) && ($iPrice>0))
  832.                 {
  833.                     $arCatItemFields["CATALOG_AVAILABLE"]="Y";
  834.                     $arCatItemFields["CATALOG_QUANTITY"]+=$arItem["CATALOG_QUANTITY"];
  835.                     $arCatItemProperties["ACTIVE"]=1;
  836.                     $arCatPrices[]=$iPrice;
  837.                 }
  838.             }
  839.             $arCatItemSKU[]=$arItem["ID"];
  840.         }
  841. //die();
  842.         ArrayToFile($arResult, "arCatItems", $docRoot.self::$dir.self::$catFile);
  843.         //die();
  844.         self::setParams(Array("action"=>"processCatalogItems"));
  845.         return true;
  846.     }
  847.  
  848.     public static function arrayCRC($array)
  849.     {
  850.         return md5(serialize($array));
  851.     }
  852.  
  853.     public static function processCatalogItems()
  854.     {
  855.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  856.         /**
  857.          * @var $arCatItems array
  858.          */
  859.         include($docRoot.self::$dir.self::$catFile);
  860.  
  861.         $obNewElement = new CIBlockElement();
  862.  
  863.         $iTime = microtime(1);
  864.         $bAnotherTime = false;
  865.  
  866.         self::setNoHandler(true);
  867.         $iProcessed = 0;
  868.         foreach($arCatItems as $iKey=>$arElement)
  869.         {
  870.             $iProcessed++;
  871.             if(IntVal($arElement["PROCESSED"])) continue;
  872.             $bUpdated = false;
  873.             $iCatElementID = 0;
  874.  
  875.  
  876.             /**
  877.              * Create catalog element
  878.              */
  879.             if(IntVal($arElement["FIELDS"]["ID"]))
  880.             {
  881.                 $iCatElementID=$arElement["FIELDS"]["ID"];
  882.                
  883.                 if(self::arrayCRC($arElement["FIELDS"])!=$arElement["CRC"]["FIELDS"])
  884.                 {
  885.                     unset($arElement["FIELDS"]["CODE"]);
  886.                     if(!$obNewElement->Update($iCatElementID,$arElement["FIELDS"]))
  887.                     {
  888.                         self::exception($obNewElement->LAST_ERROR,$arElement["FIELDS"],__LINE__);
  889.                     }
  890.                     $arCatalogUpdate=Array(
  891.                         "ID"=>$iCatElementID,
  892.                         "AVAILABLE"=>$arElement["FIELDS"]["CATALOG_AVAILABLE"],
  893.                         "QUANTITY"=>$arElement["FIELDS"]["CATALOG_QUANTITY"]
  894.                     );
  895.                     CCatalogProduct::Add($arCatalogUpdate);
  896.                     $bUpdated=true;
  897.                 }
  898.             }
  899.             else
  900.             {
  901.                 ///printra($arElement);
  902.  
  903.                 if(!($iCatElementID = $obNewElement->Add($arElement["FIELDS"])))
  904.                 {
  905.                     self::exception($obNewElement->LAST_ERROR,$arElement["FIELDS"],__LINE__);
  906.                 }
  907.             }
  908.  
  909.             /**
  910.              * Set sections
  911.              */
  912.  
  913.             if(self::arrayCRC($arElement["SECTIONS"])!=$arElement["CRC"]["SECTIONS"])
  914.             {
  915.                 CIBlockElement::SetElementSection($iCatElementID,$arElement["SECTIONS"]);
  916.                 $bUpdated=true;
  917.             }
  918.  
  919.             /**
  920.              * Set properties
  921.              */
  922.  
  923.             $arElement["PROPERTIES"]["PRICE_FROM"]=min($arElement["PRICES"]);
  924.             $arElement["PROPERTIES"]["PRICE_TO"]=max($arElement["PRICES"]);
  925.             $sCurrentCRC=self::arrayCRC($arElement["PROPERTIES"]);
  926.             $arNewCRC = Array(
  927.                 "CRC_PROPERTIES"=>self::arrayCRC($arElement["PROPERTIES"]),
  928.                 "CRC_SECTIONS"=>self::arrayCRC($arElement["SECTIONS"]),
  929.                 "CRC_FIELDS"=>self::arrayCRC($arElement["FIELDS"]),
  930.                 "CRC_SKU_ITEMS"=>self::arrayCRC($arElement["SKU_ITEMS"]),
  931.             );
  932.             $arElement["PROPERTIES"]+=$arNewCRC;
  933.  
  934.  
  935.             if($bUpdated || ($sCurrentCRC!=$arElement["CRC"]["PROPERTIES"]))
  936.             {
  937.                 CIBlockElement::SetPropertyValuesEx($iCatElementID,IB_CATALOG,$arElement["PROPERTIES"]);
  938.                 $bUpdated=true;
  939.             }
  940.  
  941.             /**
  942.              * Link SKU Items
  943.              */
  944.             if(self::arrayCRC($arElement["SKU_ITEMS"])!=$arElement["CRC"]["SKU_ITEMS"])
  945.             {
  946.                 foreach($arElement["SKU_ITEMS"] as $iSKUItemID)
  947.                 {
  948.                     CIBlockElement::SetPropertyValuesEx($iSKUItemID,IB_SKU,Array("CML2_LINK"=>$iCatElementID));
  949.                 }
  950.                 $bUpdated=true;
  951.                
  952.             }
  953.  
  954.             if($bUpdated)
  955.             {
  956.                 //CIBlockElement::UpdateSearch($iCatElementID,true);
  957.                 CIBlockExt::RunUpdate($iCatElementID);
  958.                 CCacheClean::CatalogElement($iCatElementID);
  959.                 \Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex(IB_CATALOG, $iCatElementID);
  960.             }
  961.  
  962.             $arCatItems[$iKey]=Array(
  963.                 "PROCESSED"=>1,
  964.                 "ID"=>$iCatElementID
  965.             );
  966.             if(time()-$iTime>15)
  967.             {
  968.                 $bAnotherTime = true;
  969.                 break;
  970.             }
  971.         }
  972.  
  973.         self::setNoHandler(false);
  974.  
  975.         ArrayToFile($arCatItems, "arCatItems", $docRoot.self::$dir.self::$catFile);
  976.         if($bAnotherTime)
  977.         {
  978.             $params = self::getParams();
  979.             $params["processed"] = "{$iProcessed} / ".count($arCatItems);
  980.             self::logToFile("Processed ".$params["processed"]);
  981.             self::setParams($params);
  982.         }
  983.         else
  984.         {
  985.             self::setParams(Array("action"=>"deactivateItems"));
  986.         }
  987.         return !$bAnotherTime;
  988.     }
  989.  
  990.     public static function deactivateItems()
  991.     {
  992.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  993.         /**
  994.          * @var $arCatItems array
  995.          */
  996.         require($docRoot.self::$dir.self::$catFile);
  997.  
  998.         $bAnotherTime = false;
  999.         $iTime = microtime(1);
  1000.         $obNewElement = new CIBlockElement();
  1001.         self::setNoHandler(true);
  1002.         $iProcessed=0;
  1003.         $arIDs = Array();
  1004.         foreach($arCatItems as $arItem)
  1005.         {
  1006.             $arIDs[]=$arItem["ID"];
  1007.         }
  1008.  
  1009.         $iCount = 0;
  1010.         if(!empty($arIDs))
  1011.         {
  1012.             $obItems = $obNewElement->GetList(
  1013.                 Array(),
  1014.                 Array(
  1015.                     "IBLOCK_ID"=>IB_CATALOG,
  1016.                     "ACTIVE"=>"Y",
  1017.                     "!ID"=>$arIDs
  1018.                 ),
  1019.                 false,
  1020.                 false,
  1021.                 Array("ID")
  1022.             );
  1023.             $iCount=$obItems->SelectedRowsCount();
  1024.  
  1025.  
  1026.             while($arItem = $obItems->Fetch())
  1027.             {
  1028.                 $iProcessed++;
  1029.                 $obNewElement->Update($arItem["ID"],Array("ACTIVE"=>"N"));
  1030.                 if(time()-$iTime>15)
  1031.                 {
  1032.                     $bAnotherTime=true;
  1033.                     break;
  1034.                 }
  1035.             }
  1036.         }
  1037.  
  1038.  
  1039.  
  1040.         if($bAnotherTime)
  1041.         {
  1042.             $params = self::getParams();
  1043.             $params["processed"] = "{$iProcessed} / ".$iCount;
  1044.             self::setParams($params);
  1045.             self::logToFile("Processed ".$params["processed"]);
  1046.             ArrayToFile($arCatItems, "arCatItems", $docRoot.self::$dir.self::$catFile);
  1047.         }
  1048.         else
  1049.         {
  1050.             //self::setParams(Array());
  1051.             self::setParams(Array("action"=>"updateSearch"));
  1052.         }
  1053.         self::setNoHandler(false);
  1054.         return !$bAnotherTime;
  1055.     }
  1056.    
  1057.     public static function updateSearch()
  1058.     {
  1059.         $obInstance = new CYandexSearch;
  1060.         $obInstance->SaveYMLFile();
  1061.         self::setParams(Array());
  1062.         return true;
  1063.     }
  1064.  
  1065.     public static function cleanString($s)
  1066.     {
  1067.         return trim(preg_replace("#[ ]+#", " ", $s));
  1068.     }
  1069.  
  1070.     private function __clone(){}
  1071.  
  1072.     private function __construct()
  1073.     {
  1074.         $docRoot = $_SERVER["DOCUMENT_ROOT"];
  1075.         CheckDirPath($docRoot.self::$dir);
  1076.         touch($docRoot.self::$dir.self::$paramFile);
  1077.         touch($docRoot.self::$dir.self::$catFile);
  1078.         self::$params=self::getParams();
  1079.     }
  1080.  
  1081.     public static function getInstance()
  1082.     {
  1083.         if(null === self::$_instance)
  1084.         {
  1085.             self::$_instance = new self();
  1086.         }
  1087.         return self::$_instance;
  1088.     }
  1089. }
Add Comment
Please, Sign In to add comment