├── LICENSE ├── README.MD ├── export.php ├── import_arrtibute_set.php ├── bootstrap.php ├── import.php ├── export_attribute_set.php ├── export_attribute.php ├── prepare_products.php ├── import_arrtibute.php └── export_product.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sunel Tr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | ## Magento Export & Import Script 2 | 3 | ### Note 4 | 5 | !!! DONT NOT USE IN PRODUCTION DIRECTLY !!! 6 | 7 | Please go through each script files and modify the code according to you needs. The code is written based on assumptions. 8 | 9 | Read through the file, you will find comments that will help you understand the code. 10 | 11 | Improvements are welcomed. 12 | 13 | ### Setup 14 | 15 | Move the files to shell directory of your magento installation. 16 | 17 | In the export.php file 18 | 19 | ```php 20 | $attributeSetNames = array( 21 | 'Default' 22 | ); 23 | ``` 24 | 25 | Add the attribute set that you need to export 26 | 27 | 28 | ### Export 29 | 30 | Run the script 31 | 32 | ```bash 33 | $ php export.php --set --attr --products 34 | ``` 35 | 36 | The above will export Attribute Set, Attribute, Product. 37 | 38 | The options will let the script what to export 39 | 40 | `--set` will export Attribute Set 41 | 42 | `--attr` will export Attribute 43 | 44 | `--products` will export Product 45 | 46 | 47 | > It will create three csv files "importAttributeSet.csv" "importAttribute.csv" "product.csv" by default. You can change the file name if you need. 48 | 49 | 50 | ### Import 51 | 52 | Run the script 53 | 54 | ```bash 55 | $ php import.php --set --attr 56 | ``` 57 | 58 | The above will import Attribute Set, Attribute 59 | 60 | 61 | To Import Product use [magmi](http://wiki.magmi.org/) `RECOMMENDED` 62 | 63 | 64 | To increase the import performace and also to fully support magmi run 65 | 66 | 67 | ```bash 68 | $ php prepare_products.php 69 | ``` 70 | 71 | 72 | This will split the product csv into smaller chunks of csv (count of 500 per file) and then modifies the files to support magmi 73 | 74 | -------------------------------------------------------------------------------- /export.php: -------------------------------------------------------------------------------- 1 | export($attributeSetNames, $fileName, Arguments::getArg('products')); 32 | 33 | unset($attrSetExporter); 34 | 35 | echo "\nMEMORY USED : ".convert(memory_get_usage(true)) . "\n\n"; 36 | } 37 | 38 | 39 | /* 40 | |-------------------------------------------------------------------------- 41 | | Attribute Export 42 | |-------------------------------------------------------------------------- 43 | */ 44 | 45 | if (Arguments::getArg('attr')) { 46 | echo "Collecting all attribute..... \n"; 47 | 48 | $fileName = MAGENTO . '/var/importAttribute.csv'; 49 | 50 | $attrExporter = new ArrtibuteExporter(); 51 | 52 | $attrExporter->export(array_unique($result[0]), $fileName); 53 | 54 | unset($attrExporter); 55 | 56 | echo "\nMEMORY USED : ".convert(memory_get_usage(true)) . "\n\n"; 57 | } 58 | 59 | /* 60 | |-------------------------------------------------------------------------- 61 | | Product Export 62 | |-------------------------------------------------------------------------- 63 | */ 64 | 65 | 66 | if (Arguments::getArg('products')) { 67 | echo "Collecting all product..... \n"; 68 | 69 | $fileName = MAGENTO . '/var/product.csv'; 70 | 71 | // Execute the product export 72 | $exporter = new ProductExporter(); 73 | 74 | $exporter->export(array_unique($result[1]), $fileName); 75 | 76 | echo "\n"; 77 | echo "$fileName \n\n"; 78 | 79 | unset($exporter); 80 | 81 | echo "MEMORY USED : ".convert(memory_get_usage(true)) . "\n"; 82 | } 83 | -------------------------------------------------------------------------------- /import_arrtibute_set.php: -------------------------------------------------------------------------------- 1 | getStores(); 16 | foreach ($allStores as $_eachStoreId => $val) { 17 | $this->_storeIds[] = Mage::app()->getStore($_eachStoreId)->getId(); 18 | } 19 | $this->_attributeSetModel = Mage::getModel('eav/entity_setup', 'core_write'); 20 | $this->_entityTypeId = Mage::getModel('catalog/product')->getResource()->getTypeId(); 21 | } 22 | 23 | public function import($fileName) 24 | { 25 | echo "Reading $fileName.\n"; 26 | $file = fopen($fileName, "r"); 27 | while (!feof($file)) { 28 | $csv[] = fgetcsv($file, 0, ','); 29 | } 30 | $keys = array_shift($csv); 31 | foreach ($csv as $i=>$row) { 32 | $csv[$i] = array_combine($keys, $row); 33 | } 34 | 35 | $currentSet = null; 36 | foreach ($csv as $row) { 37 | if (trim($row['ID']) != '') { 38 | $currentSet = $row['NAME']; 39 | $this->_groups[$currentSet] = array('sku'=>explode(';', $row['PRODUCT SKU'])); 40 | 41 | echo "Creating Attribute Set [$currentSet].\n"; 42 | $this->_attributeSetModel->addAttributeSet($this->_entityTypeId, $currentSet); 43 | } else { 44 | $this->_groups[$currentSet]['groups'][] = array( 45 | 'name'=>$row['NAME'], 46 | 'attributes'=>explode(';', $row['DEFAULT GROUP']) 47 | ); 48 | } 49 | } 50 | echo "MEMORY USED : ".convert(memory_get_usage(true)) . "\n"; 51 | 52 | $this->processAtributeGroup($this->_groups); 53 | fclose($file); 54 | unset($csv, $keys, $file); 55 | 56 | echo "MEMORY USED : ".convert(memory_get_usage(true)) . "\n"; 57 | } 58 | 59 | 60 | protected function processAtributeGroup($sets) 61 | { 62 | foreach ($sets as $setId => $setInfo) { 63 | echo "Adding Group to Attribute Set [$setId].\n"; 64 | foreach ($setInfo['groups'] as $_group) { 65 | if(!empty($_group['name'])) { 66 | $this->_attributeSetModel->addAttributeGroup($this->_entityTypeId, $setId, $_group['name']); 67 | echo " Adding Attribute to Group [".$_group['name']."].\n"; 68 | foreach ($_group['attributes'] as $_attribute) { 69 | $attribute = explode('/', $_attribute); 70 | if(!empty($attribute[0])) { 71 | echo " ->Adding [".$attribute[0]."]\n"; 72 | $this->_attributeSetModel->addAttributeToSet($this->_entityTypeId, $setId, $_group['name'], $attribute[0]); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /bootstrap.php: -------------------------------------------------------------------------------- 1 | _parseArgs(); 33 | } 34 | 35 | /** 36 | * Parse input arguments 37 | * 38 | * @return Mage_Shell_Abstract 39 | */ 40 | protected function _parseArgs() 41 | { 42 | $current = null; 43 | foreach ($_SERVER['argv'] as $arg) { 44 | $match = array(); 45 | if (preg_match('#^--([\w\d_-]{1,})$#', $arg, $match) || preg_match('#^-([\w\d_]{1,})$#', $arg, $match)) { 46 | $current = $match[1]; 47 | static::$_args[$current] = true; 48 | } else { 49 | if ($current) { 50 | static::$_args[$current] = $arg; 51 | } elseif (preg_match('#^([\w\d_]{1,})$#', $arg, $match)) { 52 | static::$_args[$match[1]] = true; 53 | } 54 | } 55 | } 56 | return $this; 57 | } 58 | 59 | /** 60 | * Retrieve argument value by name or false 61 | * 62 | * @param string $name the argument name 63 | * @return mixed 64 | */ 65 | public static function getArg($name) 66 | { 67 | if (isset(static::$_args[$name])) { 68 | return static::$_args[$name]; 69 | } 70 | return false; 71 | } 72 | 73 | 74 | /** 75 | * Check if argumnets are given 76 | * 77 | * @return bool 78 | */ 79 | public static function hasArgs() 80 | { 81 | return count(static::$_args) !== 0; 82 | } 83 | } 84 | 85 | 86 | new Arguments(); 87 | 88 | function convert($size) 89 | { 90 | $unit=array('b','kb','mb','gb','tb','pb'); 91 | return @round($size/pow(1024, ($i=floor(log($size, 1024)))), 2).' '.$unit[$i]; 92 | } 93 | 94 | 95 | function writeCsv($attributesCollection, $filename = "import.csv", $delimiter = '|', $enclosure = '"') 96 | { 97 | $f = fopen($filename, "w") or die("Unable to open file!"); 98 | $first = true; 99 | foreach ($attributesCollection as $line) { 100 | if ($first) { 101 | $titles = array(); 102 | foreach ($line as $field => $val) { 103 | $titles[] = $field; 104 | } 105 | fputcsv($f, $titles, $delimiter, $enclosure); 106 | $first = false; 107 | } 108 | fputcsv($f, $line, $delimiter, $enclosure); 109 | } 110 | fclose($f); 111 | echo "MEMORY USED : ".convert(memory_get_usage(true)) . "\n"; 112 | echo "csv dumped to $filename \n\n"; 113 | } 114 | -------------------------------------------------------------------------------- /import.php: -------------------------------------------------------------------------------- 1 | getConnection('core_read'); 22 | 23 | $attribute_sets = $db_read->fetchCol("SELECT attribute_set_id FROM " . $resource->getTableName("eav_attribute_set") . " WHERE attribute_set_id<> 4 AND entity_type_id=4"); 24 | foreach ($attribute_sets as $attribute_set_id) { 25 | try { 26 | Mage::getModel("eav/entity_attribute_set")->load($attribute_set_id)->delete(); 27 | } catch (Exception $e) { 28 | echo $e->getMessage() . "\n"; 29 | } 30 | } 31 | */ 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | Attribute Delete 36 | |-------------------------------------------------------------------------- 37 | | To delete attributes just create a csv file with name oldAttributes and 38 | | uncomment the below section and run it. 39 | | 40 | */ 41 | 42 | /* 43 | $fileName = MAGENTO . '/var/oldAttributes.csv'; 44 | $file = fopen($fileName,"r"); 45 | $oldCode = array(); 46 | while(!feof($file)){ 47 | $tmpCode = fgetcsv($file, 0, ','); 48 | if(is_array($tmpCode)){ 49 | $oldCode[] = $tmpCode[0]; 50 | } 51 | } 52 | fclose($file); 53 | 54 | $attrCollection = Mage::getResourceModel('catalog/product_attribute_collection') 55 | ->addFilter('is_user_defined','1') 56 | ->addFieldToFilter('main_table.attribute_code', array('in' => $oldCode)); 57 | foreach($attrCollection as $_attibute) { 58 | if ($_attibute->getIsUserDefined()) { 59 | try { 60 | $_attibute->delete(); 61 | } catch (Exception $e) { 62 | echo $_attibute->getAttributeCode()." -- ".$e->getMessage() .'\n'; 63 | 64 | } 65 | } 66 | } 67 | */ 68 | 69 | /* 70 | |-------------------------------------------------------------------------- 71 | | Attribute Import 72 | |-------------------------------------------------------------------------- 73 | */ 74 | 75 | if (Arguments::getArg('attr')) { 76 | echo "Creating Attribute. \n"; 77 | 78 | $fileName = MAGENTO . '/var/importAttribute.csv'; 79 | 80 | $importer = new ArrtibuteImporter(); 81 | 82 | $importer->import($fileName); 83 | 84 | unset($importer); 85 | 86 | echo "\nMEMORY USED : ".convert(memory_get_usage(true)) . "\n\n"; 87 | } 88 | 89 | /* 90 | |-------------------------------------------------------------------------- 91 | | Attribute Set Import 92 | |-------------------------------------------------------------------------- 93 | */ 94 | 95 | if (Arguments::getArg('set')) { 96 | echo "Creating Attribute Sets. \n"; 97 | 98 | 99 | $fileName = MAGENTO . '/var/importAttributeSet.csv'; 100 | 101 | $importer = new ArrtibuteSetImporter(); 102 | 103 | $writeConnection = Mage::getSingleton('core/resource')->getConnection('core_write'); 104 | 105 | $writeConnection->query("SET FOREIGN_KEY_CHECKS = 0"); 106 | 107 | $importer->import($fileName); 108 | 109 | $writeConnection->query("SET FOREIGN_KEY_CHECKS = 1"); 110 | 111 | unset($importer); 112 | 113 | echo "\nMEMORY USED : ".convert(memory_get_usage(true)) . "\n\n"; 114 | } 115 | -------------------------------------------------------------------------------- /export_attribute_set.php: -------------------------------------------------------------------------------- 1 | getStores(); 12 | foreach ($allStores as $_eachStoreId => $val) { 13 | $this->_storeIds[] = Mage::app()->getStore($_eachStoreId)->getId(); 14 | } 15 | 16 | $this->_entityTypeId = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId(); 17 | } 18 | 19 | public function export($attributeSetNames, $filename, $pullProducts = false) 20 | { 21 | $exportProducts = array(); 22 | $exportAttributes = array(); 23 | 24 | $collection = Mage::getResourceModel('eav/entity_attribute_set_collection') 25 | ->setEntityTypeFilter($this->_entityTypeId) 26 | ->addFieldToFilter('attribute_set_name', array('in', $attributeSetNames)); 27 | 28 | $attibute_set = array(); 29 | $i = 0; 30 | 31 | foreach ($collection as $attributeSet) { 32 | $defaultGroupId = $attributeSet->getDefaultGroupId(); 33 | $defaultGroup = Mage::getModel('eav/entity_attribute_group')->load($attributeSet->getDefaultGroupId()); 34 | 35 | $attibute_set[$i]['ID'] = $attributeSet->getId(); 36 | $attibute_set[$i]['NAME'] = $attributeSet->getAttributeSetName(); 37 | $attibute_set[$i]['Group ID'] = $defaultGroupId; 38 | $attibute_set[$i]['DEFAULT GROUP'] = $defaultGroup->getAttributeGroupName(); 39 | 40 | if ($pullProducts) { 41 | $products = Mage::getModel('catalog/product') 42 | ->getCollection() 43 | ->addAttributeToSelect('sku') 44 | ->addFieldToFilter('attribute_set_id', $attributeSet->getId()); 45 | 46 | $productsSku = array(); 47 | foreach ($products as $p) { 48 | $productsSku[] = $p->getSku(); 49 | $exportProducts[] = $p->getSku(); 50 | } 51 | unset($productsSku, $products); 52 | 53 | $attibute_set[$i]['PRODUCT SKU'] = join(';', $productsSku); 54 | } else { 55 | $attibute_set[$i]['PRODUCT SKU'] = ' '; 56 | } 57 | 58 | 59 | 60 | /** @var $groupCollection Mage_Eav_Model_Resource_Entity_Attribute_Group_Collection */ 61 | $groupCollection = Mage::getResourceModel('eav/entity_attribute_group_collection') 62 | ->setAttributeSetFilter($attributeSet->getId()) 63 | ->addOrder('sort_order', 'ASC') 64 | ->load(); 65 | foreach ($groupCollection as $group) { 66 | $i++; 67 | /* @var $group Mage_Eav_Model_Entity_Attribute_Group */ 68 | $attrs = Mage::getResourceModel('catalog/product_attribute_collection') 69 | ->setAttributeGroupFilter($group->getId()) 70 | ->addVisibleFilter() 71 | ->checkConfigurableProducts(); 72 | $attrCodes = array(); 73 | foreach ($attrs as $attr) { 74 | $attrCodes[] = $attr->getAttributeCode() .'/'. $attr->getSortOrder(); 75 | $exportAttributes[] = '"'.$attr->getAttributeCode().'"'; 76 | } 77 | 78 | $attibute_set[$i]['ID'] = ' '; 79 | $attibute_set[$i]['NAME'] = $group->getAttributeGroupName(); 80 | $attibute_set[$i]['Group ID'] = ' '; 81 | $attibute_set[$i]['DEFAULT GROUP'] = join(';', $attrCodes); 82 | $attibute_set[$i]['PRODUCT SKU'] = ' '; 83 | } 84 | unset($attrCodes, $attrs, $groupCollection); 85 | $i++; 86 | } 87 | unset($collection); 88 | 89 | echo "preparing csv.... \n"; 90 | writeCsv($attibute_set, $filename, ','); 91 | unset($attibute_set); 92 | 93 | return [ $exportAttributes, $exportProducts ]; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /export_attribute.php: -------------------------------------------------------------------------------- 1 | _entityTypeId = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId(); 10 | } 11 | 12 | public function export($exportAttributes, $filename) 13 | { 14 | $resource = Mage::getSingleton('core/resource'); 15 | $connection = $resource->getConnection('core_read'); 16 | 17 | // Increase maximium length for group_concat 18 | $connection->query("SET SESSION group_concat_max_len = 1000000;"); 19 | 20 | $select_attribs = $connection 21 | ->select() 22 | ->from( 23 | array('ea' => $resource->getTableName('eav/attribute')), 24 | array('ea.*', 'c_ea.*', 25 | "(SELECT GROUP_CONCAT(CONCAT_WS('|',l_ea.value,l_ea.store_id) SEPARATOR ':') FROM ".$resource->getTableName('eav/attribute_label')." as l_ea WHERE ea.attribute_id = l_ea.attribute_id GROUP BY l_ea.attribute_id) as arrtibute_frontname") 26 | ); 27 | 28 | $select_attribs->join( 29 | 30 | array('c_ea' => $resource->getTableName('catalog/eav_attribute')), 31 | 'ea.attribute_id = c_ea.attribute_id' 32 | 33 | ); 34 | 35 | if (!empty($exportAttributes)) { 36 | $select_attribs = $select_attribs->where('ea.attribute_code in ( '.implode(',', $exportAttributes) .' )'); 37 | } 38 | $select_prod_attribs = $select_attribs->where('ea.entity_type_id = ' . $this->_entityTypeId)->order('ea.attribute_id ASC'); 39 | 40 | $product_attributes = $connection->fetchAll($select_prod_attribs); 41 | 42 | 43 | $select_attrib_option = $select_attribs 44 | ->join( 45 | array('e_ao' => $resource->getTableName('eav/attribute_option'), array('option_id')), 46 | 'c_ea.attribute_id = e_ao.attribute_id' 47 | ) 48 | ->columns("(SELECT GROUP_CONCAT(CONCAT_WS('|',e_aov.value,e_aov.store_id) SEPARATOR ':') FROM ".$resource->getTableName('eav/attribute_option_value')." as e_aov WHERE e_ao.option_id = e_aov.option_id GROUP BY e_aov.option_id) as value") 49 | ->join( 50 | array('e_aov' => $resource->getTableName('eav/attribute_option_value'), array('value')), 51 | 'e_ao.option_id = e_aov.option_id ', 52 | array() 53 | ) 54 | ->order('e_ao.attribute_id ASC'); 55 | 56 | 57 | $product_attribute_options = $connection->fetchAll($select_attrib_option); 58 | 59 | $attributesCollection = $this->mergeCollections($product_attributes, $product_attribute_options); 60 | 61 | unset($product_attributes, $product_attribute_options); 62 | 63 | echo "preparing csv.... \n"; 64 | writeCsv($attributesCollection, $filename, ','); 65 | unset($attributesCollection); 66 | } 67 | 68 | protected function mergeCollections($product_attributes, $product_attribute_options) 69 | { 70 | foreach ($product_attributes as $key => $_prodAttrib) { 71 | $values = array(); 72 | $attribId = $_prodAttrib['attribute_id']; 73 | foreach ($product_attribute_options as $pao) { 74 | if ($pao['attribute_id'] == $attribId) { 75 | $values[] = $pao['value']; 76 | } 77 | } 78 | $values = array_unique($values); 79 | if (count($values) > 0) { 80 | $values = implode(";", $values); 81 | $product_attributes[$key]['_options'] = $values; 82 | } else { 83 | $product_attributes[$key]['_options'] = ""; 84 | } 85 | /* 86 | temp 87 | */ 88 | $product_attributes[$key]['attribute_code'] = $product_attributes[$key]['attribute_code']; 89 | } 90 | 91 | return $product_attributes; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /prepare_products.php: -------------------------------------------------------------------------------- 1 | getConnection('core_write'); 5 | 6 | 7 | /* 8 | |-------------------------------------------------------------------------- 9 | | Product Delete script 10 | |-------------------------------------------------------------------------- 11 | */ 12 | 13 | //$writeConnection->query("DELETE FROM `catalog_product_entity`"); 14 | 15 | //$writeConnection->query("TRUNCATE TABLE `catalog_product_entity`"); 16 | 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Prepare for Product Import ( works with magmi) 21 | |-------------------------------------------------------------------------- 22 | */ 23 | 24 | echo "Creating Products files. \n"; 25 | 26 | if (!is_dir(MAGENTO.'/var/split/unformated')) { 27 | mkdir(MAGENTO.'/var/split/unformated', 0777, true); 28 | } 29 | 30 | if (!is_dir(MAGENTO.'/var/split/formated')) { 31 | mkdir(MAGENTO.'/var/split/formated', 0777, true); 32 | } 33 | 34 | /* 35 | |-------------------------------------------------------------------------- 36 | | Slpitting the Product 37 | |-------------------------------------------------------------------------- 38 | */ 39 | 40 | $handle = fopen(MAGENTO . "/var/product.csv", 'r'); 41 | $maxRange = 500; 42 | $count = 0; 43 | $prefix = 1; 44 | $line = 1; 45 | while (($data = fgetcsv($handle)) !== false) { 46 | if ($line == 1) { 47 | $headers = $data; 48 | } 49 | 50 | if ($data[0] != null) { 51 | $count++; 52 | if ($count > $maxRange) { 53 | $prefix++; 54 | $count = 0; 55 | if ($prefix != 1) { 56 | $filename = MAGENTO.'/var/split/unformated/product-' . $prefix . '.csv'; 57 | $write = fopen($filename, 'a'); 58 | fputcsv($write, $headers); 59 | fclose($write); 60 | } 61 | echo "Count prefix [" . $prefix . "]\n"; 62 | } 63 | 64 | $filename = MAGENTO.'/var/split/unformated/product-'. $prefix . '.csv'; 65 | $write = fopen($filename, 'a'); 66 | fputcsv($write, $data); 67 | fclose($write); 68 | } else { 69 | $filename = MAGENTO.'/var/split/unformated/product-' . $prefix . '.csv'; 70 | $write = fopen($filename, 'a'); 71 | fputcsv($write, $data); 72 | fclose($write); 73 | } 74 | $line++; 75 | } 76 | 77 | echo "\nMEMORY USED : ".convert(memory_get_usage(true)) . "\n\n"; 78 | unset($handle, $write, $data); 79 | 80 | //$writeConnection->query('TRUNCATE log_url; TRUNCATE log_url_info; TRUNCATE log_visitor; TRUNCATE log_visitor_info; TRUNCATE dataflow_batch_import; TRUNCATE dataflow_batch_export; TRUNCATE index_event; TRUNCATE report_event;'); 81 | 82 | function array_equal($a, $b) 83 | { 84 | return (is_array($a) && is_array($b) && array_diff($a, $b) === array_diff($b, $a)); 85 | } 86 | 87 | for ($i=1; $i <=$prefix ; $i++) { 88 | $fileName = 'product-'.$i.'.csv'; 89 | $importer = new PrepareProductImporter(); 90 | 91 | $importer->run($fileName); 92 | 93 | unset($importer); 94 | } 95 | 96 | 97 | echo "\nMEMORY USED : ".convert(memory_get_usage(true)) . "\n\n"; 98 | 99 | class PrepareProductImporter 100 | { 101 | private $_storeIds = array(); 102 | 103 | private $_groups = array(); 104 | 105 | private $_entityTypeId; 106 | 107 | private $_missedProduct = array(); 108 | 109 | public function __construct() 110 | { 111 | $allStores = Mage::app()->getStores(); 112 | foreach ($allStores as $_eachStoreId => $val) { 113 | $this->_storeIds[] = Mage::app()->getStore($_eachStoreId)->getId(); 114 | } 115 | $this->_entityTypeId = Mage::getModel('catalog/product')->getResource()->getTypeId(); 116 | } 117 | 118 | public static function checkEmpty($value) 119 | { 120 | if ($value === '') { 121 | return false; 122 | } 123 | return true; 124 | } 125 | 126 | public function run($name) 127 | { 128 | $fileName = MAGENTO . '/var/split/unformated/'.$name; 129 | 130 | echo "Reading $fileName.\n"; 131 | $file = fopen($fileName, "r"); 132 | while (!feof($file)) { 133 | $csv[] = fgetcsv($file, 0, ','); 134 | } 135 | $keys = array_shift($csv); 136 | 137 | foreach ($csv as $i=>$row) { 138 | $csv[$i] = array_combine($keys, $row); 139 | $csv[$i] = $csv[$i];//array_filter($csv[$i],'self::checkEmpty'); 140 | } 141 | $i = 0; 142 | $currentSet = null; 143 | foreach ($csv as $row) { 144 | $row['sku_type'] = 1; 145 | $row['price_type'] = 1; 146 | $row['weight_type'] = 1; 147 | 148 | // Add Convertions Based on you needs 149 | 150 | $row = $this->removeInvalidData($row); // Remove in valid data 151 | //$row = $this->convertBool($row); // Example 152 | 153 | if (trim($row['sku']) != '') { 154 | $currentSet = $row['sku']; 155 | $this->_groups[$currentSet][] = $row; 156 | $i++; 157 | } else { 158 | $processedChild = array_filter($row, 'self::checkEmpty'); 159 | if (!empty($processedChild)) { 160 | $newExtRow = array_merge($this->_groups[$currentSet][0], $processedChild); 161 | if (array_equal($this->_groups[$currentSet][0], $newExtRow)) { 162 | continue; 163 | } 164 | $newExtRow['bundle_skus'] = ''; 165 | $newExtRow['bundle_options'] = ''; 166 | $this->_groups[$currentSet][] = $newExtRow; 167 | } 168 | unset($processedChild, $newExtRow); 169 | } 170 | } 171 | echo "MEMORY USED : ".convert(memory_get_usage(true)) . "\n"; 172 | 173 | fclose($file); 174 | unset($csv, $keys, $file, $row); 175 | $finalArray = array(); 176 | foreach ($this->_groups as $sku => $_product) { 177 | foreach ($_product as $__product) { 178 | $finalArray[] = $__product; 179 | } 180 | } 181 | unset($this->_groups); 182 | 183 | writeCsv($finalArray, MAGENTO . '/var/split/formated/'.$name, ','); 184 | 185 | echo "MEMORY USED : ".convert(memory_get_usage(true)) . "\n"; 186 | } 187 | 188 | /** 189 | * To convert string into boll value (1 or 0) 190 | * 191 | * @param Array $row 192 | * @return Array 193 | */ 194 | protected function convertBool($row) 195 | { 196 | /* 197 | if($row['cpsp_enable'] == 'Yes') { 198 | $row['cpsp_enable'] = 1; 199 | } else { 200 | $row['cpsp_enable'] = 0; 201 | } 202 | 203 | */ 204 | return $row; 205 | } 206 | 207 | /** 208 | * To remove invalid data form the row 209 | * 210 | * @param Array $row 211 | * @return Array 212 | */ 213 | protected function removeInvalidData($row) 214 | { 215 | 216 | // Add the row that needs to removed 217 | $invalid = array( 218 | 219 | ); 220 | 221 | foreach ($invalid as $_invlaid) { 222 | unset($row[$_invlaid]); 223 | } 224 | 225 | return $row; 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /import_arrtibute.php: -------------------------------------------------------------------------------- 1 | getStores(); 15 | foreach ($allStores as $_eachStoreId => $val) { 16 | $this->_storeIds[] = Mage::app()->getStore($_eachStoreId)->getId(); 17 | } 18 | 19 | $this->_entityTypeId = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId(); 20 | } 21 | 22 | public function import($fileName) 23 | { 24 | // $csv = array_map("str_getcsv", file($fileName,FILE_SKIP_EMPTY_LINES)); 25 | echo "\nReading $fileName.\n\n"; 26 | $file = fopen($fileName, "r"); 27 | while (!feof($file)) { 28 | $csv[] = fgetcsv($file, 0, ','); 29 | } 30 | $keys = array_shift($csv); 31 | foreach ($csv as $i=>$row) { 32 | $csv[$i] = array_combine($keys, $row); 33 | } 34 | foreach ($csv as $row) { 35 | $labelText = $row['frontend_label']; 36 | $attributeCode = $row['attribute_code']; 37 | if ($row['_options'] != "") { 38 | $options = array_unique(explode(";", $row['_options'])); 39 | } // add this to createAttribute parameters and call "addAttributeValue" function. 40 | else { 41 | $options = -1; 42 | } 43 | if ($row['apply_to'] != "") { 44 | $productTypes = explode(",", $row['apply_to']); 45 | } else { 46 | $productTypes = -1; 47 | } 48 | unset($row['category_ids'], $row['frontend_label'], $row['attribute_code'], $row['_options'], $row['apply_to'], $row['attribute_id'], $row['entity_type_id'], $row['search_weight']); 49 | $this->createAttribute($labelText, $attributeCode, $row, $productTypes, -1, $options); 50 | echo "\nMEMORY USED : ".convert(memory_get_usage(true)) . "\n\n"; 51 | } 52 | fclose($file); 53 | unset($csv, $keys, $file); 54 | } 55 | 56 | 57 | /** 58 | * Create an attribute. 59 | * 60 | * For reference, see Mage_Adminhtml_Catalog_Product_AttributeController::saveAction(). 61 | * 62 | * @return int|false 63 | */ 64 | public function createAttribute($labelText, $attributeCode, $values = -1, $productTypes = -1, $setInfo = -1, $options = -1) 65 | { 66 | $labelText = trim($labelText); 67 | $attributeCode = trim($attributeCode); 68 | 69 | if ($labelText == '' || $attributeCode == '') { 70 | echo " Can't import the attribute with an empty label or code. LABEL= [$labelText] CODE= [$attributeCode]"." \n"; 71 | echo " Or might be due to empty line\n"; 72 | return false; 73 | } 74 | 75 | if ($values === -1) { 76 | $values = array(); 77 | } 78 | 79 | if ($productTypes === -1) { 80 | $productTypes = array(); 81 | } 82 | 83 | if ($setInfo !== -1 && (isset($setInfo['SetID']) == false || isset($setInfo['GroupID']) == false)) { 84 | echo " Please provide both the set-ID and the group-ID of the attribute-set if you'd like to subscribe to one."." \n"; 85 | return false; 86 | } 87 | 88 | echo " Creating attribute [$labelText] with code [$attributeCode]."." \n"; 89 | 90 | //>>>> Build the data structure that will define the attribute. See 91 | // Mage_Adminhtml_Catalog_Product_AttributeController::saveAction(). 92 | 93 | $data = array( 94 | 'is_global' => '0', 95 | 'frontend_input' => 'text', 96 | 'default_value_text' => '', 97 | 'default_value_yesno' => '0', 98 | 'default_value_date' => '', 99 | 'default_value_textarea' => '', 100 | 'is_unique' => '0', 101 | 'is_required' => '0', 102 | 'frontend_class' => '', 103 | 'is_searchable' => '1', 104 | 'is_visible_in_advanced_search' => '1', 105 | 'is_comparable' => '1', 106 | 'is_used_for_promo_rules' => '0', 107 | 'is_html_allowed_on_front' => '1', 108 | 'is_visible_on_front' => '0', 109 | 'used_in_product_listing' => '0', 110 | 'used_for_sort_by' => '0', 111 | 'is_configurable' => '0', 112 | 'is_filterable' => '0', 113 | 'is_filterable_in_search' => '0', 114 | 'backend_type' => 'varchar', 115 | 'default_value' => '', 116 | 'is_user_defined' => '0', 117 | 'is_visible' => '1', 118 | 'is_used_for_price_rules' => '0', 119 | 'position' => '0', 120 | 'is_wysiwyg_enabled' => '0', 121 | 'backend_model' => '', 122 | 'attribute_model' => '', 123 | 'backend_table' => '', 124 | 'frontend_model' => '', 125 | 'source_model' => '', 126 | 'note' => '', 127 | 'frontend_input_renderer' => '', 128 | 'position_in_key_features' => '', 129 | 'use_in_key_features' => '0', 130 | 'use_in_key_features' => '0', 131 | 'is_used_for_customer_segment' => '0', 132 | 'is_used_for_target_rules' => '0', 133 | ); 134 | 135 | 136 | 137 | // Valid product types: simple, grouped, configurable, virtual, bundle, downloadable, giftcard 138 | $data['apply_to'] = $productTypes; 139 | $data['attribute_code'] = $attributeCode; 140 | $data['frontend_label'] = array(0 => $labelText); 141 | 142 | $arrtibuteFrontname = explode(':', $values['arrtibute_frontname']); 143 | unset($values['arrtibute_frontname']); 144 | $arrtibuteStoreFrontname = array(); 145 | foreach ($arrtibuteFrontname as $_names) { 146 | list($name, $storeId) = explode('|', $_names); 147 | $arrtibuteStoreFrontname[$storeId] = $name; 148 | } 149 | 150 | foreach ($this->_storeIds as $_store) { 151 | $data['frontend_label'][$_store] = $arrtibuteStoreFrontname[$_store]; 152 | } 153 | 154 | // Now, overlay the incoming values on to the defaults. 155 | foreach ($values as $key => $newValue) { 156 | if (isset($data[$key]) == false) { 157 | echo " Attribute feature [$key] is not valid."." \n"; 158 | //return false; 159 | } else { 160 | $data[$key] = $newValue; 161 | } 162 | } 163 | 164 | // Build the model. 165 | $model = Mage::getModel('catalog/resource_eav_attribute'); 166 | 167 | $model->addData($data); 168 | 169 | if ($setInfo !== -1) { 170 | $model->setAttributeSetId($setInfo['SetID']); 171 | $model->setAttributeGroupId($setInfo['GroupID']); 172 | } 173 | 174 | $model->setEntityTypeId($this->_entityTypeId); 175 | 176 | $model->setIsUserDefined(1); 177 | 178 | //<<<< 179 | 180 | // Save. 181 | 182 | try { 183 | $model->save(); 184 | } catch (Exception $ex) { 185 | echo " Attribute [$labelText] could not be saved: " . $ex->getMessage()." \n"; 186 | return false; 187 | } 188 | 189 | if (is_array($options)) { 190 | echo " Adding (".count($options).") attribute value for [$attributeCode]."." \n"; 191 | foreach ($options as $_opt) { 192 | $this->addAttributeValue($attributeCode, $_opt); 193 | echo "*"; 194 | } 195 | echo "\n"; 196 | } 197 | 198 | $id = $model->getId(); 199 | 200 | echo " Attribute [$labelText] has been saved as ID ($id). \n"; 201 | 202 | // return $id; 203 | } 204 | 205 | public function addAttributeValue($arg_attribute, $arg_value) 206 | { 207 | $attribute_model = Mage::getModel('eav/entity_attribute'); 208 | 209 | $attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute); 210 | $attribute = $attribute_model->load($attribute_code); 211 | 212 | $optionFrontname = explode(':', $arg_value); 213 | $optionStoreFrontname = array(); 214 | foreach ($optionFrontname as $_names) { 215 | list($name, $storeId) = explode('|', $_names); 216 | $optionStoreFrontname[$storeId] = $name; 217 | } 218 | $data = array(); 219 | if (!$this->attributeValueExists($arg_attribute, $optionStoreFrontname[0])) { 220 | $data[0] = $optionStoreFrontname[0]; 221 | foreach ($this->_storeIds as $_store) { 222 | $data[$_store] = $optionStoreFrontname[$_store]; 223 | } 224 | 225 | $value['option'] = $data; 226 | $result = array('value' => $value); 227 | $attribute->setData('option', $result); 228 | 229 | $attribute->save(); 230 | } 231 | } 232 | 233 | public function attributeValueExists($arg_attribute, $arg_value) 234 | { 235 | $attribute_model = Mage::getModel('eav/entity_attribute'); 236 | $attribute_options_model= Mage::getModel('eav/entity_attribute_source_table') ; 237 | 238 | $attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute); 239 | $attribute = $attribute_model->load($attribute_code); 240 | 241 | $attribute_table = $attribute_options_model->setAttribute($attribute); 242 | $options = $attribute_options_model->getAllOptions(false); 243 | 244 | foreach ($options as $option) { 245 | if ($option['label'] == $arg_value) { 246 | return $option['value']; 247 | } 248 | } 249 | 250 | return false; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /export_product.php: -------------------------------------------------------------------------------- 1 | _parameters[Mage_ImportExport_Model_Export::FILTER_ELEMENT_GROUP]) 16 | || !is_array($this->_parameters[Mage_ImportExport_Model_Export::FILTER_ELEMENT_GROUP])) { 17 | $exportFilter = array(); 18 | } else { 19 | $exportFilter = $this->_parameters[Mage_ImportExport_Model_Export::FILTER_ELEMENT_GROUP]; 20 | } 21 | $exportAttrCodes = $this->_getExportAttrCodes(); 22 | 23 | foreach ($this->filterAttributeCollection($this->getAttributeCollection()) as $attribute) { 24 | $attrCode = $attribute->getAttributeCode(); 25 | 26 | // filter applying 27 | if (isset($exportFilter[$attrCode])) { 28 | $attrFilterType = Mage_ImportExport_Model_Export::getAttributeFilterType($attribute); 29 | if ($attrCode == 'sku') { 30 | $collection->addAttributeToFilter($attrCode, array('in' => $exportFilter[$attrCode])); 31 | } elseif (Mage_ImportExport_Model_Export::FILTER_TYPE_SELECT == $attrFilterType) { 32 | if (is_scalar($exportFilter[$attrCode]) && trim($exportFilter[$attrCode])) { 33 | $collection->addAttributeToFilter($attrCode, array('eq' => $exportFilter[$attrCode])); 34 | } 35 | } elseif (Mage_ImportExport_Model_Export::FILTER_TYPE_INPUT == $attrFilterType) { 36 | if (is_scalar($exportFilter[$attrCode]) && trim($exportFilter[$attrCode])) { 37 | $collection->addAttributeToFilter($attrCode, array('like' => "%{$exportFilter[$attrCode]}%")); 38 | } 39 | } elseif (Mage_ImportExport_Model_Export::FILTER_TYPE_DATE == $attrFilterType) { 40 | if (is_array($exportFilter[$attrCode]) && count($exportFilter[$attrCode]) == 2) { 41 | $from = array_shift($exportFilter[$attrCode]); 42 | $to = array_shift($exportFilter[$attrCode]); 43 | 44 | if (is_scalar($from) && !empty($from)) { 45 | $date = Mage::app()->getLocale()->date($from, null, null, false)->toString('MM/dd/YYYY'); 46 | $collection->addAttributeToFilter($attrCode, array('from' => $date, 'date' => true)); 47 | } 48 | if (is_scalar($to) && !empty($to)) { 49 | $date = Mage::app()->getLocale()->date($to, null, null, false)->toString('MM/dd/YYYY'); 50 | $collection->addAttributeToFilter($attrCode, array('to' => $date, 'date' => true)); 51 | } 52 | } 53 | } elseif (Mage_ImportExport_Model_Export::FILTER_TYPE_NUMBER == $attrFilterType) { 54 | if (is_array($exportFilter[$attrCode]) && count($exportFilter[$attrCode]) == 2) { 55 | $from = array_shift($exportFilter[$attrCode]); 56 | $to = array_shift($exportFilter[$attrCode]); 57 | 58 | if (is_numeric($from)) { 59 | $collection->addAttributeToFilter($attrCode, array('from' => $from)); 60 | } 61 | if (is_numeric($to)) { 62 | $collection->addAttributeToFilter($attrCode, array('to' => $to)); 63 | } 64 | } 65 | } 66 | } 67 | if (in_array($attrCode, $exportAttrCodes)) { 68 | $collection->addAttributeToSelect($attrCode); 69 | } 70 | } 71 | return $collection; 72 | } 73 | 74 | /** 75 | * Prepare products bundel options 76 | * 77 | * @param array $productIds 78 | * @return array 79 | */ 80 | protected function _prepareBundelOptions($collection) 81 | { 82 | if (!$collection->count()) { 83 | return array(); 84 | } 85 | $rowBundel = array(); 86 | 87 | foreach ($collection as $_product) { 88 | if ($_product->getTypeID() == 'bundle') { 89 | $bundledProduct = $_product; 90 | $selectionCollection = $bundledProduct->getTypeInstance()->getSelectionsCollection( 91 | $bundledProduct->getTypeInstance()->getOptionsIds($bundledProduct), 92 | $bundledProduct 93 | ); 94 | $bundled_items = array(); 95 | $optionCollection = $bundledProduct->getTypeInstance()->getOptionsCollection($bundledProduct); 96 | 97 | $_options = $optionCollection->appendSelections($selectionCollection, true); 98 | 99 | $bundle_sku = array(); 100 | $bundle_options = array(); 101 | $i=0; 102 | foreach ($_options as $option) { 103 | $bundle_options[] = join(':', array( 104 | $option->getDefaultTitle()."_$i", 105 | $option->getDefaultTitle(), 106 | $option->getType(), 107 | $option->getRequired(), 108 | $option->getPosition(), 109 | )); 110 | if ($option->getSelections()) { 111 | foreach ($option->getSelections() as $selection) { 112 | $bundle_sku[] = join(':', array( 113 | $option->getDefaultTitle()."_$i", 114 | $selection->getSku(), 115 | $selection->getData('selection_qty'), 116 | $selection->getData('selection_can_change_qty'), 117 | $selection->getData('position'), 118 | $selection->getData('is_default'), 119 | $selection->getData('selection_price_value'), 120 | $selection->getData('selection_price_type') 121 | )); 122 | } 123 | } 124 | $i++; 125 | } 126 | $rowBundel[$_product->getId()][] = array( 127 | 'bundle_skus' => join(';', $bundle_sku), 128 | 'bundle_options'=> join(';', $bundle_options) 129 | ); 130 | unset($optionCollection); 131 | $bundle_sku = array(); 132 | } else { 133 | $rowBundel[$_product->getId()][] = array( 134 | 'bundle_skus' => '' , 135 | 'bundle_options' => '' 136 | ); 137 | } 138 | } 139 | return $rowBundel; 140 | } 141 | 142 | /** 143 | * Export process. 144 | * 145 | * @return string 146 | */ 147 | public function export() 148 | { 149 | //Execution time may be very long 150 | set_time_limit(0); 151 | 152 | /** @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */ 153 | $validAttrCodes = $this->_getExportAttrCodes(); 154 | $writer = $this->getWriter(); 155 | $defaultStoreId = Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID; 156 | 157 | $memoryLimit = trim(ini_get('memory_limit')); 158 | $lastMemoryLimitLetter = strtolower($memoryLimit[strlen($memoryLimit)-1]); 159 | switch ($lastMemoryLimitLetter) { 160 | case 'g': 161 | $memoryLimit *= 1024; 162 | // no break 163 | case 'm': 164 | $memoryLimit *= 1024; 165 | // no break 166 | case 'k': 167 | $memoryLimit *= 1024; 168 | break; 169 | default: 170 | // minimum memory required by Magento 171 | $memoryLimit = 250000000; 172 | } 173 | 174 | // Tested one product to have up to such size 175 | $memoryPerProduct = 100000; 176 | // Decrease memory limit to have supply 177 | $memoryUsagePercent = 0.8; 178 | // Minimum Products limit 179 | $minProductsLimit = 500; 180 | 181 | $limitProducts = intval(($memoryLimit * $memoryUsagePercent - memory_get_usage(true)) / $memoryPerProduct); 182 | if ($limitProducts < $minProductsLimit) { 183 | $limitProducts = $minProductsLimit; 184 | } 185 | $offsetProducts = 0; 186 | 187 | while (true) { 188 | ++$offsetProducts; 189 | $dataRows = array(); 190 | $rowCategories = array(); 191 | $rowWebsites = array(); 192 | $rowTierPrices = array(); 193 | $rowGroupPrices = array(); 194 | $rowMultiselects = array(); 195 | $mediaGalery = array(); 196 | $rowBundelOptions= array(); 197 | 198 | // prepare multi-store values and system columns values 199 | foreach ($this->_storeIdToCode as $storeId => &$storeCode) { // go through all stores 200 | $collection = $this->_prepareEntityCollection(Mage::getResourceModel('catalog/product_collection')); 201 | $collection 202 | ->setStoreId($storeId) 203 | ->setPage($offsetProducts, $limitProducts); 204 | if ($collection->getCurPage() < $offsetProducts) { 205 | break; 206 | } 207 | $collection->load(); 208 | 209 | if ($collection->count() == 0) { 210 | break; 211 | } 212 | echo "\nFound : ".$collection->count()." products in [$storeId] - store \n"; 213 | 214 | if ($defaultStoreId == $storeId) { 215 | $collection->addCategoryIds()->addWebsiteNamesToResult(); 216 | 217 | // tier and group price data getting only once 218 | $rowTierPrices = $this->_prepareTierPrices($collection->getAllIds()); 219 | $rowGroupPrices = $this->_prepareGroupPrices($collection->getAllIds()); 220 | 221 | // getting media gallery data 222 | $mediaGalery = $this->_prepareMediaGallery($collection->getAllIds()); 223 | 224 | //get bundel product 225 | $rowBundelOptions = $this->_prepareBundelOptions($collection); 226 | } 227 | foreach ($collection as $itemId => $item) { // go through all products 228 | echo "\r\033 ".$itemId; 229 | $rowIsEmpty = true; // row is empty by default 230 | 231 | foreach ($validAttrCodes as &$attrCode) { // go through all valid attribute codes 232 | $attrValue = $item->getData($attrCode); 233 | 234 | if (!empty($this->_attributeValues[$attrCode])) { 235 | if ($this->_attributeTypes[$attrCode] == 'multiselect') { 236 | $attrValue = explode(',', $attrValue); 237 | $attrValue = array_intersect_key( 238 | $this->_attributeValues[$attrCode], 239 | array_flip($attrValue) 240 | ); 241 | $rowMultiselects[$itemId][$attrCode] = $attrValue; 242 | } elseif (isset($this->_attributeValues[$attrCode][$attrValue])) { 243 | $attrValue = $this->_attributeValues[$attrCode][$attrValue]; 244 | } else { 245 | $attrValue = null; 246 | } 247 | } 248 | // do not save value same as default or not existent 249 | if ($storeId != $defaultStoreId 250 | && isset($dataRows[$itemId][$defaultStoreId][$attrCode]) 251 | && $dataRows[$itemId][$defaultStoreId][$attrCode] == $attrValue 252 | ) { 253 | $attrValue = null; 254 | } 255 | if (is_scalar($attrValue)) { 256 | $dataRows[$itemId][$storeId][$attrCode] = $attrValue; 257 | $rowIsEmpty = false; // mark row as not empty 258 | } 259 | } 260 | if ($rowIsEmpty) { // remove empty rows 261 | unset($dataRows[$itemId][$storeId]); 262 | } else { 263 | $attrSetId = $item->getAttributeSetId(); 264 | $dataRows[$itemId][$storeId][self::COL_STORE] = $storeCode; 265 | $dataRows[$itemId][$storeId][self::COL_ATTR_SET] = $this->_attrSetIdToName[$attrSetId]; 266 | $dataRows[$itemId][$storeId][self::COL_TYPE] = $item->getTypeId(); 267 | 268 | if ($defaultStoreId == $storeId) { 269 | $rowWebsites[$itemId] = $item->getWebsites(); 270 | $rowCategories[$itemId] = $item->getCategoryIds(); 271 | } 272 | } 273 | $item = null; 274 | } 275 | $collection->clear(); 276 | } 277 | 278 | if ($collection->getCurPage() < $offsetProducts) { 279 | break; 280 | } 281 | 282 | // remove unused categories 283 | $allCategoriesIds = array_merge(array_keys($this->_categories), array_keys($this->_rootCategories)); 284 | foreach ($rowCategories as &$categories) { 285 | $categories = array_intersect($categories, $allCategoriesIds); 286 | } 287 | 288 | // prepare catalog inventory information 289 | $productIds = array_keys($dataRows); 290 | $stockItemRows = $this->_prepareCatalogInventory($productIds); 291 | 292 | // prepare links information 293 | $linksRows = $this->_prepareLinks($productIds); 294 | $linkIdColPrefix = array( 295 | Mage_Catalog_Model_Product_Link::LINK_TYPE_RELATED => '_links_related_', 296 | Mage_Catalog_Model_Product_Link::LINK_TYPE_UPSELL => '_links_upsell_', 297 | Mage_Catalog_Model_Product_Link::LINK_TYPE_CROSSSELL => '_links_crosssell_', 298 | Mage_Catalog_Model_Product_Link::LINK_TYPE_GROUPED => '_associated_' 299 | ); 300 | $configurableProductsCollection = Mage::getResourceModel('catalog/product_collection'); 301 | $configurableProductsCollection->addAttributeToFilter( 302 | 'entity_id', 303 | array( 304 | 'in' => $productIds 305 | ) 306 | )->addAttributeToFilter( 307 | 'type_id', 308 | array( 309 | 'eq' => Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE 310 | ) 311 | ); 312 | $configurableData = array(); 313 | while ($product = $configurableProductsCollection->fetchItem()) { 314 | $productAttributesOptions = $product->getTypeInstance(true)->getConfigurableOptions($product); 315 | 316 | foreach ($productAttributesOptions as $productAttributeOption) { 317 | $configurableData[$product->getId()] = array(); 318 | foreach ($productAttributeOption as $optionValues) { 319 | $priceType = $optionValues['pricing_is_percent'] ? '%' : ''; 320 | $configurableData[$product->getId()][] = array( 321 | '_super_products_sku' => $optionValues['sku'], 322 | '_super_attribute_code' => $optionValues['attribute_code'], 323 | '_super_attribute_option' => $optionValues['option_title'], 324 | '_super_attribute_price_corr' => $optionValues['pricing_value'] . $priceType 325 | ); 326 | } 327 | } 328 | } 329 | 330 | // prepare custom options information 331 | $customOptionsData = array(); 332 | $customOptionsDataPre = array(); 333 | $customOptCols = array( 334 | '_custom_option_store', '_custom_option_type', '_custom_option_title', '_custom_option_is_required', 335 | '_custom_option_price', '_custom_option_sku', '_custom_option_max_characters', 336 | '_custom_option_sort_order', '_custom_option_row_title', '_custom_option_row_price', 337 | '_custom_option_row_sku', '_custom_option_row_sort' 338 | ); 339 | 340 | foreach ($this->_storeIdToCode as $storeId => &$storeCode) { 341 | $options = Mage::getResourceModel('catalog/product_option_collection') 342 | ->reset() 343 | ->addTitleToResult($storeId) 344 | ->addPriceToResult($storeId) 345 | ->addProductToFilter($productIds) 346 | ->addValuesToResult($storeId); 347 | 348 | foreach ($options as $option) { 349 | $row = array(); 350 | $productId = $option['product_id']; 351 | $optionId = $option['option_id']; 352 | $customOptions = isset($customOptionsDataPre[$productId][$optionId]) 353 | ? $customOptionsDataPre[$productId][$optionId] 354 | : array(); 355 | 356 | if ($defaultStoreId == $storeId) { 357 | $row['_custom_option_type'] = $option['type']; 358 | $row['_custom_option_title'] = $option['title']; 359 | $row['_custom_option_is_required'] = $option['is_require']; 360 | $row['_custom_option_price'] = $option['price'] 361 | . ($option['price_type'] == 'percent' ? '%' : ''); 362 | $row['_custom_option_sku'] = $option['sku']; 363 | $row['_custom_option_max_characters'] = $option['max_characters']; 364 | $row['_custom_option_sort_order'] = $option['sort_order']; 365 | 366 | // remember default title for later comparisons 367 | $defaultTitles[$option['option_id']] = $option['title']; 368 | } elseif ($option['title'] != $customOptions[0]['_custom_option_title']) { 369 | $row['_custom_option_title'] = $option['title']; 370 | } 371 | $values = $option->getValues(); 372 | if ($values) { 373 | $firstValue = array_shift($values); 374 | $priceType = $firstValue['price_type'] == 'percent' ? '%' : ''; 375 | 376 | if ($defaultStoreId == $storeId) { 377 | $row['_custom_option_row_title'] = $firstValue['title']; 378 | $row['_custom_option_row_price'] = $firstValue['price'] . $priceType; 379 | $row['_custom_option_row_sku'] = $firstValue['sku']; 380 | $row['_custom_option_row_sort'] = $firstValue['sort_order']; 381 | 382 | $defaultValueTitles[$firstValue['option_type_id']] = $firstValue['title']; 383 | } elseif ($firstValue['title'] != $customOptions[0]['_custom_option_row_title']) { 384 | $row['_custom_option_row_title'] = $firstValue['title']; 385 | } 386 | } 387 | if ($row) { 388 | if ($defaultStoreId != $storeId) { 389 | $row['_custom_option_store'] = $this->_storeIdToCode[$storeId]; 390 | } 391 | $customOptionsDataPre[$productId][$optionId][] = $row; 392 | } 393 | foreach ($values as $value) { 394 | $row = array(); 395 | $valuePriceType = $value['price_type'] == 'percent' ? '%' : ''; 396 | 397 | if ($defaultStoreId == $storeId) { 398 | $row['_custom_option_row_title'] = $value['title']; 399 | $row['_custom_option_row_price'] = $value['price'] . $valuePriceType; 400 | $row['_custom_option_row_sku'] = $value['sku']; 401 | $row['_custom_option_row_sort'] = $value['sort_order']; 402 | } elseif ($value['title'] != $customOptions[0]['_custom_option_row_title']) { 403 | $row['_custom_option_row_title'] = $value['title']; 404 | } 405 | if ($row) { 406 | if ($defaultStoreId != $storeId) { 407 | $row['_custom_option_store'] = $this->_storeIdToCode[$storeId]; 408 | } 409 | $customOptionsDataPre[$option['product_id']][$option['option_id']][] = $row; 410 | } 411 | } 412 | $option = null; 413 | } 414 | $options = null; 415 | } 416 | foreach ($customOptionsDataPre as $productId => &$optionsData) { 417 | $customOptionsData[$productId] = array(); 418 | 419 | foreach ($optionsData as $optionId => &$optionRows) { 420 | $customOptionsData[$productId] = array_merge($customOptionsData[$productId], $optionRows); 421 | } 422 | unset($optionRows, $optionsData); 423 | } 424 | unset($customOptionsDataPre); 425 | 426 | if ($offsetProducts == 1) { 427 | // create export file 428 | $headerCols = array_merge( 429 | array( 430 | self::COL_SKU, self::COL_STORE, self::COL_ATTR_SET, 431 | self::COL_TYPE, self::COL_CATEGORY, self::COL_ROOT_CATEGORY, '_product_websites' 432 | ), 433 | $validAttrCodes, 434 | reset($stockItemRows) ? array_keys(end($stockItemRows)) : array(), 435 | array(), 436 | array( 437 | '_links_related_sku', '_links_related_position', '_links_crosssell_sku', 438 | '_links_crosssell_position', '_links_upsell_sku', '_links_upsell_position', 439 | '_associated_sku', '_associated_default_qty', '_associated_position' 440 | ), 441 | array('_tier_price_website', '_tier_price_customer_group', '_tier_price_qty', '_tier_price_price'), 442 | array('_group_price_website', '_group_price_customer_group', '_group_price_price'), 443 | array( 444 | '_media_attribute_id', 445 | '_media_image', 446 | '_media_lable', 447 | '_media_position', 448 | '_media_is_disabled' 449 | ), 450 | array( 451 | 'bundle_skus', 452 | 'bundle_options' 453 | ) 454 | ); 455 | 456 | // have we merge custom options columns 457 | if ($customOptionsData) { 458 | $headerCols = array_merge($headerCols, $customOptCols); 459 | } 460 | 461 | // have we merge configurable products data 462 | if ($configurableData) { 463 | $headerCols = array_merge($headerCols, array( 464 | '_super_products_sku', '_super_attribute_code', 465 | '_super_attribute_option', '_super_attribute_price_corr' 466 | )); 467 | } 468 | 469 | $writer->setHeaderCols($headerCols); 470 | } 471 | 472 | foreach ($dataRows as $productId => &$productData) { 473 | foreach ($productData as $storeId => &$dataRow) { 474 | if ($defaultStoreId != $storeId) { 475 | $dataRow[self::COL_SKU] = null; 476 | $dataRow[self::COL_ATTR_SET] = null; 477 | $dataRow[self::COL_TYPE] = null; 478 | } else { 479 | $dataRow[self::COL_STORE] = null; 480 | //$dataRow += $stockItemRows[$productId]; 481 | $dataRow = array_merge($dataRow, $stockItemRows[$productId]); 482 | } 483 | 484 | $this->_updateDataWithCategoryColumns($dataRow, $rowCategories, $productId); 485 | if ($rowWebsites[$productId]) { 486 | $dataRow['_product_websites'] = $this->_websiteIdToCode[array_shift($rowWebsites[$productId])]; 487 | } 488 | if (!empty($rowTierPrices[$productId])) { 489 | $dataRow = array_merge($dataRow, array_shift($rowTierPrices[$productId])); 490 | } 491 | if (!empty($rowGroupPrices[$productId])) { 492 | $dataRow = array_merge($dataRow, array_shift($rowGroupPrices[$productId])); 493 | } 494 | if (!empty($mediaGalery[$productId])) { 495 | $dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId])); 496 | } 497 | if (!empty($rowBundelOptions[$productId])) { 498 | $dataRow = array_merge($dataRow, array_shift($rowBundelOptions[$productId])); 499 | } 500 | foreach ($linkIdColPrefix as $linkId => &$colPrefix) { 501 | if (!empty($linksRows[$productId][$linkId])) { 502 | $linkData = array_shift($linksRows[$productId][$linkId]); 503 | $dataRow[$colPrefix . 'position'] = $linkData['position']; 504 | $dataRow[$colPrefix . 'sku'] = $linkData['sku']; 505 | 506 | if (null !== $linkData['default_qty']) { 507 | $dataRow[$colPrefix . 'default_qty'] = $linkData['default_qty']; 508 | } 509 | } 510 | } 511 | if (!empty($customOptionsData[$productId])) { 512 | $dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId])); 513 | } 514 | if (!empty($configurableData[$productId])) { 515 | $dataRow = array_merge($dataRow, array_shift($configurableData[$productId])); 516 | } 517 | if (!empty($rowMultiselects[$productId])) { 518 | foreach ($rowMultiselects[$productId] as $attrKey => $attrVal) { 519 | if (!empty($rowMultiselects[$productId][$attrKey])) { 520 | $dataRow[$attrKey] = array_shift($rowMultiselects[$productId][$attrKey]); 521 | } 522 | } 523 | } 524 | 525 | $writer->writeRow($dataRow); 526 | } 527 | // calculate largest links block 528 | $largestLinks = 0; 529 | 530 | if (isset($linksRows[$productId])) { 531 | $linksRowsKeys = array_keys($linksRows[$productId]); 532 | foreach ($linksRowsKeys as $linksRowsKey) { 533 | $largestLinks = max($largestLinks, count($linksRows[$productId][$linksRowsKey])); 534 | } 535 | } 536 | $additionalRowsCount = max( 537 | count($rowCategories[$productId]), 538 | count($rowWebsites[$productId]), 539 | $largestLinks 540 | ); 541 | if (!empty($rowTierPrices[$productId])) { 542 | $additionalRowsCount = max($additionalRowsCount, count($rowTierPrices[$productId])); 543 | } 544 | if (!empty($rowGroupPrices[$productId])) { 545 | $additionalRowsCount = max($additionalRowsCount, count($rowGroupPrices[$productId])); 546 | } 547 | if (!empty($mediaGalery[$productId])) { 548 | $additionalRowsCount = max($additionalRowsCount, count($mediaGalery[$productId])); 549 | } 550 | if (!empty($rowBundelOptions[$productId])) { 551 | $additionalRowsCount = max($additionalRowsCount, count($rowBundelOptions[$productId])); 552 | } 553 | if (!empty($customOptionsData[$productId])) { 554 | $additionalRowsCount = max($additionalRowsCount, count($customOptionsData[$productId])); 555 | } 556 | if (!empty($configurableData[$productId])) { 557 | $additionalRowsCount = max($additionalRowsCount, count($configurableData[$productId])); 558 | } 559 | if (!empty($rowMultiselects[$productId])) { 560 | foreach ($rowMultiselects[$productId] as $attributes) { 561 | $additionalRowsCount = max($additionalRowsCount, count($attributes)); 562 | } 563 | } 564 | 565 | if ($additionalRowsCount) { 566 | for ($i = 0; $i < $additionalRowsCount; $i++) { 567 | $dataRow = array(); 568 | 569 | $this->_updateDataWithCategoryColumns($dataRow, $rowCategories, $productId); 570 | if ($rowWebsites[$productId]) { 571 | $dataRow['_product_websites'] = $this 572 | ->_websiteIdToCode[array_shift($rowWebsites[$productId])]; 573 | } 574 | if (!empty($rowTierPrices[$productId])) { 575 | $dataRow = array_merge($dataRow, array_shift($rowTierPrices[$productId])); 576 | } 577 | if (!empty($rowGroupPrices[$productId])) { 578 | $dataRow = array_merge($dataRow, array_shift($rowGroupPrices[$productId])); 579 | } 580 | if (!empty($mediaGalery[$productId])) { 581 | $dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId])); 582 | } 583 | if (!empty($rowBundelOptions[$productId])) { 584 | $dataRow = array_merge($dataRow, array_shift($rowBundelOptions[$productId])); 585 | } 586 | foreach ($linkIdColPrefix as $linkId => &$colPrefix) { 587 | if (!empty($linksRows[$productId][$linkId])) { 588 | $linkData = array_shift($linksRows[$productId][$linkId]); 589 | $dataRow[$colPrefix . 'position'] = $linkData['position']; 590 | $dataRow[$colPrefix . 'sku'] = $linkData['sku']; 591 | 592 | if (null !== $linkData['default_qty']) { 593 | $dataRow[$colPrefix . 'default_qty'] = $linkData['default_qty']; 594 | } 595 | } 596 | } 597 | if (!empty($customOptionsData[$productId])) { 598 | $dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId])); 599 | } 600 | if (!empty($configurableData[$productId])) { 601 | $dataRow = array_merge($dataRow, array_shift($configurableData[$productId])); 602 | } 603 | if (!empty($rowMultiselects[$productId])) { 604 | foreach ($rowMultiselects[$productId] as $attrKey=>$attrVal) { 605 | if (!empty($rowMultiselects[$productId][$attrKey])) { 606 | $dataRow[$attrKey] = array_shift($rowMultiselects[$productId][$attrKey]); 607 | } 608 | } 609 | } 610 | $writer->writeRow($dataRow); 611 | } 612 | } 613 | } 614 | } 615 | //return $writer->getContents(); 616 | } 617 | 618 | /** 619 | * Export process for EE 1.10. 620 | * 621 | * @return string 622 | */ 623 | public function export110() 624 | { 625 | /** @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */ 626 | $validAttrCodes = $this->_getExportAttrCodes(); 627 | $writer = $this->getWriter(); 628 | $resource = Mage::getSingleton('core/resource'); 629 | $dataRows = array(); 630 | $rowCategories = array(); 631 | $rowWebsites = array(); 632 | $rowTierPrices = array(); 633 | $stockItemRows = array(); 634 | $linksRows = array(); 635 | $gfAmountFields = array(); 636 | $mediaGalery = array(); 637 | $rowBundelOptions= array(); 638 | $defaultStoreId = Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID; 639 | $collection = $this->_prepareEntityCollection(Mage::getResourceModel('catalog/product_collection')); 640 | 641 | // prepare multi-store values and system columns values 642 | foreach ($this->_storeIdToCode as $storeId => &$storeCode) { // go through all stores 643 | $collection->setStoreId($storeId) 644 | ->load(); 645 | 646 | if ($defaultStoreId == $storeId) { 647 | $collection->addCategoryIds()->addWebsiteNamesToResult(); 648 | 649 | // tier price data getting only once 650 | $rowTierPrices = $this->_prepareTierPrices($collection->getAllIds()); 651 | 652 | // getting media gallery data 653 | $mediaGalery = $this->_prepareMediaGallery($collection->getAllIds()); 654 | 655 | $rowBundelOptions = $this->_prepareBundelOptions($collection); 656 | } 657 | echo "\nFound : ".$collection->count()." products in [$storeId] - store \n"; 658 | foreach ($collection as $itemId => $item) { // go through all products 659 | $rowIsEmpty = true; // row is empty by default 660 | echo "\r\033 ".$itemId; 661 | foreach ($validAttrCodes as &$attrCode) { // go through all valid attribute codes 662 | $attrValue = $item->getData($attrCode); 663 | 664 | if (!empty($this->_attributeValues[$attrCode])) { 665 | if ($this->_attributeTypes[$attrCode] == 'multiselect') { 666 | $attrValue = explode(',', $attrValue); 667 | $attrValue = array_intersect_key( 668 | $this->_attributeValues[$attrCode], 669 | array_flip($attrValue) 670 | ); 671 | $rowMultiselects[$itemId][$attrCode] = $attrValue; 672 | } elseif (isset($this->_attributeValues[$attrCode][$attrValue])) { 673 | $attrValue = $this->_attributeValues[$attrCode][$attrValue]; 674 | } else { 675 | $attrValue = null; 676 | } 677 | } 678 | // do not save value same as default or not existent 679 | if ($storeId != $defaultStoreId 680 | && isset($dataRows[$itemId][$defaultStoreId][$attrCode]) 681 | && $dataRows[$itemId][$defaultStoreId][$attrCode] == $attrValue 682 | ) { 683 | $attrValue = null; 684 | } 685 | if (is_scalar($attrValue)) { 686 | $dataRows[$itemId][$storeId][$attrCode] = $attrValue; 687 | $rowIsEmpty = false; // mark row as not empty 688 | } 689 | } 690 | if ($rowIsEmpty) { // remove empty rows 691 | unset($dataRows[$itemId][$storeId]); 692 | } else { 693 | $attrSetId = $item->getAttributeSetId(); 694 | $dataRows[$itemId][$storeId][self::COL_STORE] = $storeCode; 695 | $dataRows[$itemId][$storeId][self::COL_ATTR_SET] = $this->_attrSetIdToName[$attrSetId]; 696 | $dataRows[$itemId][$storeId][self::COL_TYPE] = $item->getTypeId(); 697 | 698 | if ($defaultStoreId == $storeId) { 699 | $rowWebsites[$itemId] = $item->getWebsites(); 700 | $rowCategories[$itemId] = $item->getCategoryIds(); 701 | } 702 | } 703 | $item = null; 704 | } 705 | $collection->clear(); 706 | } 707 | 708 | // remove root categories 709 | foreach ($rowCategories as $productId => &$categories) { 710 | $categories = array_intersect($categories, array_keys($this->_categories)); 711 | } 712 | 713 | // prepare catalog inventory information 714 | $productIds = array_keys($dataRows); 715 | $stockItemRows = $this->_prepareCatalogInventory($productIds); 716 | 717 | // prepare links information 718 | $this->_prepareLinks($productIds); 719 | $linkIdColPrefix = array( 720 | Mage_Catalog_Model_Product_Link::LINK_TYPE_RELATED => '_links_related_', 721 | Mage_Catalog_Model_Product_Link::LINK_TYPE_UPSELL => '_links_upsell_', 722 | Mage_Catalog_Model_Product_Link::LINK_TYPE_CROSSSELL => '_links_crosssell_', 723 | Mage_Catalog_Model_Product_Link::LINK_TYPE_GROUPED => '_associated_' 724 | ); 725 | 726 | // prepare configurable products data 727 | $configurableData = $this->_prepareConfigurableProductData($productIds); 728 | $configurablePrice = array(); 729 | if ($configurableData) { 730 | $configurablePrice = $this->_prepareConfigurableProductPrice($productIds); 731 | foreach ($configurableData as $productId => &$rows) { 732 | if (isset($configurablePrice[$productId])) { 733 | $largest = max(count($rows), count($configurablePrice[$productId])); 734 | 735 | for ($i = 0; $i < $largest; $i++) { 736 | if (!isset($configurableData[$productId][$i])) { 737 | $configurableData[$productId][$i] = array(); 738 | } 739 | if (isset($configurablePrice[$productId][$i])) { 740 | $configurableData[$productId][$i] = array_merge( 741 | $configurableData[$productId][$i], 742 | $configurablePrice[$productId][$i] 743 | ); 744 | } 745 | } 746 | } 747 | } 748 | unset($configurablePrice); 749 | } 750 | 751 | // prepare custom options information 752 | $customOptionsData = array(); 753 | $customOptionsDataPre = array(); 754 | $customOptCols = array( 755 | '_custom_option_store', '_custom_option_type', '_custom_option_title', '_custom_option_is_required', 756 | '_custom_option_price', '_custom_option_sku', '_custom_option_max_characters', 757 | '_custom_option_sort_order', '_custom_option_row_title', '_custom_option_row_price', 758 | '_custom_option_row_sku', '_custom_option_row_sort' 759 | ); 760 | 761 | foreach ($this->_storeIdToCode as $storeId => &$storeCode) { 762 | $options = Mage::getResourceModel('catalog/product_option_collection') 763 | ->reset() 764 | ->addTitleToResult($storeId) 765 | ->addPriceToResult($storeId) 766 | ->addProductToFilter($productIds) 767 | ->addValuesToResult($storeId); 768 | 769 | foreach ($options as $option) { 770 | $row = array(); 771 | $productId = $option['product_id']; 772 | $optionId = $option['option_id']; 773 | $customOptions = isset($customOptionsDataPre[$productId][$optionId]) 774 | ? $customOptionsDataPre[$productId][$optionId] 775 | : array(); 776 | 777 | if ($defaultStoreId == $storeId) { 778 | $row['_custom_option_type'] = $option['type']; 779 | $row['_custom_option_title'] = $option['title']; 780 | $row['_custom_option_is_required'] = $option['is_require']; 781 | $row['_custom_option_price'] = $option['price'] . ($option['price_type'] == 'percent' ? '%' : ''); 782 | $row['_custom_option_sku'] = $option['sku']; 783 | $row['_custom_option_max_characters'] = $option['max_characters']; 784 | $row['_custom_option_sort_order'] = $option['sort_order']; 785 | 786 | // remember default title for later comparisons 787 | $defaultTitles[$option['option_id']] = $option['title']; 788 | } elseif ($option['title'] != $customOptions[0]['_custom_option_title']) { 789 | $row['_custom_option_title'] = $option['title']; 790 | } 791 | if ($values = $option->getValues()) { 792 | $firstValue = array_shift($values); 793 | $priceType = $firstValue['price_type'] == 'percent' ? '%' : ''; 794 | 795 | if ($defaultStoreId == $storeId) { 796 | $row['_custom_option_row_title'] = $firstValue['title']; 797 | $row['_custom_option_row_price'] = $firstValue['price'] . $priceType; 798 | $row['_custom_option_row_sku'] = $firstValue['sku']; 799 | $row['_custom_option_row_sort'] = $firstValue['sort_order']; 800 | 801 | $defaultValueTitles[$firstValue['option_type_id']] = $firstValue['title']; 802 | } elseif ($firstValue['title'] != $customOptions[0]['_custom_option_row_title']) { 803 | $row['_custom_option_row_title'] = $firstValue['title']; 804 | } 805 | } 806 | if ($row) { 807 | if ($defaultStoreId != $storeId) { 808 | $row['_custom_option_store'] = $this->_storeIdToCode[$storeId]; 809 | } 810 | $customOptionsDataPre[$productId][$optionId][] = $row; 811 | } 812 | foreach ($values as $value) { 813 | $row = array(); 814 | $valuePriceType = $value['price_type'] == 'percent' ? '%' : ''; 815 | 816 | if ($defaultStoreId == $storeId) { 817 | $row['_custom_option_row_title'] = $value['title']; 818 | $row['_custom_option_row_price'] = $value['price'] . $valuePriceType; 819 | $row['_custom_option_row_sku'] = $value['sku']; 820 | $row['_custom_option_row_sort'] = $value['sort_order']; 821 | } elseif ($value['title'] != $customOptions[0]['_custom_option_row_title']) { 822 | $row['_custom_option_row_title'] = $value['title']; 823 | } 824 | if ($row) { 825 | if ($defaultStoreId != $storeId) { 826 | $row['_custom_option_store'] = $this->_storeIdToCode[$storeId]; 827 | } 828 | $customOptionsDataPre[$option['product_id']][$option['option_id']][] = $row; 829 | } 830 | } 831 | $option = null; 832 | } 833 | $options = null; 834 | } 835 | foreach ($customOptionsDataPre as $productId => &$optionsData) { 836 | $customOptionsData[$productId] = array(); 837 | 838 | foreach ($optionsData as $optionId => &$optionRows) { 839 | $customOptionsData[$productId] = array_merge($customOptionsData[$productId], $optionRows); 840 | } 841 | unset($optionRows, $optionsData); 842 | } 843 | unset($customOptionsDataPre); 844 | 845 | // create export file 846 | $headerCols = array_merge( 847 | array( 848 | self::COL_SKU, self::COL_STORE, self::COL_ATTR_SET, 849 | self::COL_TYPE, self::COL_CATEGORY, '_product_websites' 850 | ), 851 | $validAttrCodes, 852 | reset($stockItemRows) ? array_keys(end($stockItemRows)) : array(), 853 | $gfAmountFields, 854 | array( 855 | '_links_related_sku', '_links_related_position', '_links_crosssell_sku', 856 | '_links_crosssell_position', '_links_upsell_sku', '_links_upsell_position', 857 | '_associated_sku', '_associated_default_qty', '_associated_position' 858 | ), 859 | array('_tier_price_website', '_tier_price_customer_group', '_tier_price_qty', '_tier_price_price'), 860 | array( 861 | '_media_attribute_id', 862 | '_media_image', 863 | '_media_lable', 864 | '_media_position', 865 | '_media_is_disabled' 866 | ), 867 | array( 868 | 'bundle_skus', 869 | 'bundle_options' 870 | ) 871 | ); 872 | 873 | // have we merge custom options columns 874 | if ($customOptionsData) { 875 | $headerCols = array_merge($headerCols, $customOptCols); 876 | } 877 | 878 | // have we merge configurable products data 879 | if ($configurableData) { 880 | $headerCols = array_merge($headerCols, array( 881 | '_super_products_sku', '_super_attribute_code', 882 | '_super_attribute_option', '_super_attribute_price_corr' 883 | )); 884 | } 885 | 886 | $writer->setHeaderCols($headerCols); 887 | 888 | foreach ($dataRows as $productId => &$productData) { 889 | foreach ($productData as $storeId => &$dataRow) { 890 | if ($defaultStoreId != $storeId) { 891 | $dataRow[self::COL_SKU] = null; 892 | $dataRow[self::COL_ATTR_SET] = null; 893 | $dataRow[self::COL_TYPE] = null; 894 | } else { 895 | $dataRow[self::COL_STORE] = null; 896 | //$dataRow += $stockItemRows[$productId]; 897 | if (is_array($stockItemRows[$productId])) { 898 | $dataRow = array_merge($dataRow, $stockItemRows[$productId]); 899 | } 900 | } 901 | if ($rowCategories[$productId]) { 902 | $dataRow[self::COL_CATEGORY] = $this->_categories[array_shift($rowCategories[$productId])]; 903 | } 904 | if ($rowWebsites[$productId]) { 905 | $dataRow['_product_websites'] = $this->_websiteIdToCode[array_shift($rowWebsites[$productId])]; 906 | } 907 | if (!empty($rowTierPrices[$productId])) { 908 | $dataRow = array_merge($dataRow, array_shift($rowTierPrices[$productId])); 909 | } 910 | if (!empty($mediaGalery[$productId])) { 911 | $dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId])); 912 | } 913 | if (!empty($rowBundelOptions[$productId])) { 914 | $dataRow = array_merge($dataRow, array_shift($rowBundelOptions[$productId])); 915 | } 916 | foreach ($linkIdColPrefix as $linkId => &$colPrefix) { 917 | if (!empty($linksRows[$productId][$linkId])) { 918 | $linkData = array_shift($linksRows[$productId][$linkId]); 919 | $dataRow[$colPrefix . 'position'] = $linkData['position']; 920 | $dataRow[$colPrefix . 'sku'] = $linkData['sku']; 921 | 922 | if (null !== $linkData['default_qty']) { 923 | $dataRow[$colPrefix . 'default_qty'] = $linkData['default_qty']; 924 | } 925 | } 926 | } 927 | if (!empty($customOptionsData[$productId])) { 928 | $dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId])); 929 | } 930 | if (!empty($configurableData[$productId])) { 931 | $dataRow = array_merge($dataRow, array_shift($configurableData[$productId])); 932 | } 933 | $writer->writeRow($dataRow); 934 | } 935 | // calculate largest links block 936 | $largestLinks = 0; 937 | 938 | if (isset($linksRows[$productId])) { 939 | foreach ($linksRows[$productId] as &$linkData) { 940 | $largestLinks = max($largestLinks, count($linkData)); 941 | } 942 | } 943 | $additionalRowsCount = max( 944 | count($rowCategories[$productId]), 945 | count($rowWebsites[$productId]), 946 | $largestLinks 947 | ); 948 | if (!empty($rowTierPrices[$productId])) { 949 | $additionalRowsCount = max($additionalRowsCount, count($rowTierPrices[$productId])); 950 | } 951 | if (!empty($customOptionsData[$productId])) { 952 | $additionalRowsCount = max($additionalRowsCount, count($customOptionsData[$productId])); 953 | } 954 | if (!empty($configurableData[$productId])) { 955 | $additionalRowsCount = max($additionalRowsCount, count($configurableData[$productId])); 956 | } 957 | if (!empty($mediaGalery[$productId])) { 958 | $additionalRowsCount = max($additionalRowsCount, count($mediaGalery[$productId])); 959 | } 960 | if (!empty($rowBundelOptions[$productId])) { 961 | $additionalRowsCount = max($additionalRowsCount, count($rowBundelOptions[$productId])); 962 | } 963 | 964 | if ($additionalRowsCount) { 965 | for ($i = 0; $i < $additionalRowsCount; $i++) { 966 | $dataRow = array(); 967 | 968 | if ($rowCategories[$productId]) { 969 | $dataRow[self::COL_CATEGORY] = $this->_categories[array_shift($rowCategories[$productId])]; 970 | } 971 | if ($rowWebsites[$productId]) { 972 | $dataRow['_product_websites'] = $this->_websiteIdToCode[array_shift($rowWebsites[$productId])]; 973 | } 974 | if (!empty($rowTierPrices[$productId])) { 975 | $dataRow = array_merge($dataRow, array_shift($rowTierPrices[$productId])); 976 | } 977 | foreach ($linkIdColPrefix as $linkId => &$colPrefix) { 978 | if (!empty($linksRows[$productId][$linkId])) { 979 | $linkData = array_shift($linksRows[$productId][$linkId]); 980 | $dataRow[$colPrefix . 'position'] = $linkData['position']; 981 | $dataRow[$colPrefix . 'sku'] = $linkData['sku']; 982 | 983 | if (null !== $linkData['default_qty']) { 984 | $dataRow[$colPrefix . 'default_qty'] = $linkData['default_qty']; 985 | } 986 | } 987 | } 988 | if (!empty($customOptionsData[$productId])) { 989 | $dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId])); 990 | } 991 | if (!empty($configurableData[$productId])) { 992 | $dataRow = array_merge($dataRow, array_shift($configurableData[$productId])); 993 | } 994 | if (!empty($mediaGalery[$productId])) { 995 | $dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId])); 996 | } 997 | if (!empty($rowBundelOptions[$productId])) { 998 | $dataRow = array_merge($dataRow, array_shift($rowBundelOptions[$productId])); 999 | } 1000 | $writer->writeRow($dataRow); 1001 | } 1002 | } 1003 | } 1004 | //return $writer->getContents(); 1005 | } 1006 | 1007 | /** 1008 | * Prepare products media gallery 1009 | * 1010 | * @param array $productIds 1011 | * @return array 1012 | */ 1013 | protected function _prepareMediaGallery(array $productIds) 1014 | { 1015 | if (empty($productIds)) { 1016 | return array(); 1017 | } 1018 | $resource = Mage::getSingleton('core/resource'); 1019 | $select = $this->_connection->select() 1020 | ->from( 1021 | array('mg' => $resource->getTableName('catalog/product_attribute_media_gallery')), 1022 | array( 1023 | 'mg.entity_id', 'mg.attribute_id', 'filename' => 'mg.value', 'mgv.label', 1024 | 'mgv.position', 'mgv.disabled' 1025 | ) 1026 | ) 1027 | ->joinLeft( 1028 | array('mgv' => $resource->getTableName('catalog/product_attribute_media_gallery_value')), 1029 | '(mg.value_id = mgv.value_id AND mgv.store_id = 0)', 1030 | array() 1031 | ) 1032 | ->where('entity_id IN(?)', $productIds); 1033 | 1034 | $rowMediaGallery = array(); 1035 | $stmt = $this->_connection->query($select); 1036 | while ($mediaRow = $stmt->fetch()) { 1037 | $rowMediaGallery[$mediaRow['entity_id']][] = array( 1038 | '_media_attribute_id' => $mediaRow['attribute_id'], 1039 | '_media_image' => $mediaRow['filename'], 1040 | '_media_lable' => $mediaRow['label'], 1041 | '_media_position' => $mediaRow['position'], 1042 | '_media_is_disabled' => $mediaRow['disabled'] 1043 | ); 1044 | } 1045 | 1046 | return $rowMediaGallery; 1047 | } 1048 | } 1049 | class CustomImportExport_Export extends Mage_ImportExport_Model_Export 1050 | { 1051 | public function export($destination) 1052 | { 1053 | $_getEntityAdapter = new Entity_Product(); 1054 | 1055 | $_getEntityAdapter->setParameters($this->getData()); 1056 | 1057 | return $_getEntityAdapter 1058 | ->setWriter(Mage::getModel('importexport/export_adapter_csv', $destination)) 1059 | ->export(); 1060 | } 1061 | } 1062 | 1063 | class ProductExporter 1064 | { 1065 | private $_profile; 1066 | 1067 | public function __construct() 1068 | { 1069 | $this->_profile = Mage::getModel('dataflow/profile'); 1070 | } 1071 | 1072 | public function export($exportProducts, $filename) 1073 | { 1074 | $n = new CustomImportExport_Export(); 1075 | $n->setData(array( 1076 | "entity" => "catalog_product", 1077 | "file_format" => "csv", 1078 | 'attribute_code' => "sku", 1079 | "export_filter" => array( 1080 | 'sku' => $exportProducts 1081 | ) 1082 | )); 1083 | 1084 | $n->export($filename); 1085 | } 1086 | } 1087 | --------------------------------------------------------------------------------