This is an old revision of the document!
<?php error_reporting(E_ALL); set_time_limit(300); // 5 мин. /** * Выполняет перенос товаров и доп. свойств из одного интернет-магазина в другой * */ class ShopTransferer { /** * Исходный интернет-магазин * * @var Shop_Model */ protected $_SourceShop; /** * Интернет-магазин, в который требуется перенести товары из исходного * * @var Shop_Model */ protected $_DestShop; /** * Устанавливает исходный интернет-магазин * * @param Shop_Model $oShop * @return self */ public function sourceShop(Shop_Model $oShop) { $this->_SourceShop = $oSourceShop; return $this; } /** * Устанавливает интернет-магазин назначения * * @param Shop_Model $oShop * @return self */ public function destShop(Shop_Model $oShop) { $this->_DestShop = $DestShop; return $this; } /** * Конструктор * * @param Shop_Model $oSourceShop * @param Shop_Model $oDestShop */ public function __construct(Shop_Model $oSourceShop, Shop_Model $oDestShop) { $this->_SourceShop = $oSourceShop; $this->_DestShop = $oDestShop; $this->_log('Transferer constructed.'); } /** * Выполняем перенос групп и товаров * */ public function execute() { // Переносим списки товаров и групп $this->_transferLists(); // Переносим доп. свойства товаров и групп $this->_transferProperties(); // Переносим справочники $this->_transferReferencies(); // Переносим товары из корня $this->_transferShopItems(); } /** * Переносит директорию доп. свойств $oSourcePropertyDir в родительскую директорию $oDestParentDir * * @param Property_Dir_Model $oSourcePropertyDir=null Исходная директория для переноса * @param Property_Dir_Model $oDestParentDir=null Родительская директория, в которую требуется поместить копию исходной */ protected function _transferProperties(Property_Dir_Model $oSourcePropertyDir = null, Property_Dir_Model $oDestParentDir = null) { $this->_log('Transfer properties.'); $this->_transferPropertiesList('Shop_Item_Property_List'); $this->_transferPropertiesList('Shop_Group_Property_List'); } /** * Переносит директорию доп. свойств $oSourcePropertyDir в родительскую директорию $oDestParentDir * * @param string propertiesList Список свойств для переноса * @param Property_Dir_Model $oSourcePropertyDir=null Исходная директория для переноса * @param Property_Dir_Model $oDestParentDir=null Родительская директория, в которую требуется поместить копию исходной */ protected function _transferPropertiesList($propertiesList, Property_Dir_Model $oSourcePropertyDir = null, Property_Dir_Model $oDestParentDir = null) { // Список доп. свойств $oSourceShopPropertiesList = Core_Entity::factory($propertiesList, $this->_SourceShop->id); $oDestShopPropertyList = Core_Entity::factory($propertiesList, $this->_DestShop->id); // Свойства и разделы из корня if (!$oSourcePropertyDir) { $oSourceProperties = $oSourceShopPropertiesList->Properties; $oSourceProperties->queryBuilder() ->where('property_dir_id', '=', 0); $oSourcePropertyDirs = $oSourceShopPropertiesList->Property_Dirs; $oSourcePropertyDirs->queryBuilder() ->where('parent_id', '=', 0); $oDestPropertyDir = null; } // Свойства и разделы из директории else { $oSourceProperties = $oSourcePropertyDir->Properties; $oSourcePropertyDirs = $oSourcePropertyDir->Property_Dirs; // if (!$oDestParentDir) { $oDestTopPropertyDirs = $oDestShopPropertyList->Property_Dirs; $oDestTopPropertyDirs->queryBuilder() ->where('parent_id', '=', 0); $oDestPropertyDir = $oDestTopPropertyDirs->getByName($oSourcePropertyDir->name); } else { $oDestPropertyDir = $oDestParentDir->Property_Dirs->getByName($oSourcePropertyDir->name); } if (!$oDestPropertyDir) { $oDestPropertyDir = clone $oSourcePropertyDir; $oDestPropertyDir->parent_id = 0; $oDestShopPropertyList->add($oDestPropertyDir); if ($oDestParentDir) { $oDestPropertyDir->add($oDestParentDir); } } } // Переносим свойства $aoSourceProperties = $oSourceProperties->findAll(); foreach ($aoSourceProperties as $oSourceProperty) { $this->_log("Transfer property {$oSourceProperty->name} ({$oSourceProperty->id})"); if (!$oDestPropertyDir) { $oDestTopProperties = $oDestShopPropertyList->Properties; $oDestTopProperties->queryBuilder() ->where('property_dir_id', '=', 0); $oDestProperty = $oDestTopProperties->getByName($oSourceProperty->name); } else { $oDestProperty = $oDestPropertyDir->Properties->getByName($oSourceProperty->name); } if (!$oDestProperty) { $oDestProperty = clone $oSourceProperty; $oDestProperty->property_dir_id = 0; $oDestProperty->list_id = 0; $oDestShopPropertyList->add($oDestProperty); if ($oSourceProperty->List->id) { $oDestList = $this->_getDestList($oSourceProperty->List); if ($oDestList) { $oDestProperty->add($oDestList); } } $this->_log("Create property {$oDestProperty->name} ({$oDestProperty->id})"); if ($oDestPropertyDir) { // $this->_log("Add property to {$oDestPropertyDir->name} ({$oDestPropertyDir->id})"); $oDestProperty->add($oDestPropertyDir); } // TODO: Перенос единиц измерения } } // Переносим разделы свойств $aoSourcePropertyDirs = $oSourcePropertyDirs->findAll(); foreach ($aoSourcePropertyDirs as $oSourcePropertyDir) { $this->_transferPropertiesList($propertiesList, $oSourcePropertyDir, $oDestPropertyDir); } } /** * Переносит товары группы $oSourceShopGroup в группу $oDestShopGroup * * @param Shop_Group_Model $oSourceShopGroup=null Исходная группа для переноса * @param Shop_Group_Model $oDestShopGroup=null Родительская группа, в которую требуется поместить товары из исходной */ protected function _transferShopItems(Shop_Group_Model $oSourceShopGroup = null, Shop_Group_Model $oDestParentGroup = null) { // Перенос группы товаров if (!$oSourceShopGroup) { $oSourceShopItems = $this->_SourceShop->Shop_Items; $oSourceShopItems->queryBuilder() ->where('shop_group_id', '=', 0); $oSourceShopGroups = $this->_SourceShop->Shop_Groups; $oSourceShopGroups->queryBuilder() ->where('parent_id', '=', 0); $oDestShopGroup = null; } else { $oSourceShopItems = $oSourceShopGroup->Shop_Items; $oSourceShopGroups = $oSourceShopGroup->Shop_Groups; if (!$oDestParentGroup) { $oDestTopShopGroups = $this->_DestShop->Shop_Groups; $oDestTopShopGroups->queryBuilder() ->where('parent_id', '=', 0); $oDestShopGroup = $oDestTopShopGroups->getByName($oSourceShopGroup->name); } else { $oDestShopGroup = $oDestParentGroup->Shop_Groups->getByName($oSourceShopGroup->name); } if (!$oDestShopGroup) { $oDestShopGroup = clone $oSourceShopGroup; $oDestShopGroup->parent_id = 0; $oDestShopGroup->add($this->_DestShop); // $this->_transferImage($oSourceShopGroup, $oDestShopGroup); // Переносим доп. свойства $this->_transferPropertyValues($oSourceShopGroup, $oDestShopGroup); if ($oDestParentGroup) { $oDestParentGroup->add($oDestParentGroup); } } } // Перенос товаров $aoSourceShopItems = $oSourceShopItems->findAll(); foreach ($aoSourceShopItems as $oSourceShopItem) { $this->_log("Transfer shop item {$oSourceShopItem->name} ({$oSourceShopItem->id})"); if (!$oDestShopGroup) { $oDestTopShopItems = $this->_DestShop->Shop_Items; $oDestTopShopItems->queryBuilder() ->where('shop_group_id', '=', 0); $oDestShopItems = $oDestTopShopItems; } else { $oDestShopItems = $oDestShopGroup->Shop_Items; } // Ищем по артикулу if (trim($oSourceShopItem->marking)) { $oDestShopItem = $oDestShopItems->getByMarking($oSourceShopItem->marking, false); } // Или по названию else { $oDestShopItem = $oDestShopItems->getByName($oSourceShopItem->name, false); } if (!$oDestShopItem) { $oDestShopItem = clone $oSourceShopItem; $oDestShopItem->shop_group_id = 0; // $oDestShopItem->path = ''; $oDestShopItem->add($this->_DestShop); if ($oDestShopGroup) { $oDestShopItem->add($oDestShopGroup); } // Переносим изображения $this->_transferImage($oSourceShopItem, $oDestShopItem); // Переносим значения доп. свойств $this->_transferPropertyValues($oSourceShopItem, $oDestShopItem); } } // Переносим группы $aoSourceShopGroups = $oSourceShopGroups->findAll(); foreach ($aoSourceShopGroups as $oSourceShopGroup) { $this->_transferShopItems($oSourceShopGroup, $oDestShopGroup); } } /** * Переносит изображение товара или группы * * @param object $sourceObject Исходный товар или группа товаров * @param object $destObject Новый товар или группа товаров */ protected function _transferImage($oSourceObject, $oDestObject, $fromLarge = true) { $oDestShop = $oDestObject->Shop; if (is_file($oSourceObject->getLargeFilePath())) { try { $oDestObject->createDir(); $oDestObject->image_large = $oDestObject->getTableName() . '_' . $oDestObject->id . '.' . Core_File::getExtension($oSourceObject->image_large); Core_File::copy($oSourceObject->getLargeFilePath(), $oDestObject->getLargeFilePath()); $oDestObject->save(); } catch (Exception $e) {} } if (!$fromLarge && is_file($oSourceObject->getSmallFilePath())) { try { $oDestObject->createDir(); $oDestObject->image_small = 'small_' . $oDestObject->getTableName() . '_' . $oDestObject->id . '.' . Core_File::getExtension($oSourceObject->image_small); Core_File::copy($oSourceObject->getSmallFilePath(), $oDestObject->getSmallFilePath()); $oDestObject->save(); } catch (Exception $e) {} } elseif (is_file($oSourceObject->getLargeFilePath())) { try { $oDestObject->createDir(); $oDestObject->image_small = 'small_' . $oDestObject->getTableName() . '_' . $oDestObject->id . '.' . Core_File::getExtension($oSourceObject->image_small); Core_Image::instance()->resizeImage($oSourceObject->getLargeFilePath(), $oDestShop->image_small_max_width, $oDestShop->image_small_max_height, $oDestObject->getSmallFilePath()); $oDestObject->save(); } catch (Exception $e) {} } } /** * Выполняет перенос доп. свойств товара * * @param object $oSourceObject Исходный товар или группа * @param object $oDestObject Товар или группа, в который необходимо перенести значения доп. свойств * @param boolean $bImageFromLarge Создавать малое изображение из большого (true), либо копировать исходное малое изображение */ protected function _transferPropertyValues($oSourceObject, $oDestObject, $bImageFromLarge = true) { $bShopItem = ($oDestObject->getModelName() == 'shop_item'); $oDestShop = $oDestObject->Shop; $propertyList = $bShopItem ? 'Shop_Item_Property_List' : 'Shop_Group_Property_List'; $aoSourcePropertyValues = $oSourceObject->getPropertyValues(); foreach ($aoSourcePropertyValues as $oSourcePropertyValue) { $oDestProperty = $this->_getDestProperty($propertyList, $oSourcePropertyValue->Property); if (!$oDestProperty) { continue; } if ($bShopItem) { $this->_DestShop ->Shop_Item_Property_For_Groups ->allowAccess($oDestProperty->Shop_Item_Property->id, $oDestObject->shop_group_id); // $oDestProperty->show_in_item = 1; } $oDestPropertyValue = clone $oSourcePropertyValue; $oDestPropertyValue->entity_id = $oDestObject->id; $oDestPropertyValue->add($oDestProperty); switch ($oDestProperty->type) { // Список case 3: $oSourceListItem = $oSourcePropertyValue->List_Item; if ($oSourceListItem->id) { $oDestList = $oDestProperty->List; $oDestListItem = $oDestList->List_Items->getByValue($oSourceListItem->value); $oDestPropertyValue->add($oDestListItem); } break; // Файл case 2: if ($bShopItem) { $oSourcePropertyValue->setDir($oSourceObject->getItemPath()); $oDestPropertyValue->setDir($oDestObject->getItemPath()); } else { $oSourcePropertyValue->setDir($oSourceObject->getGroupPath()); $oDestPropertyValue->setDir($oDestObject->getGroupPath()); } if (is_file($oSourcePropertyValue->getLargeFilePath())) { try { $oDestPropertyValue->file = $oDestObject->getTableName() . '_property_' . $oDestPropertyValue->id . '.' . Core_File::getExtension($oSourcePropertyValue->file); Core_File::copy($oSourcePropertyValue->getLargeFilePath(), $oDestPropertyValue->getLargeFilePath()); $oDestPropertyValue->save(); } catch (Exception $e) {} } if (!$bImageFromLarge && is_file($oSourcePropertyValue->getSmallFilePath())) { try { $oDestPropertyValue->file_small = 'small_' . $oDestObject->getTableName() . '_property_' . $oDestPropertyValue->id . '.' . Core_File::getExtension($oSourcePropertyValue->file_small); Core_File::copy($oSourcePropertyValue->getSmallFilePath(), $oDestPropertyValue->getSmallFilePath()); $oDestPropertyValue->save(); } catch (Exception $e) {} } elseif (is_file($oSourcePropertyValue->getLargeFilePath())) { try { $oDestPropertyValue->file_small = 'small_' . $oDestObject->getTableName() . '_property_' . $oDestPropertyValue->id . '.' . Core_File::getExtension($oSourcePropertyValue->file_small); Core_Image::instance()->resizeImage($oSourcePropertyValue->getLargeFilePath(), $oDestShop->image_small_max_width, $oDestShop->image_small_max_height, $oDestPropertyValue->getSmallFilePath()); $oDestPropertyValue->save(); } catch (Exception $e) {} } break; } } } /** * Возвращает список в новом сайте по структуре списков старого сайта * * Например, если в исходном сайте есть список: * Сайт №1 / Раздел №1 / Раздел №2 / Исходный список, * * то функция возвратит список, вложенный в такие же разделы, как и исходный: * Сайт №2 / Раздел №1 / Раздел №2 / Исходный список, * * @param List_Model $oSourceList * @return List_Model */ protected function _getDestList(List_Model $oSourceList) { $aSourceDirsHierarhy = array(); $oSourceListDir = $oSourceList->List_Dir; while ($oSourceListDir->id) { $aSourceDirsHierarhy[] = $oSourceListDir->name; $oSourceListDir = $oSourceListDir->List_Dir; } $aSourceDirsHierarhy = array_reverse($aSourceDirsHierarhy); // $oDestSite = $this->_DestShop->Site; if (empty($aSourceDirsHierarhy)) { $oDestTopLists = $oDestSite->Lists; $oDestTopLists->queryBuilder() ->where('list_dir_id', '=', 0); return $oDestTopLists->getByName($oSourceList->name, false); } else { $oDestListDirs = $oDestSite->List_Dirs; $oDestListDirs->queryBuilder() ->where('parent_id', '=', 0); $oDestListDir = null; foreach ($aSourceDirsHierarhy as $sourceDirName) { $oDestListDir = $oDestListDirs->getByName($sourceDirName); if ($oDestListDir) { $oDestListDirs = $oDestListDir->List_Dirs; } else { break; } } return $oDestListDir ? $oDestListDir->Lists->getByName($oSourceList, false) : null; } } /** * Возвращает доп. свойство в новом сайте по структуре доп. свойств старого сайта * * Например, если в исходном сайте есть доп. свойство: * Сайт №1 / Раздел №1 / Раздел №2 / Исходное доп. свойство, * * то функция возвратит доп. свойство, вложеное в такие же разделы, как и исходный * Сайт №2 / Раздел №1 / Раздел №2 / Новое доп. свойство, * * @param List_Model $oSourceList * @return List_Model */ protected function _getDestProperty($propertyList, Property_Model $oSourceProperty) { $oDestObjectPropertyList = Core_Entity::factory($propertyList, $this->_DestShop->id); $aSourceDirsHierarhy = array(); $oSourcePropertyDir = $oSourceProperty->Property_Dir; while ($oSourcePropertyDir->id) { $aSourceDirsHierarhy[] = $oSourcePropertyDir->name; $oSourcePropertyDir = $oSourcePropertyDir->Property_Dir; } $aSourceDirsHierarhy = array_reverse($aSourceDirsHierarhy); // if (empty($aSourceDirsHierarhy)) { $oDestTopProperties = $oDestObjectPropertyList->Properties; $oDestTopProperties->queryBuilder() ->where('property_dir_id', '=', 0); return $oDestTopProperties->getByName($oSourceProperty->name, false); } else { $oDestPropertyDirs = $oDestObjectPropertyList->Property_Dirs; $oDestPropertyDirs->queryBuilder() ->where('parent_id', '=', 0); $oDestPropertyDir = null; foreach ($aSourceDirsHierarhy as $sourceDirName) { $oDestPropertyDir = $oDestPropertyDirs->getByName($sourceDirName, false); if ($oDestPropertyDir) { $oDestPropertyDirs = $oDestPropertyDir->Property_Dirs; } else { break; } } return $oDestPropertyDir ? $oDestPropertyDir->Properties->getByName($oSourceProperty->name, false) : null; } } /** * Переносит списки, используемые в доп. свойствах исходного интернет-магазина * * @param List_Dir_Model $oSourceListDir=null * @param List_Dir_Model $oDestParentDir = null */ protected function _transferLists(List_Dir_Model $oSourceListDir = null, List_Dir_Model $oDestParentDir = null) { $this->_log('Transfer lists.'); $oSourceSite = $this->_SourceShop->Site; $oDestSite = $this->_DestShop->Site; $oSourceShopListIds = $this->_getShopListIds($this->_SourceShop); $oSourceTopLists = $oSourceSite->Lists; $oSourceTopLists->queryBuilder() ->where('list_dir_id', '=', 0); $oSourcesTopListDirs = $oSourceSite->List_Dirs; $oSourcesTopListDirs->queryBuilder() ->where('parent_id', '=', 0); if (!$oSourceListDir) { $oSourceLists = $oSourceTopLists; $oSourceListDirs = $oSourcesTopListDirs; $oDestListDir = null; } else { $oSourceLists = $oSourceListDir->Lists; $oSourceListDirs = $oSourceListDir->List_Dirs; if (!$oDestParentDir) { $oDestTopListDirs = $oDestSite->List_Dirs; $oDestTopListDirs->queryBuilder() ->where('parent_id', '=', 0); $oDestListDir = $oDestTopListDirs->getByName($oSourceListDir->name); } else { $oDestListDir = $oDestParentDir->List_Dirs->getByName($oSourceListDir->name); } if (!$oDestListDir) { $oDestListDir = clone $oSourceListDir; $oDestListDir->parent_id = 0; $oDestSite->add($oDestListDir); if ($oDestParentDir) { $oDestList->add($oDestParentDir); } } } // var_dump(count($oSourceTopLists->findAll())); // Перенисим списки $aoSourceLists = $oSourceLists->findAll(); foreach ($aoSourceLists as $oSourceList) { if (!in_array($oSourceList->id, $oSourceShopListIds)) { continue; } $oDestTopLists = $oDestSite->Lists; $oDestTopLists->queryBuilder() ->where('list_dir_id', '=', 0); if (!$oDestListDir) { $oDestList = $oDestTopLists->getByName($oSourceList->name); } else { $oDestList = $oDestListDir->Lists->getByName($oSourceList->name); } if (!$oDestList) { $oDestList = clone $oSourceList; $oDestList->list_dir_id = 0; $oDestSite->add($oDestList); if ($oDestListDir) { $oDestList->add($oDestListDir); } // Элементы списка $aoSourceListItems = $oSourceList->List_Items->findAll(); foreach ($aoSourceListItems as $oSourceListItem) { $oDestListItem = clone $oSourceListItem; $oDestListItem->add($oDestList); } $this->_log("Transfer list {$oDestList->id}."); } } // Переносим разделы списков $aoSourceListDirs = $oSourceListDirs->findAll(); foreach ($aoSourceListDirs as $oSourceListDir) { $this->_transferLists($oSourceListDir, $oDestListDir); } } /** * Возвращает массив идентификаторов списков, используемых в интернет-магазине $oShop * * @param Shop_Model $oShop * @return array */ protected function _getShopListIds(Shop_Model $oShop) { $oSite = $oShop->Site; $oLists = $oSite->Lists; $oLists->queryBuilder() ->select('lists.*') ->join('properties', 'properties.list_id', '=', 'lists.id') ->leftJoin('shop_item_properties', 'shop_item_properties.property_id', '=', 'properties.id') ->leftJoin('shop_group_properties', 'shop_group_properties.property_id', '=', 'properties.id') ->open() ->where('shop_item_properties.shop_id', '=', $oShop->id) ->setOr() ->where('shop_group_properties.shop_id', '=', $oShop->id) ->close(); $aoLists = $oLists->findAll(); $aListIds = array(); foreach ($aoLists as $oList) { if (!in_array($oList->id, $aListIds)) { $aListIds[] = $oList->id; } } return $aListIds; } /** * Переносит справочники */ protected function _transferReferencies() { // Переносим скидки $this->_transferShopDiscounts(); // Переносим цены $this->_transferShopPrices(); // Переносим склады $this->_transferShopWarehouses(); } /** * Переносит справочник скидкок */ protected function _transferShopDiscounts() {} /** * Переносит справочник складов */ protected function _transferShopWarehouses() {} /** * Переносит справочник цен * */ protected function _transferShopPrices() { $aoSourceShopPrices = $this->_SourceShop->Shop_Prices->findAll(); foreach ($aoSourceShopPrices as $oSourceShopPrice) { $oSourceShopPrices = $this->_DestShop->Shop_Prices; $oDestShopPrice = $oSourceShopPrices->getByName($oSourceShopPrice->name); if (!$oDestShopPrice) { $oDestShopPrice = clone $oSourceShopPrice; $oDestShopPrice->add($this->_DestShop); } } } /** * Вполняет лог сообщения * */ protected function _log($log) { print $log . '<br />'; } } // Action $shopTranferer = new ShopTransferer( Core_Entity::factory('Shop')->getById(3), Core_Entity::factory('Shop')->getById(19) ); $shopTranferer->execute(); exit();
Страницу создал Максим Засорин 09.05.16 в 22:06