2014-01-13 29 views
0

我正在写一个模块,将从一个Magento实例中提取对象,如网站,组,类别和产品,序列化它们的属性并将所有内容写入文本文件,序列化和在另一台服务器上。然后使用这些属性以编程方式在新服务器上重新创建这些对象。我们的想法是,我们将能够提取组成Magento网上商店的所有对象,并将它们移动到另一台服务器。 (不,我们不希望将整个实例移动到另一台服务器,我们只是希望能够移动一个商店及其相关对象)。Magento:正确的方法来创建类别对象

显然,由于我们在新服务器上创建类别,因此它们entity_id将会改变。我已经完成了这部分工作,并确保子类别具有正确的父级ID。直到我尝试重新创建类别和子类别对象时,该项目一直很直接。我遇到各种各样的问题。新的类别对象保存数据库。但是,有时它们不会显示在类别树中,有时它们的parent_id会更改为0,有时整个类别树会消失。我一直在为此工作大约一周。我已经读过,您必须在保存之前将“路径”属性设置为父路径。我已经读过,你必须使用“移动”方法将类别设置为其父项的子项。有很多理论,但没有人似乎有答案。

所以我的问题:你如何创建实际工作的类别和子类别记录,是否正确链接到他们的父类别,在类别树中显示,并且不要啄住事物?我从存储在名为$ aryData()的数组中的原始源类别中获得以下属性。

[entity_id] => 127  //This usually changes on new server 
[parent_id] => 1   //Lookup NEW entity_id of parent and use it 
[path] =>    //Not sure how to properly set this. Tried a few things 
[position] => 8   //Leave this alone, hope for the best 
[children_count] => 0 //Have to zero this out when you create new category object 
[name] => Best Test  
[url_key] => best-test 
[is_active] => 1 
[include_in_menu] => 1 

这里一般是我在做什么,以简化的方式:

$objNewCat = Mage::getModel('catalog/category'); //Create new object to populate 

$parent_id = getNewParent($data['name'], $data['url-key']; //Get new parent id by name and URL key. (This works) 
$objParentCat = Mage::getModel('catalog/category')->load($parent_id); 

$aryData(['parent_id']) = $parent_id; //Update parent ID in data array 
$aryData(['children_count']) = 0; //Must set to 0. Updated as children are added 


$objNewCat->setData($data); //Set all data parameters from our save array 
$objNewCat->setPath($objParentCat->getPath()); //Is this correct? Read you have to do this 
$objNewCat->save(); //Save object to populate entity_id field 

//--- Now assign object to be child of the parent. 
$objCat = Mage::getModel('catalog/category')->load($newCat->getId()); //reloading to set 'current category' 
Mage::unregister('category'); 
Mage::unregister('current_category'); 
Mage::register('category', $objCat); 
Mage::register('current_category', $objCat); 
$objCat->move($parent_id); 
$objCat->save(); 

是,一些这段代码是那种粗糙。这是一个简化的,我一直在尝试很多事情来实现它的工作。这非常令人沮丧。帮助我Obi-Wan Knobi。你我唯一的希望。

回答

1

唐!我花了很多时间研究和解决这个问题。在互联网上有许多关于这个问题的提法,但是到现在为止还没有人提出可靠的解决方案。

Magento使用对象模型来处理所有的数据库I/O。这应该让你不必做繁琐的工作,比如更新相关领域。例如,如果您添加新的子类别,则Magento对象模型将自动更新父记录中的'children_count'。 Magento对象模型基本上可以让您关注自己希望编写的数据,同时为您管理家务。但是,当对象模型没有做到应有的东西时,事情真的很糟糕。这是'parent_id'字段和'路径'字段的情况。 Magento不会按照它应该的方式更新它们。

解决方法是通过对象模型进行所需的更改,保存对象,然后通过数据库查询强制更改'parent_id'和'path'的正确值。我发现'parent_id'和'path'字段似乎在第一次创建记录时被正确保存,但是如果对象被更新,它们会变得混乱。此代码假定您正在更新现有的类别对象。

$catId = 127; //ID of category record you wish to edit 
$objCat = Mage::getModel('catalog/category')->load($catId); 
if(!is_object($objCat)) { 
    throw new Exception("ERROR: Could not find category id: " .$catId); 
} 

//--- Make sure we have proper parent_id and path values 
$parentId = $objCatParent->getId(); 
$path = $objCatParent->getPath() ."/" .$objCat->getId(); 

$objCatParent = $objCat->getParentCategory(); //We will need this parent category 
$data = array('name'  => 'My Cool Category', 
       'parent_id => $parentId, 
       'path'  => $path; 
$objCat->addData($data); //Use 'addData' rather than 'setData' 
$objCat->save(); //Save to update record and break parent_id, path fields 

//--- Now we get a connection to the database, build a query, and update record 
$resource = Mage::getSingleton('core/resource'); 
$objCon = $resource->getConnection('core_write'); 
$tableName = "catalog_category_entity"; //Well, it's the name of the Category table 
$query = "UPDATE {$table} SET parent_id = {$parentId}, path = '{$path}' " 
     . " WHERE entity_id = " .$catId; 
$objCon->query($query); //Force proper values directly into table 

是的,是的,是的,你当你绕过对象模型和直接修改数据库记录要非常小心。但是,Magento对象模型在这里似乎不起作用,所以我们没有多少选择。而且由于我们正在通过对象的'save()'方法保存记录,所以它在做任何'幕后'工作之前都应该这样做。我们正在纠正一个错误。

我希望这可以帮助你。这是一个棘手的问题。我希望有更好的解决方案,但是当他们修复API时,我将停止使用数据库。对于那些会说第三个人回答自己的问题的人来说,我会说“哈!”

相关问题