Magento:创建类别对象的正确方法



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

显然,由于我们在新服务器上创建类别,它们的entity_id将发生变化。我已经解决了这一部分,并确保子类别具有正确的父id。在我尝试重新创建类别和子类别对象之前,这个项目一直很简单。我有各种各样的问题。新的类别对象保存在数据库中。然而,有时它们不会出现在类别树中,有时它们的parent_id变为0,有时整个类别树都消失了。我已经做了大约一个星期了。我已经读到,在保存之前,您必须将"path"属性设置为父级的路径。我读到过,您必须使用"move"方法将类别设置为其父类别的子类别。有很多理论,但似乎没有人有答案。

所以我的问题是:你如何创建真正有效的类别和子类别记录,并正确地链接到它们的父类别,显示在类别树中,并且不喙东西??我将原始源类别中的以下属性存储在一个名为$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();

是的,有些代码有点粗糙。这是一个简化版,我一直在尝试很多方法来让它发挥作用。这很令人沮丧。帮帮我欧比-万·克诺比。你是我唯一的希望。

唐!,我花了很多时间研究和解决这个问题。互联网上有很多关于这个问题的参考文献,但到目前为止,还没有人提出可靠的解决方案。

Magento使用对象模型来处理所有数据库I/O。这是为了使您不必做乏味的工作,例如更新相关字段。例如,如果添加新的子类别,Magento对象模型将自动更新父记录中的"children_count"。Magento对象模型基本上允许您关注您希望编写的数据,同时为您负责内务管理。然而,当对象模型没有做它应该做的事情时,事情真的很糟糕。"parent_id"字段和"path"字段就是这种情况。Magento只是没有按照它应该的方式更新它们。

解决方案是通过对象模型进行所需的更改,保存对象,然后通过数据库查询强制执行"parent_id"one_answers"path"的正确值。我发现,当第一次创建记录时,"parent_id"one_answers"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时,我将停止使用数据库。对于那些会说用第三人称回答自己的问题是危险的人,我说"HA!">

最新更新