<?php // class MarketParser { protected $_Shop; protected $_apiKey; protected $_cacheDir; protected $_onlyCache; protected $_geoId = 10645; protected $_apiUrl = 'http://market.apisystem.ru/v1'; protected $_categoryFiltersXml = null; protected $_importedItems = 0; protected $_importedProperties = 0; protected $_importedListItems = 0; protected $_page = 0; protected $_parserOutput = ''; /** * Создает экземпляр класса * * @param integer $shopId Идентификатор интернет-магазина * @param string $apiKey Ключ для доступа к сервису */ public function __construct($shopId, $apiKey, $onlyCache = false) { $this->_Shop = Core_Entity::factory('Shop', $shopId); $this->_apiKey = $apiKey; $this->_cacheDir = CMS_FOLDER . 'upload/parser/cache/'; $this->_onlyCache = $onlyCache; } /** * Выполняет парсинг и импорт товаров из категории * * @param integer $categoryId * @param integer $page * @param $count * @return boolean */ public function parseCategoryPage($categoryId, $page = 1, $count = 30) { $this->_importedItems = 0; $this->_importedProperties = 0; $this->_importedListItems = 0; $this->_page = $page; $this->_parserOutput = ''; if ($page < 1 && $page > 50) { return false; } $oCategoryXml = $this->_getResource('/category/' . $categoryId); $categoryName = strval($oCategoryXml['name']); $oCategoryModelsXml = $this->_getResource('/category/' . $categoryId . '/models', array('page' => $page, 'count' => $count)); $aoModelsXml = $oCategoryModelsXml->xpath('model'); if (count($aoModelsXml) == 0) { return false; } $oShop_Group = $this->_getShopGroup($categoryName, $categoryId); foreach ($aoModelsXml as $oModelXml) { // Товар $this->parseModel($oShop_Group, $categoryId, intval($oModelXml['id'])); } $this->_printOutput(); return true; } public function parseProducerPage($categoryId, $producerId, $page = 1, $count = 30) { $this->_importedItems = 0; $this->_importedProperties = 0; $this->_importedListItems = 0; $this->_page = $page; $this->_parserOutput = ''; if ($page < 1 && $page > 50) { return false; } // Категория $oCategoryXml = $this->_getResource('/category/' . $categoryId); $categoryName = strval($oCategoryXml['name']); $oShop_Group = $this->_getShopGroup($categoryName, $categoryId); // Производитель $oProducerFilter = $this->_getDetailsParamFilter('Производитель', $categoryId); $filterId = strval($oProducerFilter['id']); // Поиск $oSearchResultXml = $this->_getResource('/filter/' . $categoryId, array( $filterId => $producerId, 'page' => $page, 'count' => $count )); $aoSearchItems = $oSearchResultXml->xpath('search-item'); if (count($aoSearchItems) == 0) { return false; } foreach ($aoSearchItems as $oSearchItem) { $aoModelsXml = $oSearchItem->xpath('model'); $oModelXml = $aoModelsXml[0]; $this->parseModel($oShop_Group, $categoryId, intval($oModelXml['id'])); } $this->_printOutput(); return true; } public function getNextProducerId($categoryId, $producerId = 0) { $oProducerFilter = $this->_getDetailsParamFilter('Производитель', $categoryId); if (!$producerId) { $aoProducers = $oProducerFilter->xpath('option'); $oProducer = $aoProducers[0]; return intval($oProducer['id']); } else { $aoNextProducer = $oProducerFilter->xpath('option[@id="' . $producerId . '"]/following-sibling::option[1]'); if (count($aoNextProducer)) { return intval($aoNextProducer[0]['id']); } else { return 0; } } } /** * Выполняет парсинг и импорт товара * * @param Shop_Group_Model $oShop_Group * @param integer $categoryId * @param integer $modelId */ public function parseModel(Shop_Group_Model $oShop_Group, $categoryId, $modelId) { $oModelXml = $this->_getResource('/model/' . $modelId); $aoNameXml = $oModelXml->xpath('name'); $aoVendorXml = $oModelXml->xpath('vendor'); $sModelName = strval($aoNameXml[0]); $sProducerName = strval($aoVendorXml[0]); $sShopItemName = $sProducerName . ' ' . $sModelName; // Товар $oShop_Item = $oShop_Group->Shop_Items->getByName($sShopItemName, false); if (!$oShop_Item) { $oShop_Item = Core_Entity::factory('Shop_Item'); $oShop_Item->name = $sShopItemName; $oShop_Item->save(); $oShop_Group->add($oShop_Item); $this->_Shop->add($oShop_Item); $oShop_Item->makePath(); $oShop_Item->save(); // Производитель $this->_saveProducer($oShop_Item, $sProducerName); // Изображения $this->_savePhotos($oShop_Item, $oModelXml); // Характеристики $this->_parseDetails($oShop_Item, $categoryId, $modelId); // Сохраняет информацию о товаре $this->_saveModelInfo($oShop_Item, $oModelXml); $this->_importedItems++; $this->_parserOutput .= $sShopItemName . '<br />'; } } /** * Сохраняет производителя товара * * @param Shop_Item_Model $oShop_Item * @param string $sProducerName */ protected function _saveProducer(Shop_Item_Model $oShop_Item, $sProducerName) { $oShop = $this->_Shop; $oShop_Producer = $oShop->Shop_Producers->getByName($sProducerName, false); if (!$oShop_Producer) { $oShop_Producer = Core_Entity::factory('Shop_Producer'); $oShop_Producer->name = $sProducerName; $oShop_Producer->save(); $oShop->add($oShop_Producer); $oShop_Producer_Dir->add($oShop_Producer); $oShop_Producer->makePath(); $oShop_Producer->save(); } $oShop_Item->add($oShop_Producer); } /** * Сохраняет фотографии товара * * @param Shop_Item_Model $oShop_Item * @param SimpleXmlElement $oModelXml */ protected function _savePhotos(Shop_Item_Model $oShop_Item, SimpleXmlElement $oModelXml) { $oMainPhotoXml = $oModelXml->xpath('main-photo'); if (count($oMainPhotoXml) > 0) { $this->_savePhoto($oShop_Item, strval($oMainPhotoXml[0])); } $aoPhotosXml = $oModelXml->xpath('photos/photo'); foreach ($aoPhotosXml as $oPhotoXml) { $this->_savePhoto($oShop_Item, strval($oPhotoXml), false); } } /** * Сохраняет одну фотографию товара * * @param Shop_Item_Model $oShop_Item * @param string $sRemoteFile * @param boolean $bFirstPhoto */ protected function _savePhoto(Shop_Item_Model $oShop_Item, $sRemoteFile, $bFirstPhoto = true) { $oShop = $this->_Shop; if (Core_File::isValidExtension($sRemoteFile, Core::$mainConfig['availableExtension'])) { // Папка назначения $sDestinationFolder = $oShop_Item->getItemPath(); if (!$bFirstPhoto) { $sFileName = basename($sRemoteFile); $oShop_Item_Property_List = Core_Entity::factory('Shop_Item_Property_List', $oShop->id); $oProperties = $oShop_Item_Property_List->Properties; $oProperties->queryBuilder() ->where('tag_name', '=', 'image') ->where('deleted', '=', 0); $aoProperties = $oProperties->findAll(false); if (count($aoProperties) > 0) { $oProperty = $aoProperties[0]; } else { $oProperty = Core_Entity::factory('Property'); $oProperty->name = 'Изображение'; $oProperty->type = 2; $oProperty->tag_name = 'image'; // Для вновь создаваемого допсвойства размеры берем из магазина $oProperty->image_large_max_width = $oShop->image_large_max_width; $oProperty->image_large_max_height = $oShop->image_large_max_height; $oProperty->image_small_max_width = $oShop->image_small_max_width; $oProperty->image_small_max_height = $oShop->image_small_max_height; $oProperty->save(); $oShop_Item_Property_List->add($oProperty); } $oShop->Shop_Item_Property_For_Groups->allowAccess($oProperty->Shop_Item_Property->id, ($oShop_Item->modification_id == 0 ? intval($oShop_Item->Shop_Group->id) : intval($oShop_Item->Modification->Shop_Group->id) )); $aPropertyValues = $oProperty->getValues($oShop_Item->id, false); $oProperty_Value = null; foreach ($aPropertyValues as $oTmpPropertyValue) { // Ранее загруженное значение ищим по имени файла if ($oTmpPropertyValue->file_name == $sFileName) { $oProperty_Value = $oTmpPropertyValue; break; } } if (is_null($oProperty_Value)) { $oProperty_Value = $oProperty->createNewValue($oShop_Item->id); } $oProperty_Value->save(); if ($oProperty_Value->file != '') { try { Core_File::delete($sDestinationFolder . $oProperty_Value->file); } catch (Exception $e) {} } // Удаляем старое малое изображение if ($oProperty_Value->file_small != '') { try { Core_File::delete($sDestinationFolder . $oProperty_Value->file_small); } catch (Exception $e) {} } } else { if ($oShop_Item->image_large != '' && is_file($sDestinationFolder . $oShop_Item->image_large)) { try { Core_File::delete($sDestinationFolder . $oShop_Item->image_large); } catch (Exception $e) {} } // Удаляем старое малое изображение if ($oShop_Item->image_small != '' && is_file($sDestinationFolder . $oShop_Item->image_small)) { try { Core_File::delete($sDestinationFolder . $oShop_Item->image_small); } catch (Exception $e) {} } } clearstatcache(); // Создаем папку назначения $oShop_Item->createDir(); // Файл-источник $sSourceFile = $this->_downloadPhoto($sRemoteFile); $sSourceFileBaseName = basename($sRemoteFile); if (!$oShop->change_filename) { $sTargetFileName = $sSourceFileBaseName; } else { $sTargetFileExtension = Core_File::getExtension($sRemoteFile); if ($sTargetFileExtension != '') { $sTargetFileExtension = ".{$sTargetFileExtension}"; } if (!$bFirstPhoto) { $sTargetFileName = "shop_property_file_{$oShop_Item->id}_{$oProperty_Value->id}{$sTargetFileExtension}"; } else { $sTargetFileName = "shop_items_catalog_image{$oShop_Item->id}{$sTargetFileExtension}"; } } $aPicturesParam = array(); $aPicturesParam['large_image_isset'] = TRUE; $aPicturesParam['large_image_source'] = $sSourceFile; $aPicturesParam['large_image_name'] = $sSourceFileBaseName; $aPicturesParam['large_image_target'] = $sDestinationFolder . $sTargetFileName; $aPicturesParam['watermark_file_path'] = $oShop->getWatermarkFilePath(); $aPicturesParam['watermark_position_x'] = $oShop->watermark_default_position_x; $aPicturesParam['watermark_position_y'] = $oShop->watermark_default_position_y; $aPicturesParam['large_image_preserve_aspect_ratio'] = $oShop->preserve_aspect_ratio; $aPicturesParam['small_image_source'] = $aPicturesParam['large_image_source']; $aPicturesParam['small_image_name'] = $aPicturesParam['large_image_name']; $aPicturesParam['small_image_target'] = $sDestinationFolder . "small_{$sTargetFileName}"; $aPicturesParam['create_small_image_from_large'] = TRUE; if (!$bFirstPhoto) { $aPicturesParam['large_image_max_width'] = $oProperty->image_large_max_width; $aPicturesParam['large_image_max_height'] = $oProperty->image_large_max_height; $aPicturesParam['small_image_max_width'] = $oProperty->image_small_max_width; $aPicturesParam['small_image_max_height'] = $oProperty->image_small_max_height; } else { $aPicturesParam['large_image_max_width'] = $oShop->image_large_max_width; $aPicturesParam['large_image_max_height'] = $oShop->image_large_max_height; $aPicturesParam['small_image_max_width'] = $oShop->image_small_max_width; $aPicturesParam['small_image_max_height'] = $oShop->image_small_max_height; } $aPicturesParam['small_image_watermark'] = $oShop->watermark_default_use_small_image; $aPicturesParam['small_image_preserve_aspect_ratio'] = $oShop->preserve_aspect_ratio_small; $aPicturesParam['large_image_watermark'] = $oShop->watermark_default_use_large_image; try { $result = Core_File::adminUpload($aPicturesParam); } catch (Exception $exc) { $result = array('large_image' => FALSE, 'small_image' => FALSE); } if ($result['large_image']) { if (!$bFirstPhoto) { $oProperty_Value->file = $sTargetFileName; $oProperty_Value->file_name = $sFileName; $oProperty_Value->save(); } else { $oShop_Item->image_large = $sTargetFileName; $oShop_Item->setLargeImageSizes(); } } if ($result['small_image']) { if (!$bFirstPhoto) { $oProperty_Value->file_small = "small_{$sTargetFileName}"; $oProperty_Value->file_small_name = ''; $oProperty_Value->save(); } else { $oShop_Item->image_small = "small_{$sTargetFileName}"; $oShop_Item->setSmallImageSizes(); } } $oShop_Item->save(); } } /** * Выполняет парсинг и импорт характеристик * * @param Shop_Item_Model $oShop_Item * @param integer $categoryId * @param integer $ modelId */ protected function _parseDetails(Shop_Item_Model $oShop_Item, $categoryId, $modelId) { $oDetailsXml = $this->_getResource('/model/' . $modelId . '/details'); $aoDetailsBlocks = $oDetailsXml->xpath('block'); foreach ($aoDetailsBlocks as $oDetailsBlock) { $this->_saveDetailsBlock($oShop_Item, $oDetailsBlock, $categoryId); } } /** * Сохраняет информацию о товаре * * @param Shop_Item_Model $oShop_Item * @param SimpleXmlElement $oModelXml */ protected function _saveModelInfo(Shop_Item_Model $oShop_Item, SimpleXmlElement $oModelXml) { $oNameXml = $oModelXml->xpath('name'); $sModelName = strval($oNameXml[0]); $iModelId = intval($oModelXml['id']); $this->_createPropertyAndSetValue( 'Идентификатор модели в Яндекс.Маркете', 'market_model_id', 0, $oShop_Item, $iModelId ); $this->_createPropertyAndSetValue( 'Модель', 'model_name', 1, $oShop_Item, $sModelName ); } // Сохраняет блок характеристик товара protected function _saveDetailsBlock(Shop_Item_Model $oShop_Item, $oDetailsBlock, $categoryId) { $sBlockName = strval($oDetailsBlock['name']); if ($sBlockName == 'Габариты и вес') { $this->_saveDimensionsAndWeight($oShop_Item, $oDetailsBlock); return; } $sCategoryName = $oShop_Item->Shop_Group->name; $aoDetailsParams = $oDetailsBlock->xpath('param'); foreach ($aoDetailsParams as $oDetailsParam) { $sParamName = strval($oDetailsParam['name']); if (strpos($sParamName, 'Габариты') !== false || strpos($sParamName, 'Размеры') !== false) { $this->_saveDimensions($oShop_Item, strval($oDetailsParam['value'])); continue; } if ($sParamName == 'Вес') { $this->_saveWeight($oShop_Item, strval($oDetailsParam['value'])); continue; } $sParamValue = strval($oDetailsParam['value']); $oProperty = $this->_getProperty($sCategoryName, $sBlockName, $sParamName, $categoryId); $sParamValue = str_replace($oProperty->Shop_Item_Property->Shop_Measure->name, '', $sParamValue); $sParamValue = trim($sParamValue); // Удаляем кавычки в начале и в конце значения $sParamValue = preg_replace('/^\"/', '', $sParamValue); $sParamValue = preg_replace('/\"$/', '', $sParamValue); // Разрешаем свойство группе $this->_Shop->Shop_Item_Property_For_Groups->allowAccess($oProperty->Shop_Item_Property->id, intval($oShop_Item->Shop_Group->id)); switch ($oProperty->type) { case 3: // Список $aParamValue = explode(', ', $sParamValue); foreach ($aParamValue as $sParamValue) { $oProperty_Value = $oProperty->createNewValue($oShop_Item->id); $oList_Item = $this->_getListItem($sCategoryName, $sBlockName, $sParamName, trim($sParamValue)); $oProperty_Value->value = $oList_Item->id; $oProperty_Value->save(); } break; case 7: // Флажок $oProperty_Value = $oProperty->createNewValue($oShop_Item->id); $oProperty_Value->value = (strpos($sParamValue, 'есть') !== null) ? 1 : 0; $oProperty_Value->save(); break; default: $oProperty_Value = $oProperty->createNewValue($oShop_Item->id); $oProperty_Value->value = $sParamValue; $oProperty_Value->save(); break; } } } // Сохраняет габариты и вес товара protected function _saveDimensionsAndWeight(Shop_Item_Model $oShop_Item, $oDimensionsAndWeightBlock) { $aoDimensions = $oDimensionsAndWeightBlock->xpath('param[contains(@name, "Габариты") or contains(@name, "Размеры")]'); $aoWeight = $oDimensionsAndWeightBlock->xpath('param[contains(@name, "Вес")]'); if (count($aoDimensions) > 0) { $this->_saveDimensions($oShop_Item, strval($aoDimensions[0]['value'])); } if (count($aoWeight) > 0) { $this->_saveWeight($oShop_Item, strval($aoWeight[0]['value'])); } } // Сохраняет габариты товара protected function _saveDimensions(Shop_Item_Model $oShop_Item, $sDimensionsValue) { $aDimensionsWithUnit = explode(' ', $sDimensionsValue); $sDimensions = $aDimensionsWithUnit[0]; $sUnit = $aDimensionsWithUnit[1]; switch ($sUnit) { case 'см': $coefficient = 10; break; case 'м': $coefficient = 1000; break; default: $coefficient = 1; break; } $aDimensions = explode('x', $sDimensions); $oShop_Item->length = $aDimensions[0] * $coefficient; if (count($aDimensions) > 1) { $oShop_Item->width = $aDimensions[1] * $coefficient; } if (count($aDimensions) > 2) { $oShop_Item->height = $aDimensions[2] * $coefficient; } $oShop_Item->save(); } // Сохраняет вес товара protected function _saveWeight(Shop_Item_Model $oShop_Item, $sWeightValue) { $iWeight = $sWeightValue; $oShop_Item->weight = $iWeight; $oShop_Item->save(); } /** * Возвращает XML-данные ресурса * * Например, получим фильтры категории: * $aFiltersXml = $this->_getResource('category/85674362/filters', array('filter_set' => 'all'); * * @param string $resource * @param array $resourceParams * @param string $type * @return SimpleXmlElement */ protected function _getResource($resource, $resourceParams = array(), $type = 'xml') { $authParams = array('api_key' => $this->_apiKey, 'geo_id' => $this->_geoId); $query = $authParams + $resourceParams; $resourceUrl = $this->_apiUrl . $resource . '.' . $type; $resourceUrl .= '?' . http_build_query($query, '', '&'); // Кэширование запросов $cacheFile = $this->_cacheDir . md5($resourceUrl); $bFromCache = false; if (is_file($cacheFile) || $this->_onlyCache) { $content = file_get_contents($cacheFile); try { $contentXml = new SimpleXmlElement($content); $bFromCache = true; } catch (Exception $e) { // Кэш файл сломался $content = $this->_getRemoteContent($resourceUrl); } } else { $content = $this->_getRemoteContent($resourceUrl); $contentXml = new SimpleXmlElement($content); } if ($content && !$bFromCache) { file_put_contents($cacheFile, $content); } if (!$contentXml || count($contentXml->xpath('error')) > 0) { throw new Core_Exception('Ошибка в запросе.'); } return $contentXml; } /** * Возвращает тело ответа по URL * * @param string $url * @return string */ protected function _getRemoteContent($url) { $statusCode = false; $i = 0; while ($statusCode != 200 && $i < 10) { $content = file_get_contents($url); if (isset($http_response_header)) { $aResponseHeader = explode(' ', $http_response_header[0]); $statusCode = $aResponseHeader[1]; } else { $statusCode = false; } if ($statusCode != 200) { usleep(100 * $i * $i); } $i++; } return $content; } // protected function _createPropertyAndSetValue($sName, $sTagName, $type, Shop_Item_Model $oShop_Item, $value) { $oShop = $this->_Shop; $oShop_Item_Property_List = Core_Entity::factory('Shop_Item_Property_List', $oShop->id); $oProperties = $oShop_Item_Property_List->Properties; $oProperties->queryBuilder() ->where('tag_name', '=', $sTagName) ->where('deleted', '=', 0); $aoProperties = $oProperties->findAll(false); if (count($aoProperties) > 0) { $oProperty = $aoProperties[0]; } else { $oProperty = Core_Entity::factory('Property'); $oProperty->name = $sName; $oProperty->tag_name = $sTagName; $oProperty->type = $type; $oProperty->save(); $oShop_Item_Property_List->add($oProperty); } $aoProperty_Values = $oProperty->getValues($oShop_Item->id); $oProperty_Value = count($aoProperty_Values) > 0 ? $aoProperty_Values[0] : $oProperty->createNewValue($oShop_Item->id); $oProperty_Value->value = $value; $oProperty_Value->save(); $oShop->Shop_Item_Property_For_Groups->allowAccess($oProperty->Shop_Item_Property->id, ($oShop_Item->modification_id == 0 ? intval($oShop_Item->Shop_Group->id) : intval($oShop_Item->Modification->Shop_Group->id) )); } // Возвращает группу по имени, если такой нет, то создает protected function _getShopGroup($sGroupName) { $oShop_Group = $this->_Shop->Shop_Groups->getByName($sGroupName, false); if (!$oShop_Group) { $oShop_Group = Core_Entity::factory('Shop_Group'); $oShop_Group->name = $sGroupName; $oShop_Group->save(); $this->_Shop->add($oShop_Group); $oShop_Group->makePath(); $oShop_Group->save(); } return $oShop_Group; } /** * Возвращает фильтр характеристики * * @param string $sParamName * @param integer $categoryId * @param boolean $bStrict * @return SimpleXmlElement */ protected function _getDetailsParamFilter($sParamName, $categoryId, $bStrict = true) { if (!$this->_categoryFiltersXml) { $this->_categoryFiltersXml = $this->_getResource('/category/' . $categoryId . '/filters', array('filter_set' => 'all')); } if ($bStrict) { $oFiltersXml = $this->_categoryFiltersXml->xpath('filter[@name = "' . $sParamName . '"]'); } else { $oFiltersXml = $this->_categoryFiltersXml->xpath('filter[contains(@name, "' . $sParamName . '")]'); } if (count($oFiltersXml) > 0) { return $oFiltersXml[0]; } return null; } // Возвращает единицу измерения по имени protected function _getMeasure($sMeasureName) { $oShop_Measure = Core_Entity::factory('Shop_Measure')->getByName($sMeasureName, false); if (!$oShop_Measure) { $oShop_Measure = Core_Entity::factory('Shop_Measure'); $oShop_Measure->name = $sMeasureName; $oShop_Measure->description = $sMeasureName; $oShop_Measure->save(); } return $oShop_Measure; } // Возвращает директорию свойства, если такой нет, то создает protected function _getDetailsPropertyDir($sCategoryName, $sBlockName) { $oShop_Item_Property_List = Core_Entity::factory('Shop_Item_Property_List', $this->_Shop->id); $oCategoryPropertyDir = $oShop_Item_Property_List->Property_Dirs->getByName($sCategoryName, false); if (!$oCategoryPropertyDir) { $oCategoryPropertyDir = Core_Entity::factory('Property_Dir'); $oCategoryPropertyDir->name = $sCategoryName; $oCategoryPropertyDir->save(); $oShop_Item_Property_List->add($oCategoryPropertyDir); } $oProperty_Dir = $oCategoryPropertyDir->Property_Dirs->getByName($sBlockName, false); if (!$oProperty_Dir) { $oProperty_Dir = Core_Entity::factory('Property_Dir'); $oProperty_Dir->name = $sBlockName; $oProperty_Dir->parent_id = $oCategoryPropertyDir->id; $oProperty_Dir->save(); $oShop_Item_Property_List->add($oProperty_Dir); } return $oProperty_Dir; } // Возвращает свойство, если такого нет, то создает protected function _getProperty($sCategoryName, $sBlockName, $sParamName, $categoryId) { $oShop_Item_Property_List = Core_Entity::factory('Shop_Item_Property_List', $this->_Shop->id); // Определяем название свойства $oFilterXml = $this->_getDetailsParamFilter($sParamName, $categoryId); $sParamType = strval($oFilterXml['type']); $sParamMeasure = strval($oFilterXml['unit']); $sParamShortname = strval($oFilterXml['shortname']); $oProperty_Dir = $this->_getDetailsPropertyDir($sCategoryName, $sBlockName); $oProperties = $oProperty_Dir->Properties; $oProperties->queryBuilder() ->where('name', 'LIKE', $sParamName . '%') ->where('deleted', '=', 0); $aoProperties = $oProperties->findAll(false); if (count($aoProperties) > 0) { $oProperty = $aoProperties[0]; } else { $oProperty = Core_Entity::factory('Property'); $oProperty->name = $sParamName . ($sParamMeasure ? ', ' . $sParamMeasure : ''); $oProperty->multiple = 0; if ($sParamShortname) { $oProperty->tag_name = strtolower(preg_replace('/(?<=\\w)(?=[A-Z])/','_$1', $sParamShortname)); } else { $sTranslated = Core_Str::translate($sParamName); $oProperty->tag_name = $sTranslated ? $sTranslated : $sParamName; $oProperty->tag_name = Core_Str::transliteration($oProperty->tag_name); } switch ($sParamType) { case 'enum': $oProperty->type = 3; // Список $oProperty->save(); $oList = $this->_getList($sCategoryName, $sBlockName, $sParamName); $oProperty->add($oList); break; case 'numeric': $oProperty->type = 11; // Число с плавающей запятой $oProperty->save(); break; case 'bool': $oProperty->type = 7; // Флажок $oProperty->save(); break; default: if ($sParamName == 'Дополнительная информация') { $oProperty->type = 4; // Большое текстовое поле } else { $oProperty->type = 3; // Список $oProperty->save(); $oList = $this->_getList($sCategoryName, $sBlockName, $sParamName); $oProperty->add($oList); } $oProperty->save(); break; } $oShop_Item_Property_List->add($oProperty); $oProperty_Dir->add($oProperty); // Единица измерения $oShop_Measure = $this->_getMeasure($sParamMeasure); $oProperty->Shop_Item_Property->add($oShop_Measure); $this->_importedProperties++; } return $oProperty; } // Возвращает список свойства, если такого нет, то создает protected function _getList($sCategoryName, $sBlockName, $sParamName) { $oCategoryList_Dirs = Core_Entity::factory('List_Dir'); $oCategoryList_Dirs->queryBuilder() ->where('name', '=', $sCategoryName) ->where('deleted', '=', 0) ->where('parent_id', '=', 0); $aoCategoryList_Dirs = $oCategoryList_Dirs->findAll(false); if (count($aoCategoryList_Dirs) > 0) { $oCategoryListDir = $aoCategoryList_Dirs[0]; } else { $oCategoryListDir = Core_Entity::factory('List_Dir'); $oCategoryListDir->name = $sCategoryName; $oCategoryListDir->save(); } $oList_Dir = $oCategoryListDir->List_Dirs->getByName($sBlockName, false); if (!$oList_Dir) { $oList_Dir = Core_Entity::factory('List_Dir'); $oList_Dir->name($sBlockName); $oList_Dir->parent_id = $oCategoryListDir->id; $oList_Dir->save(); } $oList = $oList_Dir->Lists->getByName($sParamName, false); if (!$oList) { $oList = Core_Entity::factory('List'); $oList->name = $sParamName; $oList->save(); $oList_Dir->add($oList); } return $oList; } // Возвращает элемент списка, если такого нет, то создает protected function _getListItem($sCategoryName, $sBlockName, $sParamName, $value) { $oList = $this->_getList($sCategoryName, $sBlockName, $sParamName); $oList_Item = $oList->List_Items->getByValue($value, false); if (!$oList_Item) { $oList_Item = Core_Entity::factory('List_Item'); $oList_Item->value = $value; $sTranslated = Core_Str::translate($value); $oList_Item->tag = $sTranslated ? $sTranslated : $value; $oList_Item->tag = Core_Str::transliteration($oList_Item->tag); $oList_Item->save(); $oList->add($oList_Item); $this->_importedListItems++; } return $oList_Item; } /** * Скачивает удаленный файл, возвращает путь к временному файлу * * @param string $sRemoteFile * @return string */ protected function _downloadPhoto($sRemoteFile) { $sTempFileName = tempnam(CMS_FOLDER . TMP_DIR, 'CMS'); // Копируем содержимое WEB-файла в локальный временный файл file_put_contents($sTempFileName, file_get_contents($sRemoteFile)); return $sTempFileName; } protected function _printOutput() { ?> <strong>Импортирована страница <?=$this->_page?>:</strong><br /> Создано товаров: <?=$this->_importedItems?><br /> Создано свойств: <?=$this->_importedProperties?><br /> Создано элементов списков: <?=$this->_importedListItems?><br /><br /> <?php print $this->_parserOutput; } } $iPage = Core_Array::getGet('page') !== null ? Core_Array::getGet('page') : ( isset($_SESSION['parser_page']) ? $_SESSION['parser_page'] : 1 ); $iCategoryId = Core_Array::getGet('category_id') !== null ? Core_Array::getGet('category_id') : ( isset($_SESSION['parser_category_id']) ? $_SESSION['parser_category_id'] : 0 ); $iProducerId = Core_Array::getGet('producer_id') !== null ? Core_Array::getGet('producer_id') : ( isset($_SESSION['parser_producer_id']) ? $_SESSION['parser_producer_id'] : 0 ); $bMakeParsing = Core_Array::getGet('parse') && $iCategoryId; if ($bMakeParsing) { ob_start(); $marketParser = new MarketParser( Core_Array::get(Core_Page::instance()->libParams, 'shopId'), Core_Array::get(Core_Page::instance()->libParams, 'key'), false ); if (!$iProducerId) { $iProducerId = $marketParser->getNextProducerId($iCategoryId, 0); } // if ($iProducerId) // { $hasItems = $marketParser->parseProducerPage($iCategoryId, $iProducerId, $iPage); // } // else // { // $hasItems = $marketParser->parseCategoryPage($iCategoryId, $iPage); // } $iPage++; if (!$hasItems) { $iProducerId = $marketParser->getNextProducerId($iCategoryId, $iProducerId); $iPage = 1; if ($iProducerId) { $hasItems = true; } } $_SESSION['parser_page'] = $iPage; $_SESSION['parser_category_id'] = $iCategoryId; $_SESSION['parser_producer_id'] = $iProducerId; $sParserOutput = ob_get_clean(); } ?> <form name="parsing_form" method="GET"> <table> <tr> <td>Категория:</td> <td><input name="category_id" type="text" size="50" value="<?=$iCategoryId?>" style="margin: 5px 0" /><!-- Водяные насосы --></td> </tr> <tr> <td>Производитель:</td> <td><input name="producer_id" type="text" size="50" value="<?=$iProducerId?>" style="margin: 5px 0" /></td> </tr> <tr> <td>Страница:</td> <td><input name="page" value="<?=$iPage <= 50 ? $iPage : 1?>" style="margin: 5px 0" /></td> </tr> </table> <input type="hidden" name="parse" value="1" /> <button type="submit" style="margin: 5px 0">Парсить</button><br/><br/> </form> <div> <?php if (isset($sParserOutput)) { print $sParserOutput; } ?> </div> <?php if ($bMakeParsing) { if ($hasItems && $iPage >= 1 && $iPage <= 50) { ?> <script> setTimeout( function() { document.parsing_form.submit(); }, 2000 ); </script> <? } else { ?>Парсинг завершен!<? } }