Парсер Fapi для сайта автозапчастей на Битриксе


https://fapi.iisis.ru/api-dostup
https://app.swaggerhub.com/apis/serp83/fapi/1.0.4#/
define("FAPI_API_KEY", 'XXXXXXXXXXXXXXX'); //это ключ, который вам выдают для доступа
Непосредственные запросы с FAPI

Получаем список производителей с FAPI
function GetBrandsFapi(){
    $url = 'http://fapi.iisis.ru/fapi/v2/manufacturerList?ui='.FAPI_API_KEY;
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
    $result = curl_exec($curl);
    curl_close($curl);
    return $result;
} 
Получить картинку детали с FAPI
function GetImageFapi($mfi,$numDetail){
   $url = 'https://static.fapi.iisis.ru/fapi/v2/imageList?ui='.FAPI_API_KEY;
   $result = '';
   if(!empty($mfi) && !empty($numDetail)){
   $numDetail = urlencode($numDetail);
   $url = $url.'&mfi='.$mfi."&n=".$numDetail."&width=1000&imgd=false";

   $curl = curl_init();
   curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
    $result = curl_exec($curl);     
   curl_close($curl);       
   }
   return $result;
}
Получить применяемость с FAPI
function GetApplicabilityFapi($mfi,$numDetail){
   $url = 'https://fapi.iisis.ru/fapi/v2/productApplicabilityList?ui='.FAPI_API_KEY;
   $result = '';
   if(!empty($mfi) && !empty($numDetail)){
   $numDetail = urlencode($numDetail);
   $url = $url.'&mfi='.$mfi."&n=".$numDetail;      
   $curl = curl_init();
   curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        $result = curl_exec($curl);     
        curl_close($curl);       
   }
   return $result;
}
получить список аналогов для детали с FAPI
function GetAnalogsFapi($mfi,$numDetail){
   $url = 'https://fapi.iisis.ru/fapi/v2/analogList?ui='.FAPI_API_KEY;
   $result = '';
   if(!empty($mfi) && !empty($numDetail)){
    $numDetail = urlencode($numDetail);
   $url = $url.'&mfi='.$mfi."&n=".$numDetail."&r=2&O=CORRECT_AR";      
   $curl = curl_init();
   curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        $result = curl_exec($curl);     
        curl_close($curl);       
   }
   return $result;
}

Вспомогательные функции
получить список брендов по фильтру
function GetBrandsByFilter($filter=array()){
   $arBrands = array();
   if(!empty($filter) && CModule::IncludeModule('iblock')){      
      $arSelect = Array("ID", "NAME","IBLOCK_ID","PROPERTY_MFI");
      $arFilter = Array(
         "IBLOCK_ID"=>9, 
         "ID" => $filter,      
         "!PROPERTY_MFI"=>false         
      );
      $res = CIBlockElement::GetList(Array("id"=>"asc"), $arFilter, false, Array("nPageSize"=>500,"iNumPage"=>1), $arSelect);   
      while ($arBrand = $res->Fetch()) {
         $arBrands[$arBrand["ID"]] = $arBrand;
      }
   }
   return $arBrands;
}
Получить список брендов по коду
function GetBrandsCarByCode($arCodes=array()){
   $arBrands = array();
   if(!empty($arCodes) && CModule::IncludeModule('iblock')){      
      $arSelect = Array("ID", "CODE","IBLOCK_ID");
      $arFilter = Array(
         "IBLOCK_ID"=>19, 
         "CODE" => $arCodes,         
      );
      $res = CIBlockElement::GetList(Array("id"=>"asc"), $arFilter, false, Array("nPageSize"=>500,"iNumPage"=>1), $arSelect);   
      while ($arBrand = $res->Fetch()) {
         $arBrands[$arBrand["CODE"]] = $arBrand["ID"];
      }
   }
   return $arBrands;   
}
Получить модели по имени и бренду
function  GetModelsByNames($brandId,$arModelsNames=array()){
   $arModels = array();
   if(!empty($arModelsNames)&& CModule::IncludeModule('iblock')){
      $arSelect = Array("ID", "NAME","IBLOCK_ID");
      $arFilter = Array(
         "IBLOCK_ID"=>20, 
         "NAME" => $arModelsNames,         
         "PROPERTY_CAR_BRAND" =>$brandId
      );
      $res = CIBlockElement::GetList(Array("id"=>"desc"), $arFilter, false, Array("nPageSize"=>500,"iNumPage"=>1), $arSelect);   
      while ($arModel = $res->Fetch()) {
         $arModels[$arModel["ID"]] = $arModel["NAME"];
      }
   }
   return $arModels;
}
Получить модификации по имени и модели
function  GetModefsByNames($modelId,$arModifNames=array()){
   $arModifs = array();
   if(!empty($arModifNames)&& CModule::IncludeModule('iblock')){
      $arSelect = Array("ID", "NAME","IBLOCK_ID");
      $arFilter = Array(
         "IBLOCK_ID"=>21, 
         "NAME" => $arModifNames,         
         "PROPERTY_CAR_MODEL" =>$modelId
      );
      $res = CIBlockElement::GetList(Array("id"=>"asc"), $arFilter, false, Array("nPageSize"=>500,"iNumPage"=>1), $arSelect);   
      while ($arModif = $res->Fetch()) {
         $arModifs[$arModif["ID"]] = $arModif["NAME"];
      }
   }
   return $arModifs;
}
Очищаем артикул от добовочных слов
function NewCatalogNumber($num){
   if(!empty($num)){
      $num = strtolower($num);
      $num = explode("_уценка", $num);
      $num = $num[0];
      $num = explode("_б/у", $num);
      $num = $num[0];
      $num = explode("_брак", $num);
      $num = $num[0];
   }
   return $num;
}

Заполняем применимость

function PrimenimostFapiFill($id='',$brandMfi='',$number=''){   
   $sPrimenimost = "";
   //подходит к автомобилям с Fapi заполняем
   if(!empty($id) && !empty($brandMfi) && !empty($number) && CModule::IncludeModule("iblock")){
      $number = NewCatalogNumber($number);
      $result = GetApplicabilityFapi($brandMfi,$number);
      if(!empty($result) && ($result!= '400 Bad Request')){
         $result = json_decode($result);              
         $arBrandsFapi = array();               
         if(property_exists($result, "manufacturerList")){
            $brandsFapiT = $result->manufacturerList;
            if(property_exists($brandsFapiT, "mf")){
               $brandsFapi = $brandsFapiT->mf;
               foreach ($brandsFapi as $brandFapi) {                           
                  $arBrandsFapi[$brandFapi->i] = array(
                     "NAME"=> $brandFapi->ds,
                     "NAME_SHORT" => strtolower($brandFapi->da),
                     "MFI" => $brandFapi->dbi,
                     "MODELS" => array(),                                                      
                  );
                  $arBrandsCodes[] = strtolower($brandFapi->da);                        
               }
            }
         }
         if(property_exists($result, "modelList")){
            $modelsFapiT = $result->modelList;
            if(property_exists($modelsFapiT, "m")){
               $modelsFapi = $modelsFapiT->m;
               foreach ($modelsFapi as $model) {
                  $arBrandsFapi[$model->mfi]["MODELS"][$model->i] = array(
                     // "I" => $model->i,
                   // "DBI" => $model->dbi,
                     // "MFI" => $model->mfi,
                   "NAME" => $model->d,
                   // "FD" => $model->fd,
                   // "CB" => $model->cb,
                   // "CE" => $model->ce,
                   "MODIFICATIONS" =>array()
                  );
               }
            }
         }         if(property_exists($result, "modificationList")){
            $modelsFapiT = $result->modificationList;
            if(property_exists($modelsFapiT, "m")){
               $modelsFapi = $modelsFapiT->m;
               foreach ($modelsFapi as $model) {
                  $arBrandsFapi[$model->mfi]["MODELS"][$model->mdi]["MODIFICATIONS"][$model->i] = array(
                  //    "I" => $model->i,                         
                  //    "MFI" => $model->mfi,
                  //    "MDI" => $model->mdi,
                   "NAME" => $model->d,
                   // "FD" => $model->fd,
                   // "d1" => $model->cb,
                   // "d2" => $model->ce,
                   "CB" => gmdate("d.m.Y",$model->cb/1000),
                   "CE" => gmdate("d.m.Y",$model->ce/1000)                      
                  );
               }
            }
         }
      
         $arBrandsCar = GetBrandsCarByCode($arBrandsCodes);
         $el = new CIBlockElement;
         $arItemProps = array(
            "PRIMENIMOST_BRAND_FAPI" => array(),
            "PRIMENIMOST_MODEL_FAPI" => array(),
            "PRIMENIMOST_MODIF_FAPI" => array()

         );
         foreach ($arBrandsFapi as $idFapi => $arBrandFapi) {
            if(isset($arBrandsCar[$arBrandFapi["NAME_SHORT"]])){
               $brandId = $arBrandsCar[$arBrandFapi["NAME_SHORT"]];
               $arItemProps["PRIMENIMOST_BRAND_FAPI"][] = $brandId;

               $arModelsNames = array();
               foreach ($arBrandFapi["MODELS"] as $key => $arModel){
                  $arModelsNames[] = $arModelName;                        
               }
               $arModels = GetModelsByNames($brandId,$arModelsNames);
               foreach ($arBrandFapi["MODELS"] as $key => $arModel){
                  $modelId  = array_search($arModel["NAME"], $arModels);
                  if($modelId === false){
                     $modelId = $el->Add(array(
                           "IBLOCK_ID" => 20,
                           "NAME" => $arModel["NAME"],                                                       
                           "PROPERTY_VALUES"=> array(
                              "CAR_BRAND" => $brandId
                           ),
                        ));                              
                        if($modelId>0){
                           $arItemProps["PRIMENIMOST_MODEL_FAPI"][] = $modelId;
                           foreach ($arModel["MODIFICATIONS"] as $arModif) {
                              $modifId = $el->Add(array(
                                 "IBLOCK_ID" => 21,
                                 "NAME" => $arModif["NAME"],
                                 "DATE_ACTIVE_FROM" => $arModif["CB"],
                                 "DATE_ACTIVE_TO" => $arModif["CE"],                              
                                 "PROPERTY_VALUES"=> array(
                                    "CAR_MODEL" => $modelId
                                 ),
                              ));   
                              if($modifId>0){
                                 $arItemProps["PRIMENIMOST_MODIF_FAPI"][] = $modifId;
                              }   
                           }
                        }
                  }
                  else{
                     $arItemProps["PRIMENIMOST_MODEL_FAPI"][] = $modelId;
                     $arModifNames = array();
                     foreach ($arModel["MODIFICATIONS"] as $arModif) {
                        $arModifNames[] = $arModif["NAME"];
                     }
                     $arModifs = GetModefsByNames($modelId,$arModifNames);
                     foreach ($arModel["MODIFICATIONS"] as $arModif) {
                        $modifId = array_search($arModif["NAME"], $arModifs);
                        if($modifId===false){
                           $modifId = $el->Add(array(
                                 "IBLOCK_ID" => 21,
                                 "NAME" => $arModif["NAME"],
                                 "DATE_ACTIVE_FROM" => $arModif["CB"],
                                 "DATE_ACTIVE_TO" => $arModif["CE"],                              
                                 "PROPERTY_VALUES"=> array(
                                    "CAR_MODEL" => $modelId
                                 ),
                              ));   
                              if($modifId>0){
                                 $arItemProps["PRIMENIMOST_MODIF_FAPI"][] = $modifId;
                                 $arModifs[$modifId] = $arModif["NAME"];
                              }   
                        }
                        else{
                           $arItemProps["PRIMENIMOST_MODIF_FAPI"][] = $modifId;
                        }
                     }
                  }                        
               }

            }
            else{
               $brandId = $el->Add(array(
                  "IBLOCK_ID" => 19,
                  "NAME" => $arBrandFapi["NAME"],
                  "CODE" => strtolower($arBrandFapi["NAME_SHORT"]),
                  "PROPERTY_VALUES"=> array(
                     "MFI" => $arBrandFapi["MFI"]
                  ),
               ));
               if($brandId>0){
                  $arItemProps["PRIMENIMOST_BRAND_FAPI"][] = $brandId;
                  foreach ($arBrandFapi["MODELS"] as $key => $arModel) {
                     $modelId = $el->Add(array(
                        "IBLOCK_ID" => 20,
                        "NAME" => $arModel["NAME"],                                                            
                        "PROPERTY_VALUES"=> array(
                           "CAR_BRAND" => $brandId
                        ),
                     ));      
                     if($modelId>0){
                        $arItemProps["PRIMENIMOST_MODEL_FAPI"][] = $modelId;
                        foreach ($arModel["MODIFICATIONS"] as $arModif) {
                           $modifId = $el->Add(array(
                              "IBLOCK_ID" => 21,
                              "NAME" => $arModif["NAME"],
                              "DATE_ACTIVE_FROM" => $arModif["CB"],
                              "DATE_ACTIVE_TO" => $arModif["CE"],                              
                              "PROPERTY_VALUES"=> array(
                                 "CAR_MODEL" => $modelId
                              ),
                           ));   
                           if($modifId>0){
                              $arItemProps["PRIMENIMOST_MODIF_FAPI"][] = $modifId;
                           }   
                        }
                     }
                     
                  }
               }
            }
         }
         $arItemProps["PRIMENIMOST_FAPI_FIND"] = 47;
         
         //формируем тестом применимость
         
         foreach ($arBrandsFapi as $arBrand) {
            foreach ($arBrand["MODELS"] as $arModel) {
               $sPrimenimost .=  "<b>".$arBrand["NAME"]." ".$arModel["NAME"]."</b><br> ";
               if(!empty($arModel["MODIFICATIONS"])){
                  $sPrimenimost .= "<ul>";
               }
               foreach ($arModel["MODIFICATIONS"] as $arModif) {
                  $sPrimenimost .= "<li><b>".$arModif["NAME"]."</b>. Дата выпуска: ".$arModif["CB"]."-".$arModif["CE"]."</li>";
               }
               if(!empty($arModel["MODIFICATIONS"])){
                  $sPrimenimost .="</ul>";
               }
               $sPrimenimost .="<br>";
            }
            $sPrimenimost .="<br>";
         }
         $arItemProps["PRIMENIMOST_FAPI_TEXT"] = array(
            "VALUE" =>array("TYPE"=>"HTML","TEXT"=>$sPrimenimost)
         );
         CIBlockElement::SetPropertyValuesEx($id, false, $arItemProps);
      }
      else{
         CIBlockElement::SetPropertyValuesEx($id, false, array("PRIMENIMOST_FAPI_FIND"=>47));   
      }
      
   }
   return $sPrimenimost;
}
Заполняем картинку
function ImageFapiFill($id='',$brandMfi='',$number=''){
   //картинка с Fapi
   $return = "";
   if(!empty($id) && !empty($brandMfi) && !empty($number) && CModule::IncludeModule("iblock")){
      $number = NewCatalogNumber($number);
      $result = GetImageFapi($brandMfi,$number);
      if(!empty($result) && ($result!= '400 Bad Request')){
         $fileName = $_SERVER["DOCUMENT_ROOT"]."/upload/fapi/".$id.".jpg";
         $fp = fopen($fileName, "w"); 
         fwrite($fp, $result);
         fclose($fp);
         $file = CFile::MakeFileArray($fileName);
         if(!empty($file)){
            $el = new CIBlockElement; 
            $res = $el->Update($id, array(                        
               "PREVIEW_PICTURE" => $file,
               "DETAIL_PICTURE" => $file,
            ));
            if($res){
               $return = $file["SRC"];
            }
            CIBlockElement::SetPropertyValuesEx($id, false, array("IMAGE_FAPI_FIND"=>46));
            
         }
      }
      else{
         CIBlockElement::SetPropertyValuesEx($id, false, array("IMAGE_FAPI_FIND"=>46));
      }
   }
   return $return;
}
Получаем аналоги (не с FAPI, не понравились аналоги с FAPI, заполняем аналоги из прайса поставщиков)
function GetProductsAnalog($filter = array(),$sectionId=false){
   $arProducts = array();
   if(!empty($filter)&& CModule::IncludeModule('iblock')){
      $arSelect = Array("ID","IBLOCK_ID","NAME","DETAIL_PAGE_URL","PROPERTY_CATALOG_NUMBER");
      $arFilter = Array(
         "IBLOCK_ID"=>14,                
         "PROPERTY_CATALOG_NUMBER" =>$filter
      );
      if($sectionId){
         $arFilter["SECTION_ID"] = $sectionId;
      }
      $res = CIBlockElement::GetList(Array("id"=>"asc"), $arFilter, false, Array("nPageSize"=>500,"iNumPage"=>1), $arSelect);   
      $arIds = array();
      while ($arProduct = $res->Fetch()) {
         $arProducts[$arProduct["ID"]]= $arProduct;
         $arIds[] = $arProduct["ID"];
      }
      if(!empty($arIds) && CModule::IncludeModule('catalog')){
         $db_res = CPrice::GetList(
              array(),
              array(
                   "PRODUCT_ID" => $arIds,               
               )
          );
         while($arPrice = $db_res->Fetch()){
             $arProducts[$arPrice["PRODUCT_ID"]]["PRICE"] = $arPrice["PRICE"];
         }
      }
   }
   return $arProducts;
}
Очищаем имя от кавычек
function NewName($name){
   $name = preg_replace("/&#?[a-z0-9]{2,8};/i","",$name); 
   $name = str_replace("quot;", " ", $name);
   $name = str_replace("  ", " ", $name);
   return $name;
}
Итоговая функция, которая запускает все остальные
function SetNewName($id){   
   if(CModule::IncludeModule("iblock")){
      $arSelect = Array("ID", "NAME", "PROPERTY_BRAND", "PROPERTY_CATALOG_NUMBER","PROPERTY_IMAGE_FAPI_FIND");
      $arFilter = Array("IBLOCK_ID"=>14, "ID"=>$id);
      $res = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>1), $arSelect);
      if($arFields = $res->Fetch()){                              
         $newName = NewName($arFields["NAME"]);
         
         $arFields["PROPERTY_CATALOG_NUMBER_VALUE"] = NewCatalogNumber($arFields["PROPERTY_CATALOG_NUMBER_VALUE"]);
         $file = "";
         
         if($arFields["PROPERTY_BRAND_VALUE"] > 0){
            $arSelect = Array("ID", "NAME","PROPERTY_MFI");
            $arFilter = Array("IBLOCK_ID"=>9, "ID"=>$arFields["PROPERTY_BRAND_VALUE"]);
            $res1 = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>1), $arSelect);
            if($arBrand = $res1->Fetch()){                                       
               if(strpos(strtoupper($newName), strtoupper($arBrand["NAME"])) === false){         
                  $newName .= " ".$arBrand["NAME"];                     
               }
               
               ImageFapiFill($id,$arBrand["PROPERTY_MFI_VALUE"],$arFields["PROPERTY_CATALOG_NUMBER_VALUE"]);       
               PrimenimostFapiFill($id,$arBrand["PROPERTY_MFI_VALUE"],$arFields["PROPERTY_CATALOG_NUMBER_VALUE"]);    

            }
         }
         if(($arFields["PROPERTY_CATALOG_NUMBER_VALUE"] != '') && (strpos(strtoupper($newName) , strtoupper($arFields["PROPERTY_CATALOG_NUMBER_VALUE"])) === false)){
            $newName .= " ".$arFields["PROPERTY_CATALOG_NUMBER_VALUE"];
            $arParams = array( "replace_space" => "-", "replace_other" => "-" );         
            $code = Cutil::translit( $arProp["VALUE"], "ru", $arParams );
         }   
         $arFieldsNew = array();                        
         if($newName != $arFields["NAME"]){
            $arFieldsNew["NAME"] = $newName;
         }
         if($code!=''){
            $arFieldsNew["CODE"] = $code;
         }

         if(!empty($arFieldsNew)){
            $el = new CIBlockElement;             
            $el->Update($id, $arFieldsNew);       
         }            
      }      
   }
}