_select) { $this->_select = new Zend_Db_Select($this->_getDbAdapter()); } return $this->_select->reset(); } protected function _getDbAdapter() { return $this->_dbAdapter; } public function processConfigurableProducts(array $productsSkuList, Product_Import $import) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); /** @var Orange35_ProductImport_Helper_Data $helper */ $helper = Mage::app()->getHelper('orange35_productImport'); $this->_dbAdapter = $import->getDbAdapter(); $this->_importObj = clone $import; $this->_importObj->getAttributesManager()->setAttributeFilter('base_cloth'); if (!empty($productsSkuList)) { $helper->log(array('message' => "Process configurable products: BEGIN PROCESS"), true); Mage::helper('orange35_productImport/timer')->addTimer('Create configurable products'); $productGroups = $this->_getProductGroups($productsSkuList); $helper->log(array('message' => "Process configurable products: created product groups")); $importProducts = array(); foreach ($productGroups as $groupKey => $products) { $preparedProductsArray = $this->_prepareGroupProducts($products); $beads = $preparedProductsArray['beads']; $bases = $preparedProductsArray['bases']; $threads = $preparedProductsArray['threads']; $specialSizeProduct = $preparedProductsArray['special']; $configurableProduct = $preparedProductsArray['configurable']; if (count($bases) > 1) { $firstBlank = $this->_getFirstProductWithImages($bases); if (!array_key_exists($firstBlank['attribute_set_id'], $conf->configurableAttributes)) { continue; } $configurableProduct = $this->_getConfigurableProduct( $configurableProduct, $firstBlank, $bases, $conf->configurableAttributes[$firstBlank['attribute_set_id']] ); $configurableProduct['sku'] = 'configurable_' . $groupKey; $this->_addProductComponentsAsCustomOptions($configurableProduct, $beads, $threads); if ($firstBlank['attribute_set_id'] == Orange35_ProductImport_Helper_Config::ATTRIBUTE_SET_CLOTHING_BASE && $specialSizeProduct ) { $this->_addCustomSizeOptions($configurableProduct, $specialSizeProduct); } $importProducts[] = $configurableProduct; if ($beads) { $beads['manage_stock'] = 0; $importProducts[] = $beads; } if ($threads) { $threads['manage_stock'] = 0; $importProducts[] = $threads; } $importProducts = array_merge($importProducts, $bases); } else if ($product = reset($bases)) { $this->_addProductComponentsAsCustomOptions($product, $beads, $threads); $importProducts[] = $product; } if ($specialSizeProduct) { $specialSizeProduct['custom_options'] = array_merge( $configurableProduct['custom_options'], $this->_getAdditionCustomOptions() ); $specialSizeProduct['visibility'] = 'Not Visible Individually'; $importProducts[] = $specialSizeProduct; } } Mage::helper('orange35_productImport/timer')->addTimer('Create products list'); /** @var Product_Import_Adapter_Array $adapter */ $adapter = $import->getImportAdapter(); $helper->log("Process configurable products: created products list"); $adapter->setProductsData($importProducts); $import->processDataImport(); Mage::helper('orange35_productImport/timer')->addTimer('Create Components'); $helper->log("Process configurable products: END PROCESS. START PROCESS Components"); $importProducts = $this->_processComponents($productGroups); $adapter->setProductsData($importProducts); Mage::helper('orange35_productImport/timer')->addTimer('Insert/Update Components'); $import->processDataImport(); $helper->log("Process configurable products: END PROCESS Components", true); } return $this; } protected function _processComponents($productGroups) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $importProducts = array(); foreach ($productGroups as $groupKey => $products) { $products = $this->_prepareComponentGroups($products); foreach ($products as $attributeSet => $relatedProducts) { if (!array_key_exists($attributeSet, $conf->configurableAttributes)) { continue; } if (count($relatedProducts['simple']) <= 1) { continue; } $configurableProduct = isset($relatedProducts['configurable']) ? $relatedProducts['configurable'] : null; $configurableProduct = $this->_getConfigurableProduct( $configurableProduct, $this->_getFirstProductWithImages($relatedProducts['simple']), $relatedProducts['simple'], $conf->configurableAttributes[$attributeSet] ); $configurableProduct['sku'] = 'configurable_' . $groupKey . '_' . $attributeSet; $importProducts[] = $configurableProduct; $importProducts = array_merge($importProducts, $relatedProducts['simple']); } } return $importProducts; } protected function _prepareComponentGroups($products) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $productsGroupedByAttributeSet = array(); foreach ($products as $productInfo) { if (in_array($productInfo['attribute_set_id'], $conf->configurableProductBases)) { continue; } if ('simple' === $productInfo['type_id']) { $attributeSet = $productInfo['attribute_set_id']; $id = $productInfo['entity_id']; $productsGroupedByAttributeSet[$attributeSet]['simple'][$id] = $productInfo; } else { $productsGroupedByAttributeSet[$productInfo['attribute_set_id']]['configurable'] = $productInfo; } } return $productsGroupedByAttributeSet; } protected function _getFirstProductWithImages($products) { foreach ($products as $product) { if ($product['hasImages']) { return $product; } } return reset($products); } protected function _getMinOptPrice($childProductsIds) { $select = new Zend_Db_Select($this->_getDbAdapter()); $where = 'customer_group_id = ' . Orange35_ProductImport_Helper_Config::OPT_CUSTOMER_GROUP_ID . ' AND entity_id IN (\'' . implode('\',\'', $childProductsIds) . '\')'; $select->from('catalog_product_entity_group_price', array('min_price' => 'MIN(value)')) ->where($where); $result = $select->query()->fetch(); return $result['min_price']; } protected function _getMinPrice($childProductsIds) { $select = new Zend_Db_Select($this->_getDbAdapter()); $where = 'attribute_id = ' . Orange35_ProductImport_Helper_Config::EAV_ATTRIBUTE_PRICE_CODE . ' AND entity_type_id = ' . Product_Import::PRODUCT_TYPE_ID . ' AND entity_id IN (\'' . implode('\',\'', $childProductsIds) . '\')'; $select->from('catalog_product_entity_decimal', array('MIN(value)')) ->where($where); $result = $select->query()->fetch(); return reset($result); } protected function _getAdditionCustomOptions() { if (null == $this->_additionCustomOptions) { $this->_additionCustomOptions = $this->_initAdditionCustomOptions(); } return $this->_additionCustomOptions; } protected function _initAdditionCustomOptions() { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $customOptions = array(); $storesWhereString = '(\'' . $conf->storesMap[Orange35_ProductImport_Helper_Config::RUS_STORE_ALIAS] . '\',\'' . $conf->storesMap[Orange35_ProductImport_Helper_Config::ENG_STORE_ALIAS] . '\',\'' . $conf->storesMap[Orange35_ProductImport_Helper_Config::UKR_STORE_ALIAS] . '\',\'0\')'; $processAttributes = array( Orange35_ProductImport_Helper_Config::BASE_COLOR_ATTRIBUTE_ID, Orange35_ProductImport_Helper_Config::BASE_CLOTH_ATTRIBUTE_ID, ); foreach ($processAttributes as $attributeId) { $attributeInfo = $this->_importObj->getAttributesManager()->getAttribute($attributeId); $newOption = array( 'type' => 'drop_down', 'title' => $attributeInfo['frontend_label'], ); $select = $this->_getSelect(); $where = 'attribute_id = ' . $attributeId . ' AND store_id IN ' . $storesWhereString; $select->from('eav_attribute_label', array('store_id', 'value')) ->where($where); $result = $select->query()->fetchAll(); foreach ($result as $row) { switch ($row['store_id']) { case Product_Import::DEFAULT_STORE_ID: $newOption['title'] = $row['value']; break; case $conf->storesMap[Orange35_ProductImport_Helper_Config::UKR_STORE_ALIAS]: $newOption['title_ua'] = $row['value']; break; case $conf->storesMap[Orange35_ProductImport_Helper_Config::RUS_STORE_ALIAS]: $newOption['title_ru'] = $row['value']; break; case $conf->storesMap[Orange35_ProductImport_Helper_Config::ENG_STORE_ALIAS]: $newOption['title_en'] = $row['value']; break; default: } } $options = $this->_getAdditionCustomOptionChildOptions($attributeId); $newOption['options'] = $options; $customOptions[] = $newOption; } return $customOptions; } protected function _getAdditionCustomOptionChildOptions($attributeId) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $select = $this->_getSelect(); $storesWhereString = '(\'' . $conf->storesMap[Orange35_ProductImport_Helper_Config::RUS_STORE_ALIAS] . '\',\'' . $conf->storesMap[Orange35_ProductImport_Helper_Config::ENG_STORE_ALIAS] . '\',\'' . $conf->storesMap[Orange35_ProductImport_Helper_Config::UKR_STORE_ALIAS] . '\',\'0\')'; $joinWhere = 'j.attribute_id = ' . $attributeId . ' AND m.option_id = j.option_id' . ' AND store_id IN ' . $storesWhereString; $select->from(array('m' => 'eav_attribute_option_value'), array('option_id', 'store_id', 'value')) ->join(array('j' => 'eav_attribute_option'), $joinWhere); $result = $select->query()->fetchAll(); $options = array(); foreach ($result as $row) { $id = $row['option_id']; if (!isset($options[$id])) { $options[$id] = array( 'price' => 0, 'sku' => '', ); } switch ($row['store_id']) { case Product_Import::DEFAULT_STORE_ID: $options[$id]['title'] = $row['value']; break; case $conf->storesMap[Orange35_ProductImport_Helper_Config::UKR_STORE_ALIAS]: $options[$id]['title_ua'] = $row['value']; break; case $conf->storesMap[Orange35_ProductImport_Helper_Config::RUS_STORE_ALIAS]: $options[$id]['title_ru'] = $row['value']; break; case $conf->storesMap[Orange35_ProductImport_Helper_Config::ENG_STORE_ALIAS]: $options[$id]['title_en'] = $row['value']; break; default: } } return $options; } protected function _getProductGroups(array $productsSkuList) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $select = new Zend_Db_Select($this->_dbAdapter); $where = 'v.entity_id = p.entity_id' . ' AND p.sku IN (\'' . implode('\',\'', $productsSkuList) . '\')' . ' AND v.attribute_id = ' . $conf->groupKeyAttributeId; $select->from(array('v' => 'catalog_product_entity_varchar'), array('value')) ->distinct() ->join(array('p' => 'catalog_product_entity'), $where, null); $groupKeysList = $select->query()->fetchAll(); foreach ($groupKeysList as $key => $value) { $groupKey = reset($value); if ($groupKey) { $groupKeysList[$key] = reset($value); } } $where = 'v.entity_id = p.entity_id' . ' AND v.value IN (\'' . implode('\',\'', $groupKeysList) . '\')' . ' AND v.store_id = ' . Product_Import::DEFAULT_STORE_ID . ' AND p.attribute_set_id IN ("' . implode('","', array_keys($conf->configurableAttributes)) . '")'; $select->reset() ->from(array('p' => 'catalog_product_entity'), array( 'attribute_set_id', 'entity_id', 'type_id', 'sku' )) ->join( array('v' => 'catalog_product_entity_varchar'), $where, array('group_key' => 'value') ) ->columns(array( 'hasImages' => new Zend_Db_Expr( 'EXISTS(SELECT 1 FROM catalog_product_entity_media_gallery AS g WHERE g.entity_id = p.entity_id LIMIT 1)' ) )) ->order('p.entity_id'); $productsList = $select->query()->fetchAll(); $productGroups = array(); foreach ($productsList as $productInfo) { $groupKey = $productInfo['group_key']; if ($groupKey) { if (!isset($productGroups[$groupKey])) { $productGroups[$groupKey] = array(); } $productGroups[$groupKey][$productInfo['entity_id']] = $productInfo; } } return $productGroups; } protected function _prepareGroupProducts($groupedProducts) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $select = new Zend_Db_Select($this->_getDbAdapter()); $configurableProduct = null; $beads = null; $threads = null; $bases = array(); $specialSizeProduct = null; foreach ($groupedProducts as $productInfo) { if ('simple' == $productInfo['type_id']) { if (Orange35_ProductImport_Helper_Config::ATTRIBUTE_SET_BEADS_SET == $productInfo['attribute_set_id']) { $beads = $productInfo; } else if (Orange35_ProductImport_Helper_Config::ATTRIBUTE_SET_THREADS_SET == $productInfo['attribute_set_id']) { $threads = $productInfo; } else if (in_array($productInfo['attribute_set_id'], $conf->configurableProductBases)) { $bases[$productInfo['entity_id']] = $productInfo; } } else if ('configurable' == $productInfo['type_id'] && in_array($productInfo['attribute_set_id'], $conf->configurableProductBases) ) { $configurableProduct = $productInfo; } if (!empty($bases)) { $where = 'entity_id IN (\'' . implode('\',\'', array_keys($bases)) . '\') AND attribute_id = ' . Orange35_ProductImport_Helper_Config::SPECIAL_SIZE_ATTRIBUTE . ' AND value = 1'; $select->reset() ->from('catalog_product_entity_int', array('entity_id')) ->where($where); $row = $select->query()->fetch(); if ($row) { $entityId = reset($row); $specialSizeProduct = $bases[$entityId]; unset($bases[$entityId]); } } } return array( 'bases' => $bases, 'beads' => $beads, 'threads' => $threads, 'special' => $specialSizeProduct, 'configurable' => $configurableProduct, ); } protected function _prepareConfigurableAttributes(&$attributes, $collection) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $productIds = array_keys($collection); $db = $this->_getDbAdapter(); $select = new Zend_Db_Select($db); $select->from('catalog_category_product', array('category_id')) ->where($db->quoteInto('product_id IN (?)', $productIds)); $categories = $db->fetchCol($select); if (count(array_intersect($conf->basesCategoriesExcludeSize, $categories))) { if (false !== ($key = array_search('base_size', $attributes))) { unset($attributes[$key]); } if (false !== ($key = array_search('picture_size', $attributes))) { unset($attributes[$key]); } } if (count(array_intersect($conf->basesCategoriesIncludeFashion, $categories))) { $attributes[] = 'fashion'; } return $this; } protected function _getConfigurableProduct( $configurableProduct, $simpleProduct, &$collection, $configurableAttributes ) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $this->_prepareConfigurableAttributes($configurableAttributes, $collection); if (null == $configurableProduct) { $configurableProduct = $this->_cloneProduct($simpleProduct); $configurableProduct['manage_stock'] = false; $configurableProduct['type_id'] = 'configurable'; } $childProducts = array(); $childProductsIds = array(); foreach ($collection as &$blank) { $blank['visibility'] = 'Not Visible Individually'; $blank['custom_options'] = array(); $blank['use_config_manage_stock'] = 0; $blank['manage_stock'] = 0; $childProducts[] = $blank['sku']; $childProductsIds[] = $blank['entity_id']; } $configurableProduct['price'] = $this->_getMinPrice($childProductsIds); $configurableProduct['price_opt'] = $this->_getMinOptPrice($childProductsIds); $configurableProduct['_child_products'] = $childProducts; $configurableProduct['_configurable_attributes'] = $configurableAttributes; $configurableProduct['use_config_manage_stock'] = 0; $configurableProduct['manage_stock'] = 0; $configurableProduct['visibility'] = 'Catalog, Search'; $configurableProduct['status'] = 'Enabled'; $configurableProduct['attribute_set'] = array_search( $configurableProduct['attribute_set_id'], $conf->attributeSetsMap ); return $configurableProduct; } protected function _addProductComponentsAsCustomOptions(&$product, $beads, $threads) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $options = array(); if ($beads) { $beadsOption = array( 'sku' => $beads['sku'], 'price' => 0, ); foreach ($conf->beadsCustomOptionsTitles as $alias => $title) { if ($alias === 0) { $beadsOption['title'] = $title; } else { $beadsOption['title_' . $alias] = $title; } } $options[] = $beadsOption; } if ($threads) { $threadsOption = array( 'sku' => $threads['sku'], 'price' => 0, ); foreach ($conf->threadsCustomOptionsTitles as $alias => $title) { if ($alias === 0) { $threadsOption['title'] = $title; } else { $threadsOption['title_' . $alias] = $title; } } $options[] = $threadsOption; } if (!empty($options)) { $customOption = array( 'type' => 'checkbox', 'options' => $options, ); foreach ($conf->customOptionsTitles as $alias => $title) { if ($alias === 0) { $customOption['title'] = $title; } else { $customOption['title_' . $alias] = $title; } } $product['custom_options'] = array($customOption); } return $this; } protected function _addCustomSizeOptions(&$product, $specialSizeProduct) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $customSizeOptions = $conf->customSizeOptions; $customSizeOptions[1]['options'][0]['sku'] = $specialSizeProduct['sku']; $customSizeOptions = array_merge( array_slice($customSizeOptions, 0, 1), $this->_getAdditionCustomOptions(), array_slice($customSizeOptions, 1) ); $customSizeOptions = array_values($customSizeOptions); if (isset($product['custom_options'])) { $product['custom_options'] = array_merge($product['custom_options'], $customSizeOptions); } else { $product['custom_options'] = $customSizeOptions; } return $this; } protected function _getAttributeSetsIdsList() { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); if (null == $conf->attributeSetsIdsList) { $attributeSetsItdList = array(); foreach ($conf->attributeSetsMap as $alias => $id) { $attributeSetsItdList[$id] = $alias; } $conf->attributeSetsIdsList = $attributeSetsItdList; } return $conf->attributeSetsIdsList; } protected function _getAttributeCode($attributeCode, $storeId) { $storesMapIdsList = $this->_getStoresMapIdsList(); if (isset($storesMapIdsList[$storeId])) { return $attributeCode . '_' . $storesMapIdsList[$storeId]; } return $attributeCode; } protected function _getStoresMapIdsList() { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); if (null == $this->_storesMapIdsList) { $storesMapIdsList = array(); foreach ($conf->storesMap as $alias => $storeId) { $storesMapIdsList[$storeId] = $alias; } $this->_storesMapIdsList = $storesMapIdsList; } return $this->_storesMapIdsList; } protected function _cloneProduct($product) { /** @var Orange35_ProductImport_Helper_Config $conf */ $conf = Mage::app()->getHelper('orange35_productImport/config'); $preparedProduct = $product; $attributeSetsIdsList = $this->_getAttributeSetsIdsList(); $preparedProduct['attribute_set'] = $attributeSetsIdsList[$product['attribute_set_id']]; $import = $this->_importObj; $select = new Zend_Db_Select($this->_getDbAdapter()); foreach ($conf->entityValueTablesList as $table) { $select->reset() ->from($table, array('attribute_id', 'value', 'store_id')) ->where('entity_id = ' . $product['entity_id']); $rows = $select->query()->fetchAll(); foreach ($rows as $attributeValue) { $attributeInfo = $import->getAttributesManager()->getAttribute($attributeValue['attribute_id']); if (!in_array($attributeInfo['attribute_code'], $conf->nonClonedAttributeCodes) && null != $attributeValue['value'] ) { $attributeCode = $this->_getAttributeCode( $attributeInfo['attribute_code'], $attributeValue['store_id'] ); $value = $attributeValue['value']; $preparedProduct[$attributeCode] = $value; } } } $this->_cloneCategoryIds($product, $preparedProduct); $this->_cloneWebsiteIds($product, $preparedProduct); $this->_cloneImages($product, $preparedProduct); return $preparedProduct; } protected function _cloneCategoryIds($product, &$preparedProduct) { $select = new Zend_Db_Select($this->_getDbAdapter()); $select->from('catalog_category_product') ->where('product_id = ' . $product['entity_id']); $categoryIds = array(); $rows = $select->query()->fetchAll(); foreach ($rows as $row) { $categoryId = $row['category_id']; if (!in_array($categoryId, $categoryIds)) { $categoryIds[] = $categoryId; } } $preparedProduct['category_ids'] = implode(',', $categoryIds); return $this; } protected function _cloneWebsiteIds($product, &$preparedProduct) { $select = new Zend_Db_Select($this->_getDbAdapter()); $select->from('catalog_product_website') ->where('product_id = ' . $product['entity_id']); $websiteIds = array(); $rows = $select->query()->fetchAll(); foreach ($rows as $row) { $websiteId = $row['website_id']; if (!in_array($websiteId, $websiteIds)) { $websiteIds[] = $websiteId; } } $preparedProduct['website_ids'] = implode(',', $websiteIds); return $this; } protected function _cloneImages($product, &$preparedProduct) { $select = new Zend_Db_Select($this->_getDbAdapter()); $select->from('catalog_product_entity_media_gallery') ->where('entity_id = ' . $product['entity_id']); $images = array(); $rows = $select->query()->fetchAll(); foreach ($rows as $row) { $image = $row['value']; if (!in_array($image, $images)) { $images[] = $image; } } if (!empty($images)) { $preparedProduct['image'] = implode(',', $images); } return $this; } }