简体   繁体   English

Magento中的CSV导入/导出问题

[英]CSV Import/Export problems in Magento

Ok, so I managed to export my categories into a csv-file by following a set of instructions on justcode.in. 好的,所以我设法通过遵循justcode.in上的一组指令将我的类别导出到csv文件中。 I want to import my CSV back to a new installation of Magento. 我想将我的CSV导入到Magento的新安装中。

I am running Magento 1.9.2.2 When I try to run the profile, it finds my CSV-file and loads it, but it throws me this error. 我正在运行Magento 1.9.2.2当我尝试运行配置文件时,它会找到我的CSV文件并加载它,但它会抛出这个错误。

Error message, 错误信息,

<br /> <b>Fatal error</b>: Call to undefined method ImpCat_Catalog_Model_Convert_Adapter_Category::getStoreById() in <b>/var/www/public/secondstore/app/code/local/ImpCat/Catalog/Model/Convert/Adapter/Category.php</b> on line <b>32</b><br />

The CSV file is structured in this matter, CSV文件是在这个问题上构建的,

store;categories;is_active;meta_title;meta_keywords;meta_description;include_in_menu;is_anchor;description

Then I created config.xml at app\\code\\local\\ImpCat\\Catalog\\etc\\config.xml. 然后我在app \\ code \\ local \\ ImpCat \\ Catalog \\ etc \\ config.xml中创建了config.xml。 this file looks like this, 这个文件看起来像这样,

<?xml version="1.0"?>
<config>
 <global>
  <models>
   <catalog>
    <rewrite>
     <convert_adapter_category>ImpCat_Catalog_Model_Convert_Adapter_Category</convert_adapter_category>
    </rewrite>
   </catalog>
  </models>
 </global>
</config>

I then proceeded to create Category.php at app\\code\\local\\ImpCat\\Catalog\\Model\\Convert\\Adapter\\Category.php 然后我继续在app \\ code \\ local \\ ImpCat \\ Catalog \\ Model \\ Convert \\ Adapter \\ Category.php创建Category.php

Category.php looks like this, Category.php看起来像这样,

<?php
class ImpCat_Catalog_Model_Convert_Adapter_Category extends Mage_Eav_Model_Convert_Adapter_Entity
{
 protected $_categoryCache = array();
 protected $_stores;
 /**
 * Category display modes
 */
 protected $_displayModes = array( 'PRODUCTS', 'PAGE', 'PRODUCTS_AND_PAGE');

 public function parse()
 {
 $batchModel = Mage::getSingleton('dataflow/batch');
 $batchImportModel = $batchModel->getBatchImportModel();
 $importIds = $batchImportModel->getIdCollection();
 foreach ($importIds as $importId){
  $batchImportModel->load($importId);
  $importData = $batchImportModel->getBatchData();
  $this->saveRow($importData);
 }
 }
 /**
 * Save category (import)
 * @param array $importData
 * @throws Mage_Core_Exception
 * @return bool
 */
 public function saveRow(array $importData)
 {
 if (empty($importData['store'])) {
   if (!is_null($this->getBatchParams('store'))) {
   $store = $this->getStoreById($this->getBatchParams('store'));
   } else {
   $message = Mage::helper('catalog')->__('Skip import row, required field "%s" not defined', 'store');
   Mage::throwException($message);
   }
 }else{
  $store = $this->getStoreByCode($importData['store']);
 }
 if ($store === false){
  $message = Mage::helper('catalog')->__('Skip import row, store "%s" field not exists', $importData['store']);
  Mage::throwException($message);
 }
 $rootId = $store->getRootCategoryId();
  if (!$rootId) {
  return array();
  }
 $rootPath = '1/'.$rootId;
  if (empty($this->_categoryCache[$store->getId()])) {
  $collection = Mage::getModel('catalog/category')->getCollection()
              ->setStore($store)
              ->addAttributeToSelect('name');
 $collection->getSelect()->where("path like '".$rootPath."/%'");
 foreach ($collection as $cat) {
  $pathArr = explode('/', $cat->getPath());
  $namePath = '';
  for ($i=2, $l=sizeof($pathArr); $i<$l; $i++) {
  $name = $collection->getItemById($pathArr[$i])->getName();
  $namePath .= (empty($namePath) ? '' : '/').trim($name);
  }
  $cat->setNamePath($namePath);
 }
  $cache = array();
  foreach ($collection as $cat) {
  $cache[strtolower($cat->getNamePath())] = $cat;
  $cat->unsNamePath();
  }
  $this->_categoryCache[$store->getId()] = $cache;
  }
  $cache =& $this->_categoryCache[$store->getId()];
  $importData['categories'] = preg_replace('#\s*/\s*#', '/', trim($importData['categories']));
  if (!empty($cache[$importData['categories']])) {
  return true;
  }
  $path = $rootPath;
  $namePath = '';
  $i = 1;
 $categories = explode('/', $importData['categories']);
 /*$IsActive = $importData['IsActive'];*/
 $IsActive = $importData['is_active'];
 $IsAnchor =$importData['is_anchor'];
 $Description =$importData['description'];
 $IncludeInMenu=$importData['include_in_menu'];
 $MetaTitle=$importData['meta_title'];
 $MetaKeywords=$importData['meta_keywords'];
 $MetaDescription=$importData['meta_description'];
 $Image=$importData['image'];
 $URlkey=$importData['url_key'];
  foreach ($categories as $catName) {
  $namePath .= (empty($namePath) ? '' : '/').strtolower($catName);
  if (empty($cache[$namePath])) {
  $dispMode = $this->_displayModes[2];
    $cat = Mage::getModel('catalog/category')
    ->setStoreId($store->getId())
    ->setPath($path)
    ->setName($catName)
    ->setIsActive($IsActive)
    ->setIsAnchor($IsAnchor)
    ->setDisplayMode($dispMode)->save();
   $cat = Mage::getModel('catalog/category')->load($cat->getId());
   $cat->setIncludeInMenu($IncludeInMenu);
   $cat->setDescription($Description);
   $cat->setMetaTitle($MetaTitle).
    $cat->setMetaKeywords($MetaKeywords);
    $cat->setMetaDescription($MetaDescription);
    $cat->save();
   $cat = Mage::getModel('catalog/category')->load($cat->getId());
   $data['meta_keywords']=$MetaKeywords;
   $data['meta_title']=$MetaTitle;
   $data['meta_keywords']=$MetaKeywords;
   $data['meta_description']=$MetaDescription;
   $data['url_key']= $URlkey;
   $cat->addData($data);
   $cat->save();
  $cache[$namePath] = $cat;
  }
  $catId = $cache[$namePath]->getId();
  $path .= '/'.$catId;
  $i++;
  }
  return true;
 }

 /**
 * Retrieve store object by code
 *
 * @param string $store
 * @return Mage_Core_Model_Store
 */
 public function getStoreByCode($store)
 {
  $this->_initStores();
  if (isset($this->_stores[$store])) {
  return $this->_stores[$store];
  }
  return false;
 }

 /**
 * Init stores
 *
 * @param none
 * @return void
 */
 protected function _initStores ()
 {
  if (is_null($this->_stores)) {
  $this->_stores = Mage::app()->getStores(true, true);
  foreach ($this->_stores as $code => $store) {
  $this->_storesIdCode[$store->getId()] = $code;
  }
  }
 }
}

?>

I then continued to create ImpCat_All.xml at app\\etc\\modules ImpCat_All.xml looks like this, 然后我继续在app \\ etc \\ modules创建ImpCat_All.xml ImpCat_All.xml看起来像这样,

<?xml version="1.0"?>
<config>
 <modules>
  <ImpCat_Catalog>
   <codePool>local</codePool>
   <active>true</active>
  </ImpCat_Catalog>
 </modules>
</config>

I then created a dataflow advanced profile at admin > system >Import/Export > Dataflow - Advanced Profile called category import, and added this XML code. 然后,我在管理>系统>导入/导出>数据流 - 称为类别导入的高级配置文件中创建了数据流高级配置文件,并添加了此XML代码。

<action type="dataflow/convert_adapter_io" method="load">
     <var name="type">file</var>
     <var name="path">var/import</var>
     <var name="filename"><![CDATA[Categories.csv]]></var>
     <var name="format"><![CDATA[csv]]></var>
    </action>
    <action type="dataflow/convert_parser_csv" method="parse">
     <var name="delimiter"><![CDATA[,]]></var>
     <var name="enclose"><![CDATA["]]></var>
     <var name="fieldnames">true</var>
     <var name="store"><![CDATA[0]]></var>
     <var name="number_of_records">1</var>
     <var name="decimal_separator"><![CDATA[.]]></var>
     <var name="adapter">catalog/convert_adapter_category</var>
     <var name="method">parse</var>
 </action>

After many hours and days of trying one script after another, I finally figured out how to export and import all my categories to a new installation of Magento and keep all original ID's. 经过几个小时和几天尝试一个接一个的脚本后,我终于想出了如何将我的所有类别导出并导入到Magento的新安装并保留所有原始ID。

Exporting from your old Magento 从您的旧Magento导出

Here's my export tool, exporter.php (run through browser or in CLI), put this file at your Magento root. 这是我的导出工具exporter.php(通过浏览器或在CLI中运行),将此文件放在Magento根目录下。

exporter.php exporter.php

<?php
require_once 'app/Mage.php';
Mage::app();
$allCategories = Mage::getModel ( 'catalog/category' );
$categoryTree = $allCategories->getTreeModel();
$categoryTree->load();
$categoryIds = $categoryTree->getCollection()->getAllIds();
if ($categoryIds) {
  $outputFile = "var/export/categories-and-ids.csv";
  $write = fopen($outputFile, 'w');
  foreach ( $categoryIds as $categoryId ) {
    $parentId = $allCategories->load($categoryId)->getParentId();
    $data = array($parentId, $allCategories->load($categoryId)->getName(), $categoryId);
    fputcsv($write, $data);
  }
}
fclose($write);
echo "File written at /var/export";
?>

This produces a CSV-file at /var/export/categories-and-ids.csv Open this file and remove the top row containing your Default Category. 这将在/var/export/categories-and-ids.csv生成CSV文件打开此文件并删除包含默认类别的顶行。 You need to manually create a new Default Category in your installation, remember it's ID and correct your top level categories Parent ID. 您需要在安装中手动创建新的默认类别,记住它的ID并更正您的顶级类别父ID。 The CSV file you get from Export is structured as follows, 从Export获得的CSV文件的结构如下,

  1. First column is Parent_Id 第一列是Parent_Id
  2. Second column is name of sub-category 第二列是子类别的名称
  3. Third column is the original category ID from your old store 第三列是旧商店的原始类别ID

I recommend using OpenOffice Calc for editing and saving the CSV-file. 我建议使用OpenOffice Calc进行编辑和保存CSV文件。 The file MUST BE IN UTF-8 without BOM-format. 文件必须是UTF-8而没有BOM格式。

Importing to your new store 导入到您的新商店

To import your categories from your created/edited CSV-file, you just run this importer from your Magento root. 要从创建/编辑的CSV文件中导入类别,只需从Magento根目录运行此导入程序即可。 Remember to edit line 21 to reflect the name and location of your CSV. 请记住编辑第21行以反映CSV的名称和位置。

create-categories.php 创建-categories.php

<?php
/**
* Script created by sonassi.com (http://www.sonassi.com/knowledge-base/quick-script-batch-create-magento-categories/)
*
* Edited by Christer Johansson for Magento 1.9.2.2 in december 2015
*
* File format of the CSV file categories-and-ids.csv :
* parent_category_id,category_name,category_id
* example: 3,subcat,5
* -> This will create a subcategory with 'subcat' as name and 5 as category id. The parent category id is 3 (Can also be Root
* Category with id 0).
*/

define('MAGENTO', realpath(dirname(__FILE__)));
require_once MAGENTO . '/app/Mage.php';

setlocale(LC_ALL, 'en_US.UTF-8');
umask(0);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

$file = fopen('./var/import/categories-and-ids.csv', 'r');
while (($column = fgetcsv($file)) !== FALSE) {
        //$column is an array of the csv elements
        if (!empty($column[0]) && !empty($column[1]) && !empty($column[2])) {
                $data['general']['name'] = $column[1];
                $data['general']['entity_id'] = $column[2];
                $data['general']['meta_title'] = "";
                $data['general']['meta_description'] = "";
                $data['general']['is_active'] = 1;
                $data['general']['url_key'] = "";
                $data['general']['display_mode'] = "PRODUCTS";
                $data['general']['is_anchor'] = 0;

                $data['category']['parent'] = $column[0]; // 2 or 3 is top level depending on Magento version
                $storeId = 0;

                createCategory($data, $storeId);
                sleep(0.5);
                unset($data);
        }
}

function createCategory($data, $storeId) {
        echo "Starting {$data['general']['name']} [{$data['category']['parent']}] ...";

        $category = Mage::getModel('catalog/category');
        $category->setStoreId($storeId);

        if (is_array($data)) {
                $category->addData($data['general']);

                $parentId = $data['category']['parent'];
                $parentCategory = Mage::getModel('catalog/category')->load($parentId);
                $category->setPath($parentCategory->getPath() . "/" . $category->getId());

                /**
                * Check "Use Default Value" checkboxes values
                */
                if ($useDefaults = $data['use_default']) {
                        foreach ($useDefaults as $attributeCode) {
                                $category->setData($attributeCode, null);
                        }
                }

                $category->setAttributeSetId($category->getDefaultAttributeSetId());

                if (isset($data['category_products']) && !$category->getProductsReadonly()) {
                        $products = [];
                        parse_str($data['category_products'], $products);
                        $category->setPostedProducts($products);
                }

                try {
                        $category->save();
                        echo "Import successful - ID: " . $category->getId() . " - " . $category->getPath() . "<br /> ";
                } catch (Exception $e){
                        echo "Failed import <br />";
                }
        }

}

Depending on how big your site is and how many categories you are importing, this will take anything from a few seconds to minutes or even hours if you have thousands of them. 根据您的网站有多大以及您要导入的类别数量,如果您有数千个,则需要几秒到几分钟甚至几小时。

Just be patient, and the script will give you a list of all imported categories and show you if any failed to import. 请耐心等待,脚本会为您提供所有导入类别的列表,并显示是否导入失败。 Remember to clean your category names before import. 请记住在导入前清除类别名称。

After import is done, clear your cache and re-index Magento through Admin. 导入完成后,清除缓存并通过Admin重新索引Magento。 Check out your categories in your Manage Categories, and start importing or creating products. 在“管理类别”中查看您的类别,然后开始导入或创建产品。

Good luck! 祝好运! :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM