diff --git a/.gitignore b/.gitignore index 37b8f6d..8c2145a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ vizitka/tmp/ vkteamssetup.exe local/*.json local/*.txt +local/*.xml local/commands/ !local/sitemap.php -element*.txt \ No newline at end of file +element*.txt +drom*.xml \ No newline at end of file diff --git a/api/index.php b/api/index.php index efa531f..234fa80 100644 --- a/api/index.php +++ b/api/index.php @@ -3,6 +3,8 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_be header('Content-Type: application/json; charset=utf-8'); use \Bitrix\Main\Service\GeoIp; +use \Bitrix\Main\Grid\Declension; + $httpClient = new \Bitrix\Main\Web\HttpClient(); $PARAM_1 = isset($_REQUEST["PARAM_1"]) ? $_REQUEST["PARAM_1"] : null; @@ -1360,6 +1362,40 @@ switch($PARAM_1) $filter['>=PROPERTY_RESERVE_DATE'] = date("Y-m-d"); + } + else + { + array_push($filter, [ 'LOGIC' => 'OR', [ '=PROPERTY_RESERVE_DATE' => false ], [ ' date("Y-m-d") ]]); + } + + //$filter['=PROPERTY_RESERVE_DATE'] = false; + } + + if(!empty($REQ['PTS'])) + { + $filter['PROPERTY_PTS_VALUE'] = $REQ['PTS'] === "DIGITAL" ? "ЭПТС" : "Бумажный ПТС"; + } + + if(!empty($REQ['RESTRICTIONS'])) + { + $filter['PROPERTY_RESTRICTIONS_VALUE'] = $REQ['RESTRICTIONS'] === "YES" ? "Есть ограничения ФССП" : "Нет ограничений ФССП"; + } + + if(isset($REQ['KEYS'])) + { + $filter['PROPERTY_KEY_COUNT'] = $REQ['KEYS']; + } + + if(isset($REQ['AFTER_ACCIDENT'])) + { + $filter['PROPERTY_AFTER_ACCIDENT_VALUE'] = $REQ['AFTER_ACCIDENT'] == "YES" ? "Да" : "Нет"; + } + $total = CIBlockElement::GetList([ "SORT" => "ASC", "NAME" => "ASC" ], array_merge([ "IBLOCK_ID" => USED ? IBLOCK_ID_CATALOG_CARS_USED : IBLOCK_ID_CATALOG_CARS_NEW ], $filter), [], false, []); $result = [ "total" => $total, @@ -1369,7 +1405,12 @@ switch($PARAM_1) $vehicle_types = []; $vehicle_subtypes = []; $cities = []; - + $restrictions = []; + $pts = []; + $keys = []; + $reserved = []; + $condition = []; + $brands = []; $models = []; $modifications = []; @@ -1397,6 +1438,21 @@ switch($PARAM_1) if(USED) { + $flags = []; + $flag_names = [ "PTS" => [], "RESTRICTIONS" => [], "AFTER_ACCIDENT" => [] ]; + + foreach($flag_names AS $k => $f) + { + $properties = CIBlockPropertyEnum::GetList([ "sort" => "asc", "name" => "asc" ], [ "IBLOCK_ID" => IBLOCK_ID_CATALOG_CARS_USED, "CODE" => $k ]); + while ($prop_fields = $properties->GetNext()) + { + $flags[ $k ][ $prop_fields["ID"] ] = [ + "value" => $prop_fields['XML_ID'], + "label" => $prop_fields['VALUE'], + ]; + } + } + //filter for types $filter_vehicle_types = $filter; unset($filter_vehicle_types['PROPERTY_VEHICLE_TYPE']); @@ -1494,9 +1550,112 @@ switch($PARAM_1) //print_r($row[ PROPERTY_ID_CATALOG_CARS_USED_PARKING_CITY ]); array_push($cities, $row[ PROPERTY_ID_CATALOG_CARS_USED_PARKING_CITY ]); } - //print "\n\ncities\n\n"; - //print_r($cities); - //die(); + + //filter for restrictions + $filter_restrictions = $filter; + unset($filter_restrictions['PROPERTY_RESTRICTIONS_VALUE']); + + $restrictions_values = []; + $iterator = CIBlockElement::GetPropertyValues( IBLOCK_ID_CATALOG_CARS_USED, $filter_restrictions, true, [ 'ID' => [ PROPERTY_ID_CATALOG_CARS_USED_RESTRICTIONS ] ] ); + while ($row = $iterator->Fetch()) + { + array_push($restrictions_values, $row[ PROPERTY_ID_CATALOG_CARS_USED_RESTRICTIONS ]); + } + $restrictions_values = array_unique($restrictions_values); + foreach($restrictions_values AS $rv) + { + array_push($restrictions, $flags['RESTRICTIONS'][ $rv ]); + } + + //filter for pts + $filter_pts = $filter; + unset($filter_pts['PROPERTY_PTS_VALUE']); + + $pts_values = []; + $iterator = CIBlockElement::GetPropertyValues( IBLOCK_ID_CATALOG_CARS_USED, $filter_pts, true, [ 'ID' => [ PROPERTY_ID_CATALOG_CARS_USED_PTS ] ] ); + while ($row = $iterator->Fetch()) + { + array_push($pts_values, $row[ PROPERTY_ID_CATALOG_CARS_USED_PTS ]); + } + $pts_values = array_unique($pts_values); + foreach($pts_values AS $rp) + { + array_push($pts, $flags['PTS'][ $rp ]); + } + + //filter for reserved + $filter_reserved = $filter; + unset($filter_reserved['PROPERTY_RESERVE_DATE_VALUE']); + unset($filter_reserved['>=PROPERTY_RESERVE_DATE']); + unset($filter_reserved['=PROPERTY_RESERVE_DATE']); + unset($filter_reserved['!=PROPERTY_RESERVE_DATE']); + unset($filter_reserved[' [ PROPERTY_ID_CATALOG_CARS_USED_RESERVE_DATE ] ] ); + while ($row = $iterator->Fetch()) + { + array_push($reserved_values, $row[ PROPERTY_ID_CATALOG_CARS_USED_RESERVE_DATE ]); + } + + $reserved = [ [ "value" => "NO", "label" => "Не в резерве", ] ]; + foreach($reserved_values AS $rv) + { + if($rv >= date("Y-m-d")) + { + array_push($reserved, [ "value" => "YES", "label" => "В резерве", ]); + break; + } + } + + //filter for keys + $filter_key_count = $filter; + unset($filter_key_count['PROPERTY_KEY_COUNT']); + + $key_count_values = []; + $iterator = CIBlockElement::GetPropertyValues( IBLOCK_ID_CATALOG_CARS_USED, $filter_key_count, true, [ 'ID' => [ PROPERTY_ID_CATALOG_CARS_USED_KEY_COUNT ] ] ); + while ($row = $iterator->Fetch()) + { + array_push($key_count_values, $row[ PROPERTY_ID_CATALOG_CARS_USED_KEY_COUNT ]); + } + $key_count_values = array_unique($key_count_values); + sort($key_count_values); + + $dec = new Declension('ключ', 'ключа', 'ключей'); + foreach($key_count_values AS $kc) + { + array_push($keys, [ "value" => $kc, "label" => $kc == 0 ? "Нет ключей" : $kc." ".$dec->get($kc), ]); + } + + //filter for condition + $filter_condition = $filter; + unset($filter_condition['PROPERTY_AFTER_ACCIDENT_VALUE']); + + $condition_values = []; + $iterator = CIBlockElement::GetPropertyValues( IBLOCK_ID_CATALOG_CARS_USED, $filter_condition, true, [ 'ID' => [ PROPERTY_ID_CATALOG_CARS_USED_AFTER_ACCIDENT ] ] ); + while ($row = $iterator->Fetch()) + { + array_push($condition_values, $row[ PROPERTY_ID_CATALOG_CARS_USED_AFTER_ACCIDENT ]); + } + + $f = [ "NO" => "Кроме битых", "YES" => "Битые/не на ходу", ]; + $condition_values = array_unique($condition_values); + foreach($condition_values AS $cv) + { + $option = $flags['AFTER_ACCIDENT'][ $cv ]; + $option['label'] = $f[$option['value']]; + + array_push($condition, $option); + } } //filter for brands @@ -1723,6 +1882,13 @@ switch($PARAM_1) $result["cities"] = $cities; $result["years"] = $years; $result["mileages"] = $mileages; + + $result["pts"] = $pts; + $result["keys"] = $keys; + $result["restrictions"] = $restrictions; + $result['reserved'] = $reserved; + $result['condition'] = $condition; + if(USED) { $result["bitrix_mileages"] = $bitrix_mileages; diff --git a/bitrix/php_interface/classes/drom/DromXMLGenerator.php b/bitrix/php_interface/classes/drom/DromXMLGenerator.php new file mode 100644 index 0000000..cc49d5f --- /dev/null +++ b/bitrix/php_interface/classes/drom/DromXMLGenerator.php @@ -0,0 +1,634 @@ + [], + "bus" => [], + "motorhome" => [], + "mobile_crane" => [], + "bulldozer" => [], + "atv" => [], + "truck" => [], + "building" => [], + "misc" => [], + "municipal" => [], + "forestry" => [], + "loader" => [], + "semi_trailer" => [], + "trailer" => [], + "truck_tractor" => [], + "tractor" => [], + "excavator" => [], + ]; + protected $special_frames_mapping = [ + "BUS" => "bus", + "TRUCK" => "truck", + "TRUCK_TRACTOR" => "truck_tractor", + "MOTORHOME" => "motorhome", + "BUILDING" => "building", + "CRANE" => "mobile_crane", + "LOADER" => "loader", + "TRAILER" => "trailer", + "SEMITRAILER" => "semi_trailer", + "EXCAVATOR" => "excavator", + "FARM" => "tractor", + "MISC" => "misc", + "FORESTRY" => "forestry", + "MUNICIPAL" => "municipal", + "ATV" => "atv", + "BULLDOZER" => "bulldozer", + "QUADBIKE" => "atv", + "SNOWMOBILE" => "atv", + "SCOOTER" => "misc", + ]; + protected $special_frames = []; + + protected $xml_cars = null; + protected $xml_special = null; + protected $offers_cars = null; + protected $offers_special = null; + protected $total = 0; + protected $found_cars = 0; + protected $found_special = 0; + protected $valid_cars = 0; + protected $valid_special = 0; + protected $invalid_special = 0; + protected $not_found_special = 0; + protected $p1 = 0; + protected $p2 = 0; + protected $p3 = 0; + protected $p4 = 0; + + protected $fuels = [ + "БЕНЗИН" => "GASOLINE", + "ГАЗ" => "GAS", + "ДИЗЕЛЬ" => "DIESEL", + "ЭЛЕКТРИЧЕСКИЙ" => "ELECTRICITY", + ]; + + protected $errors = ""; + + function __construct() + { + $this->xml_cars = new SimpleXMLElement(""); + $this->offers_cars = $this->xml_cars->addChild('Offers'); + + $this->xml_special = new SimpleXMLElement(""); + $this->offers_special = $this->xml_special->addChild('SpecOffers'); + + $this->loadTypes(); + + foreach($this->dictionaries AS $type => $v) + { + $structure = [ + "brands" => [], + "models" => [], + "cities" => [], + "bodies" => [], + "colors" => [], + "transmissions" => [], + "engines" => [], + "wheels" => [], + "fuels" => [], + ]; + + $url = "https://www.drom.ru/cached_files/autoload/files/"; + if($type === "car") + { + $url = $url."ref.xml"; + } + else + { + $url = $url."ref_".$type.".xml"; + } + + $response_xml = file_get_contents($url); + file_put_contents("/home/bitrix/www/local/ref_".$type.".xml", $response_xml); + + $structure_object = new SimpleXMLElement($response_xml); + + foreach($structure_object->MarksSpec->MarkSpec AS $mark) + { + $k = mb_strtoupper((string) $mark->sMarkSpec); + $n = (int) $mark->idMarkSpec; + + $models = []; + foreach($structure_object->ModelsSpec->ModelSpec AS $model) + { + $mmn = (int) $model->idMarkSpec; + + if($mmn === $n) + { + $km = mb_strtoupper((string) $model->sModelSpec); + $nm = (int) $model->idModelSpec; + + $models[ $km ] = $nm; + $structure['models'][ $km ] = $nm; + } + } + + $structure['brands'][ $k ] = [ "id" => $n, "models" => $models ]; + } + + foreach($structure_object->Marks->Mark AS $mark) + { + $k = mb_strtoupper((string) $mark->sMark); + $n = (int) $mark->idMark; + + $models = []; + foreach($structure_object->Models->Model AS $model) + { + $mmn = (int) $model->idMark; + + if($mmn === $n) + { + $km = mb_strtoupper((string) $model->sModel); + $nm = (int) $model->idModel; + + $models[ $km ] = $nm; + } + } + + $structure['brands'][ $k ] = [ "id" => $n, "models" => $models ]; + } + + foreach($structure_object->Cities->City AS $city) + { + $k = mb_strtoupper((string) $city->sCity); + $n = (int) $city->idCity; + + $structure['cities'][ $k ] = $n; + } + + foreach($structure_object->FrameTypes->FrameType AS $frame_type) + { + $k = mb_strtoupper((string) $frame_type->sFrameType); + $n = (int) $frame_type->idFrameType; + + $structure['bodies'][ $k ] = $n; + } + + foreach($structure_object->Colors->Color AS $color) + { + $k = mb_strtoupper((string) $color->sColor); + $n = (int) $color->idColor; + + $structure['colors'][ $k ] = $n; + } + + foreach($structure_object->WheelFormulaTypes->WheelFormulaType AS $wheel_type) + { + $k = mb_strtoupper((string) $wheel_type->sWheelFormulaType); + $n = (int) $wheel_type->idWheelFormulaType; + + $structure['wheels'][ $k ] = $n; + } + + foreach($structure_object->EngineTypesSpec->EngineTypeSpec AS $engine_type) + { + $k = mb_strtoupper((string) $engine_type->sEngineTypeSpec); + $n = (int) $engine_type->idEngineTypeSpec; + + $structure['fuels'][ $k ] = $n; + } + + $this->dictionaries[ $type ] = $structure; + } + } + + function addOffer($entry) + { + $this->total++; + + $type = $entry['PROPERTIES']['VEHICLE_SUBTYPE']['VALUE']; + //print $type."\n"; + + if($type === "Легковой автомобиль") + { + $this->found_cars++; + $this->buildOffer(false, [ 'group' => 'car' ], $entry); + + /* + $idMark = $this->getDictionaryRecordId($this->dictionaries['car']['brands'], mb_strtoupper($entry['PROPERTIES']['BRAND']['RELATED']['NAME'])); + //print $entry['CODE']." - ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']." - ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']." - [".$idMark."] - [".$idModel."]\n"; + //if(is_null($idMark)) { $this->errors .= "Не найдена марка ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']."\n"; continue; } + + if($idMark !== null) + { + //* id марки авто (см. файл-справочник); если не можете указать id, то укажите название марки текстом в поле sMark + $offer['idMark'] = $idMark; + } + else + { + //* название марки авто (Toyota, Honda, BMW и т.п.); указывать обязательно только в том случае, если не можете указать idMark + $offer['sMark'] = $entry['PROPERTIES']['BRAND']['RELATED']['NAME']; + } + + $idModel = $this->getDictionaryRecordId($this->dictionaries['car']['models'], mb_strtoupper($entry['PROPERTIES']['MODEL']['RELATED']['NAME'])); + //if(is_null($idModel)) { $this->errors .= "Не найдена модель ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']." для ".".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']."."\n"; continue; } + if($idModel !== null) + { + //* id модели авто (см. файл-справочник); если не можете указать id, то укажите название модели текстом в поле sModel + $offer['idModel'] = $idModel; + } + else + { + //* название модели авто (Land Cruiser, Accord, X5 и т.п.); указывать обязательно только в том случае, если не можете указать idModel + $offer['sModel'] = $entry['PROPERTIES']['MODEL']['RELATED']['NAME']; + } + */ + + /* + $payload = [ + "idOffer" => $entry['CODE'], //* уникальный id объявления в вашей базе данных + "idMark" => "", //* id марки авто (см. файл-справочник); если не можете указать id, то укажите название марки текстом в поле sMark + "idModel" => "", //* id модели авто (см. файл-справочник); если не можете указать id, то укажите название модели текстом в поле sModel + "sMark" => "", //* название марки авто (Toyota, Honda, BMW и т.п.); указывать обязательно только в том случае, если не можете указать idMark + "sModel" => "", //* название модели авто (Land Cruiser, Accord, X5 и т.п.); указывать обязательно только в том случае, если не можете указать idModel + "idCountry" => "", //id страны, где находится авто (см. файл-справочник, по умолчанию — 0) + "idCity" => "", //id города, в котором находится авто (см. файл-справочник) + "sCity" => "", //название города, в котором находится авто (см. файл-справочник) + "YearOfMade" => "", //год выпуска ТС (только год, 4 цифры: 1995, 2003, 2018 и т.п.) + "VIN" => $entry['PROPERTIES']['VIN']['VALUE'], //* VIN или номер кузова, если VIN отсутствует + "Price" => $entry['PROPERTIES']['PRICE']['VALUE'], //цена в рублях + "NewType" => 0, //признак, что автомобиль новый; 1 — новый, 0 — не новый (с пробегом) + "Volume" => $entry['PROPERTIES']['ENGINE_VOLUME']['VALUE'], //объем двигателя в куб.см (пример: 599, 1300, 2631 и т.п.) + "FrameType" => "???", //тип кузова (см. файл-справочник) + "Color" => "???", //цвет кузова (см. файл-справочник) + "idTransmission" => "???", //id типа трансмиссии (см. файл-справочник) + "sTransmission" => "???", //название типа трансмиссии + "idEngineType" => "", //id типа двигателя (см. файл-справочник) + "sEngineType" => "", //название типа двигателя + "idHybridType" => "", //гибрид (см. файл-справочник) + "sHybridType" => "", //гибрид (да, нет) + "idGbo" => "", //ГБО (см. файл-справочник) + "sGbo" => "", //ГБО (да, нет) + "idDriveType" => "???", //id типа двигателя (см. файл-справочник) + "sDriveType" => "", //название типа двигателя + "sWheelType" => "", //положение руля (левый, правый) + "Haul" => "", //пробег (показания одометра в километрах) + "sComplectation" => "", //название комплектации (в соответствии с каталогом) + "idComplectation" => "", //id комплектации на Дроме (в соответствии с каталогом) + "Additional" => "", //текстовое описание ТС (комплектация, оснащение, тюнинг и т.п.), здесь можно указать сссылку на видео, размещенное на YouTube + "Photos" => "", //секция со списком фотографий (ниже есть подробное описание секции) + "Phone" => "", //номер телефона (поле не должно быть больше 20 символов) + "Whereabouts" => "", //авто в наличии или под заказ (см. файл-справочник) + "Power" => $entry['PROPERTIES']['ENGINE_POWER']['VALUE'], //мощность автомобиля в лошадиных силах + "idCertProgram" => "", //программа сертификации (см. файл-справочник) + "DamagedType" => "", //признак для поврежденных автомобилей (0 - небитые, 1 - битые или не на ходу) + "SOR" => "", //номер свидетельства о регистрации ТС для авто с пробегом (10 символов) + ]; + */ + } + else + { + $this->found_special++; + + $frame = $this->getFrameType(mb_strtoupper($type), mb_strtoupper($entry['PROPERTIES']['MODEL']['RELATED']['NAME'])); + + if(!is_null($frame)) + { + $this->buildOffer(true, $frame, $entry); + } + else + { + $this->invalid_special++; + print $this->invalid_special." НЕ УДАЛОСЬ ОПРЕДЕЛИТЬ ТИП: ".mb_strtoupper($type)." \t\t[ ".$entry['CODE']." ][ ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']." ][ ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']." ]\n"; + + //$this->not_found_special++; + } + } + } + + private function buildOffer($special = false, $frame, $entry) + { + //print $entry['CODE']." - ".$type."\n"; + + $payload = [ + "idOffer" => $entry['CODE'], //* уникальный id объявления в вашей базе данных + "YearOfMade" => $entry['PROPERTIES']['YEAR']['VALUE'], //год выпуска ТС (только год, 4 цифры: 1995, 2003, 2018 и т.п.) + "VIN" => $entry['PROPERTIES']['VIN']['VALUE'], //* VIN или номер кузова, если VIN отсутствует + "Price" => $entry['PROPERTIES']['PRICE']['VALUE'], //цена в рублях + "NewType" => 0, //признак, что автомобиль новый; 1 — новый, 0 — не новый (с пробегом) + "Volume" => $entry['PROPERTIES']['ENGINE_VOLUME']['VALUE'], //объем двигателя в куб.см (пример: 599, 1300, 2631 и т.п.) + "Power" => $entry['PROPERTIES']['ENGINE_POWER']['VALUE'], //мощность автомобиля в лошадиных силах + ]; + + if($special) + { + $payload['idFrameTypeSpec'] = $frame['id']; + $payload['idWheelType'] = 2; + + if(in_array($frame['group'], [ "bus", "motorhome" ])) + { + $this->invalid_special++; + print $this->invalid_special." НЕВОЗМОЖНО УКАЗААТЬ DriveTypeSpec: ".$entry['CODE']." ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']." ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']."\n"; + return; + } + + if(in_array($frame['group'], [ "trailer", "semi_trailer" ])) + { + $this->invalid_special++; + print $this->invalid_special." НЕВОЗМОЖНО УКААЗАТЬ КОЛИЧЕСТВО ОСЕЙ Axles: ".$entry['CODE']." ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']." ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']."\n"; + return; + } + + if(in_array($frame['group'], [ "truck", "truck_tractor", "mobile_crane", "municipal", ])) + { + $item_name = str_replace("Х", "X", mb_strtoupper($entry['PROPERTIES']['MODEL']['RELATED']['NAME'])); + preg_match('/\dX\d/', $item_name, $wheel_type_matches); + + $idWheelFormulaType = $this->getDictionaryRecordId($this->dictionaries[ $frame['group'] ]['wheels'], $wheel_type_matches[0]); + if(!is_null($idWheelFormulaType)) + { + $payload['idWheelFormulaType'] = $idWheelFormulaType; + } + else + { + $this->invalid_special++; + print $this->invalid_special." НЕТ КОЛЕСНОЙ ФОРМУЛЫ: ".$entry['CODE']." - ".$item_name." [".$wheel_type_matches[0]."]\n"; + return; + } + } + + if(in_array($frame['group'], [ "bus", "truck", "truck_tractor", "mobile_crane", "loader", "municipal", "atv", "motorhome" ])) + { + if(!empty($entry['PROPERTIES']['ENGINE_FUEL']['VALUE'])) + { + $f = mb_strtoupper($entry['PROPERTIES']['ENGINE_FUEL']['VALUE']); + if(isset($this->fuels[$f])) + { + $idEngineTypeSpec = $this->getDictionaryRecordId($this->dictionaries[ $frame['group'] ]['fuels'], $this->fuels[$f]); + + if(!is_null($idEngineTypeSpec)) + { + $payload['idEngineTypeSpec'] = $idEngineTypeSpec; + } + } + } + } + } + + if($special) + { + $patterns = array('/\s\dX\d/i', '/\s\dХ\d/i', '/САМОСВАЛ/i'); + $replacements = array('', '', ''); + $model_name = preg_replace($patterns, $replacements, mb_strtoupper($entry['PROPERTIES']['MODEL']['RELATED']['NAME'])); + $model_name = ltrim(rtrim($model_name)); + + $model_name_chunks = explode(" ", $model_name); + array_unshift($model_name_chunks, implode('', $model_name_chunks)); + + $idModel = null; + foreach($model_name_chunks AS $c) + { + $idModel = $this->getDictionaryRecordId($this->dictionaries[ $frame['group'] ]['models'], $c); + if(!is_null($idModel)) + { + break; + } + } + + if(!is_null($idModel)) + { + $payload['idModelSpec'] = $idModel; + } + else + { + $this->invalid_special++; + print $this->invalid_special." НЕВОЗМОЖНО ОПРЕДЕЛИТЬ МОДЕЛЬ ДЛЯ МАРКИ ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME'].": ".$entry['CODE']." - ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']."\n"; + + return; + } + } + else + { + $idMark = $this->findInDictionaryRecordId($this->dictionaries[ $frame['group'] ]['brands'], mb_strtoupper($entry['PROPERTIES']['BRAND']['RELATED']['NAME'])); + //print $type." - ".$frame['group']." - ".$idMark['id']."\n"; + + if(!is_null($idMark)) + { + if(!$special) { $payload['idMark'] = $idMark['id']; } + $this->p1++; + + $patterns = array('/\s\dX\d/i', '/\s\dХ\d/i', '/САМОСВАЛ/i'); + $replacements = array('', '', ''); + $model_name = preg_replace($patterns, $replacements, mb_strtoupper($entry['PROPERTIES']['MODEL']['RELATED']['NAME'])); + $model_name = ltrim(rtrim($model_name)); + + $model_name_chunks = explode(" ", $model_name); + array_unshift($model_name_chunks, implode('', $model_name_chunks)); + + $idModel = null; + foreach($model_name_chunks AS $c) + { + $idModel = $this->getDictionaryRecordId($this->dictionaries[ $frame['group'] ]['brands'][ mb_strtoupper($entry['PROPERTIES']['BRAND']['RELATED']['NAME']) ]['models'], $c); + if(!is_null($idModel)) + { + $idModel = $this->findInDictionaryRecordId($this->dictionaries[ $frame['group'] ]['brands'][ mb_strtoupper($entry['PROPERTIES']['BRAND']['RELATED']['NAME']) ]['models'], mb_strtoupper($c)); + if(!is_null($idModel)) + { + break; + } + } + } + + if(!is_null($idModel)) + { + $payload['idModel'] = $idModel; + } + else + { + $payload['sModel'] = $model_name; + } + } + else + { + $this->p2++; + + if(!$special) + { + $payload['sMark'] = $entry['PROPERTIES']['BRAND']['RELATED']['NAME']; + $payload['sModel'] = $entry['PROPERTIES']['MODEL']['RELATED']['NAME']; + } + else + { + $this->invalid_special++; + print $this->invalid_special." НЕВОЗМОЖНО ОПРЕДЕЛИТЬ МАРКУ: ".$entry['CODE']." (ТИП ".$frame['group'].") - ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']." ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']."\n"; + + return; + } + + //print $entry['PROPERTIES']['BRAND']['RELATED']['NAME']."\n"; + } + } + + $idCity = $this->getDictionaryRecordId($this->dictionaries[ $frame['group'] ]['cities'], mb_strtoupper($entry['PROPERTIES']['PARKING_CITY']['VALUE'])); + if($idCity !== null) + { + //* id города, в котором находится авто (см. файл-справочник) + $payload['idCity'] = $idCity; + } + else + { + if(!$special) + { + //* название города, в котором находится авто (см. файл-справочник) + $payload['sCity'] = $entry['PROPERTIES']['PARKING_CITY']['VALUE']; + } + else + { + $this->invalid_special++; + + print $this->invalid_special." НЕВОЗМОЖНО ОПРЕДЕЛИТЬ ГОРОД: ".$entry['CODE']." ".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']." ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']."\n"; + return; + } + + //if(is_empty($idModel)) { $this->errors .= "Не найдена модель ".$entry['PROPERTIES']['MODEL']['RELATED']['NAME']." для ".".$entry['PROPERTIES']['BRAND']['RELATED']['NAME']."."\n"; continue; } + } + + //"idCountry" => "", //id страны, где находится авто (см. файл-справочник, по умолчанию — 0) + //"idCity" => "", //id города, в котором находится авто (см. файл-справочник) + //"sCity" => "", //название города, в котором находится авто (см. файл-справочник) + + if($special) + { + $this->valid_special++; + } + else + { + $this->valid_cars++; + } + + $offer = $special ? $this->offers_special->addChild('SpecOffer') : $this->offers_cars->addChild('Offer'); + foreach($payload AS $k => $v) + { + $offer->addChild($k, $v); + } + + if(count($entry['PHOTOS_1080']) > 0) + { + $photos = $offer->addChild("Photos"); + $photos->addAttribute('PhotoMain', "https://".SITE_SERVER_NAME.$entry['PHOTOS_1080'][0]); + + foreach($entry['PHOTOS_1080'] AS $photo) + { + $photos->addChild("Photo", "https://".SITE_SERVER_NAME.$photo); + } + } + + //print $type." MATCH"."\n"; + } + + private function normalize_string($str) + { + return str_replace(["Ё", "C"], ["Е", "С"], $str); + } + + private function getFrameType($type, $model) + { + if($type === "ПРИЦЕП") { $type = "ДРУГИЕ ПРИЦЕПЫ"; } + if($type === "ТЯГАЧ") { $type = "СЕДЕЛЬНЫЙ ТЯГАЧ"; } + + if(isset($this->special_frames[ $type ])) + { + return $this->special_frames[ $type ]; + } + else + { + $found = []; + + foreach($this->special_frames AS $k => $v) + { + if(strpos($this->normalize_string($model), $k) > -1) + { + $found[ strlen($k) ] = $this->special_frames[ $k ]; + } + } + + if(count($found) > 0) + { + krsort($found); +// print_r($found); + + foreach($found AS $f) + { + return $f; + } +// return $found[0]; + } + } + + //print "[".$this->normalize_string(mb_strtoupper($k))."] <---\n"; + return null; + } + + private function getDictionaryRecordId($branch, $name) + { + if(isset($branch[ $name ])) + { + return $branch[ $name ]; + } + + return null; + } + + private function findInDictionaryRecordId($branch, $name) + { + foreach($branch AS $k => $v) + { + if(strpos($name, $k) > -1) + { + return $v; + } + } + + return null; + } + + function save() + { + if($this->total > 0) + { + print "ИТОГО: валидно ".$this->valid_cars + $this->valid_special." из ".$this->total." - ".number_format(($this->valid_cars + $this->valid_special) / (($this->found_cars + $this->found_special) / 100), 2, ".")."%\n"; + + if($this->found_cars > 0) + { + print "ЛКТ: валидно ".$this->valid_cars." из ".$this->found_cars." - ".number_format($this->valid_cars / ($this->found_cars / 100), 2, ".")."%\n"; + } + if($this->found_special > 0) + { + print "СПЕЦТЕХНИКА: валидно ".$this->valid_special." из ".$this->found_special." - ".number_format($this->valid_special / ($this->found_special / 100), 2, ".")."%\n"; + } + + file_put_contents("/home/bitrix/www/drom-offers.xml", $this->xml_cars->asXML()); + file_put_contents("/home/bitrix/www/drom-offers-special.xml", $this->xml_special->asXML()); + } + } + + private function loadTypes() + { + $types_url = "https://www.drom.ru/cached_files/autoload/files/ref_frame_types.xml"; + $response_types_xml = file_get_contents($types_url); + file_put_contents("/home/bitrix/www/local/ref_frame_types.xml", $response_types_xml); + + $types_object = new SimpleXMLElement($response_types_xml); + foreach($types_object AS $group => $branch) + { + foreach($branch AS $spec) + { + $g = (string) $group; + $k = (string) $spec->sFrameTypeSpec; + $n = (int) $spec->idFrameTypeSpec; + + //print $g." - ".$k."\n"; + $this->special_frames[ mb_strtoupper($k) ] = [ + "group" => $this->special_frames_mapping[ $g ], + "id" => $n, + ]; + } + } + } +} \ No newline at end of file diff --git a/bitrix/php_interface/init.php b/bitrix/php_interface/init.php index e5c59fc..55b2326 100644 --- a/bitrix/php_interface/init.php +++ b/bitrix/php_interface/init.php @@ -680,4 +680,32 @@ function OnBeforeIBlockElementUpdateHandler(&$arFields) return true; } +AddEventHandler("search", "BeforeIndex", "OnBeforeIBlockElement"); + +function OnBeforeIBlockElement($arFields) +{ + if($arFields['MODULE_ID'] == "iblock" && $arFields['PARAM2'] == IBLOCK_ID_CATALOG_CARS_USED) + { + file_put_contents($_SERVER['DOCUMENT_ROOT']."/element_index_".$arFields['PARAM2'].".txt", var_export($arFields, true)."\n", FILE_APPEND); + + if(array_key_exists("BODY", $arFields)) + { + preg_match("/CODE\=(\d+_\d+)/", $arFields['URL'], $matches); + $code = $matches[1]; + + if(!empty($code)) + { + if(strpos($arFields["BODY"], $code) < 0) + { + $arFields["BODY"] .= " ".$code; + } + file_put_contents($_SERVER['DOCUMENT_ROOT']."/element_index_".$arFields['PARAM2'].".txt", "CODE = ".$code."\n", FILE_APPEND); + } + } + file_put_contents($_SERVER['DOCUMENT_ROOT']."/element_index_".$arFields['PARAM2'].".txt", "\n".str_repeat("-", 150)."\n\n", FILE_APPEND); + } + + return $arFields; +} + ?> \ No newline at end of file diff --git a/local/components/evolution/form.catalog.filter/templates/.default/script.js b/local/components/evolution/form.catalog.filter/templates/.default/script.js index c368649..fc4404b 100644 --- a/local/components/evolution/form.catalog.filter/templates/.default/script.js +++ b/local/components/evolution/form.catalog.filter/templates/.default/script.js @@ -702,6 +702,227 @@ function updateCounter(parameters, reset = false) $(".filter_mileage_to").append(''); $(".filter_mileage_to").attr("disabled", "disabled"); } + + if(response.pts !== undefined) + { + if(response.pts.length > 0) + { + var current = $(".filter_pts").val(); + $(".filter_pts").empty(); + + if(!reset && current !== "" && current !== null) + { + $(".filter_pts").append(''); + } + else + { + $(".filter_pts").append(''); + } + + for(let i in response.pts) + { + $(".filter_pts").append(''); + } + + if(!loaded) + { + if(selected['PTS'] !== undefined && selected['PTS'] !== null && selected['PTS'] !== "") + { + $(".filter_pts").val(selected['PTS']); + $(".filter_pts").find("option").first().text("Не важно").attr("disabled", false); + } + } + else + { + $(".filter_pts").val(reset ? "" : current); + } + } + else + { + $(".filter_pts").empty(); + $(".filter_pts").append(''); + $(".filter_pts").attr("disabled", "disabled"); + } + } + + //updateSelectFromArray({ dom_node: "restrictions", option: "RESTRICTIONS", default: "Ограничения", reset: "Не важно", }); + if(response.restrictions !== undefined) + { + if(response.restrictions.length > 0) + { + var current = $(".filter_restrictions").val(); + $(".filter_restrictions").empty(); + + if(!reset && current !== "" && current !== null) + { + $(".filter_restrictions").append(''); + } + else + { + $(".filter_restrictions").append(''); + } + + for(let i in response.restrictions) + { + $(".filter_restrictions").append(''); + } + + if(!loaded) + { + if(selected['RESTRICTIONS'] !== undefined && selected['RESTRICTIONS'] !== null && selected['RESTRICTIONS'] !== "") + { + $(".filter_restrictions").val(selected['RESTRICTIONS']); + $(".filter_restrictions").find("option").first().text("Не важно").attr("disabled", false); + } + } + else + { + $(".filter_restrictions").val(reset ? "" : current); + } + } + else + { + $(".filter_restrictions").empty(); + $(".filter_restrictions").append(''); + $(".filter_restrictions").attr("disabled", "disabled"); + } + } + + //if(selected['RESERVED'] === "YES") + //{ + // console.log(selected); + // $(".filter_reserved").empty(); + // $(".filter_reserved").append(''); + // $(".filter_reserved").append(''); + //} + + if(response.reserved !== undefined) + { + if(response.reserved.length > 0) + { + var current = $(".filter_reserved").val(); + $(".filter_reserved").empty(); + + if(!reset && current !== "" && current !== null) + { + $(".filter_reserved").append(''); + } + else + { + $(".filter_reserved").append(''); + } + + for(let i in response.reserved) + { + $(".filter_reserved").append(''); + } + + if(!loaded) + { + if(selected['RESERVED'] !== undefined && selected['RESERVED'] !== null && selected['RESERVED'] !== "") + { + $(".filter_reserved").val(selected['RESERVED']); + $(".filter_reserved").find("option").first().text("Не важно").attr("disabled", false); + } + } + else + { + $(".filter_reserved").val(reset ? "" : current); + } + } + else + { + $(".filter_reserved").empty(); + $(".filter_reserved").append(''); + $(".filter_reserved").attr("disabled", "disabled"); + } + } + + if(response.keys !== undefined) + { + if(response.keys.length > 0) + { + var texts = filter_texts_resize(); + + var current = $(".filter_keys").val(); + $(".filter_keys").empty(); + + if(!reset && current !== "" && current !== null) + { + $(".filter_keys").append(''); + } + else + { + $(".filter_keys").append(''); + } + + for(let i in response.keys) + { + $(".filter_keys").append(''); + } + + if(!loaded) + { + if(selected['KEYS'] !== undefined && selected['KEYS'] !== null && selected['KEYS'] !== "") + { + $(".filter_keys").val(selected['KEYS']); + $(".filter_keys").find("option").first().text("Не важно").attr("disabled", false); + } + } + else + { + $(".filter_keys").val(reset ? "" : current); + } + } + else + { + $(".filter_keys").empty(); + $(".filter_keys").append(''); + $(".filter_keys").attr("disabled", "disabled"); + } + } + + if(response.condition !== undefined) + { + if(response.condition.length > 0) + { + var current = $(".filter_condition").val(); + $(".filter_condition").empty(); + + if(!reset && current !== "" && current !== null) + { + $(".filter_condition").append(''); + } + else + { + $(".filter_condition").append(''); + } + + for(let i in response.condition) + { + $(".filter_condition").append(''); + } + + if(!loaded) + { + if(selected['AFTER_ACCIDENT'] !== undefined && selected['AFTER_ACCIDENT'] !== null && selected['AFTER_ACCIDENT'] !== "") + { + $(".filter_condition").val(selected['AFTER_ACCIDENT']); + $(".filter_condition").find("option").first().text("Не важно").attr("disabled", false); + } + } + else + { + $(".filter_condition").val(reset ? "" : current); + } + } + else + { + $(".filter_condition").empty(); + $(".filter_condition").append(''); + $(".filter_condition").attr("disabled", "disabled"); + } + } } $(".catalog_filter_spinner").hide(); @@ -840,11 +1061,6 @@ function loadModifications(uid) }, "json"); } -$(function() -{ - setTimeout(init_filter, 100); -}); - function handle_small_filter_brands(element, event) { $(used ? ".filter_brands_used" : ".filter_brands").val(event.target.value); @@ -987,6 +1203,53 @@ function handle_filter_models(element) } } +function filter_texts_resize() +{ + if(window.innerWidth >= 1280) + { + return { + "filter_keys": "Кол-во ключей", + "filter_pts": "Бумажный ПТС", + }; + } + else if(window.innerWidth >= 1080 && window.innerWidth < 1280) + { + return { + "filter_keys": "Количество ключей", + "filter_pts": "Бумажный ПТС", + }; + } + else if(window.innerWidth >= 960 && window.innerWidth < 1080) + { + return { + "filter_keys": "Количество ключей", + "filter_pts": "Бумажный ПТС", + }; + } + else if(window.innerWidth >= 768 && window.innerWidth < 960) + { + return { + "filter_keys": "Кол-во ключей", + "filter_pts": "Бум. ПТС", + }; + } + else if(window.innerWidth >= 500) + { + return { + "filter_keys": "Количество ключей", + "filter_pts": "Бумажный ПТС", + }; + } + else + { + return { + "filter_restrictions": "Огр. ФССП", + "filter_keys": "Кол-во ключей", + "filter_pts": "Бумажный ПТС", + }; + } +} + function init_filter() { $(".catalog_filter_select").attr("disabled", true); @@ -1124,7 +1387,7 @@ function init_filter() else { $(this).find("option").first().text("Привод").attr("disabled", "disabled"); } - selected['DRIVE'] = $(this).val();; + selected['DRIVE'] = $(this).val(); updateCounter(selected); }); @@ -1135,7 +1398,7 @@ function init_filter() else { $(this).find("option").first().text("Двигатель").attr("disabled", "disabled"); } - selected['ENGINE_FUEL'] = $(this).val();; + selected['ENGINE_FUEL'] = $(this).val(); updateCounter(selected); }); @@ -1146,11 +1409,11 @@ function init_filter() else { $(this).find("option").first().text("Коробка").attr("disabled", "disabled"); } - selected['GEAR'] = $(this).val();; + selected['GEAR'] = $(this).val(); updateCounter(selected); }); - //used ? ".filter_models_used" : ".filter_models" + //used ? ".filter_models_used" : ".filter_models" $(".catalog_filter_search_button").on("click", function(e) { @@ -1228,7 +1491,7 @@ function init_filter() else { $(this).find("option").first().text("Объем, от").attr("disabled", "disabled"); } - selected['ENGINE_VOLUME_FROM'] = $(this).val();; + selected['ENGINE_VOLUME_FROM'] = $(this).val(); updateCounter(selected); }); @@ -1239,7 +1502,7 @@ function init_filter() else { $(this).find("option").first().text("Объем, до").attr("disabled", "disabled"); } - selected['ENGINE_VOLUME_TO'] = $(this).val();; + selected['ENGINE_VOLUME_TO'] = $(this).val(); updateCounter(selected); }); @@ -1250,7 +1513,7 @@ function init_filter() else { $(this).find("option").first().text("Год, от").attr("disabled", "disabled"); } - selected['YEAR_FROM'] = $(this).val();; + selected['YEAR_FROM'] = $(this).val(); updateCounter(selected); }); @@ -1261,7 +1524,7 @@ function init_filter() else { $(this).find("option").first().text("Год, до").attr("disabled", "disabled"); } - selected['YEAR_TO'] = $(this).val();; + selected['YEAR_TO'] = $(this).val(); updateCounter(selected); }); @@ -1272,7 +1535,7 @@ function init_filter() else { $(this).find("option").first().text("Пробег, от").attr("disabled", "disabled"); } - selected['MILEAGE_FROM'] = $(this).val();; + selected['MILEAGE_FROM'] = $(this).val(); updateCounter(selected); }); @@ -1283,7 +1546,7 @@ function init_filter() else { $(this).find("option").first().text("Пробег, до").attr("disabled", "disabled"); } - selected['MILEAGE_TO'] = $(this).val();; + selected['MILEAGE_TO'] = $(this).val(); updateCounter(selected); }); @@ -1294,7 +1557,7 @@ function init_filter() else { $(this).find("option").first().text("Город").attr("disabled", "disabled"); } - selected['PARKING_CITY'] = $(this).val();; + selected['PARKING_CITY'] = $(this).val(); updateCounter(selected); }); @@ -1305,7 +1568,7 @@ function init_filter() else { $(this).find("option").first().text("Тип").attr("disabled", "disabled"); } - selected['VEHICLE_TYPE'] = $(this).val();; + selected['VEHICLE_TYPE'] = $(this).val(); updateCounter(selected); }); @@ -1316,10 +1579,76 @@ function init_filter() else { $(this).find("option").first().text("Уточнить тип").attr("disabled", "disabled"); } - selected['VEHICLE_SUBTYPE'] = $(this).val();; + selected['VEHICLE_SUBTYPE'] = $(this).val(); updateCounter(selected); }); + $(".filter_reserved").on("change", function() + { + if($(this).val() !== "") + { $(this).find("option").first().text("Не указано").attr("disabled", false); } + else + { $(this).find("option").first().text("Резерв").attr("disabled", "disabled"); } + + selected['RESERVED'] = $(this).val(); + updateCounter(selected); + }); + + $(".filter_pts").on("change", function() + { + if($(this).val() !== "") + { $(this).find("option").first().text("Не указано").attr("disabled", false); } + else + { $(this).find("option").first().text("Вид ПТС").attr("disabled", "disabled"); } + + selected['PTS'] = $(this).val(); + updateCounter(selected); + }); + + $(".filter_restrictions").on("change", function() + { + if($(this).val() !== "") + { $(this).find("option").first().text("Не указано").attr("disabled", false); } + else + { $(this).find("option").first().text("Ограничения").attr("disabled", "disabled"); } + + selected['RESTRICTIONS'] = $(this).val(); + updateCounter(selected); + }); + + $(".filter_keys").on("change", function() + { + if($(this).val() !== "") + { $(this).find("option").first().text("Не указано").attr("disabled", false); } + else + { + var texts = filter_texts_resize(); + $(this).find("option").first().text(texts['filter_keys']).attr("disabled", "disabled"); + } + + selected['KEYS'] = $(this).val(); + updateCounter(selected); + }); + + $(".filter_condition").on("change", function() + { + if($(this).val() !== "") + { $(this).find("option").first().text("Не указано").attr("disabled", false); } + else + { $(this).find("option").first().text("Состояние").attr("disabled", "disabled"); } + + selected['AFTER_ACCIDENT'] = $(this).val(); + updateCounter(selected); + }); + + $(window).on("resize", function() + { + var texts = filter_texts_resize(); + + $(".filter_keys").find(".keys_count").first().text(texts['filter_keys']); + $(".filter_pts").find(".pts_paper").first().text(texts['filter_pts']); + }); + $(".sort_option").on("click", function() { // console.log("path", path); @@ -1369,4 +1698,14 @@ function init_filter() //$(this).parent().parent().css("display", "none"); $("#catalog_small_filter").css("display", "block"); }); -} \ No newline at end of file + + var texts = filter_texts_resize(); + + $(".filter_keys").find(".keys_count").first().text(texts['filter_keys']); + $(".filter_pts").find(".pts_paper").first().text(texts['filter_pts']); +} + +$(function() +{ + setTimeout(init_filter, 100); +}); \ No newline at end of file diff --git a/local/components/evolution/form.catalog.filter/templates/.default/style.css b/local/components/evolution/form.catalog.filter/templates/.default/style.css index beb9f97..07a02db 100644 --- a/local/components/evolution/form.catalog.filter/templates/.default/style.css +++ b/local/components/evolution/form.catalog.filter/templates/.default/style.css @@ -2,6 +2,10 @@ .catalog_filter_used *[data-desktop-order] { width: calc(33.333% - 21px) !important; } + + .catalog_filter_used .filter_form_group_hidden { + display: block; + } } @media all and (max-width: 1279px) and (min-width: 769px) { @@ -9,6 +13,10 @@ width: calc(50% - 15px) !important; } + .catalog_filter_used .filter_form_group_hidden { + display: none; + } + .catalog_filter_used div[data-desktop-order]:not(.fieldgroup)>.form_field { width: 100% !important; } diff --git a/local/components/evolution/form.catalog.filter/templates/.default/template.php b/local/components/evolution/form.catalog.filter/templates/.default/template.php index dd04535..d9e20da 100644 --- a/local/components/evolution/form.catalog.filter/templates/.default/template.php +++ b/local/components/evolution/form.catalog.filter/templates/.default/template.php @@ -66,6 +66,65 @@ return << + + +HTML; +} + +function render_pts() +{ +return << + + +HTML; +} + +function render_restrictions() +{ +return << + + +HTML; +} + +function render_keys() +{ +return << + + +HTML; +} + +function render_condition() +{ +return << + + +HTML; +} + ?>