【问题标题】:Magento: Proper way to create category objectsMagento:创建类别对象的正确方法
【发布时间】:2014-01-13 17:37:32
【问题描述】:

我正在编写一个模块,该模块将从一个 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();

是的,其中一些代码有点粗糙。这是一个简化的,我一直在尝试很多事情来让它工作。这非常令人沮丧。帮我欧比旺克诺比。你是我唯一的希望。

【问题讨论】:

    标签: php magento categories object-model


    【解决方案1】:

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

    Magento 使用对象模型来处理所有数据库 I/O。这应该使您不必做繁琐的工作,例如更新相关字段。例如,如果您添加一个新的子类别,Magento 对象模型将自动更新父记录中的“children_count”。 Magento 对象模型基本上让您关心您希望写入的数据,同时为您处理家务。然而,当对象模型没有做它应该做的事情时,事情真的很糟糕。这就是“parent_id”字段和“path”字段的情况。 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 时,我将停止使用数据库。对于那些会说以第三人称回答自己的问题很尴尬的人,我说“哈!”

    【讨论】:

      猜你喜欢
      • 2021-06-24
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多