6

In Magento there is a great model Mage_Catalog_Model_Product_Action which allows you to quickly update product attributes. You just pass it the IDs that the change should apply to, and an array of key/value pairs for attribute-code/value.

I was able to easily copy this and create Mage_Catalog_Model_Category_Action (along with Mage_Catalog_Model_Resource_Category_Action and Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Action). It just required changing the entity type to 'catalog_category' in a few places, (plus changing a view event names,) and it works great.

The problem though is that a category's list of product IDs isn't an attribute. Though there is a catalog_category_product table, there is no matching entity type, or even a model (!?) for this table.

So I'm left wondering how I can mass-update the category to product association. Obviously I could load each product via it's model, and update the 'category_ids' attribute, but this involves a ton of overhead. (I should note, I'm looking to be able to mass update thousands of category->product associations.)

The only method left available to me is direct query manipulation, and I'm hoping to avoid that.

I do know that the API has an assignProducts method, but I don't want to make thousands of SOAP calls back to my own server, and I'm not sure how to use the API models directly in my code.

Any help appreciated.

Edit: The class Mage_Catalog_Model_Category_Indexer_Product and method _registerProductEvent and/or _registerCategoryEvent might hold some clues. However these are protected methods and I'm not sure how to build or spoof the Mage_Index_Model_Event object correctly.

  • The code that updates these categories runs on a cron. I would be okay with programmatically rebuilding the index after the cron completes. – Tyler V. Aug 27 '14 at 22:54
  • That's a very valid point. Still, it seem strange that one can quickly and easily update normal attribute values through the above mentioned action models, but the same can't be done for category->product relationships. I mean, the table that holds that data is a whopping 3 columns. Is it really such a complex relationship the alter that the entire model must be loaded? – Tyler V. Aug 28 '14 at 0:05
4

the fastest way is with direct queries. And there shouldn't be an issue with that. I've done it a lot of times. The only thing required is to rebuild the indexes when you are done.

INSERT INTO `catalog_category_product` SET
    `category_id` = category id here
    `product_id` = product id here
    `position` = position here
ON DUPLICATE KEY UPDATE
    `position` = position here

but if you want to avoid this you can group your product ids by category then do this:

$category = Mage::getModel('catalog/category')->load(category id here);
$postedProducts = $category->getProductsPosition();
foreach ($productIds as $productId) {
    $postedProducts[$productId] = position here;
}
$category->setPostedProducts($postedProducts);
$category->save();

 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.